Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 05/11/21 19:35, Matteo Bruni wrote:
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com
v3: Add validation of filter directive, initialize current_sampler variable.
Makefile.am | 2 + tests/sampler.shader_test | 34 +++++++++ tests/shader_runner_d3d12.c | 141 ++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 tests/sampler.shader_test
diff --git a/Makefile.am b/Makefile.am index eaa4f816..d6e14cf1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,6 +90,7 @@ vkd3d_shader_tests = \ tests/preproc-invalid.shader_test \ tests/preproc-macro.shader_test \ tests/preproc-misc.shader_test \
- tests/sampler.shader_test \ tests/saturate.shader_test \ tests/swizzle-0.shader_test \ tests/swizzle-1.shader_test \
@@ -302,6 +303,7 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/math.shader_test \ tests/max.shader_test \
- tests/sampler.shader_test \ tests/texture-load.shader_test \ tests/texture-load-typed.shader_test \ tests/trigonometry.shader_test \
diff --git a/tests/sampler.shader_test b/tests/sampler.shader_test new file mode 100644 index 00000000..3970fb51 --- /dev/null +++ b/tests/sampler.shader_test @@ -0,0 +1,34 @@ +[sampler 0] +filter linear linear linear +address clamp clamp clamp
+[texture 0] +size (2, 2) +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Sample(s, float2(0.5, 0.5));
+}
+[test] +draw quad +probe all rgba (0.25, 0, 0.25, 0)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Sample(s, float2(0.5, 0.5));
+}
+[test] +draw quad +probe all rgba (0.25, 0, 0.25, 0) diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 20d1ad6a..8dd95dce 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -80,6 +80,14 @@ enum texture_data_type TEXTURE_DATA_UINT, };
+struct sampler +{
- unsigned int slot;
- D3D12_FILTER filter;
- D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address;
+};
- struct texture { unsigned int slot;
@@ -108,6 +116,9 @@ struct shader_context
struct texture *textures; size_t texture_count;
struct sampler *samplers;
size_t sampler_count; };
static ID3D10Blob *compile_shader(const char *source, const char *target)
@@ -139,6 +150,7 @@ enum parse_state STATE_NONE, STATE_PREPROC, STATE_PREPROC_INVALID,
- STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_PIXEL, STATE_TEXTURE,
@@ -195,6 +207,74 @@ static void parse_texture_format(struct texture *texture, const char *line) texture->texel_size = 16; }
+static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest) +{
- if (match_string(line, "border", rest))
return D3D12_TEXTURE_ADDRESS_MODE_BORDER;
- if (match_string(line, "clamp", rest))
return D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- if (match_string(line, "mirror_once", rest))
return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
- if (match_string(line, "mirror", rest))
return D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
- if (match_string(line, "wrap", rest))
return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
- fprintf(stderr, "Malformed address mode '%s'.\n", line);
- return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
+}
+static void parse_sampler_directive(struct sampler *sampler, const char *line) +{
- const char *const orig_line = line;
- if (match_string(line, "address", &line))
- {
sampler->u_address = parse_sampler_address_mode(line, &line);
sampler->v_address = parse_sampler_address_mode(line, &line);
sampler->w_address = parse_sampler_address_mode(line, &line);
- }
- else if (match_string(line, "filter", &line))
- {
static const struct
{
const char *string;
D3D12_FILTER filter;
}
filters[] =
{
{"point point point", D3D12_FILTER_MIN_MAG_MIP_POINT},
{"point point linear", D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR},
{"point linear point", D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT},
{"point linear linear", D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR},
{"linear point point", D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT},
{"linear point linear", D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR},
{"linear linear point", D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT},
{"linear linear linear", D3D12_FILTER_MIN_MAG_MIP_LINEAR},
};
unsigned int i;
for (i = 0; i < ARRAY_SIZE(filters); ++i)
{
if (match_string(line, filters[i].string, &line))
{
sampler->filter = filters[i].filter;
break;
}
}
if (i == ARRAY_SIZE(filters))
goto err;
- }
- else
- {
goto err;
- }
- return;
+err:
- fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line);
+}
- static void parse_texture_directive(struct texture *texture, const char *line) { const char *const orig_line = line;
@@ -266,6 +346,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin ID3D12GraphicsCommandList *command_list = context->c.list; D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0}; D3D12_ROOT_PARAMETER root_params[3], *root_param;
D3D12_STATIC_SAMPLER_DESC static_samplers[1]; static const float clear_color[4]; unsigned int uniform_index; ID3D12PipelineState *pso;
@@ -274,6 +355,8 @@ static void parse_test_directive(struct shader_context *context, const char *lin
root_signature_desc.NumParameters = 0; root_signature_desc.pParameters = root_params;
root_signature_desc.NumStaticSamplers = 0;
root_signature_desc.pStaticSamplers = static_samplers; if (context->uniform_count) {
@@ -324,6 +407,21 @@ static void parse_test_directive(struct shader_context *context, const char *lin
assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
for (i = 0; i < context->sampler_count; ++i)
{
D3D12_STATIC_SAMPLER_DESC *sampler_desc = &static_samplers[root_signature_desc.NumStaticSamplers++];
const struct sampler *sampler = &context->samplers[i];
memset(sampler_desc, 0, sizeof(*sampler_desc));
sampler_desc->Filter = sampler->filter;
sampler_desc->AddressU = sampler->u_address;
sampler_desc->AddressV = sampler->v_address;
sampler_desc->AddressW = sampler->w_address;
sampler_desc->ShaderRegister = sampler->slot;
sampler_desc->RegisterSpace = 0;
sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
}
if (context->c.root_signature) ID3D12RootSignature_Release(context->c.root_signature); hr = create_root_signature(context->c.device, &root_signature_desc, &context->c.root_signature);
@@ -486,6 +584,22 @@ err: fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line); }
+static struct sampler *get_sampler(struct shader_context *context, unsigned int slot) +{
- struct sampler *sampler;
- size_t i;
- for (i = 0; i < context->sampler_count; ++i)
- {
sampler = &context->samplers[i];
if (sampler->slot == slot)
return sampler;
- }
- return NULL;
+}
- static struct texture *get_texture(struct shader_context *context, unsigned int slot) { struct texture *texture;
@@ -511,6 +625,7 @@ START_TEST(shader_runner_d3d12) .rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT, }; size_t shader_source_size = 0, shader_source_len = 0;
- struct sampler *current_sampler = NULL; struct texture *current_texture = NULL; enum parse_state state = STATE_NONE; unsigned int i, line_number = 0;
@@ -559,6 +674,7 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE:
case STATE_SAMPLER: case STATE_TEST: case STATE_TEXTURE: break;
@@ -663,6 +779,27 @@ START_TEST(shader_runner_d3d12) { state = STATE_SHADER_INVALID_PIXEL; }
else if (sscanf(line, "[sampler %u]\n", &index))
{
state = STATE_SAMPLER;
if ((current_sampler = get_sampler(&context, index)))
{
memset(current_sampler, 0, sizeof(*current_sampler));
}
else
{
context.samplers = realloc(context.samplers,
++context.sampler_count * sizeof(*context.samplers));
current_sampler = &context.samplers[context.sampler_count - 1];
memset(current_sampler, 0, sizeof(*current_sampler));
}
current_sampler->slot = index;
current_sampler->filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
current_sampler->u_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
current_sampler->v_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
current_sampler->w_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
} else if (sscanf(line, "[texture %u]\n", &index)) { state = STATE_TEXTURE;
@@ -719,6 +856,10 @@ START_TEST(shader_runner_d3d12) break; }
case STATE_SAMPLER:
parse_sampler_directive(current_sampler, line);
break;
case STATE_TEXTURE: parse_texture_directive(current_texture, line); break;