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-implicit-conversion.shader_test \
|
||||||
tests/hlsl/return.shader_test \
|
tests/hlsl/return.shader_test \
|
||||||
tests/hlsl/round.shader_test \
|
tests/hlsl/round.shader_test \
|
||||||
|
tests/hlsl/rt-array-index.shader_test \
|
||||||
tests/hlsl/rt-format-mismatch.shader_test \
|
tests/hlsl/rt-format-mismatch.shader_test \
|
||||||
tests/hlsl/rt-get-sample-info.shader_test \
|
tests/hlsl/rt-get-sample-info.shader_test \
|
||||||
tests/hlsl/sample-bias.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[] =
|
static const char *const shader_cap_strings[] =
|
||||||
{
|
{
|
||||||
[SHADER_CAP_CLIP_PLANES] = "clip-planes",
|
[SHADER_CAP_CLIP_PLANES] = "clip-planes",
|
||||||
[SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds",
|
[SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds",
|
||||||
[SHADER_CAP_FLOAT64] = "float64",
|
[SHADER_CAP_FLOAT64] = "float64",
|
||||||
[SHADER_CAP_FOG] = "fog",
|
[SHADER_CAP_FOG] = "fog",
|
||||||
[SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader",
|
[SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader",
|
||||||
[SHADER_CAP_INT64] = "int64",
|
[SHADER_CAP_INT64] = "int64",
|
||||||
[SHADER_CAP_POINT_SIZE] = "point-size",
|
[SHADER_CAP_POINT_SIZE] = "point-size",
|
||||||
[SHADER_CAP_ROV] = "rov",
|
[SHADER_CAP_ROV] = "rov",
|
||||||
[SHADER_CAP_WAVE_OPS] = "wave-ops",
|
[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)
|
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.dimension = RESOURCE_DIMENSION_BUFFER;
|
||||||
resource->desc.height = 1;
|
resource->desc.height = 1;
|
||||||
|
resource->desc.depth = 1;
|
||||||
}
|
}
|
||||||
else if (sscanf(line, "( raw_buffer , %u ) ", &resource->desc.width) == 1)
|
else if (sscanf(line, "( raw_buffer , %u ) ", &resource->desc.width) == 1)
|
||||||
{
|
{
|
||||||
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
|
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
|
||||||
resource->desc.height = 1;
|
resource->desc.height = 1;
|
||||||
|
resource->desc.depth = 1;
|
||||||
resource->is_raw = true;
|
resource->is_raw = true;
|
||||||
}
|
}
|
||||||
else if (sscanf(line, "( counter_buffer , %u ) ", &resource->desc.width) == 1)
|
else if (sscanf(line, "( counter_buffer , %u ) ", &resource->desc.width) == 1)
|
||||||
{
|
{
|
||||||
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
|
resource->desc.dimension = RESOURCE_DIMENSION_BUFFER;
|
||||||
resource->desc.height = 1;
|
resource->desc.height = 1;
|
||||||
|
resource->desc.depth = 1;
|
||||||
resource->is_uav_counter = true;
|
resource->is_uav_counter = true;
|
||||||
resource->stride = sizeof(uint32_t);
|
resource->stride = sizeof(uint32_t);
|
||||||
resource->desc.texel_size = resource->stride;
|
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)
|
else if (sscanf(line, "( 2d , %u , %u ) ", &resource->desc.width, &resource->desc.height) == 2)
|
||||||
{
|
{
|
||||||
resource->desc.dimension = RESOURCE_DIMENSION_2D;
|
resource->desc.dimension = RESOURCE_DIMENSION_2D;
|
||||||
|
resource->desc.depth = 1;
|
||||||
}
|
}
|
||||||
else if (sscanf(line, "( 2dms , %u , %u , %u ) ",
|
else if (sscanf(line, "( 2dms , %u , %u , %u ) ",
|
||||||
&resource->desc.sample_count, &resource->desc.width, &resource->desc.height) == 3)
|
&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;
|
resource->desc.dimension = RESOURCE_DIMENSION_2D;
|
||||||
}
|
}
|
||||||
@ -642,6 +653,9 @@ static void parse_resource_directive(struct resource_params *resource, const cha
|
|||||||
if (rest == line)
|
if (rest == line)
|
||||||
break;
|
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);
|
vkd3d_array_reserve((void **)&resource->data, &resource->data_capacity, resource->data_size + sizeof(u), 1);
|
||||||
memcpy(resource->data + resource->data_size, &u, sizeof(u));
|
memcpy(resource->data + resource->data_size, &u, sizeof(u));
|
||||||
resource->data_size += 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.texel_size = 16;
|
||||||
params.desc.width = RENDER_TARGET_WIDTH;
|
params.desc.width = RENDER_TARGET_WIDTH;
|
||||||
params.desc.height = RENDER_TARGET_HEIGHT;
|
params.desc.height = RENDER_TARGET_HEIGHT;
|
||||||
|
params.desc.depth = 1;
|
||||||
params.desc.level_count = 1;
|
params.desc.level_count = 1;
|
||||||
|
|
||||||
set_resource(runner, ¶ms);
|
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))
|
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_readback *rb;
|
||||||
struct resource *resource;
|
struct resource *resource;
|
||||||
bool is_signed = false;
|
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);
|
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)
|
if (sscanf(line, " ( %d , %d , %d , %d )%n", &left, &top, &right, &bottom, &len) == 4)
|
||||||
{
|
{
|
||||||
set_rect(&rect, left, top, right, bottom);
|
set_rect(&rect, left, top, right, bottom);
|
||||||
line += len;
|
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)
|
else if (sscanf(line, " ( %u , %u )%n", &left, &top, &len) == 2)
|
||||||
{
|
{
|
||||||
set_rect(&rect, left, top, left + 1, top + 1);
|
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);
|
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))
|
if (match_string(line, "rgbaui", &line))
|
||||||
{
|
{
|
||||||
struct uvec4 v;
|
struct uvec4 v;
|
||||||
|
@ -95,7 +95,7 @@ struct resource_desc
|
|||||||
|
|
||||||
DXGI_FORMAT format;
|
DXGI_FORMAT format;
|
||||||
unsigned int texel_size;
|
unsigned int texel_size;
|
||||||
unsigned int width, height;
|
unsigned int width, height, depth;
|
||||||
unsigned int level_count;
|
unsigned int level_count;
|
||||||
unsigned int sample_count;
|
unsigned int sample_count;
|
||||||
};
|
};
|
||||||
@ -148,6 +148,7 @@ enum shader_cap
|
|||||||
SHADER_CAP_INT64,
|
SHADER_CAP_INT64,
|
||||||
SHADER_CAP_POINT_SIZE,
|
SHADER_CAP_POINT_SIZE,
|
||||||
SHADER_CAP_ROV,
|
SHADER_CAP_ROV,
|
||||||
|
SHADER_CAP_RT_VP_ARRAY_INDEX,
|
||||||
SHADER_CAP_WAVE_OPS,
|
SHADER_CAP_WAVE_OPS,
|
||||||
SHADER_CAP_COUNT,
|
SHADER_CAP_COUNT,
|
||||||
};
|
};
|
||||||
@ -251,7 +252,8 @@ struct shader_runner_ops
|
|||||||
unsigned int instance_count);
|
unsigned int instance_count);
|
||||||
bool (*copy)(struct shader_runner *runner, struct resource *src, struct resource *dst);
|
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);
|
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);
|
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)
|
static BOOL init_test_context(struct d3d11_shader_runner *runner)
|
||||||
{
|
{
|
||||||
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2 = {0};
|
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2 = {0};
|
||||||
|
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options3 = {0};
|
||||||
D3D11_FEATURE_DATA_DOUBLES doubles = {0};
|
D3D11_FEATURE_DATA_DOUBLES doubles = {0};
|
||||||
unsigned int rt_width, rt_height;
|
unsigned int rt_width, rt_height;
|
||||||
D3D11_RASTERIZER_DESC rs_desc;
|
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));
|
D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2));
|
||||||
ok(hr == S_OK, "Failed to check feature options2 support, hr %#lx.\n", hr);
|
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_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)
|
for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i)
|
||||||
{
|
{
|
||||||
runner->caps.format_caps[formats[i]] = get_format_support(runner->device, 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.Width = params->desc.width;
|
||||||
desc.Height = params->desc.height;
|
desc.Height = params->desc.height;
|
||||||
desc.MipLevels = params->desc.level_count;
|
desc.MipLevels = params->desc.level_count;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = params->desc.depth;
|
||||||
desc.Format = params->desc.format;
|
desc.Format = params->desc.format;
|
||||||
desc.SampleDesc.Count = max(params->desc.sample_count, 1);
|
desc.SampleDesc.Count = max(params->desc.sample_count, 1);
|
||||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
@ -926,9 +932,11 @@ struct d3d11_resource_readback
|
|||||||
{
|
{
|
||||||
struct resource_readback rb;
|
struct resource_readback rb;
|
||||||
ID3D11Resource *resource;
|
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_shader_runner *runner = d3d11_shader_runner(r);
|
||||||
struct d3d11_resource_readback *rb = malloc(sizeof(*rb));
|
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);
|
ID3D11DeviceContext_CopyStructureCount(runner->immediate_context, (ID3D11Buffer *)rb->resource, 0, resource->uav);
|
||||||
else
|
else
|
||||||
ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, src_resource);
|
ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, src_resource);
|
||||||
hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &map_desc);
|
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);
|
ok(hr == S_OK, "Failed to map texture, hr %#lx.\n", hr);
|
||||||
|
|
||||||
if (resolved_resource)
|
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.width = resource->r.desc.width;
|
||||||
rb->rb.height = resource->r.desc.height;
|
rb->rb.height = resource->r.desc.height;
|
||||||
rb->rb.depth = 1;
|
rb->rb.depth = 1;
|
||||||
|
rb->sub_resource_idx = sub_resource_idx;
|
||||||
|
|
||||||
return &rb->rb;
|
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_resource_readback *d3d11_rb = CONTAINING_RECORD(rb, struct d3d11_resource_readback, rb);
|
||||||
struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
|
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);
|
ID3D11Resource_Release(d3d11_rb->resource);
|
||||||
free(d3d11_rb);
|
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)
|
if (params->desc.sample_count > 1 && params->desc.level_count > 1)
|
||||||
fatal_error("Multisampled texture has multiple levels.\n");
|
fatal_error("Multisampled texture has multiple levels.\n");
|
||||||
|
|
||||||
resource->resource = create_default_texture_(__FILE__, __LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
resource->resource = create_default_texture_(__FILE__, __LINE__, device,
|
||||||
params->desc.width, params->desc.height, 1, params->desc.level_count, params->desc.sample_count,
|
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);
|
params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, initial_state);
|
||||||
ID3D12Device_CreateRenderTargetView(device, resource->resource,
|
ID3D12Device_CreateRenderTargetView(device, resource->resource,
|
||||||
NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.desc.slot));
|
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);
|
runner->dsv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
|
||||||
|
|
||||||
resource->resource = create_default_texture2d(device, params->desc.width,
|
resource->resource = create_default_texture2d(device, params->desc.width,
|
||||||
params->desc.height, 1, params->desc.level_count, params->desc.format,
|
params->desc.height, params->desc.depth, params->desc.level_count,
|
||||||
D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, initial_state);
|
params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, initial_state);
|
||||||
ID3D12Device_CreateDepthStencilView(device, resource->resource,
|
ID3D12Device_CreateDepthStencilView(device, resource->resource,
|
||||||
NULL, get_cpu_dsv_handle(test_context, runner->dsv_heap, 0));
|
NULL, get_cpu_dsv_handle(test_context, runner->dsv_heap, 0));
|
||||||
break;
|
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");
|
fatal_error("Multisampled texture has multiple levels.\n");
|
||||||
|
|
||||||
resource->resource = create_default_texture_(__FILE__, __LINE__, device,
|
resource->resource = create_default_texture_(__FILE__, __LINE__, device,
|
||||||
D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height, 1,
|
D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height,
|
||||||
params->desc.level_count, params->desc.sample_count, params->desc.format,
|
params->desc.depth, params->desc.level_count, params->desc.sample_count, params->desc.format,
|
||||||
/* Multisampled textures must have ALLOW_RENDER_TARGET set. */
|
/* Multisampled textures must have ALLOW_RENDER_TARGET set. */
|
||||||
(params->desc.sample_count > 1) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET : 0, initial_state);
|
(params->desc.sample_count > 1) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET : 0, initial_state);
|
||||||
if (params->data)
|
if (params->data)
|
||||||
@ -219,8 +220,8 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
resource->resource = create_default_texture2d(device, params->desc.width,
|
resource->resource = create_default_texture2d(device, params->desc.width,
|
||||||
params->desc.height, 1, params->desc.level_count, params->desc.format,
|
params->desc.height, params->desc.depth, params->desc.level_count,
|
||||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, initial_state);
|
params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, initial_state);
|
||||||
if (params->data)
|
if (params->data)
|
||||||
{
|
{
|
||||||
upload_texture_data_with_states(resource->resource, resource_data, params->desc.level_count,
|
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;
|
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 d3d12_shader_runner *runner = d3d12_shader_runner(r);
|
||||||
struct test_context *test_context = &runner->test_context;
|
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;
|
D3D12_RESOURCE_STATES state;
|
||||||
|
|
||||||
state = resource_get_state(res);
|
state = resource_get_state(res);
|
||||||
get_resource_readback_with_command_list_and_states(resource->resource, 0, rb,
|
get_resource_readback_with_command_list_and_states(resource->resource,
|
||||||
test_context->queue, test_context->list, state, state);
|
sub_resource_idx, rb, test_context->queue, test_context->list, state, state);
|
||||||
reset_command_list(test_context->list, test_context->allocator);
|
reset_command_list(test_context->list, test_context->allocator);
|
||||||
|
|
||||||
return &rb->rb;
|
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_GEOMETRY_SHADER] = true;
|
||||||
runner->caps.shader_caps[SHADER_CAP_INT64] = options1.Int64ShaderOps;
|
runner->caps.shader_caps[SHADER_CAP_INT64] = options1.Int64ShaderOps;
|
||||||
runner->caps.shader_caps[SHADER_CAP_ROV] = options.ROVsSupported;
|
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.shader_caps[SHADER_CAP_WAVE_OPS] = options1.WaveOps;
|
||||||
|
|
||||||
runner->caps.tag_count = 0;
|
runner->caps.tag_count = 0;
|
||||||
|
@ -584,7 +584,8 @@ struct d3d9_resource_readback
|
|||||||
IDirect3DSurface9 *surface;
|
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_shader_runner *runner = d3d9_shader_runner(r);
|
||||||
struct d3d9_resource_readback *rb = malloc(sizeof(*rb));
|
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;
|
HRESULT hr;
|
||||||
|
|
||||||
assert(resource->r.desc.type == RESOURCE_TYPE_RENDER_TARGET);
|
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);
|
hr = IDirect3DSurface9_GetDesc(resource->surface, &desc);
|
||||||
ok(hr == D3D_OK, "Failed to get surface desc, hr %#lx.\n", hr);
|
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;
|
const struct format_info *format;
|
||||||
GLuint id, tbo_id;
|
GLuint id, tbo_id;
|
||||||
|
GLenum target;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gl_resource *gl_resource(struct resource *r)
|
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);
|
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)
|
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 true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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)
|
static bool check_gl_extensions(struct gl_runner *runner)
|
||||||
{
|
{
|
||||||
GLint count;
|
GLint count, spirv_count = 0;
|
||||||
|
|
||||||
static const char *required_extensions[] =
|
static const char *required_extensions[] =
|
||||||
{
|
{
|
||||||
@ -126,8 +137,14 @@ static bool check_gl_extensions(struct gl_runner *runner)
|
|||||||
|
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||||
|
|
||||||
if (runner->language == SPIR_V && !check_gl_extension("GL_ARB_gl_spirv", count))
|
if (runner->language == SPIR_V)
|
||||||
return false;
|
{
|
||||||
|
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)
|
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;
|
runner->caps.shader_caps[SHADER_CAP_FLOAT64] = true;
|
||||||
if (check_gl_extension("GL_ARB_gpu_shader_int64", count))
|
if (check_gl_extension("GL_ARB_gpu_shader_int64", count))
|
||||||
runner->caps.shader_caps[SHADER_CAP_INT64] = true;
|
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))
|
if (check_gl_extension("GL_EXT_depth_bounds_test", count))
|
||||||
runner->caps.shader_caps[SHADER_CAP_DEPTH_BOUNDS] = true;
|
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)
|
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;
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
glTexStorage2D(target, params->desc.level_count,
|
if (params->desc.depth > 1)
|
||||||
resource->format->internal_format, params->desc.width, params->desc.height);
|
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_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_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)
|
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->format = get_format_info(params->desc.format, false);
|
||||||
|
resource->target = target;
|
||||||
|
|
||||||
glGenBuffers(1, &resource->id);
|
glGenBuffers(1, &resource->id);
|
||||||
glBindBuffer(GL_TEXTURE_BUFFER, resource->id);
|
glBindBuffer(target, resource->id);
|
||||||
glBufferData(GL_TEXTURE_BUFFER, params->data_size, params->data, GL_STATIC_DRAW);
|
glBufferData(target, params->data_size, params->data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
glGenTextures(1, &resource->tbo_id);
|
glGenTextures(1, &resource->tbo_id);
|
||||||
glBindTexture(GL_TEXTURE_BUFFER, resource->tbo_id);
|
glBindTexture(target, resource->tbo_id);
|
||||||
glTexBuffer(GL_TEXTURE_BUFFER, resource->format->internal_format, resource->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)
|
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_scan_hull_shader_tessellation_info tessellation_info;
|
||||||
struct vkd3d_shader_spirv_domain_shader_target_info domain_info;
|
struct vkd3d_shader_spirv_domain_shader_target_info domain_info;
|
||||||
struct vkd3d_shader_combined_resource_sampler *sampler;
|
struct vkd3d_shader_combined_resource_sampler *sampler;
|
||||||
|
enum vkd3d_shader_spirv_extension spirv_extensions[1];
|
||||||
struct vkd3d_shader_resource_binding *binding;
|
struct vkd3d_shader_resource_binding *binding;
|
||||||
struct vkd3d_shader_parameter parameters[1];
|
struct vkd3d_shader_parameter parameters[1];
|
||||||
unsigned int count, i;
|
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;
|
info.next = &spirv_info;
|
||||||
spirv_info.next = &interface_info;
|
spirv_info.next = &interface_info;
|
||||||
spirv_info.environment = VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5;
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -1159,11 +1199,9 @@ static bool gl_runner_draw(struct shader_runner *r,
|
|||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + s->binding.binding);
|
glActiveTexture(GL_TEXTURE0 + s->binding.binding);
|
||||||
if (resource->desc.dimension == RESOURCE_DIMENSION_BUFFER)
|
if (resource->desc.dimension == RESOURCE_DIMENSION_BUFFER)
|
||||||
glBindTexture(GL_TEXTURE_BUFFER, gl_resource(resource)->tbo_id);
|
glBindTexture(gl_resource(resource)->target, gl_resource(resource)->tbo_id);
|
||||||
else if (resource->desc.sample_count > 1)
|
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, gl_resource(resource)->id);
|
|
||||||
else
|
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)
|
if (s->sampler_index == VKD3D_SHADER_DUMMY_SAMPLER_INDEX)
|
||||||
continue;
|
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 *s = gl_resource(src);
|
||||||
struct gl_resource *d = gl_resource(dst);
|
struct gl_resource *d = gl_resource(dst);
|
||||||
GLenum target = GL_TEXTURE_2D;
|
|
||||||
unsigned int l, w, h;
|
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;
|
return false;
|
||||||
|
|
||||||
if (src->desc.sample_count > 1)
|
|
||||||
target = GL_TEXTURE_2D_MULTISAMPLE;
|
|
||||||
for (l = 0; l < src->desc.level_count; ++l)
|
for (l = 0; l < src->desc.level_count; ++l)
|
||||||
{
|
{
|
||||||
w = get_level_dimension(src->desc.width, l);
|
w = get_level_dimension(src->desc.width, l);
|
||||||
h = get_level_dimension(src->desc.height, 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;
|
return true;
|
||||||
@ -1329,11 +1364,14 @@ struct gl_resource_readback
|
|||||||
struct resource_readback rb;
|
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_resource *resource = gl_resource(res);
|
||||||
struct gl_runner *runner = gl_runner(r);
|
struct gl_runner *runner = gl_runner(r);
|
||||||
struct resource_readback *rb;
|
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
|
if (resource->r.desc.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.desc.type != RESOURCE_TYPE_DEPTH_STENCIL
|
||||||
&& resource->r.desc.type != RESOURCE_TYPE_UAV)
|
&& 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->depth = 1;
|
||||||
|
|
||||||
rb->row_pitch = rb->width * resource->r.desc.texel_size;
|
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)
|
if (resource->r.desc.dimension == RESOURCE_DIMENSION_BUFFER)
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_TEXTURE_BUFFER, resource->id);
|
glBindBuffer(resource->target, resource->id);
|
||||||
glGetBufferSubData(GL_TEXTURE_BUFFER, 0, rb->row_pitch * rb->height, rb->data);
|
glGetBufferSubData(resource->target, 0, slice_pitch, rb->data);
|
||||||
}
|
}
|
||||||
else if (resource->r.desc.sample_count > 1)
|
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
|
else
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, resource->id);
|
glBindTexture(resource->target, resource->id);
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, resource->format->format, resource->format->type, rb->data);
|
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;
|
return rb;
|
||||||
|
@ -200,10 +200,13 @@ static void init_resource_texture(struct metal_runner *runner,
|
|||||||
desc = [[MTLTextureDescriptor alloc] init];
|
desc = [[MTLTextureDescriptor alloc] init];
|
||||||
if (params->desc.sample_count > 1)
|
if (params->desc.sample_count > 1)
|
||||||
desc.textureType = MTLTextureType2DMultisample;
|
desc.textureType = MTLTextureType2DMultisample;
|
||||||
|
else if (params->desc.depth > 1)
|
||||||
|
desc.textureType = MTLTextureType2DArray;
|
||||||
desc.pixelFormat = get_metal_pixel_format(params->desc.format);
|
desc.pixelFormat = get_metal_pixel_format(params->desc.format);
|
||||||
ok(desc.pixelFormat != MTLPixelFormatInvalid, "Unhandled pixel format %#x.\n", params->desc.format);
|
ok(desc.pixelFormat != MTLPixelFormatInvalid, "Unhandled pixel format %#x.\n", params->desc.format);
|
||||||
desc.width = params->desc.width;
|
desc.width = params->desc.width;
|
||||||
desc.height = params->desc.height;
|
desc.height = params->desc.height;
|
||||||
|
desc.arrayLength = params->desc.depth;
|
||||||
desc.mipmapLevelCount = params->desc.level_count;
|
desc.mipmapLevelCount = params->desc.level_count;
|
||||||
desc.sampleCount = max(params->desc.sample_count, 1);
|
desc.sampleCount = max(params->desc.sample_count, 1);
|
||||||
desc.storageMode = MTLStorageModePrivate;
|
desc.storageMode = MTLStorageModePrivate;
|
||||||
@ -572,13 +575,15 @@ static bool metal_runner_copy(struct shader_runner *r, struct resource *src, str
|
|||||||
return false;
|
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_resource *resource = metal_resource(res);
|
||||||
struct metal_runner *runner = metal_runner(r);
|
struct metal_runner *runner = metal_runner(r);
|
||||||
id<MTLCommandBuffer> command_buffer;
|
id<MTLCommandBuffer> command_buffer;
|
||||||
struct metal_resource_readback *rb;
|
struct metal_resource_readback *rb;
|
||||||
id<MTLBlitCommandEncoder> blit;
|
id<MTLBlitCommandEncoder> blit;
|
||||||
|
unsigned int layer, level;
|
||||||
|
|
||||||
if (resource->r.desc.dimension != RESOURCE_DIMENSION_2D)
|
if (resource->r.desc.dimension != RESOURCE_DIMENSION_2D)
|
||||||
fatal_error("Unhandled resource dimension %#x.\n", resource->r.desc.dimension);
|
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
|
rb->buffer = [runner->device newBufferWithLength:rb->rb.row_pitch * rb->rb.height
|
||||||
options:DEFAULT_BUFFER_RESOURCE_OPTIONS];
|
options:DEFAULT_BUFFER_RESOURCE_OPTIONS];
|
||||||
|
|
||||||
|
level = sub_resource_idx % resource->r.desc.level_count;
|
||||||
|
layer = sub_resource_idx / resource->r.desc.level_count;
|
||||||
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
command_buffer = [runner->queue commandBuffer];
|
command_buffer = [runner->queue commandBuffer];
|
||||||
|
|
||||||
blit = [command_buffer blitCommandEncoder];
|
blit = [command_buffer blitCommandEncoder];
|
||||||
[blit copyFromTexture:resource->texture
|
[blit copyFromTexture:resource->texture
|
||||||
sourceSlice:0
|
sourceSlice:layer
|
||||||
sourceLevel:0
|
sourceLevel:level
|
||||||
sourceOrigin:MTLOriginMake(0, 0, 0)
|
sourceOrigin:MTLOriginMake(0, 0, 0)
|
||||||
sourceSize:MTLSizeMake(rb->rb.width, rb->rb.height, rb->rb.depth)
|
sourceSize:MTLSizeMake(rb->rb.width, rb->rb.height, rb->rb.depth)
|
||||||
toBuffer:rb->buffer
|
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;
|
const struct vulkan_test_context *context = &runner->context;
|
||||||
VkFormat format = vkd3d_get_vk_format(params->desc.format);
|
VkFormat format = vkd3d_get_vk_format(params->desc.format);
|
||||||
const struct resource_desc *desc = ¶ms->desc;
|
const struct resource_desc *desc = ¶ms->desc;
|
||||||
|
uint32_t layer_count = desc->depth;
|
||||||
VkDevice device = context->device;
|
VkDevice device = context->device;
|
||||||
unsigned int buffer_offset = 0;
|
unsigned int buffer_offset = 0;
|
||||||
VkDeviceMemory staging_memory;
|
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;
|
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,
|
resource->image = create_vulkan_2d_image(context, desc->width, desc->height,
|
||||||
usage, format, &resource->memory);
|
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);
|
resource->image_view = create_vulkan_2d_image_view(context,
|
||||||
|
resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, layer_count);
|
||||||
|
|
||||||
if (!params->data)
|
if (!params->data)
|
||||||
{
|
{
|
||||||
begin_command_buffer(context);
|
begin_command_buffer(context);
|
||||||
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
|
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);
|
end_command_buffer(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -126,8 +128,8 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
|
|||||||
|
|
||||||
begin_command_buffer(context);
|
begin_command_buffer(context);
|
||||||
|
|
||||||
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
|
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, 0,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
layer_count, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
for (unsigned int level = 0; level < params->desc.level_count; ++level)
|
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;
|
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);
|
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);
|
struct vulkan_shader_runner *runner = vulkan_shader_runner(r);
|
||||||
const struct vulkan_test_context *context = &runner->context;
|
const struct vulkan_test_context *context = &runner->context;
|
||||||
const struct resource_desc *desc = ¶ms->desc;
|
const struct resource_desc *desc = ¶ms->desc;
|
||||||
|
unsigned int layer_count = desc->depth;
|
||||||
VkDevice device = context->device;
|
VkDevice device = context->device;
|
||||||
struct vulkan_resource *resource;
|
struct vulkan_resource *resource;
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
@ -201,29 +205,30 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
|
|||||||
case RESOURCE_TYPE_RENDER_TARGET:
|
case RESOURCE_TYPE_RENDER_TARGET:
|
||||||
format = vkd3d_get_vk_format(params->desc.format);
|
format = vkd3d_get_vk_format(params->desc.format);
|
||||||
|
|
||||||
resource->image = create_vulkan_2d_image(context, desc->width, desc->height, desc->level_count,
|
resource->image = create_vulkan_2d_image(context, desc->width,
|
||||||
desc->sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
desc->height, desc->level_count, desc->depth, desc->sample_count,
|
||||||
format, &resource->memory);
|
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_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);
|
begin_command_buffer(context);
|
||||||
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT,
|
transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, 0,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
layer_count, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
end_command_buffer(context);
|
end_command_buffer(context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESOURCE_TYPE_DEPTH_STENCIL:
|
case RESOURCE_TYPE_DEPTH_STENCIL:
|
||||||
format = vkd3d_get_vk_format(params->desc.format);
|
format = vkd3d_get_vk_format(params->desc.format);
|
||||||
|
|
||||||
resource->image = create_vulkan_2d_image(context, desc->width, desc->height, desc->level_count,
|
resource->image = create_vulkan_2d_image(context, desc->width,
|
||||||
desc->sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
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);
|
format, &resource->memory);
|
||||||
resource->image_view = create_vulkan_2d_image_view(context,
|
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);
|
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);
|
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
end_command_buffer(context);
|
end_command_buffer(context);
|
||||||
break;
|
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_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
|
||||||
struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS];
|
struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS];
|
||||||
struct vkd3d_shader_push_constant_buffer push_constants;
|
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_varying_map varying_map[12];
|
||||||
struct vkd3d_shader_resource_binding *binding;
|
struct vkd3d_shader_resource_binding *binding;
|
||||||
struct vkd3d_shader_compile_option options[2];
|
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])
|
if (runner->caps.shader_caps[SHADER_CAP_ROV])
|
||||||
spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_FRAGMENT_SHADER_INTERLOCK;
|
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)
|
if (runner->demote_to_helper_invocation)
|
||||||
spirv_extensions[spirv_info.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_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;
|
unsigned int i, color_ref_count = 0, view_count = 0;
|
||||||
VkSubpassDescription subpass_desc = {0};
|
VkSubpassDescription subpass_desc = {0};
|
||||||
VkImageView views[MAX_RESOURCES];
|
VkImageView views[MAX_RESOURCES];
|
||||||
|
unsigned int layer_count = ~0u;
|
||||||
VkImageLayout layout;
|
VkImageLayout layout;
|
||||||
bool is_ds;
|
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;
|
runner->rt_size.width = resource->r.desc.width;
|
||||||
if (resource->r.desc.height < runner->rt_size.height)
|
if (resource->r.desc.height < runner->rt_size.height)
|
||||||
runner->rt_size.height = resource->r.desc.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;
|
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.pAttachments = views;
|
||||||
fb_desc.width = runner->rt_size.width;
|
fb_desc.width = runner->rt_size.width;
|
||||||
fb_desc.height = runner->rt_size.height;
|
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));
|
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.pAttachments = &resource->image_view;
|
||||||
fb_desc.width = width;
|
fb_desc.width = width;
|
||||||
fb_desc.height = height;
|
fb_desc.height = height;
|
||||||
fb_desc.layers = 1;
|
fb_desc.layers = resource->r.desc.depth;
|
||||||
VK_CALL(vkCreateFramebuffer(device, &fb_desc, NULL, &fb));
|
VK_CALL(vkCreateFramebuffer(device, &fb_desc, NULL, &fb));
|
||||||
|
|
||||||
begin_desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
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;
|
VkImageCopy vk_image_copy;
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
|
|
||||||
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER)
|
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.depth > 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (src->desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
|
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);
|
dst_layout = resource_get_layout(dst);
|
||||||
|
|
||||||
begin_command_buffer(context);
|
begin_command_buffer(context);
|
||||||
transition_image_layout(context, s->image, aspect_mask, src_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
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,
|
transition_image_layout(context, d->image, aspect_mask, 0, 1,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
vk_image_copy.srcSubresource = (VkImageSubresourceLayers){.aspectMask = aspect_mask, .layerCount = 1};
|
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));
|
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, d->image, aspect_mask, 0, 1, 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, s->image, aspect_mask, 0, 1, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src_layout);
|
||||||
end_command_buffer(context);
|
end_command_buffer(context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1412,7 +1422,8 @@ struct vulkan_resource_readback
|
|||||||
VkBuffer buffer;
|
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);
|
struct vulkan_shader_runner *runner = vulkan_shader_runner(r);
|
||||||
const struct vulkan_test_context *context = &runner->context;
|
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;
|
VkDevice device = context->device;
|
||||||
VkImageAspectFlags aspect_mask;
|
VkImageAspectFlags aspect_mask;
|
||||||
VkBufferImageCopy region = {0};
|
VkBufferImageCopy region = {0};
|
||||||
|
unsigned int layer, level;
|
||||||
VkImageLayout layout;
|
VkImageLayout layout;
|
||||||
|
|
||||||
rb->rb.width = resource->r.desc.width;
|
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;
|
VkImage resolved_image = VK_NULL_HANDLE;
|
||||||
VkDeviceMemory resolved_memory;
|
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)
|
aspect_mask = (resource->r.desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
|
||||||
? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
layout = resource_get_layout(res);
|
layout = resource_get_layout(res);
|
||||||
|
|
||||||
begin_command_buffer(context);
|
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.aspectMask = aspect_mask;
|
||||||
|
region.imageSubresource.mipLevel = level;
|
||||||
|
region.imageSubresource.baseArrayLayer = layer;
|
||||||
region.imageSubresource.layerCount = 1;
|
region.imageSubresource.layerCount = 1;
|
||||||
region.imageExtent.width = resource->r.desc.width;
|
region.imageExtent.width = resource->r.desc.width;
|
||||||
region.imageExtent.height = resource->r.desc.height;
|
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_desc.sample_count = 1;
|
||||||
resolved_image = create_vulkan_2d_image(context, resolved_desc.width, resolved_desc.height,
|
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,
|
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||||
vkd3d_get_vk_format(resource->r.desc.format), &resolved_memory);
|
vkd3d_get_vk_format(resource->r.desc.format), &resolved_memory);
|
||||||
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT,
|
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT, layer,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
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,
|
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));
|
resolved_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region));
|
||||||
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT,
|
transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT, layer,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
1, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
VK_CALL(vkCmdCopyImageToBuffer(context->cmd_buffer, resolved_image,
|
VK_CALL(vkCmdCopyImageToBuffer(context->cmd_buffer, resolved_image,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion));
|
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));
|
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);
|
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_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME},
|
||||||
{VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_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_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, true},
|
||||||
{VK_KHR_MAINTENANCE1_EXTENSION_NAME, true},
|
{VK_KHR_MAINTENANCE1_EXTENSION_NAME, true},
|
||||||
{VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME},
|
{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;
|
enabled_extensions->names[enabled_extensions->count++] = name;
|
||||||
if (!strcmp(name, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME))
|
if (!strcmp(name, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME))
|
||||||
runner->caps.shader_caps[SHADER_CAP_ROV] = true;
|
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))
|
if (!strcmp(name, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME))
|
||||||
runner->demote_to_helper_invocation = true;
|
runner->demote_to_helper_invocation = true;
|
||||||
if (!strcmp(name, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
|
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,
|
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};
|
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.aspectMask = aspect_mask;
|
||||||
barrier.subresourceRange.baseMipLevel = 0;
|
barrier.subresourceRange.baseMipLevel = 0;
|
||||||
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
barrier.subresourceRange.baseArrayLayer = 0;
|
barrier.subresourceRange.baseArrayLayer = base_layer;
|
||||||
barrier.subresourceRange.layerCount = 1;
|
barrier.subresourceRange.layerCount = layer_count;
|
||||||
|
|
||||||
VK_CALL(vkCmdPipelineBarrier(context->cmd_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
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));
|
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;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *context, uint32_t width, uint32_t height,
|
static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *context, unsigned int width,
|
||||||
uint32_t level_count, uint32_t sample_count, VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory)
|
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};
|
VkImageCreateInfo image_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
|
||||||
VkMemoryRequirements memory_reqs;
|
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.height = height;
|
||||||
image_info.extent.depth = 1;
|
image_info.extent.depth = 1;
|
||||||
image_info.mipLevels = level_count;
|
image_info.mipLevels = level_count;
|
||||||
image_info.arrayLayers = 1;
|
image_info.arrayLayers = layer_count;
|
||||||
image_info.samples = max(sample_count, 1);
|
image_info.samples = max(sample_count, 1);
|
||||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
image_info.usage = usage;
|
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,
|
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};
|
VkImageViewCreateInfo view_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
||||||
VkImageView view;
|
VkImageView view;
|
||||||
|
|
||||||
view_info.image = image;
|
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.format = format;
|
||||||
view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
view_info.components.g = 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.baseMipLevel = 0;
|
||||||
view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
view_info.subresourceRange.baseArrayLayer = 0;
|
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));
|
VK_CALL(vkCreateImageView(context->device, &view_info, NULL, &view));
|
||||||
return view;
|
return view;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user