gpu: implement polygon offset

Co-authored-by: Pouare514 <julienaulycee@gmail.com>
This commit is contained in:
nmzikandPouare514 committed 2026-08-06 22:02:19 +02:00
1 parent 3052dac82e
commit e9f5da27f8
9 files changed
+146 -26

No files matched your search

@@ -18,7 +18,9 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <bit>
#include <cstdio> #include <cstdio>
#include <cstring>
#include <vector> #include <vector>
#define KYTY_HW_CTX_PARSER_ARGS \ #define KYTY_HW_CTX_PARSER_ARGS \
@@ -895,23 +897,44 @@ KYTY_HW_CTX_PARSER(HwCtxSetModeControl) {
return 1; return 1;
} }
static void HwCtxIgnorePolyOffsetRegister(uint32_t cmd_offset, uint32_t value) { static void HwCtxSetPolyOffsetRegister(CommandProcessor& cp, uint32_t cmd_offset, uint32_t value) {
static std::atomic<uint32_t> log_count = 0; HW::PolyOffset offset = cp.GetCtx().GetPolyOffset();
auto count = log_count.fetch_add(1); switch (cmd_offset) {
if (count < 8) { case Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL: {
LOGF_COLOR(Log::Color::Red, const auto neg_bits =
"\t temporary: ignoring polygon offset context register 0x%03" PRIx32 KYTY_PM4_GET(value, PA_SU_POLY_OFFSET_DB_FMT_CNTL, NEG_NUM_DB_BITS);
" = 0x%08" PRIx32 " (depth bias not implemented)\n", offset.neg_num_db_bits = std::bit_cast<int8_t>(static_cast<uint8_t>(neg_bits));
offset.db_is_float_fmt =
KYTY_PM4_GET(value, PA_SU_POLY_OFFSET_DB_FMT_CNTL, DB_IS_FLOAT_FMT) != 0;
break;
}
case Pm4::PA_SU_POLY_OFFSET_CLAMP: offset.clamp = std::bit_cast<float>(value); break;
case Pm4::PA_SU_POLY_OFFSET_FRONT_SCALE:
offset.front_scale = std::bit_cast<float>(value);
break;
case Pm4::PA_SU_POLY_OFFSET_FRONT_OFFSET:
offset.front_offset = std::bit_cast<float>(value);
break;
case Pm4::PA_SU_POLY_OFFSET_BACK_SCALE:
offset.back_scale = std::bit_cast<float>(value);
break;
case Pm4::PA_SU_POLY_OFFSET_BACK_OFFSET:
offset.back_offset = std::bit_cast<float>(value);
break;
default:
EXIT("unknown polygon offset context register 0x%03" PRIx32 " = 0x%08" PRIx32 "\n",
cmd_offset, value); cmd_offset, value);
} }
cp.GetCtx().SetPolyOffset(offset);
} }
KYTY_HW_CTX_PARSER(HwCtxSetPolyOffsetRegisters) { KYTY_HW_CTX_PARSER(HwCtxSetPolyOffsetRegisters) {
auto num_values = KYTY_PM4_LEN(cmd_id) - 2u; auto num_values = KYTY_PM4_LEN(cmd_id) - 2u;
for (uint32_t i = 0; i < num_values; i++) { for (uint32_t i = 0; i < num_values; i++) {
HwCtxIgnorePolyOffsetRegister(cmd_offset + i, buffer[i]); HwCtxSetPolyOffsetRegister(cp, cmd_offset + i, buffer[i]);
} }
return num_values; return num_values;
@@ -3705,22 +3728,22 @@ void GraphicsInitJmpTablesCxIndirect() {
}; };
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
HwCtxIgnorePolyOffsetRegister(cmd_offset, value); HwCtxSetPolyOffsetRegister(cp, cmd_offset, value);
}; };
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_CLAMP] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_CLAMP] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
HwCtxIgnorePolyOffsetRegister(cmd_offset, value); HwCtxSetPolyOffsetRegister(cp, cmd_offset, value);
}; };
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_FRONT_SCALE] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_FRONT_SCALE] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
HwCtxIgnorePolyOffsetRegister(cmd_offset, value); HwCtxSetPolyOffsetRegister(cp, cmd_offset, value);
}; };
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_FRONT_OFFSET] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_FRONT_OFFSET] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
HwCtxIgnorePolyOffsetRegister(cmd_offset, value); HwCtxSetPolyOffsetRegister(cp, cmd_offset, value);
}; };
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_BACK_SCALE] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_BACK_SCALE] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
HwCtxIgnorePolyOffsetRegister(cmd_offset, value); HwCtxSetPolyOffsetRegister(cp, cmd_offset, value);
}; };
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_BACK_OFFSET] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_BACK_OFFSET] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
HwCtxIgnorePolyOffsetRegister(cmd_offset, value); HwCtxSetPolyOffsetRegister(cp, cmd_offset, value);
}; };
g_hw_ctx_indirect_func[Pm4::DB_Z_INFO] = [](KYTY_HW_CTX_INDIRECT_ARGS) { g_hw_ctx_indirect_func[Pm4::DB_Z_INFO] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
+13
View File
@@ -348,6 +348,16 @@ struct ModeControl {
bool persp_corr_dis = false; bool persp_corr_dis = false;
}; };
struct PolyOffset {
int8_t neg_num_db_bits = -23;
bool db_is_float_fmt = true;
float clamp = 0.0f;
float front_scale = 0.0f;
float front_offset = 0.0f;
float back_scale = 0.0f;
float back_offset = 0.0f;
};
struct BlendControl { struct BlendControl {
uint8_t color_srcblend = 1; uint8_t color_srcblend = 1;
uint8_t color_comb_fcn = 0; uint8_t color_comb_fcn = 0;
@@ -905,6 +915,8 @@ public:
void SetDepthControl(const DepthControl& control) { m_depth_control = control; } void SetDepthControl(const DepthControl& control) { m_depth_control = control; }
[[nodiscard]] const ModeControl& GetModeControl() const { return m_mode_control; } [[nodiscard]] const ModeControl& GetModeControl() const { return m_mode_control; }
void SetModeControl(const ModeControl& control) { m_mode_control = control; } void SetModeControl(const ModeControl& control) { m_mode_control = control; }
[[nodiscard]] const PolyOffset& GetPolyOffset() const { return m_poly_offset; }
void SetPolyOffset(const PolyOffset& offset) { m_poly_offset = offset; }
[[nodiscard]] const EqaaControl& GetEqaaControl() const { return m_eqaa_control; } [[nodiscard]] const EqaaControl& GetEqaaControl() const { return m_eqaa_control; }
void SetEqaaControl(const EqaaControl& control) { m_eqaa_control = control; } void SetEqaaControl(const EqaaControl& control) { m_eqaa_control = control; }
[[nodiscard]] const StencilControl& GetStencilControl() const { return m_stencil_control; } [[nodiscard]] const StencilControl& GetStencilControl() const { return m_stencil_control; }
@@ -1002,6 +1014,7 @@ private:
uint8_t m_stencil_clear_value = 0; uint8_t m_stencil_clear_value = 0;
ModeControl m_mode_control; ModeControl m_mode_control;
PolyOffset m_poly_offset;
EqaaControl m_eqaa_control; EqaaControl m_eqaa_control;
ShaderRegisters m_sh_regs; ShaderRegisters m_sh_regs;
+4
View File
@@ -588,6 +588,10 @@ constexpr uint32_t VGT_LS_HS_CONFIG = 0x2D6;
constexpr uint32_t VGT_TF_PARAM = 0x2DB; constexpr uint32_t VGT_TF_PARAM = 0x2DB;
constexpr uint32_t DB_ALPHA_TO_MASK = 0x2DC; constexpr uint32_t DB_ALPHA_TO_MASK = 0x2DC;
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL = 0x2DE; constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL = 0x2DE;
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_NEG_NUM_DB_BITS_SHIFT = 0;
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_NEG_NUM_DB_BITS_MASK = 0xFF;
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_DB_IS_FLOAT_FMT_SHIFT = 8;
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_DB_IS_FLOAT_FMT_MASK = 0x1;
constexpr uint32_t PA_SU_POLY_OFFSET_CLAMP = 0x2DF; constexpr uint32_t PA_SU_POLY_OFFSET_CLAMP = 0x2DF;
constexpr uint32_t PA_SU_POLY_OFFSET_FRONT_SCALE = 0x2E0; constexpr uint32_t PA_SU_POLY_OFFSET_FRONT_SCALE = 0x2E0;
constexpr uint32_t PA_SU_POLY_OFFSET_FRONT_OFFSET = 0x2E1; constexpr uint32_t PA_SU_POLY_OFFSET_FRONT_OFFSET = 0x2E1;
-8
View File
@@ -686,14 +686,6 @@ static void McCheck(const HW::ModeControl& c) {
} }
EXIT_NOT_IMPLEMENTED(c.polymode_front_ptype != 0 && c.polymode_front_ptype != 2); EXIT_NOT_IMPLEMENTED(c.polymode_front_ptype != 0 && c.polymode_front_ptype != 2);
EXIT_NOT_IMPLEMENTED(c.polymode_back_ptype != 0 && c.polymode_back_ptype != 2); EXIT_NOT_IMPLEMENTED(c.polymode_back_ptype != 0 && c.polymode_back_ptype != 2);
if (c.poly_offset_front_enable || c.poly_offset_back_enable) {
static bool logged = false;
if (!logged) {
LOGF("\t temporary: PA_SU_SC_MODE_CNTL.POLY_OFFSET_*_ENABLE is not implemented; "
"continuing without depth bias\n");
logged = true;
}
}
if (c.vtx_window_offset_enable) { if (c.vtx_window_offset_enable) {
static bool logged = false; static bool logged = false;
if (!logged) { if (!logged) {
@@ -947,6 +947,8 @@ void CreatePipelineInternal(
vk::DynamicState::eViewport, vk::DynamicState::eViewport,
vk::DynamicState::eScissor, vk::DynamicState::eScissor,
vk::DynamicState::eLineWidth, vk::DynamicState::eLineWidth,
vk::DynamicState::eDepthBiasEnable,
vk::DynamicState::eDepthBias,
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilCompareMask,
vk::DynamicState::eStencilReference, vk::DynamicState::eStencilReference,
vk::DynamicState::eStencilWriteMask, vk::DynamicState::eStencilWriteMask,
@@ -68,8 +68,28 @@ static std::atomic<uint32_t> g_draw_state_log_count = 0;
static std::atomic<uint32_t> g_draw_input_log_count = 0; static std::atomic<uint32_t> g_draw_input_log_count = 0;
static std::atomic<uint32_t> g_mrt_state_log_count = 0; static std::atomic<uint32_t> g_mrt_state_log_count = 0;
static std::atomic<uint32_t> g_shader_stage_log_count = 0; static std::atomic<uint32_t> g_shader_stage_log_count = 0;
static std::atomic<uint32_t> g_framebuffer_skip_log_count = 0; static std::atomic<uint32_t> g_framebuffer_skip_log_count = 0;
static float ConvertPolygonOffsetConstantFactor(float guest_factor, const HW::PolyOffset& offset,
vk::Format host_depth_format) {
if (offset.db_is_float_fmt) {
return guest_factor;
}
int host_depth_bits = 0;
switch (host_depth_format) {
case vk::Format::eD16Unorm:
case vk::Format::eD16UnormS8Uint: host_depth_bits = 16; break;
case vk::Format::eD24UnormS8Uint: host_depth_bits = 24; break;
default:
// A fixed-point guest bias cannot be represented exactly by a floating-point host
// attachment without VK_EXT_depth_bias_control.
return guest_factor;
}
return std::ldexp(guest_factor, host_depth_bits + offset.neg_num_db_bits);
}
static const char* RenderColorTypeName(RenderColorType type) { static const char* RenderColorTypeName(RenderColorType type) {
switch (type) { switch (type) {
case RenderColorType::NoColorOutput: return "NoColorOutput"; case RenderColorType::NoColorOutput: return "NoColorOutput";
@@ -335,6 +355,22 @@ static PipelineDynamicParameters BuildGraphicsDynamicParams(const RenderCommandB
ret.stencil_front = depth.stencil_dynamic_front; ret.stencil_front = depth.stencil_dynamic_front;
ret.stencil_back = depth.stencil_dynamic_back; ret.stencil_back = depth.stencil_dynamic_back;
const auto& mode = ctx.GetModeControl();
const auto& poly_offset = ctx.GetPolyOffset();
const bool use_front = mode.poly_offset_front_enable && !mode.cull_front;
const bool use_back = mode.poly_offset_back_enable && !mode.cull_back;
ret.depth_bias_enable = use_front || use_back;
if (ret.depth_bias_enable) {
// Vulkan has one bias for both faces. Prefer a visible front face when both are enabled.
const float guest_constant_factor =
use_front ? poly_offset.front_offset : poly_offset.back_offset;
ret.depth_bias_constant_factor =
ConvertPolygonOffsetConstantFactor(guest_constant_factor, poly_offset, depth.format);
ret.depth_bias_clamp = poly_offset.clamp;
ret.depth_bias_slope_factor =
(use_front ? poly_offset.front_scale : poly_offset.back_scale) / 16.0f;
}
// CB_COLOR_CONTROL.operation controls special CB operations, not the normal color component // CB_COLOR_CONTROL.operation controls special CB operations, not the normal color component
// write mask. Use CB_TARGET_MASK here so scanout passes with mode=Disable do not go black. // write mask. Use CB_TARGET_MASK here so scanout passes with mode=Disable do not go black.
for (uint32_t i = 0; i < RENDER_COLOR_ATTACHMENTS_MAX; i++) { for (uint32_t i = 0; i < RENDER_COLOR_ATTACHMENTS_MAX; i++) {
@@ -379,6 +415,13 @@ static void SetDynamicParams(const RenderCommandBuffer& buffer, vk::CommandBuffe
} }
vk_buffer.setLineWidth(line_width); vk_buffer.setLineWidth(line_width);
vk_buffer.setDepthBiasEnable(dynamic_params.depth_bias_enable ? VK_TRUE : VK_FALSE);
if (dynamic_params.depth_bias_enable) {
vk_buffer.setDepthBias(dynamic_params.depth_bias_constant_factor,
dynamic_params.depth_bias_clamp,
dynamic_params.depth_bias_slope_factor);
}
if (dynamic_params.stencil_test_enable) { if (dynamic_params.stencil_test_enable) {
vk_buffer.setStencilCompareMask(vk::StencilFaceFlagBits::eFront, vk_buffer.setStencilCompareMask(vk::StencilFaceFlagBits::eFront,
dynamic_params.stencil_front.compareMask); dynamic_params.stencil_front.compareMask);
+4 -4
View File
@@ -15,12 +15,16 @@ struct ShaderVertexInputInfo;
struct PipelineDynamicParameters { struct PipelineDynamicParameters {
bool stencil_test_enable = false; bool stencil_test_enable = false;
bool depth_bias_enable = false;
float viewport_scale[3] = {}; float viewport_scale[3] = {};
float viewport_offset[3] = {}; float viewport_offset[3] = {};
int scissor_ltrb[4] = {0}; int scissor_ltrb[4] = {0};
float line_width = 1.0f; float line_width = 1.0f;
float depth_bias_constant_factor = 0.0f;
float depth_bias_clamp = 0.0f;
float depth_bias_slope_factor = 0.0f;
uint32_t color_write_count = 1; uint32_t color_write_count = 1;
bool color_write_enable[RENDER_COLOR_ATTACHMENTS_MAX] = {true, true}; bool color_write_enable[RENDER_COLOR_ATTACHMENTS_MAX] = {true, true};
@@ -33,10 +37,6 @@ struct PipelineDynamicParameters {
static_assert(std::is_trivially_copyable_v<PipelineDynamicParameters>); static_assert(std::is_trivially_copyable_v<PipelineDynamicParameters>);
static_assert(std::is_standard_layout_v<PipelineDynamicParameters>); static_assert(std::is_standard_layout_v<PipelineDynamicParameters>);
static_assert(alignof(PipelineDynamicParameters) == 1); static_assert(alignof(PipelineDynamicParameters) == 1);
static_assert(sizeof(PipelineDynamicParameters) ==
sizeof(bool) + sizeof(float[3]) + sizeof(float[3]) + sizeof(int[4]) + sizeof(float) +
sizeof(uint32_t) + sizeof(bool[RENDER_COLOR_ATTACHMENTS_MAX]) +
sizeof(PipelineStencilDynamicState) * 2);
[[nodiscard]] int32_t ResolveVertexOffset(uint32_t index_offset, [[nodiscard]] int32_t ResolveVertexOffset(uint32_t index_offset,
const ShaderVertexInputInfo& vs_input_info); const ShaderVertexInputInfo& vs_input_info);
@@ -260,6 +260,10 @@ static void VulkanFindPhysicalDevice(vk::Instance instance, vk::SurfaceKHR surfa
LOGF("sampleRateShading is not supported\n"); LOGF("sampleRateShading is not supported\n");
skip_device = true; skip_device = true;
} }
if (device_features2.features.depthBiasClamp != VK_TRUE) {
LOGF("depthBiasClamp is not supported\n");
skip_device = true;
}
if (device_features2.features.fragmentStoresAndAtomics != VK_TRUE) { if (device_features2.features.fragmentStoresAndAtomics != VK_TRUE) {
LOGF("fragmentStoresAndAtomics is not supported\n"); LOGF("fragmentStoresAndAtomics is not supported\n");
@@ -549,6 +553,7 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
EXIT_NOT_IMPLEMENTED(required_features13.synchronization2 == VK_TRUE && EXIT_NOT_IMPLEMENTED(required_features13.synchronization2 == VK_TRUE &&
supported_features13.synchronization2 != VK_TRUE); supported_features13.synchronization2 != VK_TRUE);
EXIT_NOT_IMPLEMENTED(supported_features2.features.sampleRateShading != VK_TRUE); EXIT_NOT_IMPLEMENTED(supported_features2.features.sampleRateShading != VK_TRUE);
EXIT_NOT_IMPLEMENTED(supported_features2.features.depthBiasClamp != VK_TRUE);
features12.timelineSemaphore = VK_TRUE; features12.timelineSemaphore = VK_TRUE;
vk::PhysicalDeviceFeatures device_features {}; vk::PhysicalDeviceFeatures device_features {};
@@ -564,6 +569,7 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
device_features.independentBlend = VK_TRUE; device_features.independentBlend = VK_TRUE;
device_features.tessellationShader = VK_TRUE; device_features.tessellationShader = VK_TRUE;
device_features.sampleRateShading = VK_TRUE; device_features.sampleRateShading = VK_TRUE;
device_features.depthBiasClamp = VK_TRUE;
graphics.sample_rate_shading_enabled = true; graphics.sample_rate_shading_enabled = true;
device_features.vertexPipelineStoresAndAtomics = device_features.vertexPipelineStoresAndAtomics =
supported_features2.features.vertexPipelineStoresAndAtomics; supported_features2.features.vertexPipelineStoresAndAtomics;
+37
View File
@@ -18059,6 +18059,41 @@ void CheckPm4StencilInfoValueLane(RenderContext& renderer) {
std::printf("[host] %-32s ok\n", "Pm4StencilInfoValueLane"); std::printf("[host] %-32s ok\n", "Pm4StencilInfoValueLane");
} }
void CheckPm4PolygonOffsetRegisters(RenderContext& renderer) {
GraphicsInitJmpTables();
CommandProcessor processor(renderer);
const auto& defaults = processor.GetCtx().GetPolyOffset();
Require("Pm4PolygonOffset", "format defaults",
defaults.neg_num_db_bits == -23 && defaults.db_is_float_fmt,
"polygon offset Z format did not default to D32F");
constexpr std::array<uint32_t, 6> payload {
0x000000f0u, std::bit_cast<uint32_t>(2.5f), std::bit_cast<uint32_t>(16.0f),
std::bit_cast<uint32_t>(-3.25f), std::bit_cast<uint32_t>(32.0f),
std::bit_cast<uint32_t>(4.5f)};
const auto consumed = HwCtxSetPolyOffsetRegisters(
processor, KYTY_PM4(8, Pm4::IT_SET_CONTEXT_REG, Pm4::R_ZERO),
Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL, payload.data(), 0);
const auto& direct = processor.GetCtx().GetPolyOffset();
Require("Pm4PolygonOffset", "direct registers",
consumed == payload.size() && direct.neg_num_db_bits == -16 &&
!direct.db_is_float_fmt && direct.clamp == 2.5f && direct.front_scale == 16.0f &&
direct.front_offset == -3.25f && direct.back_scale == 32.0f &&
direct.back_offset == 4.5f,
"direct polygon offset register packet was decoded incorrectly");
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL](
processor, Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL, 0x000001e9u);
g_hw_ctx_indirect_func[Pm4::PA_SU_POLY_OFFSET_FRONT_SCALE](
processor, Pm4::PA_SU_POLY_OFFSET_FRONT_SCALE, std::bit_cast<uint32_t>(24.0f));
const auto& indirect = processor.GetCtx().GetPolyOffset();
Require("Pm4PolygonOffset", "indirect registers",
indirect.neg_num_db_bits == -23 && indirect.db_is_float_fmt &&
indirect.front_scale == 24.0f && indirect.front_offset == -3.25f,
"indirect polygon offset register write was decoded incorrectly");
std::printf("[host] %-32s ok\n", "Pm4PolygonOffset");
}
void CheckPm4ContextStateOperations(RenderContext& renderer) { void CheckPm4ContextStateOperations(RenderContext& renderer) {
GraphicsInitJmpTables(); GraphicsInitJmpTables();
CommandProcessor processor(renderer); CommandProcessor processor(renderer);
@@ -18327,6 +18362,7 @@ int main(int argc, char** argv) {
} }
if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) { if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) {
VulkanHarness vulkan; VulkanHarness vulkan;
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer()); CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
return 0; return 0;
} }
@@ -18464,6 +18500,7 @@ int main(int argc, char** argv) {
CheckVulkan13FeatureRequirements(); CheckVulkan13FeatureRequirements();
CheckPm4AcquireMemNoOp(vulkan.RuntimeRenderer()); CheckPm4AcquireMemNoOp(vulkan.RuntimeRenderer());
CheckPm4StencilInfoValueLane(vulkan.RuntimeRenderer()); CheckPm4StencilInfoValueLane(vulkan.RuntimeRenderer());
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer()); CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
CheckPm4WaitResume(vulkan.RuntimeRenderer()); CheckPm4WaitResume(vulkan.RuntimeRenderer());
CheckPm4CeCompletion(vulkan.RuntimeRenderer()); CheckPm4CeCompletion(vulkan.RuntimeRenderer());