From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
This should be the last feature needed to implement D3D12 swapchains in Wine.
Vulkan swapchains are quite limited, e.g. * Vulkan implementations support very limited set of formats for swapchains, * views with a different format cannot be created for swapchains, * swapchains are not multisampled (AFAIK it's the same in D3D12).
This patch adds flexibility needed to emulate support for missing swapchain features, e.g. additional swapchain formats.
--- demos/demo_xcb.h | 31 ++++++++++++++++--------------- include/vkd3d.h | 20 ++++++++++++++------ libs/vkd3d/command.c | 28 +++++++++++++++++++--------- libs/vkd3d/resource.c | 16 +++++++++++----- libs/vkd3d/vkd3d_private.h | 3 ++- 5 files changed, 62 insertions(+), 36 deletions(-)
diff --git a/demos/demo_xcb.h b/demos/demo_xcb.h index 9980b506ffb6..053db0df9bab 100644 --- a/demos/demo_xcb.h +++ b/demos/demo_xcb.h @@ -307,13 +307,13 @@ static inline void demo_set_idle_func(struct demo *demo, static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *command_queue, struct demo_window *window, const struct demo_swapchain_desc *desc) { + struct vkd3d_image_resource_create_info resource_create_info; struct VkSwapchainCreateInfoKHR vk_swapchain_desc; struct VkXcbSurfaceCreateInfoKHR surface_desc; VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE; uint32_t format_count, queue_family_index; VkSurfaceCapabilitiesKHR surface_caps; VkPhysicalDevice vk_physical_device; - D3D12_RESOURCE_DESC resource_desc; VkFence vk_fence = VK_NULL_HANDLE; struct demo_swapchain *swapchain; unsigned int image_count, i, j; @@ -446,22 +446,23 @@ static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *c vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX); vkResetFences(vk_device, 1, &vk_fence);
- resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - resource_desc.Alignment = 0; - resource_desc.Width = desc->width; - resource_desc.Height = desc->height; - resource_desc.DepthOrArraySize = 1; - resource_desc.MipLevels = 1; - resource_desc.Format = desc->format; - resource_desc.SampleDesc.Count = 1; - resource_desc.SampleDesc.Quality = 0; - resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_create_info.desc.Alignment = 0; + resource_create_info.desc.Width = desc->width; + resource_create_info.desc.Height = desc->height; + resource_create_info.desc.DepthOrArraySize = 1; + resource_create_info.desc.MipLevels = 1; + resource_create_info.desc.Format = desc->format; + resource_create_info.desc.SampleDesc.Count = 1; + resource_create_info.desc.SampleDesc.Quality = 0; + resource_create_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_create_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resource_create_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION; + resource_create_info.present_state = D3D12_RESOURCE_STATE_PRESENT; for (i = 0; i < image_count; ++i) { - if (FAILED(vkd3d_create_image_resource(d3d12_device, &resource_desc, vk_images[i], - VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_SWAPCHAIN_IMAGE, - &swapchain->buffers[i]))) + resource_create_info.vk_image = vk_images[i]; + if (FAILED(vkd3d_create_image_resource(d3d12_device, &resource_create_info, &swapchain->buffers[i]))) { for (j = 0; j < i; ++j) { diff --git a/include/vkd3d.h b/include/vkd3d.h index 6ec85dbf2ffb..692b58d70065 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -73,9 +73,17 @@ struct vkd3d_device_create_info LUID adapter_luid; };
-/* resource flags */ +/* vkd3d_image_resource_create_info flags */ #define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001 -#define VKD3D_RESOURCE_SWAPCHAIN_IMAGE 0x00000002 +#define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002 + +struct vkd3d_image_resource_create_info +{ + VkImage vk_image; + D3D12_RESOURCE_DESC desc; + unsigned int flags; + D3D12_RESOURCE_STATES present_state; +};
#ifndef VKD3D_NO_PROTOTYPES
@@ -96,8 +104,8 @@ uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue); VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue); void vkd3d_release_vk_queue(ID3D12CommandQueue *queue);
-HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc, - VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource); +HRESULT vkd3d_create_image_resource(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource); ULONG vkd3d_resource_decref(ID3D12Resource *resource); ULONG vkd3d_resource_incref(ID3D12Resource *resource);
@@ -131,8 +139,8 @@ typedef uint32_t (*PFN_vkd3d_get_vk_queue_family_index)(ID3D12CommandQueue *queu typedef VkQueue (*PFN_vkd3d_acquire_vk_queue)(ID3D12CommandQueue *queue); typedef void (*PFN_vkd3d_release_vk_queue)(ID3D12CommandQueue *queue);
-typedef HRESULT (*PFN_vkd3d_create_image_resource)(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc, - VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource); +typedef HRESULT (*PFN_vkd3d_create_image_resource)(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource); typedef ULONG (*PFN_vkd3d_resource_decref)(ID3D12Resource *resource); typedef ULONG (*PFN_vkd3d_resource_incref)(ID3D12Resource *resource);
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 1c0a18ae09e7..39094c24e913 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1150,7 +1150,8 @@ static void d3d12_command_list_invalidate_bindings(struct d3d12_command_list *li } }
-static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, bool is_swapchain_image, +static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, + bool is_swapchain_image, D3D12_RESOURCE_STATES present_state, VkAccessFlags *access_mask, VkPipelineStageFlags *stage_flags, VkImageLayout *image_layout) { switch (state) @@ -1164,10 +1165,18 @@ static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, * state when GPU finishes execution of a command list. */ if (is_swapchain_image) { - *access_mask = VK_ACCESS_MEMORY_READ_BIT; - *stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - if (image_layout) - *image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + if (present_state == D3D12_RESOURCE_STATE_PRESENT) + { + *access_mask = VK_ACCESS_MEMORY_READ_BIT; + *stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + if (image_layout) + *image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + } + else + { + vk_barrier_parameters_from_d3d12_resource_state(present_state, + false, 0, access_mask, stage_flags, image_layout); + } } else { @@ -1353,7 +1362,7 @@ static void d3d12_command_list_transition_resource_to_initial_state(struct d3d12 VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED;
if (!vk_barrier_parameters_from_d3d12_resource_state(resource->initial_state, - resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE, + resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION, resource->present_state, &barrier.dstAccessMask, &dst_stage_mask, &barrier.newLayout)) { FIXME("Unhandled state %#x.\n", resource->initial_state); @@ -2877,14 +2886,14 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC sub_resource_idx = transition->Subresource;
if (!vk_barrier_parameters_from_d3d12_resource_state(transition->StateBefore, - resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE, + resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION, resource->present_state, &src_access_mask, &src_stage_mask, &layout_before)) { FIXME("Unhandled state %#x.\n", transition->StateBefore); continue; } if (!vk_barrier_parameters_from_d3d12_resource_state(transition->StateAfter, - resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE, + resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION, resource->present_state, &dst_access_mask, &dst_stage_mask, &layout_after)) { FIXME("Unhandled state %#x.\n", transition->StateAfter); @@ -2905,7 +2914,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC
resource = unsafe_impl_from_ID3D12Resource(uav->pResource); vk_barrier_parameters_from_d3d12_resource_state(D3D12_RESOURCE_STATE_UNORDERED_ACCESS, - resource && (resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE), + resource && (resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION), + resource ? resource->present_state : 0, &access_mask, &stage_mask, &image_layout); src_access_mask = dst_access_mask = access_mask; src_stage_mask = dst_stage_mask = stage_mask; diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 81135d373ae7..4746ee2cf59b 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -797,28 +797,34 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device, return S_OK; }
-HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc, - VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource) +HRESULT vkd3d_create_image_resource(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource) { struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device(device); struct d3d12_resource *object;
+ TRACE("device %p, create_info %p, resource %p.\n", device, create_info, resource); + if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY;
object->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl; object->refcount = 1; object->internal_refcount = 1; - object->desc = *desc; - object->u.vk_image = vk_image; + object->desc = create_info->desc; + object->u.vk_image = create_info->vk_image; object->vk_memory = VK_NULL_HANDLE; object->flags = VKD3D_RESOURCE_EXTERNAL; - object->flags |= resource_flags & VKD3D_RESOURCE_PUBLIC_FLAGS; + object->flags |= create_info->flags & VKD3D_RESOURCE_PUBLIC_FLAGS; object->map_count = 0; object->map_data = NULL; memset(&object->heap_properties, 0, sizeof(object->heap_properties)); object->heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; object->initial_state = D3D12_RESOURCE_STATE_COMMON; + if (create_info->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION) + object->present_state = create_info->present_state; + else + object->present_state = D3D12_RESOURCE_STATE_COMMON; object->device = d3d12_device; ID3D12Device_AddRef(&d3d12_device->ID3D12Device_iface);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 988522f99e70..cf3112e845b3 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -175,7 +175,7 @@ HRESULT d3d12_fence_create(struct d3d12_device *device, UINT64 initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence) DECLSPEC_HIDDEN;
#define VKD3D_RESOURCE_PUBLIC_FLAGS \ - (VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_SWAPCHAIN_IMAGE) + (VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION) #define VKD3D_RESOURCE_EXTERNAL 0x00000004
/* ID3D12Resource */ @@ -202,6 +202,7 @@ struct d3d12_resource D3D12_HEAP_PROPERTIES heap_properties; D3D12_HEAP_FLAGS heap_flags; D3D12_RESOURCE_STATES initial_state; + D3D12_RESOURCE_STATES present_state;
struct d3d12_device *device; };
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- Makefile.am | 5 +- tests/d3d12.c | 695 +-------------------------------------------- tests/vkd3d_d3d12_test.h | 720 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 725 insertions(+), 695 deletions(-) create mode 100644 tests/vkd3d_d3d12_test.h
diff --git a/Makefile.am b/Makefile.am index 260641bc8194..d10a0e35938f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,6 +39,9 @@ vkd3d_tests = \ vkd3d_cross_tests = \ tests/d3d12
+vkd3d_test_headers = \ + tests/vkd3d_d3d12_test.h + vkd3d_demos = \ demos/gears \ demos/triangle @@ -129,7 +132,7 @@ tests_vkd3d_api_LDADD = libvkd3d.la @VULKAN_LIBS@ DEMOS_LDADD = $(LDADD) libvkd3d-shader.la @XCB_LIBS@ @VULKAN_LIBS@ DEMOS_CFLAGS = @XCB_CFLAGS@ noinst_PROGRAMS += $(vkd3d_demos) -EXTRA_DIST += $(vkd3d_demos_headers) +EXTRA_DIST += $(vkd3d_test_headers) $(vkd3d_demos_headers)
demos_gears_CFLAGS = $(DEMOS_CFLAGS) demos_gears_LDADD = $(DEMOS_LDADD) -lm diff --git a/tests/d3d12.c b/tests/d3d12.c index 587f8b72d47a..0f858ff985d1 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -55,13 +55,7 @@ typedef int HRESULT; # include "vkd3d_utils.h" #endif
-static void set_rect(RECT *rect, int left, int top, int right, int bottom) -{ - rect->left = left; - rect->right = right; - rect->top = top; - rect->bottom = bottom; -} +#include "vkd3d_d3d12_test.h"
static void set_box(D3D12_BOX *box, unsigned int left, unsigned int top, unsigned int front, unsigned int right, unsigned int bottom, unsigned int back) @@ -74,17 +68,6 @@ static void set_box(D3D12_BOX *box, unsigned int left, unsigned int top, unsigne box->back = back; }
-static void set_viewport(D3D12_VIEWPORT *vp, float x, float y, - float width, float height, float min_depth, float max_depth) -{ - vp->TopLeftX = x; - vp->TopLeftY = y; - vp->Width = width; - vp->Height = height; - vp->MinDepth = min_depth; - vp->MaxDepth = max_depth; -} - struct vec2 { float x, y; @@ -153,22 +136,6 @@ static bool compare_uint16(uint16_t a, uint16_t b, unsigned int max_diff) return abs(a - b) <= max_diff; }
-static bool compare_color(DWORD c1, DWORD c2, BYTE max_diff) -{ - if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) - return false; - c1 >>= 8; c2 >>= 8; - if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) - return false; - c1 >>= 8; c2 >>= 8; - if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) - return false; - c1 >>= 8; c2 >>= 8; - if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) - return false; - return true; -} - static ULONG get_refcount(void *iface) { IUnknown *unk = iface; @@ -190,49 +157,6 @@ static void check_interface_(unsigned int line, IUnknown *iface, REFIID riid, bo IUnknown_Release(unk); }
-static HRESULT create_root_signature(ID3D12Device *device, const D3D12_ROOT_SIGNATURE_DESC *desc, - ID3D12RootSignature **root_signature) -{ - ID3DBlob *blob; - HRESULT hr; - - if (FAILED(hr = D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1_0, &blob, NULL))) - return hr; - - hr = ID3D12Device_CreateRootSignature(device, 0, ID3D10Blob_GetBufferPointer(blob), - ID3D10Blob_GetBufferSize(blob), &IID_ID3D12RootSignature, (void **)root_signature); - ID3D10Blob_Release(blob); - return hr; -} - -static D3D12_SHADER_BYTECODE shader_bytecode(const DWORD *code, size_t size) -{ - D3D12_SHADER_BYTECODE shader_bytecode = { code, size }; - return shader_bytecode; -} - -static void transition_sub_resource_state(ID3D12GraphicsCommandList *list, ID3D12Resource *resource, - unsigned int sub_resource_idx, D3D12_RESOURCE_STATES state_before, D3D12_RESOURCE_STATES state_after) -{ - D3D12_RESOURCE_BARRIER barrier; - - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = resource; - barrier.Transition.Subresource = sub_resource_idx; - barrier.Transition.StateBefore = state_before; - barrier.Transition.StateAfter = state_after; - - ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier); -} - -static void transition_resource_state(ID3D12GraphicsCommandList *list, ID3D12Resource *resource, - D3D12_RESOURCE_STATES state_before, D3D12_RESOURCE_STATES state_after) -{ - transition_sub_resource_state(list, resource, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, - state_before, state_after); -} - static void uav_barrier(ID3D12GraphicsCommandList *list, ID3D12Resource *resource) { D3D12_RESOURCE_BARRIER barrier; @@ -244,12 +168,6 @@ static void uav_barrier(ID3D12GraphicsCommandList *list, ID3D12Resource *resourc ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier); }
-static void exec_command_list(ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *list) -{ - ID3D12CommandList *lists[] = {(ID3D12CommandList *)list}; - ID3D12CommandQueue_ExecuteCommandLists(queue, 1, lists); -} - #define reset_command_list(a, b) reset_command_list_(__LINE__, a, b) static void reset_command_list_(unsigned int line, ID3D12GraphicsCommandList *list, ID3D12CommandAllocator *allocator) @@ -410,7 +328,6 @@ static HRESULT wait_for_fence(ID3D12Fence *fence, UINT64 value) return ret == WAIT_OBJECT_0 ? S_OK : E_FAIL; }
-#define wait_queue_idle(a, b) wait_queue_idle_(__LINE__, a, b) static void wait_queue_idle_(unsigned int line, ID3D12Device *device, ID3D12CommandQueue *queue) { ID3D12Fence *fence; @@ -443,38 +360,6 @@ static void update_buffer_data_(unsigned int line, ID3D12Resource *buffer, ID3D12Resource_Unmap(buffer, 0, NULL); }
-#define create_buffer(a, b, c, d, e) create_buffer_(__LINE__, a, b, c, d, e) -static ID3D12Resource *create_buffer_(unsigned int line, ID3D12Device *device, - D3D12_HEAP_TYPE heap_type, size_t size, D3D12_RESOURCE_FLAGS resource_flags, - D3D12_RESOURCE_STATES initial_resource_state) -{ - D3D12_HEAP_PROPERTIES heap_properties; - D3D12_RESOURCE_DESC resource_desc; - ID3D12Resource *buffer; - HRESULT hr; - - memset(&heap_properties, 0, sizeof(heap_properties)); - heap_properties.Type = heap_type; - - resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resource_desc.Alignment = 0; - resource_desc.Width = size; - resource_desc.Height = 1; - resource_desc.DepthOrArraySize = 1; - resource_desc.MipLevels = 1; - resource_desc.Format = DXGI_FORMAT_UNKNOWN; - resource_desc.SampleDesc.Count = 1; - resource_desc.SampleDesc.Quality = 0; - resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - resource_desc.Flags = resource_flags; - - hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, - D3D12_HEAP_FLAG_NONE, &resource_desc, initial_resource_state, - NULL, &IID_ID3D12Resource, (void **)&buffer); - ok_(line)(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); - return buffer; -} - #define create_default_buffer(a, b, c, d) create_default_buffer_(__LINE__, a, b, c, d) static ID3D12Resource *create_default_buffer_(unsigned int line, ID3D12Device *device, size_t size, D3D12_RESOURCE_FLAGS resource_flags, D3D12_RESOURCE_STATES initial_resource_state) @@ -496,44 +381,6 @@ static ID3D12Resource *create_upload_buffer_(unsigned int line, ID3D12Device *de return buffer; }
-#define create_readback_buffer(a, b) create_readback_buffer_(__LINE__, a, b) -static ID3D12Resource *create_readback_buffer_(unsigned int line, ID3D12Device *device, - size_t size) -{ - return create_buffer_(line, device, D3D12_HEAP_TYPE_READBACK, size, - D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST); -} - -#define create_texture(a, b, c, d, e) create_default_texture_(__LINE__, a, b, c, d, 0, e) -#define create_default_texture(a, b, c, d, e, f) create_default_texture_(__LINE__, a, b, c, d, e, f) -static ID3D12Resource *create_default_texture_(unsigned int line, ID3D12Device *device, - unsigned int width, unsigned int height, DXGI_FORMAT format, - D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) -{ - D3D12_HEAP_PROPERTIES heap_properties; - D3D12_RESOURCE_DESC resource_desc; - ID3D12Resource *texture; - HRESULT hr; - - memset(&heap_properties, 0, sizeof(heap_properties)); - heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; - - memset(&resource_desc, 0, sizeof(resource_desc)); - resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - resource_desc.Width = width; - resource_desc.Height = height; - resource_desc.DepthOrArraySize = 1; - resource_desc.MipLevels = 1; - resource_desc.Format = format; - resource_desc.SampleDesc.Count = 1; - resource_desc.Flags = flags; - hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, - &resource_desc, initial_state, NULL, &IID_ID3D12Resource, (void **)&texture); - ok_(line)(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); - - return texture; -} - static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src, unsigned int row_count, unsigned int slice_count, size_t row_size) { @@ -648,51 +495,6 @@ static void upload_texture_data_(unsigned int line, ID3D12Resource *texture, free(row_sizes); }
-static unsigned int format_size(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_UNKNOWN: - case DXGI_FORMAT_A8_UNORM: - return 1; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - return 16; - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8A8_UNORM: - return 4; - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16_UNORM: - return 2; - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - return 8; - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 16; - default: - trace("Unhandled format %#x.\n", format); - return 1; - } -} - static unsigned int format_block_width(DXGI_FORMAT format) { switch (format) @@ -741,15 +543,6 @@ static unsigned int format_block_height(DXGI_FORMAT format) } }
-struct resource_readback -{ - unsigned int width; - unsigned int height; - ID3D12Resource *resource; - unsigned int row_pitch; - void *data; -}; - static void get_buffer_readback_with_command_list(ID3D12Resource *buffer, DXGI_FORMAT format, struct resource_readback *rb, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) { @@ -800,69 +593,6 @@ static void get_buffer_readback_with_command_list(ID3D12Resource *buffer, DXGI_F ok(SUCCEEDED(hr), "Failed to map readback buffer, hr %#x.\n", hr); }
-static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsigned int sub_resource, - struct resource_readback *rb, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) -{ - D3D12_TEXTURE_COPY_LOCATION dst_location, src_location; - D3D12_RESOURCE_DESC resource_desc; - D3D12_RANGE read_range; - unsigned int miplevel; - ID3D12Device *device; - DXGI_FORMAT format; - HRESULT hr; - - hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device); - ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr); - - resource_desc = ID3D12Resource_GetDesc(texture); - ok(resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER, - "Resource %p is not texture.\n", texture); - ok(resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D, - "Readback not implemented for 3D textures.\n"); - - miplevel = sub_resource % resource_desc.MipLevels; - rb->width = max(1, resource_desc.Width >> miplevel); - rb->height = max(1, resource_desc.Height >> miplevel); - rb->row_pitch = align(rb->width * format_size(resource_desc.Format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - rb->data = NULL; - - format = resource_desc.Format; - - rb->resource = create_readback_buffer(device, rb->row_pitch * rb->height); - - dst_location.pResource = rb->resource; - dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst_location.PlacedFootprint.Offset = 0; - dst_location.PlacedFootprint.Footprint.Format = format; - dst_location.PlacedFootprint.Footprint.Width = rb->width; - dst_location.PlacedFootprint.Footprint.Height = rb->height; - dst_location.PlacedFootprint.Footprint.Depth = 1; - dst_location.PlacedFootprint.Footprint.RowPitch = rb->row_pitch; - - src_location.pResource = texture; - src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src_location.SubresourceIndex = sub_resource; - - ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, NULL); - hr = ID3D12GraphicsCommandList_Close(command_list); - ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr); - - exec_command_list(queue, command_list); - wait_queue_idle(device, queue); - ID3D12Device_Release(device); - - read_range.Begin = 0; - read_range.End = resource_desc.Width; - hr = ID3D12Resource_Map(rb->resource, 0, &read_range, &rb->data); - ok(SUCCEEDED(hr), "Failed to map readback buffer, hr %#x.\n", hr); -} - -static void *get_readback_data(struct resource_readback *rb, unsigned int x, unsigned int y, - size_t element_size) -{ - return &((BYTE *)rb->data)[rb->row_pitch * y + x * element_size]; -} - static uint8_t get_readback_uint8(struct resource_readback *rb, unsigned int x, unsigned int y) { return *(uint8_t *)get_readback_data(rb, x, y, sizeof(uint8_t)); @@ -873,11 +603,6 @@ static uint16_t get_readback_uint16(struct resource_readback *rb, unsigned int x return *(uint16_t *)get_readback_data(rb, x, y, sizeof(uint16_t)); }
-static unsigned int get_readback_uint(struct resource_readback *rb, unsigned int x, unsigned int y) -{ - return *(unsigned int *)get_readback_data(rb, x, y, sizeof(unsigned int)); -} - static UINT64 get_readback_uint64(struct resource_readback *rb, unsigned int x, unsigned int y) { return *(UINT64 *)get_readback_data(rb, x, y, sizeof(UINT64)); @@ -898,13 +623,6 @@ static const struct uvec4 *get_readback_uvec4(struct resource_readback *rb, unsi return get_readback_data(rb, x, y, sizeof(struct uvec4)); }
-static void release_resource_readback(struct resource_readback *rb) -{ - D3D12_RANGE range = {0, 0}; - ID3D12Resource_Unmap(rb->resource, 0, &range); - ID3D12Resource_Release(rb->resource); -} - #define check_readback_data_float(a, b, c, d) check_readback_data_float_(__LINE__, a, b, c, d) static void check_readback_data_float_(unsigned int line, struct resource_readback *rb, const RECT *rect, float expected, unsigned int max_diff) @@ -1028,47 +746,6 @@ static void check_sub_resource_uint16_(unsigned int line, ID3D12Resource *textur release_resource_readback(&rb); }
-#define check_readback_data_uint(a, b, c, d) check_readback_data_uint_(__LINE__, a, b, c, d) -static void check_readback_data_uint_(unsigned int line, struct resource_readback *rb, - const RECT *rect, unsigned int expected, unsigned int max_diff) -{ - RECT r = {0, 0, rb->width, rb->height}; - unsigned int x = 0, y; - bool all_match = true; - unsigned int got = 0; - - if (rect) - r = *rect; - - for (y = r.top; y < r.bottom; ++y) - { - for (x = r.left; x < r.right; ++x) - { - got = get_readback_uint(rb, x, y); - if (!compare_color(got, expected, max_diff)) - { - all_match = false; - break; - } - } - if (!all_match) - break; - } - ok_(line)(all_match, "Got 0x%08x, expected 0x%08x at (%u, %u).\n", got, expected, x, y); -} - -#define check_sub_resource_uint(a, b, c, d, e, f) check_sub_resource_uint_(__LINE__, a, b, c, d, e, f) -static void check_sub_resource_uint_(unsigned int line, ID3D12Resource *texture, - unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, - unsigned int expected, unsigned int max_diff) -{ - struct resource_readback rb; - - get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list); - check_readback_data_uint_(line, &rb, NULL, expected, max_diff); - release_resource_readback(&rb); -} - #define check_sub_resource_vec4(a, b, c, d, e, f) check_sub_resource_vec4_(__LINE__, a, b, c, d, e, f) static void check_sub_resource_vec4_(unsigned int line, ID3D12Resource *texture, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, @@ -1159,25 +836,6 @@ static bool is_min_max_filtering_supported(ID3D12Device *device) return options.TiledResourcesTier >= D3D12_TILED_RESOURCES_TIER_2; }
-#define create_empty_root_signature(device, flags) create_empty_root_signature_(__LINE__, device, flags) -static ID3D12RootSignature *create_empty_root_signature_(unsigned int line, - ID3D12Device *device, D3D12_ROOT_SIGNATURE_FLAGS flags) -{ - D3D12_ROOT_SIGNATURE_DESC root_signature_desc; - ID3D12RootSignature *root_signature = NULL; - HRESULT hr; - - root_signature_desc.NumParameters = 0; - root_signature_desc.pParameters = NULL; - root_signature_desc.NumStaticSamplers = 0; - root_signature_desc.pStaticSamplers = NULL; - root_signature_desc.Flags = flags; - hr = create_root_signature(device, &root_signature_desc, &root_signature); - ok_(line)(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); - - return root_signature; -} - #define create_cb_root_signature(a, b, c, e) create_cb_root_signature_(__LINE__, a, b, c, e) static ID3D12RootSignature *create_cb_root_signature_(unsigned int line, ID3D12Device *device, unsigned int reg_idx, D3D12_SHADER_VISIBILITY shader_visibility, @@ -1300,236 +958,6 @@ static ID3D12PipelineState *create_compute_pipeline_state_(unsigned int line, ID return pipeline_state; }
-static void init_pipeline_state_desc(D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, - ID3D12RootSignature *root_signature, DXGI_FORMAT rt_format, - const D3D12_SHADER_BYTECODE *vs, const D3D12_SHADER_BYTECODE *ps, - const D3D12_INPUT_LAYOUT_DESC *input_layout) -{ - static const DWORD vs_code[] = - { -#if 0 - void main(uint id : SV_VertexID, out float4 position : SV_Position) - { - float2 coords = float2((id << 1) & 2, id & 2); - position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); - } -#endif - 0x43425844, 0xf900d25e, 0x68bfefa7, 0xa63ac0a7, 0xa476af7a, 0x00000001, 0x0000018c, 0x00000003, - 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, - 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978, - 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, - 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x000000f0, 0x00010050, - 0x0000003c, 0x0100086a, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, - 0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, - 0x00000001, 0x00004001, 0x00000001, 0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, - 0x00100042, 0x00000000, 0x0010100a, 0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, - 0x00000000, 0x00100086, 0x00000000, 0x0f000032, 0x00102032, 0x00000000, 0x00100046, 0x00000000, - 0x00004002, 0x40000000, 0xc0000000, 0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, - 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, - 0x00000000, 0x3f800000, 0x0100003e, - }; - static const DWORD ps_code[] = - { -#if 0 - void main(const in float4 position : SV_Position, out float4 target : SV_Target0) - { - target = float4(0.0f, 1.0f, 0.0f, 1.0f); - } -#endif - 0x43425844, 0x8a4a8140, 0x5eba8e0b, 0x714e0791, 0xb4b8eed2, 0x00000001, 0x000000d8, 0x00000003, - 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, - 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, - 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, - 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, - 0x0000000f, 0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, - 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, - }; - - memset(desc, 0, sizeof(*desc)); - desc->pRootSignature = root_signature; - if (vs) - desc->VS = *vs; - else - desc->VS = shader_bytecode(vs_code, sizeof(vs_code)); - if (ps) - desc->PS = *ps; - else - desc->PS = shader_bytecode(ps_code, sizeof(ps_code)); - desc->StreamOutput.RasterizedStream = 0; - desc->BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - desc->RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; - desc->RasterizerState.CullMode = D3D12_CULL_MODE_BACK; - if (input_layout) - desc->InputLayout = *input_layout; - desc->SampleMask = ~(UINT)0; - desc->PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - desc->NumRenderTargets = 1; - desc->RTVFormats[0] = rt_format; - desc->SampleDesc.Count = 1; -} - -#define create_pipeline_state(a, b, c, d, e, f) create_pipeline_state_(__LINE__, a, b, c, d, e, f) -static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Device *device, - ID3D12RootSignature *root_signature, DXGI_FORMAT rt_format, - const D3D12_SHADER_BYTECODE *vs, const D3D12_SHADER_BYTECODE *ps, - const D3D12_INPUT_LAYOUT_DESC *input_layout) -{ - D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_state_desc; - ID3D12PipelineState *pipeline_state; - HRESULT hr; - - init_pipeline_state_desc(&pipeline_state_desc, root_signature, rt_format, vs, ps, input_layout); - hr = ID3D12Device_CreateGraphicsPipelineState(device, &pipeline_state_desc, - &IID_ID3D12PipelineState, (void **)&pipeline_state); - ok_(line)(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr); - - return pipeline_state; -} - -struct test_context_desc -{ - unsigned int rt_width, rt_height; - DXGI_FORMAT rt_format; - unsigned int rt_descriptor_count; - unsigned int root_signature_flags; - bool no_render_target; - bool no_root_signature; - bool no_pipeline; - const D3D12_SHADER_BYTECODE *ps; -}; - -struct test_context -{ - ID3D12Device *device; - - ID3D12CommandQueue *queue; - ID3D12CommandAllocator *allocator; - ID3D12GraphicsCommandList *list; - - D3D12_RESOURCE_DESC render_target_desc; - ID3D12Resource *render_target; - - ID3D12DescriptorHeap *rtv_heap; - D3D12_CPU_DESCRIPTOR_HANDLE rtv; - - ID3D12RootSignature *root_signature; - ID3D12PipelineState *pipeline_state; - - D3D12_VIEWPORT viewport; - RECT scissor_rect; -}; - -#define create_render_target(context, a, b, c) create_render_target_(__LINE__, context, a, b, c) -static void create_render_target_(unsigned int line, struct test_context *context, - const struct test_context_desc *desc, ID3D12Resource **render_target, - const D3D12_CPU_DESCRIPTOR_HANDLE *rtv) -{ - D3D12_HEAP_PROPERTIES heap_properties; - D3D12_RESOURCE_DESC resource_desc; - D3D12_CLEAR_VALUE clear_value; - HRESULT hr; - - 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 = desc && desc->rt_width ? desc->rt_width : 32; - resource_desc.Height = desc && desc->rt_height ? desc->rt_height : 32; - resource_desc.DepthOrArraySize = 1; - resource_desc.MipLevels = 1; - resource_desc.Format = desc && desc->rt_format ? desc->rt_format : DXGI_FORMAT_R8G8B8A8_UNORM; - resource_desc.SampleDesc.Count = 1; - resource_desc.SampleDesc.Quality = 0; - resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - clear_value.Format = resource_desc.Format; - clear_value.Color[0] = 1.0f; - clear_value.Color[1] = 1.0f; - clear_value.Color[2] = 1.0f; - clear_value.Color[3] = 1.0f; - hr = ID3D12Device_CreateCommittedResource(context->device, - &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc, - D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value, - &IID_ID3D12Resource, (void **)render_target); - ok_(line)(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); - - context->render_target_desc = resource_desc; - - if (rtv) - ID3D12Device_CreateRenderTargetView(context->device, *render_target, NULL, *rtv); -} - -#define init_test_context(context, desc) init_test_context_(__LINE__, context, desc) -static bool init_test_context_(unsigned int line, struct test_context *context, - const struct test_context_desc *desc) -{ - D3D12_COMMAND_QUEUE_DESC command_queue_desc; - D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc; - ID3D12Device *device; - HRESULT hr; - - memset(context, 0, sizeof(*context)); - - if (!(context->device = create_device())) - { - skip_(line)("Failed to create device.\n"); - return false; - } - device = context->device; - - 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 **)&context->queue); - ok_(line)(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr); - - hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, - &IID_ID3D12CommandAllocator, (void **)&context->allocator); - ok_(line)(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr); - - hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, - context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list); - ok_(line)(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); - - if (desc && desc->no_render_target) - return true; - - rtv_heap_desc.NumDescriptors = desc && desc->rt_descriptor_count ? desc->rt_descriptor_count : 1; - rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - rtv_heap_desc.NodeMask = 0; - hr = ID3D12Device_CreateDescriptorHeap(device, &rtv_heap_desc, - &IID_ID3D12DescriptorHeap, (void **)&context->rtv_heap); - ok_(line)(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); - - context->rtv = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(context->rtv_heap); - - create_render_target_(line, context, desc, &context->render_target, &context->rtv); - - set_viewport(&context->viewport, 0.0f, 0.0f, - context->render_target_desc.Width, context->render_target_desc.Height, 0.0f, 1.0f); - set_rect(&context->scissor_rect, 0, 0, - context->render_target_desc.Width, context->render_target_desc.Height); - - if (desc && desc->no_root_signature) - return true; - - context->root_signature = create_empty_root_signature_(line, - device, desc ? desc->root_signature_flags : D3D12_ROOT_SIGNATURE_FLAG_NONE); - - if (desc && desc->no_pipeline) - return true; - - context->pipeline_state = create_pipeline_state_(line, device, - context->root_signature, context->render_target_desc.Format, - NULL, desc ? desc->ps : NULL, NULL); - - return true; -} - #define init_compute_test_context(context) init_compute_test_context_(__LINE__, context) static bool init_compute_test_context_(unsigned int line, struct test_context *context) { @@ -1565,127 +993,6 @@ static bool init_compute_test_context_(unsigned int line, struct test_context *c return true; }
-#define destroy_test_context(context) destroy_test_context_(__LINE__, context) -static void destroy_test_context_(unsigned int line, struct test_context *context) -{ - ULONG refcount; - - if (context->pipeline_state) - ID3D12PipelineState_Release(context->pipeline_state); - if (context->root_signature) - ID3D12RootSignature_Release(context->root_signature); - - if (context->rtv_heap) - ID3D12DescriptorHeap_Release(context->rtv_heap); - if (context->render_target) - ID3D12Resource_Release(context->render_target); - - ID3D12CommandAllocator_Release(context->allocator); - ID3D12CommandQueue_Release(context->queue); - ID3D12GraphicsCommandList_Release(context->list); - - refcount = ID3D12Device_Release(context->device); - ok_(line)(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); -} - -#define create_cpu_descriptor_heap(a, b, c) create_cpu_descriptor_heap_(__LINE__, a, b, c) -static ID3D12DescriptorHeap *create_cpu_descriptor_heap_(unsigned int line, ID3D12Device *device, - D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int descriptor_count) -{ - D3D12_DESCRIPTOR_HEAP_DESC heap_desc; - ID3D12DescriptorHeap *descriptor_heap; - HRESULT hr; - - heap_desc.Type = heap_type, - heap_desc.NumDescriptors = descriptor_count; - heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - heap_desc.NodeMask = 0; - hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, - &IID_ID3D12DescriptorHeap, (void **)&descriptor_heap); - ok_(line)(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); - - return descriptor_heap; -} - -#define create_gpu_descriptor_heap(a, b, c) create_gpu_descriptor_heap_(__LINE__, a, b, c) -static ID3D12DescriptorHeap *create_gpu_descriptor_heap_(unsigned int line, ID3D12Device *device, - D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int descriptor_count) -{ - D3D12_DESCRIPTOR_HEAP_DESC heap_desc; - ID3D12DescriptorHeap *descriptor_heap; - HRESULT hr; - - heap_desc.Type = heap_type, - heap_desc.NumDescriptors = descriptor_count; - heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - heap_desc.NodeMask = 0; - hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, - &IID_ID3D12DescriptorHeap, (void **)&descriptor_heap); - ok_(line)(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); - - return descriptor_heap; -} - -static D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_handle(ID3D12Device *device, - ID3D12DescriptorHeap *heap, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int offset) -{ - D3D12_CPU_DESCRIPTOR_HANDLE handle; - unsigned int descriptor_size; - - handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); - if (!offset) - return handle; - - descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, heap_type); - handle.ptr += offset * descriptor_size; - return handle; -} - -static D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_descriptor_handle(struct test_context *context, - ID3D12DescriptorHeap *heap, unsigned int offset) -{ - return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, offset); -} - -static D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_sampler_handle(struct test_context *context, - ID3D12DescriptorHeap *heap, unsigned int offset) -{ - return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, offset); -} - -static D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_rtv_handle(struct test_context *context, - ID3D12DescriptorHeap *heap, unsigned int offset) -{ - return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, offset); -} - -static D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_handle(ID3D12Device *device, - ID3D12DescriptorHeap *heap, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int offset) -{ - D3D12_GPU_DESCRIPTOR_HANDLE handle; - unsigned int descriptor_size; - - handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); - if (!offset) - return handle; - - descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, heap_type); - handle.ptr += offset * descriptor_size; - return handle; -} - -static D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_descriptor_handle(struct test_context *context, - ID3D12DescriptorHeap *heap, unsigned int offset) -{ - return get_gpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, offset); -} - -static D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_sampler_handle(struct test_context *context, - ID3D12DescriptorHeap *heap, unsigned int offset) -{ - return get_gpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, offset); -} - struct depth_stencil_resource { ID3D12Resource *texture; diff --git a/tests/vkd3d_d3d12_test.h b/tests/vkd3d_d3d12_test.h new file mode 100644 index 000000000000..538479e922c1 --- /dev/null +++ b/tests/vkd3d_d3d12_test.h @@ -0,0 +1,720 @@ +/* + * Copyright 2016-2018 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VKD3D_D3D12_TEST_H +#define __VKD3D_D3D12_TEST_H + +#define wait_queue_idle(a, b) wait_queue_idle_(__LINE__, a, b) +static void wait_queue_idle_(unsigned int line, ID3D12Device *device, ID3D12CommandQueue *queue); +static ID3D12Device *create_device(void); + +static void set_rect(RECT *rect, int left, int top, int right, int bottom) +{ + rect->left = left; + rect->right = right; + rect->top = top; + rect->bottom = bottom; +} + +static void set_viewport(D3D12_VIEWPORT *vp, float x, float y, + float width, float height, float min_depth, float max_depth) +{ + vp->TopLeftX = x; + vp->TopLeftY = y; + vp->Width = width; + vp->Height = height; + vp->MinDepth = min_depth; + vp->MaxDepth = max_depth; +} + +static bool compare_color(DWORD c1, DWORD c2, BYTE max_diff) +{ + if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) + return false; + c1 >>= 8; c2 >>= 8; + if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) + return false; + c1 >>= 8; c2 >>= 8; + if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) + return false; + c1 >>= 8; c2 >>= 8; + if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) + return false; + return true; +} + +static D3D12_SHADER_BYTECODE shader_bytecode(const DWORD *code, size_t size) +{ + D3D12_SHADER_BYTECODE shader_bytecode = { code, size }; + return shader_bytecode; +} + +static void exec_command_list(ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *list) +{ + ID3D12CommandList *lists[] = {(ID3D12CommandList *)list}; + ID3D12CommandQueue_ExecuteCommandLists(queue, 1, lists); +} + +#define create_buffer(a, b, c, d, e) create_buffer_(__LINE__, a, b, c, d, e) +static ID3D12Resource *create_buffer_(unsigned int line, ID3D12Device *device, + D3D12_HEAP_TYPE heap_type, size_t size, D3D12_RESOURCE_FLAGS resource_flags, + D3D12_RESOURCE_STATES initial_resource_state) +{ + D3D12_HEAP_PROPERTIES heap_properties; + D3D12_RESOURCE_DESC resource_desc; + ID3D12Resource *buffer; + HRESULT hr; + + memset(&heap_properties, 0, sizeof(heap_properties)); + heap_properties.Type = heap_type; + + resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + resource_desc.Alignment = 0; + resource_desc.Width = size; + resource_desc.Height = 1; + resource_desc.DepthOrArraySize = 1; + resource_desc.MipLevels = 1; + resource_desc.Format = DXGI_FORMAT_UNKNOWN; + resource_desc.SampleDesc.Count = 1; + resource_desc.SampleDesc.Quality = 0; + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + resource_desc.Flags = resource_flags; + + hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, + D3D12_HEAP_FLAG_NONE, &resource_desc, initial_resource_state, + NULL, &IID_ID3D12Resource, (void **)&buffer); + ok_(line)(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); + return buffer; +} + +#define create_readback_buffer(a, b) create_readback_buffer_(__LINE__, a, b) +static ID3D12Resource *create_readback_buffer_(unsigned int line, ID3D12Device *device, + size_t size) +{ + return create_buffer_(line, device, D3D12_HEAP_TYPE_READBACK, size, + D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST); +} + +#define create_cpu_descriptor_heap(a, b, c) create_cpu_descriptor_heap_(__LINE__, a, b, c) +static inline ID3D12DescriptorHeap *create_cpu_descriptor_heap_(unsigned int line, ID3D12Device *device, + D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int descriptor_count) +{ + D3D12_DESCRIPTOR_HEAP_DESC heap_desc; + ID3D12DescriptorHeap *descriptor_heap; + HRESULT hr; + + heap_desc.Type = heap_type, + heap_desc.NumDescriptors = descriptor_count; + heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + heap_desc.NodeMask = 0; + hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, + &IID_ID3D12DescriptorHeap, (void **)&descriptor_heap); + ok_(line)(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); + + return descriptor_heap; +} + +#define create_gpu_descriptor_heap(a, b, c) create_gpu_descriptor_heap_(__LINE__, a, b, c) +static inline ID3D12DescriptorHeap *create_gpu_descriptor_heap_(unsigned int line, ID3D12Device *device, + D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int descriptor_count) +{ + D3D12_DESCRIPTOR_HEAP_DESC heap_desc; + ID3D12DescriptorHeap *descriptor_heap; + HRESULT hr; + + heap_desc.Type = heap_type, + heap_desc.NumDescriptors = descriptor_count; + heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + heap_desc.NodeMask = 0; + hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, + &IID_ID3D12DescriptorHeap, (void **)&descriptor_heap); + ok_(line)(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); + + return descriptor_heap; +} + +static unsigned int format_size(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_UNKNOWN: + case DXGI_FORMAT_A8_UNORM: + return 1; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + return 16; + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8A8_UNORM: + return 4; + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_R16_UNORM: + return 2; + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 8; + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 16; + default: + trace("Unhandled format %#x.\n", format); + return 1; + } +} + +struct resource_readback +{ + unsigned int width; + unsigned int height; + ID3D12Resource *resource; + unsigned int row_pitch; + void *data; +}; + +static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsigned int sub_resource, + struct resource_readback *rb, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) +{ + D3D12_TEXTURE_COPY_LOCATION dst_location, src_location; + D3D12_RESOURCE_DESC resource_desc; + D3D12_RANGE read_range; + unsigned int miplevel; + ID3D12Device *device; + DXGI_FORMAT format; + HRESULT hr; + + hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device); + ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr); + + resource_desc = ID3D12Resource_GetDesc(texture); + ok(resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER, + "Resource %p is not texture.\n", texture); + ok(resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D, + "Readback not implemented for 3D textures.\n"); + + miplevel = sub_resource % resource_desc.MipLevels; + rb->width = max(1, resource_desc.Width >> miplevel); + rb->height = max(1, resource_desc.Height >> miplevel); + rb->row_pitch = align(rb->width * format_size(resource_desc.Format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + rb->data = NULL; + + format = resource_desc.Format; + + rb->resource = create_readback_buffer(device, rb->row_pitch * rb->height); + + dst_location.pResource = rb->resource; + dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dst_location.PlacedFootprint.Offset = 0; + dst_location.PlacedFootprint.Footprint.Format = format; + dst_location.PlacedFootprint.Footprint.Width = rb->width; + dst_location.PlacedFootprint.Footprint.Height = rb->height; + dst_location.PlacedFootprint.Footprint.Depth = 1; + dst_location.PlacedFootprint.Footprint.RowPitch = rb->row_pitch; + + src_location.pResource = texture; + src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + src_location.SubresourceIndex = sub_resource; + + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, NULL); + hr = ID3D12GraphicsCommandList_Close(command_list); + ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr); + + exec_command_list(queue, command_list); + wait_queue_idle(device, queue); + ID3D12Device_Release(device); + + read_range.Begin = 0; + read_range.End = resource_desc.Width; + hr = ID3D12Resource_Map(rb->resource, 0, &read_range, &rb->data); + ok(SUCCEEDED(hr), "Failed to map readback buffer, hr %#x.\n", hr); +} + +static void *get_readback_data(struct resource_readback *rb, unsigned int x, unsigned int y, + size_t element_size) +{ + return &((BYTE *)rb->data)[rb->row_pitch * y + x * element_size]; +} + +static unsigned int get_readback_uint(struct resource_readback *rb, unsigned int x, unsigned int y) +{ + return *(unsigned int *)get_readback_data(rb, x, y, sizeof(unsigned int)); +} + +static void release_resource_readback(struct resource_readback *rb) +{ + D3D12_RANGE range = {0, 0}; + ID3D12Resource_Unmap(rb->resource, 0, &range); + ID3D12Resource_Release(rb->resource); +} + +#define check_readback_data_uint(a, b, c, d) check_readback_data_uint_(__LINE__, a, b, c, d) +static void check_readback_data_uint_(unsigned int line, struct resource_readback *rb, + const RECT *rect, unsigned int expected, unsigned int max_diff) +{ + RECT r = {0, 0, rb->width, rb->height}; + unsigned int x = 0, y; + bool all_match = true; + unsigned int got = 0; + + if (rect) + r = *rect; + + for (y = r.top; y < r.bottom; ++y) + { + for (x = r.left; x < r.right; ++x) + { + got = get_readback_uint(rb, x, y); + if (!compare_color(got, expected, max_diff)) + { + all_match = false; + break; + } + } + if (!all_match) + break; + } + ok_(line)(all_match, "Got 0x%08x, expected 0x%08x at (%u, %u).\n", got, expected, x, y); +} + +#define check_sub_resource_uint(a, b, c, d, e, f) check_sub_resource_uint_(__LINE__, a, b, c, d, e, f) +static void check_sub_resource_uint_(unsigned int line, ID3D12Resource *texture, + unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, + unsigned int expected, unsigned int max_diff) +{ + struct resource_readback rb; + + get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list); + check_readback_data_uint_(line, &rb, NULL, expected, max_diff); + release_resource_readback(&rb); +} + +#define create_texture(a, b, c, d, e) create_default_texture_(__LINE__, a, b, c, d, 0, e) +#define create_default_texture(a, b, c, d, e, f) create_default_texture_(__LINE__, a, b, c, d, e, f) +static ID3D12Resource *create_default_texture_(unsigned int line, ID3D12Device *device, + unsigned int width, unsigned int height, DXGI_FORMAT format, + D3D12_RESOURCE_FLAGS flags, D3D12_RESOURCE_STATES initial_state) +{ + D3D12_HEAP_PROPERTIES heap_properties; + D3D12_RESOURCE_DESC resource_desc; + ID3D12Resource *texture; + HRESULT hr; + + memset(&heap_properties, 0, sizeof(heap_properties)); + heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; + + memset(&resource_desc, 0, sizeof(resource_desc)); + resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_desc.Width = width; + resource_desc.Height = height; + resource_desc.DepthOrArraySize = 1; + resource_desc.MipLevels = 1; + resource_desc.Format = format; + resource_desc.SampleDesc.Count = 1; + resource_desc.Flags = flags; + hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, + &resource_desc, initial_state, NULL, &IID_ID3D12Resource, (void **)&texture); + ok_(line)(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + return texture; +} + +static void transition_sub_resource_state(ID3D12GraphicsCommandList *list, ID3D12Resource *resource, + unsigned int sub_resource_idx, D3D12_RESOURCE_STATES state_before, D3D12_RESOURCE_STATES state_after) +{ + D3D12_RESOURCE_BARRIER barrier; + + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = resource; + barrier.Transition.Subresource = sub_resource_idx; + barrier.Transition.StateBefore = state_before; + barrier.Transition.StateAfter = state_after; + + ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier); +} + +static void transition_resource_state(ID3D12GraphicsCommandList *list, ID3D12Resource *resource, + D3D12_RESOURCE_STATES state_before, D3D12_RESOURCE_STATES state_after) +{ + transition_sub_resource_state(list, resource, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + state_before, state_after); +} + +static HRESULT create_root_signature(ID3D12Device *device, const D3D12_ROOT_SIGNATURE_DESC *desc, + ID3D12RootSignature **root_signature) +{ + ID3DBlob *blob; + HRESULT hr; + + if (FAILED(hr = D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1_0, &blob, NULL))) + return hr; + + hr = ID3D12Device_CreateRootSignature(device, 0, ID3D10Blob_GetBufferPointer(blob), + ID3D10Blob_GetBufferSize(blob), &IID_ID3D12RootSignature, (void **)root_signature); + ID3D10Blob_Release(blob); + return hr; +} + +#define create_empty_root_signature(device, flags) create_empty_root_signature_(__LINE__, device, flags) +static ID3D12RootSignature *create_empty_root_signature_(unsigned int line, + ID3D12Device *device, D3D12_ROOT_SIGNATURE_FLAGS flags) +{ + D3D12_ROOT_SIGNATURE_DESC root_signature_desc; + ID3D12RootSignature *root_signature = NULL; + HRESULT hr; + + root_signature_desc.NumParameters = 0; + root_signature_desc.pParameters = NULL; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = NULL; + root_signature_desc.Flags = flags; + hr = create_root_signature(device, &root_signature_desc, &root_signature); + ok_(line)(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr); + + return root_signature; +} + +static void init_pipeline_state_desc(D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, + ID3D12RootSignature *root_signature, DXGI_FORMAT rt_format, + const D3D12_SHADER_BYTECODE *vs, const D3D12_SHADER_BYTECODE *ps, + const D3D12_INPUT_LAYOUT_DESC *input_layout) +{ + static const DWORD vs_code[] = + { +#if 0 + void main(uint id : SV_VertexID, out float4 position : SV_Position) + { + float2 coords = float2((id << 1) & 2, id & 2); + position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); + } +#endif + 0x43425844, 0xf900d25e, 0x68bfefa7, 0xa63ac0a7, 0xa476af7a, 0x00000001, 0x0000018c, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x000000f0, 0x00010050, + 0x0000003c, 0x0100086a, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, + 0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, + 0x00000001, 0x00004001, 0x00000001, 0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, + 0x00100042, 0x00000000, 0x0010100a, 0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, + 0x00000000, 0x00100086, 0x00000000, 0x0f000032, 0x00102032, 0x00000000, 0x00100046, 0x00000000, + 0x00004002, 0x40000000, 0xc0000000, 0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, + 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, + 0x00000000, 0x3f800000, 0x0100003e, + }; + static const DWORD ps_code[] = + { +#if 0 + void main(const in float4 position : SV_Position, out float4 target : SV_Target0) + { + target = float4(0.0f, 1.0f, 0.0f, 1.0f); + } +#endif + 0x43425844, 0x8a4a8140, 0x5eba8e0b, 0x714e0791, 0xb4b8eed2, 0x00000001, 0x000000d8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, + 0x0000000f, 0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, + 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, + }; + + memset(desc, 0, sizeof(*desc)); + desc->pRootSignature = root_signature; + if (vs) + desc->VS = *vs; + else + desc->VS = shader_bytecode(vs_code, sizeof(vs_code)); + if (ps) + desc->PS = *ps; + else + desc->PS = shader_bytecode(ps_code, sizeof(ps_code)); + desc->StreamOutput.RasterizedStream = 0; + desc->BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + desc->RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + desc->RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + if (input_layout) + desc->InputLayout = *input_layout; + desc->SampleMask = ~(UINT)0; + desc->PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc->NumRenderTargets = 1; + desc->RTVFormats[0] = rt_format; + desc->SampleDesc.Count = 1; +} + +#define create_pipeline_state(a, b, c, d, e, f) create_pipeline_state_(__LINE__, a, b, c, d, e, f) +static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Device *device, + ID3D12RootSignature *root_signature, DXGI_FORMAT rt_format, + const D3D12_SHADER_BYTECODE *vs, const D3D12_SHADER_BYTECODE *ps, + const D3D12_INPUT_LAYOUT_DESC *input_layout) +{ + D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_state_desc; + ID3D12PipelineState *pipeline_state; + HRESULT hr; + + init_pipeline_state_desc(&pipeline_state_desc, root_signature, rt_format, vs, ps, input_layout); + hr = ID3D12Device_CreateGraphicsPipelineState(device, &pipeline_state_desc, + &IID_ID3D12PipelineState, (void **)&pipeline_state); + ok_(line)(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr); + + return pipeline_state; +} + +struct test_context_desc +{ + unsigned int rt_width, rt_height; + DXGI_FORMAT rt_format; + unsigned int rt_descriptor_count; + unsigned int root_signature_flags; + bool no_render_target; + bool no_root_signature; + bool no_pipeline; + const D3D12_SHADER_BYTECODE *ps; +}; + +struct test_context +{ + ID3D12Device *device; + + ID3D12CommandQueue *queue; + ID3D12CommandAllocator *allocator; + ID3D12GraphicsCommandList *list; + + D3D12_RESOURCE_DESC render_target_desc; + ID3D12Resource *render_target; + + ID3D12DescriptorHeap *rtv_heap; + D3D12_CPU_DESCRIPTOR_HANDLE rtv; + + ID3D12RootSignature *root_signature; + ID3D12PipelineState *pipeline_state; + + D3D12_VIEWPORT viewport; + RECT scissor_rect; +}; + +#define create_render_target(context, a, b, c) create_render_target_(__LINE__, context, a, b, c) +static void create_render_target_(unsigned int line, struct test_context *context, + const struct test_context_desc *desc, ID3D12Resource **render_target, + const D3D12_CPU_DESCRIPTOR_HANDLE *rtv) +{ + D3D12_HEAP_PROPERTIES heap_properties; + D3D12_RESOURCE_DESC resource_desc; + D3D12_CLEAR_VALUE clear_value; + HRESULT hr; + + 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 = desc && desc->rt_width ? desc->rt_width : 32; + resource_desc.Height = desc && desc->rt_height ? desc->rt_height : 32; + resource_desc.DepthOrArraySize = 1; + resource_desc.MipLevels = 1; + resource_desc.Format = desc && desc->rt_format ? desc->rt_format : DXGI_FORMAT_R8G8B8A8_UNORM; + resource_desc.SampleDesc.Count = 1; + resource_desc.SampleDesc.Quality = 0; + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + clear_value.Format = resource_desc.Format; + clear_value.Color[0] = 1.0f; + clear_value.Color[1] = 1.0f; + clear_value.Color[2] = 1.0f; + clear_value.Color[3] = 1.0f; + hr = ID3D12Device_CreateCommittedResource(context->device, + &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc, + D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value, + &IID_ID3D12Resource, (void **)render_target); + ok_(line)(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + context->render_target_desc = resource_desc; + + if (rtv) + ID3D12Device_CreateRenderTargetView(context->device, *render_target, NULL, *rtv); +} + +#define init_test_context(context, desc) init_test_context_(__LINE__, context, desc) +static bool init_test_context_(unsigned int line, struct test_context *context, + const struct test_context_desc *desc) +{ + D3D12_COMMAND_QUEUE_DESC command_queue_desc; + D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc; + ID3D12Device *device; + HRESULT hr; + + memset(context, 0, sizeof(*context)); + + if (!(context->device = create_device())) + { + skip_(line)("Failed to create device.\n"); + return false; + } + device = context->device; + + 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 **)&context->queue); + ok_(line)(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr); + + hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, + &IID_ID3D12CommandAllocator, (void **)&context->allocator); + ok_(line)(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr); + + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, + context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list); + ok_(line)(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + + if (desc && desc->no_render_target) + return true; + + rtv_heap_desc.NumDescriptors = desc && desc->rt_descriptor_count ? desc->rt_descriptor_count : 1; + rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + rtv_heap_desc.NodeMask = 0; + hr = ID3D12Device_CreateDescriptorHeap(device, &rtv_heap_desc, + &IID_ID3D12DescriptorHeap, (void **)&context->rtv_heap); + ok_(line)(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); + + context->rtv = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(context->rtv_heap); + + create_render_target_(line, context, desc, &context->render_target, &context->rtv); + + set_viewport(&context->viewport, 0.0f, 0.0f, + context->render_target_desc.Width, context->render_target_desc.Height, 0.0f, 1.0f); + set_rect(&context->scissor_rect, 0, 0, + context->render_target_desc.Width, context->render_target_desc.Height); + + if (desc && desc->no_root_signature) + return true; + + context->root_signature = create_empty_root_signature_(line, + device, desc ? desc->root_signature_flags : D3D12_ROOT_SIGNATURE_FLAG_NONE); + + if (desc && desc->no_pipeline) + return true; + + context->pipeline_state = create_pipeline_state_(line, device, + context->root_signature, context->render_target_desc.Format, + NULL, desc ? desc->ps : NULL, NULL); + + return true; +} + +#define destroy_test_context(context) destroy_test_context_(__LINE__, context) +static void destroy_test_context_(unsigned int line, struct test_context *context) +{ + ULONG refcount; + + if (context->pipeline_state) + ID3D12PipelineState_Release(context->pipeline_state); + if (context->root_signature) + ID3D12RootSignature_Release(context->root_signature); + + if (context->rtv_heap) + ID3D12DescriptorHeap_Release(context->rtv_heap); + if (context->render_target) + ID3D12Resource_Release(context->render_target); + + ID3D12CommandAllocator_Release(context->allocator); + ID3D12CommandQueue_Release(context->queue); + ID3D12GraphicsCommandList_Release(context->list); + + refcount = ID3D12Device_Release(context->device); + ok_(line)(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); +} + +static inline D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_handle(ID3D12Device *device, + ID3D12DescriptorHeap *heap, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int offset) +{ + D3D12_CPU_DESCRIPTOR_HANDLE handle; + unsigned int descriptor_size; + + handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); + if (!offset) + return handle; + + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, heap_type); + handle.ptr += offset * descriptor_size; + return handle; +} + +static inline D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_handle(ID3D12Device *device, + ID3D12DescriptorHeap *heap, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, unsigned int offset) +{ + D3D12_GPU_DESCRIPTOR_HANDLE handle; + unsigned int descriptor_size; + + handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap); + if (!offset) + return handle; + + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, heap_type); + handle.ptr += offset * descriptor_size; + return handle; +} + +static inline D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_descriptor_handle(struct test_context *context, + ID3D12DescriptorHeap *heap, unsigned int offset) +{ + return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, offset); +} + +static inline D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_sampler_handle(struct test_context *context, + ID3D12DescriptorHeap *heap, unsigned int offset) +{ + return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, offset); +} + +static inline D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_rtv_handle(struct test_context *context, + ID3D12DescriptorHeap *heap, unsigned int offset) +{ + return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, offset); +} + +static inline D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_descriptor_handle(struct test_context *context, + ID3D12DescriptorHeap *heap, unsigned int offset) +{ + return get_gpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, offset); +} + +static inline D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_sampler_handle(struct test_context *context, + ID3D12DescriptorHeap *heap, unsigned int offset) +{ + return get_gpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, offset); +} + +#endif /* __VKD3D_D3D12_TEST_H */
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- tests/vkd3d_api.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 198 insertions(+), 30 deletions(-)
diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c index abef8675a7ac..4b3466edc919 100644 --- a/tests/vkd3d_api.c +++ b/tests/vkd3d_api.c @@ -24,6 +24,23 @@ #include "vkd3d_test.h" #include <vkd3d.h>
+#include "vkd3d_d3d12_test.h" + +HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc, + D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob) +{ + return vkd3d_serialize_root_signature(root_signature_desc, version, blob, error_blob); +} + +static void wait_queue_idle_(unsigned int line, ID3D12Device *device, ID3D12CommandQueue *queue) +{ + VkQueue vk_queue; + + vk_queue = vkd3d_acquire_vk_queue(queue); + vkQueueWaitIdle(vk_queue); + vkd3d_release_vk_queue(queue); +} + static ULONG get_refcount(void *iface) { IUnknown *unk = iface; @@ -82,36 +99,6 @@ static ID3D12CommandQueue *create_command_queue(ID3D12Device *device, return queue; }
-static ID3D12Resource *create_buffer(ID3D12Device *device, D3D12_HEAP_TYPE heap_type, - size_t size, D3D12_RESOURCE_FLAGS resource_flags, D3D12_RESOURCE_STATES initial_resource_state) -{ - D3D12_HEAP_PROPERTIES heap_properties; - D3D12_RESOURCE_DESC resource_desc; - ID3D12Resource *buffer; - HRESULT hr; - - memset(&heap_properties, 0, sizeof(heap_properties)); - heap_properties.Type = heap_type; - - resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resource_desc.Alignment = 0; - resource_desc.Width = size; - resource_desc.Height = 1; - resource_desc.DepthOrArraySize = 1; - resource_desc.MipLevels = 1; - resource_desc.Format = DXGI_FORMAT_UNKNOWN; - resource_desc.SampleDesc.Count = 1; - resource_desc.SampleDesc.Quality = 0; - resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - resource_desc.Flags = resource_flags; - - hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, - D3D12_HEAP_FLAG_NONE, &resource_desc, initial_resource_state, - NULL, &IID_ID3D12Resource, (void **)&buffer); - ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr); - return buffer; -} - static void test_create_instance(void) { struct vkd3d_instance_create_info create_info; @@ -730,6 +717,186 @@ static void test_resource_internal_refcount(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+static VkImage create_vulkan_image(ID3D12Device *device, + unsigned int width, unsigned int height, VkFormat vk_format, VkImageUsageFlags usage) +{ + VkImageCreateInfo image_info; + VkDevice vk_device; + VkImage vk_image; + VkResult vr; + + vk_device = vkd3d_get_vk_device(device); + + image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_info.pNext = NULL; + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.format = vk_format; + image_info.extent.width = width; + image_info.extent.height = height; + image_info.extent.depth = 1; + image_info.arrayLayers = 1; + image_info.mipLevels = 1; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + image_info.usage |= usage; + image_info.flags = 0; + image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_info.queueFamilyIndexCount = 0; + image_info.pQueueFamilyIndices = NULL; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + vr = vkCreateImage(vk_device, &image_info, NULL, &vk_image); + ok(vr == VK_SUCCESS, "Failed to create image, vr %d.\n", vr); + + return vk_image; +} + +static unsigned int select_vulkan_memory_type(ID3D12Device *device, + uint32_t memory_type_mask, VkMemoryPropertyFlags required_flags) +{ + VkPhysicalDeviceMemoryProperties memory_info; + VkPhysicalDevice vk_physical_device; + unsigned int i; + + vk_physical_device = vkd3d_get_vk_physical_device(device); + + vkGetPhysicalDeviceMemoryProperties(vk_physical_device, &memory_info); + + for (i = 0; i < memory_info.memoryTypeCount; ++i) + { + if (!(memory_type_mask & (1u << i))) + continue; + if ((memory_info.memoryTypes[i].propertyFlags & required_flags) == required_flags) + return i; + } + + return ~0u; +} + +static VkDeviceMemory allocate_vulkan_device_memory(ID3D12Device *device, + VkMemoryPropertyFlags required_flags, const VkMemoryRequirements *memory_requirements) +{ + VkMemoryAllocateInfo allocate_info; + VkDeviceMemory vk_memory; + VkDevice vk_device; + VkResult vr; + + vk_device = vkd3d_get_vk_device(device); + + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.pNext = NULL; + allocate_info.allocationSize = memory_requirements->size; + allocate_info.memoryTypeIndex = select_vulkan_memory_type(device, + memory_requirements->memoryTypeBits, required_flags); + ok(allocate_info.memoryTypeIndex != ~0u, "Failed to find memory type.\n"); + + vr = vkAllocateMemory(vk_device, &allocate_info, NULL, &vk_memory); + ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr); + + return vk_memory; +} + +static VkDeviceMemory allocate_vulkan_image_memory(ID3D12Device *device, + VkMemoryPropertyFlags required_flags, VkImage vk_image) +{ + VkMemoryRequirements memory_requirements; + VkDeviceMemory vk_memory; + VkDevice vk_device; + VkResult vr; + + vk_device = vkd3d_get_vk_device(device); + + vkGetImageMemoryRequirements(vk_device, vk_image, &memory_requirements); + vk_memory = allocate_vulkan_device_memory(device, required_flags, &memory_requirements); + + vr = vkBindImageMemory(vk_device, vk_image, vk_memory, 0); + ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr); + + return vk_memory; +} + +static void test_vulkan_resource_present_state(void) +{ + static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + + struct vkd3d_image_resource_create_info resource_create_info; + ID3D12GraphicsCommandList *command_list; + ID3D12Resource *vk_resource, *resource; + D3D12_CPU_DESCRIPTOR_HANDLE rtv; + struct test_context_desc desc; + struct test_context context; + ID3D12CommandQueue *queue; + VkDeviceMemory vk_memory; + ID3D12Device *device; + VkDevice vk_device; + VkImage vk_image; + HRESULT hr; + + memset(&desc, 0, sizeof(desc)); + desc.rt_width = desc.rt_height = 32; + if (!init_test_context(&context, &desc)) + return; + device = context.device; + command_list = context.list; + queue = context.queue; + + resource = create_default_texture(device, 32, 32, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + + vk_image = create_vulkan_image(device, 32, 32, + VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); + vk_memory = allocate_vulkan_image_memory(device, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk_image); + + resource_create_info.vk_image = vk_image; + resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_create_info.desc.Alignment = 0; + resource_create_info.desc.Width = 32; + resource_create_info.desc.Height = 32; + resource_create_info.desc.DepthOrArraySize = 1; + resource_create_info.desc.MipLevels = 1; + resource_create_info.desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + resource_create_info.desc.SampleDesc.Count = 1; + resource_create_info.desc.SampleDesc.Quality = 0; + resource_create_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_create_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resource_create_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION; + resource_create_info.present_state = D3D12_RESOURCE_STATE_COPY_SOURCE; + hr = vkd3d_create_image_resource(device, &resource_create_info, &vk_resource); + ok(hr == S_OK, "Failed to create D3D12 resource for Vulkan image, hr %#x.\n", hr); + + rtv = get_cpu_descriptor_handle(&context, context.rtv_heap, 0); + ID3D12Device_CreateRenderTargetView(device, vk_resource, NULL, rtv); + + transition_resource_state(command_list, vk_resource, + D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); + + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, white, 0, NULL); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, FALSE, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, vk_resource, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); + ID3D12GraphicsCommandList_CopyResource(command_list, resource, vk_resource); + transition_resource_state(command_list, resource, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE); + + check_sub_resource_uint(resource, 0, queue, command_list, 0xff00ff00, 0); + + ID3D12Resource_Release(vk_resource); + vk_device = vkd3d_get_vk_device(device); + vkDestroyImage(vk_device, vk_image, NULL); + vkFreeMemory(vk_device, vk_memory, NULL); + ID3D12Resource_Release(resource); + destroy_test_context(&context); +} + static bool have_d3d12_device(void) { ID3D12Device *device; @@ -757,4 +924,5 @@ START_TEST(vkd3d_api) run_test(test_device_parent); run_test(test_vkd3d_queue); run_test(test_resource_internal_refcount); + run_test(test_vulkan_resource_present_state); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com