Commit 054aeeed by Charlie Lao Committed by Commit Bot

Vulkan: Batch vkUpdateDescriptorSets calls

Right now we are making this calls multiple times as we loop through each shader stage. Qualcomm performance validation layer warns about this. This change will aggregate the calls into one call per dispatch. Bug: b/158787299 Change-Id: I48aa3752f708c26ffbca2fb7947cb8bbc0f76dcd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2243321 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 70e706f4
...@@ -47,6 +47,12 @@ namespace rx ...@@ -47,6 +47,12 @@ namespace rx
namespace namespace
{ {
// For DesciptorSetUpdates
constexpr size_t kDescriptorBufferInfosInitialSize = 8;
constexpr size_t kDescriptorImageInfosInitialSize = 4;
constexpr size_t kDescriptorWriteInfosInitialSize =
kDescriptorBufferInfosInitialSize + kDescriptorImageInfosInitialSize;
// For shader uniforms such as gl_DepthRange and the viewport size. // For shader uniforms such as gl_DepthRange and the viewport size.
struct GraphicsDriverUniforms struct GraphicsDriverUniforms
{ {
...@@ -620,7 +626,10 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -620,7 +626,10 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mPrimaryBufferCounter(0), mPrimaryBufferCounter(0),
mRenderPassCounter(0), mRenderPassCounter(0),
mContextPriority(renderer->getDriverPriority(GetContextPriority(state))), mContextPriority(renderer->getDriverPriority(GetContextPriority(state))),
mCurrentIndirectBuffer(nullptr) mCurrentIndirectBuffer(nullptr),
mBufferInfos(),
mImageInfos(),
mWriteInfos()
{ {
ANGLE_TRACE_EVENT0("gpu.angle", "ContextVk::ContextVk"); ANGLE_TRACE_EVENT0("gpu.angle", "ContextVk::ContextVk");
memset(&mClearColorValue, 0, sizeof(mClearColorValue)); memset(&mClearColorValue, 0, sizeof(mClearColorValue));
...@@ -709,6 +718,11 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -709,6 +718,11 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mPipelineDirtyBitsMask.set(); mPipelineDirtyBitsMask.set();
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_TEXTURE_BINDINGS); mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
// Reserve reasonable amount of spaces so that for majority of apps we don't need to grow at all
mBufferInfos.reserve(kDescriptorBufferInfosInitialSize);
mImageInfos.reserve(kDescriptorImageInfosInitialSize);
mWriteInfos.reserve(kDescriptorWriteInfosInitialSize);
} }
ContextVk::~ContextVk() = default; ContextVk::~ContextVk() = default;
...@@ -935,6 +949,10 @@ angle::Result ContextVk::setupDraw(const gl::Context *context, ...@@ -935,6 +949,10 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
*commandBufferOut = mRenderPassCommandBuffer; *commandBufferOut = mRenderPassCommandBuffer;
ASSERT(*commandBufferOut); ASSERT(*commandBufferOut);
// Create a local object to ensure we flush the descriptor updates to device when we leave this
// function
ScopedDescriptorSetUpdates descriptorSetUpdates(this);
if (mProgram && mProgram->dirtyUniforms()) if (mProgram && mProgram->dirtyUniforms())
{ {
ANGLE_TRY(mProgram->updateUniforms(this)); ANGLE_TRY(mProgram->updateUniforms(this));
...@@ -1163,6 +1181,10 @@ angle::Result ContextVk::setupDispatch(const gl::Context *context, ...@@ -1163,6 +1181,10 @@ angle::Result ContextVk::setupDispatch(const gl::Context *context,
ANGLE_TRY(endRenderPass()); ANGLE_TRY(endRenderPass());
*commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer(); *commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer();
// Create a local object to ensure we flush the descriptor updates to device when we leave this
// function
ScopedDescriptorSetUpdates descriptorSetUpdates(this);
if (mProgram && mProgram->dirtyUniforms()) if (mProgram && mProgram->dirtyUniforms())
{ {
ANGLE_TRY(mProgram->updateUniforms(this)); ANGLE_TRY(mProgram->updateUniforms(this));
...@@ -3600,23 +3622,21 @@ angle::Result ContextVk::updateDriverUniformsDescriptorSet( ...@@ -3600,23 +3622,21 @@ angle::Result ContextVk::updateDriverUniformsDescriptorSet(
&driverUniforms->descriptorPoolBinding, &driverUniforms->descriptorSet)); &driverUniforms->descriptorPoolBinding, &driverUniforms->descriptorSet));
// Update the driver uniform descriptor set. // Update the driver uniform descriptor set.
VkDescriptorBufferInfo bufferInfo = {}; VkDescriptorBufferInfo &bufferInfo = allocBufferInfo();
bufferInfo.buffer = buffer; bufferInfo.buffer = buffer;
bufferInfo.offset = 0; bufferInfo.offset = 0;
bufferInfo.range = driverUniformsSize; bufferInfo.range = driverUniformsSize;
VkWriteDescriptorSet writeInfo = {}; VkWriteDescriptorSet &writeInfo = allocWriteInfo();
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfo.dstSet = driverUniforms->descriptorSet; writeInfo.dstSet = driverUniforms->descriptorSet;
writeInfo.dstBinding = 0; writeInfo.dstBinding = 0;
writeInfo.dstArrayElement = 0; writeInfo.dstArrayElement = 0;
writeInfo.descriptorCount = 1; writeInfo.descriptorCount = 1;
writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
writeInfo.pImageInfo = nullptr; writeInfo.pImageInfo = nullptr;
writeInfo.pTexelBufferView = nullptr; writeInfo.pTexelBufferView = nullptr;
writeInfo.pBufferInfo = &bufferInfo; writeInfo.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(getDevice(), 1, &writeInfo, 0, nullptr);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -4474,4 +4494,74 @@ bool ContextVk::isRobustResourceInitEnabled() const ...@@ -4474,4 +4494,74 @@ bool ContextVk::isRobustResourceInitEnabled() const
return mState.isRobustResourceInitEnabled(); return mState.isRobustResourceInitEnabled();
} }
VkDescriptorBufferInfo &ContextVk::allocBufferInfos(size_t count)
{
return allocInfos<VkDescriptorBufferInfo, &VkWriteDescriptorSet::pBufferInfo>(&mBufferInfos,
count);
}
VkDescriptorImageInfo &ContextVk::allocImageInfos(size_t count)
{
return allocInfos<VkDescriptorImageInfo, &VkWriteDescriptorSet::pImageInfo>(&mImageInfos,
count);
}
template <typename T, const T *VkWriteDescriptorSet::*pInfo>
T &ContextVk::allocInfos(std::vector<T> *mInfos, size_t count)
{
size_t oldSize = mInfos->size();
size_t newSize = oldSize + count;
if (newSize > mInfos->capacity())
{
// If we have reached capacity, grow the storage and patch the descriptor set with new
// buffer info pointer
growCapacity<T, pInfo>(mInfos, newSize);
}
mInfos->resize(newSize);
return (*mInfos)[oldSize];
}
template <typename T, const T *VkWriteDescriptorSet::*pInfo>
void ContextVk::growCapacity(std::vector<T> *mInfos, size_t newSize)
{
const T *const oldInfoStart = mInfos->empty() ? nullptr : &(*mInfos)[0];
size_t newCapacity = std::max(mInfos->capacity() << 1, newSize);
mInfos->reserve(newCapacity);
if (oldInfoStart)
{
// patch mWriteInfo with new BufferInfo/ImageInfo pointers
for (VkWriteDescriptorSet &set : mWriteInfos)
{
if (set.*pInfo)
{
size_t index = set.*pInfo - oldInfoStart;
set.*pInfo = &(*mInfos)[index];
}
}
}
}
// ScopedDescriptorSetUpdates
ANGLE_INLINE ContextVk::ScopedDescriptorSetUpdates::ScopedDescriptorSetUpdates(ContextVk *contextVk)
: mContextVk(contextVk)
{}
ANGLE_INLINE ContextVk::ScopedDescriptorSetUpdates::~ScopedDescriptorSetUpdates()
{
if (mContextVk->mWriteInfos.empty())
{
ASSERT(mContextVk->mBufferInfos.empty());
ASSERT(mContextVk->mImageInfos.empty());
return;
}
vkUpdateDescriptorSets(mContextVk->getDevice(),
static_cast<uint32_t>(mContextVk->mWriteInfos.size()),
mContextVk->mWriteInfos.data(), 0, nullptr);
mContextVk->mWriteInfos.clear();
mContextVk->mBufferInfos.clear();
mContextVk->mImageInfos.clear();
}
} // namespace rx } // namespace rx
...@@ -526,6 +526,20 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -526,6 +526,20 @@ class ContextVk : public ContextImpl, public vk::Context
// When worker thread completes, it releases command buffers back to context queue // When worker thread completes, it releases command buffers back to context queue
void recycleCommandBuffer(vk::CommandBufferHelper *commandBuffer); void recycleCommandBuffer(vk::CommandBufferHelper *commandBuffer);
// DescriptorSet writes
VkDescriptorBufferInfo &allocBufferInfo() { return allocBufferInfos(1); }
VkDescriptorBufferInfo &allocBufferInfos(size_t count);
VkDescriptorImageInfo &allocImageInfo() { return allocImageInfos(1); }
VkDescriptorImageInfo &allocImageInfos(size_t count);
VkWriteDescriptorSet &allocWriteInfo() { return allocWriteInfos(1); }
VkWriteDescriptorSet &allocWriteInfos(size_t count)
{
size_t oldSize = mWriteInfos.size();
size_t newSize = oldSize + count;
mWriteInfos.resize(newSize);
return mWriteInfos[oldSize];
}
private: private:
// Dirty bits. // Dirty bits.
enum DirtyBitType : size_t enum DirtyBitType : size_t
...@@ -616,6 +630,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -616,6 +630,7 @@ class ContextVk : public ContextImpl, public vk::Context
const void *indices, const void *indices,
DirtyBits dirtyBitMask, DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
angle::Result setupIndexedDraw(const gl::Context *context, angle::Result setupIndexedDraw(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLsizei indexCount, GLsizei indexCount,
...@@ -800,6 +815,12 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -800,6 +815,12 @@ class ContextVk : public ContextImpl, public vk::Context
size_t bufferCount, size_t bufferCount,
const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers); const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers);
// DescriptorSet writes
template <typename T, const T *VkWriteDescriptorSet::*pInfo>
T &allocInfos(std::vector<T> *mInfos, size_t count);
template <typename T, const T *VkWriteDescriptorSet::*pInfo>
void growCapacity(std::vector<T> *mInfos, size_t newSize);
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers; std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers; std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
...@@ -976,6 +997,20 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -976,6 +997,20 @@ class ContextVk : public ContextImpl, public vk::Context
const vk::BufferHelper *mCurrentIndirectBuffer; const vk::BufferHelper *mCurrentIndirectBuffer;
// Storage for vkUpdateDescriptorSets
std::vector<VkDescriptorBufferInfo> mBufferInfos;
std::vector<VkDescriptorImageInfo> mImageInfos;
std::vector<VkWriteDescriptorSet> mWriteInfos;
class ScopedDescriptorSetUpdates final : angle::NonCopyable
{
public:
ScopedDescriptorSetUpdates(ContextVk *contextVk);
~ScopedDescriptorSetUpdates();
private:
ContextVk *mContextVk;
};
std::vector<std::string> mCommandBufferDiagnostics; std::vector<std::string> mCommandBufferDiagnostics;
}; };
......
...@@ -832,9 +832,9 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet( ...@@ -832,9 +832,9 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet(
return; return;
} }
DefaultUniformBlock &uniformBlock = defaultUniformBlocks[shaderType]; DefaultUniformBlock &uniformBlock = defaultUniformBlocks[shaderType];
VkDescriptorBufferInfo bufferInfo; VkWriteDescriptorSet &writeInfo = contextVk->allocWriteInfo();
VkWriteDescriptorSet writeInfo; VkDescriptorBufferInfo &bufferInfo = contextVk->allocBufferInfo();
if (!uniformBlock.uniformData.empty()) if (!uniformBlock.uniformData.empty())
{ {
...@@ -862,10 +862,6 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet( ...@@ -862,10 +862,6 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet(
writeInfo.pImageInfo = nullptr; writeInfo.pImageInfo = nullptr;
writeInfo.pBufferInfo = &bufferInfo; writeInfo.pBufferInfo = &bufferInfo;
writeInfo.pTexelBufferView = nullptr; writeInfo.pTexelBufferView = nullptr;
VkDevice device = contextVk->getDevice();
vkUpdateDescriptorSets(device, 1, &writeInfo, 0, nullptr);
} }
void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk, void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
...@@ -891,10 +887,6 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -891,10 +887,6 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS, gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
"The descriptor arrays here would have inadequate size for uniform buffer objects"); "The descriptor arrays here would have inadequate size for uniform buffer objects");
gl::StorageBuffersArray<VkDescriptorBufferInfo> descriptorBufferInfo;
gl::StorageBuffersArray<VkWriteDescriptorSet> writeDescriptorInfo;
uint32_t writeCount = 0;
// Write uniform or storage buffers. // Write uniform or storage buffers.
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
for (uint32_t bufferIndex = 0; bufferIndex < blocks.size(); ++bufferIndex) for (uint32_t bufferIndex = 0; bufferIndex < blocks.size(); ++bufferIndex)
...@@ -933,8 +925,8 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -933,8 +925,8 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
"VkDeviceSize too small"); "VkDeviceSize too small");
ASSERT(bufferBinding.getSize() >= 0); ASSERT(bufferBinding.getSize() >= 0);
VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[writeCount]; VkDescriptorBufferInfo &bufferInfo = contextVk->allocBufferInfo();
VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[writeCount]; VkWriteDescriptorSet &writeInfo = contextVk->allocWriteInfo();
BufferVk *bufferVk = vk::GetImpl(bufferBinding.get()); BufferVk *bufferVk = vk::GetImpl(bufferBinding.get());
vk::BufferHelper &bufferHelper = bufferVk->getBuffer(); vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
...@@ -955,13 +947,7 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -955,13 +947,7 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT, commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT,
kPipelineStageShaderMap[shaderType], &bufferHelper); kPipelineStageShaderMap[shaderType], &bufferHelper);
} }
++writeCount;
} }
VkDevice device = contextVk->getDevice();
vkUpdateDescriptorSets(device, writeCount, writeDescriptorInfo.data(), 0, nullptr);
} }
void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
...@@ -990,8 +976,6 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -990,8 +976,6 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
return; return;
} }
gl::AtomicCounterBuffersArray<VkDescriptorBufferInfo> descriptorBufferInfo;
gl::AtomicCounterBuffersArray<VkWriteDescriptorSet> writeDescriptorInfo;
gl::AtomicCounterBufferMask writtenBindings; gl::AtomicCounterBufferMask writtenBindings;
RendererVk *rendererVk = contextVk->getRenderer(); RendererVk *rendererVk = contextVk->getRenderer();
...@@ -1011,8 +995,8 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -1011,8 +995,8 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
continue; continue;
} }
VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[binding]; VkDescriptorBufferInfo &bufferInfo = contextVk->allocBufferInfo();
VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[binding]; VkWriteDescriptorSet &writeInfo = contextVk->allocWriteInfo();
BufferVk *bufferVk = vk::GetImpl(bufferBinding.get()); BufferVk *bufferVk = vk::GetImpl(bufferBinding.get());
vk::BufferHelper &bufferHelper = bufferVk->getBuffer(); vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
...@@ -1033,31 +1017,28 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -1033,31 +1017,28 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
// Bind the empty buffer to every array slot that's unused. // Bind the empty buffer to every array slot that's unused.
mEmptyBuffer.retain(&contextVk->getResourceUseList()); mEmptyBuffer.retain(&contextVk->getResourceUseList());
size_t count = (~writtenBindings).count();
VkDescriptorBufferInfo *bufferInfos = &contextVk->allocBufferInfos(count);
VkWriteDescriptorSet *writeInfos = &contextVk->allocWriteInfos(count);
size_t writeCount = 0;
for (size_t binding : ~writtenBindings) for (size_t binding : ~writtenBindings)
{ {
VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[binding]; bufferInfos[writeCount].buffer = mEmptyBuffer.getBuffer().getHandle();
VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[binding]; bufferInfos[writeCount].offset = 0;
bufferInfos[writeCount].range = VK_WHOLE_SIZE;
bufferInfo.buffer = mEmptyBuffer.getBuffer().getHandle();
bufferInfo.offset = 0; writeInfos[writeCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
bufferInfo.range = VK_WHOLE_SIZE; writeInfos[writeCount].pNext = nullptr;
writeInfos[writeCount].dstSet = descriptorSet;
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfos[writeCount].dstBinding = info.binding;
writeInfo.pNext = nullptr; writeInfos[writeCount].dstArrayElement = static_cast<uint32_t>(binding);
writeInfo.dstSet = descriptorSet; writeInfos[writeCount].descriptorCount = 1;
writeInfo.dstBinding = info.binding; writeInfos[writeCount].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writeInfo.dstArrayElement = static_cast<uint32_t>(binding); writeInfos[writeCount].pImageInfo = nullptr;
writeInfo.descriptorCount = 1; writeInfos[writeCount].pBufferInfo = &bufferInfos[writeCount];
writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; writeInfos[writeCount].pTexelBufferView = nullptr;
writeInfo.pImageInfo = nullptr; writeCount++;
writeInfo.pBufferInfo = &bufferInfo;
writeInfo.pTexelBufferView = nullptr;
} }
VkDevice device = contextVk->getDevice();
vkUpdateDescriptorSets(device, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS,
writeDescriptorInfo.data(), 0, nullptr);
} }
angle::Result ProgramExecutableVk::updateImagesDescriptorSet( angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
...@@ -1078,10 +1059,6 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1078,10 +1059,6 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
const gl::ActiveTextureArray<TextureVk *> &activeImages = contextVk->getActiveImages(); const gl::ActiveTextureArray<TextureVk *> &activeImages = contextVk->getActiveImages();
gl::ImagesArray<VkDescriptorImageInfo> descriptorImageInfo;
gl::ImagesArray<VkWriteDescriptorSet> writeDescriptorInfo;
uint32_t writeCount = 0;
// Write images. // Write images.
for (uint32_t imageIndex = 0; imageIndex < imageBindings.size(); ++imageIndex) for (uint32_t imageIndex = 0; imageIndex < imageBindings.size(); ++imageIndex)
{ {
...@@ -1117,8 +1094,8 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1117,8 +1094,8 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
// TODO(syoussefi): Support image data reinterpretation by using binding.format. // TODO(syoussefi): Support image data reinterpretation by using binding.format.
// http://anglebug.com/3563 // http://anglebug.com/3563
VkDescriptorImageInfo &imageInfo = descriptorImageInfo[writeCount]; VkDescriptorImageInfo &imageInfo = contextVk->allocImageInfo();
VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[writeCount]; VkWriteDescriptorSet &writeInfo = contextVk->allocWriteInfo();
imageInfo.sampler = VK_NULL_HANDLE; imageInfo.sampler = VK_NULL_HANDLE;
imageInfo.imageView = imageView->getHandle(); imageInfo.imageView = imageView->getHandle();
...@@ -1134,15 +1111,9 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1134,15 +1111,9 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
writeInfo.pImageInfo = &imageInfo; writeInfo.pImageInfo = &imageInfo;
writeInfo.pBufferInfo = nullptr; writeInfo.pBufferInfo = nullptr;
writeInfo.pTexelBufferView = nullptr; writeInfo.pTexelBufferView = nullptr;
++writeCount;
} }
} }
VkDevice device = contextVk->getDevice();
vkUpdateDescriptorSets(device, writeCount, writeDescriptorInfo.data(), 0, nullptr);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1267,10 +1238,6 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1267,10 +1238,6 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
VkDescriptorSet descriptorSet = mDescriptorSets[kTextureDescriptorSetIndex]; VkDescriptorSet descriptorSet = mDescriptorSets[kTextureDescriptorSetIndex];
gl::ActiveTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
gl::ActiveTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
uint32_t writeCount = 0;
const gl::ActiveTextureArray<vk::TextureUnit> &activeTextures = contextVk->getActiveTextures(); const gl::ActiveTextureArray<vk::TextureUnit> &activeTextures = contextVk->getActiveTextures();
bool emulateSeamfulCubeMapSampling = contextVk->emulateSeamfulCubeMapSampling(); bool emulateSeamfulCubeMapSampling = contextVk->emulateSeamfulCubeMapSampling();
...@@ -1312,6 +1279,8 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1312,6 +1279,8 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
mappedSamplerNameToArrayOffset[mappedSamplerName] += arraySize; mappedSamplerNameToArrayOffset[mappedSamplerName] += arraySize;
} }
VkDescriptorImageInfo *imageInfos = &contextVk->allocImageInfos(arraySize);
VkWriteDescriptorSet *writeInfos = &contextVk->allocWriteInfos(arraySize);
for (uint32_t arrayElement = 0; arrayElement < arraySize; ++arrayElement) for (uint32_t arrayElement = 0; arrayElement < arraySize; ++arrayElement)
{ {
GLuint textureUnit = samplerBinding.boundTextureUnits[arrayElement]; GLuint textureUnit = samplerBinding.boundTextureUnits[arrayElement];
...@@ -1320,26 +1289,24 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1320,26 +1289,24 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
vk::ImageHelper &image = textureVk->getImage(); vk::ImageHelper &image = textureVk->getImage();
VkDescriptorImageInfo &imageInfo = descriptorImageInfo[writeCount];
// Use bound sampler object if one present, otherwise use texture's sampler // Use bound sampler object if one present, otherwise use texture's sampler
const vk::Sampler &sampler = const vk::Sampler &sampler =
(samplerVk != nullptr) ? samplerVk->getSampler() : textureVk->getSampler(); (samplerVk != nullptr) ? samplerVk->getSampler() : textureVk->getSampler();
imageInfo.sampler = sampler.getHandle(); imageInfos[arrayElement].sampler = sampler.getHandle();
imageInfo.imageLayout = image.getCurrentLayout(); imageInfos[arrayElement].imageLayout = image.getCurrentLayout();
if (emulateSeamfulCubeMapSampling) if (emulateSeamfulCubeMapSampling)
{ {
// If emulating seamful cubemapping, use the fetch image view. This is // If emulating seamful cubemapping, use the fetch image view. This is
// basically the same image view as read, except it's a 2DArray view for // basically the same image view as read, except it's a 2DArray view for
// cube maps. // cube maps.
imageInfo.imageView = imageInfos[arrayElement].imageView =
textureVk->getFetchImageViewAndRecordUse(contextVk).getHandle(); textureVk->getFetchImageViewAndRecordUse(contextVk).getHandle();
} }
else else
{ {
imageInfo.imageView = imageInfos[arrayElement].imageView =
textureVk->getReadImageViewAndRecordUse(contextVk).getHandle(); textureVk->getReadImageViewAndRecordUse(contextVk).getHandle();
} }
...@@ -1350,30 +1317,20 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1350,30 +1317,20 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
: GlslangGetMappedSamplerName(samplerUniform.name); : GlslangGetMappedSamplerName(samplerUniform.name);
ShaderInterfaceVariableInfo &info = variableInfoMap[samplerName]; ShaderInterfaceVariableInfo &info = variableInfoMap[samplerName];
VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[writeCount]; writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfos[arrayElement].pNext = nullptr;
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfos[arrayElement].dstSet = descriptorSet;
writeInfo.pNext = nullptr; writeInfos[arrayElement].dstBinding = info.binding;
writeInfo.dstSet = descriptorSet; writeInfos[arrayElement].dstArrayElement = arrayOffset + arrayElement;
writeInfo.dstBinding = info.binding; writeInfos[arrayElement].descriptorCount = 1;
writeInfo.dstArrayElement = arrayOffset + arrayElement; writeInfos[arrayElement].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writeInfo.descriptorCount = 1; writeInfos[arrayElement].pImageInfo = &imageInfos[arrayElement];
writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; writeInfos[arrayElement].pBufferInfo = nullptr;
writeInfo.pImageInfo = &imageInfo; writeInfos[arrayElement].pTexelBufferView = nullptr;
writeInfo.pBufferInfo = nullptr;
writeInfo.pTexelBufferView = nullptr;
++writeCount;
} }
} }
} }
VkDevice device = contextVk->getDevice();
ASSERT(writeCount > 0);
vkUpdateDescriptorSets(device, writeCount, writeDescriptorInfo.data(), 0, nullptr);
mTextureDescriptorsCache.emplace(texturesDesc, descriptorSet); mTextureDescriptorsCache.emplace(texturesDesc, descriptorSet);
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -193,7 +193,7 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk, ...@@ -193,7 +193,7 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
if (!contextVk->getFeatures().emulateTransformFeedback.enabled) if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
return; return;
gl::TransformFeedbackBuffersArray<VkDescriptorBufferInfo> descriptorBufferInfo; VkDescriptorBufferInfo *descriptorBufferInfo = &contextVk->allocBufferInfos(xfbBufferCount);
for (size_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex) for (size_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{ {
...@@ -203,7 +203,7 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk, ...@@ -203,7 +203,7 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
bufferInfo.range = VK_WHOLE_SIZE; bufferInfo.range = VK_WHOLE_SIZE;
} }
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo.data(), descSet); writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo, descSet);
} }
void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
...@@ -221,7 +221,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, ...@@ -221,7 +221,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
ASSERT(programState.getTransformFeedbackBufferMode() != GL_INTERLEAVED_ATTRIBS || ASSERT(programState.getTransformFeedbackBufferMode() != GL_INTERLEAVED_ATTRIBS ||
xfbBufferCount == 1); xfbBufferCount == 1);
gl::TransformFeedbackBuffersArray<VkDescriptorBufferInfo> descriptorBufferInfo; VkDescriptorBufferInfo *descriptorBufferInfo = &contextVk->allocBufferInfos(xfbBufferCount);
// Update buffer descriptor binding info for output buffers // Update buffer descriptor binding info for output buffers
for (size_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex) for (size_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
...@@ -235,7 +235,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, ...@@ -235,7 +235,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
ASSERT(bufferInfo.range != 0); ASSERT(bufferInfo.range != 0);
} }
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo.data(), descSet); writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo, descSet);
} }
void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk, void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
...@@ -281,25 +281,22 @@ void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk, ...@@ -281,25 +281,22 @@ void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk,
VkDescriptorBufferInfo *pBufferInfo, VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorSet descSet) const VkDescriptorSet descSet) const
{ {
VkDevice device = contextVk->getDevice();
ProgramExecutableVk *executableVk = contextVk->getExecutable(); ProgramExecutableVk *executableVk = contextVk->getExecutable();
ShaderMapInterfaceVariableInfoMap variableInfoMap = ShaderMapInterfaceVariableInfoMap variableInfoMap =
executableVk->getShaderInterfaceVariableInfoMap(); executableVk->getShaderInterfaceVariableInfoMap();
const std::string bufferName = GetXfbBufferName(0); const std::string bufferName = GetXfbBufferName(0);
ShaderInterfaceVariableInfo &info = variableInfoMap[gl::ShaderType::Vertex][bufferName]; ShaderInterfaceVariableInfo &info = variableInfoMap[gl::ShaderType::Vertex][bufferName];
VkWriteDescriptorSet writeDescriptorInfo = {}; VkWriteDescriptorSet &writeDescriptorInfo = contextVk->allocWriteInfo();
writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorInfo.dstSet = descSet; writeDescriptorInfo.dstSet = descSet;
writeDescriptorInfo.dstBinding = info.binding; writeDescriptorInfo.dstBinding = info.binding;
writeDescriptorInfo.dstArrayElement = 0; writeDescriptorInfo.dstArrayElement = 0;
writeDescriptorInfo.descriptorCount = static_cast<uint32_t>(xfbBufferCount); writeDescriptorInfo.descriptorCount = static_cast<uint32_t>(xfbBufferCount);
writeDescriptorInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; writeDescriptorInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writeDescriptorInfo.pImageInfo = nullptr; writeDescriptorInfo.pImageInfo = nullptr;
writeDescriptorInfo.pBufferInfo = pBufferInfo; writeDescriptorInfo.pBufferInfo = pBufferInfo;
writeDescriptorInfo.pTexelBufferView = nullptr; writeDescriptorInfo.pTexelBufferView = nullptr;
vkUpdateDescriptorSets(device, 1, &writeDescriptorInfo, 0, nullptr);
} }
} // namespace rx } // namespace rx
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