mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
tests/hlsl: Add a test for SV_RenderTargetArrayIndex.
This commit is contained in:
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
@ -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 \
|
||||
|
50
tests/hlsl/rt-array-index.shader_test
Normal file
50
tests/hlsl/rt-array-index.shader_test
Normal 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)
|
@ -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, ¶ms);
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 = ¶ms->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 = ¶ms->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, ®ion));
|
||||
}
|
||||
@ -1494,7 +1511,8 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion));
|
||||
}
|
||||
|
||||
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))
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user