Commit 22e6fc03 by Jamie Madill Committed by Commit Bot

Vulkan: Move Resource Serial gen into Renderer.

Putting Serial allocation in the Renderer allows the Helper classes to manage allocating its own Serial. The init functions for ImageViewHelper only have access to a vk::Context/RendererVk, not a ContextVk. This will be updated in a future CL. Re-uses the Serial Type X-Macro to do more code generation. Serial allocation now uses an atomic because of its now Renderer shared location. Bug: angleproject:4911 Change-Id: I2d5d3d0bbf613d5468de795a700f66164291bc79 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2332884 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCharlie Lao <cclao@google.com>
parent 1780609d
......@@ -101,45 +101,6 @@ class SerialFactoryBase final : angle::NonCopyable
using SerialFactory = SerialFactoryBase<uint64_t>;
using AtomicSerialFactory = SerialFactoryBase<std::atomic<uint64_t>>;
// Clang Format doesn't like the following X macro.
// clang-format off
#define OBJECT_SERIAL_TYPES_OP(X) \
X(Buffer) \
X(Texture) \
X(Sampler) \
X(ImageView)
// clang-format on
#define DEFINE_UNIQUE_OBJECT_SERIAL_TYPE(Type) \
class Type##Serial \
{ \
public: \
constexpr Type##Serial() : mSerial(kInvalid) {} \
Type##Serial(uint32_t serial) : mSerial(serial) {} \
\
constexpr bool operator==(const Type##Serial &other) const \
{ \
ASSERT(mSerial != kInvalid); \
ASSERT(other.mSerial != kInvalid); \
return mSerial == other.mSerial; \
} \
constexpr bool operator!=(const Type##Serial &other) const \
{ \
ASSERT(mSerial != kInvalid); \
ASSERT(other.mSerial != kInvalid); \
return mSerial != other.mSerial; \
} \
constexpr uint32_t getValue() const { return mSerial; } \
constexpr bool valid() const { return mSerial != kInvalid; } \
\
private: \
uint32_t mSerial; \
static constexpr uint32_t kInvalid = 0; \
}; \
static constexpr Type##Serial kInvalid##Type##Serial = Type##Serial();
OBJECT_SERIAL_TYPES_OP(DEFINE_UNIQUE_OBJECT_SERIAL_TYPE)
} // namespace rx
#endif // LIBANGLE_RENDERER_SERIAL_UTILS_H_
......@@ -1529,7 +1529,7 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersEmulation(
vk::BufferHelper *uniformBuffer = mDefaultUniformStorage.getCurrentBuffer();
vk::UniformsAndXfbDesc xfbBufferDesc = transformFeedbackVk->getTransformFeedbackDesc();
xfbBufferDesc.updateDefaultUniformBuffer(uniformBuffer ? uniformBuffer->getBufferSerial()
: kInvalidBufferSerial);
: vk::kInvalidBufferSerial);
return mProgram->getExecutable().updateTransformFeedbackDescriptorSet(
mProgram->getState(), mProgram->getDefaultUniformBlocks(), uniformBuffer, this,
xfbBufferDesc);
......@@ -3768,7 +3768,7 @@ angle::Result ContextVk::updateDriverUniformsDescriptorSet(
}
const vk::BufferHelper *buffer = driverUniforms->dynamicBuffer.getCurrentBuffer();
BufferSerial bufferSerial = buffer->getBufferSerial();
vk::BufferSerial bufferSerial = buffer->getBufferSerial();
// Look up in the cache first
auto iter = driverUniforms->descriptorSetCache.find(bufferSerial);
if (iter != driverUniforms->descriptorSetCache.end())
......@@ -3858,16 +3858,16 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
TextureVk *textureVk = vk::GetImpl(texture);
SamplerVk *samplerVk;
SamplerSerial samplerSerial;
vk::SamplerSerial samplerSerial;
if (sampler == nullptr)
{
samplerVk = nullptr;
samplerSerial = rx::kInvalidSamplerSerial;
samplerSerial = vk::kInvalidSamplerSerial;
}
else
{
samplerVk = vk::GetImpl(sampler);
samplerSerial = samplerVk->getSerial();
samplerSerial = samplerVk->getSamplerSerial();
}
if (textureVk->getImage().hasImmutableSampler())
......@@ -4748,23 +4748,6 @@ VkWriteDescriptorSet *ContextVk::allocWriteDescriptorSets(size_t count)
return &mWriteDescriptorSets[oldSize];
}
BufferSerial ContextVk::generateBufferSerial()
{
return mShareGroupVk->generateBufferSerial();
}
TextureSerial ContextVk::generateTextureSerial()
{
return mShareGroupVk->generateTextureSerial();
}
SamplerSerial ContextVk::generateSamplerSerial()
{
return mShareGroupVk->generateSamplerSerial();
}
ImageViewSerial ContextVk::generateAttachmentImageViewSerial()
{
return mShareGroupVk->generateImageViewSerial();
}
void ContextVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
{
mDefaultUniformStorage.setMinimumSizeForTesting(minSize);
......
......@@ -468,10 +468,6 @@ class ContextVk : public ContextImpl, public vk::Context
// signature for each descriptor set. This allows us to keep a cache of descriptor sets and
// avoid calling vkAllocateDesctiporSets each texture update.
const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; }
ImageViewSerial generateAttachmentImageViewSerial();
BufferSerial generateBufferSerial();
TextureSerial generateTextureSerial();
SamplerSerial generateSamplerSerial();
angle::Result updateScissor(const gl::State &glState);
......@@ -626,7 +622,7 @@ class ContextVk : public ContextImpl, public vk::Context
uint32_t dynamicOffset;
vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
std::unordered_map<BufferSerial, VkDescriptorSet> descriptorSetCache;
std::unordered_map<vk::BufferSerial, VkDescriptorSet> descriptorSetCache;
DriverUniformsDescriptorSet();
~DriverUniformsDescriptorSet();
......
......@@ -21,15 +21,7 @@ class RendererVk;
class ShareGroupVk : public ShareGroupImpl
{
public:
ShareGroupVk() : mCurrentUniqueSerial(1) {}
BufferSerial generateBufferSerial() { return ++mCurrentUniqueSerial; }
TextureSerial generateTextureSerial() { return ++mCurrentUniqueSerial; }
SamplerSerial generateSamplerSerial() { return ++mCurrentUniqueSerial; }
ImageViewSerial generateImageViewSerial() { return ++mCurrentUniqueSerial; }
private:
uint32_t mCurrentUniqueSerial;
ShareGroupVk() {}
};
class DisplayVk : public DisplayImpl, public vk::Context
......
......@@ -1443,7 +1443,7 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context,
}
else
{
mCurrentFramebufferDesc.updateColor(colorIndexGL, kInvalidImageViewSerial);
mCurrentFramebufferDesc.updateColor(colorIndexGL, vk::kInvalidImageViewSerial);
}
if (enabledResolve)
......@@ -1453,7 +1453,7 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context,
}
else
{
mCurrentFramebufferDesc.updateColorResolve(colorIndexGL, kInvalidImageViewSerial);
mCurrentFramebufferDesc.updateColorResolve(colorIndexGL, vk::kInvalidImageViewSerial);
}
return angle::Result::Continue;
......@@ -1495,7 +1495,7 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
}
else
{
mCurrentFramebufferDesc.updateDepthStencil(kInvalidImageViewSerial);
mCurrentFramebufferDesc.updateDepthStencil(vk::kInvalidImageViewSerial);
}
}
......
......@@ -189,8 +189,10 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
mTextureDescriptorsCache.clear();
mUniformsAndXfbDescriptorSetCache.clear();
// Initialize with a unique BufferSerial
mCurrentDefaultUniformBufferSerial = contextVk->generateBufferSerial();
vk::ResourceSerialFactory &factory = contextVk->getRenderer()->getResourceSerialFactory();
mCurrentDefaultUniformBufferSerial = factory.generateBufferSerial();
for (ProgramInfo &programInfo : mGraphicsProgramInfos)
{
......
......@@ -123,7 +123,7 @@ class ProgramExecutableVk
return mGraphicsProgramInfos[optionBits.to_ulong()];
}
ProgramInfo &getComputeProgramInfo() { return mComputeProgramInfo; }
BufferSerial getCurrentDefaultUniformBufferSerial() const
vk::BufferSerial getCurrentDefaultUniformBufferSerial() const
{
return mCurrentDefaultUniformBufferSerial;
}
......@@ -220,7 +220,7 @@ class ProgramExecutableVk
std::vector<VkDescriptorSet> mDescriptorSets;
vk::DescriptorSetLayoutArray<VkDescriptorSet> mEmptyDescriptorSets;
size_t mNumDefaultUniformDescriptors;
BufferSerial mCurrentDefaultUniformBufferSerial;
vk::BufferSerial mCurrentDefaultUniformBufferSerial;
std::unordered_map<vk::UniformsAndXfbDesc, VkDescriptorSet> mUniformsAndXfbDescriptorSetCache;
std::unordered_map<vk::TextureDescriptorDesc, VkDescriptorSet> mTextureDescriptorsCache;
......
......@@ -69,25 +69,25 @@ void RenderTargetVk::reset()
mContentDefined = false;
}
ImageViewSerial RenderTargetVk::getAssignViewSerialImpl(ContextVk *contextVk,
vk::ImageViewHelper *imageViews) const
vk::ImageViewSerial RenderTargetVk::getAssignViewSerialImpl(ContextVk *contextVk,
vk::ImageViewHelper *imageViews) const
{
ASSERT(imageViews);
ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
ASSERT(mLevelIndexGL < std::numeric_limits<uint16_t>::max());
ImageViewSerial imageViewSerial =
vk::ImageViewSerial imageViewSerial =
imageViews->getAssignSerial(contextVk, mLevelIndexGL, mLayerIndex);
ASSERT(imageViewSerial.getValue() < std::numeric_limits<uint32_t>::max());
return imageViewSerial;
}
ImageViewSerial RenderTargetVk::getAssignImageViewSerial(ContextVk *contextVk) const
vk::ImageViewSerial RenderTargetVk::getAssignImageViewSerial(ContextVk *contextVk) const
{
return getAssignViewSerialImpl(contextVk, mImageViews);
}
ImageViewSerial RenderTargetVk::getAssignResolveImageViewSerial(ContextVk *contextVk) const
vk::ImageViewSerial RenderTargetVk::getAssignResolveImageViewSerial(ContextVk *contextVk) const
{
return getAssignViewSerialImpl(contextVk, mResolveImageViews);
}
......
......@@ -51,8 +51,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
bool isImageTransient);
void reset();
// This returns the serial from underlying ImageViewHelper, first assigning one if required
ImageViewSerial getAssignImageViewSerial(ContextVk *contextVk) const;
ImageViewSerial getAssignResolveImageViewSerial(ContextVk *contextVk) const;
vk::ImageViewSerial getAssignImageViewSerial(ContextVk *contextVk) const;
vk::ImageViewSerial getAssignResolveImageViewSerial(ContextVk *contextVk) const;
// Note: RenderTargets should be called in order, with the depth/stencil onRender last.
angle::Result onColorDraw(ContextVk *contextVk);
......@@ -113,8 +113,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
vk::ImageViewHelper *imageViews,
const vk::ImageView **imageViewOut) const;
ImageViewSerial getAssignViewSerialImpl(ContextVk *contextVk,
vk::ImageViewHelper *imageViews) const;
vk::ImageViewSerial getAssignViewSerialImpl(ContextVk *contextVk,
vk::ImageViewHelper *imageViews) const;
bool isResolveImageOwnerOfData() const;
......
......@@ -260,6 +260,8 @@ class RendererVk : angle::NonCopyable
bool getEnableValidationLayers() const { return mEnableValidationLayers; }
vk::ResourceSerialFactory &getResourceSerialFactory() { return mResourceSerialFactory; }
private:
angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex);
void ensureCapsInitialized() const;
......@@ -387,6 +389,9 @@ class RendererVk : angle::NonCopyable
SamplerCache mSamplerCache;
SamplerYcbcrConversionCache mYuvConversionCache;
vk::ActiveHandleCounter mActiveHandleCounts;
// Tracks resource serials.
vk::ResourceSerialFactory mResourceSerialFactory;
};
} // namespace rx
......
......@@ -16,7 +16,7 @@
namespace rx
{
SamplerVk::SamplerVk(const gl::SamplerState &state) : SamplerImpl(state), mSerial{} {}
SamplerVk::SamplerVk(const gl::SamplerState &state) : SamplerImpl(state) {}
SamplerVk::~SamplerVk() = default;
......@@ -43,7 +43,7 @@ angle::Result SamplerVk::syncState(const gl::Context *context, const bool dirty)
ANGLE_TRY(renderer->getSamplerCache().getSampler(contextVk, desc, &mSampler));
// Regenerate the serial on a sampler change.
mSerial = contextVk->generateSamplerSerial();
mSamplerSerial = renderer->getResourceSerialFactory().generateSamplerSerial();
return angle::Result::Continue;
}
......
......@@ -32,12 +32,12 @@ class SamplerVk : public SamplerImpl
return mSampler.get();
}
SamplerSerial getSerial() const { return mSerial; }
vk::SamplerSerial getSamplerSerial() const { return mSamplerSerial; }
private:
vk::BindingPointer<vk::Sampler> mSampler;
// The serial is used for cache indexing.
SamplerSerial mSerial;
vk::SamplerSerial mSamplerSerial;
};
} // namespace rx
......
......@@ -1247,7 +1247,7 @@ void TextureVk::setImageHelper(ContextVk *contextVk,
}
mRenderTargets.clear();
mSerial = contextVk->generateTextureSerial();
updateSerial(contextVk);
}
void TextureVk::updateImageHelper(ContextVk *contextVk, size_t imageCopyBufferAlignment)
......@@ -1695,8 +1695,7 @@ angle::Result TextureVk::updateBaseMaxLevels(ContextVk *contextVk,
// Track the levels in our ImageHelper
mImage->setBaseAndMaxLevels(baseLevel, maxLevel);
// Update the texture's serial so that the descriptor set is updated correctly
mSerial = contextVk->generateTextureSerial();
updateSerial(contextVk);
// Update the current max level in ImageViewHelper
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
......@@ -2155,8 +2154,7 @@ angle::Result TextureVk::syncState(const gl::Context *context,
mImage->getExternalFormat());
ANGLE_TRY(renderer->getSamplerCache().getSampler(contextVk, samplerDesc, &mSampler));
// Regenerate the serial on a sampler change.
mSerial = contextVk->generateTextureSerial();
updateSerial(contextVk);
return angle::Result::Continue;
}
......@@ -2295,7 +2293,7 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
ANGLE_TRY(initImageViews(contextVk, format, sized, levelCount, layerCount));
mSerial = contextVk->generateTextureSerial();
updateSerial(contextVk);
return angle::Result::Continue;
}
......@@ -2515,4 +2513,10 @@ void TextureVk::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMe
// Forward the notification to the parent that the staging buffer changed.
onStateChange(angle::SubjectMessage::SubjectChanged);
}
void TextureVk::updateSerial(ContextVk *contextVk)
{
vk::ResourceSerialFactory &factory = contextVk->getRenderer()->getResourceSerialFactory();
mSerial = factory.generateTextureSerial();
}
} // namespace rx
......@@ -191,7 +191,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
// Normally, initialize the image with enabled mipmap level counts.
angle::Result ensureImageInitialized(ContextVk *contextVk, ImageMipLevels mipLevels);
TextureSerial getSerial() const { return mSerial; }
vk::TextureSerial getSerial() const { return mSerial; }
void overrideStagingBufferSizeForTesting(size_t initialSizeForTesting)
{
......@@ -397,6 +397,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
return (mImage->valid()) ? mImage->getTilingMode() : VK_IMAGE_TILING_OPTIMAL;
}
void updateSerial(ContextVk *contextVk);
bool mOwnsImage;
bool mRequiresSRGBViews;
......@@ -434,7 +436,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
std::vector<RenderTargetVector> mRenderTargets;
// The unique object id is used for cache indexing.
TextureSerial mSerial;
vk::TextureSerial mSerial;
// Overridden in some tests.
size_t mStagingBufferInitialSize;
......
......@@ -969,11 +969,16 @@ struct hash<rx::vk::LayerLevel>
}
};
template <>
struct hash<rx::BufferSerial>
{
size_t operator()(const rx::BufferSerial &key) const { return key.getValue(); }
};
// See Resource Serial types defined in vk_utils.h.
#define ANGLE_HASH_VK_SERIAL(Type) \
template <> \
struct hash<rx::vk::Type##Serial> \
{ \
size_t operator()(const rx::vk::Type##Serial &key) const { return key.getValue(); } \
};
ANGLE_VK_SERIAL_OP(ANGLE_HASH_VK_SERIAL)
} // namespace std
namespace rx
......
......@@ -2249,7 +2249,7 @@ angle::Result BufferHelper::init(ContextVk *contextVk,
{
RendererVk *renderer = contextVk->getRenderer();
mSerial = contextVk->generateBufferSerial();
mSerial = renderer->getResourceSerialFactory().generateBufferSerial();
mSize = requestedCreateInfo.size;
VkBufferCreateInfo modifiedCreateInfo;
......@@ -5322,7 +5322,8 @@ ImageViewSerial ImageViewHelper::getAssignSerial(ContextVk *contextVk,
LayerLevel layerLevelPair = {layer, levelGL};
if (mSerialCache.find(layerLevelPair) == mSerialCache.end())
{
mSerialCache[layerLevelPair] = contextVk->generateAttachmentImageViewSerial();
vk::ResourceSerialFactory &factory = contextVk->getRenderer()->getResourceSerialFactory();
mSerialCache[layerLevelPair] = factory.generateImageViewSerial();
}
return mSerialCache[layerLevelPair];
}
......
......@@ -751,6 +751,26 @@ void ClearValuesArray::store(uint32_t index,
mEnabled.set(index);
}
}
// ResourceSerialFactory implementation.
ResourceSerialFactory::ResourceSerialFactory() : mCurrentUniqueSerial(1) {}
ResourceSerialFactory::~ResourceSerialFactory() {}
uint32_t ResourceSerialFactory::issueSerial()
{
ASSERT(mCurrentUniqueSerial + 1 > mCurrentUniqueSerial);
return mCurrentUniqueSerial++;
}
#define ANGLE_DEFINE_GEN_VK_SERIAL(Type) \
Type##Serial ResourceSerialFactory::generate##Type##Serial() \
{ \
return Type##Serial(issueSerial()); \
}
ANGLE_VK_SERIAL_OP(ANGLE_DEFINE_GEN_VK_SERIAL)
} // namespace vk
#if !defined(ANGLE_SHARED_LIBVULKAN)
......
......@@ -691,6 +691,60 @@ class ClearValuesArray final
gl::AttachmentArray<VkClearValue> mValues;
gl::AttachmentsMask mEnabled;
};
// Defines Serials for Vulkan objects.
#define ANGLE_VK_SERIAL_OP(X) \
X(Buffer) \
X(ImageView) \
X(Sampler) \
X(Texture)
#define ANGLE_DEFINE_VK_SERIAL_TYPE(Type) \
class Type##Serial \
{ \
public: \
constexpr Type##Serial() : mSerial(kInvalid) {} \
constexpr explicit Type##Serial(uint32_t serial) : mSerial(serial) {} \
\
constexpr bool operator==(const Type##Serial &other) const \
{ \
ASSERT(mSerial != kInvalid); \
ASSERT(other.mSerial != kInvalid); \
return mSerial == other.mSerial; \
} \
constexpr bool operator!=(const Type##Serial &other) const \
{ \
ASSERT(mSerial != kInvalid); \
ASSERT(other.mSerial != kInvalid); \
return mSerial != other.mSerial; \
} \
constexpr uint32_t getValue() const { return mSerial; } \
constexpr bool valid() const { return mSerial != kInvalid; } \
\
private: \
uint32_t mSerial; \
static constexpr uint32_t kInvalid = 0; \
}; \
static constexpr Type##Serial kInvalid##Type##Serial = Type##Serial();
ANGLE_VK_SERIAL_OP(ANGLE_DEFINE_VK_SERIAL_TYPE)
#define ANGLE_DECLARE_GEN_VK_SERIAL(Type) Type##Serial generate##Type##Serial();
class ResourceSerialFactory final : angle::NonCopyable
{
public:
ResourceSerialFactory();
~ResourceSerialFactory();
ANGLE_VK_SERIAL_OP(ANGLE_DECLARE_GEN_VK_SERIAL)
private:
uint32_t issueSerial();
// Kept atomic so it can be accessed from multiple Context threads at once.
std::atomic<uint32_t> mCurrentUniqueSerial;
};
} // namespace vk
#if !defined(ANGLE_SHARED_LIBVULKAN)
......
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