Commit adc250c3 by Jamie Madill Committed by Commit Bot

Vulkan: Refactor ImageViewHelper serials.

Instead of storing a dictionary of serials to specific image views we now store a single 32-bit serial combined with subresource info. The serials combined with a subresource info (level/layer) gives a unique identifier for each ImageView in the ImageViewHelper for the descriptor set cache and the Framebuffer cache. Also moves ImageView serial allocation to initialization and release. This means we no longer need to use "getAssign" methods and instead we use a few init methods to ensure the serials stay allocated. Bug: angleproject:4911 Change-Id: Ia6af76ae16b3ff5d4a83974bde05cc704064b079 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2333395 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent d1a96f42
...@@ -125,7 +125,7 @@ SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state, ...@@ -125,7 +125,7 @@ SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state,
} }
ASSERT(mRenderer); ASSERT(mRenderer);
return new OffscreenSurfaceVk(state); return new OffscreenSurfaceVk(state, mRenderer);
} }
SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state,
......
...@@ -1476,22 +1476,22 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context, ...@@ -1476,22 +1476,22 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context,
if (enabledColor) if (enabledColor)
{ {
mCurrentFramebufferDesc.updateColor(colorIndexGL, mCurrentFramebufferDesc.updateColor(colorIndexGL, renderTarget->getDrawSubresourceSerial());
renderTarget->getAssignImageViewSerial(contextVk));
} }
else else
{ {
mCurrentFramebufferDesc.updateColor(colorIndexGL, vk::kInvalidImageViewSerial); mCurrentFramebufferDesc.updateColor(colorIndexGL, vk::kInvalidImageViewSubresourceSerial);
} }
if (enabledResolve) if (enabledResolve)
{ {
mCurrentFramebufferDesc.updateColorResolve( mCurrentFramebufferDesc.updateColorResolve(colorIndexGL,
colorIndexGL, renderTarget->getAssignResolveImageViewSerial(contextVk)); renderTarget->getResolveSubresourceSerial());
} }
else else
{ {
mCurrentFramebufferDesc.updateColorResolve(colorIndexGL, vk::kInvalidImageViewSerial); mCurrentFramebufferDesc.updateColorResolve(colorIndexGL,
vk::kInvalidImageViewSubresourceSerial);
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -1528,12 +1528,11 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk) ...@@ -1528,12 +1528,11 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
if (depthStencilRT != nullptr) if (depthStencilRT != nullptr)
{ {
mCurrentFramebufferDesc.updateDepthStencil( mCurrentFramebufferDesc.updateDepthStencil(depthStencilRT->getDrawSubresourceSerial());
depthStencilRT->getAssignImageViewSerial(contextVk));
} }
else else
{ {
mCurrentFramebufferDesc.updateDepthStencil(vk::kInvalidImageViewSerial); mCurrentFramebufferDesc.updateDepthStencil(vk::kInvalidImageViewSubresourceSerial);
} }
} }
...@@ -1580,15 +1579,15 @@ angle::Result FramebufferVk::syncState(const gl::Context *context, ...@@ -1580,15 +1579,15 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
mCurrentFramebufferDesc.reset(); mCurrentFramebufferDesc.reset();
for (size_t colorIndexGL : mState.getEnabledDrawBuffers()) for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{ {
uint32_t colorIndex32 = static_cast<uint32_t>(colorIndexGL);
RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndexGL]; RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndexGL];
mCurrentFramebufferDesc.updateColor( mCurrentFramebufferDesc.updateColor(colorIndex32,
static_cast<uint32_t>(colorIndexGL), renderTarget->getDrawSubresourceSerial());
renderTarget->getAssignImageViewSerial(contextVk));
if (renderTarget->hasResolveAttachment()) if (renderTarget->hasResolveAttachment())
{ {
mCurrentFramebufferDesc.updateColorResolve( mCurrentFramebufferDesc.updateColorResolve(
static_cast<uint32_t>(colorIndexGL), colorIndex32, renderTarget->getResolveSubresourceSerial());
renderTarget->getAssignResolveImageViewSerial(contextVk));
} }
} }
updateDepthStencilAttachmentSerial(contextVk); updateDepthStencilAttachmentSerial(contextVk);
......
...@@ -69,27 +69,26 @@ void RenderTargetVk::reset() ...@@ -69,27 +69,26 @@ void RenderTargetVk::reset()
mContentDefined = false; mContentDefined = false;
} }
vk::ImageViewSerial RenderTargetVk::getAssignViewSerialImpl(ContextVk *contextVk, vk::ImageViewSubresourceSerial RenderTargetVk::getSubresourceSerialImpl(
vk::ImageViewHelper *imageViews) const vk::ImageViewHelper *imageViews) const
{ {
ASSERT(imageViews); ASSERT(imageViews);
ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max()); ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
ASSERT(mLevelIndexGL < std::numeric_limits<uint16_t>::max()); ASSERT(mLevelIndexGL < std::numeric_limits<uint16_t>::max());
vk::ImageViewSerial imageViewSerial = vk::ImageViewSubresourceSerial imageViewSerial =
imageViews->getAssignSerial(contextVk, mLevelIndexGL, mLayerIndex); imageViews->getSubresourceSerial(mLevelIndexGL, mLayerIndex);
ASSERT(imageViewSerial.getValue() < std::numeric_limits<uint32_t>::max());
return imageViewSerial; return imageViewSerial;
} }
vk::ImageViewSerial RenderTargetVk::getAssignImageViewSerial(ContextVk *contextVk) const vk::ImageViewSubresourceSerial RenderTargetVk::getDrawSubresourceSerial() const
{ {
return getAssignViewSerialImpl(contextVk, mImageViews); return getSubresourceSerialImpl(mImageViews);
} }
vk::ImageViewSerial RenderTargetVk::getAssignResolveImageViewSerial(ContextVk *contextVk) const vk::ImageViewSubresourceSerial RenderTargetVk::getResolveSubresourceSerial() const
{ {
return getAssignViewSerialImpl(contextVk, mResolveImageViews); return getSubresourceSerialImpl(mResolveImageViews);
} }
angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk) angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk)
......
...@@ -50,9 +50,9 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -50,9 +50,9 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
uint32_t layerIndex, uint32_t layerIndex,
bool isImageTransient); bool isImageTransient);
void reset(); void reset();
// This returns the serial from underlying ImageViewHelper, first assigning one if required
vk::ImageViewSerial getAssignImageViewSerial(ContextVk *contextVk) const; vk::ImageViewSubresourceSerial getDrawSubresourceSerial() const;
vk::ImageViewSerial getAssignResolveImageViewSerial(ContextVk *contextVk) const; vk::ImageViewSubresourceSerial getResolveSubresourceSerial() const;
// Note: RenderTargets should be called in order, with the depth/stencil onRender last. // Note: RenderTargets should be called in order, with the depth/stencil onRender last.
angle::Result onColorDraw(ContextVk *contextVk); angle::Result onColorDraw(ContextVk *contextVk);
...@@ -113,8 +113,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -113,8 +113,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
vk::ImageViewHelper *imageViews, vk::ImageViewHelper *imageViews,
const vk::ImageView **imageViewOut) const; const vk::ImageView **imageViewOut) const;
vk::ImageViewSerial getAssignViewSerialImpl(ContextVk *contextVk, vk::ImageViewSubresourceSerial getSubresourceSerialImpl(vk::ImageViewHelper *imageViews) const;
vk::ImageViewHelper *imageViews) const;
bool isResolveImageOwnerOfData() const; bool isResolveImageOwnerOfData() const;
......
...@@ -75,6 +75,7 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context, ...@@ -75,6 +75,7 @@ angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
mImage = new vk::ImageHelper(); mImage = new vk::ImageHelper();
mOwnsImage = true; mOwnsImage = true;
mImageObserverBinding.bind(mImage); mImageObserverBinding.bind(mImage);
mImageViews.init(renderer);
} }
const angle::Format &textureFormat = vkFormat.actualImageFormat(); const angle::Format &textureFormat = vkFormat.actualImageFormat();
...@@ -127,6 +128,7 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex ...@@ -127,6 +128,7 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
mImage = imageVk->getImage(); mImage = imageVk->getImage();
mOwnsImage = false; mOwnsImage = false;
mImageObserverBinding.bind(mImage); mImageObserverBinding.bind(mImage);
mImageViews.init(renderer);
const vk::Format &vkFormat = renderer->getFormat(image->getFormat().info->sizedInternalFormat); const vk::Format &vkFormat = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
const angle::Format &textureFormat = vkFormat.actualImageFormat(); const angle::Format &textureFormat = vkFormat.actualImageFormat();
......
...@@ -176,6 +176,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display ...@@ -176,6 +176,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(image.initMemory(displayVk, renderer->getMemoryProperties(), flags)); ANGLE_TRY(image.initMemory(displayVk, renderer->getMemoryProperties(), flags));
imageViews.init(renderer);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -216,6 +218,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initializeWithExternalMemory( ...@@ -216,6 +218,8 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initializeWithExternalMemory(
displayVk, renderer->getMemoryProperties(), externalMemoryRequirements, nullptr, displayVk, renderer->getMemoryProperties(), externalMemoryRequirements, nullptr,
&importMemoryHostPointerInfo, VK_QUEUE_FAMILY_EXTERNAL, flags)); &importMemoryHostPointerInfo, VK_QUEUE_FAMILY_EXTERNAL, flags));
imageViews.init(renderer);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -228,7 +232,7 @@ void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display) ...@@ -228,7 +232,7 @@ void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display)
imageViews.release(renderer); imageViews.release(renderer);
} }
OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState) OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, RendererVk *renderer)
: SurfaceVk(surfaceState), : SurfaceVk(surfaceState),
mWidth(mState.attributes.getAsInt(EGL_WIDTH, 0)), mWidth(mState.attributes.getAsInt(EGL_WIDTH, 0)),
mHeight(mState.attributes.getAsInt(EGL_HEIGHT, 0)), mHeight(mState.attributes.getAsInt(EGL_HEIGHT, 0)),
...@@ -547,6 +551,9 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk) ...@@ -547,6 +551,9 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk)
{ {
RendererVk *renderer = displayVk->getRenderer(); RendererVk *renderer = displayVk->getRenderer();
mColorImageMSViews.init(renderer);
mDepthStencilImageViews.init(renderer);
renderer->reloadVolkIfNeeded(); renderer->reloadVolkIfNeeded();
gl::Extents windowSize; gl::Extents windowSize;
...@@ -946,6 +953,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, ...@@ -946,6 +953,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
{ {
SwapchainImage &member = mSwapchainImages[imageIndex]; SwapchainImage &member = mSwapchainImages[imageIndex];
member.image.init2DWeakReference(context, swapchainImages[imageIndex], extents, format, 1); member.image.init2DWeakReference(context, swapchainImages[imageIndex], extents, format, 1);
member.imageViews.init(renderer);
} }
// Initialize depth/stencil if requested. // Initialize depth/stencil if requested.
......
...@@ -42,7 +42,7 @@ class SurfaceVk : public SurfaceImpl, public angle::ObserverInterface ...@@ -42,7 +42,7 @@ class SurfaceVk : public SurfaceImpl, public angle::ObserverInterface
class OffscreenSurfaceVk : public SurfaceVk class OffscreenSurfaceVk : public SurfaceVk
{ {
public: public:
OffscreenSurfaceVk(const egl::SurfaceState &surfaceState); OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, RendererVk *renderer);
~OffscreenSurfaceVk() override; ~OffscreenSurfaceVk() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
......
...@@ -1247,14 +1247,18 @@ void TextureVk::setImageHelper(ContextVk *contextVk, ...@@ -1247,14 +1247,18 @@ void TextureVk::setImageHelper(ContextVk *contextVk,
} }
mRenderTargets.clear(); mRenderTargets.clear();
RendererVk *renderer = contextVk->getRenderer();
updateSerial(contextVk); updateSerial(contextVk);
mImageViews.init(renderer);
} }
void TextureVk::updateImageHelper(ContextVk *contextVk, size_t imageCopyBufferAlignment) void TextureVk::updateImageHelper(ContextVk *contextVk, size_t imageCopyBufferAlignment)
{ {
RendererVk *renderer = contextVk->getRenderer();
ASSERT(mImage != nullptr); ASSERT(mImage != nullptr);
mImage->initStagingBuffer(contextVk->getRenderer(), imageCopyBufferAlignment, mImage->initStagingBuffer(renderer, imageCopyBufferAlignment, vk::kStagingBufferFlags,
vk::kStagingBufferFlags, mStagingBufferInitialSize); mStagingBufferInitialSize);
} }
angle::Result TextureVk::redefineLevel(const gl::Context *context, angle::Result TextureVk::redefineLevel(const gl::Context *context,
...@@ -1835,6 +1839,10 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context, ...@@ -1835,6 +1839,10 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
{ {
ASSERT(mState.getBaseLevelDesc().samples <= 1); ASSERT(mState.getBaseLevelDesc().samples <= 1);
// Ensure the view serial is valid.
RendererVk *renderer = contextVk->getRenderer();
mMultisampledImageViews.init(renderer);
// The image is used as either color or depth/stencil attachment. Additionally, its memory // The image is used as either color or depth/stencil attachment. Additionally, its memory
// is lazily allocated as the contents are discarded at the end of the renderpass and with // is lazily allocated as the contents are discarded at the end of the renderpass and with
// tiling GPUs no actual backing memory is required. // tiling GPUs no actual backing memory is required.
...@@ -1866,8 +1874,8 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context, ...@@ -1866,8 +1874,8 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
(hasLazilyAllocatedMemory ? VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT : 0); (hasLazilyAllocatedMemory ? VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT : 0);
ANGLE_TRY(mMultisampledImage.initMemory( ANGLE_TRY(mMultisampledImage.initMemory(contextVk, renderer->getMemoryProperties(),
contextVk, contextVk->getRenderer()->getMemoryProperties(), kMultisampledMemoryFlags)); kMultisampledMemoryFlags));
// Remove the emulated format clear from the multisampled image if any. There is one // Remove the emulated format clear from the multisampled image if any. There is one
// already staged on the resolve image if needed. // already staged on the resolve image if needed.
......
...@@ -43,7 +43,7 @@ SurfaceImpl *DisplayVkMac::createPbufferFromClientBuffer(const egl::SurfaceState ...@@ -43,7 +43,7 @@ SurfaceImpl *DisplayVkMac::createPbufferFromClientBuffer(const egl::SurfaceState
{ {
ASSERT(buftype == EGL_IOSURFACE_ANGLE); ASSERT(buftype == EGL_IOSURFACE_ANGLE);
return new IOSurfaceSurfaceVkMac(state, clientBuffer, attribs); return new IOSurfaceSurfaceVkMac(state, clientBuffer, attribs, mRenderer);
} }
egl::ConfigSet DisplayVkMac::generateConfigs() egl::ConfigSet DisplayVkMac::generateConfigs()
......
...@@ -28,7 +28,8 @@ class IOSurfaceSurfaceVkMac : public OffscreenSurfaceVk ...@@ -28,7 +28,8 @@ class IOSurfaceSurfaceVkMac : public OffscreenSurfaceVk
public: public:
IOSurfaceSurfaceVkMac(const egl::SurfaceState &state, IOSurfaceSurfaceVkMac(const egl::SurfaceState &state,
EGLClientBuffer buffer, EGLClientBuffer buffer,
const egl::AttributeMap &attribs); const egl::AttributeMap &attribs,
RendererVk *renderer);
~IOSurfaceSurfaceVkMac() override; ~IOSurfaceSurfaceVkMac() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
......
...@@ -63,8 +63,9 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type) ...@@ -63,8 +63,9 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
IOSurfaceSurfaceVkMac::IOSurfaceSurfaceVkMac(const egl::SurfaceState &state, IOSurfaceSurfaceVkMac::IOSurfaceSurfaceVkMac(const egl::SurfaceState &state,
EGLClientBuffer buffer, EGLClientBuffer buffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs,
: OffscreenSurfaceVk(state), mIOSurface(nullptr), mPlane(0), mFormatIndex(-1) RendererVk *renderer)
: OffscreenSurfaceVk(state, renderer), mIOSurface(nullptr), mPlane(0), mFormatIndex(-1)
{ {
// Keep reference to the IOSurface so it doesn't get deleted while the pbuffer exists. // Keep reference to the IOSurface so it doesn't get deleted while the pbuffer exists.
mIOSurface = reinterpret_cast<IOSurfaceRef>(buffer); mIOSurface = reinterpret_cast<IOSurfaceRef>(buffer);
......
...@@ -1800,59 +1800,59 @@ FramebufferDesc::~FramebufferDesc() = default; ...@@ -1800,59 +1800,59 @@ FramebufferDesc::~FramebufferDesc() = default;
FramebufferDesc::FramebufferDesc(const FramebufferDesc &other) = default; FramebufferDesc::FramebufferDesc(const FramebufferDesc &other) = default;
FramebufferDesc &FramebufferDesc::operator=(const FramebufferDesc &other) = default; FramebufferDesc &FramebufferDesc::operator=(const FramebufferDesc &other) = default;
void FramebufferDesc::update(uint32_t index, ImageViewSerial serial) void FramebufferDesc::update(uint32_t index, ImageViewSubresourceSerial serial)
{ {
ASSERT(index < kMaxFramebufferAttachments); ASSERT(index < kMaxFramebufferAttachments);
mSerials[index] = serial; mSerials[index] = serial;
if (serial.valid()) if (serial.imageViewSerial.valid())
{ {
mMaxValidSerialIndex = std::max(mMaxValidSerialIndex, index); mMaxIndex = std::max(mMaxIndex, index + 1);
} }
} }
void FramebufferDesc::updateColor(uint32_t index, ImageViewSerial serial) void FramebufferDesc::updateColor(uint32_t index, ImageViewSubresourceSerial serial)
{ {
update(kFramebufferDescColorIndexOffset + index, serial); update(kFramebufferDescColorIndexOffset + index, serial);
} }
void FramebufferDesc::updateColorResolve(uint32_t index, ImageViewSerial serial) void FramebufferDesc::updateColorResolve(uint32_t index, ImageViewSubresourceSerial serial)
{ {
update(kFramebufferDescResolveIndexOffset + index, serial); update(kFramebufferDescResolveIndexOffset + index, serial);
} }
void FramebufferDesc::updateDepthStencil(ImageViewSerial serial) void FramebufferDesc::updateDepthStencil(ImageViewSubresourceSerial serial)
{ {
update(kFramebufferDescDepthStencilIndex, serial); update(kFramebufferDescDepthStencilIndex, serial);
} }
size_t FramebufferDesc::hash() const size_t FramebufferDesc::hash() const
{ {
return angle::ComputeGenericHash(&mSerials, sizeof(mSerials[0]) * (mMaxValidSerialIndex + 1)); return angle::ComputeGenericHash(&mSerials, sizeof(mSerials[0]) * (mMaxIndex + 1));
} }
void FramebufferDesc::reset() void FramebufferDesc::reset()
{ {
mMaxIndex = 0;
memset(&mSerials, 0, sizeof(mSerials)); memset(&mSerials, 0, sizeof(mSerials));
mMaxValidSerialIndex = 0;
} }
bool FramebufferDesc::operator==(const FramebufferDesc &other) const bool FramebufferDesc::operator==(const FramebufferDesc &other) const
{ {
if (mMaxValidSerialIndex != other.mMaxValidSerialIndex) if (mMaxIndex != other.mMaxIndex)
{ {
return false; return false;
} }
return memcmp(&mSerials, &other.mSerials, sizeof(mSerials[0]) * (mMaxValidSerialIndex + 1)) == size_t validRegionSize = sizeof(mSerials[0]) * mMaxIndex;
0; return memcmp(&mSerials, &other.mSerials, validRegionSize) == 0;
} }
uint32_t FramebufferDesc::attachmentCount() const uint32_t FramebufferDesc::attachmentCount() const
{ {
uint32_t count = 0; uint32_t count = 0;
for (const ImageViewSerial &serial : mSerials) for (const ImageViewSubresourceSerial &serial : mSerials)
{ {
if (serial.valid()) if (serial.imageViewSerial.valid())
{ {
count++; count++;
} }
......
...@@ -787,6 +787,18 @@ class PipelineHelper final : angle::NonCopyable ...@@ -787,6 +787,18 @@ class PipelineHelper final : angle::NonCopyable
ANGLE_INLINE PipelineHelper::PipelineHelper(Pipeline &&pipeline) : mPipeline(std::move(pipeline)) {} ANGLE_INLINE PipelineHelper::PipelineHelper(Pipeline &&pipeline) : mPipeline(std::move(pipeline)) {}
struct ImageViewSubresourceSerial
{
ImageViewSerial imageViewSerial;
uint16_t level;
uint16_t layer;
};
static_assert(sizeof(ImageViewSubresourceSerial) == sizeof(uint64_t), "Size mismatch");
constexpr ImageViewSubresourceSerial kInvalidImageViewSubresourceSerial = {kInvalidImageViewSerial,
0, 0};
class TextureDescriptorDesc class TextureDescriptorDesc
{ {
public: public:
...@@ -867,9 +879,9 @@ class FramebufferDesc ...@@ -867,9 +879,9 @@ class FramebufferDesc
FramebufferDesc(const FramebufferDesc &other); FramebufferDesc(const FramebufferDesc &other);
FramebufferDesc &operator=(const FramebufferDesc &other); FramebufferDesc &operator=(const FramebufferDesc &other);
void updateColor(uint32_t index, ImageViewSerial serial); void updateColor(uint32_t index, ImageViewSubresourceSerial serial);
void updateColorResolve(uint32_t index, ImageViewSerial serial); void updateColorResolve(uint32_t index, ImageViewSubresourceSerial serial);
void updateDepthStencil(ImageViewSerial serial); void updateDepthStencil(ImageViewSubresourceSerial serial);
size_t hash() const; size_t hash() const;
void reset(); void reset();
...@@ -878,22 +890,11 @@ class FramebufferDesc ...@@ -878,22 +890,11 @@ class FramebufferDesc
uint32_t attachmentCount() const; uint32_t attachmentCount() const;
private: private:
void update(uint32_t index, ImageViewSerial serial); void update(uint32_t index, ImageViewSubresourceSerial serial);
FramebufferAttachmentArray<ImageViewSerial> mSerials;
uint32_t mMaxValidSerialIndex;
};
// Layer/level pair type used to index into Serial Cache in ImageViewHelper
struct LayerLevel
{
uint32_t layer;
uint32_t level;
bool operator==(const LayerLevel &other) const // Note: this is an exclusive index. If there is one index it will be "1".
{ uint32_t mMaxIndex;
return layer == other.layer && level == other.level; FramebufferAttachmentArray<ImageViewSubresourceSerial> mSerials;
}
}; };
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
...@@ -955,20 +956,6 @@ struct hash<rx::vk::SamplerDesc> ...@@ -955,20 +956,6 @@ struct hash<rx::vk::SamplerDesc>
size_t operator()(const rx::vk::SamplerDesc &key) const { return key.hash(); } size_t operator()(const rx::vk::SamplerDesc &key) const { return key.hash(); }
}; };
template <>
struct hash<rx::vk::LayerLevel>
{
size_t operator()(const rx::vk::LayerLevel &layerLevel) const
{
// The left-shift by 11 was found to produce unique hash values
// in a [0..1000][0..2048] space for layer/level
// Make sure that layer/level hash bits don't overlap or overflow
ASSERT((layerLevel.layer & 0x000007FF) == layerLevel.layer);
ASSERT((layerLevel.level & 0xFFE00000) == 0);
return layerLevel.layer | (layerLevel.level << 11);
}
};
// See Resource Serial types defined in vk_utils.h. // See Resource Serial types defined in vk_utils.h.
#define ANGLE_HASH_VK_SERIAL(Type) \ #define ANGLE_HASH_VK_SERIAL(Type) \
template <> \ template <> \
......
...@@ -5004,7 +5004,7 @@ ImageViewHelper::ImageViewHelper(ImageViewHelper &&other) ...@@ -5004,7 +5004,7 @@ ImageViewHelper::ImageViewHelper(ImageViewHelper &&other)
std::swap(mPerLevelStencilReadImageViews, other.mPerLevelStencilReadImageViews); std::swap(mPerLevelStencilReadImageViews, other.mPerLevelStencilReadImageViews);
std::swap(mLevelDrawImageViews, other.mLevelDrawImageViews); std::swap(mLevelDrawImageViews, other.mLevelDrawImageViews);
std::swap(mLayerLevelDrawImageViews, other.mLayerLevelDrawImageViews); std::swap(mLayerLevelDrawImageViews, other.mLayerLevelDrawImageViews);
std::swap(mSerialCache, other.mSerialCache); std::swap(mImageViewSerial, other.mImageViewSerial);
} }
ImageViewHelper::~ImageViewHelper() ImageViewHelper::~ImageViewHelper()
...@@ -5012,6 +5012,14 @@ ImageViewHelper::~ImageViewHelper() ...@@ -5012,6 +5012,14 @@ ImageViewHelper::~ImageViewHelper()
mUse.release(); mUse.release();
} }
void ImageViewHelper::init(RendererVk *renderer)
{
if (!mImageViewSerial.valid())
{
mImageViewSerial = renderer->getResourceSerialFactory().generateImageViewSerial();
}
}
void ImageViewHelper::release(RendererVk *renderer) void ImageViewHelper::release(RendererVk *renderer)
{ {
std::vector<GarbageObject> garbage; std::vector<GarbageObject> garbage;
...@@ -5049,7 +5057,8 @@ void ImageViewHelper::release(RendererVk *renderer) ...@@ -5049,7 +5057,8 @@ void ImageViewHelper::release(RendererVk *renderer)
mUse.init(); mUse.init();
} }
mSerialCache.clear(); // Update image view serial.
mImageViewSerial = renderer->getResourceSerialFactory().generateImageViewSerial();
} }
void ImageViewHelper::destroy(VkDevice device) void ImageViewHelper::destroy(VkDevice device)
...@@ -5076,7 +5085,7 @@ void ImageViewHelper::destroy(VkDevice device) ...@@ -5076,7 +5085,7 @@ void ImageViewHelper::destroy(VkDevice device)
} }
mLayerLevelDrawImageViews.clear(); mLayerLevelDrawImageViews.clear();
mSerialCache.clear(); mImageViewSerial = vk::kInvalidImageViewSerial;
} }
angle::Result ImageViewHelper::initReadViews(ContextVk *contextVk, angle::Result ImageViewHelper::initReadViews(ContextVk *contextVk,
...@@ -5105,19 +5114,21 @@ angle::Result ImageViewHelper::initReadViews(ContextVk *contextVk, ...@@ -5105,19 +5114,21 @@ angle::Result ImageViewHelper::initReadViews(ContextVk *contextVk,
} }
mCurrentMaxLevel = levelCount - 1; mCurrentMaxLevel = levelCount - 1;
// Determine if we already have ImageView's for the new max level // Determine if we already have ImageViews for the new max level
if (getReadImageView().getHandle() == VK_NULL_HANDLE) if (getReadImageView().valid())
{ {
// Since we don't have a readImageView, we must create ImageView's for the new max level return angle::Result::Continue;
ANGLE_TRY(initReadViewsImpl(contextVk, viewType, image, format, formatSwizzle, readSwizzle, }
baseLevel, levelCount, baseLayer, layerCount));
if (requiresSRGBViews) // Since we don't have a readImageView, we must create ImageViews for the new max level
{ ANGLE_TRY(initReadViewsImpl(contextVk, viewType, image, format, formatSwizzle, readSwizzle,
ANGLE_TRY(initSRGBReadViewsImpl(contextVk, viewType, image, format, formatSwizzle, baseLevel, levelCount, baseLayer, layerCount));
readSwizzle, baseLevel, levelCount, baseLayer,
layerCount, imageUsageFlags)); if (requiresSRGBViews)
} {
ANGLE_TRY(initSRGBReadViewsImpl(contextVk, viewType, image, format, formatSwizzle,
readSwizzle, baseLevel, levelCount, baseLayer, layerCount,
imageUsageFlags));
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -5134,6 +5145,8 @@ angle::Result ImageViewHelper::initReadViewsImpl(ContextVk *contextVk, ...@@ -5134,6 +5145,8 @@ angle::Result ImageViewHelper::initReadViewsImpl(ContextVk *contextVk,
uint32_t baseLayer, uint32_t baseLayer,
uint32_t layerCount) uint32_t layerCount)
{ {
ASSERT(mImageViewSerial.valid());
const VkImageAspectFlags aspectFlags = GetFormatAspectFlags(format.intendedFormat()); const VkImageAspectFlags aspectFlags = GetFormatAspectFlags(format.intendedFormat());
mLinearColorspace = IsLinearFormat(format.vkImageFormat); mLinearColorspace = IsLinearFormat(format.vkImageFormat);
...@@ -5262,6 +5275,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk, ...@@ -5262,6 +5275,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
VkFormat vkImageFormat, VkFormat vkImageFormat,
const ImageView **imageViewOut) const ImageView **imageViewOut)
{ {
ASSERT(mImageViewSerial.valid());
retain(&contextVk->getResourceUseList()); retain(&contextVk->getResourceUseList());
ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, levelVK, image.getLevelCount()); ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, levelVK, image.getLevelCount());
...@@ -5285,6 +5300,7 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk, ...@@ -5285,6 +5300,7 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
const ImageView **imageViewOut) const ImageView **imageViewOut)
{ {
ASSERT(image.valid()); ASSERT(image.valid());
ASSERT(mImageViewSerial.valid());
ASSERT(!image.getFormat().actualImageFormat().isBlock); ASSERT(!image.getFormat().actualImageFormat().isBlock);
retain(&contextVk->getResourceUseList()); retain(&contextVk->getResourceUseList());
...@@ -5315,17 +5331,15 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk, ...@@ -5315,17 +5331,15 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
imageView, levelVK, 1, layer, 1); imageView, levelVK, 1, layer, 1);
} }
ImageViewSerial ImageViewHelper::getAssignSerial(ContextVk *contextVk, ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial(uint32_t levelGL, uint32_t layer)
uint32_t levelGL,
uint32_t layer)
{ {
LayerLevel layerLevelPair = {layer, levelGL}; ASSERT(mImageViewSerial.valid());
if (mSerialCache.find(layerLevelPair) == mSerialCache.end())
{ ImageViewSubresourceSerial serial;
vk::ResourceSerialFactory &factory = contextVk->getRenderer()->getResourceSerialFactory(); serial.imageViewSerial = mImageViewSerial;
mSerialCache[layerLevelPair] = factory.generateImageViewSerial(); SetBitField(serial.level, levelGL);
} SetBitField(serial.layer, layer);
return mSerialCache[layerLevelPair]; return serial;
} }
// SamplerHelper implementation. // SamplerHelper implementation.
......
...@@ -1595,6 +1595,7 @@ class ImageViewHelper : angle::NonCopyable ...@@ -1595,6 +1595,7 @@ class ImageViewHelper : angle::NonCopyable
ImageViewHelper(ImageViewHelper &&other); ImageViewHelper(ImageViewHelper &&other);
~ImageViewHelper(); ~ImageViewHelper();
void init(RendererVk *renderer);
void release(RendererVk *renderer); void release(RendererVk *renderer);
void destroy(VkDevice device); void destroy(VkDevice device);
...@@ -1715,8 +1716,8 @@ class ImageViewHelper : angle::NonCopyable ...@@ -1715,8 +1716,8 @@ class ImageViewHelper : angle::NonCopyable
uint32_t layer, uint32_t layer,
const ImageView **imageViewOut); const ImageView **imageViewOut);
// Return unique Serial for this imageView, first assigning it if it hasn't yet been set // Return unique Serial for an imageView.
ImageViewSerial getAssignSerial(ContextVk *contextVk, uint32_t levelGL, uint32_t layer); ImageViewSubresourceSerial getSubresourceSerial(uint32_t levelGL, uint32_t layer);
private: private:
ImageView &getReadImageView() ImageView &getReadImageView()
...@@ -1805,8 +1806,8 @@ class ImageViewHelper : angle::NonCopyable ...@@ -1805,8 +1806,8 @@ class ImageViewHelper : angle::NonCopyable
ImageViewVector mLevelDrawImageViews; ImageViewVector mLevelDrawImageViews;
LayerLevelImageViewVector mLayerLevelDrawImageViews; LayerLevelImageViewVector mLayerLevelDrawImageViews;
// Store Serials per layer/level of imageView // Serial for the image view set. getSubresourceSerial combines it with subresource info.
std::unordered_map<LayerLevel, ImageViewSerial> mSerialCache; ImageViewSerial mImageViewSerial;
}; };
// The SamplerHelper allows a Sampler to be coupled with a resource lifetime. // The SamplerHelper allows a Sampler to be coupled with a resource lifetime.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment