Vulkan: Add ImgRefs to track usage of image subresorces

Change-Id: I7f111fb8aa4e1296315a8c852830205cf51f05e5
This commit is contained in:
Benson Joeris
2019-06-05 09:52:33 -07:00
committed by Baldur Karlsson
parent 217506869f
commit be2a6549dd
6 changed files with 559 additions and 1 deletions
+1
View File
@@ -37,6 +37,7 @@ set(sources
vk_serialise.cpp
vk_stringise.cpp
vk_layer.cpp
imgrefs_tests.cpp
official/vk_layer.h
official/vk_layer_dispatch_table.h
official/vk_platform.h
+214
View File
@@ -0,0 +1,214 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "common/globalconfig.h"
#if ENABLED(ENABLE_UNIT_TESTS)
#include "3rdparty/catch/catch.hpp"
#include "vk_resources.h"
#include <stdint.h>
#include <vector>
TEST_CASE("Test ImgRefs type", "[imgrefs]")
{
SECTION("unsplit")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 0);
};
SECTION("split aspect")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(true, false, false);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 1);
};
SECTION("split levels")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(false, true, false);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 2);
};
SECTION("split layers")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(false, false, true);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 5);
};
SECTION("split aspect and levels")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(true, true, false);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 11 + 2);
};
SECTION("split aspect and layers")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(true, false, true);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 17 + 5);
};
SECTION("split levels and layers")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(false, true, true);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 2 * 17 + 5);
};
SECTION("split aspect and levels and layers")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
imgRefs.Split(true, true, true);
CHECK(imgRefs.SubresourceIndex(VK_IMAGE_ASPECT_STENCIL_BIT, 2, 5) == 11 * 17 + 2 * 17 + 5);
};
SECTION("update unsplit")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
ImageRange range;
imgRefs.Update(range, eFrameRef_Read);
std::vector<FrameRefType> expected = {eFrameRef_Read};
CHECK(imgRefs.rangeRefs == expected);
};
SECTION("update split aspect")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
ImageRange range;
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
imgRefs.Update(range, eFrameRef_Read);
std::vector<FrameRefType> expected = {eFrameRef_None, eFrameRef_Read};
CHECK(imgRefs.rangeRefs == expected);
};
SECTION("update split levels")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
ImageRange range;
range.baseMipLevel = 1;
range.levelCount = 3;
imgRefs.Update(range, eFrameRef_Read);
std::vector<FrameRefType> expected = {eFrameRef_None, eFrameRef_Read, eFrameRef_Read,
eFrameRef_Read, eFrameRef_None, eFrameRef_None,
eFrameRef_None, eFrameRef_None, eFrameRef_None,
eFrameRef_None, eFrameRef_None};
CHECK(imgRefs.rangeRefs == expected);
};
SECTION("update split layers")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
ImageRange range;
range.baseArrayLayer = 7;
imgRefs.Update(range, eFrameRef_Read);
std::vector<FrameRefType> expected = {
eFrameRef_None, eFrameRef_None, eFrameRef_None, eFrameRef_None, eFrameRef_None,
eFrameRef_None, eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_Read,
eFrameRef_Read, eFrameRef_Read, eFrameRef_Read, eFrameRef_Read, eFrameRef_Read,
eFrameRef_Read, eFrameRef_Read};
CHECK(imgRefs.rangeRefs == expected);
};
SECTION("update split aspect then levels")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 11,
17, {100, 100, 1});
ImageRange range0;
range0.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
imgRefs.Update(range0, eFrameRef_Read);
ImageRange range1;
range1.baseMipLevel = 5;
range1.levelCount = 2;
imgRefs.Update(range1, eFrameRef_PartialWrite);
std::vector<FrameRefType> expected = {
// VK_IMAGE_ASPECT_DEPTH_BIT
eFrameRef_None, eFrameRef_None, eFrameRef_None, eFrameRef_None, eFrameRef_None,
eFrameRef_PartialWrite, eFrameRef_PartialWrite, eFrameRef_None, eFrameRef_None,
eFrameRef_None, eFrameRef_None,
// VK_IMAGE_ASPECT_STENCIL_BIT
eFrameRef_Read, eFrameRef_Read, eFrameRef_Read, eFrameRef_Read, eFrameRef_Read,
eFrameRef_ReadBeforeWrite, eFrameRef_ReadBeforeWrite, eFrameRef_Read, eFrameRef_Read,
eFrameRef_Read, eFrameRef_Read,
};
CHECK(imgRefs.rangeRefs == expected);
}
SECTION("update split layers then aspects and levels")
{
ImgRefs imgRefs(VK_IMAGE_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 7, 5,
{100, 100, 1});
ImageRange range0;
range0.baseArrayLayer = 1;
range0.layerCount = 2;
imgRefs.Update(range0, eFrameRef_Read);
ImageRange range1;
range1.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
range1.baseMipLevel = 2;
range1.levelCount = 3;
imgRefs.Update(range1, eFrameRef_PartialWrite);
std::vector<FrameRefType> expected = {
// (Depth, level 0)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Depth, level 1)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Depth, level 2)
eFrameRef_PartialWrite, eFrameRef_ReadBeforeWrite, eFrameRef_ReadBeforeWrite,
eFrameRef_PartialWrite, eFrameRef_PartialWrite,
// (Depth, level 3)
eFrameRef_PartialWrite, eFrameRef_ReadBeforeWrite, eFrameRef_ReadBeforeWrite,
eFrameRef_PartialWrite, eFrameRef_PartialWrite,
// (Depth, level 4)
eFrameRef_PartialWrite, eFrameRef_ReadBeforeWrite, eFrameRef_ReadBeforeWrite,
eFrameRef_PartialWrite, eFrameRef_PartialWrite,
// (Depth, level 5)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Depth, level 6)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 0)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 1)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 2)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 3)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 4)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 5)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
// (Stencil, level 6)
eFrameRef_None, eFrameRef_Read, eFrameRef_Read, eFrameRef_None, eFrameRef_None,
};
CHECK(imgRefs.rangeRefs == expected);
}
};
#endif // ENABLED(ENABLE_UNIT_TESTS)
@@ -99,6 +99,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="imgrefs_tests.cpp" />
<ClCompile Include="precompiled.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
@@ -139,6 +139,9 @@
<ClCompile Include="vk_bindless_feedback.cpp">
<Filter>Replay</Filter>
</ClCompile>
<ClCompile Include="imgrefs_tests.cpp">
<Filter>Util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="vk_replay.h">
+85
View File
@@ -2919,6 +2919,91 @@ VkImageAspectFlags FormatImageAspects(VkFormat fmt)
return VK_IMAGE_ASPECT_COLOR_BIT;
}
int ImgRefs::GetAspectCount() const
{
int aspectCount = 0;
for(auto aspectIt = ImageAspectFlagIter::begin(aspectMask);
aspectIt != ImageAspectFlagIter::end(); ++aspectIt)
{
++aspectCount;
}
return aspectCount;
}
int ImgRefs::SubresourceIndex(VkImageAspectFlagBits aspect, int level, int layer) const
{
int aspectIndex = 0;
if(areAspectsSplit)
{
for(auto aspectIt = ImageAspectFlagIter::begin(aspectMask);
aspectIt != ImageAspectFlagIter::end(); ++aspectIt)
{
if(*aspectIt == aspect)
break;
++aspectIndex;
}
}
return SubresourceIndex(aspectIndex, level, layer);
}
int ImgRefs::SubresourceIndex(int aspectIndex, int level, int layer) const
{
if(!areAspectsSplit)
aspectIndex = 0;
int splitLevelCount = 1;
if(areLevelsSplit)
splitLevelCount = levelCount;
else
level = 0;
int splitLayerCount = 1;
if(areLayersSplit)
splitLayerCount = layerCount;
else
layer = 0;
return (aspectIndex * splitLevelCount + level) * splitLayerCount + layer;
}
void ImgRefs::Split(bool splitAspects, bool splitLevels, bool splitLayers)
{
int newSplitAspectCount = 1;
if(splitAspects || areAspectsSplit)
{
newSplitAspectCount = GetAspectCount();
}
int oldSplitLevelCount = areLevelsSplit ? levelCount : 1;
int newSplitLevelCount = splitLevels ? levelCount : oldSplitLevelCount;
int oldSplitLayerCount = areLayersSplit ? layerCount : 1;
int newSplitLayerCount = splitLayers ? layerCount : oldSplitLayerCount;
int newSize = newSplitAspectCount * newSplitLevelCount * newSplitLayerCount;
if(newSize == (int)rangeRefs.size())
return;
rangeRefs.resize(newSize);
for(int newAspectIndex = newSplitAspectCount - 1; newAspectIndex >= 0; --newAspectIndex)
{
int oldAspectIndex = areAspectsSplit ? newAspectIndex : 0;
for(int newLevel = newSplitLevelCount - 1; newLevel >= 0; --newLevel)
{
int oldLevel = areLevelsSplit ? newLevel : 0;
for(int newLayer = newSplitLayerCount - 1; newLayer >= 0; --newLayer)
{
int oldLayer = areLayersSplit ? newLayer : 0;
int oldIndex =
(oldAspectIndex * oldSplitLevelCount + oldLevel) * oldSplitLayerCount + oldLayer;
int newIndex =
(newAspectIndex * newSplitLevelCount + newLevel) * newSplitLayerCount + newLayer;
rangeRefs[newIndex] = rangeRefs[oldIndex];
}
}
}
areAspectsSplit = newSplitAspectCount > 1;
areLevelsSplit = newSplitLevelCount > 1;
areLayersSplit = newSplitLayerCount > 1;
}
VkResourceRecord::~VkResourceRecord()
{
VkResourceType resType = Resource != NULL ? IdentifyTypeByPtr(Resource) : eResUnknown;
+255 -1
View File
@@ -25,6 +25,7 @@
#pragma once
#include "common/wrapped_pool.h"
#include "core/bit_flag_iterator.h"
#include "core/intervals.h"
#include "core/resource_manager.h"
#include "vk_common.h"
@@ -1006,6 +1007,221 @@ struct AttachmentInfo
VkImageMemoryBarrier barrier;
};
struct ImageRange
{
ImageRange() {}
ImageRange(const VkImageSubresourceRange &range)
: aspectMask(range.aspectMask),
baseMipLevel(range.baseMipLevel),
levelCount(range.levelCount),
baseArrayLayer(range.baseArrayLayer),
layerCount(range.layerCount)
{
}
ImageRange(const VkImageSubresourceLayers &range)
: aspectMask(range.aspectMask),
baseMipLevel(range.mipLevel),
levelCount(1),
baseArrayLayer(range.baseArrayLayer),
layerCount(range.layerCount)
{
}
VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
uint32_t baseMipLevel = 0;
uint32_t levelCount = VK_REMAINING_MIP_LEVELS;
uint32_t baseArrayLayer = 0;
uint32_t layerCount = VK_REMAINING_ARRAY_LAYERS;
VkOffset3D offset = {0, 0, 0};
VkExtent3D extent = {~0u, ~0u, ~0u};
VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
};
typedef BitFlagIterator<VkImageAspectFlagBits, VkImageAspectFlags, int32_t> ImageAspectFlagIter;
struct ImgRefs
{
std::vector<FrameRefType> rangeRefs;
WrappedVkRes *initializedLiveRes;
VkImageType type;
VkImageAspectFlags aspectMask;
int levelCount;
int layerCount;
VkExtent3D extent;
bool areAspectsSplit = false;
bool areLevelsSplit = false;
bool areLayersSplit = false;
int GetAspectCount() const;
ImgRefs() : initializedLiveRes(NULL) {}
inline ImgRefs(VkImageType type, VkImageAspectFlags aspectMask, int levelCount, int layerCount,
VkExtent3D extent)
: rangeRefs(1, eFrameRef_None),
initializedLiveRes(NULL),
type(type),
aspectMask(aspectMask),
levelCount(levelCount),
layerCount(layerCount),
extent(extent)
{
if(type == VK_IMAGE_TYPE_3D)
// Depth slices of 3D views are treated as array layers
layerCount = extent.depth;
}
int SubresourceIndex(VkImageAspectFlagBits aspect, int level, int layer) const;
int SubresourceIndex(int aspectIndex, int level, int layer) const;
inline FrameRefType SubresourceRef(VkImageAspectFlagBits aspect, int level, int layer) const
{
return rangeRefs[SubresourceIndex(aspect, level, layer)];
}
inline FrameRefType SubresourceRef(int aspectIndex, int level, int layer) const
{
return rangeRefs[SubresourceIndex(aspectIndex, level, layer)];
}
void Split(bool splitAspects, bool splitLevels, bool splitLayers);
template <typename Compose>
FrameRefType Update(ImageRange range, FrameRefType refType, Compose comp);
inline FrameRefType Update(const ImageRange &range, FrameRefType refType)
{
return Update(range, refType, ComposeFrameRefs);
}
template <typename Compose>
FrameRefType Merge(const ImgRefs &other, Compose comp);
inline FrameRefType Merge(const ImgRefs &other) { return Merge(other, ComposeFrameRefs); }
};
template <typename Compose>
FrameRefType ImgRefs::Update(ImageRange range, FrameRefType refType, Compose comp)
{
range.extent.width = RDCMIN(range.extent.width, extent.width - range.offset.x);
range.extent.height = RDCMIN(range.extent.height, extent.height - range.offset.y);
if(type == VK_IMAGE_TYPE_3D && range.viewType != VK_IMAGE_VIEW_TYPE_2D &&
range.viewType != VK_IMAGE_VIEW_TYPE_2D_ARRAY)
{
// The Vulkan spec allows 2D `VkImageView`s of 3D `VkImage`s--the depth slices of the images are
// interpreted as array layers in the 2D view. Note that the spec does not allow 3D images to
// have array layers, so 3D images always have exactly 1 array layer when not accessed using a
// 2D view.
//
// `ImgRefs` treats the depth slices of 3D images as array layers (as if accessed through a 2D
// view). When a 3D image is accessed without a 2D view, we need to translate the Z axis into
// array layer indices.
range.extent.depth = RDCMIN(range.extent.depth, extent.depth - range.offset.z);
range.baseArrayLayer = range.offset.z;
range.layerCount = range.extent.depth;
}
else if(range.layerCount == VK_REMAINING_ARRAY_LAYERS)
{
range.layerCount = layerCount - range.baseArrayLayer;
}
if(range.levelCount == VK_REMAINING_MIP_LEVELS)
range.levelCount = levelCount - range.baseMipLevel;
if(refType == eFrameRef_CompleteWrite &&
(range.offset.x != 0 || range.offset.y != 0 || range.extent.width != extent.width ||
range.extent.height != extent.height))
// Complete write, but only to part of the image.
// We don't track writes at the pixel level, so turn this into a partial write
refType = eFrameRef_PartialWrite;
if(range.aspectMask != aspectMask)
{
if(range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
{
// For multi-planar images, the color aspect can be an alias for the plane aspects
range.aspectMask |=
(VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT) &
aspectMask;
}
range.aspectMask &= aspectMask;
}
Split(range.aspectMask != aspectMask,
range.baseMipLevel != 0 || (int)range.levelCount != levelCount,
range.baseArrayLayer != 0 || (int)range.layerCount != layerCount);
std::vector<VkImageAspectFlags> splitAspects;
if(areAspectsSplit)
{
for(auto aspectIt = ImageAspectFlagIter::begin(aspectMask);
aspectIt != ImageAspectFlagIter::end(); ++aspectIt)
{
splitAspects.push_back(*aspectIt);
}
}
else
{
splitAspects.push_back(aspectMask);
}
int splitLevelCount = 1;
int levelEnd = 1;
if(areLevelsSplit)
{
splitLevelCount = levelCount;
levelEnd = (int)(range.baseMipLevel + range.levelCount);
}
int splitLayerCount = 1;
int layerEnd = 1;
if(areLayersSplit)
{
splitLayerCount = layerCount;
layerEnd = (int)(range.baseArrayLayer + range.layerCount);
}
FrameRefType maxRefType = eFrameRef_None;
for(int aspectIndex = 0; aspectIndex < (int)splitAspects.size(); ++aspectIndex)
{
VkImageAspectFlags aspect = splitAspects[aspectIndex];
if((aspect & range.aspectMask) == 0)
continue;
for(int level = (int)range.baseMipLevel; level < levelEnd; ++level)
{
for(int layer = (int)range.baseArrayLayer; layer < layerEnd; ++layer)
{
int index = (aspectIndex * splitLevelCount + level) * splitLayerCount + layer;
rangeRefs[index] = comp(rangeRefs[index], refType);
maxRefType = RDCMAX(maxRefType, rangeRefs[index]);
}
}
}
return maxRefType;
}
template <typename Compose>
FrameRefType ImgRefs::Merge(const ImgRefs &other, Compose comp)
{
Split(other.areAspectsSplit, other.areLevelsSplit, other.areLayersSplit);
int splitAspectCount = 1;
if(areAspectsSplit)
splitAspectCount = GetAspectCount();
int splitLevelCount = areLevelsSplit ? levelCount : 1;
int splitLayerCount = areLayersSplit ? layerCount : 1;
FrameRefType maxRefType = eFrameRef_None;
for(int aspectIndex = 0; aspectIndex < splitAspectCount; ++aspectIndex)
{
for(int level = 0; level < splitLevelCount; ++level)
{
for(int layer = 0; layer < splitLayerCount; ++layer)
{
int index = SubresourceIndex(aspectIndex, level, layer);
rangeRefs[index] = comp(rangeRefs[index], other.SubresourceRef(aspectIndex, level, layer));
maxRefType = RDCMAX(maxRefType, rangeRefs[index]);
}
}
}
return maxRefType;
}
struct MemRefs
{
Intervals<FrameRefType> rangeRefs;
@@ -1054,6 +1270,20 @@ FrameRefType MemRefs::Merge(MemRefs &other, Compose comp)
return maxRefType;
}
struct ImageLayouts;
template <typename Compose>
FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, ResourceId img,
const ImageLayouts &layout, const ImageRange &range,
FrameRefType refType, Compose comp);
inline FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, ResourceId img,
const ImageLayouts &layout, const ImageRange &range,
FrameRefType refType)
{
return MarkImageReferenced(imgRefs, img, layout, range, refType, ComposeFrameRefs);
}
template <typename Compose>
FrameRefType MarkMemoryReferenced(std::map<ResourceId, MemRefs> &memRefs, ResourceId mem,
VkDeviceSize offset, VkDeviceSize size, FrameRefType refType,
@@ -1319,7 +1549,12 @@ public:
struct ImageLayouts
{
ImageLayouts() : layerCount(1), levelCount(1), sampleCount(1), format(VK_FORMAT_UNDEFINED)
ImageLayouts()
: layerCount(1),
levelCount(1),
sampleCount(1),
format(VK_FORMAT_UNDEFINED),
imageType(VK_IMAGE_TYPE_MAX_ENUM)
{
extent.width = extent.height = extent.depth = 1;
}
@@ -1360,3 +1595,22 @@ void GetYUVShaderParameters(VkFormat f, Vec4u &YUVDownsampleRate, Vec4u &YUVACha
uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip);
uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format,
uint32_t mip, uint32_t plane);
template <typename Compose>
FrameRefType MarkImageReferenced(std::map<ResourceId, ImgRefs> &imgRefs, ResourceId img,
const ImageLayouts &layout, const ImageRange &range,
FrameRefType refType, Compose comp)
{
if(refType == eFrameRef_None)
return refType;
auto refs = imgRefs.find(img);
if(refs == imgRefs.end())
{
refs =
imgRefs
.insert(std::make_pair(img, ImgRefs(layout.imageType, FormatImageAspects(layout.format),
layout.levelCount, layout.layerCount, layout.extent)))
.first;
}
return refs->second.Update(range, refType, comp);
}