From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 2 + tests/d3d12_test_utils.h | 17 +++++++-- tests/hlsl/get-sample-pos.shader_test | 21 +++++++++++ tests/hlsl/rt-get-sample-info.shader_test | 45 ++++++++++++++++++++++ tests/shader_runner.c | 5 +++ tests/shader_runner.h | 2 + tests/shader_runner_d3d11.c | 5 ++- tests/shader_runner_d3d12.c | 46 +++++++++++++++++------ 8 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 tests/hlsl/get-sample-pos.shader_test create mode 100644 tests/hlsl/rt-get-sample-info.shader_test
diff --git a/Makefile.am b/Makefile.am index 68e8642e0..7b6fb8914 100644 --- a/Makefile.am +++ b/Makefile.am @@ -112,6 +112,7 @@ vkd3d_shader_tests = \ tests/hlsl/fwidth.shader_test \ tests/hlsl/gather-offset.shader_test \ tests/hlsl/gather.shader_test \ + tests/hlsl/get-sample-pos.shader_test \ tests/hlsl/getdimensions.shader_test \ tests/hlsl/half.shader_test \ tests/hlsl/hard-copy-prop.shader_test \ @@ -167,6 +168,7 @@ vkd3d_shader_tests = \ tests/hlsl/return-implicit-conversion.shader_test \ tests/hlsl/return.shader_test \ tests/hlsl/round.shader_test \ + tests/hlsl/rt-get-sample-info.shader_test \ tests/hlsl/sample-bias.shader_test \ tests/hlsl/sample-cmp.shader_test \ tests/hlsl/sample-grad.shader_test \ diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index 4fe6fa716..59eb586ec 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -583,7 +583,7 @@ static inline ID3D12Resource *create_default_buffer_(unsigned int line, ID3D12De static ID3D12Resource *create_default_texture_(unsigned int line, ID3D12Device *device, D3D12_RESOURCE_DIMENSION dimension, unsigned int width, unsigned int height, unsigned int depth_or_array_size, unsigned int miplevel_count, DXGI_FORMAT format, - D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) + unsigned int sample_count, D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) { D3D12_HEAP_PROPERTIES heap_properties; D3D12_RESOURCE_DESC resource_desc; @@ -602,7 +602,7 @@ static ID3D12Resource *create_default_texture_(unsigned int line, ID3D12Device * resource_desc.DepthOrArraySize = depth_or_array_size; resource_desc.MipLevels = miplevel_count; resource_desc.Format = format; - resource_desc.SampleDesc.Count = 1; + resource_desc.SampleDesc.Count = sample_count + !sample_count; resource_desc.Flags = flags; hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc, initial_state, NULL, &IID_ID3D12Resource, (void **)&texture); @@ -618,7 +618,16 @@ static inline ID3D12Resource *create_default_texture2d_(unsigned int line, ID3D1 DXGI_FORMAT format, D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) { return create_default_texture_(line, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D, - width, height, array_size, miplevel_count, format, flags, initial_state); + width, height, array_size, miplevel_count, format, 1, flags, initial_state); +} + +#define create_default_texture2dms(a, b, c, d, e, f, g, h) create_default_texture2dms_(__LINE__, a, b, c, d, e, f, g, h) +static inline ID3D12Resource *create_default_texture2dms_(unsigned int line, ID3D12Device *device, + unsigned int width, unsigned int height, unsigned int array_size, unsigned int sample_count, + DXGI_FORMAT format, D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) +{ + return create_default_texture_(line, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D, width, height, array_size, 1, + format, sample_count, flags | D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, initial_state); }
#define create_default_texture3d(a, b, c, d, e, f, g, h) create_default_texture3d_(__LINE__, a, b, c, d, e, f, g, h) @@ -627,7 +636,7 @@ static inline ID3D12Resource *create_default_texture3d_(unsigned int line, ID3D1 DXGI_FORMAT format, D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) { return create_default_texture_(line, device, D3D12_RESOURCE_DIMENSION_TEXTURE3D, - width, height, depth, miplevel_count, format, flags, initial_state); + width, height, depth, miplevel_count, format, 1, flags, initial_state); }
static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src, diff --git a/tests/hlsl/get-sample-pos.shader_test b/tests/hlsl/get-sample-pos.shader_test new file mode 100644 index 000000000..c3bdb6e5d --- /dev/null +++ b/tests/hlsl/get-sample-pos.shader_test @@ -0,0 +1,21 @@ +[require] +shader model >= 4.1 + + +[srv 0] +% r32g32b32a32 is not necessarily supported with 4x MSAA. +format r32 float +size (2dms, 4, 2, 2) +% Data upload is not supported. + +[pixel shader todo] +Texture2DMS<float4, 2> t; + +float4 main() : sv_target +{ + return float4(t.GetSamplePosition(0), t.GetSamplePosition(1)); +} + +[test] +todo draw quad +probe all rgba (-0.125, -0.375, 0.375, -0.125) diff --git a/tests/hlsl/rt-get-sample-info.shader_test b/tests/hlsl/rt-get-sample-info.shader_test new file mode 100644 index 000000000..d5180e583 --- /dev/null +++ b/tests/hlsl/rt-get-sample-info.shader_test @@ -0,0 +1,45 @@ +[require] +% 4.1 supports GetRenderTargetSamplePosition/Count but not UAVs, and returning +% results in the RTV brings complications in D3D11. +shader model >= 5.0 + + +[rtv 0] +% r32g32b32a32 is not necessarily supported with 4x MSAA. +format r32 float +size (2dms, 4, 640, 480) + +[uav 1] +format r32g32b32a32 float +size (buffer, 2) +0 0 0 0 +0 0 0 0 + +[pixel shader todo] +RWBuffer<float4> u : register(u1); + +float4 main() : sv_target +{ + u[0] = float4(GetRenderTargetSampleCount(), 0, 0, 0); + return 0.0; +} + +[test] +todo draw quad +probe uav 1 (0) r (4.0) + + +[pixel shader todo] +RWBuffer<float4> u : register(u1); + +float4 main() : sv_target +{ + u[0] = float4(GetRenderTargetSamplePosition(0), GetRenderTargetSamplePosition(1)); + u[1] = float4(GetRenderTargetSamplePosition(2), GetRenderTargetSamplePosition(3)); + return 0.0; +} + +[test] +todo draw quad +probe uav 1 (0) rgba (-0.125, -0.375, 0.375, -0.125) +probe uav 1 (1) rgba (-0.375, 0.125, 0.125, 0.375) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 5eafbcbe4..33f9fdc26 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -508,6 +508,10 @@ static void parse_resource_directive(struct resource_params *resource, const cha { resource->dimension = RESOURCE_DIMENSION_2D; } + else if (sscanf(line, "( 2dms , %u , %u , %u ) ", &resource->sample_count, &resource->width, &resource->height) == 3) + { + resource->dimension = RESOURCE_DIMENSION_2D; + } else { fatal_error("Malformed resource size '%s'.\n", line); @@ -599,6 +603,7 @@ void init_resource(struct resource *resource, const struct resource_params *para resource->texel_size = params->texel_size; resource->width = params->width; resource->height = params->height; + resource->sample_count = params->sample_count; }
struct resource *shader_runner_get_resource(struct shader_runner *runner, enum resource_type type, unsigned int slot) diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 2f7e8fb25..ddfcb5fbc 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -94,6 +94,7 @@ struct resource_params unsigned int stride; unsigned int width, height; unsigned int level_count; + unsigned int sample_count; uint8_t *data; size_t data_size, data_capacity; }; @@ -108,6 +109,7 @@ struct resource unsigned int size; unsigned int texel_size; unsigned int width, height; + unsigned int sample_count; };
struct input_element diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 1285ca41f..825cb04c6 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -371,7 +371,7 @@ static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re desc.MipLevels = params->level_count; desc.ArraySize = 1; desc.Format = params->format; - desc.SampleDesc.Count = 1; + desc.SampleDesc.Count = max(params->sample_count, 1); desc.Usage = D3D11_USAGE_DEFAULT; if (params->type == RESOURCE_TYPE_UAV) desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; @@ -384,6 +384,9 @@ static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re { unsigned int buffer_offset = 0;
+ if (params->sample_count > 1) + fatal_error("Cannot upload data to an MSAA texture.\n"); + for (unsigned int level = 0; level < params->level_count; ++level) { unsigned int level_width = get_level_dimension(params->width, level); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 9bf7bb248..570d6c546 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -136,8 +136,18 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co if (params->slot >= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT) fatal_error("RTV slot %u is too high.\n", params->slot);
- resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, - params->format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET); + if (params->sample_count) + { + if (params->level_count > 1) + fatal_error("Multisample resource has multiple levels.\n"); + resource->resource = create_default_texture2dms(device, params->width, params->height, 1, params->sample_count, + params->format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET); + } + else + { + resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, + params->format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET); + } ID3D12Device_CreateRenderTargetView(device, resource->resource, NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot)); break; @@ -169,13 +179,23 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co } else { - resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, - params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); - upload_texture_data_with_states(resource->resource, resource_data, - params->level_count, test_context->queue, test_context->list, - RESOURCE_STATE_DO_NOT_CHANGE, - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - reset_command_list(test_context->list, test_context->allocator); + if (params->sample_count) + { + if (params->level_count > 1) + fatal_error("Multisample resource has multiple levels.\n"); + resource->resource = create_default_texture2dms(device, params->width, params->height, 1, params->sample_count, + params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); + } + else + { + resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, + params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); + upload_texture_data_with_states(resource->resource, resource_data, + params->level_count, test_context->queue, test_context->list, + RESOURCE_STATE_DO_NOT_CHANGE, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + reset_command_list(test_context->list, test_context->allocator); + } ID3D12Device_CreateShaderResourceView(device, resource->resource, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); } @@ -439,8 +459,8 @@ static bool d3d12_runner_draw(struct shader_runner *r, ID3D12CommandQueue *queue = test_context->queue; D3D12_INPUT_ELEMENT_DESC *input_element_descs; ID3D12Device *device = test_context->device; + unsigned int uniform_index, sample_count; ID3D10Blob *vs_code, *ps_code; - unsigned int uniform_index; unsigned int rtv_count = 0; ID3D12PipelineState *pso; HRESULT hr; @@ -465,7 +485,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, test_context->root_signature = d3d12_runner_create_root_signature(runner, queue, test_context->allocator, command_list, &uniform_index);
- for (i = 0; i < runner->r.resource_count; ++i) + for (i = 0, sample_count = 1; i < runner->r.resource_count; ++i) { struct d3d12_resource *resource = d3d12_resource(runner->r.resources[i]);
@@ -474,6 +494,8 @@ static bool d3d12_runner_draw(struct shader_runner *r, pso_desc.RTVFormats[resource->r.slot] = resource->r.format; pso_desc.NumRenderTargets = max(pso_desc.NumRenderTargets, resource->r.slot + 1); pso_desc.BlendState.RenderTarget[resource->r.slot].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + if (resource->r.sample_count) + sample_count = resource->r.sample_count; } }
@@ -484,7 +506,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, pso_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; pso_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - pso_desc.SampleDesc.Count = 1; + pso_desc.SampleDesc.Count = sample_count; pso_desc.SampleMask = ~(UINT)0; pso_desc.pRootSignature = test_context->root_signature;