mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Add support for quad overdraw overlay with descriptor buffers
This commit is contained in:
@@ -4079,6 +4079,21 @@ bool WrappedVulkan::ContextProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedVulkan::CopyInternalDescriptor(VkCommandBuffer unwrappedCmdBuf, VkBuffer unwrappedSrc,
|
||||
uint32_t size)
|
||||
{
|
||||
VkBufferCopy bufCopy = {};
|
||||
bufCopy.size = size;
|
||||
|
||||
for(ResourceId id : m_ResourceDescBuffers)
|
||||
{
|
||||
VkBuffer dst = Unwrap(GetResourceManager()->GetCurrentHandle<VkBuffer>(id));
|
||||
bufCopy.dstOffset = m_CreationInfo.m_Buffer[id].size;
|
||||
|
||||
ObjDisp(m_Device)->CmdCopyBuffer(unwrappedCmdBuf, unwrappedSrc, dst, 1, &bufCopy);
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
|
||||
{
|
||||
switch(chunk)
|
||||
|
||||
@@ -529,6 +529,7 @@ private:
|
||||
bool m_NULLDescriptorPatternSaved = false;
|
||||
bool m_IgnoreLayoutForDescriptors = false;
|
||||
uint32_t m_ResourceDescriptorBufferReserveSize = 0;
|
||||
rdcarray<ResourceId> m_ResourceDescBuffers;
|
||||
std::unordered_map<ResourceId, ResourceId> m_InlineBuffers;
|
||||
|
||||
bool m_SeparateDepthStencil = false;
|
||||
@@ -1205,6 +1206,8 @@ private:
|
||||
void CaptureQueueSubmit(VkQueue queue, const rdcarray<VkCommandBuffer> &commandBuffers,
|
||||
VkFence fence);
|
||||
|
||||
void CopyInternalDescriptor(VkCommandBuffer unwrappedCmdBuf, VkBuffer unwrappedSrc, uint32_t size);
|
||||
|
||||
CommandBufferNode *BuildSubmitTree(ResourceId cmdId, uint32_t curEvent,
|
||||
CommandBufferNode *rootNode = NULL);
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ static void create(WrappedVulkan *driver, const char *objName, const int line, V
|
||||
|
||||
static void create(WrappedVulkan *driver, const char *objName, const int line,
|
||||
VkDescriptorSetLayout *descLayout,
|
||||
std::initializer_list<VkDescriptorSetLayoutBinding> bindings)
|
||||
std::initializer_list<VkDescriptorSetLayoutBinding> bindings,
|
||||
VkDescriptorSetLayoutCreateFlags flags = 0)
|
||||
{
|
||||
VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
@@ -82,6 +83,8 @@ static void create(WrappedVulkan *driver, const char *objName, const int line,
|
||||
bindings.begin(),
|
||||
};
|
||||
|
||||
descsetLayoutInfo.flags = flags;
|
||||
|
||||
VkResult vkr =
|
||||
driver->vkCreateDescriptorSetLayout(driver->GetDev(), &descsetLayoutInfo, NULL, descLayout);
|
||||
if(vkr != VK_SUCCESS)
|
||||
@@ -1762,6 +1765,13 @@ uint32_t VulkanReplay::PickVertex(uint32_t eventId, int32_t width, int32_t heigh
|
||||
return ret;
|
||||
}
|
||||
|
||||
const VulkanCreationInfo::Buffer &VulkanDebugManager::GetBufferInfo(ResourceId img) const
|
||||
{
|
||||
auto it = m_pDriver->m_CreationInfo.m_Buffer.find(img);
|
||||
RDCASSERT(it != m_pDriver->m_CreationInfo.m_Buffer.end());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const VulkanCreationInfo::Image &VulkanDebugManager::GetImageInfo(ResourceId img) const
|
||||
{
|
||||
auto it = m_pDriver->m_CreationInfo.m_Image.find(img);
|
||||
@@ -4467,6 +4477,17 @@ void VulkanReplay::OverlayRendering::Init(WrappedVulkan *driver, VkDescriptorPoo
|
||||
{0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, NULL},
|
||||
});
|
||||
|
||||
if(driver->DescriptorBuffers())
|
||||
{
|
||||
CREATE_OBJECT(m_QuadDescBufLayout,
|
||||
{
|
||||
{0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, NULL},
|
||||
},
|
||||
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT);
|
||||
|
||||
m_QuadDescriptor.Create(driver, driver->GetDev(), MaxDescriptorSize, 1, 0);
|
||||
}
|
||||
|
||||
CREATE_OBJECT(m_TriSizeDescSetLayout,
|
||||
{
|
||||
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL},
|
||||
@@ -4909,10 +4930,13 @@ void VulkanReplay::OverlayRendering::Destroy(WrappedVulkan *driver)
|
||||
driver->vkDestroyRenderPass(driver->GetDev(), NoDepthRP, NULL);
|
||||
|
||||
driver->vkDestroyDescriptorSetLayout(driver->GetDev(), m_QuadDescSetLayout, NULL);
|
||||
driver->vkDestroyDescriptorSetLayout(driver->GetDev(), m_QuadDescBufLayout, NULL);
|
||||
driver->vkDestroyPipelineLayout(driver->GetDev(), m_QuadResolvePipeLayout, NULL);
|
||||
for(size_t i = 0; i < ARRAY_COUNT(m_QuadResolvePipeline); i++)
|
||||
driver->vkDestroyPipeline(driver->GetDev(), m_QuadResolvePipeline[i], NULL);
|
||||
|
||||
m_QuadDescriptor.Destroy();
|
||||
|
||||
driver->vkDestroyPipelineLayout(driver->GetDev(), m_DepthResolvePipeLayout, NULL);
|
||||
driver->vkDestroyDescriptorSetLayout(driver->GetDev(), m_DepthCopyDescSetLayout, NULL);
|
||||
driver->vkDestroyPipelineLayout(driver->GetDev(), m_DepthCopyPipeLayout, NULL);
|
||||
|
||||
@@ -114,6 +114,7 @@ public:
|
||||
VkImageLayout GetImageLayout(ResourceId image, VkImageAspectFlagBits aspect, uint32_t mip,
|
||||
uint32_t slice);
|
||||
|
||||
const VulkanCreationInfo::Buffer &GetBufferInfo(ResourceId img) const;
|
||||
const VulkanCreationInfo::Image &GetImageInfo(ResourceId img) const;
|
||||
const VulkanCreationInfo::ImageView &GetImageViewInfo(ResourceId imgView) const;
|
||||
const VulkanCreationInfo::Pipeline &GetPipelineInfo(ResourceId pipe) const;
|
||||
|
||||
@@ -45,11 +45,12 @@ RDOC_EXTERN_CONFIG(bool, Vulkan_Debug_SingleSubmitFlushing);
|
||||
struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
{
|
||||
VulkanQuadOverdrawCallback(WrappedVulkan *vk, VkDescriptorSetLayout descSetLayout,
|
||||
VkDescriptorSet descSet, const rdcarray<uint32_t> &events,
|
||||
bool multiview)
|
||||
VkDescriptorSet descSet, VkDescriptorSetLayout descBufLayout,
|
||||
const rdcarray<uint32_t> &events, bool multiview)
|
||||
: m_pDriver(vk),
|
||||
m_DescSetLayout(descSetLayout),
|
||||
m_DescSet(descSet),
|
||||
m_DescBufLayout(descBufLayout),
|
||||
m_Events(events),
|
||||
m_Multiview(multiview)
|
||||
{
|
||||
@@ -92,6 +93,8 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
CachedPipeline pipe = m_PipelineCache[pipestate.graphics.pipeline];
|
||||
CachedShader shad = m_ShaderCache[pipestate.shaderObjects[4]];
|
||||
|
||||
bool descBuf = false;
|
||||
|
||||
// if we don't get a hit, create a modified pipeline
|
||||
if(pipestate.graphics.shaderObject ? shad.shad == VK_NULL_HANDLE : pipe.pipe == VK_NULL_HANDLE)
|
||||
{
|
||||
@@ -120,8 +123,13 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
descSetLayouts[i] = m_pDriver->GetResourceManager()->GetCurrentHandle<VkDescriptorSetLayout>(
|
||||
origDescSetLayouts[i]);
|
||||
|
||||
// this layout has storage image and
|
||||
descSetLayouts[descSet] = m_DescSetLayout;
|
||||
// this layout has storage image
|
||||
descBuf = (p.flags & VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) != 0;
|
||||
|
||||
if(descBuf)
|
||||
descSetLayouts[descSet] = m_DescBufLayout;
|
||||
else
|
||||
descSetLayouts[descSet] = m_DescSetLayout;
|
||||
|
||||
// don't have to handle separate vert/frag layouts as push constant ranges must be identical
|
||||
const rdcarray<VkPushConstantRange> &push = layout.pushRanges;
|
||||
@@ -286,18 +294,64 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
pipestate.shaderObjects[4] = GetResID(shad.shad);
|
||||
pipestate.graphics.lastBoundSet = shad.descSet;
|
||||
pipestate.graphics.pipeline = ResourceId();
|
||||
|
||||
RDCASSERT(pipestate.graphics.descSets.size() >= shad.descSet);
|
||||
pipestate.graphics.descSets.resize(shad.descSet + 1);
|
||||
pipestate.graphics.descSets[shad.descSet].pipeLayout = GetResID(shad.pipeLayout);
|
||||
pipestate.graphics.descSets[shad.descSet].descSet = GetResID(m_DescSet);
|
||||
pipestate.graphics.descSets.resize_for_index(shad.descSet);
|
||||
VulkanStatePipeline::DescriptorAndOffsets &descSet = pipestate.graphics.descSets[shad.descSet];
|
||||
|
||||
descSet.pipeLayout = GetResID(shad.pipeLayout);
|
||||
if(descBuf)
|
||||
{
|
||||
descSet.descBufferEmbeddedSamplers = false;
|
||||
|
||||
for(uint32_t i = 0; i < pipestate.descBufs.size(); i++)
|
||||
{
|
||||
if(pipestate.descBufs[i].usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)
|
||||
{
|
||||
descSet.descBufferIdx = i;
|
||||
ResourceId id;
|
||||
uint64_t ignored = 0;
|
||||
m_pDriver->GetResIDFromAddr(pipestate.descBufs[i].address, id, ignored);
|
||||
descSet.descBufferOffset = m_pDriver->GetDebugManager()->GetBufferInfo(id).size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
descSet.descSet = GetResID(m_DescSet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pipestate.graphics.pipeline = GetResID(pipe.pipe);
|
||||
|
||||
RDCASSERT(pipestate.graphics.descSets.size() >= pipe.descSet);
|
||||
pipestate.graphics.descSets.resize(pipe.descSet + 1);
|
||||
pipestate.graphics.descSets[pipe.descSet].pipeLayout = GetResID(pipe.pipeLayout);
|
||||
pipestate.graphics.descSets[pipe.descSet].descSet = GetResID(m_DescSet);
|
||||
pipestate.graphics.descSets.resize_for_index(pipe.descSet);
|
||||
VulkanStatePipeline::DescriptorAndOffsets &descSet = pipestate.graphics.descSets[pipe.descSet];
|
||||
|
||||
descSet.pipeLayout = GetResID(pipe.pipeLayout);
|
||||
if(descBuf)
|
||||
{
|
||||
descSet.descBufferEmbeddedSamplers = false;
|
||||
|
||||
for(uint32_t i = 0; i < pipestate.descBufs.size(); i++)
|
||||
{
|
||||
if(pipestate.descBufs[i].usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)
|
||||
{
|
||||
descSet.descBufferIdx = i;
|
||||
ResourceId id;
|
||||
uint64_t ignored = 0;
|
||||
m_pDriver->GetResIDFromAddr(pipestate.descBufs[i].address, id, ignored);
|
||||
descSet.descBufferOffset = m_pDriver->GetDebugManager()->GetBufferInfo(id).size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
descSet.descSet = GetResID(m_DescSet);
|
||||
}
|
||||
}
|
||||
|
||||
// modify dynamic state
|
||||
@@ -405,6 +459,7 @@ struct VulkanQuadOverdrawCallback : public VulkanActionCallback
|
||||
WrappedVulkan *m_pDriver;
|
||||
VkDescriptorSetLayout m_DescSetLayout;
|
||||
VkDescriptorSet m_DescSet;
|
||||
VkDescriptorSetLayout m_DescBufLayout;
|
||||
const rdcarray<uint32_t> &m_Events;
|
||||
bool m_Multiview;
|
||||
|
||||
@@ -3057,10 +3112,48 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw);
|
||||
|
||||
// fill descriptor here so that initial contents doesn't overwrite it
|
||||
if(m_pDriver->DescriptorBuffers())
|
||||
{
|
||||
VkDescriptorGetInfoEXT info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
|
||||
NULL,
|
||||
};
|
||||
|
||||
VkDescriptorImageInfo imginfo = {};
|
||||
info.type = write.descriptorType;
|
||||
info.data.pStorageImage = &imdesc;
|
||||
|
||||
VkDeviceSize offs = 0;
|
||||
vt->GetDescriptorSetLayoutBindingOffsetEXT(Unwrap(m_Device),
|
||||
Unwrap(m_Overlay.m_QuadDescBufLayout), 0, &offs);
|
||||
uint32_t size = m_pDriver->DescriptorDataSize(info.type);
|
||||
vt->GetDescriptorEXT(Unwrap(m_Device), &info, size,
|
||||
((byte *)m_Overlay.m_QuadDescriptor.Map()) + offs);
|
||||
m_Overlay.m_QuadDescriptor.Unmap();
|
||||
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
CHECK_VKR(m_pDriver, vkr);
|
||||
|
||||
// since we don't know which resource descriptor buffers the application is going to use when,
|
||||
// we copy our descriptor into the end of every single one so it will be available no matter what
|
||||
m_pDriver->CopyInternalDescriptor(Unwrap(cmd), m_Overlay.m_QuadDescriptor.UnwrappedBuffer(),
|
||||
size);
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
CHECK_VKR(m_pDriver, vkr);
|
||||
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
}
|
||||
|
||||
{
|
||||
// declare callback struct here
|
||||
VulkanQuadOverdrawCallback cb(m_pDriver, m_Overlay.m_QuadDescSetLayout,
|
||||
m_Overlay.m_QuadDescSet, events, multiviewMask > 0);
|
||||
m_Overlay.m_QuadDescSet, m_Overlay.m_QuadDescBufLayout,
|
||||
events, multiviewMask > 0);
|
||||
|
||||
m_pDriver->ReplayLog(events.front(), events.back(), eReplay_Full);
|
||||
|
||||
|
||||
@@ -735,9 +735,11 @@ private:
|
||||
GPUBuffer m_CheckerUBO;
|
||||
|
||||
VkDescriptorSetLayout m_QuadDescSetLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout m_QuadDescBufLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_QuadDescSet = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_QuadResolvePipeLayout = VK_NULL_HANDLE;
|
||||
VkPipeline m_QuadResolvePipeline[8] = {VK_NULL_HANDLE};
|
||||
GPUBuffer m_QuadDescriptor;
|
||||
|
||||
VkDescriptorSetLayout m_DepthCopyDescSetLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_DepthCopyDescSet = VK_NULL_HANDLE;
|
||||
|
||||
@@ -1935,6 +1935,9 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic
|
||||
m_DeviceAddressResources.IDs.push_back(GetResID(buf));
|
||||
}
|
||||
|
||||
if(patchedusage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)
|
||||
m_ResourceDescBuffers.push_back(GetResID(buf));
|
||||
|
||||
if(CreateInfo.flags &
|
||||
(VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user