tests/hlsl: Add a test for SV_RenderTargetArrayIndex.

This commit is contained in:
Conor McCarthy 2024-05-01 12:31:06 +10:00 committed by Henri Verbeet
parent d049ea640f
commit a557ad0aea
Notes: Henri Verbeet 2025-01-27 15:04:43 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Giovanni Mascellani (@giomasce)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1356
11 changed files with 268 additions and 102 deletions

View File

@ -212,6 +212,7 @@ vkd3d_shader_tests = \
tests/hlsl/return-implicit-conversion.shader_test \
tests/hlsl/return.shader_test \
tests/hlsl/round.shader_test \
tests/hlsl/rt-array-index.shader_test \
tests/hlsl/rt-format-mismatch.shader_test \
tests/hlsl/rt-get-sample-info.shader_test \
tests/hlsl/sample-bias.shader_test \

View File

@ -0,0 +1,50 @@
[require]
shader model >= 4.0
rt-vp-array-index
[rtv 0]
format r32g32b32a32-float
size (2darray, 640, 480, 4)
[vertex shader]
uint layer_offset;
void main(float4 position : POSITION,
out float4 out_position : SV_POSITION,
out uint layer : SV_RenderTargetArrayIndex)
{
out_position = position;
layer = layer_offset;
}
[pixel shader]
uint layer_offset;
uint draw_id;
float4 main(in float4 pos : SV_Position,
in uint layer : SV_RenderTargetArrayIndex) : SV_Target
{
return float4(layer, draw_id, 0, 0);
}
[test]
uniform 0 uint 0
uniform 1 uint 0
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm>=6 | glsl) draw quad
probe (320, 240, 0) rgba(0.0, 0.0, 0.0, 0.0)
probe (320, 240, 1) rgba(1.0, 1.0, 1.0, 1.0)
uniform 0 uint 1
uniform 1 uint 1
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm>=6 | glsl) draw quad
probe (320, 240, 0) rgba(1.0, 1.0, 1.0, 1.0)
probe (320, 240, 1) rgba(1.0, 1.0, 0.0, 0.0)
uniform 0 uint 3
uniform 1 uint 2
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm>=6 | glsl) draw quad
probe (320, 240, 0) rgba(1.0, 1.0, 1.0, 1.0)
probe (320, 240, 3) rgba(3.0, 2.0, 0.0, 0.0)

View File

@ -350,15 +350,16 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t
static const char *const shader_cap_strings[] =
{
[SHADER_CAP_CLIP_PLANES] = "clip-planes",
[SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds",
[SHADER_CAP_FLOAT64] = "float64",
[SHADER_CAP_FOG] = "fog",
[SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader",
[SHADER_CAP_INT64] = "int64",
[SHADER_CAP_POINT_SIZE] = "point-size",
[SHADER_CAP_ROV] = "rov",
[SHADER_CAP_WAVE_OPS] = "wave-ops",
[SHADER_CAP_CLIP_PLANES] = "clip-planes",
[SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds",
[SHADER_CAP_FLOAT64] = "float64",
[SHADER_CAP_FOG] = "fog",
[SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader",
[SHADER_CAP_INT64] = "int64",
[SHADER_CAP_POINT_SIZE] = "point-size",
[SHADER_CAP_ROV] = "rov",
[SHADER_CAP_RT_VP_ARRAY_INDEX] = "rt-vp-array-index",
[SHADER_CAP_WAVE_OPS] = "wave-ops",
};
static bool match_shader_cap_string(const char *line, enum shader_cap *cap)
@ -570,17 +571,20 @@ static void parse_resource_directive(struct resource_params *resource, const cha
{
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
resource->desc.height = 1;
resource->desc.depth = 1;
}
else if (sscanf(line, "( raw_buffer , %u ) ", &resource->desc.width) == 1)
{
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
resource->desc.height = 1;
resource->desc.depth = 1;
resource->is_raw = true;
}
else if (sscanf(line, "( counter_buffer , %u ) ", &resource->desc.width) == 1)
{
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
resource->desc.height = 1;
resource->desc.depth = 1;
resource->is_uav_counter = true;
resource->stride = sizeof(uint32_t);
resource->desc.texel_size = resource->stride;
@ -591,9 +595,16 @@ static void parse_resource_directive(struct resource_params *resource, const cha
else if (sscanf(line, "( 2d , %u , %u ) ", &resource->desc.width, &resource->desc.height) == 2)
{
resource->desc.dimension = RESOURCE_DIMENSION_2D;
resource->desc.depth = 1;
}
else if (sscanf(line, "( 2dms , %u , %u , %u ) ",
&resource->desc.sample_count, &resource->desc.width, &resource->desc.height) == 3)
{
resource->desc.dimension = RESOURCE_DIMENSION_2D;
resource->desc.depth = 1;
}
else if (sscanf(line, "( 2darray , %u , %u , %u ) ", &resource->desc.width, &resource->desc.height,
&resource->desc.depth) == 3)
{
resource->desc.dimension = RESOURCE_DIMENSION_2D;
}
@ -642,6 +653,9 @@ static void parse_resource_directive(struct resource_params *resource, const cha
if (rest == line)
break;
if (resource->desc.depth > 1)
fatal_error("Upload not implemented for 2d arrays.\n");
vkd3d_array_reserve((void **)&resource->data, &resource->data_capacity, resource->data_size + sizeof(u), 1);
memcpy(resource->data + resource->data_size, &u, sizeof(u));
resource->data_size += sizeof(u);
@ -754,6 +768,7 @@ static void set_default_target(struct shader_runner *runner)
params.desc.texel_size = 16;
params.desc.width = RENDER_TARGET_WIDTH;
params.desc.height = RENDER_TARGET_HEIGHT;
params.desc.depth = 1;
params.desc.level_count = 1;
set_resource(runner, &params);
@ -1124,7 +1139,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
}
else if (match_string(line, "probe", &line))
{
unsigned int left, top, right, bottom, ulps, slot;
unsigned int left, top, right, bottom, ulps, slot, array_layer = 0;
struct resource_readback *rb;
struct resource *resource;
bool is_signed = false;
@ -1163,13 +1178,16 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
resource = shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0);
}
rb = runner->ops->get_resource_readback(runner, resource);
if (sscanf(line, " ( %d , %d , %d , %d )%n", &left, &top, &right, &bottom, &len) == 4)
{
set_rect(&rect, left, top, right, bottom);
line += len;
}
else if (sscanf(line, " ( %u , %u , %u )%n", &left, &top, &array_layer, &len) == 3)
{
set_rect(&rect, left, top, left + 1, top + 1);
line += len;
}
else if (sscanf(line, " ( %u , %u )%n", &left, &top, &len) == 2)
{
set_rect(&rect, left, top, left + 1, top + 1);
@ -1185,6 +1203,8 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
fatal_error("Malformed probe arguments '%s'.\n", line);
}
rb = runner->ops->get_resource_readback(runner, resource, array_layer * resource->desc.level_count);
if (match_string(line, "rgbaui", &line))
{
struct uvec4 v;

View File

@ -95,7 +95,7 @@ struct resource_desc
DXGI_FORMAT format;
unsigned int texel_size;
unsigned int width, height;
unsigned int width, height, depth;
unsigned int level_count;
unsigned int sample_count;
};
@ -148,6 +148,7 @@ enum shader_cap
SHADER_CAP_INT64,
SHADER_CAP_POINT_SIZE,
SHADER_CAP_ROV,
SHADER_CAP_RT_VP_ARRAY_INDEX,
SHADER_CAP_WAVE_OPS,
SHADER_CAP_COUNT,
};
@ -251,7 +252,8 @@ struct shader_runner_ops
unsigned int instance_count);
bool (*copy)(struct shader_runner *runner, struct resource *src, struct resource *dst);
bool (*dispatch)(struct shader_runner *runner, unsigned int x, unsigned int y, unsigned int z);
struct resource_readback *(*get_resource_readback)(struct shader_runner *runner, struct resource *resource);
struct resource_readback *(*get_resource_readback)(struct shader_runner *runner,
struct resource *resource, unsigned int sub_resource_idx);
void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb);
};

View File

@ -260,6 +260,7 @@ static bool get_format_support(ID3D11Device *device, enum DXGI_FORMAT format)
static BOOL init_test_context(struct d3d11_shader_runner *runner)
{
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2 = {0};
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options3 = {0};
D3D11_FEATURE_DATA_DOUBLES doubles = {0};
unsigned int rt_width, rt_height;
D3D11_RASTERIZER_DESC rs_desc;
@ -309,7 +310,12 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner)
D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2));
ok(hr == S_OK, "Failed to check feature options2 support, hr %#lx.\n", hr);
hr = ID3D11Device_CheckFeatureSupport(runner->device,
D3D11_FEATURE_D3D11_OPTIONS3, &options3, sizeof(options3));
ok(hr == S_OK, "Failed to check feature options3 support, hr %#lx.\n", hr);
runner->caps.shader_caps[SHADER_CAP_ROV] = options2.ROVsSupported;
runner->caps.shader_caps[SHADER_CAP_RT_VP_ARRAY_INDEX] = options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer;
for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i)
{
runner->caps.format_caps[formats[i]] = get_format_support(runner->device, formats[i]);
@ -414,7 +420,7 @@ static bool init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re
desc.Width = params->desc.width;
desc.Height = params->desc.height;
desc.MipLevels = params->desc.level_count;
desc.ArraySize = 1;
desc.ArraySize = params->desc.depth;
desc.Format = params->desc.format;
desc.SampleDesc.Count = max(params->desc.sample_count, 1);
desc.Usage = D3D11_USAGE_DEFAULT;
@ -926,9 +932,11 @@ struct d3d11_resource_readback
{
struct resource_readback rb;
ID3D11Resource *resource;
unsigned int sub_resource_idx;
};
static struct resource_readback *d3d11_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
static struct resource_readback *d3d11_runner_get_resource_readback(struct shader_runner *r,
struct resource *res, unsigned int sub_resource_idx)
{
struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
struct d3d11_resource_readback *rb = malloc(sizeof(*rb));
@ -990,7 +998,8 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade
ID3D11DeviceContext_CopyStructureCount(runner->immediate_context, (ID3D11Buffer *)rb->resource, 0, resource->uav);
else
ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, src_resource);
hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &map_desc);
hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource,
sub_resource_idx, D3D11_MAP_READ, 0, &map_desc);
ok(hr == S_OK, "Failed to map texture, hr %#lx.\n", hr);
if (resolved_resource)
@ -1001,6 +1010,8 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade
rb->rb.width = resource->r.desc.width;
rb->rb.height = resource->r.desc.height;
rb->rb.depth = 1;
rb->sub_resource_idx = sub_resource_idx;
return &rb->rb;
}
@ -1009,7 +1020,7 @@ static void d3d11_runner_release_readback(struct shader_runner *r, struct resour
struct d3d11_resource_readback *d3d11_rb = CONTAINING_RECORD(rb, struct d3d11_resource_readback, rb);
struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
ID3D11DeviceContext_Unmap(runner->immediate_context, d3d11_rb->resource, 0);
ID3D11DeviceContext_Unmap(runner->immediate_context, d3d11_rb->resource, d3d11_rb->sub_resource_idx);
ID3D11Resource_Release(d3d11_rb->resource);
free(d3d11_rb);
}

View File

@ -120,8 +120,9 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
if (params->desc.sample_count > 1 && params->desc.level_count > 1)
fatal_error("Multisampled texture has multiple levels.\n");
resource->resource = create_default_texture_(__FILE__, __LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
params->desc.width, params->desc.height, 1, params->desc.level_count, params->desc.sample_count,
resource->resource = create_default_texture_(__FILE__, __LINE__, device,
D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height,
params->desc.depth, params->desc.level_count, params->desc.sample_count,
params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, initial_state);
ID3D12Device_CreateRenderTargetView(device, resource->resource,
NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.desc.slot));
@ -132,8 +133,8 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
runner->dsv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
resource->resource = create_default_texture2d(device, params->desc.width,
params->desc.height, 1, params->desc.level_count, params->desc.format,
D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, initial_state);
params->desc.height, params->desc.depth, params->desc.level_count,
params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, initial_state);
ID3D12Device_CreateDepthStencilView(device, resource->resource,
NULL, get_cpu_dsv_handle(test_context, runner->dsv_heap, 0));
break;
@ -170,8 +171,8 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
fatal_error("Multisampled texture has multiple levels.\n");
resource->resource = create_default_texture_(__FILE__, __LINE__, device,
D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height, 1,
params->desc.level_count, params->desc.sample_count, params->desc.format,
D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height,
params->desc.depth, params->desc.level_count, params->desc.sample_count, params->desc.format,
/* Multisampled textures must have ALLOW_RENDER_TARGET set. */
(params->desc.sample_count > 1) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET : 0, initial_state);
if (params->data)
@ -219,8 +220,8 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
else
{
resource->resource = create_default_texture2d(device, params->desc.width,
params->desc.height, 1, params->desc.level_count, params->desc.format,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, initial_state);
params->desc.height, params->desc.depth, params->desc.level_count,
params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, initial_state);
if (params->data)
{
upload_texture_data_with_states(resource->resource, resource_data, params->desc.level_count,
@ -930,7 +931,8 @@ static bool d3d12_runner_copy(struct shader_runner *r, struct resource *src, str
return true;
}
static struct resource_readback *d3d12_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
static struct resource_readback *d3d12_runner_get_resource_readback(struct shader_runner *r,
struct resource *res, unsigned int sub_resource_idx)
{
struct d3d12_shader_runner *runner = d3d12_shader_runner(r);
struct test_context *test_context = &runner->test_context;
@ -939,8 +941,8 @@ static struct resource_readback *d3d12_runner_get_resource_readback(struct shade
D3D12_RESOURCE_STATES state;
state = resource_get_state(res);
get_resource_readback_with_command_list_and_states(resource->resource, 0, rb,
test_context->queue, test_context->list, state, state);
get_resource_readback_with_command_list_and_states(resource->resource,
sub_resource_idx, rb, test_context->queue, test_context->list, state, state);
reset_command_list(test_context->list, test_context->allocator);
return &rb->rb;
@ -1033,6 +1035,8 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner,
runner->caps.shader_caps[SHADER_CAP_GEOMETRY_SHADER] = true;
runner->caps.shader_caps[SHADER_CAP_INT64] = options1.Int64ShaderOps;
runner->caps.shader_caps[SHADER_CAP_ROV] = options.ROVsSupported;
runner->caps.shader_caps[SHADER_CAP_RT_VP_ARRAY_INDEX]
= options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation;
runner->caps.shader_caps[SHADER_CAP_WAVE_OPS] = options1.WaveOps;
runner->caps.tag_count = 0;

View File

@ -584,7 +584,8 @@ struct d3d9_resource_readback
IDirect3DSurface9 *surface;
};
static struct resource_readback *d3d9_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
static struct resource_readback *d3d9_runner_get_resource_readback(struct shader_runner *r,
struct resource *res, unsigned int sub_resource_idx)
{
struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
struct d3d9_resource_readback *rb = malloc(sizeof(*rb));
@ -594,6 +595,8 @@ static struct resource_readback *d3d9_runner_get_resource_readback(struct shader
HRESULT hr;
assert(resource->r.desc.type == RESOURCE_TYPE_RENDER_TARGET);
if (sub_resource_idx)
fatal_error("Unsupported sub-resource index %u.\n", sub_resource_idx);
hr = IDirect3DSurface9_GetDesc(resource->surface, &desc);
ok(hr == D3D_OK, "Failed to get surface desc, hr %#lx.\n", hr);

View File

@ -58,6 +58,7 @@ struct gl_resource
const struct format_info *format;
GLuint id, tbo_id;
GLenum target;
};
static struct gl_resource *gl_resource(struct resource *r)
@ -97,20 +98,30 @@ static void debug_output(GLenum source, GLenum type, GLuint id, GLenum severity,
trace("%.*s\n", length, message);
}
static bool check_gl_extension(const char *extension, GLint extension_count)
static bool check_extension(GLenum name, const char *extension, GLint extension_count)
{
for (GLint i = 0; i < extension_count; ++i)
{
if (!strcmp(extension, (const char *)glGetStringi(GL_EXTENSIONS, i)))
if (!strcmp(extension, (const char *)glGetStringi(name, i)))
return true;
}
return false;
}
static bool check_gl_extension(const char *extension, GLint extension_count)
{
return check_extension(GL_EXTENSIONS, extension, extension_count);
}
static bool check_spirv_extension(const char *extension, GLint extension_count)
{
return check_extension(GL_SPIR_V_EXTENSIONS, extension, extension_count);
}
static bool check_gl_extensions(struct gl_runner *runner)
{
GLint count;
GLint count, spirv_count = 0;
static const char *required_extensions[] =
{
@ -126,8 +137,14 @@ static bool check_gl_extensions(struct gl_runner *runner)
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
if (runner->language == SPIR_V && !check_gl_extension("GL_ARB_gl_spirv", count))
return false;
if (runner->language == SPIR_V)
{
if (!check_gl_extension("GL_ARB_gl_spirv", count))
return false;
if (check_gl_extension("GL_ARB_spirv_extensions", count))
glGetIntegerv(GL_NUM_SPIR_V_EXTENSIONS, &spirv_count);
}
for (unsigned int i = 0; i < ARRAY_SIZE(required_extensions); ++i)
{
@ -139,6 +156,9 @@ static bool check_gl_extensions(struct gl_runner *runner)
runner->caps.shader_caps[SHADER_CAP_FLOAT64] = true;
if (check_gl_extension("GL_ARB_gpu_shader_int64", count))
runner->caps.shader_caps[SHADER_CAP_INT64] = true;
if (check_gl_extension("GL_ARB_shader_viewport_layer_array", count) && (runner->language == GLSL
|| check_spirv_extension("SPV_EXT_shader_viewport_index_layer", spirv_count)))
runner->caps.shader_caps[SHADER_CAP_RT_VP_ARRAY_INDEX] = true;
if (check_gl_extension("GL_EXT_depth_bounds_test", count))
runner->caps.shader_caps[SHADER_CAP_DEPTH_BOUNDS] = true;
@ -421,8 +441,16 @@ static void gl_runner_cleanup(struct gl_runner *runner)
static bool init_resource_2d(struct gl_resource *resource, const struct resource_params *params)
{
GLenum target = params->desc.sample_count > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
unsigned int offset, w, h, i;
GLenum target;
if (params->desc.sample_count > 1)
target = GL_TEXTURE_2D_MULTISAMPLE;
else if (params->desc.depth > 1)
target = GL_TEXTURE_2D_ARRAY;
else
target = GL_TEXTURE_2D;
resource->target = target;
resource->format = get_format_info(params->desc.format, params->is_shadow);
@ -447,8 +475,12 @@ static bool init_resource_2d(struct gl_resource *resource, const struct resource
}
else
{
glTexStorage2D(target, params->desc.level_count,
resource->format->internal_format, params->desc.width, params->desc.height);
if (params->desc.depth > 1)
glTexStorage3D(target, params->desc.level_count, resource->format->internal_format,
params->desc.width, params->desc.height, params->desc.depth);
else
glTexStorage2D(target, params->desc.level_count, resource->format->internal_format,
params->desc.width, params->desc.height);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
@ -469,15 +501,18 @@ static bool init_resource_2d(struct gl_resource *resource, const struct resource
static void init_resource_buffer(struct gl_resource *resource, const struct resource_params *params)
{
GLenum target = GL_TEXTURE_BUFFER;
resource->format = get_format_info(params->desc.format, false);
resource->target = target;
glGenBuffers(1, &resource->id);
glBindBuffer(GL_TEXTURE_BUFFER, resource->id);
glBufferData(GL_TEXTURE_BUFFER, params->data_size, params->data, GL_STATIC_DRAW);
glBindBuffer(target, resource->id);
glBufferData(target, params->data_size, params->data, GL_STATIC_DRAW);
glGenTextures(1, &resource->tbo_id);
glBindTexture(GL_TEXTURE_BUFFER, resource->tbo_id);
glTexBuffer(GL_TEXTURE_BUFFER, resource->format->internal_format, resource->id);
glBindTexture(target, resource->tbo_id);
glTexBuffer(target, resource->format->internal_format, resource->id);
}
static struct resource *gl_runner_create_resource(struct shader_runner *r, const struct resource_params *params)
@ -549,6 +584,7 @@ static bool compile_shader(struct gl_runner *runner, enum shader_type shader_typ
struct vkd3d_shader_scan_hull_shader_tessellation_info tessellation_info;
struct vkd3d_shader_spirv_domain_shader_target_info domain_info;
struct vkd3d_shader_combined_resource_sampler *sampler;
enum vkd3d_shader_spirv_extension spirv_extensions[1];
struct vkd3d_shader_resource_binding *binding;
struct vkd3d_shader_parameter parameters[1];
unsigned int count, i;
@ -620,6 +656,10 @@ static bool compile_shader(struct gl_runner *runner, enum shader_type shader_typ
info.next = &spirv_info;
spirv_info.next = &interface_info;
spirv_info.environment = VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5;
spirv_info.extensions = spirv_extensions;
spirv_info.extension_count = 0;
if (runner->caps.shader_caps[SHADER_CAP_RT_VP_ARRAY_INDEX])
spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_VIEWPORT_INDEX_LAYER;
}
else
{
@ -1159,11 +1199,9 @@ static bool gl_runner_draw(struct shader_runner *r,
glActiveTexture(GL_TEXTURE0 + s->binding.binding);
if (resource->desc.dimension == RESOURCE_DIMENSION_BUFFER)
glBindTexture(GL_TEXTURE_BUFFER, gl_resource(resource)->tbo_id);
else if (resource->desc.sample_count > 1)
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, gl_resource(resource)->id);
glBindTexture(gl_resource(resource)->target, gl_resource(resource)->tbo_id);
else
glBindTexture(GL_TEXTURE_2D, gl_resource(resource)->id);
glBindTexture(gl_resource(resource)->target, gl_resource(resource)->id);
if (s->sampler_index == VKD3D_SHADER_DUMMY_SAMPLER_INDEX)
continue;
@ -1306,19 +1344,16 @@ static bool gl_runner_copy(struct shader_runner *r, struct resource *src, struct
{
struct gl_resource *s = gl_resource(src);
struct gl_resource *d = gl_resource(dst);
GLenum target = GL_TEXTURE_2D;
unsigned int l, w, h;
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER)
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.depth > 1)
return false;
if (src->desc.sample_count > 1)
target = GL_TEXTURE_2D_MULTISAMPLE;
for (l = 0; l < src->desc.level_count; ++l)
{
w = get_level_dimension(src->desc.width, l);
h = get_level_dimension(src->desc.height, l);
glCopyImageSubData(s->id, target, l, 0, 0, 0, d->id, target, l, 0, 0, 0, w, h, 1);
glCopyImageSubData(s->id, s->target, l, 0, 0, 0, d->id, d->target, l, 0, 0, 0, w, h, 1);
}
return true;
@ -1329,11 +1364,14 @@ struct gl_resource_readback
struct resource_readback rb;
};
static struct resource_readback *gl_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
static struct resource_readback *gl_runner_get_resource_readback(struct shader_runner *r,
struct resource *res, unsigned int sub_resource_idx)
{
struct gl_resource *resource = gl_resource(res);
struct gl_runner *runner = gl_runner(r);
struct resource_readback *rb;
unsigned int layer, level;
size_t slice_pitch;
if (resource->r.desc.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.desc.type != RESOURCE_TYPE_DEPTH_STENCIL
&& resource->r.desc.type != RESOURCE_TYPE_UAV)
@ -1346,12 +1384,16 @@ static struct resource_readback *gl_runner_get_resource_readback(struct shader_r
rb->depth = 1;
rb->row_pitch = rb->width * resource->r.desc.texel_size;
rb->data = malloc(rb->row_pitch * rb->height);
slice_pitch = rb->row_pitch * rb->height;
rb->data = calloc(slice_pitch, resource->r.desc.depth);
level = sub_resource_idx % resource->r.desc.level_count;
layer = sub_resource_idx / resource->r.desc.level_count;
if (resource->r.desc.dimension == RESOURCE_DIMENSION_BUFFER)
{
glBindBuffer(GL_TEXTURE_BUFFER, resource->id);
glGetBufferSubData(GL_TEXTURE_BUFFER, 0, rb->row_pitch * rb->height, rb->data);
glBindBuffer(resource->target, resource->id);
glGetBufferSubData(resource->target, 0, slice_pitch, rb->data);
}
else if (resource->r.desc.sample_count > 1)
{
@ -1385,8 +1427,10 @@ static struct resource_readback *gl_runner_get_resource_readback(struct shader_r
}
else
{
glBindTexture(GL_TEXTURE_2D, resource->id);
glGetTexImage(GL_TEXTURE_2D, 0, resource->format->format, resource->format->type, rb->data);
glBindTexture(resource->target, resource->id);
glGetTexImage(resource->target, level, resource->format->format, resource->format->type, rb->data);
if (layer)
memcpy(rb->data, (const uint8_t *)rb->data + layer * slice_pitch, slice_pitch);
}
return rb;

View File

@ -200,10 +200,13 @@ static void init_resource_texture(struct metal_runner *runner,
desc = [[MTLTextureDescriptor alloc] init];
if (params->desc.sample_count > 1)
desc.textureType = MTLTextureType2DMultisample;
else if (params->desc.depth > 1)
desc.textureType = MTLTextureType2DArray;
desc.pixelFormat = get_metal_pixel_format(params->desc.format);
ok(desc.pixelFormat != MTLPixelFormatInvalid, "Unhandled pixel format %#x.\n", params->desc.format);
desc.width = params->desc.width;
desc.height = params->desc.height;
desc.arrayLength = params->desc.depth;
desc.mipmapLevelCount = params->desc.level_count;
desc.sampleCount = max(params->desc.sample_count, 1);
desc.storageMode = MTLStorageModePrivate;
@ -572,13 +575,15 @@ static bool metal_runner_copy(struct shader_runner *r, struct resource *src, str
return false;
}
static struct resource_readback *metal_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
static struct resource_readback *metal_runner_get_resource_readback(struct shader_runner *r,
struct resource *res, unsigned int sub_resource_idx)
{
struct metal_resource *resource = metal_resource(res);
struct metal_runner *runner = metal_runner(r);
id<MTLCommandBuffer> command_buffer;
struct metal_resource_readback *rb;
id<MTLBlitCommandEncoder> blit;
unsigned int layer, level;
if (resource->r.desc.dimension != RESOURCE_DIMENSION_2D)
fatal_error("Unhandled resource dimension %#x.\n", resource->r.desc.dimension);
@ -593,14 +598,17 @@ static struct resource_readback *metal_runner_get_resource_readback(struct shade
rb->buffer = [runner->device newBufferWithLength:rb->rb.row_pitch * rb->rb.height
options:DEFAULT_BUFFER_RESOURCE_OPTIONS];
level = sub_resource_idx % resource->r.desc.level_count;
layer = sub_resource_idx / resource->r.desc.level_count;
@autoreleasepool
{
command_buffer = [runner->queue commandBuffer];
blit = [command_buffer blitCommandEncoder];
[blit copyFromTexture:resource->texture
sourceSlice:0
sourceLevel:0
sourceSlice:layer
sourceLevel:level
sourceOrigin:MTLOriginMake(0, 0, 0)
sourceSize:MTLSizeMake(rb->rb.width, rb->rb.height, rb->rb.depth)
toBuffer:rb->buffer

View File

@ -93,6 +93,7 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
const struct vulkan_test_context *context = &runner->context;
VkFormat format = vkd3d_get_vk_format(params->desc.format);
const struct resource_desc *desc = &params->desc;
uint32_t layer_count = desc->depth;
VkDevice device = context->device;
unsigned int buffer_offset = 0;
VkDeviceMemory staging_memory;
@ -105,15 +106,16 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
usage |= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
resource->image = create_vulkan_2d_image(context, desc->width, desc->height, desc->level_count, desc->sample_count,
usage, format, &resource->memory);
resource->image_view = create_vulkan_2d_image_view(context, resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT);
resource->image = create_vulkan_2d_image(context, desc->width, desc->height,
desc->level_count, desc->depth, desc->sample_count, usage, format, &resource->memory);
resource->image_view = create_vulkan_2d_image_view(context,
resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, layer_count);
if (!params->data)
{
begin_command_buffer(context);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, layout);
0, layer_count, VK_IMAGE_LAYOUT_UNDEFINED, layout);
end_command_buffer(context);
return;
}
@ -126,8 +128,8 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
begin_command_buffer(context);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, 0,
layer_count, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
for (unsigned int level = 0; level < params->desc.level_count; ++level)
{
@ -148,7 +150,8 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
buffer_offset += level_width * level_height * params->desc.texel_size;
}
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
0, layer_count, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
end_command_buffer(context);
@ -188,6 +191,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
struct vulkan_shader_runner *runner = vulkan_shader_runner(r);
const struct vulkan_test_context *context = &runner->context;
const struct resource_desc *desc = &params->desc;
unsigned int layer_count = desc->depth;
VkDevice device = context->device;
struct vulkan_resource *resource;
VkFormat format;
@ -201,29 +205,30 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
case RESOURCE_TYPE_RENDER_TARGET:
format = vkd3d_get_vk_format(params->desc.format);
resource->image = create_vulkan_2d_image(context, desc->width, desc->height, desc->level_count,
desc->sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
format, &resource->memory);
resource->image = create_vulkan_2d_image(context, desc->width,
desc->height, desc->level_count, desc->depth, desc->sample_count,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format, &resource->memory);
resource->image_view = create_vulkan_2d_image_view(context,
resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT);
resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, layer_count);
begin_command_buffer(context);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, 0,
layer_count, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
end_command_buffer(context);
break;
case RESOURCE_TYPE_DEPTH_STENCIL:
format = vkd3d_get_vk_format(params->desc.format);
resource->image = create_vulkan_2d_image(context, desc->width, desc->height, desc->level_count,
desc->sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
resource->image = create_vulkan_2d_image(context, desc->width,
desc->height, desc->level_count, desc->depth, desc->sample_count,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
format, &resource->memory);
resource->image_view = create_vulkan_2d_image_view(context,
resource->image, format, VK_IMAGE_ASPECT_DEPTH_BIT);
resource->image, format, VK_IMAGE_ASPECT_DEPTH_BIT, layer_count);
begin_command_buffer(context);
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_DEPTH_BIT,
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_DEPTH_BIT, 0, layer_count,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
end_command_buffer(context);
break;
@ -339,7 +344,7 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS];
struct vkd3d_shader_push_constant_buffer push_constants;
enum vkd3d_shader_spirv_extension spirv_extensions[2];
enum vkd3d_shader_spirv_extension spirv_extensions[3];
struct vkd3d_shader_varying_map varying_map[12];
struct vkd3d_shader_resource_binding *binding;
struct vkd3d_shader_compile_option options[2];
@ -384,6 +389,8 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
if (runner->caps.shader_caps[SHADER_CAP_ROV])
spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_FRAGMENT_SHADER_INTERLOCK;
if (runner->caps.shader_caps[SHADER_CAP_RT_VP_ARRAY_INDEX])
spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_VIEWPORT_INDEX_LAYER;
if (runner->demote_to_helper_invocation)
spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION;
@ -1083,6 +1090,7 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn
unsigned int i, color_ref_count = 0, view_count = 0;
VkSubpassDescription subpass_desc = {0};
VkImageView views[MAX_RESOURCES];
unsigned int layer_count = ~0u;
VkImageLayout layout;
bool is_ds;
@ -1126,6 +1134,8 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn
runner->rt_size.width = resource->r.desc.width;
if (resource->r.desc.height < runner->rt_size.height)
runner->rt_size.height = resource->r.desc.height;
if (resource->r.desc.depth < layer_count)
layer_count = resource->r.desc.depth;
views[view_count++] = resource->image_view;
}
@ -1146,7 +1156,7 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn
fb_desc.pAttachments = views;
fb_desc.width = runner->rt_size.width;
fb_desc.height = runner->rt_size.height;
fb_desc.layers = 1;
fb_desc.layers = layer_count;
VK_CALL(vkCreateFramebuffer(context->device, &fb_desc, NULL, fb));
}
@ -1265,7 +1275,7 @@ static void vulkan_runner_clear(struct shader_runner *r, struct resource *res, c
fb_desc.pAttachments = &resource->image_view;
fb_desc.width = width;
fb_desc.height = height;
fb_desc.layers = 1;
fb_desc.layers = resource->r.desc.depth;
VK_CALL(vkCreateFramebuffer(device, &fb_desc, NULL, &fb));
begin_desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@ -1367,7 +1377,7 @@ static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, st
VkImageCopy vk_image_copy;
unsigned int l;
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER)
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.depth > 1)
return false;
if (src->desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
@ -1377,8 +1387,8 @@ static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, st
dst_layout = resource_get_layout(dst);
begin_command_buffer(context);
transition_image_layout(context, s->image, aspect_mask, src_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
transition_image_layout(context, d->image, aspect_mask,
transition_image_layout(context, s->image, aspect_mask, 0, 1, src_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
transition_image_layout(context, d->image, aspect_mask, 0, 1,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vk_image_copy.srcSubresource = (VkImageSubresourceLayers){.aspectMask = aspect_mask, .layerCount = 1};
@ -1398,8 +1408,8 @@ static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, st
d->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_copy));
}
transition_image_layout(context, d->image, aspect_mask, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_layout);
transition_image_layout(context, s->image, aspect_mask, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src_layout);
transition_image_layout(context, d->image, aspect_mask, 0, 1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_layout);
transition_image_layout(context, s->image, aspect_mask, 0, 1, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src_layout);
end_command_buffer(context);
return true;
@ -1412,7 +1422,8 @@ struct vulkan_resource_readback
VkBuffer buffer;
};
static struct resource_readback *vulkan_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
static struct resource_readback *vulkan_runner_get_resource_readback(struct shader_runner *r,
struct resource *res, unsigned int sub_resource_idx)
{
struct vulkan_shader_runner *runner = vulkan_shader_runner(r);
const struct vulkan_test_context *context = &runner->context;
@ -1421,6 +1432,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
VkDevice device = context->device;
VkImageAspectFlags aspect_mask;
VkBufferImageCopy region = {0};
unsigned int layer, level;
VkImageLayout layout;
rb->rb.width = resource->r.desc.width;
@ -1447,15 +1459,20 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
VkImage resolved_image = VK_NULL_HANDLE;
VkDeviceMemory resolved_memory;
level = sub_resource_idx % resource->r.desc.level_count;
layer = sub_resource_idx / resource->r.desc.level_count;
aspect_mask = (resource->r.desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
layout = resource_get_layout(res);
begin_command_buffer(context);
transition_image_layout(context, resource->image, aspect_mask, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
transition_image_layout(context, resource->image, aspect_mask,
layer, 1, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
region.imageSubresource.aspectMask = aspect_mask;
region.imageSubresource.mipLevel = level;
region.imageSubresource.baseArrayLayer = layer;
region.imageSubresource.layerCount = 1;
region.imageExtent.width = resource->r.desc.width;
region.imageExtent.height = resource->r.desc.height;
@ -1475,16 +1492,16 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
resolved_desc.sample_count = 1;
resolved_image = create_vulkan_2d_image(context, resolved_desc.width, resolved_desc.height,
resolved_desc.level_count, resolved_desc.sample_count,
resolved_desc.level_count, resolved_desc.depth, resolved_desc.sample_count,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
vkd3d_get_vk_format(resource->r.desc.format), &resolved_memory);
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT, layer,
1, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VK_CALL(vkCmdResolveImage(context->cmd_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
resolved_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region));
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT, layer,
1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VK_CALL(vkCmdCopyImageToBuffer(context->cmd_buffer, resolved_image,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, &region));
}
@ -1494,7 +1511,8 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, &region));
}
transition_image_layout(context, resource->image, aspect_mask, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout);
transition_image_layout(context, resource->image, aspect_mask,
layer, 1, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout);
end_command_buffer(context);
@ -1553,6 +1571,7 @@ static bool check_device_extensions(struct vulkan_shader_runner *runner,
{
{VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME},
{VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME},
{VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME},
{VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, true},
{VK_KHR_MAINTENANCE1_EXTENSION_NAME, true},
{VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME},
@ -1574,6 +1593,8 @@ static bool check_device_extensions(struct vulkan_shader_runner *runner,
enabled_extensions->names[enabled_extensions->count++] = name;
if (!strcmp(name, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME))
runner->caps.shader_caps[SHADER_CAP_ROV] = true;
if (!strcmp(name, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME))
runner->caps.shader_caps[SHADER_CAP_RT_VP_ARRAY_INDEX] = true;
if (!strcmp(name, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME))
runner->demote_to_helper_invocation = true;
if (!strcmp(name, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))

View File

@ -73,7 +73,8 @@ static inline void end_command_buffer(const struct vulkan_test_context *context)
}
static inline void transition_image_layout(const struct vulkan_test_context *context,
VkImage image, VkImageAspectFlags aspect_mask, VkImageLayout src_layout, VkImageLayout dst_layout)
VkImage image, VkImageAspectFlags aspect_mask, uint32_t base_layer, uint32_t layer_count,
VkImageLayout src_layout, VkImageLayout dst_layout)
{
VkImageMemoryBarrier barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
@ -87,8 +88,8 @@ static inline void transition_image_layout(const struct vulkan_test_context *con
barrier.subresourceRange.aspectMask = aspect_mask;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.baseArrayLayer = base_layer;
barrier.subresourceRange.layerCount = layer_count;
VK_CALL(vkCmdPipelineBarrier(context->cmd_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 0, NULL, 1, &barrier));
@ -166,8 +167,9 @@ static inline VkBufferView create_vulkan_buffer_view(const struct vulkan_test_co
return view;
}
static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *context, uint32_t width, uint32_t height,
uint32_t level_count, uint32_t sample_count, VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory)
static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *context, unsigned int width,
unsigned int height, unsigned int level_count, unsigned int layer_count, unsigned int sample_count,
VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory)
{
VkImageCreateInfo image_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
VkMemoryRequirements memory_reqs;
@ -179,7 +181,7 @@ static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *c
image_info.extent.height = height;
image_info.extent.depth = 1;
image_info.mipLevels = level_count;
image_info.arrayLayers = 1;
image_info.arrayLayers = layer_count;
image_info.samples = max(sample_count, 1);
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.usage = usage;
@ -196,13 +198,13 @@ static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *c
}
static inline VkImageView create_vulkan_2d_image_view(const struct vulkan_test_context *context,
VkImage image, VkFormat format, VkImageAspectFlags aspect_mask)
VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, unsigned int layer_count)
{
VkImageViewCreateInfo view_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
VkImageView view;
view_info.image = image;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.viewType = (layer_count > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
view_info.format = format;
view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
@ -212,7 +214,7 @@ static inline VkImageView create_vulkan_2d_image_view(const struct vulkan_test_c
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
view_info.subresourceRange.layerCount = layer_count;
VK_CALL(vkCreateImageView(context->device, &view_info, NULL, &view));
return view;