mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-23 07:10:19 +00:00
tests: Add a test for actual multisample loads.
The existing test loads from a single sample texture.
This commit is contained in:
parent
072b45b972
commit
aeae8322da
Notes:
Henri Verbeet
2024-10-28 18:13:33 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1225
@ -145,3 +145,56 @@ probe (0, 0) rgba (0.1, 0.2, 0.3, 0.4)
|
||||
probe (1, 0) rgba (0.5, 0.7, 0.6, 0.8)
|
||||
probe (0, 1) rgba (0.6, 0.5, 0.2, 0.1)
|
||||
probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0)
|
||||
|
||||
% Test an actual multisample load
|
||||
|
||||
[require]
|
||||
shader model >= 4.1
|
||||
|
||||
[rtv 0]
|
||||
format r32g32b32a32-float
|
||||
size (2dms, 4, 64, 64)
|
||||
|
||||
[srv 0]
|
||||
format r32g32b32a32-float
|
||||
size (2dms, 4, 64, 64)
|
||||
|
||||
[pixel shader]
|
||||
float4 main(uint id : sv_sampleindex) : sv_target
|
||||
{
|
||||
return float4(1u << id, 0.25f, 0.5f, 1.0f);
|
||||
}
|
||||
|
||||
[test]
|
||||
clear rtv 0 0.0 0.0 0.0 0.0
|
||||
todo(glsl | sm>=6) draw quad
|
||||
probe (32, 32) rgba(3.75, 0.25, 0.5, 1.0)
|
||||
copy rtv 0 srv 0
|
||||
|
||||
[rtv 0]
|
||||
format r32g32b32a32-float
|
||||
size (2d, 64, 64)
|
||||
|
||||
[pixel shader]
|
||||
Texture2DMS<float4> t;
|
||||
uint sample;
|
||||
|
||||
float4 main(float4 position : sv_position) : sv_target
|
||||
{
|
||||
float2 p = position.xy / 64.0f;
|
||||
return t.Load(p, sample);
|
||||
}
|
||||
|
||||
[test]
|
||||
uniform 0 uint 0
|
||||
todo(glsl) draw quad
|
||||
todo(sm>=6) probe (32, 32) rgba(1.0, 0.25, 0.5, 1.0)
|
||||
uniform 0 uint 1
|
||||
todo(glsl) draw quad
|
||||
todo(sm>=6) probe (32, 32) rgba(2.0, 0.25, 0.5, 1.0)
|
||||
uniform 0 uint 2
|
||||
todo(glsl) draw quad
|
||||
todo(sm>=6) probe (32, 32) rgba(4.0, 0.25, 0.5, 1.0)
|
||||
uniform 0 uint 3
|
||||
todo(glsl) draw quad
|
||||
todo(sm>=6) probe (32, 32) rgba(8.0, 0.25, 0.5, 1.0)
|
||||
|
@ -845,6 +845,30 @@ static void read_uint64_t2(const char **line, struct u64vec2 *v)
|
||||
read_uint64(line, &v->y, true);
|
||||
}
|
||||
|
||||
static struct resource *parse_resource_reference(struct shader_runner *runner, const char **const line)
|
||||
{
|
||||
enum resource_type type;
|
||||
unsigned int slot = 0;
|
||||
|
||||
if (match_string(*line, "dsv", line))
|
||||
type = RESOURCE_TYPE_DEPTH_STENCIL;
|
||||
else if (match_string(*line, "rtv", line))
|
||||
type = RESOURCE_TYPE_RENDER_TARGET;
|
||||
else if (match_string(*line, "srv", line))
|
||||
type = RESOURCE_TYPE_TEXTURE;
|
||||
else if (match_string(*line, "uav", line))
|
||||
type = RESOURCE_TYPE_UAV;
|
||||
else if (match_string(*line, "vb", line))
|
||||
type = RESOURCE_TYPE_VERTEX_BUFFER;
|
||||
else
|
||||
fatal_error("Malformed resource reference '%s'.\n", *line);
|
||||
|
||||
if (type != RESOURCE_TYPE_DEPTH_STENCIL)
|
||||
read_uint(line, &slot, false);
|
||||
|
||||
return shader_runner_get_resource(runner, type, slot);
|
||||
}
|
||||
|
||||
static void parse_test_directive(struct shader_runner *runner, const char *line)
|
||||
{
|
||||
bool skip_directive = false;
|
||||
@ -1044,6 +1068,26 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
|
||||
|
||||
runner->last_render_failed = !runner->ops->draw(runner, topology, vertex_count, instance_count);
|
||||
}
|
||||
else if (match_string(line, "copy", &line))
|
||||
{
|
||||
struct resource *src, *dst;
|
||||
|
||||
if (!(src = parse_resource_reference(runner, &line)))
|
||||
fatal_error("Undefined source resource.\n");
|
||||
if (!(dst = parse_resource_reference(runner, &line)))
|
||||
fatal_error("Undefined destination resource.\n");
|
||||
|
||||
if (src->desc.dimension != dst->desc.dimension
|
||||
|| src->desc.texel_size != dst->desc.texel_size
|
||||
|| src->desc.width != dst->desc.width
|
||||
|| src->desc.height != dst->desc.height
|
||||
|| src->desc.level_count != dst->desc.level_count
|
||||
|| src->desc.sample_count != dst->desc.sample_count)
|
||||
fatal_error("Resource dimensions don't match.\n");
|
||||
|
||||
if (!(runner->ops->copy(runner, src, dst)))
|
||||
fatal_error("Failed to copy resource.\n");
|
||||
}
|
||||
else if (match_string(line, "probe", &line))
|
||||
{
|
||||
unsigned int left, top, right, bottom, ulps, slot;
|
||||
|
@ -230,6 +230,7 @@ struct shader_runner_ops
|
||||
void (*clear)(struct shader_runner *runner, struct resource *resource, const struct vec4 *clear_value);
|
||||
bool (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count,
|
||||
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);
|
||||
void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb);
|
||||
|
@ -901,6 +901,17 @@ static bool d3d11_runner_draw(struct shader_runner *r,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool d3d11_runner_copy(struct shader_runner *r, struct resource *src, struct resource *dst)
|
||||
{
|
||||
struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
|
||||
struct d3d11_resource *s = d3d11_resource(src);
|
||||
struct d3d11_resource *d = d3d11_resource(dst);
|
||||
|
||||
ID3D11DeviceContext_CopyResource(runner->immediate_context, d->resource, s->resource);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct d3d11_resource_readback
|
||||
{
|
||||
struct resource_readback rb;
|
||||
@ -1000,6 +1011,7 @@ static const struct shader_runner_ops d3d11_runner_ops =
|
||||
.dispatch = d3d11_runner_dispatch,
|
||||
.clear = d3d11_runner_clear,
|
||||
.draw = d3d11_runner_draw,
|
||||
.copy = d3d11_runner_copy,
|
||||
.get_resource_readback = d3d11_runner_get_resource_readback,
|
||||
.release_readback = d3d11_runner_release_readback,
|
||||
};
|
||||
|
@ -902,6 +902,33 @@ static bool d3d12_runner_draw(struct shader_runner *r,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool d3d12_runner_copy(struct shader_runner *r, struct resource *src, struct resource *dst)
|
||||
{
|
||||
struct d3d12_shader_runner *runner = d3d12_shader_runner(r);
|
||||
struct test_context *context = &runner->test_context;
|
||||
struct d3d12_resource *s = d3d12_resource(src);
|
||||
struct d3d12_resource *d = d3d12_resource(dst);
|
||||
D3D12_RESOURCE_STATES src_state, dst_state;
|
||||
HRESULT hr;
|
||||
|
||||
src_state = resource_get_state(src);
|
||||
dst_state = resource_get_state(dst);
|
||||
|
||||
transition_resource_state(context->list, s->resource, src_state, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
transition_resource_state(context->list, d->resource, dst_state, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
ID3D12GraphicsCommandList_CopyResource(context->list, d->resource, s->resource);
|
||||
transition_resource_state(context->list, d->resource, D3D12_RESOURCE_STATE_COPY_DEST, dst_state);
|
||||
transition_resource_state(context->list, s->resource, D3D12_RESOURCE_STATE_COPY_SOURCE, src_state);
|
||||
|
||||
hr = ID3D12GraphicsCommandList_Close(context->list);
|
||||
ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
|
||||
exec_command_list(context->queue, context->list);
|
||||
wait_queue_idle(context->device, context->queue);
|
||||
reset_command_list(context->list, context->allocator);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct resource_readback *d3d12_runner_get_resource_readback(struct shader_runner *r, struct resource *res)
|
||||
{
|
||||
struct d3d12_shader_runner *runner = d3d12_shader_runner(r);
|
||||
@ -933,6 +960,7 @@ static const struct shader_runner_ops d3d12_runner_ops =
|
||||
.dispatch = d3d12_runner_dispatch,
|
||||
.clear = d3d12_runner_clear,
|
||||
.draw = d3d12_runner_draw,
|
||||
.copy = d3d12_runner_copy,
|
||||
.get_resource_readback = d3d12_runner_get_resource_readback,
|
||||
.release_readback = d3d12_runner_release_readback,
|
||||
};
|
||||
|
@ -546,6 +546,11 @@ static bool d3d9_runner_draw(struct shader_runner *r,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool d3d9_runner_copy(struct shader_runner *r, struct resource *src, struct resource *dst)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct d3d9_resource_readback
|
||||
{
|
||||
struct resource_readback rb;
|
||||
@ -599,6 +604,7 @@ static const struct shader_runner_ops d3d9_runner_ops =
|
||||
.dispatch = d3d9_runner_dispatch,
|
||||
.clear = d3d9_runner_clear,
|
||||
.draw = d3d9_runner_draw,
|
||||
.copy = d3d9_runner_copy,
|
||||
.get_resource_readback = d3d9_runner_get_resource_readback,
|
||||
.release_readback = d3d9_runner_release_readback,
|
||||
};
|
||||
|
@ -113,6 +113,7 @@ static bool check_gl_extensions(struct gl_runner *runner)
|
||||
{
|
||||
"GL_ARB_clip_control",
|
||||
"GL_ARB_compute_shader",
|
||||
"GL_ARB_copy_image",
|
||||
"GL_ARB_sampler_objects",
|
||||
"GL_ARB_shader_image_load_store",
|
||||
"GL_ARB_texture_storage",
|
||||
@ -1249,6 +1250,28 @@ static bool gl_runner_draw(struct shader_runner *r,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_runner_copy(struct shader_runner *r, struct resource *src, struct resource *dst)
|
||||
{
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct gl_resource_readback
|
||||
{
|
||||
struct resource_readback rb;
|
||||
@ -1330,6 +1353,7 @@ static const struct shader_runner_ops gl_runner_ops =
|
||||
.dispatch = gl_runner_dispatch,
|
||||
.clear = gl_runner_clear,
|
||||
.draw = gl_runner_draw,
|
||||
.copy = gl_runner_copy,
|
||||
.get_resource_readback = gl_runner_get_resource_readback,
|
||||
.release_readback = gl_runner_release_readback,
|
||||
};
|
||||
|
@ -1256,6 +1256,66 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static VkImageLayout resource_get_layout(struct resource *r)
|
||||
{
|
||||
if (r->desc.type == RESOURCE_TYPE_RENDER_TARGET)
|
||||
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
if (r->desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
|
||||
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
if (r->desc.type == RESOURCE_TYPE_TEXTURE)
|
||||
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, struct resource *dst)
|
||||
{
|
||||
struct vulkan_shader_runner *runner = vulkan_shader_runner(r);
|
||||
const struct vulkan_test_context *context = &runner->context;
|
||||
VkImageAspectFlags aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
struct vulkan_resource *s = vulkan_resource(src);
|
||||
struct vulkan_resource *d = vulkan_resource(dst);
|
||||
VkImageLayout src_layout, dst_layout;
|
||||
VkImageCopy vk_image_copy;
|
||||
unsigned int l;
|
||||
|
||||
if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER)
|
||||
return false;
|
||||
|
||||
if (src->desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
|
||||
aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
src_layout = resource_get_layout(src);
|
||||
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,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
vk_image_copy.srcSubresource = (VkImageSubresourceLayers){.aspectMask = aspect_mask, .layerCount = 1};
|
||||
vk_image_copy.srcOffset = (VkOffset3D){.x = 0, .y = 0, .z = 0};
|
||||
vk_image_copy.dstSubresource = vk_image_copy.srcSubresource;
|
||||
vk_image_copy.dstOffset = vk_image_copy.srcOffset;
|
||||
vk_image_copy.extent.depth = 1;
|
||||
|
||||
for (l = 0; l < src->desc.level_count; ++l)
|
||||
{
|
||||
vk_image_copy.srcSubresource.mipLevel = l;
|
||||
vk_image_copy.dstSubresource.mipLevel = l;
|
||||
vk_image_copy.extent.width = get_level_dimension(src->desc.width, l);
|
||||
vk_image_copy.extent.height = get_level_dimension(src->desc.height, l);
|
||||
|
||||
VK_CALL(vkCmdCopyImage(context->cmd_buffer, s->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
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);
|
||||
end_command_buffer(context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct vulkan_resource_readback
|
||||
{
|
||||
struct resource_readback rb;
|
||||
@ -1300,13 +1360,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
|
||||
|
||||
aspect_mask = (resource->r.desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
|
||||
? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
if (resource->r.desc.type == RESOURCE_TYPE_RENDER_TARGET)
|
||||
layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
else if (resource->r.desc.type == RESOURCE_TYPE_DEPTH_STENCIL)
|
||||
layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
else
|
||||
layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
layout = resource_get_layout(res);
|
||||
|
||||
begin_command_buffer(context);
|
||||
|
||||
@ -1388,6 +1442,7 @@ static const struct shader_runner_ops vulkan_runner_ops =
|
||||
.dispatch = vulkan_runner_dispatch,
|
||||
.clear = vulkan_runner_clear,
|
||||
.draw = vulkan_runner_draw,
|
||||
.copy = vulkan_runner_copy,
|
||||
.get_resource_readback = vulkan_runner_get_resource_readback,
|
||||
.release_readback = vulkan_runner_release_readback,
|
||||
};
|
||||
@ -1615,6 +1670,7 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
|
||||
features.x = VK_TRUE
|
||||
|
||||
ENABLE_FEATURE(fragmentStoresAndAtomics);
|
||||
ENABLE_FEATURE(sampleRateShading);
|
||||
ENABLE_FEATURE(shaderClipDistance);
|
||||
ENABLE_FEATURE(shaderImageGatherExtended);
|
||||
ENABLE_FEATURE(shaderStorageImageWriteWithoutFormat);
|
||||
|
@ -60,6 +60,7 @@ VK_DEVICE_PFN(vkCmdBindPipeline)
|
||||
VK_DEVICE_PFN(vkCmdBindVertexBuffers)
|
||||
VK_DEVICE_PFN(vkCmdClearAttachments)
|
||||
VK_DEVICE_PFN(vkCmdCopyBufferToImage)
|
||||
VK_DEVICE_PFN(vkCmdCopyImage)
|
||||
VK_DEVICE_PFN(vkCmdCopyImageToBuffer)
|
||||
VK_DEVICE_PFN(vkCmdDispatch)
|
||||
VK_DEVICE_PFN(vkCmdDraw)
|
||||
|
Loading…
Reference in New Issue
Block a user