tests/hlsl: Add tests for GetSamplePosition() and GetSampleCount().

This commit is contained in:
Conor McCarthy 2024-04-10 13:51:06 +10:00 committed by Alexandre Julliard
parent 1d6c3eae78
commit 696fc12061
Notes: Alexandre Julliard 2024-04-17 23:29:12 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/734
9 changed files with 188 additions and 34 deletions

View File

@ -115,6 +115,7 @@ vkd3d_shader_tests = \
tests/hlsl/fxgroup-syntax.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 \
@ -171,6 +172,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 \

View File

@ -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 = max(sample_count, 1);
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,

View File

@ -0,0 +1,19 @@
[require]
shader model >= 4.1
[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)

View File

@ -0,0 +1,34 @@
[require]
shader model >= 4.1
[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)

View File

@ -513,6 +513,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);
@ -604,6 +608,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)
@ -622,10 +627,28 @@ struct resource *shader_runner_get_resource(struct shader_runner *runner, enum r
return NULL;
}
static void set_resource(struct shader_runner *runner, struct resource *resource)
static void set_resource(struct shader_runner *runner, const struct resource_params *params)
{
struct resource *resource;
size_t i;
if (!(resource = runner->ops->create_resource(runner, params)))
{
if (!bitmap_is_set(runner->failed_resources[params->type], params->slot))
{
++runner->failed_resource_count;
bitmap_set(runner->failed_resources[params->type], params->slot);
}
return;
}
if (bitmap_is_set(runner->failed_resources[params->type], params->slot))
{
assert(runner->failed_resource_count);
--runner->failed_resource_count;
bitmap_clear(runner->failed_resources[params->type], params->slot);
}
for (i = 0; i < runner->resource_count; ++i)
{
if (runner->resources[i]->slot == resource->slot && runner->resources[i]->type == resource->type)
@ -838,7 +861,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
params.height = RENDER_TARGET_HEIGHT;
params.level_count = 1;
set_resource(runner, runner->ops->create_resource(runner, &params));
set_resource(runner, &params);
}
for (i = 0; i < runner->input_element_count; ++i)
@ -861,7 +884,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
params.data = malloc(sizeof(quad));
memcpy(params.data, quad, sizeof(quad));
params.data_size = sizeof(quad);
set_resource(runner, runner->ops->create_resource(runner, &params));
set_resource(runner, &params);
free(params.data);
if (!runner->vs_source)
@ -891,7 +914,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
params.height = RENDER_TARGET_HEIGHT;
params.level_count = 1;
set_resource(runner, runner->ops->create_resource(runner, &params));
set_resource(runner, &params);
}
if (match_string(line, "triangle list", &line))
@ -1574,7 +1597,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
* textures with data type other than float). */
if (!skip_tests)
{
set_resource(runner, runner->ops->create_resource(runner, &current_resource));
set_resource(runner, &current_resource);
}
free(current_resource.data);
break;
@ -1922,7 +1945,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
case STATE_TEST:
/* Compilation which fails with dxcompiler is not 'todo', therefore the tests are
* not 'todo' either. They cannot run, so skip them entirely. */
if (!skip_tests && SUCCEEDED(expect_hr))
if (!runner->failed_resource_count && !skip_tests && SUCCEEDED(expect_hr))
parse_test_directive(runner, line);
break;
}

View File

@ -96,6 +96,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;
};
@ -110,6 +111,7 @@ struct resource
unsigned int size;
unsigned int texel_size;
unsigned int width, height;
unsigned int sample_count;
};
struct input_element
@ -174,6 +176,8 @@ struct shader_runner
struct resource *resources[MAX_RESOURCES];
size_t resource_count;
uint32_t failed_resources[RESOURCE_TYPE_VERTEX_BUFFER + 1][(MAX_RESOURCES + 0x1f) / 0x20];
unsigned int failed_resource_count;
struct sampler samplers[MAX_SAMPLERS];
size_t sampler_count;

View File

@ -355,23 +355,37 @@ static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags
return buffer;
}
static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_resource *resource,
static bool init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_resource *resource,
const struct resource_params *params)
{
D3D11_SUBRESOURCE_DATA resource_data[3];
ID3D11Device *device = runner->device;
D3D11_TEXTURE2D_DESC desc = {0};
UINT quality_levels;
HRESULT hr;
if (params->level_count > ARRAY_SIZE(resource_data))
fatal_error("Level count %u is too high.\n", params->level_count);
if (params->sample_count > 1)
{
if (params->level_count > 1)
fatal_error("Multisampled texture has multiple levels.\n");
if (FAILED(ID3D11Device_CheckMultisampleQualityLevels(device,
params->format, params->sample_count, &quality_levels)) || !quality_levels)
{
trace("Format #%x with sample count %u is not supported; skipping.\n", params->format, params->sample_count);
return false;
}
}
desc.Width = params->width;
desc.Height = params->height;
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 +398,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 a multisampled texture.\n");
for (unsigned int level = 0; level < params->level_count; ++level)
{
unsigned int level_width = get_level_dimension(params->width, level);
@ -410,6 +427,8 @@ static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re
else
hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv);
ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr);
return true;
}
static void init_resource_srv_buffer(struct d3d11_shader_runner *runner, struct d3d11_resource *resource,
@ -465,15 +484,15 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
case RESOURCE_TYPE_TEXTURE:
if (params->dimension == RESOURCE_DIMENSION_BUFFER)
init_resource_srv_buffer(runner, resource, params);
else
init_resource_2d(runner, resource, params);
else if (!init_resource_2d(runner, resource, params))
return NULL;
break;
case RESOURCE_TYPE_UAV:
if (params->dimension == RESOURCE_DIMENSION_BUFFER)
init_resource_uav_buffer(runner, resource, params);
else
init_resource_2d(runner, resource, params);
else if (!init_resource_2d(runner, resource, params))
return NULL;
break;
case RESOURCE_TYPE_VERTEX_BUFFER:
@ -774,12 +793,15 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade
{
struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
struct d3d11_resource_readback *rb = malloc(sizeof(*rb));
ID3D11Resource *resolved_resource = NULL, *src_resource;
struct d3d11_resource *resource = d3d11_resource(res);
D3D11_TEXTURE2D_DESC texture_desc;
D3D11_MAPPED_SUBRESOURCE map_desc;
D3D11_BUFFER_DESC buffer_desc;
bool is_ms = false;
HRESULT hr;
src_resource = resource->resource;
switch (resource->r.type)
{
case RESOURCE_TYPE_RENDER_TARGET:
@ -797,12 +819,25 @@ 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;
texture_desc.MiscFlags = 0;
hr = ID3D11Device_CreateTexture2D(runner->device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->resource);
ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
if (is_ms)
{
texture_desc.Usage = D3D11_USAGE_DEFAULT;
hr = ID3D11Device_CreateTexture2D(runner->device, &texture_desc, NULL,
(ID3D11Texture2D **)&resolved_resource);
ok(hr == S_OK, "Failed to create multisampled texture, hr %#lx.\n", hr);
ID3D11DeviceContext_ResolveSubresource(runner->immediate_context, resolved_resource, 0,
resource->resource, 0, texture_desc.Format);
src_resource = resolved_resource;
}
}
break;
@ -814,10 +849,13 @@ 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
ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, resource->resource);
ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, src_resource);
hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &map_desc);
ok(hr == S_OK, "Failed to map texture, hr %#lx.\n", hr);
if (resolved_resource)
ID3D11Resource_Release(resolved_resource);
rb->rb.data = map_desc.pData;
rb->rb.row_pitch = map_desc.RowPitch;
rb->rb.width = resource->r.width;

View File

@ -135,9 +135,12 @@ 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);
if (params->sample_count > 1 && params->level_count > 1)
fatal_error("Multisampled texture has multiple levels.\n");
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);
resource->resource = create_default_texture_(__LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
params->width, params->height, 1, params->level_count, params->sample_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 +172,26 @@ 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 > 1 && params->level_count > 1)
fatal_error("Multisampled texture has multiple levels.\n");
resource->resource = create_default_texture_(__LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
params->width, params->height, 1, params->level_count, params->sample_count, params->format,
/* Multisampled textures must have ALLOW_RENDER_TARGET set. */
(params->sample_count > 1) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET : 0,
D3D12_RESOURCE_STATE_COPY_DEST);
if (params->data)
{
if (params->sample_count > 1)
fatal_error("Cannot upload data to a multisampled texture.\n");
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));
}
@ -440,7 +456,7 @@ 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;
unsigned int uniform_index, sample_count;
unsigned int rtv_count = 0;
ID3D12PipelineState *pso;
bool succeeded;
@ -483,7 +499,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]);
@ -492,6 +508,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;
}
}
@ -513,7 +531,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.SampleDesc.Count = 1;
pso_desc.SampleDesc.Count = sample_count;
pso_desc.SampleMask = ~(UINT)0;
pso_desc.pRootSignature = test_context->root_signature;

View File

@ -112,6 +112,7 @@ static bool check_gl_extensions(struct gl_runner *runner)
"GL_ARB_sampler_objects",
"GL_ARB_shader_image_load_store",
"GL_ARB_texture_storage",
"GL_ARB_internalformat_query",
};
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
@ -347,11 +348,24 @@ static const struct format_info *get_format_info(enum DXGI_FORMAT format, bool i
fatal_error("Failed to find format info for format %#x.\n", format);
}
static void init_resource_2d(struct gl_resource *resource, const struct resource_params *params)
static bool init_resource_2d(struct gl_resource *resource, const struct resource_params *params)
{
unsigned int offset, w, h, i;
resource->format = get_format_info(params->format, params->is_shadow);
if (params->sample_count > 1)
{
GLint max_sample_count;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, resource->format->internal_format, GL_SAMPLES, 1, &max_sample_count);
if (max_sample_count < params->sample_count)
{
trace("Format #%x with sample count %u is not supported; skipping.\n", params->format, params->sample_count);
return false;
}
}
glGenTextures(1, &resource->id);
glBindTexture(GL_TEXTURE_2D, resource->id);
glTexStorage2D(GL_TEXTURE_2D, params->level_count,
@ -359,7 +373,7 @@ static void init_resource_2d(struct gl_resource *resource, const struct resource
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
if (!params->data)
return;
return true;
for (i = 0, offset = 0; i < params->level_count; ++i)
{
@ -369,6 +383,8 @@ static void init_resource_2d(struct gl_resource *resource, const struct resource
resource->format->type, params->data + offset);
offset += w * h * params->texel_size;
}
return true;
}
static void init_resource_buffer(struct gl_resource *resource, const struct resource_params *params)
@ -398,8 +414,8 @@ static struct resource *gl_runner_create_resource(struct shader_runner *r, const
case RESOURCE_TYPE_UAV:
if (params->dimension == RESOURCE_DIMENSION_BUFFER)
init_resource_buffer(resource, params);
else
init_resource_2d(resource, params);
else if (!init_resource_2d(resource, params))
return NULL;
break;
case RESOURCE_TYPE_VERTEX_BUFFER: