From bd01035eff680221e8ed3a9fdca7410276a95727 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Fri, 20 Jul 2018 17:08:50 -0400 Subject: [PATCH 1/3] Copy depth aspect by rendering in overdraw Specifically do this for the store end (i.e. new depth/stencil image to old image), so that we don't have to add TRANSFER_DST to all depth images. --- gapii/cc/vulkan_extras.cpp | 15 +- gapis/api/vulkan/image_primer.go | 262 ++++++++++++++++----------- gapis/api/vulkan/overdraw.go | 104 +++++++++-- gapis/api/vulkan/read_framebuffer.go | 9 +- gapis/api/vulkan/state_rebuilder.go | 90 +++++++-- 5 files changed, 327 insertions(+), 153 deletions(-) diff --git a/gapii/cc/vulkan_extras.cpp b/gapii/cc/vulkan_extras.cpp index 97a9794b2e..922480b056 100644 --- a/gapii/cc/vulkan_extras.cpp +++ b/gapii/cc/vulkan_extras.cpp @@ -741,16 +741,11 @@ uint32_t VulkanSpy::SpyOverride_vkCreateBuffer( uint32_t VulkanSpy::SpyOverride_vkCreateImage( VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage) { - if (is_suspended() || is_observing()) { - VkImageCreateInfo override_create_info = *pCreateInfo; - override_create_info.musage |= - VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - return mImports.mVkDeviceFunctions[device].vkCreateImage( - device, &override_create_info, pAllocator, pImage); - } else { - return mImports.mVkDeviceFunctions[device].vkCreateImage( - device, pCreateInfo, pAllocator, pImage); - } + VkImageCreateInfo override_create_info = *pCreateInfo; + override_create_info.musage |= + VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + return mImports.mVkDeviceFunctions[device].vkCreateImage( + device, &override_create_info, pAllocator, pImage); } uint32_t VulkanSpy::SpyOverride_vkCreateSwapchainKHR( diff --git a/gapis/api/vulkan/image_primer.go b/gapis/api/vulkan/image_primer.go index 506223ab8a..dad7710d6a 100644 --- a/gapis/api/vulkan/image_primer.go +++ b/gapis/api/vulkan/image_primer.go @@ -109,13 +109,32 @@ func (p *imagePrimer) primeByRendering(img ImageObjectʳ, opaqueBoundRanges []Vk for _, aspect := range p.sb.imageAspectFlagBits(img.ImageAspect()) { for layer := uint32(0); layer < img.Info().ArrayLayers(); layer++ { for level := uint32(0); level < img.Info().MipLevels(); level++ { + inputImageObjects := copyJob.srcAspectsToDsts[aspect].dstImgs + inputImages := make([]ipRenderImage, len(inputImageObjects)) + for i, iimg := range inputImageObjects { + layout := iimg.Aspects().Get( + VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT).Layers().Get( + layer).Levels().Get( + level).Layout() + inputImages[i] = ipRenderImage{ + image: iimg, + aspect: VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT, + layer: layer, + level: level, + initialLayout: layout, + finalLayout: layout, + } + } renderJobs = append(renderJobs, &ipRenderJob{ - inputAttachmentImages: copyJob.srcAspectsToDsts[aspect].dstImgs, - renderTarget: img, - aspect: aspect, - layer: layer, - level: level, - finalLayout: img.Aspects().Get(aspect).Layers().Get(layer).Levels().Get(level).Layout(), + inputAttachmentImages: inputImages, + renderTarget: ipRenderImage{ + image: img, + aspect: aspect, + layer: layer, + level: level, + initialLayout: VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED, + finalLayout: img.Aspects().Get(aspect).Layers().Get(layer).Levels().Get(level).Layout(), + }, }) } } @@ -124,7 +143,10 @@ func (p *imagePrimer) primeByRendering(img ImageObjectʳ, opaqueBoundRanges []Vk err := p.rh.render(renderJob, renderTsk) if err != nil { log.E(p.sb.ctx, "[Priming image: %v, aspect: %v, layer: %v, level: %v data by rendering] %v", - renderJob.renderTarget.VulkanHandle(), renderJob.aspect, renderJob.layer, renderJob.level, err) + renderJob.renderTarget.image.VulkanHandle(), + renderJob.renderTarget.aspect, + renderJob.renderTarget.layer, + renderJob.renderTarget.level, err) } } @@ -961,12 +983,17 @@ func (h *ipStoreHandler) getOrCreateShaderModule(info ipStoreShaderInfo) (Shader // Input attachment -> image render handler type ipRenderJob struct { - inputAttachmentImages []ImageObjectʳ - renderTarget ImageObjectʳ - aspect VkImageAspectFlagBits - layer uint32 - level uint32 - finalLayout VkImageLayout + inputAttachmentImages []ipRenderImage + renderTarget ipRenderImage +} + +type ipRenderImage struct { + image ImageObjectʳ + aspect VkImageAspectFlagBits + layer uint32 + level uint32 + initialLayout VkImageLayout + finalLayout VkImageLayout } const ( @@ -1047,44 +1074,45 @@ func (h *ipRenderHandler) free() { } } +func imageBarrierAspectFlags(aspect VkImageAspectFlagBits, fmt VkFormat) VkImageAspectFlags { + switch fmt { + case VkFormat_VK_FORMAT_D16_UNORM_S8_UINT, + VkFormat_VK_FORMAT_D24_UNORM_S8_UINT, + VkFormat_VK_FORMAT_D32_SFLOAT_S8_UINT: + aspect |= VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT | + VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT + } + return VkImageAspectFlags(aspect) +} + func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { - var outputBarrierAspect VkImageAspectFlags - switch job.aspect { - case VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT: - outputBarrierAspect = VkImageAspectFlags(VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT) - case VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT, + switch job.renderTarget.aspect { + case VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT, + VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT, VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT: - switch job.renderTarget.Info().Fmt() { - case VkFormat_VK_FORMAT_D16_UNORM_S8_UINT, - VkFormat_VK_FORMAT_D24_UNORM_S8_UINT, - VkFormat_VK_FORMAT_D32_SFLOAT_S8_UINT: - outputBarrierAspect = VkImageAspectFlags(VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT | - VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT) - default: - outputBarrierAspect = VkImageAspectFlags(job.aspect) - } default: - return log.Errf(h.sb.ctx, nil, "unsupported aspect: %v", job.aspect) + return log.Errf(h.sb.ctx, nil, "unsupported aspect: %v", job.renderTarget.aspect) } + outputBarrierAspect := imageBarrierAspectFlags(job.renderTarget.aspect, job.renderTarget.image.Info().Fmt()) var outputPreRenderLayout VkImageLayout - switch job.aspect { + switch job.renderTarget.aspect { case VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT: outputPreRenderLayout = VkImageLayout_VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL case VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT, VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT: outputPreRenderLayout = VkImageLayout_VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL default: - return log.Errf(h.sb.ctx, nil, "unsupported aspect: %v", job.aspect) + return log.Errf(h.sb.ctx, nil, "unsupported aspect: %v", job.renderTarget.aspect) } - dev := job.renderTarget.Device() + dev := job.renderTarget.image.Device() descSetInfo := ipRenderDescriptorSetInfo{ dev: dev, numInputAttachments: len(job.inputAttachmentImages), } - if job.aspect == VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT { + if job.renderTarget.aspect == VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT { // If the render target aspect is stencil, an uniform buffer is required // to store the stencil bit index value. descSetInfo.numUniformBuffers = 1 @@ -1112,30 +1140,31 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { inputViews := []ImageViewObjectʳ{} for _, input := range job.inputAttachmentImages { // TODO: support rendering to 3D images if maintenance1 is enabled. - if input.Info().ImageType() == VkImageType_VK_IMAGE_TYPE_3D { + if input.image.Info().ImageType() == VkImageType_VK_IMAGE_TYPE_3D { return log.Errf(h.sb.ctx, nil, "rendering to 3D images are not supported yet") } - view := h.createImageView(dev, input, VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT, job.layer, job.level) + view := h.createImageView(dev, input.image, input.aspect, input.layer, input.level) inputViews = append(inputViews, view) if !view.IsNil() { tsk.deferUntilExecuted(func() { h.sb.write(h.sb.cb.VkDestroyImageView(dev, view.VulkanHandle(), memory.Nullptr)) }) } else { - return log.Errf(h.sb.ctx, nil, "failed to create image view for input attachment image: %v", input.VulkanHandle()) + return log.Errf(h.sb.ctx, nil, "failed to create image view for input attachment image: %v", input.image.VulkanHandle()) } } // TODO: support rendering to 3D images if maintenance1 is enabled. - if job.renderTarget.Info().ImageType() == VkImageType_VK_IMAGE_TYPE_3D { + if job.renderTarget.image.Info().ImageType() == VkImageType_VK_IMAGE_TYPE_3D { return log.Errf(h.sb.ctx, nil, "rendering to 3D images are not supported yet") } - outputView := h.createImageView(dev, job.renderTarget, job.aspect, job.layer, job.level) + outputView := h.createImageView(dev, job.renderTarget.image, job.renderTarget.aspect, job.renderTarget.layer, job.renderTarget.level) if !outputView.IsNil() { tsk.deferUntilExecuted(func() { h.sb.write(h.sb.cb.VkDestroyImageView(dev, outputView.VulkanHandle(), memory.Nullptr)) }) } else { - return log.Errf(h.sb.ctx, nil, "failed to create image view for rendering target image: %v", job.renderTarget.VulkanHandle()) + return log.Errf(h.sb.ctx, nil, "failed to create image view for rendering target image: %v", + job.renderTarget.image.VulkanHandle()) } imgInfoList := []VkDescriptorImageInfo{} @@ -1152,7 +1181,7 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { }) var stencilIndexBuf VkBuffer - if job.aspect == VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT { + if job.renderTarget.aspect == VkImageAspectFlagBits_VK_IMAGE_ASPECT_STENCIL_BIT { // write the uniform buffer for rendering stencil value. stencilBitIndices := []uint32{0} var sbic bytes.Buffer @@ -1181,13 +1210,13 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { renderPassInfo := ipRenderPassInfo{ dev: dev, numInputAttachments: len(job.inputAttachmentImages), - inputAttachmentImageFormat: job.inputAttachmentImages[0].Info().Fmt(), - inputAttachmentImageSamples: job.inputAttachmentImages[0].Info().Samples(), - targetAspect: job.aspect, - targetFormat: job.renderTarget.Info().Fmt(), - targetSamples: job.renderTarget.Info().Samples(), + inputAttachmentImageFormat: job.inputAttachmentImages[0].image.Info().Fmt(), + inputAttachmentImageSamples: job.inputAttachmentImages[0].image.Info().Samples(), + targetAspect: job.renderTarget.aspect, + targetFormat: job.renderTarget.image.Info().Fmt(), + targetSamples: job.renderTarget.image.Info().Samples(), } - renderPass := h.createRenderPass(renderPassInfo, job.finalLayout) + renderPass := h.createRenderPass(renderPassInfo, job.renderTarget.finalLayout) if !renderPass.IsNil() { tsk.deferUntilExecuted(func() { h.sb.write(h.sb.cb.VkDestroyRenderPass(dev, renderPass.VulkanHandle(), memory.Nullptr)) @@ -1202,7 +1231,8 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { } allViews = append(allViews, outputView.VulkanHandle()) - targetLevelSize := h.sb.levelSize(job.renderTarget.Info().Extent(), job.renderTarget.Info().Fmt(), job.level, job.aspect) + targetLevelSize := h.sb.levelSize(job.renderTarget.image.Info().Extent(), + job.renderTarget.image.Info().Fmt(), job.renderTarget.level, job.renderTarget.aspect) framebuffer := h.createFramebuffer(dev, renderPass.VulkanHandle(), allViews, uint32(targetLevelSize.width), uint32(targetLevelSize.height)) @@ -1223,8 +1253,8 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { fragShaderInfo: ipRenderShaderInfo{ dev: dev, isVertex: false, - format: job.renderTarget.Info().Fmt(), - aspect: job.aspect, + format: job.renderTarget.image.Info().Fmt(), + aspect: job.renderTarget.aspect, }, pipelineLayout: pipelineLayout.VulkanHandle(), renderPassInfo: renderPassInfo, @@ -1263,26 +1293,46 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { h.sb.write(h.sb.cb.VkDestroyBuffer(dev, indexBuf, memory.Nullptr)) }) - inputBarriers := []VkImageMemoryBarrier{} + inputSrcBarriers := []VkImageMemoryBarrier{} + dstBarriers := []VkImageMemoryBarrier{} for _, input := range job.inputAttachmentImages { - inputLevel := input.Aspects().Get(VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT).Layers().Get(job.layer).Levels().Get(job.level) - inputBarriers = append(inputBarriers, + aspects := imageBarrierAspectFlags(input.aspect, input.image.Info().Fmt()) + inputSrcBarriers = append(inputSrcBarriers, NewVkImageMemoryBarrier(h.sb.ta, VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 0, // pNext VkAccessFlags((VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT-1)|VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT), // srcAccessMask VkAccessFlags(VkAccessFlagBits_VK_ACCESS_INPUT_ATTACHMENT_READ_BIT), // dstAccessMask - inputLevel.Layout(), // oldLayout + input.initialLayout, // oldLayout VkImageLayout_VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout queueFamilyIgnore, // srcQueueFamilyIndex queueFamilyIgnore, // dstQueueFamilyIndex - input.VulkanHandle(), // image + input.image.VulkanHandle(), // image NewVkImageSubresourceRange(h.sb.ta, // subresourceRange - VkImageAspectFlags(VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT), // aspectMask - 0, // baseMipLevel - input.Info().MipLevels(), // levelCount + aspects, // aspectMask + 0, // baseMipLevel + input.image.Info().MipLevels(), // levelCount + 0, // baseArrayLayer + input.image.Info().ArrayLayers(), // layerCount + ), + )) + dstBarriers = append(dstBarriers, + NewVkImageMemoryBarrier(h.sb.ta, + VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType + 0, // pNext + VkAccessFlags((VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT-1)|VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT), // srcAccessMask + VkAccessFlags(VkAccessFlagBits_VK_ACCESS_INPUT_ATTACHMENT_READ_BIT), // dstAccessMask + VkImageLayout_VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // oldLayout + input.finalLayout, // newLayout + queueFamilyIgnore, // srcQueueFamilyIndex + queueFamilyIgnore, // dstQueueFamilyIndex + input.image.VulkanHandle(), // image + NewVkImageSubresourceRange(h.sb.ta, // subresourceRange + aspects, // aspectMask + 0, // baseMipLevel + input.image.Info().MipLevels(), // levelCount 0, // baseArrayLayer - input.Info().ArrayLayers(), // layerCount + input.image.Info().ArrayLayers(), // layerCount ), )) } @@ -1291,18 +1341,20 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { 0, // pNext 0, // srcAccessMask VkAccessFlags(VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT), // dstAccessMask - GetState(h.sb.newState).Images().Get(job.renderTarget.VulkanHandle()).Aspects().Get( - job.aspect).Layers().Get(job.layer).Levels().Get(job.level).Layout(), // oldLayout - outputPreRenderLayout, // newLayout - queueFamilyIgnore, // srcQueueFamilyIndex - queueFamilyIgnore, // dstQueueFamilyIndex - job.renderTarget.VulkanHandle(), // image + GetState(h.sb.newState).Images().Get(job.renderTarget.image.VulkanHandle()).Aspects().Get( + job.renderTarget.aspect).Layers().Get( + job.renderTarget.layer).Levels().Get( + job.renderTarget.level).Layout(), // oldLayout + outputPreRenderLayout, // newLayout + queueFamilyIgnore, // srcQueueFamilyIndex + queueFamilyIgnore, // dstQueueFamilyIndex + job.renderTarget.image.VulkanHandle(), // image NewVkImageSubresourceRange(h.sb.ta, // subresourceRange outputBarrierAspect, // aspectMask 0, // baseMipLevel - job.renderTarget.Info().MipLevels(), // levelCount + job.renderTarget.image.Info().MipLevels(), // levelCount 0, // baseArrayLayer - job.renderTarget.Info().ArrayLayers(), // layerCount + job.renderTarget.image.Info().ArrayLayers(), // layerCount )) bufBarriers := []VkBufferMemoryBarrier{ NewVkBufferMemoryBarrier(h.sb.ta, @@ -1339,12 +1391,12 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { memory.Nullptr, uint32(len(bufBarriers)), h.sb.MustAllocReadData(bufBarriers).Ptr(), - uint32(len(append(inputBarriers, outputBarrier))), - h.sb.MustAllocReadData(append(inputBarriers, outputBarrier)).Ptr(), + uint32(len(append(inputSrcBarriers, outputBarrier))), + h.sb.MustAllocReadData(append(inputSrcBarriers, outputBarrier)).Ptr(), )) }) - switch job.aspect { + switch job.renderTarget.aspect { // render color or depth aspect case VkImageAspectFlagBits_VK_IMAGE_ASPECT_COLOR_BIT, VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT: drawInfo := ipRenderDrawInfo{ @@ -1356,7 +1408,7 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { pipeline: pipeline, vertexBuf: vertexBuf, indexBuf: indexBuf, - aspect: job.aspect, + aspect: job.renderTarget.aspect, width: uint32(targetLevelSize.width), height: uint32(targetLevelSize.height), stencilWriteMask: 0, @@ -1401,13 +1453,13 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { VkImageLayout_VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // newLayout queueFamilyIgnore, // srcQueueFamilyIndex queueFamilyIgnore, // dstQueueFamilyIndex - job.renderTarget.VulkanHandle(), // image + job.renderTarget.image.VulkanHandle(), // image NewVkImageSubresourceRange(h.sb.ta, // subresourceRange outputBarrierAspect, // aspectMask 0, // baseMipLevel - job.renderTarget.Info().MipLevels(), // levelCount + job.renderTarget.image.Info().MipLevels(), // levelCount 0, // baseArrayLayer - job.renderTarget.Info().ArrayLayers(), // layerCount + job.renderTarget.image.Info().ArrayLayers(), // layerCount ), )}).Ptr(), )) @@ -1461,41 +1513,41 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { } h.beginRenderPassAndDraw(drawInfo) } - tsk.recordCmdBufCommand(func(commandBuffer VkCommandBuffer) { - h.sb.write(h.sb.cb.VkCmdPipelineBarrier( - commandBuffer, - VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT), - VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT), - VkDependencyFlags(0), - 0, - memory.Nullptr, - 0, - memory.Nullptr, - 1, - h.sb.MustAllocReadData([]VkImageMemoryBarrier{ - NewVkImageMemoryBarrier(h.sb.ta, - VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType - 0, // pNext - VkAccessFlags(VkAccessFlagBits_VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT), // srcAccessMask - VkAccessFlags(VkAccessFlagBits_VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT), // dstAccessMask - VkImageLayout_VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // oldLayout - job.finalLayout, // newLayout - queueFamilyIgnore, // srcQueueFamilyIndex - queueFamilyIgnore, // dstQueueFamilyIndex - job.renderTarget.VulkanHandle(), // image - NewVkImageSubresourceRange(h.sb.ta, // subresourceRange - outputBarrierAspect, // aspectMask - 0, // baseMipLevel - job.renderTarget.Info().MipLevels(), // levelCount - 0, // baseArrayLayer - job.renderTarget.Info().ArrayLayers(), // layerCount - ), - )}).Ptr(), - )) - }) + dstBarriers = append(dstBarriers, NewVkImageMemoryBarrier(h.sb.ta, + VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType + 0, // pNext + VkAccessFlags(VkAccessFlagBits_VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT), // srcAccessMask + VkAccessFlags(VkAccessFlagBits_VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT), // dstAccessMask + VkImageLayout_VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // oldLayout + job.renderTarget.finalLayout, // newLayout + queueFamilyIgnore, // srcQueueFamilyIndex + queueFamilyIgnore, // dstQueueFamilyIndex + job.renderTarget.image.VulkanHandle(), // image + NewVkImageSubresourceRange(h.sb.ta, // subresourceRange + outputBarrierAspect, // aspectMask + 0, // baseMipLevel + job.renderTarget.image.Info().MipLevels(), // levelCount + 0, // baseArrayLayer + job.renderTarget.image.Info().ArrayLayers(), // layerCount + ), + )) default: - return log.Errf(h.sb.ctx, nil, "invalid aspect: %v to render", job.aspect) + return log.Errf(h.sb.ctx, nil, "invalid aspect: %v to render", job.renderTarget.aspect) } + tsk.recordCmdBufCommand(func(commandBuffer VkCommandBuffer) { + h.sb.write(h.sb.cb.VkCmdPipelineBarrier( + commandBuffer, + VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT), + VkPipelineStageFlags(VkPipelineStageFlagBits_VK_PIPELINE_STAGE_ALL_COMMANDS_BIT), + VkDependencyFlags(0), + 0, + memory.Nullptr, + 0, + memory.Nullptr, + 1, + h.sb.MustAllocReadData(dstBarriers).Ptr(), + )) + }) return nil } diff --git a/gapis/api/vulkan/overdraw.go b/gapis/api/vulkan/overdraw.go index c4e9d3f7ff..9ec1d901a6 100644 --- a/gapis/api/vulkan/overdraw.go +++ b/gapis/api/vulkan/overdraw.go @@ -188,8 +188,7 @@ func (*stencilOverdraw) rewriteImageCreate(ctx context.Context, cmd.Extras().Observations().ApplyReads(gs.Memory.ApplicationPool()) createInfo := cmd.PCreateInfo().MustRead(ctx, cmd, gs, nil) - mask := VkImageUsageFlags(VkImageUsageFlagBits_VK_IMAGE_USAGE_TRANSFER_SRC_BIT | - VkImageUsageFlagBits_VK_IMAGE_USAGE_TRANSFER_DST_BIT) + mask := VkImageUsageFlags(VkImageUsageFlagBits_VK_IMAGE_USAGE_TRANSFER_SRC_BIT) if !isDepthFormat(createInfo.Fmt()) || (createInfo.Usage()&mask == mask) { out.MutateAndWrite(ctx, id, cmd) @@ -325,6 +324,13 @@ func (s *stencilOverdraw) createNewRenderPassFramebuffer(ctx context.Context, } width, height := oldFbInfo.Width(), oldFbInfo.Height() + // If we have a pre-existing depth image match our width and height to + // that for when we render from one to the other. + if depthIdx != ^uint32(0) { + depthImage := oldFbInfo.ImageAttachments().Get(depthIdx).Image() + width = depthImage.Info().Extent().Width() + height = depthImage.Info().Extent().Height() + } device := oldFbInfo.Device() image, err := s.createImage(ctx, cb, st, a, device, attachDesc.Fmt(), width, height, alloc, addCleanup, out) @@ -490,7 +496,8 @@ func (*stencilOverdraw) createImage(ctx context.Context, VkImageUsageFlags( // usage VkImageUsageFlagBits_VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT| VkImageUsageFlagBits_VK_IMAGE_USAGE_TRANSFER_SRC_BIT| - VkImageUsageFlagBits_VK_IMAGE_USAGE_TRANSFER_DST_BIT), + VkImageUsageFlagBits_VK_IMAGE_USAGE_TRANSFER_DST_BIT| + VkImageUsageFlagBits_VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT), VkSharingMode_VK_SHARING_MODE_EXCLUSIVE, // sharingMode 0, // queueFamilyIndexCount 0, // pQueueFamilyIndices @@ -1376,13 +1383,18 @@ func (s *stencilOverdraw) copyImageDepthAspect(ctx context.Context, srcImageView.Image().VulkanHandle(), // image srcImageView.SubresourceRange(), // subresourceRange ) + srcFinalLayout := srcImageDesc.layout + if srcFinalLayout == VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED || + srcFinalLayout == VkImageLayout_VK_IMAGE_LAYOUT_PREINITIALIZED { + srcFinalLayout = VkImageLayout_VK_IMAGE_LAYOUT_GENERAL + } imgBarriers1[0] = NewVkImageMemoryBarrier(a, VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 0, // pNext VkAccessFlags(VkAccessFlagBits_VK_ACCESS_TRANSFER_READ_BIT), // srcAccessMask allMemoryAccess, // dstAccessMask VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // oldLayout - srcImageDesc.layout, // newLayout + srcFinalLayout, // newLayout ^uint32(0), // srcQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED ^uint32(0), // dstQueueFamilyIndex srcImageView.Image().VulkanHandle(), // image @@ -1403,13 +1415,18 @@ func (s *stencilOverdraw) copyImageDepthAspect(ctx context.Context, dstImageView.SubresourceRange(), // subresourceRange ) + dstFinalLayout := dstImageDesc.layout + if dstFinalLayout == VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED || + dstFinalLayout == VkImageLayout_VK_IMAGE_LAYOUT_PREINITIALIZED { + dstFinalLayout = VkImageLayout_VK_IMAGE_LAYOUT_GENERAL + } imgBarriers1[1] = NewVkImageMemoryBarrier(a, VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 0, // pNext VkAccessFlags(VkAccessFlagBits_VK_ACCESS_TRANSFER_WRITE_BIT), // srcAccessMask allMemoryAccess, // dstAccessMask VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout - dstImageDesc.layout, // newLayout + dstFinalLayout, // newLayout ^uint32(0), // srcQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED ^uint32(0), // dstQueueFamilyIndex dstImageView.Image().VulkanHandle(), // image @@ -1544,34 +1561,78 @@ func (s *stencilOverdraw) storeNewDepthValues(ctx context.Context, st *State, a arena.Arena, device VkDevice, + queue VkQueue, cmdBuffer VkCommandBuffer, renderInfo renderInfo, alloc func(v ...interface{}) api.AllocResult, addCleanup func(func()), out transform.Writer, -) { +) error { if renderInfo.depthIdx == ^uint32(0) { - return + return nil } rpInfo := st.RenderPasses().Get(renderInfo.renderPass) daInfo := rpInfo.AttachmentDescriptions().Get(renderInfo.depthIdx) if daInfo.StoreOp() != VkAttachmentStoreOp_VK_ATTACHMENT_STORE_OP_STORE { - return + return nil } fbInfo := st.Framebuffers().Get(renderInfo.framebuffer) oldImageView := fbInfo.ImageAttachments().Get(uint32(fbInfo.ImageAttachments().Len() - 1)) + oldImageSubresource := oldImageView.SubresourceRange() + oldImageLayout := rpInfo.AttachmentDescriptions().Get(uint32(fbInfo.ImageAttachments().Len() - 1)).FinalLayout() newImageView := fbInfo.ImageAttachments().Get(renderInfo.depthIdx) + newImageSubresource := newImageView.SubresourceRange() newImageLayout := daInfo.FinalLayout() - s.copyImageDepthAspect(ctx, cb, gs, st, a, device, cmdBuffer, - imageDesc{oldImageView.Get(), - VkImageLayout_VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL}, - imageDesc{newImageView.Get(), newImageLayout}, - NewVkExtent3D(a, fbInfo.Width(), fbInfo.Height(), 1), - alloc, addCleanup, out) + sb := st.newStateBuilder(ctx, newTransformerOutput(out)) + ip := newImagePrimer(sb) + queueScratch := sb.getQueueFamilyScratchResources(queue) + queueScratch.commandBuffers[queue] = cmdBuffer + scratchTask := sb.newScratchTaskOnQueue(queue) + + renderJob := &ipRenderJob{ + inputAttachmentImages: []ipRenderImage{ + ipRenderImage{ + image: oldImageView.Image(), + aspect: VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT, + layer: oldImageSubresource.BaseArrayLayer(), + level: oldImageSubresource.BaseMipLevel(), + initialLayout: oldImageLayout, + finalLayout: oldImageLayout, + }, + }, + renderTarget: ipRenderImage{ + image: newImageView.Image(), + aspect: VkImageAspectFlagBits_VK_IMAGE_ASPECT_DEPTH_BIT, + layer: newImageSubresource.BaseArrayLayer(), + level: newImageSubresource.BaseMipLevel(), + initialLayout: newImageLayout, + finalLayout: newImageLayout, + }, + } + + err := ip.rh.render(renderJob, scratchTask) + if err != nil { + return err + } + // Make sure it doesn't use temporary memory as that would cause a flush of the scratch resources + queueScratch.memorySize = scratchTask.totalAllocationSize + + scratchTask.commit() + addCleanup(func() { + writeEach(ctx, out, cb.VkFreeMemory(device, queueScratch.memory, memory.Nullptr)) + }) + + cleanup := queueScratch.postExecuted[queue] + // Make sure the cleanups are executed in the right order + for i := len(cleanup) - 1; i >= 0; i-- { + addCleanup(cleanup[i]) + } + + return nil } func (s *stencilOverdraw) transitionStencilImage(ctx context.Context, @@ -1624,6 +1685,7 @@ func (s *stencilOverdraw) createCommandBuffer(ctx context.Context, gs *api.GlobalState, st *State, a arena.Arena, + queue VkQueue, cmdBuffer VkCommandBuffer, renderInfo renderInfo, rpStartIdx uint64, @@ -1717,9 +1779,10 @@ func (s *stencilOverdraw) createCommandBuffer(ctx context.Context, newCmdbuf, ok := secCmdBuffers[cmdbuf] if !ok { var err error - newCmdbuf, err = s.createCommandBuffer(ctx, - cb, gs, st, a, cmdbuf, renderInfo, - 0, alloc, addCleanup, out) + newCmdbuf, err = s.createCommandBuffer(ctx, cb, + gs, st, a, queue, cmdbuf, + renderInfo, 0, alloc, + addCleanup, out) if err != nil { return 0, err } @@ -1738,8 +1801,10 @@ func (s *stencilOverdraw) createCommandBuffer(ctx context.Context, if _, ok := args.(VkCmdEndRenderPassArgsʳ); ok { // Add commands to handle storing the new depth values if necessary - s.storeNewDepthValues(ctx, cb, gs, st, a, device, - newCmdBuffer, renderInfo, alloc, addCleanup, out) + if err := s.storeNewDepthValues(ctx, cb, gs, st, a, device, + queue, newCmdBuffer, renderInfo, alloc, addCleanup, out); err != nil { + return 0, err + } } } writeEach(ctx, out, @@ -1815,6 +1880,7 @@ func (s *stencilOverdraw) rewriteQueueSubmit(ctx context.Context, if uint64(i) == rpBeginIdx[0] { newCommandBuffer, err := s.createCommandBuffer(ctx, cb, gs, st, a, + submit.Queue(), cmdBuffers[rpBeginIdx[1]], renderInfo, rpBeginIdx[2], diff --git a/gapis/api/vulkan/read_framebuffer.go b/gapis/api/vulkan/read_framebuffer.go index ad260c4b9a..2354f26e2e 100644 --- a/gapis/api/vulkan/read_framebuffer.go +++ b/gapis/api/vulkan/read_framebuffer.go @@ -240,6 +240,11 @@ func postImageData(ctx context.Context, } queue := imageObject.Aspects().Get(aspect).Layers().Get(0).Levels().Get(0).LastBoundQueue() + if queue.IsNil() { + res(nil, &service.ErrDataUnavailable{Reason: messages.ErrMessage("The target image object has not been bound with a vkQueue")}) + return + } + vkQueue := queue.VulkanHandle() vkDevice := queue.Device() device := GetState(s).Devices().Get(vkDevice) @@ -249,10 +254,6 @@ func postImageData(ctx context.Context, requestWidth := reqWidth requestHeight := reqHeight - if queue.IsNil() { - res(nil, &service.ErrDataUnavailable{Reason: messages.ErrMessage("The target image object has not been bound with a vkQueue")}) - return - } if properties, ok := physicalDevice.QueueFamilyProperties().Lookup(queue.Family()); ok { if properties.QueueFlags()&VkQueueFlags(VkQueueFlagBits_VK_QUEUE_GRAPHICS_BIT) == 0 { if imageObject.Info().Samples() == VkSampleCountFlagBits_VK_SAMPLE_COUNT_1_BIT && diff --git a/gapis/api/vulkan/state_rebuilder.go b/gapis/api/vulkan/state_rebuilder.go index f494b67874..32ae901b54 100644 --- a/gapis/api/vulkan/state_rebuilder.go +++ b/gapis/api/vulkan/state_rebuilder.go @@ -23,6 +23,7 @@ import ( "github.com/google/gapid/core/math/interval" "github.com/google/gapid/core/memory/arena" "github.com/google/gapid/gapis/api" + "github.com/google/gapid/gapis/api/transform" "github.com/google/gapid/gapis/database" "github.com/google/gapid/gapis/memory" ) @@ -36,7 +37,7 @@ type stateBuilder struct { s *State oldState *api.GlobalState newState *api.GlobalState - cmds []api.Cmd + out stateBuilderOutput cb CommandBuilder readMemories []*api.AllocResult writeMemories []*api.AllocResult @@ -46,26 +47,90 @@ type stateBuilder struct { scratchResources map[VkDevice]map[uint32]*queueFamilyScratchResources } +type stateBuilderOutput interface { + write(ctx context.Context, cmd api.Cmd, id api.CmdID) + getOldState() *api.GlobalState + getNewState() *api.GlobalState +} + +type initialStateOutput struct { + oldState *api.GlobalState + newState *api.GlobalState + cmds []api.Cmd +} + +func newInitialStateOutput(oldState *api.GlobalState) *initialStateOutput { + return &initialStateOutput{ + oldState: oldState, + newState: api.NewStateWithAllocator(memory.NewBasicAllocator( + oldState.Allocator.FreeList()), oldState.MemoryLayout), + cmds: []api.Cmd{}, + } +} + +func (o *initialStateOutput) write(ctx context.Context, cmd api.Cmd, id api.CmdID) { + if err := cmd.Mutate(ctx, id, o.newState, nil); err != nil { + log.W(ctx, "Initial cmd %v: %v - %v", len(o.cmds), cmd, err) + } else { + log.D(ctx, "Initial cmd %v: %v", len(o.cmds), cmd) + } + o.cmds = append(o.cmds, cmd) +} + +func (o *initialStateOutput) getOldState() *api.GlobalState { + return o.oldState +} + +func (o *initialStateOutput) getNewState() *api.GlobalState { + return o.newState +} + +type transformerOutput struct { + out transform.Writer +} + +func newTransformerOutput(out transform.Writer) *transformerOutput { + return &transformerOutput{out} +} + +func (o *transformerOutput) write(ctx context.Context, cmd api.Cmd, id api.CmdID) { + o.out.MutateAndWrite(ctx, id, cmd) +} + +func (o *transformerOutput) getOldState() *api.GlobalState { + return o.out.State() +} + +func (o *transformerOutput) getNewState() *api.GlobalState { + return o.out.State() +} + type idAndRng struct { id id.ID rng memory.Range } -// TODO: wherever possible, use old resources instead of doing full reads on the old pools. -// This is especially useful for things that are internal pools, (Shader words for example) -func (s *State) RebuildState(ctx context.Context, oldState *api.GlobalState) ([]api.Cmd, interval.U64RangeList) { - // TODO: Debug Info - newState := api.NewStateWithAllocator(memory.NewBasicAllocator(oldState.Allocator.FreeList()), oldState.MemoryLayout) - sb := &stateBuilder{ +func (s *State) newStateBuilder(ctx context.Context, out stateBuilderOutput) *stateBuilder { + newState := out.getNewState() + return &stateBuilder{ ctx: ctx, s: s, - oldState: oldState, + oldState: out.getOldState(), newState: newState, + out: out, cb: CommandBuilder{Thread: 0, Arena: newState.Arena}, memoryIntervals: interval.U64RangeList{}, ta: arena.New(), scratchResources: map[VkDevice]map[uint32]*queueFamilyScratchResources{}, } +} + +// TODO: wherever possible, use old resources instead of doing full reads on the old pools. +// This is especially useful for things that are internal pools, (Shader words for example) +func (s *State) RebuildState(ctx context.Context, oldState *api.GlobalState) ([]api.Cmd, interval.U64RangeList) { + // TODO: Debug Info + out := newInitialStateOutput(oldState) + sb := s.newStateBuilder(ctx, out) defer sb.ta.Dispose() @@ -196,7 +261,7 @@ func (s *State) RebuildState(ctx context.Context, oldState *api.GlobalState) ([] sb.flushAllScratchResources() sb.freeAllScratchResources() - return sb.cmds, sb.memoryIntervals + return out.cmds, sb.memoryIntervals } func getPipelinesInOrder(s *State, compute bool) []VkPipeline { @@ -348,12 +413,7 @@ func (sb *stateBuilder) write(cmd api.Cmd) { cmd.Extras().GetOrAppendObservations().AddWrite(write.Data()) } - if err := cmd.Mutate(sb.ctx, api.CmdNoID, sb.newState, nil); err != nil { - log.W(sb.ctx, "Initial cmd %v: %v - %v", len(sb.cmds), cmd, err) - } else { - log.D(sb.ctx, "Initial cmd %v: %v", len(sb.cmds), cmd) - } - sb.cmds = append(sb.cmds, cmd) + sb.out.write(sb.ctx, cmd, api.CmdNoID) for _, read := range sb.readMemories { read.Free() } From 3eb3aecf0da79c2ff381f63e918fdc320fca6ef1 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Tue, 24 Jul 2018 11:33:55 -0400 Subject: [PATCH 2/3] Fix review comments --- gapis/api/vulkan/image_primer.go | 48 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/gapis/api/vulkan/image_primer.go b/gapis/api/vulkan/image_primer.go index dad7710d6a..a13a536daa 100644 --- a/gapis/api/vulkan/image_primer.go +++ b/gapis/api/vulkan/image_primer.go @@ -1074,7 +1074,7 @@ func (h *ipRenderHandler) free() { } } -func imageBarrierAspectFlags(aspect VkImageAspectFlagBits, fmt VkFormat) VkImageAspectFlags { +func ipImageBarrierAspectFlags(aspect VkImageAspectFlagBits, fmt VkFormat) VkImageAspectFlags { switch fmt { case VkFormat_VK_FORMAT_D16_UNORM_S8_UINT, VkFormat_VK_FORMAT_D24_UNORM_S8_UINT, @@ -1093,7 +1093,7 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { default: return log.Errf(h.sb.ctx, nil, "unsupported aspect: %v", job.renderTarget.aspect) } - outputBarrierAspect := imageBarrierAspectFlags(job.renderTarget.aspect, job.renderTarget.image.Info().Fmt()) + outputBarrierAspect := ipImageBarrierAspectFlags(job.renderTarget.aspect, job.renderTarget.image.Info().Fmt()) var outputPreRenderLayout VkImageLayout switch job.renderTarget.aspect { @@ -1296,7 +1296,7 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { inputSrcBarriers := []VkImageMemoryBarrier{} dstBarriers := []VkImageMemoryBarrier{} for _, input := range job.inputAttachmentImages { - aspects := imageBarrierAspectFlags(input.aspect, input.image.Info().Fmt()) + aspects := ipImageBarrierAspectFlags(input.aspect, input.image.Info().Fmt()) inputSrcBarriers = append(inputSrcBarriers, NewVkImageMemoryBarrier(h.sb.ta, VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType @@ -1316,25 +1316,27 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { input.image.Info().ArrayLayers(), // layerCount ), )) - dstBarriers = append(dstBarriers, - NewVkImageMemoryBarrier(h.sb.ta, - VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType - 0, // pNext - VkAccessFlags((VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT-1)|VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT), // srcAccessMask - VkAccessFlags(VkAccessFlagBits_VK_ACCESS_INPUT_ATTACHMENT_READ_BIT), // dstAccessMask - VkImageLayout_VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // oldLayout - input.finalLayout, // newLayout - queueFamilyIgnore, // srcQueueFamilyIndex - queueFamilyIgnore, // dstQueueFamilyIndex - input.image.VulkanHandle(), // image - NewVkImageSubresourceRange(h.sb.ta, // subresourceRange - aspects, // aspectMask - 0, // baseMipLevel - input.image.Info().MipLevels(), // levelCount - 0, // baseArrayLayer - input.image.Info().ArrayLayers(), // layerCount - ), - )) + if input.finalLayout != VkImageLayout_VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL { + dstBarriers = append(dstBarriers, + NewVkImageMemoryBarrier(h.sb.ta, + VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType + 0, // pNext + VkAccessFlags((VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT-1)|VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT), // srcAccessMask + VkAccessFlags(VkAccessFlagBits_VK_ACCESS_INPUT_ATTACHMENT_READ_BIT), // dstAccessMask + VkImageLayout_VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // oldLayout + input.finalLayout, // newLayout + queueFamilyIgnore, // srcQueueFamilyIndex + queueFamilyIgnore, // dstQueueFamilyIndex + input.image.VulkanHandle(), // image + NewVkImageSubresourceRange(h.sb.ta, // subresourceRange + aspects, // aspectMask + 0, // baseMipLevel + input.image.Info().MipLevels(), // levelCount + 0, // baseArrayLayer + input.image.Info().ArrayLayers(), // layerCount + ), + )) + } } outputBarrier := NewVkImageMemoryBarrier(h.sb.ta, VkStructureType_VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType @@ -1544,7 +1546,7 @@ func (h *ipRenderHandler) render(job *ipRenderJob, tsk *scratchTask) error { memory.Nullptr, 0, memory.Nullptr, - 1, + uint32(len(dstBarriers)), h.sb.MustAllocReadData(dstBarriers).Ptr(), )) }) From 77ed67604da03402ba77803b5d5c14e8d07a5e06 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Tue, 24 Jul 2018 13:36:40 -0400 Subject: [PATCH 3/3] Fix overdraw case where clear values weren't set properly --- gapis/api/vulkan/overdraw.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/gapis/api/vulkan/overdraw.go b/gapis/api/vulkan/overdraw.go index 9ec1d901a6..0db8ff906a 100644 --- a/gapis/api/vulkan/overdraw.go +++ b/gapis/api/vulkan/overdraw.go @@ -1729,10 +1729,13 @@ func (s *stencilOverdraw) createCommandBuffer(ctx context.Context, newArgs.SetRenderPass(renderInfo.renderPass) newArgs.SetFramebuffer(renderInfo.framebuffer) - clearCount := uint32(newArgs.ClearValues().Len()) + rpInfo := st.RenderPasses().Get(renderInfo.renderPass) + attachmentIdx := uint32(rpInfo.AttachmentDescriptions().Len()) - 1 newClear := NewU32ː4ᵃ(a) - if renderInfo.depthIdx != ^uint32(0) { + if renderInfo.depthIdx != ^uint32(0) && + rpInfo.AttachmentDescriptions().Get(renderInfo.depthIdx).LoadOp() == + VkAttachmentLoadOp_VK_ATTACHMENT_LOAD_OP_CLEAR { newClear.Set(0, newArgs. ClearValues(). Get(renderInfo.depthIdx). @@ -1740,8 +1743,13 @@ func (s *stencilOverdraw) createCommandBuffer(ctx context.Context, Uint32(). Get(0)) } + for j := uint32(0); j < attachmentIdx; j++ { + if !newArgs.ClearValues().Contains(j) { + newArgs.ClearValues().Add(j, NilVkClearValue) + } + } // 0 initialize the stencil buffer - newArgs.ClearValues().Add(clearCount, + newArgs.ClearValues().Add(attachmentIdx, // Use VkClearColorValue instead of // VkClearDepthValue because it doesn't // seem like the union is set up in the