Commit 2919dc6e by Courtney Goeltzenleuchter Committed by Commit Bot

Add immutable samplers to descriptor set layout

To support YUV conversion we need to track the use of immutable samplers in the descriptor set layout. Bug: b/155487768 Change-Id: Ic7dc6a08551f5125c4a519b5cfada312f95ab914 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2225423 Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com>
parent f56ba018
...@@ -4078,7 +4078,7 @@ vk::DescriptorSetLayoutDesc ContextVk::getDriverUniformsDescriptorSetDesc( ...@@ -4078,7 +4078,7 @@ vk::DescriptorSetLayoutDesc ContextVk::getDriverUniformsDescriptorSetDesc(
VkShaderStageFlags shaderStages) const VkShaderStageFlags shaderStages) const
{ {
vk::DescriptorSetLayoutDesc desc; vk::DescriptorSetLayoutDesc desc;
desc.update(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, shaderStages); desc.update(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, shaderStages, nullptr);
return desc; return desc;
} }
......
...@@ -393,7 +393,8 @@ void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc( ...@@ -393,7 +393,8 @@ void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc(
const std::string blockName = block.mappedName; const std::string blockName = block.mappedName;
const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName];
descOut->update(info.binding, descType, arraySize, gl_vk::kShaderStageMap[shaderType]); descOut->update(info.binding, descType, arraySize, gl_vk::kShaderStageMap[shaderType],
nullptr);
} }
} }
...@@ -418,7 +419,7 @@ void ProgramExecutableVk::addAtomicCounterBufferDescriptorSetDesc( ...@@ -418,7 +419,7 @@ void ProgramExecutableVk::addAtomicCounterBufferDescriptorSetDesc(
// A single storage buffer array is used for all stages for simplicity. // A single storage buffer array is used for all stages for simplicity.
descOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS,
gl_vk::kShaderStageMap[shaderType]); gl_vk::kShaderStageMap[shaderType], nullptr);
} }
void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable &executable, void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable &executable,
...@@ -447,8 +448,8 @@ void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable ...@@ -447,8 +448,8 @@ void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable
GetImageNameWithoutIndices(&name); GetImageNameWithoutIndices(&name);
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][name]; ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][name];
VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType]; VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType];
descOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, arraySize, descOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, arraySize, activeStages,
activeStages); nullptr);
} }
} }
} }
...@@ -501,7 +502,7 @@ void ProgramExecutableVk::addTextureDescriptorSetDesc(const gl::ProgramState &pr ...@@ -501,7 +502,7 @@ void ProgramExecutableVk::addTextureDescriptorSetDesc(const gl::ProgramState &pr
VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType]; VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType];
descOut->update(info.binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize, descOut->update(info.binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, arraySize,
activeStages); activeStages, nullptr);
} }
} }
} }
...@@ -645,7 +646,7 @@ angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glCon ...@@ -645,7 +646,7 @@ angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glCon
} }
uniformsAndXfbSetDesc.update(info.binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, uniformsAndXfbSetDesc.update(info.binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1,
gl_vk::kShaderStageMap[shaderType]); gl_vk::kShaderStageMap[shaderType], nullptr);
mNumDefaultUniformDescriptors++; mNumDefaultUniformDescriptors++;
} }
bool hasVertexShader = glExecutable.hasLinkedShaderStage(gl::ShaderType::Vertex); bool hasVertexShader = glExecutable.hasLinkedShaderStage(gl::ShaderType::Vertex);
......
...@@ -450,6 +450,8 @@ RendererVk::RendererVk() ...@@ -450,6 +450,8 @@ RendererVk::RendererVk()
RendererVk::~RendererVk() RendererVk::~RendererVk()
{ {
mAllocator.release();
mPipelineCache.release();
ASSERT(mSharedGarbage.empty()); ASSERT(mSharedGarbage.empty());
} }
......
...@@ -181,7 +181,7 @@ void TransformFeedbackVk::updateDescriptorSetLayout( ...@@ -181,7 +181,7 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
const ShaderInterfaceVariableInfo &info = vsVariableInfoMap[bufferName]; const ShaderInterfaceVariableInfo &info = vsVariableInfoMap[bufferName];
descSetLayoutOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, descSetLayoutOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
VK_SHADER_STAGE_VERTEX_BIT); VK_SHADER_STAGE_VERTEX_BIT, nullptr);
} }
} }
......
...@@ -384,7 +384,7 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk, ...@@ -384,7 +384,7 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk,
for (size_t i = 0; i < setSizesCount; ++i) for (size_t i = 0; i < setSizesCount; ++i)
{ {
descriptorSetDesc.update(currentBinding, setSizes[i].type, setSizes[i].descriptorCount, descriptorSetDesc.update(currentBinding, setSizes[i].type, setSizes[i].descriptorCount,
descStages); descStages, nullptr);
currentBinding += setSizes[i].descriptorCount; currentBinding += setSizes[i].descriptorCount;
} }
......
...@@ -1513,7 +1513,8 @@ bool DescriptorSetLayoutDesc::operator==(const DescriptorSetLayoutDesc &other) c ...@@ -1513,7 +1513,8 @@ bool DescriptorSetLayoutDesc::operator==(const DescriptorSetLayoutDesc &other) c
void DescriptorSetLayoutDesc::update(uint32_t bindingIndex, void DescriptorSetLayoutDesc::update(uint32_t bindingIndex,
VkDescriptorType type, VkDescriptorType type,
uint32_t count, uint32_t count,
VkShaderStageFlags stages) VkShaderStageFlags stages,
const vk::Sampler *immutableSampler)
{ {
ASSERT(static_cast<size_t>(type) < std::numeric_limits<uint16_t>::max()); ASSERT(static_cast<size_t>(type) < std::numeric_limits<uint16_t>::max());
ASSERT(count < std::numeric_limits<uint16_t>::max()); ASSERT(count < std::numeric_limits<uint16_t>::max());
...@@ -1523,9 +1524,18 @@ void DescriptorSetLayoutDesc::update(uint32_t bindingIndex, ...@@ -1523,9 +1524,18 @@ void DescriptorSetLayoutDesc::update(uint32_t bindingIndex,
SetBitField(packedBinding.type, type); SetBitField(packedBinding.type, type);
SetBitField(packedBinding.count, count); SetBitField(packedBinding.count, count);
SetBitField(packedBinding.stages, stages); SetBitField(packedBinding.stages, stages);
packedBinding.immutableSampler = VK_NULL_HANDLE;
packedBinding.pad = 0;
if (immutableSampler)
{
ASSERT(count == 1);
packedBinding.immutableSampler = immutableSampler->getHandle();
}
} }
void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *bindings) const void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *bindings,
std::vector<VkSampler> *immutableSamplers) const
{ {
for (uint32_t bindingIndex = 0; bindingIndex < kMaxDescriptorSetLayoutBindings; ++bindingIndex) for (uint32_t bindingIndex = 0; bindingIndex < kMaxDescriptorSetLayoutBindings; ++bindingIndex)
{ {
...@@ -1537,11 +1547,29 @@ void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *b ...@@ -1537,11 +1547,29 @@ void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *b
binding.binding = bindingIndex; binding.binding = bindingIndex;
binding.descriptorCount = packedBinding.count; binding.descriptorCount = packedBinding.count;
binding.descriptorType = static_cast<VkDescriptorType>(packedBinding.type); binding.descriptorType = static_cast<VkDescriptorType>(packedBinding.type);
binding.stageFlags = static_cast<VkShaderStageFlags>(packedBinding.stages); binding.stageFlags = static_cast<VkShaderStageFlags>(packedBinding.stages);
binding.pImmutableSamplers = nullptr; if (packedBinding.immutableSampler != VK_NULL_HANDLE)
{
ASSERT(packedBinding.count == 1);
immutableSamplers->push_back(packedBinding.immutableSampler);
binding.pImmutableSamplers = reinterpret_cast<const VkSampler *>(angle::DirtyPointer);
}
bindings->push_back(binding); bindings->push_back(binding);
} }
if (!immutableSamplers->empty())
{
// Patch up pImmutableSampler addresses now that the vector is stable
int immutableIndex = 0;
for (VkDescriptorSetLayoutBinding &binding : *bindings)
{
if (binding.pImmutableSamplers)
{
binding.pImmutableSamplers = &(*immutableSamplers)[immutableIndex];
immutableIndex++;
}
}
}
} }
// PipelineLayoutDesc implementation. // PipelineLayoutDesc implementation.
...@@ -2033,14 +2061,15 @@ angle::Result DescriptorSetLayoutCache::getDescriptorSetLayout( ...@@ -2033,14 +2061,15 @@ angle::Result DescriptorSetLayoutCache::getDescriptorSetLayout(
} }
// We must unpack the descriptor set layout description. // We must unpack the descriptor set layout description.
vk::DescriptorSetLayoutBindingVector bindings; vk::DescriptorSetLayoutBindingVector bindingVector;
desc.unpackBindings(&bindings); std::vector<VkSampler> immutableSamplers;
desc.unpackBindings(&bindingVector, &immutableSamplers);
VkDescriptorSetLayoutCreateInfo createInfo = {}; VkDescriptorSetLayoutCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.bindingCount = static_cast<uint32_t>(bindings.size()); createInfo.bindingCount = static_cast<uint32_t>(bindingVector.size());
createInfo.pBindings = bindings.data(); createInfo.pBindings = bindingVector.data();
vk::DescriptorSetLayout newLayout; vk::DescriptorSetLayout newLayout;
ANGLE_VK_TRY(context, newLayout.init(context->getDevice(), createInfo)); ANGLE_VK_TRY(context, newLayout.init(context->getDevice(), createInfo));
......
...@@ -525,19 +525,27 @@ class DescriptorSetLayoutDesc final ...@@ -525,19 +525,27 @@ class DescriptorSetLayoutDesc final
void update(uint32_t bindingIndex, void update(uint32_t bindingIndex,
VkDescriptorType type, VkDescriptorType type,
uint32_t count, uint32_t count,
VkShaderStageFlags stages); VkShaderStageFlags stages,
const vk::Sampler *immutableSampler);
void unpackBindings(DescriptorSetLayoutBindingVector *bindings) const; void unpackBindings(DescriptorSetLayoutBindingVector *bindings,
std::vector<VkSampler> *immutableSamplers) const;
private: private:
// There is a small risk of an issue if the sampler cache is evicted but not the descriptor
// cache we would have an invalid handle here. Thus propose follow-up work:
// TODO: https://issuetracker.google.com/issues/159156775: Have immutable sampler use serial
struct PackedDescriptorSetBinding struct PackedDescriptorSetBinding
{ {
uint8_t type; // Stores a packed VkDescriptorType descriptorType. uint8_t type; // Stores a packed VkDescriptorType descriptorType.
uint8_t stages; // Stores a packed VkShaderStageFlags. uint8_t stages; // Stores a packed VkShaderStageFlags.
uint16_t count; // Stores a packed uint32_t descriptorCount. uint16_t count; // Stores a packed uint32_t descriptorCount.
uint32_t pad;
VkSampler immutableSampler;
}; };
static_assert(sizeof(PackedDescriptorSetBinding) == sizeof(uint32_t), "Unexpected size"); // 4x 32bit
static_assert(sizeof(PackedDescriptorSetBinding) == 16, "Unexpected size");
// This is a compact representation of a descriptor set layout. // This is a compact representation of a descriptor set layout.
std::array<PackedDescriptorSetBinding, kMaxDescriptorSetLayoutBindings> std::array<PackedDescriptorSetBinding, kMaxDescriptorSetLayoutBindings>
......
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