Commit abaa3573 by Tim Van Patten Committed by Commit Bot

Vulkan: Only calculate variable locations once

Variable locations and descriptor set/binding values are calculated multiple times: - Compiling GLSL->SPIR-V - Creating the Vulkan pipeline layout - Updating descriptor sets These values should instead be calculated once and reused throughout since they won't change without recompiling the shader program. Bug: angleproject:3570 Change-Id: I5d8767b3b2e2f741aade7fec9991eea53ee2eb98 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2067101 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 10ade024
...@@ -21,20 +21,27 @@ enum class GlslangError ...@@ -21,20 +21,27 @@ enum class GlslangError
InvalidSpirv, InvalidSpirv,
}; };
constexpr gl::ShaderMap<const char *> kDefaultUniformNames = {
{gl::ShaderType::Vertex, sh::vk::kDefaultUniformsNameVS},
{gl::ShaderType::Geometry, sh::vk::kDefaultUniformsNameGS},
{gl::ShaderType::Fragment, sh::vk::kDefaultUniformsNameFS},
{gl::ShaderType::Compute, sh::vk::kDefaultUniformsNameCS},
};
struct GlslangProgramInterfaceInfo struct GlslangProgramInterfaceInfo
{ {
// Uniforms set index: // Uniforms set index:
uint32_t uniformsAndXfbDescriptorSetIndex; uint32_t uniformsAndXfbDescriptorSetIndex;
uint32_t currentUniformBindingIndex;
// Textures set index: // Textures set index:
uint32_t textureDescriptorSetIndex; uint32_t textureDescriptorSetIndex;
uint32_t currentTextureBindingIndex;
// Other shader resources set index: // Other shader resources set index:
uint32_t shaderResourceDescriptorSetIndex; uint32_t shaderResourceDescriptorSetIndex;
uint32_t currentShaderResourceBindingIndex;
// ANGLE driver uniforms set index: // ANGLE driver uniforms set index:
uint32_t driverUniformsDescriptorSetIndex; uint32_t driverUniformsDescriptorSetIndex;
// Binding index start for transform feedback buffers:
uint32_t xfbBindingIndexStart;
uint32_t locationsUsedForXfbExtension; uint32_t locationsUsedForXfbExtension;
}; };
...@@ -76,26 +83,32 @@ struct ShaderInterfaceVariableInfo ...@@ -76,26 +83,32 @@ struct ShaderInterfaceVariableInfo
uint32_t xfbStride = kInvalid; uint32_t xfbStride = kInvalid;
}; };
// TODO: http://anglebug.com/4524: Need a different hash key than a string, since
// that's slow to calculate.
using ShaderInterfaceVariableInfoMap = std::unordered_map<std::string, ShaderInterfaceVariableInfo>; using ShaderInterfaceVariableInfoMap = std::unordered_map<std::string, ShaderInterfaceVariableInfo>;
void GlslangInitialize(); void GlslangInitialize();
void GlslangRelease(); void GlslangRelease();
bool GetImageNameWithoutIndices(std::string *name);
// Get the mapped sampler name after the soure is transformed by GlslangGetShaderSource() // Get the mapped sampler name after the soure is transformed by GlslangGetShaderSource()
std::string GetMappedSamplerNameOld(const std::string &originalName);
std::string GlslangGetMappedSamplerName(const std::string &originalName); std::string GlslangGetMappedSamplerName(const std::string &originalName);
std::string GetXfbBufferName(const uint32_t bufferIndex);
// Transform the source to include actual binding points for various shader resources (textures, // Transform the source to include actual binding points for various shader resources (textures,
// buffers, xfb, etc). For some variables, these values are instead output to the variableInfoMap // buffers, xfb, etc). For some variables, these values are instead output to the variableInfoMap
// to be set during a SPIR-V transformation. This is a transitory step towards moving all variables // to be set during a SPIR-V transformation. This is a transitory step towards moving all variables
// to this map, at which point GlslangGetShaderSpirvCode will also be called by this function. // to this map, at which point GlslangGetShaderSpirvCode will also be called by this function.
void GlslangGetShaderSource(const GlslangSourceOptions &options, void GlslangGetShaderSource(GlslangSourceOptions &options,
const gl::ProgramState &programState, const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderInterfaceVariableInfoMap *variableInfoMapOut); ShaderInterfaceVariableInfoMap *variableInfoMapOut);
angle::Result GlslangGetShaderSpirvCode(GlslangErrorCallback callback, angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
......
...@@ -27,12 +27,14 @@ void ResetGlslangProgramInterfaceInfo(GlslangProgramInterfaceInfo *programInterf ...@@ -27,12 +27,14 @@ void ResetGlslangProgramInterfaceInfo(GlslangProgramInterfaceInfo *programInterf
// We don't actually use descriptor set for now, the actual binding will be done inside // We don't actually use descriptor set for now, the actual binding will be done inside
// ProgramMtl using spirv-cross. // ProgramMtl using spirv-cross.
programInterfaceInfo->uniformsAndXfbDescriptorSetIndex = kDefaultUniformsBindingIndex; programInterfaceInfo->uniformsAndXfbDescriptorSetIndex = kDefaultUniformsBindingIndex;
programInterfaceInfo->currentUniformBindingIndex = 0;
programInterfaceInfo->textureDescriptorSetIndex = 0; programInterfaceInfo->textureDescriptorSetIndex = 0;
programInterfaceInfo->currentTextureBindingIndex = 0;
programInterfaceInfo->driverUniformsDescriptorSetIndex = kDriverUniformsBindingIndex; programInterfaceInfo->driverUniformsDescriptorSetIndex = kDriverUniformsBindingIndex;
// NOTE(hqle): Unused for now, until we support ES 3.0 // NOTE(hqle): Unused for now, until we support ES 3.0
programInterfaceInfo->shaderResourceDescriptorSetIndex = -1; programInterfaceInfo->shaderResourceDescriptorSetIndex = -1;
programInterfaceInfo->xfbBindingIndexStart = -1; programInterfaceInfo->currentShaderResourceBindingIndex = 0;
programInterfaceInfo->locationsUsedForXfbExtension = 0; programInterfaceInfo->locationsUsedForXfbExtension = 0;
static_assert(kDefaultUniformsBindingIndex != 0, "kDefaultUniformsBindingIndex must not be 0"); static_assert(kDefaultUniformsBindingIndex != 0, "kDefaultUniformsBindingIndex must not be 0");
static_assert(kDriverUniformsBindingIndex != 0, "kDriverUniformsBindingIndex must not be 0"); static_assert(kDriverUniformsBindingIndex != 0, "kDriverUniformsBindingIndex must not be 0");
...@@ -50,11 +52,12 @@ void GlslangGetShaderSource(const gl::ProgramState &programState, ...@@ -50,11 +52,12 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
GlslangSourceOptions options = CreateSourceOptions();
GlslangProgramInterfaceInfo programInterfaceInfo; GlslangProgramInterfaceInfo programInterfaceInfo;
ResetGlslangProgramInterfaceInfo(&programInterfaceInfo); ResetGlslangProgramInterfaceInfo(&programInterfaceInfo);
rx::GlslangGetShaderSource(CreateSourceOptions(), programState, resources, rx::GlslangGetShaderSource(options, programState, resources, &programInterfaceInfo,
&programInterfaceInfo, shaderSourcesOut, variableInfoMapOut); shaderSourcesOut, variableInfoMapOut);
} }
angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context, angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
......
...@@ -598,6 +598,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -598,6 +598,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mVertexArray(nullptr), mVertexArray(nullptr),
mDrawFramebuffer(nullptr), mDrawFramebuffer(nullptr),
mProgram(nullptr), mProgram(nullptr),
mExecutable(nullptr),
mLastIndexBufferOffset(0), mLastIndexBufferOffset(0),
mCurrentDrawElementsType(gl::DrawElementsType::InvalidEnum), mCurrentDrawElementsType(gl::DrawElementsType::InvalidEnum),
mXfbBaseVertex(0), mXfbBaseVertex(0),
...@@ -2792,7 +2793,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -2792,7 +2793,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING: case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
break; break;
case gl::State::DIRTY_BIT_PROGRAM_BINDING: case gl::State::DIRTY_BIT_PROGRAM_BINDING:
mProgram = vk::GetImpl(glState.getProgram()); mProgram = vk::GetImpl(glState.getProgram());
mExecutable = &mProgram->getExecutable();
break; break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
{ {
......
...@@ -26,6 +26,7 @@ struct FeaturesVk; ...@@ -26,6 +26,7 @@ struct FeaturesVk;
namespace rx namespace rx
{ {
class ProgramExecutableVk;
class RendererVk; class RendererVk;
class WindowSurfaceVk; class WindowSurfaceVk;
...@@ -657,6 +658,11 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -657,6 +658,11 @@ class ContextVk : public ContextImpl, public vk::Context
size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const; size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const;
bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const; bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const;
const ProgramExecutableVk *getExecutable() const { return mExecutable; }
ProgramExecutableVk *getExecutable() { return mExecutable; }
ProgramVk *getShaderProgram(const gl::State &glState, gl::ShaderType shaderType) const;
private: private:
// Dirty bits. // Dirty bits.
enum DirtyBitType : size_t enum DirtyBitType : size_t
...@@ -950,6 +956,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -950,6 +956,7 @@ class ContextVk : public ContextImpl, public vk::Context
VertexArrayVk *mVertexArray; VertexArrayVk *mVertexArray;
FramebufferVk *mDrawFramebuffer; FramebufferVk *mDrawFramebuffer;
ProgramVk *mProgram; ProgramVk *mProgram;
ProgramExecutableVk *mExecutable;
// Graph resource used to record dispatch commands and hold resource dependencies. // Graph resource used to record dispatch commands and hold resource dependencies.
vk::DispatchHelper mDispatcher; vk::DispatchHelper mDispatcher;
......
...@@ -21,7 +21,10 @@ angle::Result ErrorHandler(vk::Context *context, GlslangError) ...@@ -21,7 +21,10 @@ angle::Result ErrorHandler(vk::Context *context, GlslangError)
return angle::Result::Stop; return angle::Result::Stop;
} }
GlslangSourceOptions CreateSourceOptions(const angle::FeaturesVk &features) } // namespace
// static
GlslangSourceOptions GlslangWrapperVk::CreateSourceOptions(const angle::FeaturesVk &features)
{ {
GlslangSourceOptions options; GlslangSourceOptions options;
...@@ -33,7 +36,6 @@ GlslangSourceOptions CreateSourceOptions(const angle::FeaturesVk &features) ...@@ -33,7 +36,6 @@ GlslangSourceOptions CreateSourceOptions(const angle::FeaturesVk &features)
return options; return options;
} }
} // namespace
// static // static
void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo( void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo(
...@@ -41,12 +43,14 @@ void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo( ...@@ -41,12 +43,14 @@ void GlslangWrapperVk::ResetGlslangProgramInterfaceInfo(
{ {
glslangProgramInterfaceInfo->uniformsAndXfbDescriptorSetIndex = glslangProgramInterfaceInfo->uniformsAndXfbDescriptorSetIndex =
kUniformsAndXfbDescriptorSetIndex; kUniformsAndXfbDescriptorSetIndex;
glslangProgramInterfaceInfo->textureDescriptorSetIndex = kTextureDescriptorSetIndex; glslangProgramInterfaceInfo->currentUniformBindingIndex = 0;
glslangProgramInterfaceInfo->textureDescriptorSetIndex = kTextureDescriptorSetIndex;
glslangProgramInterfaceInfo->currentTextureBindingIndex = 0;
glslangProgramInterfaceInfo->shaderResourceDescriptorSetIndex = glslangProgramInterfaceInfo->shaderResourceDescriptorSetIndex =
kShaderResourceDescriptorSetIndex; kShaderResourceDescriptorSetIndex;
glslangProgramInterfaceInfo->currentShaderResourceBindingIndex = 0;
glslangProgramInterfaceInfo->driverUniformsDescriptorSetIndex = glslangProgramInterfaceInfo->driverUniformsDescriptorSetIndex =
kDriverUniformsDescriptorSetIndex; kDriverUniformsDescriptorSetIndex;
glslangProgramInterfaceInfo->xfbBindingIndexStart = kXfbBindingIndexStart;
glslangProgramInterfaceInfo->locationsUsedForXfbExtension = 0; glslangProgramInterfaceInfo->locationsUsedForXfbExtension = 0;
} }
...@@ -59,8 +63,9 @@ void GlslangWrapperVk::GetShaderSource(const angle::FeaturesVk &features, ...@@ -59,8 +63,9 @@ void GlslangWrapperVk::GetShaderSource(const angle::FeaturesVk &features,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
GlslangGetShaderSource(CreateSourceOptions(features), programState, resources, GlslangSourceOptions options = CreateSourceOptions(features);
programInterfaceInfo, shaderSourcesOut, variableInfoMapOut); GlslangGetShaderSource(options, programState, resources, programInterfaceInfo, shaderSourcesOut,
variableInfoMapOut);
} }
// static // static
......
...@@ -25,6 +25,8 @@ namespace rx ...@@ -25,6 +25,8 @@ namespace rx
class GlslangWrapperVk class GlslangWrapperVk
{ {
public: public:
static GlslangSourceOptions CreateSourceOptions(const angle::FeaturesVk &features);
static void ResetGlslangProgramInterfaceInfo( static void ResetGlslangProgramInterfaceInfo(
GlslangProgramInterfaceInfo *glslangProgramInterfaceInfo); GlslangProgramInterfaceInfo *glslangProgramInterfaceInfo);
......
...@@ -44,9 +44,13 @@ class ProgramExecutableVk ...@@ -44,9 +44,13 @@ class ProgramExecutableVk
void reset(ContextVk *contextVk); void reset(ContextVk *contextVk);
void save(gl::BinaryOutputStream *stream);
std::unique_ptr<rx::LinkEvent> load(gl::BinaryInputStream *stream);
void clearVariableInfoMap(); void clearVariableInfoMap();
ShaderInterfaceVariableInfoMap &getShaderInterfaceVariableInfoMap() { return mVariableInfoMap; } ShaderInterfaceVariableInfoMap &getShaderInterfaceVariableInfoMap() { return mVariableInfoMap; }
const vk::PipelineLayout &getPipelineLayout() const { return mPipelineLayout.get(); }
angle::Result createPipelineLayout(const gl::Context *glContext, angle::Result createPipelineLayout(const gl::Context *glContext,
const gl::ProgramExecutable &glExecutable, const gl::ProgramExecutable &glExecutable,
const gl::ProgramState &programState); const gl::ProgramState &programState);
...@@ -68,19 +72,21 @@ class ProgramExecutableVk ...@@ -68,19 +72,21 @@ class ProgramExecutableVk
friend class ProgramVk; friend class ProgramVk;
friend class ProgramPipelineVk; friend class ProgramPipelineVk;
void updateBindingOffsets(const gl::ProgramState &programState);
uint32_t getUniformBlockBindingsOffset() const { return 0; }
uint32_t getStorageBlockBindingsOffset() const { return mStorageBlockBindingsOffset; }
uint32_t getAtomicCounterBufferBindingsOffset() const
{
return mAtomicCounterBufferBindingsOffset;
}
uint32_t getImageBindingsOffset() const { return mImageBindingsOffset; }
angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex); angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex);
angle::Result allocateDescriptorSetAndGetInfo(ContextVk *contextVk, angle::Result allocateDescriptorSetAndGetInfo(ContextVk *contextVk,
uint32_t descriptorSetIndex, uint32_t descriptorSetIndex,
bool *newPoolAllocatedOut); bool *newPoolAllocatedOut);
void addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> &blocks,
VkDescriptorType descType,
vk::DescriptorSetLayoutDesc *descOut);
void addAtomicCounterBufferDescriptorSetDesc(
const std::vector<gl::AtomicCounterBuffer> &atomicCounterBuffers,
vk::DescriptorSetLayoutDesc *descOut);
void addImageDescriptorSetDesc(const gl::ProgramState &programState,
vk::DescriptorSetLayoutDesc *descOut);
void addTextureDescriptorSetDesc(const gl::ProgramState &programState,
bool useOldRewriteStructSamplers,
vk::DescriptorSetLayoutDesc *descOut);
void updateDefaultUniformsDescriptorSet( void updateDefaultUniformsDescriptorSet(
const gl::ProgramState &programState, const gl::ProgramState &programState,
...@@ -100,13 +106,6 @@ class ProgramExecutableVk ...@@ -100,13 +106,6 @@ class ProgramExecutableVk
angle::Result updateImagesDescriptorSet(const gl::ProgramState &programState, angle::Result updateImagesDescriptorSet(const gl::ProgramState &programState,
ContextVk *contextVk); ContextVk *contextVk);
// In their descriptor set, uniform buffers are placed first, then storage buffers, then atomic
// counter buffers and then images. These cached values contain the offsets where storage
// buffer, atomic counter buffer and image bindings start.
uint32_t mStorageBlockBindingsOffset;
uint32_t mAtomicCounterBufferBindingsOffset;
uint32_t mImageBindingsOffset;
// This is a special "empty" placeholder buffer for when a shader has no uniforms or doesn't // This is a special "empty" placeholder buffer for when a shader has no uniforms or doesn't
// use all slots in the atomic counter buffer array. // use all slots in the atomic counter buffer array.
// //
...@@ -118,6 +117,7 @@ class ProgramExecutableVk ...@@ -118,6 +117,7 @@ class ProgramExecutableVk
std::vector<VkDescriptorSet> mDescriptorSets; std::vector<VkDescriptorSet> mDescriptorSets;
vk::DescriptorSetLayoutArray<VkDescriptorSet> mEmptyDescriptorSets; vk::DescriptorSetLayoutArray<VkDescriptorSet> mEmptyDescriptorSets;
std::vector<vk::BufferHelper *> mDescriptorBuffersCache; std::vector<vk::BufferHelper *> mDescriptorBuffersCache;
size_t mNumDefaultUniformDescriptors;
std::unordered_map<vk::TextureDescriptorDesc, VkDescriptorSet> mTextureDescriptorsCache; std::unordered_map<vk::TextureDescriptorDesc, VkDescriptorSet> mTextureDescriptorsCache;
...@@ -137,6 +137,8 @@ class ProgramExecutableVk ...@@ -137,6 +137,8 @@ class ProgramExecutableVk
gl::ShaderVector<uint32_t> mDynamicBufferOffsets; gl::ShaderVector<uint32_t> mDynamicBufferOffsets;
// TODO: http://anglebug.com/4524: Need a different hash key than a string,
// since that's slow to calculate.
ShaderInterfaceVariableInfoMap mVariableInfoMap; ShaderInterfaceVariableInfoMap mVariableInfoMap;
}; };
......
...@@ -303,6 +303,7 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context, ...@@ -303,6 +303,7 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context,
reset(contextVk); reset(contextVk);
mShaderInfo.load(stream); mShaderInfo.load(stream);
mExecutable.load(stream);
// Deserializes the uniformLayout data of mDefaultUniformBlocks // Deserializes the uniformLayout data of mDefaultUniformBlocks
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
...@@ -337,6 +338,7 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context, ...@@ -337,6 +338,7 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context,
void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream) void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{ {
mShaderInfo.save(stream); mShaderInfo.save(stream);
mExecutable.save(stream);
// Serializes the uniformLayout data of mDefaultUniformBlocks // Serializes the uniformLayout data of mDefaultUniformBlocks
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
...@@ -378,6 +380,7 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context, ...@@ -378,6 +380,7 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
linkResources(resources); linkResources(resources);
reset(contextVk); reset(contextVk);
mExecutable.clearVariableInfoMap();
// Gather variable info and transform sources. // Gather variable info and transform sources.
gl::ShaderMap<std::string> shaderSources; gl::ShaderMap<std::string> shaderSources;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Query.h" #include "libANGLE/Query.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/BufferVk.h" #include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h" #include "libANGLE/renderer/vulkan/FramebufferVk.h"
...@@ -161,6 +162,7 @@ angle::Result TransformFeedbackVk::bindIndexedBuffer( ...@@ -161,6 +162,7 @@ angle::Result TransformFeedbackVk::bindIndexedBuffer(
void TransformFeedbackVk::updateDescriptorSetLayout( void TransformFeedbackVk::updateDescriptorSetLayout(
ContextVk *contextVk, ContextVk *contextVk,
ShaderInterfaceVariableInfoMap &vsVariableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const vk::DescriptorSetLayoutDesc *descSetLayoutOut) const
{ {
...@@ -169,8 +171,11 @@ void TransformFeedbackVk::updateDescriptorSetLayout( ...@@ -169,8 +171,11 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex) for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{ {
descSetLayoutOut->update(kXfbBindingIndexStart + bufferIndex, const std::string bufferName = GetXfbBufferName(bufferIndex);
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT); const ShaderInterfaceVariableInfo &info = vsVariableInfoMap[bufferName];
descSetLayoutOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
VK_SHADER_STAGE_VERTEX_BIT);
} }
} }
...@@ -296,12 +301,17 @@ void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk, ...@@ -296,12 +301,17 @@ void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk,
VkDescriptorBufferInfo *pBufferInfo, VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorSet descSet) const VkDescriptorSet descSet) const
{ {
VkDevice device = contextVk->getDevice(); VkDevice device = contextVk->getDevice();
ProgramExecutableVk *executableVk = contextVk->getExecutable();
ShaderInterfaceVariableInfoMap variableInfoMap =
executableVk->getShaderInterfaceVariableInfoMap();
const std::string bufferName = GetXfbBufferName(0);
ShaderInterfaceVariableInfo &info = variableInfoMap[bufferName];
VkWriteDescriptorSet writeDescriptorInfo = {}; VkWriteDescriptorSet writeDescriptorInfo = {};
writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorInfo.dstSet = descSet; writeDescriptorInfo.dstSet = descSet;
writeDescriptorInfo.dstBinding = kXfbBindingIndexStart; 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;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#define LIBANGLE_RENDERER_VULKAN_TRANSFORMFEEDBACKVK_H_ #define LIBANGLE_RENDERER_VULKAN_TRANSFORMFEEDBACKVK_H_
#include "libANGLE/renderer/TransformFeedbackImpl.h" #include "libANGLE/renderer/TransformFeedbackImpl.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h" #include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace gl namespace gl
...@@ -54,6 +56,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl ...@@ -54,6 +56,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl
const gl::OffsetBindingPointer<gl::Buffer> &binding) override; const gl::OffsetBindingPointer<gl::Buffer> &binding) override;
void updateDescriptorSetLayout(ContextVk *contextVk, void updateDescriptorSetLayout(ContextVk *contextVk,
ShaderInterfaceVariableInfoMap &vsVariableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const; vk::DescriptorSetLayoutDesc *descSetLayoutOut) const;
void initDescriptorSet(ContextVk *contextVk, void initDescriptorSet(ContextVk *contextVk,
......
...@@ -977,8 +977,6 @@ constexpr uint32_t kReservedDriverUniformBindingCount = 1; ...@@ -977,8 +977,6 @@ constexpr uint32_t kReservedDriverUniformBindingCount = 1;
// supported. // supported.
constexpr uint32_t kReservedPerStageDefaultUniformBindingCount = 1; constexpr uint32_t kReservedPerStageDefaultUniformBindingCount = 1;
constexpr uint32_t kReservedDefaultUniformBindingCount = 3; constexpr uint32_t kReservedDefaultUniformBindingCount = 3;
// Binding index start for transform feedback buffers:
constexpr uint32_t kXfbBindingIndexStart = kReservedDefaultUniformBindingCount;
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_ #endif // LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_
...@@ -3998,6 +3998,12 @@ TEST_P(TextureLimitsTest, MaxFragmentTextures) ...@@ -3998,6 +3998,12 @@ TEST_P(TextureLimitsTest, MaxFragmentTextures)
// Test rendering with maximum combined texture units. // Test rendering with maximum combined texture units.
TEST_P(TextureLimitsTest, MaxCombinedTextures) TEST_P(TextureLimitsTest, MaxCombinedTextures)
{ {
// TODO(timvp): http://anglebug.com/3570
// Currently only fails on SwiftShader but we don't have an IsSwiftShader().
// max per-stage sampled image bindings count (32) exceeds device
// maxPerStageDescriptorSampledImages limit (16)
ANGLE_SKIP_TEST_IF(IsVulkan());
GLint vertexTextures = mMaxVertexTextures; GLint vertexTextures = mMaxVertexTextures;
if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures) if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
......
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