From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 2 + tests/d3d12_test_utils.h | 10 ++--- tests/hlsl/get-sample-pos.shader_test | 20 +++++++++ tests/hlsl/rt-get-sample-info.shader_test | 35 ++++++++++++++++ tests/shader_runner.c | 16 ++++++-- tests/shader_runner.h | 4 ++ tests/shader_runner_d3d11.c | 16 +++++++- tests/shader_runner_d3d12.c | 50 +++++++++++++++++------ tests/shader_runner_gl.c | 9 ++++ tests/shader_runner_vulkan.c | 2 + 10 files changed, 143 insertions(+), 21 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..890f79d68 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -582,8 +582,8 @@ 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 depth_or_array_size, unsigned int miplevel_count, unsigned int sample_count, + DXGI_FORMAT format, 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,7 @@ 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, 1, format, flags, 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 +627,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, 1, format, 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..5c4743d47 --- /dev/null +++ b/tests/hlsl/get-sample-pos.shader_test @@ -0,0 +1,20 @@ +[require] +shader model >= 4.1 +rgba float 4xmsaa + + +[srv 0] +format r32g32b32a32 float +size (2dms, 4, 2, 2) + +[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..f0a0e67a5 --- /dev/null +++ b/tests/hlsl/rt-get-sample-info.shader_test @@ -0,0 +1,35 @@ +[require] +shader model >= 4.1 +rgba float 4xmsaa + + +[rtv 0] +format r32g32b32a32 float +size (2dms, 4, 640, 480) + +[pixel shader todo] +float4 main() : sv_target +{ + return float4(GetRenderTargetSampleCount(), 0, 0, 0); +} + +[test] +todo draw quad +probe all rgba (4.0, 0.0, 0.0, 0.0) + + +[pixel shader todo] +uniform uint u; + +float4 main() : sv_target +{ + return float4(GetRenderTargetSamplePosition(u), GetRenderTargetSamplePosition(u + 1)); +} + +[test] +uniform 0 uint 0 +todo draw quad +probe all rgba (-0.125, -0.375, 0.375, -0.125) +uniform 0 uint 2 +todo draw quad +probe all rgba (-0.375, 0.125, 0.125, 0.375) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 5eafbcbe4..b9ac8f83f 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -332,6 +332,10 @@ static void parse_require_directive(struct shader_runner *runner, const char *li { runner->require_rov = true; } + else if (match_string(line, "rgba float 4xmsaa", &line)) + { + runner->require_rgba_float_4xmsaa = true; + } else { fatal_error("Unknown require directive '%s'.\n", line); @@ -508,6 +512,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 +607,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) @@ -1496,9 +1505,10 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c dxc_compiler ? "dxcompiler" : HLSL_COMPILER, caps->runner); if (caps->tag_count) trace_tags(caps); - trace(" float64: %u.\n", caps->float64); - trace(" int64: %u.\n", caps->int64); - trace(" rov: %u.\n", caps->rov); + trace(" float64: %u.\n", caps->float64); + trace(" int64: %u.\n", caps->int64); + trace(" rov: %u.\n", caps->rov); + trace("rgba float 4xmsaa: %u.\n", caps->rgba_float_4xmsaa);
if (!test_options.filename) fatal_error("No filename specified.\n"); diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 2f7e8fb25..a4eea7916 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 @@ -132,6 +134,7 @@ struct shader_runner_caps bool float64; bool int64; bool rov; + bool rgba_float_4xmsaa; };
static inline unsigned int shader_runner_caps_get_feature_flags(const struct shader_runner_caps *caps) @@ -162,6 +165,7 @@ struct shader_runner bool require_float64; bool require_int64; bool require_rov; + bool require_rgba_float_4xmsaa;
bool last_render_failed;
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 1285ca41f..e1ef4a9ee 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -258,6 +258,7 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) D3D11_FEATURE_DATA_DOUBLES doubles = {0}; unsigned int rt_width, rt_height; D3D11_RASTERIZER_DESC rs_desc; + UINT quality_levels; D3D11_VIEWPORT vp; HRESULT hr; RECT rect; @@ -284,6 +285,9 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) ok(hr == S_OK, "Got hr %#lx.\n", hr); runner->caps.rov = options2.ROVsSupported;
+ runner->caps.rgba_float_4xmsaa = SUCCEEDED(ID3D11Device_CheckMultisampleQualityLevels(runner->device, + DXGI_FORMAT_R32G32B32A32_FLOAT, 4, &quality_levels)) && quality_levels; + rt_width = RENDER_TARGET_WIDTH; rt_height = RENDER_TARGET_HEIGHT; SetRect(&rect, 0, 0, rt_width, rt_height); @@ -371,7 +375,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 +388,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); @@ -723,6 +730,7 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade D3D11_TEXTURE2D_DESC texture_desc; D3D11_MAPPED_SUBRESOURCE map_desc; D3D11_BUFFER_DESC buffer_desc; + bool is_ms = false; HRESULT hr;
switch (resource->r.type) @@ -742,6 +750,9 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade else { ID3D11Texture2D_GetDesc(resource->texture, &texture_desc); + is_ms = texture_desc.SampleDesc.Count > 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; texture_desc.Usage = D3D11_USAGE_STAGING; texture_desc.BindFlags = 0; texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; @@ -758,6 +769,9 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade
if (resource->is_uav_counter) ID3D11DeviceContext_CopyStructureCount(runner->immediate_context, (ID3D11Buffer *)rb->resource, 0, resource->uav); + else if (is_ms) + ID3D11DeviceContext_ResolveSubresource(runner->immediate_context, rb->resource, 0, + resource->resource, 0, texture_desc.Format); else ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, resource->resource); hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &map_desc); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 9bf7bb248..c0444728d 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -136,8 +136,19 @@ 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_texture_(__LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D, + params->width, params->height, 1, 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 +180,25 @@ 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"); + /* Multisampled textures must have ALLOW_RENDER_TARGET set. */ + resource->resource = create_default_texture_(__LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D, + params->width, params->height, 1, 1, params->sample_count, params->format, + D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, 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 +462,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 +488,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 +497,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 +509,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;
@@ -635,6 +660,7 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner) runner->caps.float64 = options.DoublePrecisionFloatShaderOps; runner->caps.int64 = options1.Int64ShaderOps; runner->caps.rov = options.ROVsSupported; + runner->caps.rgba_float_4xmsaa = true; }
void run_shader_tests_d3d12(void *dxc_compiler) diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index e56eccab0..6e1b6950c 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -157,6 +157,8 @@ static bool check_egl_client_extension(const char *extension)
static bool gl_runner_init(struct gl_runner *runner, enum shading_language language) { + PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ; + GLint tex_max_sample_count, rt_max_sample_count; PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT; const char *glsl_version = NULL; EGLDeviceEXT *devices; @@ -263,6 +265,13 @@ static bool gl_runner_init(struct gl_runner *runner, enum shading_language langu runner->caps.minimum_shader_model = SHADER_MODEL_4_0; runner->caps.maximum_shader_model = SHADER_MODEL_5_1;
+ if ((glGetInternalformativ = (void *)eglGetProcAddress("glGetInternalformativ"))) + { + glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA32F, GL_SAMPLES, 1, &tex_max_sample_count); + glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA32F, GL_SAMPLES, 1, &rt_max_sample_count); + runner->caps.rgba_float_4xmsaa = tex_max_sample_count >= 4 && rt_max_sample_count >= 4; + } + trace("Using device %u.\n", i); runner->display = display; runner->context = context; diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index a3bbf170c..8aaf98215 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -1544,6 +1544,8 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) runner->caps.rov = false; }
+ runner->caps.rgba_float_4xmsaa = true; + vr = VK_CALL(vkCreateDevice(runner->phys_device, &device_desc, NULL, &device)); free(enabled_extensions.names); if (vr)