dzn: Use DXGI swapchains
Makes things so much faster than doing CPU copies using StretchBlt(). Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16200>
This commit is contained in:

committed by
Marge Bot

parent
2f462105fa
commit
5f1b8b3e6c
@@ -1088,20 +1088,22 @@ dzn_CmdPipelineBarrier2(VkCommandBuffer commandBuffer,
|
||||
const VkImageSubresourceRange *range = &ibarrier->subresourceRange;
|
||||
VK_FROM_HANDLE(dzn_image, image, ibarrier->image);
|
||||
|
||||
/* We use placed resource's simple model, in which only one resource
|
||||
* pointing to a given heap is active at a given time. To make the
|
||||
* resource active we need to add an aliasing barrier.
|
||||
*/
|
||||
D3D12_RESOURCE_BARRIER aliasing_barrier = {
|
||||
.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING,
|
||||
.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||
.Aliasing = {
|
||||
.pResourceBefore = NULL,
|
||||
.pResourceAfter = image->res,
|
||||
},
|
||||
};
|
||||
if (image->mem->swapchain_res != image->res) {
|
||||
/* We use placed resource's simple model, in which only one resource
|
||||
* pointing to a given heap is active at a given time. To make the
|
||||
* resource active we need to add an aliasing barrier.
|
||||
*/
|
||||
D3D12_RESOURCE_BARRIER aliasing_barrier = {
|
||||
.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING,
|
||||
.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||
.Aliasing = {
|
||||
.pResourceBefore = NULL,
|
||||
.pResourceAfter = image->res,
|
||||
},
|
||||
};
|
||||
|
||||
ID3D12GraphicsCommandList1_ResourceBarrier(cmdbuf->cmdlist, 1, &aliasing_barrier);
|
||||
ID3D12GraphicsCommandList1_ResourceBarrier(cmdbuf->cmdlist, 1, &aliasing_barrier);
|
||||
}
|
||||
|
||||
dzn_cmd_buffer_queue_image_range_layout_transition(cmdbuf, image, range,
|
||||
ibarrier->oldLayout,
|
||||
|
@@ -279,6 +279,9 @@ dzn_instance_create(const VkInstanceCreateInfo *pCreateInfo,
|
||||
vk_instance_dispatch_table_from_entrypoints(&dispatch_table,
|
||||
&dzn_instance_entrypoints,
|
||||
true);
|
||||
vk_instance_dispatch_table_from_entrypoints(&dispatch_table,
|
||||
&wsi_instance_entrypoints,
|
||||
false);
|
||||
|
||||
VkResult result =
|
||||
vk_instance_init(&instance->vk, &instance_extensions,
|
||||
@@ -2143,12 +2146,19 @@ dzn_device_create(struct dzn_physical_device *pdev,
|
||||
{
|
||||
struct dzn_instance *instance = container_of(pdev->vk.instance, struct dzn_instance, vk);
|
||||
|
||||
uint32_t graphics_queue_count = 0;
|
||||
uint32_t queue_count = 0;
|
||||
for (uint32_t qf = 0; qf < pCreateInfo->queueCreateInfoCount; qf++) {
|
||||
const VkDeviceQueueCreateInfo *qinfo = &pCreateInfo->pQueueCreateInfos[qf];
|
||||
queue_count += qinfo->queueCount;
|
||||
if (pdev->queue_families[qinfo->queueFamilyIndex].props.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
graphics_queue_count += qinfo->queueCount;
|
||||
}
|
||||
|
||||
/* Add a swapchain queue if there's no or too many graphics queues */
|
||||
if (graphics_queue_count != 1)
|
||||
queue_count++;
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
VK_MULTIALLOC_DECL(&ma, struct dzn_device, device, 1);
|
||||
VK_MULTIALLOC_DECL(&ma, struct dzn_queue, queues, queue_count);
|
||||
@@ -2257,9 +2267,35 @@ dzn_device_create(struct dzn_physical_device *pdev,
|
||||
dzn_device_destroy(device, pAllocator);
|
||||
return result;
|
||||
}
|
||||
if (graphics_queue_count == 1 &&
|
||||
pdev->queue_families[qinfo->queueFamilyIndex].props.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
device->swapchain_queue = &queues[qindex - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!device->swapchain_queue) {
|
||||
const float swapchain_queue_priority = 0.0f;
|
||||
VkDeviceQueueCreateInfo swapchain_queue_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.queueCount = 1,
|
||||
.pQueuePriorities = &swapchain_queue_priority,
|
||||
};
|
||||
for (uint32_t qf = 0; qf < pdev->queue_family_count; qf++) {
|
||||
if (pdev->queue_families[qf].props.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
swapchain_queue_info.queueFamilyIndex = qf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = dzn_queue_init(&queues[qindex], device, &swapchain_queue_info, 0);
|
||||
if (result != VK_SUCCESS) {
|
||||
dzn_device_destroy(device, pAllocator);
|
||||
return result;
|
||||
}
|
||||
device->swapchain_queue = &queues[qindex++];
|
||||
device->need_swapchain_blits = true;
|
||||
}
|
||||
|
||||
assert(queue_count == qindex);
|
||||
*out = dzn_device_to_handle(device);
|
||||
return VK_SUCCESS;
|
||||
@@ -2372,6 +2408,9 @@ dzn_device_memory_destroy(struct dzn_device_memory *mem,
|
||||
if (mem->heap)
|
||||
ID3D12Heap_Release(mem->heap);
|
||||
|
||||
if (mem->swapchain_res)
|
||||
ID3D12Resource_Release(mem->swapchain_res);
|
||||
|
||||
vk_object_base_finish(&mem->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, mem);
|
||||
}
|
||||
|
@@ -817,9 +817,12 @@ dzn_BindImageMemory2(VkDevice dev,
|
||||
image->mem = mem;
|
||||
image->mem_offset = bind_info->memoryOffset;
|
||||
|
||||
HRESULT hres;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
if (device->dev10 && image->castable_format_count > 0) {
|
||||
if (mem->swapchain_res) {
|
||||
image->res = mem->swapchain_res;
|
||||
ID3D12Resource_AddRef(image->res);
|
||||
} else if (device->dev10 && image->castable_format_count > 0) {
|
||||
D3D12_RESOURCE_DESC1 desc = {
|
||||
.Dimension = image->desc.Dimension,
|
||||
.Alignment = image->desc.Alignment,
|
||||
|
@@ -271,6 +271,12 @@ struct dzn_device {
|
||||
#define DZN_QUERY_REFS_RES_SIZE (DZN_QUERY_REFS_ALL_ZEROS_OFFSET + DZN_QUERY_REFS_SECTION_SIZE)
|
||||
ID3D12Resource *refs;
|
||||
} queries;
|
||||
|
||||
/* Will be the app's graphics queue if there's exactly one, otherwise this will be
|
||||
* a dedicated graphics queue to host swapchain blits.
|
||||
*/
|
||||
bool need_swapchain_blits;
|
||||
struct dzn_queue *swapchain_queue;
|
||||
};
|
||||
|
||||
void dzn_meta_finish(struct dzn_device *device);
|
||||
@@ -290,6 +296,11 @@ struct dzn_device_memory {
|
||||
|
||||
struct list_head link;
|
||||
|
||||
/* Swapchain image resource, NULL if the memory is not backed by
|
||||
* a DXGI swapchain.
|
||||
*/
|
||||
ID3D12Resource *swapchain_res;
|
||||
|
||||
ID3D12Heap *heap;
|
||||
VkDeviceSize size;
|
||||
|
||||
|
@@ -31,6 +31,50 @@ dzn_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
|
||||
return vk_instance_get_proc_addr_unchecked(pdevice->vk.instance, pName);
|
||||
}
|
||||
|
||||
static void *
|
||||
dzn_wsi_get_d3d12_command_queue(VkDevice dev)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
return device->swapchain_queue->cmdqueue;
|
||||
}
|
||||
|
||||
static VkQueue
|
||||
dzn_wsi_get_blit_queue(VkDevice dev)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
return dzn_queue_to_handle(device->swapchain_queue);
|
||||
}
|
||||
|
||||
static bool
|
||||
dzn_wsi_needs_blits(VkDevice dev)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
return device->need_swapchain_blits;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_wsi_create_image_memory(VkDevice dev, void *resource,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
VkDeviceMemory *out)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
struct dzn_device_memory *mem =
|
||||
vk_zalloc2(&device->vk.alloc, alloc, sizeof(*mem), 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!mem)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY);
|
||||
mem->swapchain_res = resource;
|
||||
ID3D12Resource_AddRef(mem->swapchain_res);
|
||||
|
||||
*out = dzn_device_memory_to_handle(mem);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
dzn_wsi_finish(struct dzn_physical_device *physical_device)
|
||||
{
|
||||
@@ -43,18 +87,21 @@ dzn_wsi_init(struct dzn_physical_device *physical_device)
|
||||
{
|
||||
VkResult result;
|
||||
|
||||
/* TODO: implement a proper, non-sw winsys for D3D12 */
|
||||
bool sw_device = true;
|
||||
|
||||
result = wsi_device_init(&physical_device->wsi_device,
|
||||
dzn_physical_device_to_handle(physical_device),
|
||||
dzn_wsi_proc_addr,
|
||||
&physical_device->vk.instance->alloc,
|
||||
-1, NULL, sw_device);
|
||||
-1, NULL, false);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
physical_device->wsi_device.win32.get_d3d12_command_queue =
|
||||
dzn_wsi_get_d3d12_command_queue;
|
||||
physical_device->wsi_device.win32.requires_blits = dzn_wsi_needs_blits;
|
||||
physical_device->wsi_device.get_blit_queue = dzn_wsi_get_blit_queue;
|
||||
physical_device->wsi_device.win32.create_image_memory =
|
||||
dzn_wsi_create_image_memory;
|
||||
physical_device->wsi_device.supports_modifiers = false;
|
||||
physical_device->vk.wsi_device = &physical_device->wsi_device;
|
||||
|
||||
|
Reference in New Issue
Block a user