Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v3: tests: Add some tests for matrix packing compiler options. tests: Add test file syntax to specify compiler options. vkd3d-shader: Add compiler option to specify matrix majority.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- include/vkd3d_shader.h | 17 +++++++++++++++++ libs/vkd3d-shader/hlsl.c | 21 ++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 6c17a07b..77e6f53a 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -139,6 +139,14 @@ enum vkd3d_shader_compile_option_formatting_flags VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FORMATTING_FLAGS), };
+enum vkd3d_shader_compile_option_pack_matrix_order +{ + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR = 0x00000001, + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR = 0x00000002, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER), +}; + enum vkd3d_shader_compile_option_name { /** @@ -169,6 +177,15 @@ enum vkd3d_shader_compile_option_name * \since 1.7 */ VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE = 0x00000006, + /** + * This option specifies default matrix packing order. It's only supported for HLSL source type. + * Explicit variable modifiers or pragmas will take precedence. + * + * \a value is a member of enum vkd3d_shader_compile_option_pack_matrix_order. + * + * \since 1.9 + */ + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER = 0x00000007,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 4e9af15c..e33c8edd 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3212,9 +3212,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } }
-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, +static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) { + unsigned int i; + memset(ctx, 0, sizeof(*ctx));
ctx->profile = profile; @@ -3223,7 +3225,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name,
if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) return false; - if (!(ctx->source_files[0] = hlsl_strdup(ctx, source_name ? source_name : "<anonymous>"))) + if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : "<anonymous>"))) { vkd3d_free(ctx->source_files); return false; @@ -3262,6 +3264,19 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, return false; ctx->cur_buffer = ctx->globals_buffer;
+ for (i = 0; i < compile_info->option_count; ++i) + { + const struct vkd3d_shader_compile_option *option = &compile_info->options[i]; + + if (option->name == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER) + { + if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR) + ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR; + else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR) + ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR; + } + } + return true; }
@@ -3337,7 +3352,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_INVALID_ARGUMENT; }
- if (!hlsl_ctx_init(&ctx, compile_info->source_name, profile, message_context)) + if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) return VKD3D_ERROR_OUT_OF_MEMORY;
if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/shader_runner.c | 25 +++++++++++++++++++++++-- tests/shader_runner.h | 2 ++ tests/shader_runner_d3d11.c | 12 ++++++------ tests/shader_runner_d3d12.c | 2 +- tests/shader_runner_d3d9.c | 10 +++++----- 5 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 89137355..0691453b 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -111,6 +111,8 @@ static bool match_string(const char *line, const char *token, const char **const
static void parse_require_directive(struct shader_runner *runner, const char *line) { + unsigned int i; + if (match_string(line, "shader model >=", &line)) { static const char *const model_strings[] = @@ -122,7 +124,6 @@ static void parse_require_directive(struct shader_runner *runner, const char *li [SHADER_MODEL_5_0] = "5.0", [SHADER_MODEL_5_1] = "5.1", }; - unsigned int i;
for (i = 0; i < ARRAY_SIZE(model_strings); ++i) { @@ -135,6 +136,26 @@ static void parse_require_directive(struct shader_runner *runner, const char *li
fatal_error("Unknown shader model '%s'.\n", line); } + else if (match_string(line, "options:", &line)) + { + static const struct option + { + unsigned int option; + const char *name; + } + pack_options[] = + { + { D3DCOMPILE_PACK_MATRIX_ROW_MAJOR, "row-major" }, + { D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, "column-major" }, + }; + + runner->compile_options = 0; + for (i = 0; i < ARRAY_SIZE(pack_options); ++i) + { + if (match_string(line, pack_options[i].name, &line)) + runner->compile_options |= pack_options[i].option; + } + } else { fatal_error("Unknown require directive '%s'.\n", line); @@ -766,7 +787,7 @@ static void compile_shader(struct shader_runner *runner, const char *source, siz };
sprintf(profile, "%s_%s", type, shader_models[runner->minimum_shader_model]); - hr = D3DCompile(source, len, NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors); + hr = D3DCompile(source, len, NULL, NULL, NULL, "main", profile, runner->compile_options, 0, &blob, &errors); hr = map_unidentified_hrs(hr); ok(hr == expect, "Got unexpected hr %#x.\n", hr); if (hr == S_OK) diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 7a2498f4..0844943d 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -123,6 +123,8 @@ struct shader_runner
struct input_element *input_elements; size_t input_element_count, input_element_capacity; + + unsigned int compile_options; };
struct shader_runner_ops diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 3907e785..25b585b1 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -72,7 +72,7 @@ static struct d3d11_shader_runner *d3d11_shader_runner(struct shader_runner *r) return CONTAINING_RECORD(r, struct d3d11_shader_runner, r); }
-static ID3D10Blob *compile_shader(const char *source, const char *type, enum shader_model shader_model) +static ID3D10Blob *compile_shader(const struct d3d11_shader_runner *runner, const char *source, const char *type) { ID3D10Blob *blob = NULL, *errors = NULL; char profile[7]; @@ -88,8 +88,8 @@ static ID3D10Blob *compile_shader(const char *source, const char *type, enum sha [SHADER_MODEL_5_1] = "5_1", };
- sprintf(profile, "%s_%s", type, shader_models[shader_model]); - hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors); + sprintf(profile, "%s_%s", type, shader_models[runner->r.minimum_shader_model]); + hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, runner->r.compile_options, 0, &blob, &errors); ok(hr == S_OK, "Failed to compile shader, hr %#lx.\n", hr); if (errors) { @@ -475,7 +475,7 @@ static bool d3d11_runner_dispatch(struct shader_runner *r, unsigned int x, unsig HRESULT hr; size_t i;
- if (!(cs_code = compile_shader(runner->r.cs_source, "cs", runner->r.minimum_shader_model))) + if (!(cs_code = compile_shader(runner, runner->r.cs_source, "cs"))) return false;
hr = ID3D11Device_CreateComputeShader(device, ID3D10Blob_GetBufferPointer(cs_code), @@ -548,10 +548,10 @@ static bool d3d11_runner_draw(struct shader_runner *r, unsigned int i; HRESULT hr;
- if (!(vs_code = compile_shader(runner->r.vs_source, "vs", runner->r.minimum_shader_model))) + if (!(vs_code = compile_shader(runner, runner->r.vs_source, "vs"))) return false;
- if (!(ps_code = compile_shader(runner->r.ps_source, "ps", runner->r.minimum_shader_model))) + if (!(ps_code = compile_shader(runner, runner->r.ps_source, "ps"))) { ID3D10Blob_Release(vs_code); return false; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 6765c5ce..c5ee0cd2 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -73,7 +73,7 @@ static ID3D10Blob *compile_shader(const struct d3d12_shader_runner *runner, cons };
sprintf(profile, "%s_%s", type, shader_models[runner->r.minimum_shader_model]); - hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors); + hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, runner->r.compile_options, 0, &blob, &errors); ok(FAILED(hr) == !blob, "Got unexpected hr %#x, blob %p.\n", hr, blob); if (errors) { diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 15a5ab3e..0c6d3788 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -56,7 +56,7 @@ static struct d3d9_shader_runner *d3d9_shader_runner(struct shader_runner *r)
static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT sdk_version);
-static ID3D10Blob *compile_shader(const char *source, const char *type, enum shader_model shader_model) +static ID3D10Blob *compile_shader(const struct d3d9_shader_runner *runner, const char *source, const char *type) { ID3D10Blob *blob = NULL, *errors = NULL; char profile[7]; @@ -68,8 +68,8 @@ static ID3D10Blob *compile_shader(const char *source, const char *type, enum sha [SHADER_MODEL_3_0] = "3_0", };
- sprintf(profile, "%s_%s", type, shader_models[shader_model]); - hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors); + sprintf(profile, "%s_%s", type, shader_models[runner->r.minimum_shader_model]); + hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, runner->r.compile_options, 0, &blob, &errors); ok(hr == S_OK, "Failed to compile shader, hr %#lx.\n", hr); if (errors) { @@ -334,10 +334,10 @@ static bool d3d9_runner_draw(struct shader_runner *r, unsigned int i, j; HRESULT hr;
- if (!(vs_code = compile_shader(runner->r.vs_source, "vs", runner->r.minimum_shader_model))) + if (!(vs_code = compile_shader(runner, runner->r.vs_source, "vs"))) return false;
- if (!(ps_code = compile_shader(runner->r.ps_source, "ps", runner->r.minimum_shader_model))) + if (!(ps_code = compile_shader(runner, runner->r.ps_source, "ps"))) { ID3D10Blob_Release(vs_code); return false;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/hlsl/majority-pragma.shader_test | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+)
diff --git a/tests/hlsl/majority-pragma.shader_test b/tests/hlsl/majority-pragma.shader_test index 10778fd0..6fa39415 100644 --- a/tests/hlsl/majority-pragma.shader_test +++ b/tests/hlsl/majority-pragma.shader_test @@ -223,3 +223,89 @@ uniform 8 float4 0.0 0.5 0.0 0.0 uniform 12 float4 0.0 0.6 0.0 0.0 draw quad probe all rgba (0.3, 0.4, 0.5, 0.6) + +% Compiler options +[require] +options: row-major + +[pixel shader] +#pragma pack_matrix(column_major) +uniform float2x2 m; + +float4 main() : sv_target +{ + float4 ret; + ret.xy = m[0]; + ret.zw = m[1]; + return ret; +} + +[test] +uniform 0 float4 0.1 0.2 0.0 0.0 +uniform 4 float4 0.3 0.4 0.0 0.0 +draw quad +probe all rgba (0.1, 0.3, 0.2, 0.4) 1 + +[require] +options: column-major + +[pixel shader] +uniform float2x2 m; + +float4 main() : sv_target +{ + float4 ret; + ret.xy = m[0]; + ret.zw = m[1]; + return ret; +} + +[test] +uniform 0 float4 0.1 0.2 0.0 0.0 +uniform 4 float4 0.3 0.4 0.0 0.0 +draw quad +probe all rgba (0.1, 0.3, 0.2, 0.4) 1 + +[require] +options: column-major + +[pixel shader] +uniform float2x2 m1; +#pragma pack_matrix(row_major) +uniform float2x2 m2; + +float4 main() : sv_target +{ + float4 ret; + ret.xy = m1[0]; + ret.zw = m2[0]; + return ret; +} + +[test] +uniform 0 float4 0.1 0.2 0.0 0.0 +uniform 4 float4 0.3 0.4 0.0 0.0 +uniform 8 float4 0.5 0.6 0.0 0.0 +uniform 12 float4 0.7 0.8 0.0 0.0 +draw quad +probe all rgba (0.1, 0.3, 0.5, 0.6) 1 + +[require] +options: column-major row-major + +[pixel shader] +uniform float2x2 m; + +float4 main() : sv_target +{ + float4 ret; + ret.xy = m[0]; + ret.zw = m[1]; + return ret; +} + +[test] +uniform 0 float4 0.1 0.2 0.0 0.0 +uniform 4 float4 0.3 0.4 0.0 0.0 +draw quad +probe all rgba (0.1, 0.3, 0.2, 0.4) 1
Now with some tests, please take a look.
The test syntax looks fine, thanks. It'll still need to be hooked up to the Vulkan runner, and the tests currently pass independently of the flags.
On Windows it does affect results. I'll see what's going on Linux/vulkan.