From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 1 + tests/hlsl/sample-cmp.shader_test | 160 ++++++++++++++++++++++++++++++ tests/shader_runner.c | 34 +++++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d11.c | 2 +- tests/shader_runner_d3d12.c | 1 + tests/shader_runner_gl.c | 30 ++++++ tests/shader_runner_vulkan.c | 27 +++++ 8 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 tests/hlsl/sample-cmp.shader_test
diff --git a/Makefile.am b/Makefile.am index cfb225f9c..322fd73f8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -160,6 +160,7 @@ vkd3d_shader_tests = \ tests/hlsl/return.shader_test \ tests/hlsl/round.shader_test \ tests/hlsl/sample-bias.shader_test \ + tests/hlsl/sample-cmp.shader_test \ tests/hlsl/sample-grad.shader_test \ tests/hlsl/sample-level.shader_test \ tests/hlsl/sampler-offset.shader_test \ diff --git a/tests/hlsl/sample-cmp.shader_test b/tests/hlsl/sample-cmp.shader_test new file mode 100644 index 000000000..902e3b2c7 --- /dev/null +++ b/tests/hlsl/sample-cmp.shader_test @@ -0,0 +1,160 @@ +[require] +shader model >= 4.0 + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison never + +[srv 0] +format r32 float +size (2d, 2, 2) +0.5 0.5 +0.5 0.5 + +[pixel shader] +Texture2D<float> t : register(t0); +SamplerComparisonState s : register(s0); + +float ref; + +float4 main() : sv_target +{ + return t.SampleCmpLevelZero(s, float2(0.5, 0.5), ref); +} + +[test] +uniform 0 float 1.0 +draw quad +probe all r (0.0) + +uniform 0 float 0.0 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison less + +[test] +uniform 0 float 0.0 +draw quad +probe all r (1.0) + +uniform 0 float 0.5 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison equal + +[test] +uniform 0 float 0.5 +draw quad +probe all r (1.0) + +uniform 0 float 0.5000001 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison less equal + +[test] +% fails on 0.5, at least on RADV +uniform 0 float 0.4999999 +draw quad +probe all r (1.0) + +uniform 0 float 0.5000001 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison greater + +[test] +uniform 0 float 1.0 +draw quad +probe all r (1.0) + +uniform 0 float 0.5 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison not equal + +[test] +uniform 0 float 0.5000001 +draw quad +probe all r (1.0) + +uniform 0 float 0.5 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison greater equal + +[test] +% fails on 0.5, at least on RADV +uniform 0 float 0.5000001 +draw quad +probe all r (1.0) + +uniform 0 float 0.4999999 +draw quad +probe all r (0.0) + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison always + +[test] +uniform 0 float 0.0 +draw quad +probe all r (1.0) + +uniform 0 float 1.0 +draw quad +probe all r (1.0) + + +[sampler 0] +filter linear linear linear +address clamp clamp clamp +comparison greater + +[pixel shader] +Texture2D<float> t : register(t0); +SamplerComparisonState s : register(s0); + +float ref; + +float4 main() : sv_target +{ + return t.SampleCmp(s, float2(0.5, 0.5), ref); +} + +[test] +uniform 0 float 1.0 +draw quad +probe all r (1.0) + +uniform 0 float 0.0 +draw quad +probe all r (0.0) + diff --git a/tests/shader_runner.c b/tests/shader_runner.c index d0d806508..77d129a87 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -410,12 +410,46 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line) if (match_string(line, filters[i].string, &line)) { sampler->filter = filters[i].filter; + if (sampler->func) + sampler->filter |= D3D12_FILTER_REDUCTION_TYPE_COMPARISON << D3D12_FILTER_REDUCTION_TYPE_SHIFT; return; } }
fatal_error("Unknown sampler filter '%s'.\n", line); } + else if (match_string(line, "comparison", &line)) + { + static const struct + { + const char *string; + D3D12_COMPARISON_FUNC func; + } + funcs[] = + { + {"never", D3D12_COMPARISON_FUNC_NEVER}, + {"less", D3D12_COMPARISON_FUNC_LESS}, + {"equal", D3D12_COMPARISON_FUNC_EQUAL}, + {"less equal", D3D12_COMPARISON_FUNC_LESS_EQUAL}, + {"greater", D3D12_COMPARISON_FUNC_GREATER}, + {"not equal", D3D12_COMPARISON_FUNC_NOT_EQUAL}, + {"greater equal", D3D12_COMPARISON_FUNC_GREATER_EQUAL}, + {"always", D3D12_COMPARISON_FUNC_ALWAYS}, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(funcs); ++i) + { + if (match_string(line, funcs[i].string, &line)) + { + sampler->filter |= D3D12_FILTER_REDUCTION_TYPE_COMPARISON << D3D12_FILTER_REDUCTION_TYPE_SHIFT; + sampler->func = funcs[i].func; + return; + } + } + + fatal_error("Unknown sampler func '%s'.\n", line); + } else { fatal_error("Unknown sampler directive '%s'.\n", line); diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 62358d78c..f750dae6d 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -62,6 +62,7 @@ struct sampler
D3D12_FILTER filter; D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address; + D3D12_COMPARISON_FUNC func; };
enum resource_type diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 528c04e9d..d9310497a 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -509,7 +509,7 @@ static ID3D11SamplerState *create_sampler(ID3D11Device *device, const struct sam desc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)sampler->u_address; desc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)sampler->v_address; desc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)sampler->w_address; - desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + desc.ComparisonFunc = sampler->func; desc.MaxLOD = D3D11_FLOAT32_MAX;
hr = ID3D11Device_CreateSamplerState(device, &desc, &d3d11_sampler); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index ca1375124..ce27ad22a 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -325,6 +325,7 @@ static ID3D12RootSignature *d3d12_runner_create_root_signature(struct d3d12_shad sampler_desc->AddressU = sampler->u_address; sampler_desc->AddressV = sampler->v_address; sampler_desc->AddressW = sampler->w_address; + sampler_desc->ComparisonFunc = sampler->func; sampler_desc->MaxLOD = FLT_MAX; sampler_desc->ShaderRegister = sampler->slot; sampler_desc->RegisterSpace = 0; diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index 6cec33a43..fa6289540 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -785,6 +785,31 @@ static GLuint compile_graphics_shader_program(struct gl_runner *runner, ID3D10Bl return program_id; }
+static unsigned int gl_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op) +{ + switch (op) + { + case D3D12_COMPARISON_FUNC_NEVER: + return GL_NEVER; + case D3D12_COMPARISON_FUNC_LESS: + return GL_LESS; + case D3D12_COMPARISON_FUNC_EQUAL: + return GL_EQUAL; + case D3D12_COMPARISON_FUNC_LESS_EQUAL: + return GL_LEQUAL; + case D3D12_COMPARISON_FUNC_GREATER: + return GL_GREATER; + case D3D12_COMPARISON_FUNC_NOT_EQUAL: + return GL_NOTEQUAL; + case D3D12_COMPARISON_FUNC_GREATER_EQUAL: + return GL_GEQUAL; + case D3D12_COMPARISON_FUNC_ALWAYS: + return GL_ALWAYS; + default: + fatal_error("Unhandled compare op %#x.\n", op); + } +} + static bool gl_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY topology, unsigned int vertex_count) { @@ -837,6 +862,11 @@ static bool gl_runner_draw(struct shader_runner *r, glSamplerParameteri(id, GL_TEXTURE_WRAP_R, get_texture_wrap_gl(sampler->w_address)); glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, get_texture_filter_mag_gl(sampler->filter)); glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, get_texture_filter_min_gl(sampler->filter)); + if (sampler->func) + { + glSamplerParameteri(id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glSamplerParameteri(id, GL_TEXTURE_COMPARE_FUNC, gl_compare_op_from_d3d12(sampler->func)); + } sampler_info[i].id = id; }
diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 35db729b5..f266030ed 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -810,6 +810,31 @@ static VkSamplerAddressMode vk_address_mode_from_d3d12(D3D12_TEXTURE_ADDRESS_MOD } }
+static enum VkCompareOp vk_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op) +{ + switch (op) + { + case D3D12_COMPARISON_FUNC_NEVER: + return VK_COMPARE_OP_NEVER; + case D3D12_COMPARISON_FUNC_LESS: + return VK_COMPARE_OP_LESS; + case D3D12_COMPARISON_FUNC_EQUAL: + return VK_COMPARE_OP_EQUAL; + case D3D12_COMPARISON_FUNC_LESS_EQUAL: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case D3D12_COMPARISON_FUNC_GREATER: + return VK_COMPARE_OP_GREATER; + case D3D12_COMPARISON_FUNC_NOT_EQUAL: + return VK_COMPARE_OP_NOT_EQUAL; + case D3D12_COMPARISON_FUNC_GREATER_EQUAL: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + case D3D12_COMPARISON_FUNC_ALWAYS: + return VK_COMPARE_OP_ALWAYS; + default: + fatal_error("Unhandled compare op %#x.\n", op); + } +} + static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_runner *runner) { VkDescriptorSetLayoutCreateInfo set_desc = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; @@ -874,6 +899,8 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r sampler_desc.addressModeU = vk_address_mode_from_d3d12(sampler->u_address); sampler_desc.addressModeV = vk_address_mode_from_d3d12(sampler->v_address); sampler_desc.addressModeW = vk_address_mode_from_d3d12(sampler->w_address); + sampler_desc.compareEnable = !!sampler->func; + sampler_desc.compareOp = sampler->func ? vk_compare_op_from_d3d12(sampler->func) : 0; sampler_desc.maxLod = FLT_MAX;
VK_CALL(vkCreateSampler(runner->device, &sampler_desc, NULL, &vulkan_sampler->vk_sampler));