libs/vkd3d: Implement d3d12_command_list_ClearDepthStencilView().

This commit is contained in:
Henri Verbeet 2016-11-02 20:57:23 +01:00
parent f252d6cd31
commit 2213e126cf
4 changed files with 209 additions and 46 deletions

View File

@ -45,6 +45,7 @@ typedef enum DXGI_FORMAT
DXGI_FORMAT_R8G8B8A8_TYPELESS = 0x1b,
DXGI_FORMAT_R8G8B8A8_UNORM = 0x1c,
DXGI_FORMAT_D32_FLOAT = 0x28,
DXGI_FORMAT_R32_FLOAT = 0x29,
DXGI_FORMAT_B8G8R8A8_UNORM = 0x57,

View File

@ -2182,23 +2182,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_invalidate_current_framebuffer(list);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList *iface,
D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, FLOAT depth, UINT8 stencil,
UINT rect_count, const D3D12_RECT *rects)
static void d3d12_command_list_clear(struct d3d12_command_list *list, const struct vkd3d_vk_device_procs *vk_procs,
const struct VkAttachmentDescription *attachment_desc, const struct VkAttachmentReference *color_reference,
const struct VkAttachmentReference *ds_reference, VkImageView vk_view, size_t width, size_t height,
const union VkClearValue *clear_value, unsigned int rect_count, const D3D12_RECT *rects)
{
FIXME("iface %p, dsv %#lx, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p stub!\n",
iface, dsv.ptr, flags, depth, stencil, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList *iface,
D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects)
{
const union VkClearValue clear_value = {{{color[0], color[1], color[2], color[3]}}};
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
struct d3d12_rtv_desc *rtv_desc = (struct d3d12_rtv_desc *)rtv.ptr;
struct VkAttachmentDescription attachment_desc;
const struct vkd3d_vk_device_procs *vk_procs;
struct VkAttachmentReference color_reference;
struct VkSubpassDescription sub_pass_desc;
struct VkRenderPassCreateInfo pass_desc;
struct VkRenderPassBeginInfo begin_desc;
@ -2209,45 +2197,25 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
unsigned int i;
VkResult vr;
TRACE("iface %p, rtv %#lx, color %p, rect_count %u, rects %p.\n",
iface, rtv.ptr, color, rect_count, rects);
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
vk_procs = &list->device->vk_procs;
if (!rect_count)
{
full_rect.top = 0;
full_rect.left = 0;
full_rect.bottom = rtv_desc->height;
full_rect.right = rtv_desc->width;
full_rect.bottom = height;
full_rect.right = width;
rect_count = 1;
rects = &full_rect;
}
attachment_desc.flags = 0;
attachment_desc.format = rtv_desc->format;
attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT;
attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment_desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
color_reference.attachment = 0;
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
sub_pass_desc.flags = 0;
sub_pass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
sub_pass_desc.inputAttachmentCount = 0;
sub_pass_desc.pInputAttachments = NULL;
sub_pass_desc.colorAttachmentCount = 1;
sub_pass_desc.pColorAttachments = &color_reference;
sub_pass_desc.colorAttachmentCount = !!color_reference;
sub_pass_desc.pColorAttachments = color_reference;
sub_pass_desc.pResolveAttachments = NULL;
sub_pass_desc.pDepthStencilAttachment = NULL;
sub_pass_desc.pDepthStencilAttachment = ds_reference;
sub_pass_desc.preserveAttachmentCount = 0;
sub_pass_desc.pPreserveAttachments = NULL;
@ -2255,7 +2223,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
pass_desc.pNext = NULL;
pass_desc.flags = 0;
pass_desc.attachmentCount = 1;
pass_desc.pAttachments = &attachment_desc;
pass_desc.pAttachments = attachment_desc;
pass_desc.subpassCount = 1;
pass_desc.pSubpasses = &sub_pass_desc;
pass_desc.dependencyCount = 0;
@ -2278,9 +2246,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
fb_desc.flags = 0;
fb_desc.renderPass = vk_render_pass;
fb_desc.attachmentCount = 1;
fb_desc.pAttachments = &rtv_desc->vk_view;
fb_desc.width = rtv_desc->width;
fb_desc.height = rtv_desc->height;
fb_desc.pAttachments = &vk_view;
fb_desc.width = width;
fb_desc.height = height;
fb_desc.layers = 1;
if ((vr = VK_CALL(vkCreateFramebuffer(list->device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0)
{
@ -2300,7 +2268,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
begin_desc.renderPass = vk_render_pass;
begin_desc.framebuffer = vk_framebuffer;
begin_desc.clearValueCount = 1;
begin_desc.pClearValues = &clear_value;
begin_desc.pClearValues = clear_value;
for (i = 0; i < rect_count; ++i)
{
@ -2313,6 +2281,85 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
}
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList *iface,
D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil,
UINT rect_count, const D3D12_RECT *rects)
{
const union VkClearValue clear_value = {.depthStencil = {depth, stencil}};
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
struct d3d12_dsv_desc *dsv_desc = (struct d3d12_dsv_desc *)dsv.ptr;
struct VkAttachmentDescription attachment_desc;
struct VkAttachmentReference ds_reference;
TRACE("iface %p, dsv %#lx, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n",
iface, dsv.ptr, flags, depth, stencil, rect_count, rects);
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
attachment_desc.flags = 0;
attachment_desc.format = dsv_desc->format;
attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT;
if (flags & D3D12_CLEAR_FLAG_DEPTH)
{
attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
}
else
{
attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
if (flags & D3D12_CLEAR_FLAG_STENCIL)
{
attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
}
else
{
attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
attachment_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachment_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
ds_reference.attachment = 0;
ds_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, NULL, &ds_reference,
dsv_desc->vk_view, dsv_desc->width, dsv_desc->height, &clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList *iface,
D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects)
{
const union VkClearValue clear_value = {{{color[0], color[1], color[2], color[3]}}};
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
struct d3d12_rtv_desc *rtv_desc = (struct d3d12_rtv_desc *)rtv.ptr;
struct VkAttachmentDescription attachment_desc;
struct VkAttachmentReference color_reference;
TRACE("iface %p, rtv %#lx, color %p, rect_count %u, rects %p.\n",
iface, rtv.ptr, color, rect_count, rects);
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
attachment_desc.flags = 0;
attachment_desc.format = rtv_desc->format;
attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT;
attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment_desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
color_reference.attachment = 0;
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, &color_reference, NULL,
rtv_desc->vk_view, rtv_desc->width, rtv_desc->height, &clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList *iface,
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle,
ID3D12Resource *resource, UINT rect_count, const D3D12_RECT *rects)

View File

@ -29,6 +29,7 @@ static const struct vkd3d_format vkd3d_formats[] =
{DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT, 16, VK_IMAGE_ASPECT_COLOR_BIT},
{DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT, 12, VK_IMAGE_ASPECT_COLOR_BIT},
{DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, 4, VK_IMAGE_ASPECT_COLOR_BIT},
{DXGI_FORMAT_D32_FLOAT, VK_FORMAT_D32_SFLOAT, 4, VK_IMAGE_ASPECT_DEPTH_BIT},
{DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT, 4, VK_IMAGE_ASPECT_COLOR_BIT},
{DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, 4, VK_IMAGE_ASPECT_COLOR_BIT},
{DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, 4, VK_IMAGE_ASPECT_COLOR_BIT},

View File

@ -323,6 +323,7 @@ static unsigned int format_size(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_D32_FLOAT:
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
return 4;
@ -2290,6 +2291,118 @@ static void test_multithread_fence_wait(void)
ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
}
static void test_clear_depth_stencil_view(void)
{
D3D12_COMMAND_QUEUE_DESC command_queue_desc;
ID3D12CommandAllocator *command_allocator;
D3D12_DESCRIPTOR_HEAP_DESC dsv_heap_desc;
ID3D12GraphicsCommandList *command_list;
D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle;
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_RESOURCE_DESC resource_desc;
unsigned int dsv_increment_size;
ID3D12DescriptorHeap *dsv_heap;
D3D12_CLEAR_VALUE clear_value;
struct resource_readback rb;
ID3D12CommandQueue *queue;
ID3D12Resource *resource;
ID3D12Device *device;
unsigned int x, y;
ULONG refcount;
HRESULT hr;
if (!(device = create_device()))
{
skip("Failed to create device.\n");
return;
}
command_queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
command_queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
command_queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
command_queue_desc.NodeMask = 0;
hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc,
&IID_ID3D12CommandQueue, (void **)&queue);
ok(SUCCEEDED(hr), "CreateCommandQueue failed, hr %#x.\n", hr);
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
&IID_ID3D12CommandAllocator, (void **)&command_allocator);
ok(SUCCEEDED(hr), "CreateCommandAllocator failed, hr %#x.\n", hr);
hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
ok(SUCCEEDED(hr), "CreateCommandList failed, hr %#x.\n", hr);
dsv_heap_desc.NumDescriptors = 1;
dsv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
dsv_heap_desc.NodeMask = 0;
hr = ID3D12Device_CreateDescriptorHeap(device, &dsv_heap_desc,
&IID_ID3D12DescriptorHeap, (void **)&dsv_heap);
ok(SUCCEEDED(hr), "CreateDescriptorHeap failed, hr %#x.\n", hr);
dsv_increment_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
trace("DSV descriptor handle increment size: %u.\n", dsv_increment_size);
ok(dsv_increment_size, "Got unexpectd increment size %#x.\n", dsv_increment_size);
memset(&heap_properties, 0, sizeof(heap_properties));
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resource_desc.Alignment = 0;
resource_desc.Width = 32;
resource_desc.Height = 32;
resource_desc.DepthOrArraySize = 1;
resource_desc.MipLevels = 1;
resource_desc.Format = DXGI_FORMAT_D32_FLOAT;
resource_desc.SampleDesc.Count = 1;
resource_desc.SampleDesc.Quality = 0;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
clear_value.Format = DXGI_FORMAT_D32_FLOAT;
clear_value.DepthStencil.Depth = 0.5f;
clear_value.DepthStencil.Stencil = 0x3;
hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_DEPTH_WRITE, &clear_value, &IID_ID3D12Resource, (void **)&resource);
ok(SUCCEEDED(hr), "CreateCommittedResource failed, hr %#x.\n", hr);
dsv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(dsv_heap);
ID3D12Device_CreateDepthStencilView(device, resource, NULL, dsv_handle);
ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 0.75f, 0x7, 0, NULL);
transition_resource_state(command_list, resource,
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
hr = ID3D12GraphicsCommandList_Close(command_list);
ok(SUCCEEDED(hr), "Close failed, hr %#x.\n", hr);
exec_command_list(queue, command_list);
wait_queue_idle(device, queue);
hr = ID3D12CommandAllocator_Reset(command_allocator);
ok(SUCCEEDED(hr), "Command allocator reset failed, hr %#x.\n", hr);
hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
ok(SUCCEEDED(hr), "Command list reset failed, hr %#x.\n", hr);
get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list);
for (y = 0; y < resource_desc.Height; ++y)
{
for (x = 0; x < resource_desc.Width; ++x)
{
unsigned int v = get_readback_uint(&rb, x, y);
ok(v == 0x3f400000, "Got unexpected value 0x%08x at (%u, %u).\n", v, x, y);
}
}
release_resource_readback(&rb);
ID3D12GraphicsCommandList_Release(command_list);
ID3D12CommandAllocator_Release(command_allocator);
ID3D12Resource_Release(resource);
ID3D12CommandQueue_Release(queue);
ID3D12DescriptorHeap_Release(dsv_heap);
refcount = ID3D12Device_Release(device);
ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
}
static void test_clear_render_target_view(void)
{
static const float green[] = { 0.0f, 1.0f, 0.0f, 1.0f };
@ -3138,6 +3251,7 @@ START_TEST(d3d12)
run_test(test_cpu_signal_fence);
run_test(test_gpu_signal_fence);
run_test(test_multithread_fence_wait);
run_test(test_clear_depth_stencil_view);
run_test(test_clear_render_target_view);
run_test(test_draw_instanced);
run_test(test_texture_resource_barriers);