diff --git a/gapii/cc/vulkan_extras.cpp b/gapii/cc/vulkan_extras.cpp index c65a744199..a5a0a9e8f0 100644 --- a/gapii/cc/vulkan_extras.cpp +++ b/gapii/cc/vulkan_extras.cpp @@ -717,6 +717,10 @@ void VulkanSpy::walkImageSubRng( gapil::Ref img, VkImageSubresourceRange rng, std::function f) { + uint32_t layer_count = + subImageSubresourceLayerCount(nullptr, nullptr, img, rng); + uint32_t level_count = + subImageSubresourceLevelCount(nullptr, nullptr, img, rng); auto aspect_map = subUnpackImageAspectFlags(nullptr, nullptr, rng.maspectMask); for (auto b : aspect_map->mBits) { @@ -725,13 +729,13 @@ void VulkanSpy::walkImageSubRng( continue; } for (uint32_t layer = rng.mbaseArrayLayer; - layer < rng.mbaseArrayLayer + rng.mlayerCount; layer++) { + layer < rng.mbaseArrayLayer + layer_count; layer++) { auto layi = ai->second->mLayers.find(layer); if (layi == ai->second->mLayers.end()) { continue; } for (uint32_t level = rng.mbaseMipLevel; - level < rng.mbaseMipLevel + rng.mlevelCount; level++) { + level < rng.mbaseMipLevel + level_count; level++) { auto levi = layi->second->mLevels.find(level); if (levi == layi->second->mLevels.end()) { continue; diff --git a/gapis/api/vulkan/api/image.api b/gapis/api/vulkan/api/image.api index 4bc4a7eebb..3c007c9539 100644 --- a/gapis/api/vulkan/api/image.api +++ b/gapis/api/vulkan/api/image.api @@ -469,28 +469,13 @@ cmd void vkDestroySampler( } sub void readImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng, VkImageLayout layout) { - if layout != VK_IMAGE_LAYOUT_UNDEFINED { - _ = checkImageSubresourceRangeLayout(image, rng, layout) - } - VK_REMAINING_ARRAY_LAYERS := as!u32(0xFFFFFFFF) - VK_REMAINING_MIP_LEVELS := as!u32(0xFFFFFFFF) + layerCount := imageSubresourceLayerCount(image, rng) + levelCount := imageSubresourceLevelCount(image, rng) for _ , _ , aspectBit in unpackImageAspectFlags(rng.aspectMask).Bits { aspect := image.Aspects[aspectBit] - layerEnd := switch (rng.layerCount == VK_REMAINING_ARRAY_LAYERS) { - case true: - image.Info.ArrayLayers - rng.baseArrayLayer - case false: - rng.layerCount - } - levelEnd := switch (rng.levelCount == VK_REMAINING_MIP_LEVELS) { - case true: - image.Info.MipLevels - rng.baseMipLevel - case false: - rng.levelCount - } - for layerIndex in (rng.baseArrayLayer .. layerEnd) { + for layerIndex in (rng.baseArrayLayer .. rng.baseArrayLayer + layerCount) { layer := aspect.Layers[layerIndex] - for mipLevel in (rng.baseMipLevel .. levelEnd) { + for mipLevel in (rng.baseMipLevel .. rng.baseMipLevel + levelCount) { level := layer.Levels[mipLevel] read(level.Data) } @@ -499,28 +484,13 @@ sub void readImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng } sub void writeImageSubresource(ref!ImageObject image, VkImageSubresourceRange rng, VkImageLayout layout) { - if layout != VK_IMAGE_LAYOUT_UNDEFINED { - _ = checkImageSubresourceRangeLayout(image, rng, layout) - } - VK_REMAINING_ARRAY_LAYERS := as!u32(0xFFFFFFFF) - VK_REMAINING_MIP_LEVELS := as!u32(0xFFFFFFFF) + layerCount := imageSubresourceLayerCount(image, rng) + levelCount := imageSubresourceLevelCount(image, rng) for _ , _ , aspectBit in unpackImageAspectFlags(rng.aspectMask).Bits { aspect := image.Aspects[aspectBit] - layerEnd := switch (rng.layerCount == VK_REMAINING_ARRAY_LAYERS) { - case true: - image.Info.ArrayLayers - rng.baseArrayLayer - case false: - rng.layerCount - } - levelEnd := switch (rng.levelCount == VK_REMAINING_MIP_LEVELS) { - case true: - image.Info.MipLevels - rng.baseMipLevel - case false: - rng.levelCount - } - for layerIndex in (rng.baseArrayLayer .. layerEnd) { + for layerIndex in (rng.baseArrayLayer .. rng.baseArrayLayer + layerCount) { layer := aspect.Layers[layerIndex] - for mipLevel in (rng.baseMipLevel .. levelEnd) { + for mipLevel in (rng.baseMipLevel .. rng.baseMipLevel + levelCount) { level := layer.Levels[mipLevel] write(level.Data) } @@ -528,15 +498,44 @@ sub void writeImageSubresource(ref!ImageObject image, VkImageSubresourceRange rn } } -sub void transitionImageLayout(ref!ImageObject img, VkImageSubresourceRange rng, VkImageLayout oldLayout, VkImageLayout newLayout) { - if oldLayout != VK_IMAGE_LAYOUT_UNDEFINED { - _ = checkImageSubresourceRangeLayout(img, rng, oldLayout) +sub u32 imageSubresourceLayerCount(ref!ImageObject image, VkImageSubresourceRange rng) { + VK_REMAINING_ARRAY_LAYERS := as!u32(0xFFFFFFFF) + return switch (rng.layerCount == VK_REMAINING_ARRAY_LAYERS) { + case true: + image.Info.ArrayLayers - rng.baseArrayLayer + case false: + switch ((rng.layerCount + rng.baseArrayLayer) > image.Info.ArrayLayers) { + case true: + image.Info.ArrayLayers - rng.baseArrayLayer + case false: + rng.layerCount + } } +} + +sub u32 imageSubresourceLevelCount(ref!ImageObject image, VkImageSubresourceRange rng) { + VK_REMAINING_MIP_LEVELS := as!u32(0xFFFFFFFF) + return switch (rng.levelCount == VK_REMAINING_MIP_LEVELS) { + case true: + image.Info.MipLevels - rng.baseMipLevel + case false: + switch ((rng.levelCount + rng.baseMipLevel) > image.Info.MipLevels) { + case true: + image.Info.MipLevels - rng.baseMipLevel + case false: + rng.levelCount + } + } +} + +sub void transitionImageLayout(ref!ImageObject img, VkImageSubresourceRange rng, VkImageLayout oldLayout, VkImageLayout newLayout) { + layerCount := imageSubresourceLayerCount(img, rng) + levelCount := imageSubresourceLevelCount(img, rng) for _ , _ , aspectBit in unpackImageAspectFlags(rng.aspectMask).Bits { if (aspectBit in img.Aspects) { - for layer in (rng.baseArrayLayer .. rng.baseArrayLayer + rng.layerCount) { + for layer in (rng.baseArrayLayer .. rng.baseArrayLayer + layerCount) { if (layer in img.Aspects[aspectBit].Layers) { - for level in (rng.baseMipLevel .. rng.baseMipLevel + rng.levelCount) { + for level in (rng.baseMipLevel .. rng.baseMipLevel + levelCount) { if (level in img.Aspects[aspectBit].Layers[layer].Levels) { imgLevel := img.Aspects[aspectBit].Layers[layer].Levels[level] imgLevel.Layout = newLayout @@ -547,59 +546,3 @@ sub void transitionImageLayout(ref!ImageObject img, VkImageSubresourceRange rng, } } } - -sub bool checkImageSubresourceRangeLayout(ref!ImageObject img, VkImageSubresourceRange rng, VkImageLayout expectedLayout) { - res := MutableBool(true) - for _ , _ , aspectBit in unpackImageAspectFlags(rng.aspectMask).Bits { - for layer in (rng.baseArrayLayer .. rng.baseArrayLayer + rng.layerCount) { - for level in (rng.baseMipLevel .. rng.baseMipLevel + rng.levelCount) { - if !(checkImageLevelLayout(img, aspectBit, layer, level, expectedLayout, true)) { - res.b = false - } - } - } - } - return res.b -} - -sub bool checkImageLevelLayout(ref!ImageObject img, VkImageAspectFlagBits aspect, u32 layer, u32 level, VkImageLayout expectedLayout, bool report) { - res := MutableBool(false) - if checkImageLevelExistence(img, aspect, layer, level, report) { - imgLevel := img.Aspects[aspect].Layers[layer].Levels[level] - if (imgLevel.Layout == expectedLayout) { - res.b = true - } else { - if report { - vkErrorInvalidImageLayout(img.VulkanHandle, aspect, layer, level, imgLevel.Layout, expectedLayout) - } - } - } - return res.b -} - -sub bool checkImageLevelExistence(ref!ImageObject img, VkImageAspectFlagBits aspect, u32 layer, u32 level, bool report) { - exist := MutableBool(false) - if !(aspect in img.Aspects) { - if report { - vkErrorInvalidImageAspect(img.VulkanHandle, aspect) - } - } - else { - if !(layer in img.Aspects[aspect].Layers) { - if report { - vkErrorInvalidImageArrayLayer(img.VulkanHandle, layer) - } - } - else { - if !(level in img.Aspects[aspect].Layers[layer].Levels) { - if report { - vkErrorInvalidImageMipLevel(img.VulkanHandle, level) - } - } - else { - exist.b = true - } - } - } - return exist.b -} diff --git a/gapis/api/vulkan/footprint_builder.go b/gapis/api/vulkan/footprint_builder.go index 01244d1084..b1d9307ddb 100644 --- a/gapis/api/vulkan/footprint_builder.go +++ b/gapis/api/vulkan/footprint_builder.go @@ -32,6 +32,8 @@ var emptyDefUseVars = []dependencygraph.DefUseVariable{} const vkWholeSize = uint64(0xFFFFFFFFFFFFFFFF) const vkAttachmentUnused = uint32(0xFFFFFFFF) const vkNullHandle = vkHandle(0x0) +const vkRemainingArrayLayers = uint32(0xFFFFFFFF) +const vkRemainingMipLevels = uint32(0xFFFFFFFF) // Assume the value of a Vulkan handle is always unique type vkHandle uint64 @@ -608,11 +610,13 @@ func (qei *queueExecutionState) beginRenderPass(ctx context.Context, case VkImageViewType_VK_IMAGE_VIEW_TYPE_2D, VkImageViewType_VK_IMAGE_VIEW_TYPE_2D_ARRAY: if viewObj.SubresourceRange().BaseArrayLayer() == uint32(0) && - imgObj.Info().ArrayLayers() == viewObj.SubresourceRange().LayerCount() && + (imgObj.Info().ArrayLayers() == viewObj.SubresourceRange().LayerCount() || + viewObj.SubresourceRange().LayerCount() == vkRemainingArrayLayers) && imgObj.Info().ImageType() == VkImageType_VK_IMAGE_TYPE_2D && imgObj.Info().Extent().Width() == fb.Width() && imgObj.Info().Extent().Height() == fb.Height() && - fb.Layers() == imgObj.Info().ArrayLayers() { + (fb.Layers() == imgObj.Info().ArrayLayers() || + fb.Layers() == vkRemainingArrayLayers) { fullImageData = true } } @@ -696,11 +700,13 @@ func (qei *queueExecutionState) beginRenderPass(ctx context.Context, case VkImageViewType_VK_IMAGE_VIEW_TYPE_2D, VkImageViewType_VK_IMAGE_VIEW_TYPE_2D_ARRAY: if viewObj.SubresourceRange().BaseArrayLayer() == uint32(0) && - imgObj.Info().ArrayLayers() == viewObj.SubresourceRange().LayerCount() && + (imgObj.Info().ArrayLayers() == viewObj.SubresourceRange().LayerCount() || + viewObj.SubresourceRange().LayerCount() == vkRemainingMipLevels) && imgObj.Info().ImageType() == VkImageType_VK_IMAGE_TYPE_2D && imgObj.Info().Extent().Width() == fb.Width() && imgObj.Info().Extent().Height() == fb.Height() && - fb.Layers() == imgObj.Info().ArrayLayers() { + (fb.Layers() == imgObj.Info().ArrayLayers() || + fb.Layers() == vkRemainingArrayLayers) { fullImageData = true } } @@ -3093,7 +3099,7 @@ func subresourceLayersFullyCoverImage(img ImageObjectʳ, layers VkImageSubresour if layers.BaseArrayLayer() != uint32(0) { return false } - if layers.LayerCount() != img.Info().ArrayLayers() { + if layers.LayerCount() != img.Info().ArrayLayers() && layers.LayerCount() != vkRemainingArrayLayers { return false } // Be conservative, only returns true if both the depth and the stencil @@ -3115,7 +3121,8 @@ func subresourceRangeFullyCoverImage(img ImageObjectʳ, rng VkImageSubresourceRa if rng.BaseArrayLayer() != 0 || rng.BaseMipLevel() != 0 { return false } - if rng.LayerCount() != img.Info().ArrayLayers() || rng.LevelCount() != img.Info().MipLevels() { + if (rng.LayerCount() != img.Info().ArrayLayers() && rng.LayerCount() != vkRemainingArrayLayers) || + (rng.LevelCount() != img.Info().MipLevels() && rng.LevelCount() != vkRemainingMipLevels) { return false } // Be conservative, only returns true if both the depth and the stencil bits diff --git a/gapis/api/vulkan/image_primer.go b/gapis/api/vulkan/image_primer.go index a9db145302..1f1aaae8d5 100644 --- a/gapis/api/vulkan/image_primer.go +++ b/gapis/api/vulkan/image_primer.go @@ -2593,11 +2593,13 @@ func writeDescriptorSet(sb *stateBuilder, dev VkDevice, descSet VkDescriptorSet, } func walkImageSubresourceRange(sb *stateBuilder, img ImageObjectʳ, rng VkImageSubresourceRange, f func(aspect VkImageAspectFlagBits, layer, level uint32, levelSize byteSizeAndExtent)) { + layerCount, _ := subImageSubresourceLayerCount(sb.ctx, nil, api.CmdNoID, nil, sb.oldState, nil, 0, nil, img, rng) + levelCount, _ := subImageSubresourceLevelCount(sb.ctx, nil, api.CmdNoID, nil, sb.oldState, nil, 0, nil, img, rng) for _, aspect := range sb.imageAspectFlagBits(rng.AspectMask()) { - for i := uint32(0); i < rng.LevelCount(); i++ { + for i := uint32(0); i < levelCount; i++ { level := rng.BaseMipLevel() + i levelSize := sb.levelSize(img.Info().Extent(), img.Info().Fmt(), level, aspect) - for j := uint32(0); j < rng.LayerCount(); j++ { + for j := uint32(0); j < layerCount; j++ { layer := rng.BaseArrayLayer() + j f(aspect, layer, level, levelSize) } diff --git a/gapis/api/vulkan/state_rebuilder.go b/gapis/api/vulkan/state_rebuilder.go index 2c239aacde..ca0a9eeb6e 100644 --- a/gapis/api/vulkan/state_rebuilder.go +++ b/gapis/api/vulkan/state_rebuilder.go @@ -1409,8 +1409,10 @@ func (sb *stateBuilder) createImage(img ImageObjectʳ, imgPrimer *imagePrimer) { // layout. The unused byteSizeAndExtent is to meet the requirement of // walkImageSubresourceRange() appendImageLevelToOpaqueRanges := func(aspect VkImageAspectFlagBits, layer, level uint32, unused byteSizeAndExtent) { - // TODO: Re-enable the code to prevent copying to an - // undefined layout. + imgLevel := img.Aspects().Get(aspect).Layers().Get(layer).Levels().Get(level) + if imgLevel.Layout() == VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED { + return + } opaqueRanges = append(opaqueRanges, NewVkImageSubresourceRange(sb.ta, VkImageAspectFlags(aspect), // aspectMask level, // baseMipLevel @@ -1565,11 +1567,10 @@ func (sb *stateBuilder) createImage(img ImageObjectʳ, imgPrimer *imagePrimer) { walkImageSubresourceRange(sb, img, sb.imageWholeSubresourceRange(img), func(aspect VkImageAspectFlagBits, layer, level uint32, unused byteSizeAndExtent) { // No need to handle for undefined layout - if isUndef, _ := subCheckImageLevelLayout(sb.ctx, nil, api.CmdNoID, nil, sb.oldState, - nil, 0, nil, img, aspect, layer, level, VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED, false); isUndef { + imgLevel := img.Aspects().Get(aspect).Layers().Get(layer).Levels().Get(level) + if imgLevel.Layout() == VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED { return } - imgLevel := img.Aspects().Get(aspect).Layers().Get(layer).Levels().Get(level) transitionInfo = append(transitionInfo, imgSubRngLayoutTransitionInfo{ aspectMask: VkImageAspectFlags(aspect), baseMipLevel: level,