From 885e48f5fe599d7fa29066c4a545fd6e9479fe02 Mon Sep 17 00:00:00 2001 From: AWoloszyn Date: Tue, 4 Sep 2018 09:53:43 -0400 Subject: [PATCH] Add spy_disabled annotation to subroutines. This allows us to have subroutines that are not sensible in the spy, but should still run in the server. The starting example for this is an expensive loop through all levels/layers of an image to do a read, which is disabled in the interceptor anyway. --- gapis/api/templates/api_spy.cpp.tmpl | 8 +- gapis/api/vulkan/api/coherent_memory.api | 93 ++++++++++--------- gapis/api/vulkan/api/copy_clear_commands.api | 3 + gapis/api/vulkan/api/descriptor.api | 1 + gapis/api/vulkan/api/image.api | 44 ++++++++- .../api/vulkan/api/renderpass_framebuffer.api | 12 ++- gapis/api/vulkan/api/synchronization.api | 1 + gapis/api/vulkan/api/util.api | 2 +- gapis/api/vulkan/extensions/khr_swapchain.api | 6 +- 9 files changed, 115 insertions(+), 55 deletions(-) diff --git a/gapis/api/templates/api_spy.cpp.tmpl b/gapis/api/templates/api_spy.cpp.tmpl index 5c4d9fae28..6176edfc3b 100644 --- a/gapis/api/templates/api_spy.cpp.tmpl +++ b/gapis/api/templates/api_spy.cpp.tmpl @@ -316,8 +316,12 @@ {{$args := Strings "CallObserver* observer" "const std::function& call" (Macro "C++.CallParameters" $) | JoinWith ", "}} {{Template "C++.SubReturnType" $}} {{$spyname}}::{{$name}}({{$args}}) { - {{Global "CurrentCommand" $}} - {{Template "C++.Block" $.Block}} + {{if (GetAnnotation ($) "spy_disabled")}} + // @spy_disabled + {{else}} + {{Global "CurrentCommand" $}} + {{Template "C++.Block" $.Block}} + {{end}} } {{end}} diff --git a/gapis/api/vulkan/api/coherent_memory.api b/gapis/api/vulkan/api/coherent_memory.api index 6eda80a0ca..30fe36a53e 100644 --- a/gapis/api/vulkan/api/coherent_memory.api +++ b/gapis/api/vulkan/api/coherent_memory.api @@ -100,6 +100,7 @@ sub void readMemoryInImageBindings(map!(u32, ref!VkDescriptorImageInfo) imageBin imageViewObj := ImageViews[v.ImageView] imageObj := imageViewObj.Image rng := imageViewObj.SubresourceRange + updateImageQueue(imageObj, rng) readImageSubresource(imageObj, rng) } } @@ -107,30 +108,32 @@ sub void readMemoryInImageBindings(map!(u32, ref!VkDescriptorImageInfo) imageBin } sub void readMemoryInDescriptorSet(ref!DescriptorSetObject descriptor_set, map!(u32, map!(u32, VkDeviceSize)) bufferBindingOffsets) { - for i in (0 .. len(descriptor_set.Bindings)) { - binding := descriptor_set.Bindings[as!u32(i)] - switch binding.BindingType { - case - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - if as!u32(i) in bufferBindingOffsets { - readMemoryInBufferBindings(binding.BufferBinding, bufferBindingOffsets[as!u32(i)]) - } else { - readMemoryInBufferBindings(binding.BufferBinding, null) - } - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - readMemoryInBufferViewBindings(binding.BufferViewBindings) - case - VK_DESCRIPTOR_TYPE_SAMPLER, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - readMemoryInImageBindings(binding.ImageBinding) - default: {} + if descriptor_set != null { + for i in (0 .. len(descriptor_set.Bindings)) { + binding := descriptor_set.Bindings[as!u32(i)] + switch binding.BindingType { + case + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + if as!u32(i) in bufferBindingOffsets { + readMemoryInBufferBindings(binding.BufferBinding, bufferBindingOffsets[as!u32(i)]) + } else { + readMemoryInBufferBindings(binding.BufferBinding, null) + } + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + readMemoryInBufferViewBindings(binding.BufferViewBindings) + case + VK_DESCRIPTOR_TYPE_SAMPLER, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + readMemoryInImageBindings(binding.ImageBinding) + default: {} + } } } } @@ -188,27 +191,30 @@ sub void writeMemoryInImageBindings(map!(u32, ref!VkDescriptorImageInfo) imageBi imageObj := imageViewObj.Image rng := imageViewObj.SubresourceRange writeImageSubresource(imageObj, rng) + updateImageQueue(imageObj, rng) } } } sub void writeMemoryInDescriptorSet(ref!DescriptorSetObject descriptor_set, map!(u32, map!(u32, VkDeviceSize)) bufferBindingOffsets) { - for i in (0 .. len(descriptor_set.Bindings)) { - binding := descriptor_set.Bindings[as!u32(i)] - switch binding.BindingType { - case - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - if as!u32(i) in bufferBindingOffsets { - writeMemoryInBufferBindings(binding.BufferBinding, bufferBindingOffsets[as!u32(i)]) - } else { - writeMemoryInBufferBindings(binding.BufferBinding, null) - } - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - writeMemoryInBufferViewBindings(binding.BufferViewBindings) - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - writeMemoryInImageBindings(binding.ImageBinding) - default: {} + if descriptor_set != null { + for i in (0 .. len(descriptor_set.Bindings)) { + binding := descriptor_set.Bindings[as!u32(i)] + switch binding.BindingType { + case + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + if as!u32(i) in bufferBindingOffsets { + writeMemoryInBufferBindings(binding.BufferBinding, bufferBindingOffsets[as!u32(i)]) + } else { + writeMemoryInBufferBindings(binding.BufferBinding, null) + } + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + writeMemoryInBufferViewBindings(binding.BufferViewBindings) + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + writeMemoryInImageBindings(binding.ImageBinding) + default: {} + } } } } @@ -220,11 +226,8 @@ sub void readWriteMemoryInBoundDescriptorSets( map!(u32, map!(u32, map!(u32, VkDeviceSize))) bufferBindingOffsets) { layerCount := len(pipelineLayout.SetLayouts) for i in (0 .. layerCount) { - descriptorSet := descriptorSets[as!u32(i)] - if descriptorSet != null { - readMemoryInDescriptorSet(descriptorSet, bufferBindingOffsets[as!u32(i)]) - writeMemoryInDescriptorSet(descriptorSet, bufferBindingOffsets[as!u32(i)]) - } + readMemoryInDescriptorSet(descriptorSets[as!u32(i)], bufferBindingOffsets[as!u32(i)]) + writeMemoryInDescriptorSet(descriptorSets[as!u32(i)], bufferBindingOffsets[as!u32(i)]) } } diff --git a/gapis/api/vulkan/api/copy_clear_commands.api b/gapis/api/vulkan/api/copy_clear_commands.api index 31b7e6f111..29c12081f9 100644 --- a/gapis/api/vulkan/api/copy_clear_commands.api +++ b/gapis/api/vulkan/api/copy_clear_commands.api @@ -784,7 +784,10 @@ sub void dovkCmdResolveImage(ref!vkCmdResolveImageArgs args) { 1, r.dstSubresource.baseArrayLayer, r.dstSubresource.layerCount) + + updateImageQueue(Images[args.SrcImage], srcRange) readImageSubresource(Images[args.SrcImage], srcRange) + updateImageQueue(Images[args.DstImage], dstRange) writeImageSubresource(Images[args.DstImage], dstRange) } } diff --git a/gapis/api/vulkan/api/descriptor.api b/gapis/api/vulkan/api/descriptor.api index ebd7305847..b8e7fc5a5d 100644 --- a/gapis/api/vulkan/api/descriptor.api +++ b/gapis/api/vulkan/api/descriptor.api @@ -740,6 +740,7 @@ sub void dovkCmdBindDescriptorSets(ref!vkCmdBindDescriptorSetsArgs args) { imageObj := imageViewObj.Image rng := imageViewObj.SubresourceRange readImageSubresource(imageObj, rng) + updateImageQueue(imageObj, rng) } } } diff --git a/gapis/api/vulkan/api/image.api b/gapis/api/vulkan/api/image.api index 77b51bb286..30562f4533 100644 --- a/gapis/api/vulkan/api/image.api +++ b/gapis/api/vulkan/api/image.api @@ -74,6 +74,9 @@ VkMemoryRequirements MemoryRequirements map!(u32, VkSparseImageMemoryRequirements) SparseMemoryRequirements ref!DedicatedRequirementsKHR DedicatedRequirementsKHR + // If ever layer/level is set to the same queue, then set it here instead. + // This can save expensive looping through Aspects/Layers/Levels + @unused ref!QueueObject LastBoundQueue } @internal class ImageAspect { @@ -578,6 +581,44 @@ cmd void vkDestroySampler( } } +sub bool isEntireSubresource(ref!ImageObject image, VkImageSubresourceRange rng) { + layerCount := imageSubresourceLayerCount(image, rng) + levelCount := imageSubresourceLevelCount(image, rng) + return ((as!u32(image.ImageAspect) & as!u32(rng.aspectMask)) == as!u32(image.ImageAspect)) && + (rng.baseArrayLayer == 0) && (rng.baseMipLevel == 0) && + (layerCount == image.Info.ArrayLayers) && (levelCount == image.Info.MipLevels) +} + +sub void updateImageQueue(ref!ImageObject image, VkImageSubresourceRange rng) { + if (image.LastBoundQueue != LastBoundQueue) { + if (isEntireSubresource(image, rng)) { + image.LastBoundQueue = LastBoundQueue + setQueueInRange(image, rng, LastBoundQueue) + } else { + setQueueInRange(image, rng, LastBoundQueue) + image.LastBoundQueue = null + } + } +} + +sub void setQueueInRange(ref!ImageObject image, VkImageSubresourceRange rng, + ref!QueueObject queue) { + layerCount := imageSubresourceLayerCount(image, rng) + levelCount := imageSubresourceLevelCount(image, rng) + for _ , _ , aspectBit in unpackImageAspectFlags(rng.aspectMask) { + for _, i, layer in image.Aspects[aspectBit].Layers { + if (i >= rng.baseArrayLayer) && (i < rng.baseArrayLayer + layerCount) { + for _, k, level in layer.Levels { + if (k >= rng.baseMipLevel) && (k < rng.baseMipLevel + levelCount) { + level.LastBoundQueue = queue + } + } + } + } + } +} + +@spy_disabled sub void readImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng) { layerCount := imageSubresourceLayerCount(image, rng) levelCount := imageSubresourceLevelCount(image, rng) @@ -587,7 +628,6 @@ sub void readImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng for _, k, level in layer.Levels { if (k >= rng.baseMipLevel) && (k < rng.baseMipLevel + levelCount) { read(level.Data) - level.LastBoundQueue = LastBoundQueue } } } @@ -595,6 +635,7 @@ sub void readImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng } } +@spy_disabled sub void writeImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng) { layerCount := imageSubresourceLayerCount(image, rng) levelCount := imageSubresourceLevelCount(image, rng) @@ -605,7 +646,6 @@ sub void writeImageSubresource(ref!ImageObject image, VkImageSubresourceRange rn for mipLevel in (rng.baseMipLevel .. rng.baseMipLevel + levelCount) { level := layer.Levels[mipLevel] write(level.Data) - level.LastBoundQueue = LastBoundQueue } } } diff --git a/gapis/api/vulkan/api/renderpass_framebuffer.api b/gapis/api/vulkan/api/renderpass_framebuffer.api index 0875618fdd..ba616d9c13 100644 --- a/gapis/api/vulkan/api/renderpass_framebuffer.api +++ b/gapis/api/vulkan/api/renderpass_framebuffer.api @@ -339,11 +339,15 @@ sub void loadImageAttachment(u32 attachmentID) { desc := lastDrawInfo().RenderPass.AttachmentDescriptions[attachmentID] if attachment.Image != null { switch desc.loadOp { - case VK_ATTACHMENT_LOAD_OP_LOAD: + case VK_ATTACHMENT_LOAD_OP_LOAD: { readImageSubresource(attachment.Image, attachment.SubresourceRange) - default: + updateImageQueue(attachment.Image, attachment.SubresourceRange) + } + default: { // write to the attachment image, to prevent any dependencies on previous writes + updateImageQueue(attachment.Image, attachment.SubresourceRange) writeImageSubresource(attachment.Image, attachment.SubresourceRange) + } } } } @@ -359,8 +363,10 @@ sub void storeImageAttachment(u32 attachmentID) { transitionImageLayout(attachment.Image, attachment.SubresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, desc.finalLayout) } switch desc.storeOp { - case VK_ATTACHMENT_STORE_OP_STORE: + case VK_ATTACHMENT_STORE_OP_STORE: { writeImageSubresource(attachment.Image, attachment.SubresourceRange) + updateImageQueue(attachment.Image, attachment.SubresourceRange) + } default: { // do nothing } diff --git a/gapis/api/vulkan/api/synchronization.api b/gapis/api/vulkan/api/synchronization.api index ff94828704..f46eeac62b 100644 --- a/gapis/api/vulkan/api/synchronization.api +++ b/gapis/api/vulkan/api/synchronization.api @@ -419,6 +419,7 @@ sub void dovkCmdPipelineBarrier(ref!vkCmdPipelineBarrierArgs args) { transitionImageLayout(image, v.subresourceRange, v.oldLayout, v.newLayout) if v.oldLayout == VK_IMAGE_LAYOUT_UNDEFINED { writeImageSubresource(image, v.subresourceRange) + updateImageQueue(image, v.subresourceRange) } } } diff --git a/gapis/api/vulkan/api/util.api b/gapis/api/vulkan/api/util.api index 37e6202a50..ba5bb4bfed 100644 --- a/gapis/api/vulkan/api/util.api +++ b/gapis/api/vulkan/api/util.api @@ -351,7 +351,7 @@ sub u32 getDepthElementSize(VkFormat format, bool inBuffer) { map!(VkImageAspectFlags, dense_map!(u32, VkImageAspectFlagBits)) allBits } -@serialize +@hidden @serialize AllBits allBits @internal class unpackedImageAspectFlagBits { diff --git a/gapis/api/vulkan/extensions/khr_swapchain.api b/gapis/api/vulkan/extensions/khr_swapchain.api index f620b8753b..2f717b2363 100644 --- a/gapis/api/vulkan/extensions/khr_swapchain.api +++ b/gapis/api/vulkan/extensions/khr_swapchain.api @@ -281,12 +281,14 @@ cmd VkResult vkQueuePresentKHR( if !(swapchains[i] in Swapchains) { vkErrorInvalidSwapchain(swapchains[i]) } swapchain := Swapchains[swapchains[i]] image := swapchain.SwapchainImages[imageIndices[i]] - readImageSubresource(image, VkImageSubresourceRange( + rng := VkImageSubresourceRange( aspectMask: image.ImageAspect, baseMipLevel: 0, levelCount: image.Info.MipLevels, baseArrayLayer: 0, - layerCount: image.Info.ArrayLayers)) + layerCount: image.Info.ArrayLayers) + readImageSubresource(image, rng) + updateImageQueue(image, rng) LastPresentInfo.PresentImages[LastPresentInfo.PresentImageCount] = image LastPresentInfo.PresentImageCount = LastPresentInfo.PresentImageCount + 1