diff --git a/tests/hlsl/tessellation.shader_test b/tests/hlsl/tessellation.shader_test index 6993398a..f34bf703 100644 --- a/tests/hlsl/tessellation.shader_test +++ b/tests/hlsl/tessellation.shader_test @@ -132,3 +132,176 @@ void main(InputPatch input) [test] if(!llvmpipe) todo(sm<6) draw 3 control point patch list 3 if(!llvmpipe) todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0) + +[require] +shader model >= 5.0 +shader model < 5.1 + +[hull shader dxbc-tpf-hex] +% As above, but with some DCL_INDEXRANGE instructions that skip a signature +% element (i.e., it has "dcl_indexrange o0.z 3" at some point, but o1.z does +% not exist). This must be kept in compiled form rather than source code +% because we want to test a specific quirk of the code generated by the native +% d3dcompiler. It should be converted to assembly as soon as that's available, +% though. + +% struct data +% { +% float4 position : SV_Position; +% float r : RED; +% float g : GREEN; +% float b : BLUE; +% }; +% +% struct patch_constant_data +% { +% float edges[3] : SV_TessFactor; +% float inside : SV_InsideTessFactor; +% float2 x : X; +% float1 y : Y; +% float2 z : Z; +% }; +% +% void patch_constant(InputPatch input, out patch_constant_data output) +% { +% output.edges[0] = output.edges[1] = output.edges[2] = 1.0f; +% output.inside = 1.0f; +% output.x = 0.0f; +% output.y = 0.0f; +% output.z = 0.0f; +% } +% +% [domain("tri")] +% [outputcontrolpoints(3)] +% [partitioning("integer")] +% [outputtopology("triangle_cw")] +% [patchconstantfunc("patch_constant")] +% data main(InputPatch input, uint i : SV_OutputControlPointID) +% { +% return input[i]; +% } + +% hs_5_0 +% hs_decls +% dcl_input_control_point_count 3 +% dcl_output_control_point_count 3 +% dcl_tessellator_domain domain_tri +% dcl_tessellator_partitioning partitioning_integer +% dcl_tessellator_output_primitive output_triangle_cw +% dcl_globalFlags refactoringAllowed +% hs_fork_phase +% dcl_hs_fork_phase_instance_count 3 +% dcl_input vForkInstanceID +% dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor +% dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor +% dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor +% dcl_temps 1 +% dcl_indexrange o0.x 3 +% mov r0.x, vForkInstanceID.x +% mov o[r0.x + 0].x, l(1.000000) +% ret +% hs_fork_phase +% dcl_output_siv o3.x, finalTriInsideTessFactor +% mov o3.x, l(1.000000) +% ret +% hs_fork_phase +% dcl_hs_fork_phase_instance_count 3 +% dcl_input vForkInstanceID +% dcl_output o0.y +% dcl_output o1.y +% dcl_output o2.y +% dcl_temps 1 +% dcl_indexrange o0.y 3 +% mov r0.x, vForkInstanceID.x +% mov o[r0.x + 0].y, l(0) +% ret +% hs_fork_phase +% dcl_hs_fork_phase_instance_count 2 +% dcl_input vForkInstanceID +% dcl_output o0.z +% dcl_output o2.z +% dcl_temps 1 +% dcl_indexrange o0.z 3 +% ult r0.x, vForkInstanceID.x, l(1) +% movc r0.x, r0.x, l(0), l(2) +% mov o[r0.x + 0].z, l(0) +% ret + +44584243 3429d2d3 fb408d2b 2fd030cc 69cd5a0b 01000000 3c050000 06000000 +38000000 b0000000 3c010000 c8010000 a8020000 a0040000 52444546 70000000 +00000000 00000000 00000000 3c000000 00055348 00010000 3c000000 52443131 +3c000000 18000000 20000000 28000000 24000000 0c000000 00000000 4d696372 +6f736f66 74202852 2920484c 534c2053 68616465 7220436f 6d70696c 65722031 +302e302e 31303031 312e3136 33383400 4953474e 84000000 04000000 08000000 +68000000 00000000 01000000 03000000 00000000 0f0f0000 74000000 00000000 +00000000 03000000 01000000 01010000 78000000 00000000 00000000 03000000 +01000000 02020000 7e000000 00000000 00000000 03000000 01000000 04040000 +53565f50 6f736974 696f6e00 52454400 47524545 4e00424c 554500ab 4f53474e +84000000 04000000 08000000 68000000 00000000 01000000 03000000 00000000 +0f000000 74000000 00000000 00000000 03000000 01000000 010e0000 78000000 +00000000 00000000 03000000 01000000 020d0000 7e000000 00000000 00000000 +03000000 01000000 040b0000 53565f50 6f736974 696f6e00 52454400 47524545 +4e00424c 554500ab 50435347 d8000000 07000000 08000000 b0000000 00000000 +0d000000 03000000 00000000 010e0000 be000000 00000000 00000000 03000000 +00000000 06090000 b0000000 01000000 0d000000 03000000 01000000 010e0000 +c0000000 00000000 00000000 03000000 01000000 020d0000 b0000000 02000000 +0d000000 03000000 02000000 010e0000 c2000000 00000000 00000000 03000000 +02000000 06090000 c4000000 00000000 0e000000 03000000 03000000 010e0000 +53565f54 65737346 6163746f 72005800 59005a00 53565f49 6e736964 65546573 +73466163 746f7200 53484558 f0010000 50000300 7c000000 71000001 93180001 +94180001 95100001 96080001 97180001 6a080001 73000001 99000002 03000000 +5f000002 00700100 67000004 12201000 00000000 11000000 67000004 12201000 +01000000 12000000 67000004 12201000 02000000 13000000 68000002 01000000 +5b000004 12201000 00000000 03000000 36000004 12001000 00000000 0a700100 +36000006 12209000 0a001000 00000000 01400000 0000803f 3e000001 73000001 +67000004 12201000 03000000 14000000 36000005 12201000 03000000 01400000 +0000803f 3e000001 73000001 99000002 03000000 5f000002 00700100 65000003 +22201000 00000000 65000003 22201000 01000000 65000003 22201000 02000000 +68000002 01000000 5b000004 22201000 00000000 03000000 36000004 12001000 +00000000 0a700100 36000006 22209000 0a001000 00000000 01400000 00000000 +3e000001 73000001 99000002 02000000 5f000002 00700100 65000003 42201000 +00000000 65000003 42201000 02000000 68000002 01000000 5b000004 42201000 +00000000 03000000 4f000006 12001000 00000000 0a700100 01400000 01000000 +37000009 12001000 00000000 0a001000 00000000 01400000 00000000 01400000 +02000000 36000006 42209000 0a001000 00000000 01400000 00000000 3e000001 +53544154 94000000 0c000000 01000000 00000000 04000000 00000000 00000000 +01000000 04000000 00000000 00000000 00000000 00000000 00000000 00000000 +00000000 00000000 00000000 00000000 00000000 06000000 01000000 00000000 +00000000 0a000000 00000000 00000000 00000000 00000000 00000000 00000000 +03000000 03000000 01000000 02000000 00000000 00000000 00000000 + +[domain shader] +struct data +{ + float4 position : SV_Position; + float r : RED; + float g : GREEN; + float b : BLUE; +}; + +struct patch_constant_data +{ + float edges[3] : SV_TessFactor; + float inside : SV_InsideTessFactor; + float2 x : X; + float1 y : Y; + float2 z : Z; +}; + + [domain("tri")] +void main(patch_constant_data input, + float3 tess_coord : SV_DomainLocation, + const OutputPatch patch, + out data output) +{ + output.position = tess_coord.x * patch[0].position + + tess_coord.y * patch[1].position + + tess_coord.z * patch[2].position; + output.r = tess_coord.x * patch[0].r + tess_coord.y * patch[1].r + tess_coord.z * patch[2].r; + output.g = tess_coord.x * patch[0].g + tess_coord.y * patch[1].g + tess_coord.z * patch[2].g; + output.b = tess_coord.x * patch[0].b + tess_coord.y * patch[1].b + tess_coord.z * patch[2].b; +} + +[test] +todo draw 3 control point patch list 3 +todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index a8103c0c..8e5f5276 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -1643,13 +1643,58 @@ static HRESULT dxc_compiler_compile_shader(void *dxc_compiler, const char *profi return hr; } +static ID3D10Blob *parse_hex(const char *source) +{ + size_t len = strlen(source), i, pos = 0; + unsigned char *ptr, value = 0; + bool even = false; + ID3D10Blob *blob; + + ptr = malloc(len / 2); + + for (i = 0; i < len; ++i) + { + char c = source[i]; + + if (isspace(c)) + continue; + + if ('0' <= c && c <= '9') + value = 16 * value + (c - '0'); + else if ('a' <= c && c <= 'f') + value = 16 * value + (c - 'a' + 10); + else if ('A' <= c && c <= 'F') + value = 16 * value + (c - 'A' + 10); + else + fatal_error("Invalid hex character '%c'\n", c); + + if (even) + { + ptr[pos++] = value; + value = 0; + } + + even = !even; + } + + if (even) + fatal_error("Odd number of hex characters.\n"); + + D3DCreateBlob(pos, &blob); + if (pos) + memcpy(ID3D10Blob_GetBufferPointer(blob), ptr, pos); + free(ptr); + + return blob; +} + ID3D10Blob *compile_hlsl(const struct shader_runner *runner, enum shader_type type) { const char *source = runner->shader_source[type]; unsigned int options = runner->compile_options; ID3D10Blob *blob = NULL, *errors = NULL; + HRESULT hr = S_OK; char profile[7]; - HRESULT hr; static const char *const shader_models[] = { @@ -1672,16 +1717,45 @@ ID3D10Blob *compile_hlsl(const struct shader_runner *runner, enum shader_type ty sprintf(profile, "%s_%s", shader_type_string(type), shader_models[runner->minimum_shader_model]); - if (runner->minimum_shader_model >= SHADER_MODEL_6_0) + switch (runner->shader_format[type]) { - assert(runner->dxc_compiler); - hr = dxc_compiler_compile_shader(runner->dxc_compiler, profile, options, - runner->require_shader_caps[SHADER_CAP_NATIVE_16_BIT], source, &blob); - } - else - { - hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, options, 0, &blob, &errors); + case SOURCE_FORMAT_HLSL: + if (runner->minimum_shader_model >= SHADER_MODEL_6_0) + { + assert(runner->dxc_compiler); + hr = dxc_compiler_compile_shader(runner->dxc_compiler, profile, options, + runner->require_shader_caps[SHADER_CAP_NATIVE_16_BIT], source, &blob); + } + else + { + hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, options, 0, &blob, &errors); + } + break; + + case SOURCE_FORMAT_D3DBC_HEX: + if (runner->maximum_shader_model >= SHADER_MODEL_4_0) + fatal_error("Cannot use d3dbc-hex with maximum shader model %#x.\n", runner->maximum_shader_model); + blob = parse_hex(source); + hr = S_OK; + break; + + case SOURCE_FORMAT_DXBC_TPF_HEX: + if (runner->minimum_shader_model < SHADER_MODEL_4_0) + fatal_error("Cannot use dxbc-tpf-hex with minimum shader model %#x.\n", runner->minimum_shader_model); + if (runner->maximum_shader_model >= SHADER_MODEL_6_0) + fatal_error("Cannot use dxbc-tpf-hex with maximum shader model %#x.\n", runner->maximum_shader_model); + blob = parse_hex(source); + hr = S_OK; + break; + + case SOURCE_FORMAT_DXBC_DXIL_HEX: + if (runner->minimum_shader_model < SHADER_MODEL_6_0) + fatal_error("Cannot use dxbc-dxil-hex with minimum shader model %#x.\n", runner->minimum_shader_model); + blob = parse_hex(source); + hr = S_OK; + break; } + if (hr != S_OK) { todo_if (runner->is_todo) @@ -1725,6 +1799,17 @@ static void compile_shader(struct shader_runner *runner, const char *source, [SHADER_MODEL_5_0] = "5_0", }; + switch (runner->shader_format[type]) + { + case SOURCE_FORMAT_HLSL: + break; + + case SOURCE_FORMAT_D3DBC_HEX: + case SOURCE_FORMAT_DXBC_TPF_HEX: + case SOURCE_FORMAT_DXBC_DXIL_HEX: + return; + } + /* We can let this go through D3DCompile() with the invalid shader model * string, but it returns a unique error code. Just skip it. */ if (model < SHADER_MODEL_4_0 && type != SHADER_TYPE_VS && type != SHADER_TYPE_PS && type != SHADER_TYPE_FX) @@ -1775,7 +1860,8 @@ static void compile_shader(struct shader_runner *runner, const char *source, } } -static void read_shader_directive(struct shader_runner *runner, const char *line, const char *src) +static void read_shader_directive(struct shader_runner *runner, const char *line, + const char *src, enum shader_type shader_type) { for (unsigned int i = SHADER_MODEL_MIN; i <= SHADER_MODEL_MAX; ++i) { @@ -1783,6 +1869,8 @@ static void read_shader_directive(struct shader_runner *runner, const char *line runner->hlsl_todo[i] = false; } + runner->shader_format[shader_type] = SOURCE_FORMAT_HLSL; + while (*src && *src != ']') { uint32_t model_mask; @@ -1815,6 +1903,18 @@ static void read_shader_directive(struct shader_runner *runner, const char *line runner->hlsl_hrs[i] = E_NOTIMPL; } } + else if (match_string(src, "d3dbc-hex", &src)) + { + runner->shader_format[shader_type] = SOURCE_FORMAT_D3DBC_HEX; + } + else if (match_string(src, "dxbc-tpf-hex", &src)) + { + runner->shader_format[shader_type] = SOURCE_FORMAT_DXBC_TPF_HEX; + } + else if (match_string(src, "dxbc-dxil-hex", &src)) + { + runner->shader_format[shader_type] = SOURCE_FORMAT_DXBC_DXIL_HEX; + } else { fatal_error("Malformed line '%s'.\n", line); @@ -2340,7 +2440,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c } if (state == STATE_SHADER) - read_shader_directive(runner, line_buffer, line); + read_shader_directive(runner, line_buffer, line, shader_type); } else if (line[0] != '%' && line[0] != '\n') { diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 03259c8d..aed946cc 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -188,6 +188,14 @@ enum fog_mode FOG_MODE_DISABLE, }; +enum source_format +{ + SOURCE_FORMAT_HLSL, + SOURCE_FORMAT_D3DBC_HEX, + SOURCE_FORMAT_DXBC_TPF_HEX, + SOURCE_FORMAT_DXBC_DXIL_HEX, +}; + struct shader_runner { const struct shader_runner_ops *ops; @@ -199,6 +207,7 @@ struct shader_runner HRESULT hlsl_hrs[SHADER_MODEL_MAX + 1]; char *shader_source[SHADER_TYPE_COUNT]; + enum source_format shader_format[SHADER_TYPE_COUNT]; enum shader_model minimum_shader_model; enum shader_model maximum_shader_model; bool require_shader_caps[SHADER_CAP_COUNT]; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 9346cb47..e46e1869 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -787,11 +787,11 @@ static bool d3d12_runner_draw(struct shader_runner *r, succeeded = succeeded && gs_code; } - todo_if(runner->r.is_todo && runner->r.minimum_shader_model < SHADER_MODEL_6_0) - ok(succeeded, "Failed to compile shaders.\n"); - if (!succeeded) { + todo_if(runner->r.is_todo && runner->r.minimum_shader_model < SHADER_MODEL_6_0) + ok(false, "Failed to compile shaders.\n"); + if (ps_code) ID3D10Blob_Release(ps_code); if (vs_code) diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 1fe1a3dd..c99ca4ba 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -329,9 +329,8 @@ static bool compile_hlsl_and_scan(struct vulkan_shader_runner *runner, enum shad runner->signatures[type].type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO; runner->signatures[type].next = NULL; ret = vkd3d_shader_scan(&info, NULL); - ok(!ret, "Failed to scan, error %d.\n", ret); - return true; + return ret >= 0; } static bool compile_d3d_code(struct vulkan_shader_runner *runner,