Commit 67980f13 by Charlie Lao Committed by Commit Bot

Vulkan: add Buffer/Texture/ImageViewSerial class

In a few places we need a unique ID to represent that object and use that to compute hash key. Right now we are using Serial for that purpose but it creates confusion with QueueSerial which we are using Serial to track GPU progress. This CL changes these usage of Serial to TextureSerial, SamplerSerial, ImageViewSerial type so that compiler can perform type checking. It also adds BufferSerial in preparation for next CL. Bug: b/159457348 Change-Id: I8e2da69c2029e4ddbcf163981ae46f85e19f751b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2287426 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent e0a2bd5e
......@@ -100,6 +100,46 @@ 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_
......@@ -13,6 +13,7 @@
#include "common/debug.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/Program.h"
#include "libANGLE/Semaphore.h"
#include "libANGLE/Surface.h"
......@@ -20,6 +21,7 @@
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FenceNVVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/MemoryObjectVk.h"
......@@ -630,7 +632,8 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mCurrentIndirectBuffer(nullptr),
mBufferInfos(),
mImageInfos(),
mWriteInfos()
mWriteInfos(),
mShareGroupVk(vk::GetImpl(state.getShareGroup()))
{
ANGLE_TRACE_EVENT0("gpu.angle", "ContextVk::ContextVk");
memset(&mClearColorValue, 0, sizeof(mClearColorValue));
......@@ -3769,11 +3772,11 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
TextureVk *textureVk = vk::GetImpl(texture);
SamplerVk *samplerVk;
Serial samplerSerial;
SamplerSerial samplerSerial;
if (sampler == nullptr)
{
samplerVk = nullptr;
samplerSerial = rx::kZeroSerial;
samplerSerial = rx::kInvalidSamplerSerial;
}
else
{
......@@ -4673,4 +4676,21 @@ ANGLE_INLINE ContextVk::ScopedDescriptorSetUpdates::~ScopedDescriptorSetUpdates(
mContextVk->mImageInfos.clear();
}
BufferSerial ContextVk::generateBufferSerial()
{
return mShareGroupVk->generateBufferSerial();
}
TextureSerial ContextVk::generateTextureSerial()
{
return mShareGroupVk->generateTextureSerial();
}
SamplerSerial ContextVk::generateSamplerSerial()
{
return mShareGroupVk->generateSamplerSerial();
}
ImageViewSerial ContextVk::generateAttachmentImageViewSerial()
{
return mShareGroupVk->generateImageViewSerial();
}
} // namespace rx
......@@ -31,6 +31,7 @@ namespace rx
class ProgramExecutableVk;
class RendererVk;
class WindowSurfaceVk;
class ShareGroupVk;
struct CommandBatch final : angle::NonCopyable
{
......@@ -462,16 +463,15 @@ class ContextVk : public ContextImpl, public vk::Context
vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc(
VkShaderStageFlags shaderStages) const;
// We use texture serials to optimize texture binding updates. Each permutation of a
// {VkImage/VkSampler} generates a unique serial. These serials are combined to form a unique
// We use textureSerial to optimize texture binding updates. Each permutation of a
// {VkImage/VkSampler} generates a unique serial. These object ids are combined to form a unique
// signature for each descriptor set. This allows us to keep a cache of descriptor sets and
// avoid calling vkAllocateDesctiporSets each texture update.
Serial generateTextureSerial() { return mTextureSerialFactory.generate(); }
const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; }
Serial generateAttachmentImageViewSerial()
{
return mAttachmentImageViewSerialFactory.generate();
}
ImageViewSerial generateAttachmentImageViewSerial();
BufferSerial generateBufferSerial();
TextureSerial generateTextureSerial();
SamplerSerial generateSamplerSerial();
angle::Result updateScissor(const gl::State &glState);
......@@ -1036,10 +1036,6 @@ class ContextVk : public ContextImpl, public vk::Context
uint32_t mPrimaryBufferCounter;
uint32_t mRenderPassCounter;
// Generators for texture & framebuffer serials.
SerialFactory mTextureSerialFactory;
SerialFactory mAttachmentImageViewSerialFactory;
gl::State::DirtyBits mPipelineDirtyBitsMask;
// List of all resources currently being used by this ContextVk's recorded commands.
......@@ -1063,6 +1059,8 @@ class ContextVk : public ContextImpl, public vk::Context
ContextVk *mContextVk;
};
ShareGroupVk *mShareGroupVk;
std::vector<std::string> mCommandBufferDiagnostics;
};
......
......@@ -20,7 +20,16 @@ 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;
};
class DisplayVk : public DisplayImpl, public vk::Context
......
......@@ -1336,7 +1336,7 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context,
}
else
{
mCurrentFramebufferDesc.update(colorIndexGL, kZeroSerial);
mCurrentFramebufferDesc.update(colorIndexGL, kInvalidImageViewSerial);
}
return angle::Result::Continue;
......@@ -1378,7 +1378,8 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
}
else
{
mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex, kZeroSerial);
mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex,
kInvalidImageViewSerial);
}
}
......
......@@ -58,13 +58,14 @@ void RenderTargetVk::reset()
mContentDefined = false;
}
Serial RenderTargetVk::getAssignImageViewSerial(ContextVk *contextVk)
ImageViewSerial RenderTargetVk::getAssignImageViewSerial(ContextVk *contextVk)
{
ASSERT(mImageViews);
ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
ASSERT(mLevelIndex < std::numeric_limits<uint16_t>::max());
Serial imageViewSerial = mImageViews->getAssignSerial(contextVk, mLevelIndex, mLayerIndex);
ImageViewSerial imageViewSerial =
mImageViews->getAssignSerial(contextVk, mLevelIndex, mLayerIndex);
ASSERT(imageViewSerial.getValue() < std::numeric_limits<uint32_t>::max());
return imageViewSerial;
}
......
......@@ -48,7 +48,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
uint32_t layerIndex);
void reset();
// This returns the serial from underlying ImageViewHelper, first assigning one if required
Serial getAssignImageViewSerial(ContextVk *contextVk);
ImageViewSerial getAssignImageViewSerial(ContextVk *contextVk);
// Note: RenderTargets should be called in order, with the depth/stencil onRender last.
angle::Result onColorDraw(ContextVk *contextVk);
......
......@@ -827,8 +827,8 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferCreateInfo.size = 16;
bufferCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
ANGLE_TRY(
mTheNullBuffer.init(displayVk, bufferCreateInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
ANGLE_TRY(mTheNullBuffer.init(displayVk, kInvalidBufferSerial, bufferCreateInfo,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
}
if (!mGlslangInitialized)
......
......@@ -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->generateTextureSerial();
mSerial = contextVk->generateSamplerSerial();
return angle::Result::Continue;
}
......
......@@ -32,12 +32,12 @@ class SamplerVk : public SamplerImpl
return mSampler.get();
}
Serial getSerial() const { return mSerial; }
SamplerSerial getSerial() const { return mSerial; }
private:
vk::BindingPointer<vk::Sampler> mSampler;
// The serial is used for cache indexing.
Serial mSerial;
SamplerSerial mSerial;
};
} // 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);
Serial getSerial() const { return mSerial; }
TextureSerial getSerial() const { return mSerial; }
void overrideStagingBufferSizeForTesting(size_t initialSizeForTesting)
{
......@@ -421,8 +421,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
// Level is first dimension, layer is second
std::vector<RenderTargetVector> mRenderTargets;
// The serial is used for cache indexing.
Serial mSerial;
// The unique object id is used for cache indexing.
TextureSerial mSerial;
// Overridden in some tests.
size_t mStagingBufferInitialSize;
......
......@@ -1648,7 +1648,9 @@ TextureDescriptorDesc::TextureDescriptorDesc(const TextureDescriptorDesc &other)
TextureDescriptorDesc &TextureDescriptorDesc::operator=(const TextureDescriptorDesc &other) =
default;
void TextureDescriptorDesc::update(size_t index, Serial textureSerial, Serial samplerSerial)
void TextureDescriptorDesc::update(size_t index,
TextureSerial textureSerial,
SamplerSerial samplerSerial)
{
if (index >= mMaxIndex)
{
......@@ -1696,7 +1698,7 @@ FramebufferDesc::~FramebufferDesc() = default;
FramebufferDesc::FramebufferDesc(const FramebufferDesc &other) = default;
FramebufferDesc &FramebufferDesc::operator=(const FramebufferDesc &other) = default;
void FramebufferDesc::update(uint32_t index, Serial serial)
void FramebufferDesc::update(uint32_t index, ImageViewSerial serial)
{
ASSERT(index < kMaxFramebufferAttachments);
mSerials[index] = serial;
......@@ -1704,23 +1706,25 @@ void FramebufferDesc::update(uint32_t index, Serial serial)
size_t FramebufferDesc::hash() const
{
return angle::ComputeGenericHash(&mSerials, sizeof(Serial) * kMaxFramebufferAttachments);
return angle::ComputeGenericHash(&mSerials,
sizeof(ImageViewSerial) * kMaxFramebufferAttachments);
}
void FramebufferDesc::reset()
{
memset(&mSerials, 0, sizeof(Serial) * kMaxFramebufferAttachments);
memset(&mSerials, 0, sizeof(ImageViewSerial) * kMaxFramebufferAttachments);
}
bool FramebufferDesc::operator==(const FramebufferDesc &other) const
{
return memcmp(&mSerials, &other.mSerials, sizeof(Serial) * kMaxFramebufferAttachments) == 0;
return memcmp(&mSerials, &other.mSerials,
sizeof(ImageViewSerial) * kMaxFramebufferAttachments) == 0;
}
uint32_t FramebufferDesc::attachmentCount() const
{
uint32_t count = 0;
for (const Serial &serial : mSerials)
for (const ImageViewSerial &serial : mSerials)
{
if (serial.valid())
{
......
......@@ -774,7 +774,7 @@ class TextureDescriptorDesc
TextureDescriptorDesc(const TextureDescriptorDesc &other);
TextureDescriptorDesc &operator=(const TextureDescriptorDesc &other);
void update(size_t index, Serial textureSerial, Serial samplerSerial);
void update(size_t index, TextureSerial textureSerial, SamplerSerial samplerSerial);
size_t hash() const;
void reset();
......@@ -808,7 +808,7 @@ class FramebufferDesc
FramebufferDesc(const FramebufferDesc &other);
FramebufferDesc &operator=(const FramebufferDesc &other);
void update(uint32_t index, Serial serial);
void update(uint32_t index, ImageViewSerial serial);
size_t hash() const;
void reset();
......@@ -817,7 +817,7 @@ class FramebufferDesc
uint32_t attachmentCount() const;
private:
gl::AttachmentArray<Serial> mSerials;
gl::AttachmentArray<ImageViewSerial> mSerials;
};
// Layer/level pair type used to index into Serial Cache in ImageViewHelper
......
......@@ -2183,18 +2183,21 @@ BufferHelper::BufferHelper()
mCurrentWriteAccess(0),
mCurrentReadAccess(0),
mCurrentWriteStages(0),
mCurrentReadStages(0)
mCurrentReadStages(0),
mSerial()
{}
BufferHelper::~BufferHelper() = default;
angle::Result BufferHelper::init(Context *context,
BufferSerial serial,
const VkBufferCreateInfo &requestedCreateInfo,
VkMemoryPropertyFlags memoryPropertyFlags)
{
RendererVk *renderer = context->getRenderer();
mSize = requestedCreateInfo.size;
mSerial = serial;
mSize = requestedCreateInfo.size;
VkBufferCreateInfo modifiedCreateInfo;
const VkBufferCreateInfo *createInfo = &requestedCreateInfo;
......@@ -2257,6 +2260,14 @@ angle::Result BufferHelper::init(Context *context,
return angle::Result::Continue;
}
angle::Result BufferHelper::init(ContextVk *contextVk,
const VkBufferCreateInfo &createInfo,
VkMemoryPropertyFlags memoryPropertyFlags)
{
BufferSerial serial = contextVk->generateBufferSerial();
return init(contextVk, serial, createInfo, memoryPropertyFlags);
}
angle::Result BufferHelper::initializeNonZeroMemory(Context *context, VkDeviceSize size)
{
// Staging buffer memory is non-zero-initialized in 'init'.
......@@ -5242,7 +5253,9 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
imageView, level, 1, layer, 1);
}
Serial ImageViewHelper::getAssignSerial(ContextVk *contextVk, uint32_t level, uint32_t layer)
ImageViewSerial ImageViewHelper::getAssignSerial(ContextVk *contextVk,
uint32_t level,
uint32_t layer)
{
LayerLevel layerLevelPair = {layer, level};
if (mSerialCache.find(layerLevelPair) == mSerialCache.end())
......
......@@ -697,13 +697,18 @@ class BufferHelper final : public Resource
BufferHelper();
~BufferHelper() override;
angle::Result init(ContextVk *contextVk,
const VkBufferCreateInfo &createInfo,
VkMemoryPropertyFlags memoryPropertyFlags);
angle::Result init(Context *context,
BufferSerial serial,
const VkBufferCreateInfo &createInfo,
VkMemoryPropertyFlags memoryPropertyFlags);
void destroy(RendererVk *renderer);
void release(RendererVk *renderer);
BufferSerial getBufferSerial() const { return mSerial; }
bool valid() const { return mBuffer.valid(); }
const Buffer &getBuffer() const { return mBuffer; }
VkDeviceSize getSize() const { return mSize; }
......@@ -830,6 +835,8 @@ class BufferHelper final : public Resource
VkFlags mCurrentReadAccess;
VkPipelineStageFlags mCurrentWriteStages;
VkPipelineStageFlags mCurrentReadStages;
BufferSerial mSerial;
};
// CommandBufferHelper (CBH) class wraps ANGLE's custom command buffer
......@@ -1652,7 +1659,7 @@ class ImageViewHelper : angle::NonCopyable
const ImageView **imageViewOut);
// Return unique Serial for this imageView, first assigning it if it hasn't yet been set
Serial getAssignSerial(ContextVk *contextVk, uint32_t level, uint32_t layer);
ImageViewSerial getAssignSerial(ContextVk *contextVk, uint32_t level, uint32_t layer);
private:
ImageView &getReadImageView()
......@@ -1687,7 +1694,7 @@ class ImageViewHelper : angle::NonCopyable
LayerLevelImageViewVector mLayerLevelDrawImageViews;
// Store Serials per layer/level of imageView
std::unordered_map<LayerLevel, Serial> mSerialCache;
std::unordered_map<LayerLevel, ImageViewSerial> mSerialCache;
};
// The SamplerHelper allows a Sampler to be coupled with a resource lifetime.
......
......@@ -46,6 +46,7 @@ namespace egl
{
class Display;
class Image;
class ShareGroup;
} // namespace egl
namespace gl
......@@ -67,12 +68,12 @@ ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_OBJECT)
namespace rx
{
class CommandGraphResource;
class DisplayVk;
class ImageVk;
class RenderTargetVk;
class RendererVk;
class RenderPassCache;
class ShareGroupVk;
} // namespace rx
namespace angle
......@@ -182,6 +183,12 @@ struct ImplTypeHelper<egl::Image>
using ImplType = ImageVk;
};
template <>
struct ImplTypeHelper<egl::ShareGroup>
{
using ImplType = ShareGroupVk;
};
template <typename T>
using GetImplType = typename ImplTypeHelper<T>::ImplType;
......
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