Commit 85ddcc93 by Tim Van Patten Committed by Commit Bot

Vulkan: Convert ProgramExecutableVk::mDescriptorSets to std::array

Currently ProgramExecutableVk::mDescriptorSets is a vector, but it's size is bound so it can be a std::array (DescriptorSetLayoutArray). To ensure the size grows correctly in the future, the various descriptor set indexes are also being converted from independent constexpr uint32_ts into the enum DescriptorSetIndex. Bug: angleproject:4898 Test: CQ Change-Id: I7ae8ff3455bcfb61e24b73bd16cc3f8cf9873087 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2372664Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Tim Van Patten <timvp@google.com>
parent d787149a
......@@ -267,4 +267,13 @@ void writeFile(const char *path, const void *data, size_t size);
void ScheduleYield();
#endif
// Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter
// of the extraneous static_cast<>() calls.
// https://stackoverflow.com/a/8357462
template <typename E>
constexpr typename std::underlying_type<E>::type ToUnderlying(E e) noexcept
{
return static_cast<typename std::underlying_type<E>::type>(e);
}
#endif // COMMON_UTILITIES_H_
......@@ -3487,20 +3487,20 @@ angle::Result ContextVk::onPauseTransformFeedback()
return angle::Result::Continue;
}
void ContextVk::invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet)
void ContextVk::invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet)
{
// UtilsVk currently only uses set 0
ASSERT(usedDescriptorSet == kDriverUniformsDescriptorSetIndex);
ASSERT(usedDescriptorSet == DescriptorSetIndex::DriverUniforms);
if (mDriverUniforms[PipelineType::Graphics].descriptorSet != VK_NULL_HANDLE)
{
mGraphicsDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING);
}
}
void ContextVk::invalidateComputeDescriptorSet(uint32_t usedDescriptorSet)
void ContextVk::invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet)
{
// UtilsVk currently only uses set 0
ASSERT(usedDescriptorSet == kDriverUniformsDescriptorSetIndex);
ASSERT(usedDescriptorSet == DescriptorSetIndex::DriverUniforms);
if (mDriverUniforms[PipelineType::Compute].descriptorSet != VK_NULL_HANDLE)
{
mComputeDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING);
......@@ -3775,7 +3775,7 @@ void ContextVk::handleDirtyDriverUniformsBindingImpl(
const DriverUniformsDescriptorSet &driverUniforms)
{
commandBuffer->bindDescriptorSets(
mExecutable->getPipelineLayout(), bindPoint, kDriverUniformsDescriptorSetIndex, 1,
mExecutable->getPipelineLayout(), bindPoint, DescriptorSetIndex::DriverUniforms, 1,
&driverUniforms.descriptorSet, 1, &driverUniforms.dynamicOffset);
}
......
......@@ -370,8 +370,8 @@ class ContextVk : public ContextImpl, public vk::Context
// When UtilsVk issues draw or dispatch calls, it binds descriptor sets that the context is not
// aware of. This function is called to make sure affected descriptor set bindings are dirtied
// for the next application draw/dispatch call.
void invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet);
void invalidateComputeDescriptorSet(uint32_t usedDescriptorSet);
void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);
void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle);
......
......@@ -42,15 +42,16 @@ void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo(
GlslangProgramInterfaceInfo *glslangProgramInterfaceInfo)
{
glslangProgramInterfaceInfo->uniformsAndXfbDescriptorSetIndex =
kUniformsAndXfbDescriptorSetIndex;
ToUnderlying(DescriptorSetIndex::UniformsAndXfb);
glslangProgramInterfaceInfo->currentUniformBindingIndex = 0;
glslangProgramInterfaceInfo->textureDescriptorSetIndex = kTextureDescriptorSetIndex;
glslangProgramInterfaceInfo->textureDescriptorSetIndex =
ToUnderlying(DescriptorSetIndex::Texture);
glslangProgramInterfaceInfo->currentTextureBindingIndex = 0;
glslangProgramInterfaceInfo->shaderResourceDescriptorSetIndex =
kShaderResourceDescriptorSetIndex;
ToUnderlying(DescriptorSetIndex::ShaderResource);
glslangProgramInterfaceInfo->currentShaderResourceBindingIndex = 0;
glslangProgramInterfaceInfo->driverUniformsDescriptorSetIndex =
kDriverUniformsDescriptorSetIndex;
ToUnderlying(DescriptorSetIndex::DriverUniforms);
glslangProgramInterfaceInfo->locationsUsedForXfbExtension = 0;
}
......
......@@ -16,6 +16,7 @@
#include "libANGLE/InfoLog.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx
......@@ -176,9 +177,10 @@ class ProgramExecutableVk
const vk::UniformsAndXfbDesc &xfbBufferDesc,
bool *newDescriptorSetAllocated);
angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex);
angle::Result allocateDescriptorSet(ContextVk *contextVk,
DescriptorSetIndex descriptorSetIndex);
angle::Result allocateDescriptorSetAndGetInfo(ContextVk *contextVk,
uint32_t descriptorSetIndex,
DescriptorSetIndex descriptorSetIndex,
bool *newPoolAllocatedOut);
void addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> &blocks,
const gl::ShaderType shaderType,
......@@ -217,7 +219,7 @@ class ProgramExecutableVk
ContextVk *contextVk);
// Descriptor sets for uniform blocks and textures for this program.
std::vector<VkDescriptorSet> mDescriptorSets;
vk::DescriptorSetLayoutArray<VkDescriptorSet> mDescriptorSets;
vk::DescriptorSetLayoutArray<VkDescriptorSet> mEmptyDescriptorSets;
size_t mNumDefaultUniformDescriptors;
vk::BufferSerial mCurrentDefaultUniformBufferSerial;
......
......@@ -18,11 +18,14 @@
namespace rx
{
enum DescriptorSetIndex : uint32_t;
namespace vk
{
namespace priv
{
// NOTE: Please keep command-related enums, stucts, functions
// and other code dealing with commands in alphabetical order
// This simplifies searching and updating commands.
......@@ -468,7 +471,7 @@ class SecondaryCommandBuffer final : angle::NonCopyable
void bindDescriptorSets(const PipelineLayout &layout,
VkPipelineBindPoint pipelineBindPoint,
uint32_t firstSet,
DescriptorSetIndex firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount,
......@@ -846,7 +849,7 @@ ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pi
ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
VkPipelineBindPoint pipelineBindPoint,
uint32_t firstSet,
DescriptorSetIndex firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount,
......@@ -860,7 +863,7 @@ ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayou
// Copy params into memory
paramStruct->layout = layout.getHandle();
paramStruct->pipelineBindPoint = pipelineBindPoint;
paramStruct->firstSet = firstSet;
paramStruct->firstSet = ToUnderlying(firstSet);
paramStruct->descriptorSetCount = descriptorSetCount;
paramStruct->dynamicOffsetCount = dynamicOffsetCount;
// Copy variable sized data
......
......@@ -29,9 +29,6 @@ namespace GenerateMipmap_comp = vk::InternalShader::GenerateMipmap
namespace
{
// All internal shaders assume there is only one descriptor set, indexed at 0
constexpr uint32_t kSetIndex = 0;
constexpr uint32_t kConvertIndexDestinationBinding = 0;
constexpr uint32_t kConvertVertexDestinationBinding = 0;
constexpr uint32_t kConvertVertexSourceBinding = 1;
......@@ -423,8 +420,9 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk,
++currentBinding;
}
ANGLE_TRY(renderer->getDescriptorSetLayout(contextVk, descriptorSetDesc,
&mDescriptorSetLayouts[function][kSetIndex]));
ANGLE_TRY(renderer->getDescriptorSetLayout(
contextVk, descriptorSetDesc,
&mDescriptorSetLayouts[function][ToUnderlying(DescriptorSetIndex::InternalShader)]));
gl::ShaderType pushConstantsShaderStage =
isCompute ? gl::ShaderType::Compute : gl::ShaderType::Fragment;
......@@ -432,7 +430,8 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk,
// Corresponding pipeline layouts:
vk::PipelineLayoutDesc pipelineLayoutDesc;
pipelineLayoutDesc.updateDescriptorSetLayout(kSetIndex, descriptorSetDesc);
pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::InternalShader,
descriptorSetDesc);
if (pushConstantsSize)
{
pipelineLayoutDesc.updatePushConstantRange(pushConstantsShaderStage, 0,
......@@ -746,15 +745,16 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk,
if (descriptorSet != VK_NULL_HANDLE)
{
commandBuffer->bindDescriptorSets(pipelineLayout.get(), pipelineBindPoint, 0, 1,
&descriptorSet, 0, nullptr);
commandBuffer->bindDescriptorSets(pipelineLayout.get(), pipelineBindPoint,
DescriptorSetIndex::InternalShader, 1, &descriptorSet, 0,
nullptr);
if (isCompute)
{
contextVk->invalidateComputeDescriptorSet(0);
contextVk->invalidateComputeDescriptorSet(DescriptorSetIndex::InternalShader);
}
else
{
contextVk->invalidateGraphicsDescriptorSet(0);
contextVk->invalidateGraphicsDescriptorSet(DescriptorSetIndex::InternalShader);
}
}
......@@ -2119,8 +2119,11 @@ angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk,
VkDescriptorSet *descriptorSetOut)
{
ANGLE_TRY(mDescriptorPools[function].allocateSets(
contextVk, mDescriptorSetLayouts[function][kSetIndex].get().ptr(), 1, bindingOut,
descriptorSetOut));
contextVk,
mDescriptorSetLayouts[function][ToUnderlying(DescriptorSetIndex::InternalShader)]
.get()
.ptr(),
1, bindingOut, descriptorSetOut));
bindingOut->get().updateSerial(contextVk->getCurrentQueueSerial());
return angle::Result::Continue;
}
......
......@@ -1718,11 +1718,11 @@ bool PipelineLayoutDesc::operator==(const PipelineLayoutDesc &other) const
return memcmp(this, &other, sizeof(PipelineLayoutDesc)) == 0;
}
void PipelineLayoutDesc::updateDescriptorSetLayout(uint32_t setIndex,
void PipelineLayoutDesc::updateDescriptorSetLayout(DescriptorSetIndex setIndex,
const DescriptorSetLayoutDesc &desc)
{
ASSERT(setIndex < mDescriptorSetLayouts.size());
mDescriptorSetLayouts[setIndex] = desc;
ASSERT(ToUnderlying(setIndex) < mDescriptorSetLayouts.size());
mDescriptorSetLayouts[ToUnderlying(setIndex)] = desc;
}
void PipelineLayoutDesc::updatePushConstantRange(gl::ShaderType shaderType,
......
......@@ -18,6 +18,38 @@
namespace rx
{
// Some descriptor set and pipeline layout constants.
//
// The set/binding assignment is done as following:
//
// - Set 0 contains the ANGLE driver uniforms at binding 0. Note that driver uniforms are updated
// only under rare circumstances, such as viewport or depth range change. However, there is only
// one binding in this set. This set is placed before Set 1 containing transform feedback
// buffers, so that switching between xfb and non-xfb programs doesn't require rebinding this set.
// Otherwise, as the layout of Set 1 changes (due to addition and removal of xfb buffers), and all
// subsequent sets need to be rebound (due to Vulkan pipeline layout validation rules), we would
// have needed to invalidateGraphicsDriverUniforms().
// - Set 1 contains uniform blocks created to encompass default uniforms. 1 binding is used per
// pipeline stage. Additionally, transform feedback buffers are bound from binding 2 and up.
// - Set 2 contains all textures.
// - Set 3 contains all other shader resources, such as uniform and storage blocks, atomic counter
// buffers and images.
// ANGLE driver uniforms set index (binding is always 0):
enum DescriptorSetIndex : uint32_t
{
// All internal shaders assume there is only one descriptor set, indexed at 0
InternalShader = 0,
DriverUniforms = 0, // ANGLE driver uniforms set index
UniformsAndXfb, // Uniforms set index
Texture, // Textures set index
ShaderResource, // Other shader resources set index
InvalidEnum,
EnumCount = InvalidEnum,
};
namespace vk
{
class ImageHelper;
......@@ -611,7 +643,7 @@ struct PackedPushConstantRange
};
template <typename T>
using DescriptorSetLayoutArray = std::array<T, kMaxDescriptorSetLayouts>;
using DescriptorSetLayoutArray = std::array<T, static_cast<size_t>(DescriptorSetIndex::EnumCount)>;
using DescriptorSetLayoutPointerArray =
DescriptorSetLayoutArray<BindingPointer<DescriptorSetLayout>>;
template <typename T>
......@@ -628,7 +660,8 @@ class PipelineLayoutDesc final
size_t hash() const;
bool operator==(const PipelineLayoutDesc &other) const;
void updateDescriptorSetLayout(uint32_t setIndex, const DescriptorSetLayoutDesc &desc);
void updateDescriptorSetLayout(DescriptorSetIndex setIndex,
const DescriptorSetLayoutDesc &desc);
void updatePushConstantRange(gl::ShaderType shaderType, uint32_t offset, uint32_t size);
const PushConstantRangeArray<PackedPushConstantRange> &getPushConstantRanges() const;
......@@ -1230,32 +1263,6 @@ class SamplerYcbcrConversionCache final : angle::NonCopyable
std::unordered_map<uint64_t, vk::RefCountedSamplerYcbcrConversion> mPayload;
};
// Some descriptor set and pipeline layout constants.
//
// The set/binding assignment is done as following:
//
// - Set 0 contains the ANGLE driver uniforms at binding 0. Note that driver uniforms are updated
// only under rare circumstances, such as viewport or depth range change. However, there is only
// one binding in this set. This set is placed before Set 1 containing transform feedback
// buffers, so that switching between xfb and non-xfb programs doesn't require rebinding this set.
// Otherwise, as the layout of Set 1 changes (due to addition and removal of xfb buffers), and all
// subsequent sets need to be rebound (due to Vulkan pipeline layout validation rules), we would
// have needed to invalidateGraphicsDriverUniforms().
// - Set 1 contains uniform blocks created to encompass default uniforms. 1 binding is used per
// pipeline stage. Additionally, transform feedback buffers are bound from binding 2 and up.
// - Set 2 contains all textures.
// - Set 3 contains all other shader resources, such as uniform and storage blocks, atomic counter
// buffers and images.
// ANGLE driver uniforms set index (binding is always 0):
constexpr uint32_t kDriverUniformsDescriptorSetIndex = 0;
// Uniforms set index:
constexpr uint32_t kUniformsAndXfbDescriptorSetIndex = 1;
// Textures set index:
constexpr uint32_t kTextureDescriptorSetIndex = 2;
// Other shader resources set index:
constexpr uint32_t kShaderResourceDescriptorSetIndex = 3;
// Only 1 driver uniform binding is used.
constexpr uint32_t kReservedDriverUniformBindingCount = 1;
// There is 1 default uniform binding used per stage. Currently, a maxium of three stages are
......
......@@ -72,8 +72,8 @@ class VulkanUniformUpdatesTest : public ANGLETest
rx::ProgramVk *programVk = hackProgram(program);
// Force a small limit on the max sets per pool to more easily trigger a new allocation.
rx::vk::DynamicDescriptorPool *uniformPool =
programVk->getDynamicDescriptorPool(rx::kUniformsAndXfbDescriptorSetIndex);
rx::vk::DynamicDescriptorPool *uniformPool = programVk->getDynamicDescriptorPool(
ToUnderlying(rx::DescriptorSetIndex::UniformsAndXfb));
uniformPool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
rx::kReservedDefaultUniformBindingCount};
......@@ -86,7 +86,7 @@ class VulkanUniformUpdatesTest : public ANGLETest
textureCount = std::max(textureCount, 1u);
rx::vk::DynamicDescriptorPool *texturePool =
programVk->getDynamicDescriptorPool(rx::kTextureDescriptorSetIndex);
programVk->getDynamicDescriptorPool(ToUnderlying(rx::DescriptorSetIndex::Texture));
texturePool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
textureCount};
......
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