Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle VK_REMAINING_ARRAY_LAYER/MIP_LEVEL #1946

Merged
merged 1 commit into from
Jun 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions gapii/cc/vulkan_extras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,10 @@ void VulkanSpy::walkImageSubRng(
gapil::Ref<ImageObject> img, VkImageSubresourceRange rng,
std::function<void(uint32_t aspect_bit, uint32_t layer, uint32_t level)>
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) {
Expand All @@ -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;
Expand Down
141 changes: 42 additions & 99 deletions gapis/api/vulkan/api/image.api
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -499,44 +484,58 @@ 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)
}
}
}
}

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
Expand All @@ -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
}
19 changes: 13 additions & 6 deletions gapis/api/vulkan/footprint_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
6 changes: 4 additions & 2 deletions gapis/api/vulkan/image_primer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
11 changes: 6 additions & 5 deletions gapis/api/vulkan/state_rebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down