From 803e626e8d21e279dd83fea8da9eb557a18eb3ae Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 8 Nov 2015 18:07:48 +0100 Subject: [PATCH] [Sparse #3] Create sparse info structs on resource creation --- renderdoc/driver/vulkan/vk_resources.cpp | 4 ++ renderdoc/driver/vulkan/vk_resources.h | 4 ++ .../vulkan/wrappers/vk_resource_funcs.cpp | 67 +++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index 8a1665d2f..3bc96238c 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -503,4 +503,8 @@ VkResourceRecord::~VkResourceRecord() SAFE_DELETE(memMapState); } + if(sparseOwner) + { + SAFE_DELETE(sparseInfo); + } } diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index d989a5dcb..c47edbb95 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -649,6 +649,9 @@ struct VkResourceRecord : public ResourceRecord mem(VK_NULL_HANDLE), memOffset(0), memProps(NULL), + memIdxMap(NULL), + sparseOwner(false), + sparseInfo(NULL), layout(NULL), swapInfo(NULL), cmdInfo(NULL), @@ -718,6 +721,7 @@ struct VkResourceRecord : public ResourceRecord // ie. the resource that can be modified or changes (or can become dirty) // since typical memory bindings are immutable and must happen before // creation or use, this can always be determined + bool sparseOwner; ResourceId baseResource; ResourceId baseResourceMem; // for image views, we need to point to both the image and mem SparseMapping *sparseInfo; diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 1d6df426d..6c5a06e0f 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -785,6 +785,24 @@ VkResult WrappedVulkan::vkCreateBuffer( VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pBuffer); record->AddChunk(chunk); + + if(pCreateInfo->flags & (VK_BUFFER_CREATE_SPARSE_BINDING_BIT|VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)) + { + record->sparseInfo = new SparseMapping(); + record->sparseOwner = true; + + // buffers are always bound opaquely and in arbitrary divisions, sparse residency + // only means not all the buffer needs to be bound, which is not that interesting for + // our purposes + + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State != WRITING_CAPFRAME) + GetResourceManager()->MarkDirtyResource(id); + else + GetResourceManager()->MarkPendingDirty(id); + } + } } else { @@ -864,6 +882,7 @@ VkResult WrappedVulkan::vkCreateBufferView( // store the base resource record->baseResource = bufferRecord->baseResource; + record->sparseInfo = bufferRecord->sparseInfo; } else { @@ -967,6 +986,53 @@ VkResult WrappedVulkan::vkCreateImage( VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pImage); record->AddChunk(chunk); + + if(pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) + { + record->sparseInfo = new SparseMapping(); + record->sparseOwner = true; + + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State != WRITING_CAPFRAME) + GetResourceManager()->MarkDirtyResource(id); + else + GetResourceManager()->MarkPendingDirty(id); + } + + if(pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) + { + // must record image and page dimension, and create page tables + uint32_t numreqs = VK_IMAGE_ASPECT_NUM; + VkSparseImageMemoryRequirements reqs[VK_IMAGE_ASPECT_NUM]; + ObjDisp(device)->GetImageSparseMemoryRequirements(Unwrap(device), Unwrap(*pImage), &numreqs, reqs); + + RDCASSERT(numreqs > 0); + + record->sparseInfo->pagedim = reqs[0].formatProps.imageGranularity; + record->sparseInfo->imgdim = pCreateInfo->extent; + record->sparseInfo->imgdim.width /= record->sparseInfo->pagedim.width; + record->sparseInfo->imgdim.height /= record->sparseInfo->pagedim.height; + record->sparseInfo->imgdim.depth /= record->sparseInfo->pagedim.depth; + + uint32_t numpages = record->sparseInfo->imgdim.width*record->sparseInfo->imgdim.height*record->sparseInfo->imgdim.depth; + + for(uint32_t i=0; i < numreqs; i++) + { + // assume all page sizes are the same for all aspects + RDCASSERT(record->sparseInfo->pagedim.width == reqs[i].formatProps.imageGranularity.width && + record->sparseInfo->pagedim.height == reqs[i].formatProps.imageGranularity.height && + record->sparseInfo->pagedim.depth == reqs[i].formatProps.imageGranularity.depth); + + record->sparseInfo->pages[reqs[i].formatProps.aspect] = new pair[numpages]; + } + } + else + { + // don't have to do anything, image is opaque and must be fully bound, just need + // to track the memory bindings. + } + } } else { @@ -1079,6 +1145,7 @@ VkResult WrappedVulkan::vkCreateImageView( // to their memory, which we will also need so we store that separately record->baseResource = imageRecord->GetResourceID(); record->baseResourceMem = imageRecord->baseResource; + record->sparseInfo = imageRecord->sparseInfo; } else {