diff --git a/renderdoc/data/spv/texdisplay.frag b/renderdoc/data/spv/texdisplay.frag index 309ea7987..978e4cd16 100644 --- a/renderdoc/data/spv/texdisplay.frag +++ b/renderdoc/data/spv/texdisplay.frag @@ -90,8 +90,18 @@ void main(void) // RGBM encoding if(texdisplay.HDRMul > 0.0f) { - col = vec4(col.rgb * col.a * texdisplay.HDRMul, 1.0); + if (uintTex) + col = vec4(ucol.rgb * ucol.a * uint(texdisplay.HDRMul), 1.0); + else if (sintTex) + col = vec4(scol.rgb * scol.a * int(texdisplay.HDRMul), 1.0); + else + col = vec4(col.rgb * col.a * texdisplay.HDRMul, 1.0); } + + if (uintTex) + col = vec4(ucol); + else if (sintTex) + col = vec4(scol); vec4 pre_range_col = col; diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 5c3e8271d..efb8670a2 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -341,6 +341,7 @@ void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan, Vu void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageCreateInfo* pCreateInfo) { view = VK_NULL_HANDLE; + stencilView = VK_NULL_HANDLE; type = pCreateInfo->imageType; format = pCreateInfo->format; diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index fed1c1f99..f0ca5625c 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -246,6 +246,7 @@ struct VulkanCreationInfo void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageCreateInfo* pCreateInfo); VkImageView view; + VkImageView stencilView; VkImageType type; VkFormat format; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index f5e2e821e..bbb197b29 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -736,107 +736,130 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_ int oldW = m_DebugWidth, oldH = m_DebugHeight; m_DebugWidth = m_DebugHeight = 1; + + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texture]; - // render picked pixel to readback F32 RGBA texture + bool isStencil = IsStencilFormat(iminfo.format); + + // do a second pass to render the stencil, if needed + for(int pass=0; pass < (isStencil ? 2 : 1); pass++) { - TextureDisplay texDisplay; + // render picked pixel to readback F32 RGBA texture + { + TextureDisplay texDisplay; - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = true; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = sample; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = sliceFace; - texDisplay.overlay = eTexOverlay_None; - texDisplay.rangemin = 0.0f; - texDisplay.rangemax = 1.0f; - texDisplay.scale = 1.0f; - texDisplay.texid = texture; - texDisplay.rawoutput = true; - texDisplay.offx = -float(x); - texDisplay.offy = -float(y); - - VkClearValue clearval = {0}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(GetDebugManager()->m_PickPixelRP), Unwrap(GetDebugManager()->m_PickPixelFB), - { { 0, 0, }, { 1, 1 } }, - 1, &clearval, - }; + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = true; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = sample; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = sliceFace; + texDisplay.overlay = eTexOverlay_None; + texDisplay.rangemin = 0.0f; + texDisplay.rangemax = 1.0f; + texDisplay.scale = 1.0f; + texDisplay.texid = texture; + texDisplay.rawoutput = true; + texDisplay.offx = -float(x); + texDisplay.offy = -float(y); - RenderTextureInternal(texDisplay, rpbegin, true); + // only render green (stencil) in second pass + if(pass == 1) + { + texDisplay.Green = true; + texDisplay.Red = texDisplay.Blue = texDisplay.Alpha = false; + } + + VkClearValue clearval = {0}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, + Unwrap(GetDebugManager()->m_PickPixelRP), Unwrap(GetDebugManager()->m_PickPixelFB), + { { 0, 0, }, { 1, 1 } }, + 1, &clearval, + }; + + RenderTextureInternal(texDisplay, rpbegin, true); + } + + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); + + VkResult vkr = VK_SUCCESS; + + { + VkImageMemoryBarrier pickimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, + 0, 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, + Unwrap(GetDebugManager()->m_PickPixelImage), + { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } + }; + + // update image layout from color attachment to transfer source, with proper memory barriers + pickimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + pickimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + + VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERT(vkr == VK_SUCCESS); + + void *barrier = (void *)&pickimBarrier; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + pickimBarrier.oldLayout = pickimBarrier.newLayout; + pickimBarrier.srcAccessMask = pickimBarrier.dstAccessMask; + + // do copy + VkBufferImageCopy region = { + 0, 128, 1, + { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, + { 0, 0, 0 }, + { 1, 1, 1 }, + }; + vt->CmdCopyImageToBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_PickPixelImage), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.buf), 1, ®ion); + + // update image layout back to color attachment + pickimBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + pickimBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + + vt->EndCommandBuffer(Unwrap(cmd)); + } + + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + float *pData = NULL; + vt->MapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem), 0, VK_WHOLE_SIZE, 0, (void **)&pData); + + RDCASSERT(pData != NULL); + + if(pData == NULL) + { + RDCERR("Failed ot map readback buffer memory"); + } + else + { + // only write stencil to .y + if(pass == 1) + { + pixel[1] = pData[1]/255.0f; + } + else + { + pixel[0] = pData[0]; + pixel[1] = pData[1]; + pixel[2] = pData[2]; + pixel[3] = pData[3]; + } + } + + vt->UnmapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem)); } - - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); - - VkResult vkr = VK_SUCCESS; - - { - VkImageMemoryBarrier pickimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(GetDebugManager()->m_PickPixelImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - // update image layout from color attachment to transfer source, with proper memory barriers - pickimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - pickimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERT(vkr == VK_SUCCESS); - - void *barrier = (void *)&pickimBarrier; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); - pickimBarrier.oldLayout = pickimBarrier.newLayout; - pickimBarrier.srcAccessMask = pickimBarrier.dstAccessMask; - - // do copy - VkBufferImageCopy region = { - 0, 128, 1, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - }; - vt->CmdCopyImageToBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_PickPixelImage), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.buf), 1, ®ion); - - // update image layout back to color attachment - pickimBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - pickimBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); - - vt->EndCommandBuffer(Unwrap(cmd)); - } - - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - - float *pData = NULL; - vt->MapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem), 0, VK_WHOLE_SIZE, 0, (void **)&pData); - - RDCASSERT(pData != NULL); - - if(pData == NULL) - { - RDCERR("Failed ot map readback buffer memory"); - } - else - { - pixel[0] = pData[0]; - pixel[1] = pData[1]; - pixel[2] = pData[2]; - pixel[3] = pData[3]; - } - - vt->UnmapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem)); } uint32_t VulkanReplay::PickVertex(uint32_t frameID, uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) @@ -876,36 +899,51 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn ImageLayouts &layouts = m_pDriver->m_ImageLayouts[cfg.texid]; VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[cfg.texid]; VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.texid); - VkImageView liveImView = iminfo.view; - bool isDepth = (layouts.subresourceStates[0].subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + + int displayformat = 0; + int descSetBinding = 0; - if(liveImView == VK_NULL_HANDLE) + if(IsUIntFormat(iminfo.format)) { - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D, - iminfo.format, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, 1, }, - }; - - if(isDepth) - { - viewInfo.components.g = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; - } - - VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &iminfo.view); - RDCASSERT(vkr == VK_SUCCESS); - - ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), iminfo.view); - // register as a live-only resource, so it is cleaned up properly - m_pDriver->GetResourceManager()->AddLiveResource(viewid, iminfo.view); - - liveImView = iminfo.view; + descSetBinding = 10; + displayformat |= TEXDISPLAY_UINT_TEX; } + else if(IsSIntFormat(iminfo.format)) + { + descSetBinding = 15; + displayformat |= TEXDISPLAY_SINT_TEX; + } + else + { + descSetBinding = 5; + } + + if(IsDepthOnlyFormat(layouts.format)) + { + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + } + else if(IsDepthStencilFormat(layouts.format)) + { + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + if(layouts.format == VK_FORMAT_S8_UINT || (!cfg.Red && cfg.Green)) + { + aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT; + descSetBinding = 10; + displayformat |= TEXDISPLAY_UINT_TEX; + + // rescale the range so that stencil seems to fit to 0-1 + cfg.rangemin *= 255.0f; + cfg.rangemax *= 255.0f; + } + } + + CreateTexImageView(aspectFlags, liveIm, iminfo); + + VkImageView liveImView = (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); + + RDCASSERT(liveImView != VK_NULL_HANDLE); uint32_t uboOffs = 0; @@ -993,23 +1031,9 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn textype = RESTYPE_TEX2DMS; } - int displayformat = textype; - int descSetBinding = textype; + displayformat |= textype; - if(IsUIntFormat(iminfo.format)) - { - descSetBinding += 10; - displayformat |= TEXDISPLAY_UINT_TEX; - } - else if(IsSIntFormat(iminfo.format)) - { - descSetBinding += 15; - displayformat |= TEXDISPLAY_SINT_TEX; - } - else - { - descSetBinding += 5; - } + descSetBinding += textype; // VKTODOMED: RESTYPE_TEXBUFFER @@ -1060,7 +1084,7 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(liveIm), - { VkImageAspectFlags(isDepth ? (VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT) : VK_IMAGE_ASPECT_COLOR_BIT), 0, 1, 0, 1 } + { aspectFlags, 0, 1, 0, 1 } }; // ensure all previous writes have completed @@ -1095,7 +1119,11 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe)); vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_TexDisplayPipeLayout), 0, 1, UnwrapPtr(descset), 1, &uboOffs); - VkViewport viewport = { 0.0f, 0.0f, (float)m_DebugWidth, (float)m_DebugHeight, 0.0f, 1.0f }; + VkViewport viewport = { + (float)rpbegin.renderArea.offset.x, (float)rpbegin.renderArea.offset.y, + (float)m_DebugWidth, (float)m_DebugHeight, + 0.0f, 1.0f + }; vt->CmdSetViewport(Unwrap(cmd), 1, &viewport); vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); @@ -1114,6 +1142,59 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn return true; } +void VulkanReplay::CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage liveIm, VulkanCreationInfo::Image &iminfo) +{ + VkDevice dev = m_pDriver->GetDev(); + + if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) + { + if(iminfo.stencilView != VK_NULL_HANDLE) + return; + } + else + { + if(iminfo.view != VK_NULL_HANDLE) + return; + } + + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, + 0, Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D_ARRAY, + iminfo.format, + { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, + { aspectFlags, 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, RDCMAX(1U, (uint32_t)iminfo.arrayLayers), }, + }; + + if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT) + { + viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; + } + else if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) + { + viewInfo.components.r = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_R; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; + } + + VkImageView view; + + VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &view); + RDCASSERT(vkr == VK_SUCCESS); + + ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), view); + // register as a live-only resource, so it is cleaned up properly + m_pDriver->GetResourceManager()->AddLiveResource(viewid, view); + + if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) + iminfo.stencilView = view; + else + iminfo.view = view; +} + void VulkanReplay::RenderCheckerboard(Vec3f light, Vec3f dark) { auto it = m_OutputWindows.find(m_ActiveWinID); @@ -3252,37 +3333,17 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - VkImageView liveImView = iminfo.view; - bool isDepth = (layouts.subresourceStates[0].subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthStencilFormat(layouts.format)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - if(liveImView == VK_NULL_HANDLE) - { - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D, - iminfo.format, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, 1, }, - }; + CreateTexImageView(aspectFlags, liveIm, iminfo); - if(isDepth) - { - viewInfo.components.g = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; - } + VkImageView liveImView = (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); - VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &iminfo.view); - RDCASSERT(vkr == VK_SUCCESS); + RDCASSERT(liveImView != VK_NULL_HANDLE); - ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), iminfo.view); - // register as a live-only resource, so it is cleaned up properly - m_pDriver->GetResourceManager()->AddLiveResource(viewid, iminfo.view); - - liveImView = iminfo.view; - } - VkDescriptorImageInfo imdesc = {0}; imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; imdesc.imageView = Unwrap(liveImView); @@ -3369,7 +3430,7 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(liveIm), - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), 0, 1, 0, 1 } + { aspectFlags, 0, 1, 0, 1 } }; // ensure all previous writes have completed @@ -3484,38 +3545,17 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - VkImageView liveImView = iminfo.view; - bool isDepth = (layouts.subresourceStates[0].subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; - - // VKTODOMED extract this out somewhere - if(liveImView == VK_NULL_HANDLE) - { - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D, - iminfo.format, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, 1, }, - }; - - if(isDepth) - { - viewInfo.components.g = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; - } - - VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &iminfo.view); - RDCASSERT(vkr == VK_SUCCESS); - - ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), iminfo.view); - // register as a live-only resource, so it is cleaned up properly - m_pDriver->GetResourceManager()->AddLiveResource(viewid, iminfo.view); - - liveImView = iminfo.view; - } + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthStencilFormat(layouts.format)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + CreateTexImageView(aspectFlags, liveIm, iminfo); + + VkImageView liveImView = (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); + + RDCASSERT(liveImView != VK_NULL_HANDLE); + VkDescriptorImageInfo imdesc = {0}; imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; imdesc.imageView = Unwrap(liveImView); @@ -3589,7 +3629,7 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(liveIm), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } + { aspectFlags, 0, 1, 0, 1 } }; // ensure all previous writes have completed diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 305129ba5..9d2a4a445 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -25,6 +25,7 @@ #pragma once #include "vk_common.h" +#include "vk_info.h" #include "api/replay/renderdoc_replay.h" #include "replay/replay_driver.h" #include "core/core.h" @@ -242,6 +243,8 @@ class VulkanReplay : public IReplayDriver bool RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, bool f32render); + void VulkanReplay::CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage liveIm, VulkanCreationInfo::Image &iminfo); + void FillCBufferVariables(rdctype::array, vector &outvars, const vector &data, size_t &offset); VulkanDebugManager *GetDebugManager(); diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index bb606481e..eb307b31a 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -187,6 +187,22 @@ bool IsDepthStencilFormat(VkFormat f) return false; } +bool IsStencilFormat(VkFormat f) +{ + switch(f) + { + case VK_FORMAT_S8_UINT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return true; + default: + break; + } + + return false; +} + bool IsDepthOnlyFormat(VkFormat f) { switch(f) diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 370419970..5842971e3 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -790,6 +790,7 @@ struct ImageLayouts bool IsBlockFormat(VkFormat f); bool IsDepthStencilFormat(VkFormat f); bool IsDepthOnlyFormat(VkFormat f); +bool IsStencilFormat(VkFormat f); bool IsSRGBFormat(VkFormat f); bool IsUIntFormat(VkFormat f); bool IsSIntFormat(VkFormat f);