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); ...@@ -267,4 +267,13 @@ void writeFile(const char *path, const void *data, size_t size);
void ScheduleYield(); void ScheduleYield();
#endif #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_ #endif // COMMON_UTILITIES_H_
...@@ -3487,20 +3487,20 @@ angle::Result ContextVk::onPauseTransformFeedback() ...@@ -3487,20 +3487,20 @@ angle::Result ContextVk::onPauseTransformFeedback()
return angle::Result::Continue; return angle::Result::Continue;
} }
void ContextVk::invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet) void ContextVk::invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet)
{ {
// UtilsVk currently only uses set 0 // UtilsVk currently only uses set 0
ASSERT(usedDescriptorSet == kDriverUniformsDescriptorSetIndex); ASSERT(usedDescriptorSet == DescriptorSetIndex::DriverUniforms);
if (mDriverUniforms[PipelineType::Graphics].descriptorSet != VK_NULL_HANDLE) if (mDriverUniforms[PipelineType::Graphics].descriptorSet != VK_NULL_HANDLE)
{ {
mGraphicsDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING); mGraphicsDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING);
} }
} }
void ContextVk::invalidateComputeDescriptorSet(uint32_t usedDescriptorSet) void ContextVk::invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet)
{ {
// UtilsVk currently only uses set 0 // UtilsVk currently only uses set 0
ASSERT(usedDescriptorSet == kDriverUniformsDescriptorSetIndex); ASSERT(usedDescriptorSet == DescriptorSetIndex::DriverUniforms);
if (mDriverUniforms[PipelineType::Compute].descriptorSet != VK_NULL_HANDLE) if (mDriverUniforms[PipelineType::Compute].descriptorSet != VK_NULL_HANDLE)
{ {
mComputeDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING); mComputeDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING);
...@@ -3775,7 +3775,7 @@ void ContextVk::handleDirtyDriverUniformsBindingImpl( ...@@ -3775,7 +3775,7 @@ void ContextVk::handleDirtyDriverUniformsBindingImpl(
const DriverUniformsDescriptorSet &driverUniforms) const DriverUniformsDescriptorSet &driverUniforms)
{ {
commandBuffer->bindDescriptorSets( commandBuffer->bindDescriptorSets(
mExecutable->getPipelineLayout(), bindPoint, kDriverUniformsDescriptorSetIndex, 1, mExecutable->getPipelineLayout(), bindPoint, DescriptorSetIndex::DriverUniforms, 1,
&driverUniforms.descriptorSet, 1, &driverUniforms.dynamicOffset); &driverUniforms.descriptorSet, 1, &driverUniforms.dynamicOffset);
} }
......
...@@ -370,8 +370,8 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -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 // 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 // aware of. This function is called to make sure affected descriptor set bindings are dirtied
// for the next application draw/dispatch call. // for the next application draw/dispatch call.
void invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet); void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
void invalidateComputeDescriptorSet(uint32_t usedDescriptorSet); void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);
void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle); void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle);
......
...@@ -42,15 +42,16 @@ void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo( ...@@ -42,15 +42,16 @@ void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo(
GlslangProgramInterfaceInfo *glslangProgramInterfaceInfo) GlslangProgramInterfaceInfo *glslangProgramInterfaceInfo)
{ {
glslangProgramInterfaceInfo->uniformsAndXfbDescriptorSetIndex = glslangProgramInterfaceInfo->uniformsAndXfbDescriptorSetIndex =
kUniformsAndXfbDescriptorSetIndex; ToUnderlying(DescriptorSetIndex::UniformsAndXfb);
glslangProgramInterfaceInfo->currentUniformBindingIndex = 0; glslangProgramInterfaceInfo->currentUniformBindingIndex = 0;
glslangProgramInterfaceInfo->textureDescriptorSetIndex = kTextureDescriptorSetIndex; glslangProgramInterfaceInfo->textureDescriptorSetIndex =
ToUnderlying(DescriptorSetIndex::Texture);
glslangProgramInterfaceInfo->currentTextureBindingIndex = 0; glslangProgramInterfaceInfo->currentTextureBindingIndex = 0;
glslangProgramInterfaceInfo->shaderResourceDescriptorSetIndex = glslangProgramInterfaceInfo->shaderResourceDescriptorSetIndex =
kShaderResourceDescriptorSetIndex; ToUnderlying(DescriptorSetIndex::ShaderResource);
glslangProgramInterfaceInfo->currentShaderResourceBindingIndex = 0; glslangProgramInterfaceInfo->currentShaderResourceBindingIndex = 0;
glslangProgramInterfaceInfo->driverUniformsDescriptorSetIndex = glslangProgramInterfaceInfo->driverUniformsDescriptorSetIndex =
kDriverUniformsDescriptorSetIndex; ToUnderlying(DescriptorSetIndex::DriverUniforms);
glslangProgramInterfaceInfo->locationsUsedForXfbExtension = 0; glslangProgramInterfaceInfo->locationsUsedForXfbExtension = 0;
} }
......
...@@ -172,7 +172,7 @@ void ProgramExecutableVk::reset(ContextVk *contextVk) ...@@ -172,7 +172,7 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
} }
mPipelineLayout.reset(); mPipelineLayout.reset();
mDescriptorSets.clear(); mDescriptorSets.fill(VK_NULL_HANDLE);
mEmptyDescriptorSets.fill(VK_NULL_HANDLE); mEmptyDescriptorSets.fill(VK_NULL_HANDLE);
mNumDefaultUniformDescriptors = 0; mNumDefaultUniformDescriptors = 0;
mTransformOptionBits.reset(); mTransformOptionBits.reset();
...@@ -347,13 +347,13 @@ angle::Result ProgramExecutableVk::allocUniformAndXfbDescriptorSet( ...@@ -347,13 +347,13 @@ angle::Result ProgramExecutableVk::allocUniformAndXfbDescriptorSet(
auto iter = mUniformsAndXfbDescriptorSetCache.find(xfbBufferDesc); auto iter = mUniformsAndXfbDescriptorSetCache.find(xfbBufferDesc);
if (iter != mUniformsAndXfbDescriptorSetCache.end()) if (iter != mUniformsAndXfbDescriptorSetCache.end())
{ {
mDescriptorSets[kUniformsAndXfbDescriptorSetIndex] = iter->second; mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)] = iter->second;
*newDescriptorSetAllocated = false; *newDescriptorSetAllocated = false;
return angle::Result::Continue; return angle::Result::Continue;
} }
bool newPoolAllocated; bool newPoolAllocated;
ANGLE_TRY(allocateDescriptorSetAndGetInfo(contextVk, kUniformsAndXfbDescriptorSetIndex, ANGLE_TRY(allocateDescriptorSetAndGetInfo(contextVk, DescriptorSetIndex::UniformsAndXfb,
&newPoolAllocated)); &newPoolAllocated));
// Clear descriptor set cache. It may no longer be valid. // Clear descriptor set cache. It may no longer be valid.
...@@ -363,38 +363,35 @@ angle::Result ProgramExecutableVk::allocUniformAndXfbDescriptorSet( ...@@ -363,38 +363,35 @@ angle::Result ProgramExecutableVk::allocUniformAndXfbDescriptorSet(
} }
// Add the descriptor set into cache // Add the descriptor set into cache
mUniformsAndXfbDescriptorSetCache.emplace(xfbBufferDesc, mUniformsAndXfbDescriptorSetCache.emplace(
mDescriptorSets[kUniformsAndXfbDescriptorSetIndex]); xfbBufferDesc, mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]);
*newDescriptorSetAllocated = true; *newDescriptorSetAllocated = true;
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ProgramExecutableVk::allocateDescriptorSet(ContextVk *contextVk, angle::Result ProgramExecutableVk::allocateDescriptorSet(ContextVk *contextVk,
uint32_t descriptorSetIndex) DescriptorSetIndex descriptorSetIndex)
{ {
bool ignoreNewPoolAllocated; bool ignoreNewPoolAllocated;
return allocateDescriptorSetAndGetInfo(contextVk, descriptorSetIndex, &ignoreNewPoolAllocated); return allocateDescriptorSetAndGetInfo(contextVk, descriptorSetIndex, &ignoreNewPoolAllocated);
} }
angle::Result ProgramExecutableVk::allocateDescriptorSetAndGetInfo(ContextVk *contextVk, angle::Result ProgramExecutableVk::allocateDescriptorSetAndGetInfo(
uint32_t descriptorSetIndex, ContextVk *contextVk,
bool *newPoolAllocatedOut) DescriptorSetIndex descriptorSetIndex,
bool *newPoolAllocatedOut)
{ {
vk::DynamicDescriptorPool &dynamicDescriptorPool = mDynamicDescriptorPools[descriptorSetIndex]; vk::DynamicDescriptorPool &dynamicDescriptorPool =
mDynamicDescriptorPools[ToUnderlying(descriptorSetIndex)];
uint32_t potentialNewCount = descriptorSetIndex + 1;
if (potentialNewCount > mDescriptorSets.size())
{
mDescriptorSets.resize(potentialNewCount, VK_NULL_HANDLE);
}
const vk::DescriptorSetLayout &descriptorSetLayout = const vk::DescriptorSetLayout &descriptorSetLayout =
mDescriptorSetLayouts[descriptorSetIndex].get(); mDescriptorSetLayouts[ToUnderlying(descriptorSetIndex)].get();
ANGLE_TRY(dynamicDescriptorPool.allocateSetsAndGetInfo( ANGLE_TRY(dynamicDescriptorPool.allocateSetsAndGetInfo(
contextVk, descriptorSetLayout.ptr(), 1, &mDescriptorPoolBindings[descriptorSetIndex], contextVk, descriptorSetLayout.ptr(), 1,
&mDescriptorSets[descriptorSetIndex], newPoolAllocatedOut)); &mDescriptorPoolBindings[ToUnderlying(descriptorSetIndex)],
mEmptyDescriptorSets[descriptorSetIndex] = VK_NULL_HANDLE; &mDescriptorSets[ToUnderlying(descriptorSetIndex)], newPoolAllocatedOut));
mEmptyDescriptorSets[ToUnderlying(descriptorSetIndex)] = VK_NULL_HANDLE;
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -714,7 +711,7 @@ angle::Result ProgramExecutableVk::updatePipelineLayout( ...@@ -714,7 +711,7 @@ angle::Result ProgramExecutableVk::updatePipelineLayout(
ANGLE_TRY(renderer->getDescriptorSetLayout( ANGLE_TRY(renderer->getDescriptorSetLayout(
contextVk, uniformsAndXfbSetDesc, contextVk, uniformsAndXfbSetDesc,
&mDescriptorSetLayouts[kUniformsAndXfbDescriptorSetIndex])); &mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]));
// Uniform and storage buffers, atomic counter buffers and images: // Uniform and storage buffers, atomic counter buffers and images:
vk::DescriptorSetLayoutDesc resourcesSetDesc; vk::DescriptorSetLayoutDesc resourcesSetDesc;
...@@ -739,7 +736,8 @@ angle::Result ProgramExecutableVk::updatePipelineLayout( ...@@ -739,7 +736,8 @@ angle::Result ProgramExecutableVk::updatePipelineLayout(
} }
ANGLE_TRY(renderer->getDescriptorSetLayout( ANGLE_TRY(renderer->getDescriptorSetLayout(
contextVk, resourcesSetDesc, &mDescriptorSetLayouts[kShaderResourceDescriptorSetIndex])); contextVk, resourcesSetDesc,
&mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::ShaderResource)]));
// Textures: // Textures:
vk::DescriptorSetLayoutDesc texturesSetDesc; vk::DescriptorSetLayoutDesc texturesSetDesc;
...@@ -752,8 +750,9 @@ angle::Result ProgramExecutableVk::updatePipelineLayout( ...@@ -752,8 +750,9 @@ angle::Result ProgramExecutableVk::updatePipelineLayout(
activeTextures, &texturesSetDesc); activeTextures, &texturesSetDesc);
} }
ANGLE_TRY(renderer->getDescriptorSetLayout(contextVk, texturesSetDesc, ANGLE_TRY(renderer->getDescriptorSetLayout(
&mDescriptorSetLayouts[kTextureDescriptorSetIndex])); contextVk, texturesSetDesc,
&mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::Texture)]));
// Driver uniforms: // Driver uniforms:
VkShaderStageFlags driverUniformsStages = VkShaderStageFlags driverUniformsStages =
...@@ -762,16 +761,16 @@ angle::Result ProgramExecutableVk::updatePipelineLayout( ...@@ -762,16 +761,16 @@ angle::Result ProgramExecutableVk::updatePipelineLayout(
contextVk->getDriverUniformsDescriptorSetDesc(driverUniformsStages); contextVk->getDriverUniformsDescriptorSetDesc(driverUniformsStages);
ANGLE_TRY(renderer->getDescriptorSetLayout( ANGLE_TRY(renderer->getDescriptorSetLayout(
contextVk, driverUniformsSetDesc, contextVk, driverUniformsSetDesc,
&mDescriptorSetLayouts[kDriverUniformsDescriptorSetIndex])); &mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::DriverUniforms)]));
// Create pipeline layout with these 4 descriptor sets. // Create pipeline layout with these 4 descriptor sets.
vk::PipelineLayoutDesc pipelineLayoutDesc; vk::PipelineLayoutDesc pipelineLayoutDesc;
pipelineLayoutDesc.updateDescriptorSetLayout(kUniformsAndXfbDescriptorSetIndex, pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::UniformsAndXfb,
uniformsAndXfbSetDesc); uniformsAndXfbSetDesc);
pipelineLayoutDesc.updateDescriptorSetLayout(kShaderResourceDescriptorSetIndex, pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::ShaderResource,
resourcesSetDesc); resourcesSetDesc);
pipelineLayoutDesc.updateDescriptorSetLayout(kTextureDescriptorSetIndex, texturesSetDesc); pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::Texture, texturesSetDesc);
pipelineLayoutDesc.updateDescriptorSetLayout(kDriverUniformsDescriptorSetIndex, pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::DriverUniforms,
driverUniformsSetDesc); driverUniformsSetDesc);
ANGLE_TRY(renderer->getPipelineLayout(contextVk, pipelineLayoutDesc, mDescriptorSetLayouts, ANGLE_TRY(renderer->getPipelineLayout(contextVk, pipelineLayoutDesc, mDescriptorSetLayouts,
...@@ -849,17 +848,17 @@ angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glCon ...@@ -849,17 +848,17 @@ angle::Result ProgramExecutableVk::createPipelineLayout(const gl::Context *glCon
VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, textureCount}; VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, textureCount};
ANGLE_TRY(mDynamicDescriptorPools[kUniformsAndXfbDescriptorSetIndex].init( ANGLE_TRY(mDynamicDescriptorPools[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)].init(
contextVk, uniformAndXfbSetSize.data(), uniformAndXfbSetSize.size())); contextVk, uniformAndXfbSetSize.data(), uniformAndXfbSetSize.size()));
if (resourceSetSize.size() > 0) if (resourceSetSize.size() > 0)
{ {
ANGLE_TRY(mDynamicDescriptorPools[kShaderResourceDescriptorSetIndex].init( ANGLE_TRY(mDynamicDescriptorPools[ToUnderlying(DescriptorSetIndex::ShaderResource)].init(
contextVk, resourceSetSize.data(), static_cast<uint32_t>(resourceSetSize.size()))); contextVk, resourceSetSize.data(), static_cast<uint32_t>(resourceSetSize.size())));
} }
if (textureCount > 0) if (textureCount > 0)
{ {
ANGLE_TRY(mDynamicDescriptorPools[kTextureDescriptorSetIndex].init(contextVk, ANGLE_TRY(mDynamicDescriptorPools[ToUnderlying(DescriptorSetIndex::Texture)].init(
&textureSetSize, 1)); contextVk, &textureSetSize, 1));
} }
mDynamicBufferOffsets.resize(glExecutable.getLinkedShaderStageCount()); mDynamicBufferOffsets.resize(glExecutable.getLinkedShaderStageCount());
...@@ -899,7 +898,7 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet( ...@@ -899,7 +898,7 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet(
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfo.pNext = nullptr; writeInfo.pNext = nullptr;
writeInfo.dstSet = mDescriptorSets[kUniformsAndXfbDescriptorSetIndex]; writeInfo.dstSet = mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)];
writeInfo.dstBinding = info.binding; writeInfo.dstBinding = info.binding;
writeInfo.dstArrayElement = 0; writeInfo.dstArrayElement = 0;
writeInfo.descriptorCount = 1; writeInfo.descriptorCount = 1;
...@@ -921,7 +920,8 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -921,7 +920,8 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
return; return;
} }
VkDescriptorSet descriptorSet = mDescriptorSets[kShaderResourceDescriptorSetIndex]; VkDescriptorSet descriptorSet =
mDescriptorSets[ToUnderlying(DescriptorSetIndex::ShaderResource)];
ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
...@@ -1012,7 +1012,8 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -1012,7 +1012,8 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
return; return;
} }
VkDescriptorSet descriptorSet = mDescriptorSets[kShaderResourceDescriptorSetIndex]; VkDescriptorSet descriptorSet =
mDescriptorSets[ToUnderlying(DescriptorSetIndex::ShaderResource)];
std::string blockName(sh::vk::kAtomicCountersBlockName); std::string blockName(sh::vk::kAtomicCountersBlockName);
const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName];
...@@ -1102,7 +1103,8 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1102,7 +1103,8 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
return angle::Result::Continue; return angle::Result::Continue;
} }
VkDescriptorSet descriptorSet = mDescriptorSets[kShaderResourceDescriptorSetIndex]; VkDescriptorSet descriptorSet =
mDescriptorSets[ToUnderlying(DescriptorSetIndex::ShaderResource)];
const gl::ActiveTextureArray<TextureVk *> &activeImages = contextVk->getActiveImages(); const gl::ActiveTextureArray<TextureVk *> &activeImages = contextVk->getActiveImages();
...@@ -1174,7 +1176,7 @@ angle::Result ProgramExecutableVk::updateShaderResourcesDescriptorSet( ...@@ -1174,7 +1176,7 @@ angle::Result ProgramExecutableVk::updateShaderResourcesDescriptorSet(
gl::ShaderMap<const gl::ProgramState *> programStates; gl::ShaderMap<const gl::ProgramState *> programStates;
fillProgramStateMap(contextVk, &programStates); fillProgramStateMap(contextVk, &programStates);
ANGLE_TRY(allocateDescriptorSet(contextVk, kShaderResourceDescriptorSetIndex)); ANGLE_TRY(allocateDescriptorSet(contextVk, DescriptorSetIndex::ShaderResource));
for (const gl::ShaderType shaderType : executable->getLinkedShaderStages()) for (const gl::ShaderType shaderType : executable->getLinkedShaderStages())
{ {
...@@ -1250,14 +1252,14 @@ void ProgramExecutableVk::updateTransformFeedbackDescriptorSetImpl( ...@@ -1250,14 +1252,14 @@ void ProgramExecutableVk::updateTransformFeedbackDescriptorSetImpl(
TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback); TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback);
transformFeedbackVk->initDescriptorSet( transformFeedbackVk->initDescriptorSet(
contextVk, executable.getTransformFeedbackBufferCount(), contextVk, executable.getTransformFeedbackBufferCount(),
mDescriptorSets[kUniformsAndXfbDescriptorSetIndex]); mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]);
} }
return; return;
} }
TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(glState.getCurrentTransformFeedback()); TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(glState.getCurrentTransformFeedback());
transformFeedbackVk->updateDescriptorSet(contextVk, programState, transformFeedbackVk->updateDescriptorSet(
mDescriptorSets[kUniformsAndXfbDescriptorSetIndex]); contextVk, programState, mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]);
} }
angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contextVk) angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contextVk)
...@@ -1275,13 +1277,13 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1275,13 +1277,13 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
auto iter = mTextureDescriptorsCache.find(texturesDesc); auto iter = mTextureDescriptorsCache.find(texturesDesc);
if (iter != mTextureDescriptorsCache.end()) if (iter != mTextureDescriptorsCache.end())
{ {
mDescriptorSets[kTextureDescriptorSetIndex] = iter->second; mDescriptorSets[ToUnderlying(DescriptorSetIndex::Texture)] = iter->second;
return angle::Result::Continue; return angle::Result::Continue;
} }
bool newPoolAllocated; bool newPoolAllocated;
ANGLE_TRY( ANGLE_TRY(
allocateDescriptorSetAndGetInfo(contextVk, kTextureDescriptorSetIndex, &newPoolAllocated)); allocateDescriptorSetAndGetInfo(contextVk, DescriptorSetIndex::Texture, &newPoolAllocated));
// Clear descriptor set cache. It may no longer be valid. // Clear descriptor set cache. It may no longer be valid.
if (newPoolAllocated) if (newPoolAllocated)
...@@ -1289,7 +1291,7 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1289,7 +1291,7 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
mTextureDescriptorsCache.clear(); mTextureDescriptorsCache.clear();
} }
VkDescriptorSet descriptorSet = mDescriptorSets[kTextureDescriptorSetIndex]; VkDescriptorSet descriptorSet = mDescriptorSets[ToUnderlying(DescriptorSetIndex::Texture)];
const gl::ActiveTextureArray<vk::TextureUnit> &activeTextures = contextVk->getActiveTextures(); const gl::ActiveTextureArray<vk::TextureUnit> &activeTextures = contextVk->getActiveTextures();
...@@ -1394,13 +1396,10 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk, ...@@ -1394,13 +1396,10 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk,
{ {
// Can probably use better dirty bits here. // Can probably use better dirty bits here.
if (mDescriptorSets.empty())
return angle::Result::Continue;
// Find the maximum non-null descriptor set. This is used in conjunction with a driver // Find the maximum non-null descriptor set. This is used in conjunction with a driver
// workaround to bind empty descriptor sets only for gaps in between 0 and max and avoid // workaround to bind empty descriptor sets only for gaps in between 0 and max and avoid
// binding unnecessary empty descriptor sets for the sets beyond max. // binding unnecessary empty descriptor sets for the sets beyond max.
const size_t descriptorSetStart = kUniformsAndXfbDescriptorSetIndex; const size_t descriptorSetStart = ToUnderlying(DescriptorSetIndex::UniformsAndXfb);
size_t descriptorSetRange = 0; size_t descriptorSetRange = 0;
for (size_t descriptorSetIndex = descriptorSetStart; for (size_t descriptorSetIndex = descriptorSetStart;
descriptorSetIndex < mDescriptorSets.size(); ++descriptorSetIndex) descriptorSetIndex < mDescriptorSets.size(); ++descriptorSetIndex)
...@@ -1446,12 +1445,13 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk, ...@@ -1446,12 +1445,13 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk,
// through dynamic uniform buffers (requiring dynamic offsets). No other descriptor // through dynamic uniform buffers (requiring dynamic offsets). No other descriptor
// requires a dynamic offset. // requires a dynamic offset.
const uint32_t uniformBlockOffsetCount = const uint32_t uniformBlockOffsetCount =
descriptorSetIndex == kUniformsAndXfbDescriptorSetIndex descriptorSetIndex == ToUnderlying(DescriptorSetIndex::UniformsAndXfb)
? static_cast<uint32_t>(mNumDefaultUniformDescriptors) ? static_cast<uint32_t>(mNumDefaultUniformDescriptors)
: 0; : 0;
commandBuffer->bindDescriptorSets(getPipelineLayout(), pipelineBindPoint, commandBuffer->bindDescriptorSets(getPipelineLayout(), pipelineBindPoint,
descriptorSetIndex, 1, &descSet, uniformBlockOffsetCount, static_cast<DescriptorSetIndex>(descriptorSetIndex), 1,
&descSet, uniformBlockOffsetCount,
mDynamicBufferOffsets.data()); mDynamicBufferOffsets.data());
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "libANGLE/InfoLog.h" #include "libANGLE/InfoLog.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h" #include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h" #include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx namespace rx
...@@ -176,9 +177,10 @@ class ProgramExecutableVk ...@@ -176,9 +177,10 @@ class ProgramExecutableVk
const vk::UniformsAndXfbDesc &xfbBufferDesc, const vk::UniformsAndXfbDesc &xfbBufferDesc,
bool *newDescriptorSetAllocated); bool *newDescriptorSetAllocated);
angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex); angle::Result allocateDescriptorSet(ContextVk *contextVk,
DescriptorSetIndex descriptorSetIndex);
angle::Result allocateDescriptorSetAndGetInfo(ContextVk *contextVk, angle::Result allocateDescriptorSetAndGetInfo(ContextVk *contextVk,
uint32_t descriptorSetIndex, DescriptorSetIndex descriptorSetIndex,
bool *newPoolAllocatedOut); bool *newPoolAllocatedOut);
void addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> &blocks, void addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> &blocks,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
...@@ -217,7 +219,7 @@ class ProgramExecutableVk ...@@ -217,7 +219,7 @@ class ProgramExecutableVk
ContextVk *contextVk); ContextVk *contextVk);
// Descriptor sets for uniform blocks and textures for this program. // Descriptor sets for uniform blocks and textures for this program.
std::vector<VkDescriptorSet> mDescriptorSets; vk::DescriptorSetLayoutArray<VkDescriptorSet> mDescriptorSets;
vk::DescriptorSetLayoutArray<VkDescriptorSet> mEmptyDescriptorSets; vk::DescriptorSetLayoutArray<VkDescriptorSet> mEmptyDescriptorSets;
size_t mNumDefaultUniformDescriptors; size_t mNumDefaultUniformDescriptors;
vk::BufferSerial mCurrentDefaultUniformBufferSerial; vk::BufferSerial mCurrentDefaultUniformBufferSerial;
......
...@@ -18,11 +18,14 @@ ...@@ -18,11 +18,14 @@
namespace rx namespace rx
{ {
enum DescriptorSetIndex : uint32_t;
namespace vk namespace vk
{ {
namespace priv namespace priv
{ {
// NOTE: Please keep command-related enums, stucts, functions // NOTE: Please keep command-related enums, stucts, functions
// and other code dealing with commands in alphabetical order // and other code dealing with commands in alphabetical order
// This simplifies searching and updating commands. // This simplifies searching and updating commands.
...@@ -468,7 +471,7 @@ class SecondaryCommandBuffer final : angle::NonCopyable ...@@ -468,7 +471,7 @@ class SecondaryCommandBuffer final : angle::NonCopyable
void bindDescriptorSets(const PipelineLayout &layout, void bindDescriptorSets(const PipelineLayout &layout,
VkPipelineBindPoint pipelineBindPoint, VkPipelineBindPoint pipelineBindPoint,
uint32_t firstSet, DescriptorSetIndex firstSet,
uint32_t descriptorSetCount, uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets, const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
...@@ -846,7 +849,7 @@ ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pi ...@@ -846,7 +849,7 @@ ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pi
ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout, ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
VkPipelineBindPoint pipelineBindPoint, VkPipelineBindPoint pipelineBindPoint,
uint32_t firstSet, DescriptorSetIndex firstSet,
uint32_t descriptorSetCount, uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets, const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
...@@ -860,7 +863,7 @@ ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayou ...@@ -860,7 +863,7 @@ ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayou
// Copy params into memory // Copy params into memory
paramStruct->layout = layout.getHandle(); paramStruct->layout = layout.getHandle();
paramStruct->pipelineBindPoint = pipelineBindPoint; paramStruct->pipelineBindPoint = pipelineBindPoint;
paramStruct->firstSet = firstSet; paramStruct->firstSet = ToUnderlying(firstSet);
paramStruct->descriptorSetCount = descriptorSetCount; paramStruct->descriptorSetCount = descriptorSetCount;
paramStruct->dynamicOffsetCount = dynamicOffsetCount; paramStruct->dynamicOffsetCount = dynamicOffsetCount;
// Copy variable sized data // Copy variable sized data
......
...@@ -29,9 +29,6 @@ namespace GenerateMipmap_comp = vk::InternalShader::GenerateMipmap ...@@ -29,9 +29,6 @@ namespace GenerateMipmap_comp = vk::InternalShader::GenerateMipmap
namespace 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 kConvertIndexDestinationBinding = 0;
constexpr uint32_t kConvertVertexDestinationBinding = 0; constexpr uint32_t kConvertVertexDestinationBinding = 0;
constexpr uint32_t kConvertVertexSourceBinding = 1; constexpr uint32_t kConvertVertexSourceBinding = 1;
...@@ -423,8 +420,9 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk, ...@@ -423,8 +420,9 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk,
++currentBinding; ++currentBinding;
} }
ANGLE_TRY(renderer->getDescriptorSetLayout(contextVk, descriptorSetDesc, ANGLE_TRY(renderer->getDescriptorSetLayout(
&mDescriptorSetLayouts[function][kSetIndex])); contextVk, descriptorSetDesc,
&mDescriptorSetLayouts[function][ToUnderlying(DescriptorSetIndex::InternalShader)]));
gl::ShaderType pushConstantsShaderStage = gl::ShaderType pushConstantsShaderStage =
isCompute ? gl::ShaderType::Compute : gl::ShaderType::Fragment; isCompute ? gl::ShaderType::Compute : gl::ShaderType::Fragment;
...@@ -432,7 +430,8 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk, ...@@ -432,7 +430,8 @@ angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk,
// Corresponding pipeline layouts: // Corresponding pipeline layouts:
vk::PipelineLayoutDesc pipelineLayoutDesc; vk::PipelineLayoutDesc pipelineLayoutDesc;
pipelineLayoutDesc.updateDescriptorSetLayout(kSetIndex, descriptorSetDesc); pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::InternalShader,
descriptorSetDesc);
if (pushConstantsSize) if (pushConstantsSize)
{ {
pipelineLayoutDesc.updatePushConstantRange(pushConstantsShaderStage, 0, pipelineLayoutDesc.updatePushConstantRange(pushConstantsShaderStage, 0,
...@@ -746,15 +745,16 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk, ...@@ -746,15 +745,16 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk,
if (descriptorSet != VK_NULL_HANDLE) if (descriptorSet != VK_NULL_HANDLE)
{ {
commandBuffer->bindDescriptorSets(pipelineLayout.get(), pipelineBindPoint, 0, 1, commandBuffer->bindDescriptorSets(pipelineLayout.get(), pipelineBindPoint,
&descriptorSet, 0, nullptr); DescriptorSetIndex::InternalShader, 1, &descriptorSet, 0,
nullptr);
if (isCompute) if (isCompute)
{ {
contextVk->invalidateComputeDescriptorSet(0); contextVk->invalidateComputeDescriptorSet(DescriptorSetIndex::InternalShader);
} }
else else
{ {
contextVk->invalidateGraphicsDescriptorSet(0); contextVk->invalidateGraphicsDescriptorSet(DescriptorSetIndex::InternalShader);
} }
} }
...@@ -2119,8 +2119,11 @@ angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk, ...@@ -2119,8 +2119,11 @@ angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk,
VkDescriptorSet *descriptorSetOut) VkDescriptorSet *descriptorSetOut)
{ {
ANGLE_TRY(mDescriptorPools[function].allocateSets( ANGLE_TRY(mDescriptorPools[function].allocateSets(
contextVk, mDescriptorSetLayouts[function][kSetIndex].get().ptr(), 1, bindingOut, contextVk,
descriptorSetOut)); mDescriptorSetLayouts[function][ToUnderlying(DescriptorSetIndex::InternalShader)]
.get()
.ptr(),
1, bindingOut, descriptorSetOut));
bindingOut->get().updateSerial(contextVk->getCurrentQueueSerial()); bindingOut->get().updateSerial(contextVk->getCurrentQueueSerial());
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -1718,11 +1718,11 @@ bool PipelineLayoutDesc::operator==(const PipelineLayoutDesc &other) const ...@@ -1718,11 +1718,11 @@ bool PipelineLayoutDesc::operator==(const PipelineLayoutDesc &other) const
return memcmp(this, &other, sizeof(PipelineLayoutDesc)) == 0; return memcmp(this, &other, sizeof(PipelineLayoutDesc)) == 0;
} }
void PipelineLayoutDesc::updateDescriptorSetLayout(uint32_t setIndex, void PipelineLayoutDesc::updateDescriptorSetLayout(DescriptorSetIndex setIndex,
const DescriptorSetLayoutDesc &desc) const DescriptorSetLayoutDesc &desc)
{ {
ASSERT(setIndex < mDescriptorSetLayouts.size()); ASSERT(ToUnderlying(setIndex) < mDescriptorSetLayouts.size());
mDescriptorSetLayouts[setIndex] = desc; mDescriptorSetLayouts[ToUnderlying(setIndex)] = desc;
} }
void PipelineLayoutDesc::updatePushConstantRange(gl::ShaderType shaderType, void PipelineLayoutDesc::updatePushConstantRange(gl::ShaderType shaderType,
......
...@@ -18,6 +18,38 @@ ...@@ -18,6 +18,38 @@
namespace rx 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 namespace vk
{ {
class ImageHelper; class ImageHelper;
...@@ -611,7 +643,7 @@ struct PackedPushConstantRange ...@@ -611,7 +643,7 @@ struct PackedPushConstantRange
}; };
template <typename T> template <typename T>
using DescriptorSetLayoutArray = std::array<T, kMaxDescriptorSetLayouts>; using DescriptorSetLayoutArray = std::array<T, static_cast<size_t>(DescriptorSetIndex::EnumCount)>;
using DescriptorSetLayoutPointerArray = using DescriptorSetLayoutPointerArray =
DescriptorSetLayoutArray<BindingPointer<DescriptorSetLayout>>; DescriptorSetLayoutArray<BindingPointer<DescriptorSetLayout>>;
template <typename T> template <typename T>
...@@ -628,7 +660,8 @@ class PipelineLayoutDesc final ...@@ -628,7 +660,8 @@ class PipelineLayoutDesc final
size_t hash() const; size_t hash() const;
bool operator==(const PipelineLayoutDesc &other) 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); void updatePushConstantRange(gl::ShaderType shaderType, uint32_t offset, uint32_t size);
const PushConstantRangeArray<PackedPushConstantRange> &getPushConstantRanges() const; const PushConstantRangeArray<PackedPushConstantRange> &getPushConstantRanges() const;
...@@ -1230,32 +1263,6 @@ class SamplerYcbcrConversionCache final : angle::NonCopyable ...@@ -1230,32 +1263,6 @@ class SamplerYcbcrConversionCache final : angle::NonCopyable
std::unordered_map<uint64_t, vk::RefCountedSamplerYcbcrConversion> mPayload; 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. // Only 1 driver uniform binding is used.
constexpr uint32_t kReservedDriverUniformBindingCount = 1; constexpr uint32_t kReservedDriverUniformBindingCount = 1;
// There is 1 default uniform binding used per stage. Currently, a maxium of three stages are // There is 1 default uniform binding used per stage. Currently, a maxium of three stages are
......
...@@ -72,8 +72,8 @@ class VulkanUniformUpdatesTest : public ANGLETest ...@@ -72,8 +72,8 @@ class VulkanUniformUpdatesTest : public ANGLETest
rx::ProgramVk *programVk = hackProgram(program); rx::ProgramVk *programVk = hackProgram(program);
// Force a small limit on the max sets per pool to more easily trigger a new allocation. // Force a small limit on the max sets per pool to more easily trigger a new allocation.
rx::vk::DynamicDescriptorPool *uniformPool = rx::vk::DynamicDescriptorPool *uniformPool = programVk->getDynamicDescriptorPool(
programVk->getDynamicDescriptorPool(rx::kUniformsAndXfbDescriptorSetIndex); ToUnderlying(rx::DescriptorSetIndex::UniformsAndXfb));
uniformPool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting); uniformPool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
rx::kReservedDefaultUniformBindingCount}; rx::kReservedDefaultUniformBindingCount};
...@@ -86,7 +86,7 @@ class VulkanUniformUpdatesTest : public ANGLETest ...@@ -86,7 +86,7 @@ class VulkanUniformUpdatesTest : public ANGLETest
textureCount = std::max(textureCount, 1u); textureCount = std::max(textureCount, 1u);
rx::vk::DynamicDescriptorPool *texturePool = rx::vk::DynamicDescriptorPool *texturePool =
programVk->getDynamicDescriptorPool(rx::kTextureDescriptorSetIndex); programVk->getDynamicDescriptorPool(ToUnderlying(rx::DescriptorSetIndex::Texture));
texturePool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting); texturePool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
textureCount}; 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