Commit 29fba5e0 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Prepare for variable-stage pipelines

Compute (single-stage pipeline) is upcoming, but this change prepares GlslangWrapper to handle any number of stages (mostly). Additionally, this change binds each resource to each stage based on whether it's active, so that we don't hit the per-stage limit of resources by binding every resource to every stage. Bug: angleproject:3633 Bug: angleproject:3562 Change-Id: Ifebf691482846e0371c6e314f514226a4cfee258 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1689330Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent a1754dc8
...@@ -722,6 +722,18 @@ void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block) ...@@ -722,6 +722,18 @@ void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block)
LoadShaderVariableBuffer(stream, block); LoadShaderVariableBuffer(stream, block);
} }
size_t CountUniqueBlocks(const std::vector<InterfaceBlock> &blocks)
{
size_t count = 0;
for (const InterfaceBlock &block : blocks)
{
if (!block.isArray || block.arrayElement == 0)
{
++count;
}
}
return count;
}
} // anonymous namespace } // anonymous namespace
// Saves the linking context for later use in resolveLink(). // Saves the linking context for later use in resolveLink().
...@@ -955,7 +967,7 @@ ImageBinding::~ImageBinding() = default; ...@@ -955,7 +967,7 @@ ImageBinding::~ImageBinding() = default;
// ProgramState implementation. // ProgramState implementation.
ProgramState::ProgramState() ProgramState::ProgramState()
: mLabel(), : mLabel(),
mAttachedShaders({}), mAttachedShaders{},
mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS), mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
mMaxActiveAttribLocation(0), mMaxActiveAttribLocation(0),
mSamplerUniformRange(0, 0), mSamplerUniformRange(0, 0),
...@@ -991,6 +1003,16 @@ Shader *ProgramState::getAttachedShader(ShaderType shaderType) const ...@@ -991,6 +1003,16 @@ Shader *ProgramState::getAttachedShader(ShaderType shaderType) const
return mAttachedShaders[shaderType]; return mAttachedShaders[shaderType];
} }
size_t ProgramState::getUniqueUniformBlockCount() const
{
return CountUniqueBlocks(mUniformBlocks);
}
size_t ProgramState::getUniqueStorageBlockCount() const
{
return CountUniqueBlocks(mShaderStorageBlocks);
}
GLuint ProgramState::getUniformIndexFromName(const std::string &name) const GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
{ {
return GetResourceIndexFromName(mUniforms, name); return GetResourceIndexFromName(mUniforms, name);
...@@ -1029,6 +1051,12 @@ GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const ...@@ -1029,6 +1051,12 @@ GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
return uniformIndex - mSamplerUniformRange.low(); return uniformIndex - mSamplerUniformRange.low();
} }
GLuint ProgramState::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
{
ASSERT(samplerIndex < mSamplerUniformRange.length());
return samplerIndex + mSamplerUniformRange.low();
}
bool ProgramState::isImageUniformIndex(GLuint index) const bool ProgramState::isImageUniformIndex(GLuint index) const
{ {
return mImageUniformRange.contains(index); return mImageUniformRange.contains(index);
...@@ -1040,6 +1068,12 @@ GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const ...@@ -1040,6 +1068,12 @@ GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const
return uniformIndex - mImageUniformRange.low(); return uniformIndex - mImageUniformRange.low();
} }
GLuint ProgramState::getUniformIndexFromImageIndex(GLuint imageIndex) const
{
ASSERT(imageIndex < mImageUniformRange.length());
return imageIndex + mImageUniformRange.low();
}
GLuint ProgramState::getAttributeLocation(const std::string &name) const GLuint ProgramState::getAttributeLocation(const std::string &name) const
{ {
for (const sh::Attribute &attribute : mAttributes) for (const sh::Attribute &attribute : mAttributes)
...@@ -1433,6 +1467,8 @@ angle::Result Program::link(const Context *context) ...@@ -1433,6 +1467,8 @@ angle::Result Program::link(const Context *context)
mState.updateTransformFeedbackStrides(); mState.updateTransformFeedbackStrides();
} }
updateLinkedShaderStages();
mLinkingState.reset(new LinkingState()); mLinkingState.reset(new LinkingState());
mLinkingState->context = context; mLinkingState->context = context;
mLinkingState->linkingFromBinary = false; mLinkingState->linkingFromBinary = false;
...@@ -1474,7 +1510,6 @@ void Program::resolveLinkImpl(const Context *context) ...@@ -1474,7 +1510,6 @@ void Program::resolveLinkImpl(const Context *context)
// According to GLES 3.0/3.1 spec for LinkProgram and UseProgram, // According to GLES 3.0/3.1 spec for LinkProgram and UseProgram,
// Only successfully linked program can replace the executables. // Only successfully linked program can replace the executables.
ASSERT(mLinked); ASSERT(mLinked);
updateLinkedShaderStages();
// Mark implementation-specific unreferenced uniforms as ignored. // Mark implementation-specific unreferenced uniforms as ignored.
mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings, mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings,
......
...@@ -359,13 +359,19 @@ class ProgramState final : angle::NonCopyable ...@@ -359,13 +359,19 @@ class ProgramState final : angle::NonCopyable
return mAtomicCounterBuffers; return mAtomicCounterBuffers;
} }
// Count the number of uniform and storage buffer declarations, counting arrays as one.
size_t getUniqueUniformBlockCount() const;
size_t getUniqueStorageBlockCount() const;
GLuint getUniformIndexFromName(const std::string &name) const; GLuint getUniformIndexFromName(const std::string &name) const;
GLuint getUniformIndexFromLocation(GLint location) const; GLuint getUniformIndexFromLocation(GLint location) const;
Optional<GLuint> getSamplerIndex(GLint location) const; Optional<GLuint> getSamplerIndex(GLint location) const;
bool isSamplerUniformIndex(GLuint index) const; bool isSamplerUniformIndex(GLuint index) const;
GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
bool isImageUniformIndex(GLuint index) const; bool isImageUniformIndex(GLuint index) const;
GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const; GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const;
GLuint getAttributeLocation(const std::string &name) const; GLuint getAttributeLocation(const std::string &name) const;
GLuint getBufferVariableIndexFromName(const std::string &name) const; GLuint getBufferVariableIndexFromName(const std::string &name) const;
...@@ -374,6 +380,11 @@ class ProgramState final : angle::NonCopyable ...@@ -374,6 +380,11 @@ class ProgramState final : angle::NonCopyable
bool usesMultiview() const { return mNumViews != -1; } bool usesMultiview() const { return mNumViews != -1; }
const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; }
bool hasLinkedShaderStage(ShaderType shaderType) const
{
return mLinkedShaderStages.test(shaderType);
}
size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); }
bool hasAttachedShader() const; bool hasAttachedShader() const;
......
...@@ -410,7 +410,7 @@ class FlattenUniformVisitor : public sh::VariableNameVisitor ...@@ -410,7 +410,7 @@ class FlattenUniformVisitor : public sh::VariableNameVisitor
bool isSampler = IsSamplerType(variable.type); bool isSampler = IsSamplerType(variable.type);
bool isImage = IsImageType(variable.type); bool isImage = IsImageType(variable.type);
bool isAtomicCounter = IsAtomicCounterType(variable.type); bool isAtomicCounter = IsAtomicCounterType(variable.type);
std::vector<gl::LinkedUniform> *uniformList = mUniforms; std::vector<LinkedUniform> *uniformList = mUniforms;
if (isSampler) if (isSampler)
{ {
uniformList = mSamplerUniforms; uniformList = mSamplerUniforms;
...@@ -618,7 +618,7 @@ bool InterfaceBlockInfo::getBlockSize(const std::string &name, ...@@ -618,7 +618,7 @@ bool InterfaceBlockInfo::getBlockSize(const std::string &name,
size_t *sizeOut) size_t *sizeOut)
{ {
size_t nameLengthWithoutArrayIndex; size_t nameLengthWithoutArrayIndex;
gl::ParseArrayIndex(name, &nameLengthWithoutArrayIndex); ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex); std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
auto sizeIter = mBlockSizes.find(baseName); auto sizeIter = mBlockSizes.find(baseName);
if (sizeIter == mBlockSizes.end()) if (sizeIter == mBlockSizes.end())
...@@ -699,7 +699,7 @@ bool UniformLinker::validateGraphicsUniforms(InfoLog &infoLog) const ...@@ -699,7 +699,7 @@ bool UniformLinker::validateGraphicsUniforms(InfoLog &infoLog) const
// Check that uniforms defined in the graphics shaders are identical // Check that uniforms defined in the graphics shaders are identical
std::map<std::string, ShaderUniform> linkedUniforms; std::map<std::string, ShaderUniform> linkedUniforms;
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (const ShaderType shaderType : kAllGraphicsShaderTypes)
{ {
Shader *currentShader = mState.getAttachedShader(shaderType); Shader *currentShader = mState.getAttachedShader(shaderType);
if (currentShader) if (currentShader)
...@@ -988,7 +988,7 @@ bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoL ...@@ -988,7 +988,7 @@ bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoL
std::vector<LinkedUniform> atomicCounterUniforms; std::vector<LinkedUniform> atomicCounterUniforms;
std::vector<UnusedUniform> unusedUniforms; std::vector<UnusedUniform> unusedUniforms;
for (ShaderType shaderType : AllShaderTypes()) for (const ShaderType shaderType : AllShaderTypes())
{ {
Shader *shader = mState.getAttachedShader(shaderType); Shader *shader = mState.getAttachedShader(shaderType);
if (!shader) if (!shader)
...@@ -1050,7 +1050,7 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSizeFunc &getBlockSize, ...@@ -1050,7 +1050,7 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSizeFunc &getBlockSize,
std::set<std::string> visitedList; std::set<std::string> visitedList;
for (ShaderType shaderType : AllShaderTypes()) for (const ShaderType shaderType : AllShaderTypes())
{ {
if (!mShaderBlocks[shaderType]) if (!mShaderBlocks[shaderType])
{ {
...@@ -1242,14 +1242,14 @@ ProgramLinkedResources::ProgramLinkedResources( ...@@ -1242,14 +1242,14 @@ ProgramLinkedResources::ProgramLinkedResources(
ProgramLinkedResources::~ProgramLinkedResources() = default; ProgramLinkedResources::~ProgramLinkedResources() = default;
void ProgramLinkedResourcesLinker::linkResources(const gl::ProgramState &programState, void ProgramLinkedResourcesLinker::linkResources(const ProgramState &programState,
const gl::ProgramLinkedResources &resources) const const ProgramLinkedResources &resources) const
{ {
// Gather uniform interface block info. // Gather uniform interface block info.
InterfaceBlockInfo uniformBlockInfo(mCustomEncoderFactory); InterfaceBlockInfo uniformBlockInfo(mCustomEncoderFactory);
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (const ShaderType shaderType : AllShaderTypes())
{ {
gl::Shader *shader = programState.getAttachedShader(shaderType); Shader *shader = programState.getAttachedShader(shaderType);
if (shader) if (shader)
{ {
uniformBlockInfo.getShaderBlockInfo(shader->getUniformBlocks()); uniformBlockInfo.getShaderBlockInfo(shader->getUniformBlocks());
...@@ -1272,9 +1272,9 @@ void ProgramLinkedResourcesLinker::linkResources(const gl::ProgramState &program ...@@ -1272,9 +1272,9 @@ void ProgramLinkedResourcesLinker::linkResources(const gl::ProgramState &program
// Gather storage bufer interface block info. // Gather storage bufer interface block info.
InterfaceBlockInfo shaderStorageBlockInfo(mCustomEncoderFactory); InterfaceBlockInfo shaderStorageBlockInfo(mCustomEncoderFactory);
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (const ShaderType shaderType : AllShaderTypes())
{ {
gl::Shader *shader = programState.getAttachedShader(shaderType); Shader *shader = programState.getAttachedShader(shaderType);
if (shader) if (shader)
{ {
shaderStorageBlockInfo.getShaderBlockInfo(shader->getShaderStorageBlocks()); shaderStorageBlockInfo.getShaderBlockInfo(shader->getShaderStorageBlocks());
...@@ -1303,12 +1303,12 @@ void ProgramLinkedResourcesLinker::linkResources(const gl::ProgramState &program ...@@ -1303,12 +1303,12 @@ void ProgramLinkedResourcesLinker::linkResources(const gl::ProgramState &program
} }
void ProgramLinkedResourcesLinker::getAtomicCounterBufferSizeMap( void ProgramLinkedResourcesLinker::getAtomicCounterBufferSizeMap(
const gl::ProgramState &programState, const ProgramState &programState,
std::map<int, unsigned int> &sizeMapOut) const std::map<int, unsigned int> &sizeMapOut) const
{ {
for (unsigned int index : programState.getAtomicCounterUniformRange()) for (unsigned int index : programState.getAtomicCounterUniformRange())
{ {
const gl::LinkedUniform &glUniform = programState.getUniforms()[index]; const LinkedUniform &glUniform = programState.getUniforms()[index];
auto &bufferDataSize = sizeMapOut[glUniform.binding]; auto &bufferDataSize = sizeMapOut[glUniform.binding];
......
...@@ -232,11 +232,11 @@ class ProgramLinkedResourcesLinker final : angle::NonCopyable ...@@ -232,11 +232,11 @@ class ProgramLinkedResourcesLinker final : angle::NonCopyable
: mCustomEncoderFactory(customEncoderFactory) : mCustomEncoderFactory(customEncoderFactory)
{} {}
void linkResources(const gl::ProgramState &programState, void linkResources(const ProgramState &programState,
const gl::ProgramLinkedResources &resources) const; const ProgramLinkedResources &resources) const;
private: private:
void getAtomicCounterBufferSizeMap(const gl::ProgramState &programState, void getAtomicCounterBufferSizeMap(const ProgramState &programState,
std::map<int, unsigned int> &sizeMapOut) const; std::map<int, unsigned int> &sizeMapOut) const;
CustomBlockLayoutEncoderFactory *mCustomEncoderFactory; CustomBlockLayoutEncoderFactory *mCustomEncoderFactory;
......
...@@ -26,12 +26,6 @@ void ActiveVariable::setActive(ShaderType shaderType, bool used) ...@@ -26,12 +26,6 @@ void ActiveVariable::setActive(ShaderType shaderType, bool used)
mActiveUseBits.set(shaderType, used); mActiveUseBits.set(shaderType, used);
} }
bool ActiveVariable::isActive(ShaderType shaderType) const
{
ASSERT(shaderType != ShaderType::InvalidEnum);
return mActiveUseBits[shaderType];
}
void ActiveVariable::unionReferencesWith(const ActiveVariable &other) void ActiveVariable::unionReferencesWith(const ActiveVariable &other)
{ {
mActiveUseBits |= other.mActiveUseBits; mActiveUseBits |= other.mActiveUseBits;
......
...@@ -31,7 +31,12 @@ struct ActiveVariable ...@@ -31,7 +31,12 @@ struct ActiveVariable
ShaderType getFirstShaderTypeWhereActive() const; ShaderType getFirstShaderTypeWhereActive() const;
void setActive(ShaderType shaderType, bool used); void setActive(ShaderType shaderType, bool used);
void unionReferencesWith(const ActiveVariable &other); void unionReferencesWith(const ActiveVariable &other);
bool isActive(ShaderType shaderType) const; bool isActive(ShaderType shaderType) const
{
ASSERT(shaderType != ShaderType::InvalidEnum);
return mActiveUseBits[shaderType];
}
ShaderBitSet activeShaders() const { return mActiveUseBits; }
GLuint activeShaderCount() const; GLuint activeShaderCount() const;
private: private:
......
...@@ -444,6 +444,11 @@ constexpr size_t kCubeFaceCount = 6; ...@@ -444,6 +444,11 @@ constexpr size_t kCubeFaceCount = 6;
using TextureMap = angle::PackedEnumMap<TextureType, BindingPointer<Texture>>; using TextureMap = angle::PackedEnumMap<TextureType, BindingPointer<Texture>>;
// ShaderVector can contain one item per shader. It differs from ShaderMap in that the values are
// not indexed by ShaderType.
template <typename T>
using ShaderVector = angle::FixedVector<T, static_cast<size_t>(ShaderType::EnumCount)>;
template <typename T> template <typename T>
using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>; using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
......
...@@ -182,11 +182,9 @@ class ProgramVk : public ProgramImpl ...@@ -182,11 +182,9 @@ class ProgramVk : public ProgramImpl
angle::Result linkImpl(const gl::Context *glContext, gl::InfoLog &infoLog); angle::Result linkImpl(const gl::Context *glContext, gl::InfoLog &infoLog);
void linkResources(const gl::ProgramLinkedResources &resources); void linkResources(const gl::ProgramLinkedResources &resources);
uint32_t getUniformBuffersBindingStart() const { return 0; } void updateBindingOffsets();
uint32_t getStorageBuffersBindingStart() const uint32_t getUniformBlockBindingsOffset() const { return 0; }
{ uint32_t getStorageBlockBindingsOffset() const { return mStorageBlockBindingsOffset; }
return static_cast<uint32_t>(mState.getUniformBlocks().size());
}
ANGLE_INLINE angle::Result initShaders(ContextVk *contextVk, ANGLE_INLINE angle::Result initShaders(ContextVk *contextVk,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
...@@ -233,10 +231,7 @@ class ProgramVk : public ProgramImpl ...@@ -233,10 +231,7 @@ class ProgramVk : public ProgramImpl
gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks; gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
gl::ShaderBitSet mDefaultUniformBlocksDirty; gl::ShaderBitSet mDefaultUniformBlocksDirty;
static constexpr uint32_t kShaderTypeMin = static_cast<uint32_t>(gl::kGLES2ShaderTypeMin); gl::ShaderVector<uint32_t> mDynamicBufferOffsets;
static constexpr uint32_t kShaderTypeMax = static_cast<uint32_t>(gl::kGLES2ShaderTypeMax);
static constexpr uint32_t kShaderTypeCount = kShaderTypeMax - kShaderTypeMin + 1;
std::array<uint32_t, kShaderTypeCount> mDynamicBufferOffsets;
// This is a special "empty" placeholder buffer for when a shader has no uniforms. // This is a special "empty" placeholder buffer for when a shader has no uniforms.
// It is necessary because we want to keep a compatible pipeline layout in all cases, // It is necessary because we want to keep a compatible pipeline layout in all cases,
...@@ -285,6 +280,10 @@ class ProgramVk : public ProgramImpl ...@@ -285,6 +280,10 @@ class ProgramVk : public ProgramImpl
// We keep the translated linked shader sources to use with shader draw call patching. // We keep the translated linked shader sources to use with shader draw call patching.
gl::ShaderMap<std::string> mShaderSource; gl::ShaderMap<std::string> mShaderSource;
// Storage buffers are placed after uniform buffers in their descriptor set. This cached value
// contains the offset where storage buffer bindings start.
uint32_t mStorageBlockBindingsOffset;
// Store descriptor pools here. We store the descriptors in the Program to facilitate descriptor // Store descriptor pools here. We store the descriptors in the Program to facilitate descriptor
// cache management. It can also allow fewer descriptors for shaders which use fewer // cache management. It can also allow fewer descriptors for shaders which use fewer
// textures/buffers. // textures/buffers.
......
...@@ -47,9 +47,6 @@ namespace rx ...@@ -47,9 +47,6 @@ namespace rx
namespace namespace
{ {
// We currently only allocate 2 uniform buffer per descriptor set, one for the fragment shader and
// one for the vertex shader.
constexpr size_t kUniformBufferDescriptorsPerDescriptorSet = 2;
// Update the pipeline cache every this many swaps (if 60fps, this means every 10 minutes) // Update the pipeline cache every this many swaps (if 60fps, this means every 10 minutes)
constexpr uint32_t kPipelineCacheVkUpdatePeriod = 10 * 60 * 60; constexpr uint32_t kPipelineCacheVkUpdatePeriod = 10 * 60 * 60;
// Wait a maximum of 10s. If that times out, we declare it a failure. // Wait a maximum of 10s. If that times out, we declare it a failure.
...@@ -1322,25 +1319,6 @@ const gl::Limitations &RendererVk::getNativeLimitations() const ...@@ -1322,25 +1319,6 @@ const gl::Limitations &RendererVk::getNativeLimitations() const
return mNativeLimitations; return mNativeLimitations;
} }
uint32_t RendererVk::getMaxUniformBlocks() const
{
return std::min<uint32_t>(mPhysicalDeviceProperties.limits.maxDescriptorSetUniformBuffers,
gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
}
uint32_t RendererVk::getMaxStorageBlocks() const
{
return std::min<uint32_t>(mPhysicalDeviceProperties.limits.maxDescriptorSetStorageBuffers,
gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
}
uint32_t RendererVk::getMaxActiveTextures() const
{
// TODO(lucferron): expose this limitation to GL in Context Caps
return std::min<uint32_t>(mPhysicalDeviceProperties.limits.maxDescriptorSetSamplers,
gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
}
angle::Result RendererVk::getDescriptorSetLayout( angle::Result RendererVk::getDescriptorSetLayout(
vk::Context *context, vk::Context *context,
const vk::DescriptorSetLayoutDesc &desc, const vk::DescriptorSetLayoutDesc &desc,
...@@ -1575,9 +1553,4 @@ angle::Result RendererVk::cleanupGarbage(vk::Context *context, bool block) ...@@ -1575,9 +1553,4 @@ angle::Result RendererVk::cleanupGarbage(vk::Context *context, bool block)
return angle::Result::Continue; return angle::Result::Continue;
} }
uint32_t GetUniformBufferDescriptorCount()
{
return kUniformBufferDescriptorsPerDescriptorSet;
}
} // namespace rx } // namespace rx
...@@ -85,9 +85,6 @@ class RendererVk : angle::NonCopyable ...@@ -85,9 +85,6 @@ class RendererVk : angle::NonCopyable
const gl::TextureCapsMap &getNativeTextureCaps() const; const gl::TextureCapsMap &getNativeTextureCaps() const;
const gl::Extensions &getNativeExtensions() const; const gl::Extensions &getNativeExtensions() const;
const gl::Limitations &getNativeLimitations() const; const gl::Limitations &getNativeLimitations() const;
uint32_t getMaxUniformBlocks() const;
uint32_t getMaxStorageBlocks() const;
uint32_t getMaxActiveTextures() const;
uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; } uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
...@@ -233,8 +230,6 @@ class RendererVk : angle::NonCopyable ...@@ -233,8 +230,6 @@ class RendererVk : angle::NonCopyable
DescriptorSetLayoutCache mDescriptorSetLayoutCache; DescriptorSetLayoutCache mDescriptorSetLayoutCache;
}; };
uint32_t GetUniformBufferDescriptorCount();
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_ #endif // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
...@@ -135,8 +135,7 @@ void TransformFeedbackVk::addFramebufferDependency(ContextVk *contextVk, ...@@ -135,8 +135,7 @@ void TransformFeedbackVk::addFramebufferDependency(ContextVk *contextVk,
void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState, const gl::ProgramState &programState,
VkDescriptorSet descSet, VkDescriptorSet descSet) const
uint32_t bindingOffset) const
{ {
const std::vector<gl::OffsetBindingPointer<gl::Buffer>> &xfbBuffers = const std::vector<gl::OffsetBindingPointer<gl::Buffer>> &xfbBuffers =
mState.getIndexedBuffers(); mState.getIndexedBuffers();
...@@ -171,7 +170,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, ...@@ -171,7 +170,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
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 = bindingOffset; writeDescriptorInfo.dstBinding = kXfbBindingIndexStart;
writeDescriptorInfo.dstArrayElement = 0; writeDescriptorInfo.dstArrayElement = 0;
writeDescriptorInfo.descriptorCount = xfbBufferCount; writeDescriptorInfo.descriptorCount = xfbBufferCount;
writeDescriptorInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; writeDescriptorInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
......
...@@ -47,8 +47,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl ...@@ -47,8 +47,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl
vk::FramebufferHelper *framebuffer) const; vk::FramebufferHelper *framebuffer) const;
void updateDescriptorSet(ContextVk *contextVk, void updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState, const gl::ProgramState &programState,
VkDescriptorSet descSet, VkDescriptorSet descSet) const;
uint32_t bindingOffset) const;
void getBufferOffsets(ContextVk *contextVk, void getBufferOffsets(ContextVk *contextVk,
const gl::ProgramState &programState, const gl::ProgramState &programState,
GLint drawCallFirstVertex, GLint drawCallFirstVertex,
......
...@@ -1429,7 +1429,7 @@ void PipelineLayoutDesc::updatePushConstantRange(gl::ShaderType shaderType, ...@@ -1429,7 +1429,7 @@ void PipelineLayoutDesc::updatePushConstantRange(gl::ShaderType shaderType,
{ {
ASSERT(shaderType == gl::ShaderType::Vertex || shaderType == gl::ShaderType::Fragment || ASSERT(shaderType == gl::ShaderType::Vertex || shaderType == gl::ShaderType::Fragment ||
shaderType == gl::ShaderType::Compute); shaderType == gl::ShaderType::Compute);
PackedPushConstantRange &packed = mPushConstantRanges[static_cast<size_t>(shaderType)]; PackedPushConstantRange &packed = mPushConstantRanges[shaderType];
packed.offset = offset; packed.offset = offset;
packed.size = size; packed.size = size;
} }
...@@ -1770,30 +1770,22 @@ angle::Result PipelineLayoutCache::getPipelineLayout( ...@@ -1770,30 +1770,22 @@ angle::Result PipelineLayoutCache::getPipelineLayout(
} }
} }
angle::FixedVector<VkPushConstantRange, vk::kMaxPushConstantRanges> pushConstantRanges;
const vk::PushConstantRangeArray<vk::PackedPushConstantRange> &descPushConstantRanges = const vk::PushConstantRangeArray<vk::PackedPushConstantRange> &descPushConstantRanges =
desc.getPushConstantRanges(); desc.getPushConstantRanges();
for (size_t shaderIndex = 0; shaderIndex < descPushConstantRanges.size(); ++shaderIndex)
gl::ShaderVector<VkPushConstantRange> pushConstantRanges;
for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
const vk::PackedPushConstantRange &pushConstantDesc = descPushConstantRanges[shaderIndex]; const vk::PackedPushConstantRange &pushConstantDesc = descPushConstantRanges[shaderType];
if (pushConstantDesc.size > 0) if (pushConstantDesc.size > 0)
{ {
static constexpr VkShaderStageFlagBits kShaderStages[vk::kMaxPushConstantRanges] = { VkPushConstantRange range;
VK_SHADER_STAGE_VERTEX_BIT, range.stageFlags = gl_vk::kShaderStageMap[shaderType];
VK_SHADER_STAGE_FRAGMENT_BIT, range.offset = pushConstantDesc.offset;
VK_SHADER_STAGE_GEOMETRY_BIT, range.size = pushConstantDesc.size;
VK_SHADER_STAGE_COMPUTE_BIT,
}; pushConstantRanges.push_back(range);
static_assert(static_cast<uint32_t>(gl::ShaderType::Vertex) == 0, "Fix this table");
static_assert(static_cast<uint32_t>(gl::ShaderType::Fragment) == 1, "Fix this table");
static_assert(static_cast<uint32_t>(gl::ShaderType::Geometry) == 2, "Fix this table");
static_assert(static_cast<uint32_t>(gl::ShaderType::Compute) == 3, "Fix this table");
VkPushConstantRange pushConstantRange = {};
pushConstantRange.stageFlags = kShaderStages[shaderIndex];
pushConstantRange.offset = pushConstantDesc.offset;
pushConstantRange.size = pushConstantDesc.size;
pushConstantRanges.push_back(pushConstantRange);
} }
} }
...@@ -1803,7 +1795,7 @@ angle::Result PipelineLayoutCache::getPipelineLayout( ...@@ -1803,7 +1795,7 @@ angle::Result PipelineLayoutCache::getPipelineLayout(
createInfo.flags = 0; createInfo.flags = 0;
createInfo.setLayoutCount = static_cast<uint32_t>(setLayoutHandles.size()); createInfo.setLayoutCount = static_cast<uint32_t>(setLayoutHandles.size());
createInfo.pSetLayouts = setLayoutHandles.data(); createInfo.pSetLayouts = setLayoutHandles.data();
createInfo.pushConstantRangeCount = static_cast<uint32_t>(pushConstantRanges.size()); createInfo.pushConstantRangeCount = pushConstantRanges.size();
createInfo.pPushConstantRanges = pushConstantRanges.data(); createInfo.pPushConstantRanges = pushConstantRanges.data();
vk::PipelineLayout newLayout; vk::PipelineLayout newLayout;
......
...@@ -532,10 +532,9 @@ class DescriptorSetLayoutDesc final ...@@ -532,10 +532,9 @@ class DescriptorSetLayoutDesc final
mPackedDescriptorSetLayout; mPackedDescriptorSetLayout;
}; };
// The following are for caching descriptor set layouts. Limited to max four descriptor set layouts // The following are for caching descriptor set layouts. Limited to max four descriptor set layouts.
// and one push constant per shader stage. This can be extended in the future. // This can be extended in the future.
constexpr size_t kMaxDescriptorSetLayouts = 4; constexpr size_t kMaxDescriptorSetLayouts = 4;
constexpr size_t kMaxPushConstantRanges = angle::EnumSize<gl::ShaderType>();
struct PackedPushConstantRange struct PackedPushConstantRange
{ {
...@@ -548,7 +547,7 @@ using DescriptorSetLayoutArray = std::array<T, kMaxDescriptorSetLayouts>; ...@@ -548,7 +547,7 @@ using DescriptorSetLayoutArray = std::array<T, kMaxDescriptorSetLayouts>;
using DescriptorSetLayoutPointerArray = using DescriptorSetLayoutPointerArray =
DescriptorSetLayoutArray<BindingPointer<DescriptorSetLayout>>; DescriptorSetLayoutArray<BindingPointer<DescriptorSetLayout>>;
template <typename T> template <typename T>
using PushConstantRangeArray = std::array<T, kMaxPushConstantRanges>; using PushConstantRangeArray = gl::ShaderMap<T>;
class PipelineLayoutDesc final class PipelineLayoutDesc final
{ {
...@@ -575,14 +574,14 @@ class PipelineLayoutDesc final ...@@ -575,14 +574,14 @@ class PipelineLayoutDesc final
(sizeof(DescriptorSetLayoutDesc) * kMaxDescriptorSetLayouts), (sizeof(DescriptorSetLayoutDesc) * kMaxDescriptorSetLayouts),
"Unexpected size"); "Unexpected size");
static_assert(sizeof(decltype(mPushConstantRanges)) == static_assert(sizeof(decltype(mPushConstantRanges)) ==
(sizeof(PackedPushConstantRange) * kMaxPushConstantRanges), (sizeof(PackedPushConstantRange) * angle::EnumSize<gl::ShaderType>()),
"Unexpected size"); "Unexpected size");
}; };
// Verify the structure is properly packed. // Verify the structure is properly packed.
static_assert(sizeof(PipelineLayoutDesc) == static_assert(sizeof(PipelineLayoutDesc) ==
(sizeof(DescriptorSetLayoutArray<DescriptorSetLayoutDesc>) + (sizeof(DescriptorSetLayoutArray<DescriptorSetLayoutDesc>) +
sizeof(std::array<PackedPushConstantRange, kMaxPushConstantRanges>)), sizeof(gl::ShaderMap<PackedPushConstantRange>)),
"Unexpected Size"); "Unexpected Size");
// Disable warnings about struct padding. // Disable warnings about struct padding.
...@@ -911,12 +910,12 @@ constexpr uint32_t kDriverUniformsDescriptorSetIndex = 3; ...@@ -911,12 +910,12 @@ constexpr uint32_t kDriverUniformsDescriptorSetIndex = 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;
// Binding index for default uniforms in the vertex shader: // There is 1 default uniform binding used per stage. Currently, a maxium of two stages are
constexpr uint32_t kVertexUniformsBindingIndex = 0; // supported.
// Binding index for default uniforms in the fragment shader: constexpr uint32_t kReservedPerStageDefaultUniformBindingCount = 1;
constexpr uint32_t kFragmentUniformsBindingIndex = 1; constexpr uint32_t kReservedDefaultUniformBindingCount = 2;
// Binding index start for transform feedback buffers: // Binding index start for transform feedback buffers:
constexpr uint32_t kXfbBindingIndexStart = 2; 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_
...@@ -176,12 +176,13 @@ void RendererVk::ensureCapsInitialized() const ...@@ -176,12 +176,13 @@ void RendererVk::ensureCapsInitialized() const
// we'll defer the implementation until we tackle the next version. // we'll defer the implementation until we tackle the next version.
// mNativeCaps.maxServerWaitTimeout // mNativeCaps.maxServerWaitTimeout
GLuint maxUniformVectors = mPhysicalDeviceProperties.limits.maxUniformBufferRange / GLuint maxUniformBlockSize = mPhysicalDeviceProperties.limits.maxUniformBufferRange;
(sizeof(GLfloat) * kComponentsPerVector);
// Clamp the maxUniformVectors to 1024u, on AMD the maxUniformBufferRange is way too high. // Clamp the maxUniformBlockSize to 64KB (majority of devices support up to this size
maxUniformVectors = std::min(1024u, maxUniformVectors); // currently), on AMD the maxUniformBufferRange is near uint32_t max.
maxUniformBlockSize = std::min(0x10000u, maxUniformBlockSize);
const GLuint maxUniformVectors = maxUniformBlockSize / (sizeof(GLfloat) * kComponentsPerVector);
const GLuint maxUniformComponents = maxUniformVectors * kComponentsPerVector; const GLuint maxUniformComponents = maxUniformVectors * kComponentsPerVector;
// Uniforms are implemented using a uniform buffer, so the max number of uniforms we can // Uniforms are implemented using a uniform buffer, so the max number of uniforms we can
...@@ -191,30 +192,49 @@ void RendererVk::ensureCapsInitialized() const ...@@ -191,30 +192,49 @@ void RendererVk::ensureCapsInitialized() const
mNativeCaps.maxFragmentUniformVectors = maxUniformVectors; mNativeCaps.maxFragmentUniformVectors = maxUniformVectors;
mNativeCaps.maxShaderUniformComponents[gl::ShaderType::Fragment] = maxUniformComponents; mNativeCaps.maxShaderUniformComponents[gl::ShaderType::Fragment] = maxUniformComponents;
// We use the same bindings on each stage, so the texture, UBO and SSBO limitations are the same // Every stage has 1 reserved uniform buffer for the default uniforms, and 1 for the driver
// as the per-stage limits. // uniforms.
constexpr uint32_t kTotalReservedPerStageUniformBuffers =
kReservedDriverUniformBindingCount + kReservedPerStageDefaultUniformBindingCount;
constexpr uint32_t kTotalReservedUniformBuffers =
kReservedDriverUniformBindingCount + kReservedDefaultUniformBindingCount;
const uint32_t maxPerStageUniformBuffers = const uint32_t maxPerStageUniformBuffers =
mPhysicalDeviceProperties.limits.maxPerStageDescriptorUniformBuffers; mPhysicalDeviceProperties.limits.maxPerStageDescriptorUniformBuffers -
kTotalReservedPerStageUniformBuffers;
const uint32_t maxCombinedUniformBuffers =
mPhysicalDeviceProperties.limits.maxDescriptorSetUniformBuffers -
kTotalReservedUniformBuffers;
mNativeCaps.maxShaderUniformBlocks[gl::ShaderType::Vertex] = maxPerStageUniformBuffers; mNativeCaps.maxShaderUniformBlocks[gl::ShaderType::Vertex] = maxPerStageUniformBuffers;
mNativeCaps.maxShaderUniformBlocks[gl::ShaderType::Fragment] = maxPerStageUniformBuffers; mNativeCaps.maxShaderUniformBlocks[gl::ShaderType::Fragment] = maxPerStageUniformBuffers;
mNativeCaps.maxCombinedUniformBlocks = maxPerStageUniformBuffers; mNativeCaps.maxCombinedUniformBlocks = maxCombinedUniformBuffers;
mNativeCaps.maxUniformBufferBindings = maxCombinedUniformBuffers;
mNativeCaps.maxUniformBlockSize = maxUniformBlockSize;
mNativeCaps.uniformBufferOffsetAlignment =
static_cast<GLuint>(mPhysicalDeviceProperties.limits.minUniformBufferOffsetAlignment);
// Note that Vulkan currently implements textures as combined image+samplers, so the limit is // Note that Vulkan currently implements textures as combined image+samplers, so the limit is
// the minimum of supported samplers and sampled images. // the minimum of supported samplers and sampled images.
const uint32_t maxPerStageTextures = const uint32_t maxPerStageTextures =
std::min(mPhysicalDeviceProperties.limits.maxPerStageDescriptorSamplers, std::min(mPhysicalDeviceProperties.limits.maxPerStageDescriptorSamplers,
mPhysicalDeviceProperties.limits.maxPerStageDescriptorSampledImages); mPhysicalDeviceProperties.limits.maxPerStageDescriptorSampledImages);
mNativeCaps.maxCombinedTextureImageUnits = maxPerStageTextures; const uint32_t maxCombinedTextures =
mNativeCaps.maxShaderTextureImageUnits[gl::ShaderType::Fragment] = maxPerStageTextures; std::min(mPhysicalDeviceProperties.limits.maxDescriptorSetSamplers,
mPhysicalDeviceProperties.limits.maxDescriptorSetSampledImages);
mNativeCaps.maxShaderTextureImageUnits[gl::ShaderType::Vertex] = maxPerStageTextures; mNativeCaps.maxShaderTextureImageUnits[gl::ShaderType::Vertex] = maxPerStageTextures;
mNativeCaps.maxShaderTextureImageUnits[gl::ShaderType::Fragment] = maxPerStageTextures;
mNativeCaps.maxCombinedTextureImageUnits = maxCombinedTextures;
const uint32_t maxPerStageStorageBuffers = const uint32_t maxPerStageStorageBuffers =
mPhysicalDeviceProperties.limits.maxPerStageDescriptorStorageBuffers; mPhysicalDeviceProperties.limits.maxPerStageDescriptorStorageBuffers;
const uint32_t maxCombinedStorageBuffers =
mPhysicalDeviceProperties.limits.maxDescriptorSetStorageBuffers;
mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Vertex] = mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Vertex] =
mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics ? maxPerStageStorageBuffers : 0; mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics ? maxPerStageStorageBuffers : 0;
mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Fragment] = mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Fragment] =
mPhysicalDeviceFeatures.fragmentStoresAndAtomics ? maxPerStageStorageBuffers : 0; mPhysicalDeviceFeatures.fragmentStoresAndAtomics ? maxPerStageStorageBuffers : 0;
mNativeCaps.maxCombinedShaderStorageBlocks = maxPerStageStorageBuffers; mNativeCaps.maxCombinedShaderStorageBlocks = maxCombinedStorageBuffers;
// A number of storage buffer slots are used in the vertex shader to emulate transform feedback. // A number of storage buffer slots are used in the vertex shader to emulate transform feedback.
// Note that Vulkan requires maxPerStageDescriptorStorageBuffers to be at least 4 (i.e. the same // Note that Vulkan requires maxPerStageDescriptorStorageBuffers to be at least 4 (i.e. the same
...@@ -231,22 +251,21 @@ void RendererVk::ensureCapsInitialized() const ...@@ -231,22 +251,21 @@ void RendererVk::ensureCapsInitialized() const
ASSERT(maxPerStageStorageBuffers >= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); ASSERT(maxPerStageStorageBuffers >= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Vertex] -= mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Vertex] -=
gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS;
mNativeCaps.maxCombinedShaderStorageBlocks -=
gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS;
} }
// Fill in additional limits for UBOs and SSBOs. mNativeCaps.maxShaderStorageBufferBindings = maxCombinedStorageBuffers;
mNativeCaps.maxUniformBufferBindings = maxPerStageUniformBuffers;
mNativeCaps.maxUniformBlockSize = mPhysicalDeviceProperties.limits.maxUniformBufferRange;
mNativeCaps.uniformBufferOffsetAlignment =
static_cast<GLuint>(mPhysicalDeviceProperties.limits.minUniformBufferOffsetAlignment);
mNativeCaps.maxShaderStorageBufferBindings = maxPerStageStorageBuffers;
mNativeCaps.maxShaderStorageBlockSize = mPhysicalDeviceProperties.limits.maxStorageBufferRange; mNativeCaps.maxShaderStorageBlockSize = mPhysicalDeviceProperties.limits.maxStorageBufferRange;
mNativeCaps.shaderStorageBufferOffsetAlignment = mNativeCaps.shaderStorageBufferOffsetAlignment =
static_cast<GLuint>(mPhysicalDeviceProperties.limits.minStorageBufferOffsetAlignment); static_cast<GLuint>(mPhysicalDeviceProperties.limits.minStorageBufferOffsetAlignment);
// There is no additional limit to the combined number of components. We can have up to a // There is no additional limit to the combined number of components. We can have up to a
// maximum number of uniform buffers, each having the maximum number of components. // maximum number of uniform buffers, each having the maximum number of components. Note that
const uint32_t maxCombinedUniformComponents = maxPerStageUniformBuffers * maxUniformComponents; // this limit includes both components in and out of uniform buffers.
const uint32_t maxCombinedUniformComponents =
(maxPerStageUniformBuffers + kReservedPerStageDefaultUniformBindingCount) *
maxUniformComponents;
for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes) for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
{ {
mNativeCaps.maxCombinedShaderUniformComponents[shaderType] = maxCombinedUniformComponents; mNativeCaps.maxCombinedShaderUniformComponents[shaderType] = maxCombinedUniformComponents;
......
...@@ -864,6 +864,16 @@ VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bo ...@@ -864,6 +864,16 @@ VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bo
(blue ? VK_COLOR_COMPONENT_B_BIT : 0) | (alpha ? VK_COLOR_COMPONENT_A_BIT : 0); (blue ? VK_COLOR_COMPONENT_B_BIT : 0) | (alpha ? VK_COLOR_COMPONENT_A_BIT : 0);
} }
VkShaderStageFlags GetShaderStageFlags(gl::ShaderBitSet activeShaders)
{
VkShaderStageFlags flags = 0;
for (const gl::ShaderType shaderType : activeShaders)
{
flags |= kShaderStageMap[shaderType];
}
return flags;
}
void GetViewport(const gl::Rectangle &viewport, void GetViewport(const gl::Rectangle &viewport,
float nearPlane, float nearPlane,
float farPlane, float farPlane,
......
...@@ -587,11 +587,19 @@ constexpr angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> kIndexTypeMap ...@@ -587,11 +587,19 @@ constexpr angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> kIndexTypeMap
{gl::DrawElementsType::UnsignedInt, VK_INDEX_TYPE_UINT32}, {gl::DrawElementsType::UnsignedInt, VK_INDEX_TYPE_UINT32},
}; };
constexpr gl::ShaderMap<VkShaderStageFlagBits> kShaderStageMap = {
{gl::ShaderType::Vertex, VK_SHADER_STAGE_VERTEX_BIT},
{gl::ShaderType::Fragment, VK_SHADER_STAGE_FRAGMENT_BIT},
{gl::ShaderType::Geometry, VK_SHADER_STAGE_GEOMETRY_BIT},
{gl::ShaderType::Compute, VK_SHADER_STAGE_COMPUTE_BIT},
};
void GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset); void GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset);
void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent); void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
VkImageType GetImageType(gl::TextureType textureType); VkImageType GetImageType(gl::TextureType textureType);
VkImageViewType GetImageViewType(gl::TextureType textureType); VkImageViewType GetImageViewType(gl::TextureType textureType);
VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bool alpha); VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bool alpha);
VkShaderStageFlags GetShaderStageFlags(gl::ShaderBitSet activeShaders);
void GetViewport(const gl::Rectangle &viewport, void GetViewport(const gl::Rectangle &viewport,
float nearPlane, float nearPlane,
......
...@@ -714,14 +714,20 @@ ...@@ -714,14 +714,20 @@
3520 VULKAN : dEQP-GLES31.functional.state_query.texture_level.texture_2d.compressed_integer = SKIP 3520 VULKAN : dEQP-GLES31.functional.state_query.texture_level.texture_2d.compressed_integer = SKIP
3520 VULKAN : dEQP-GLES31.functional.state_query.texture_level.texture_2d.compressed_float = SKIP 3520 VULKAN : dEQP-GLES31.functional.state_query.texture_level.texture_2d.compressed_float = SKIP
// Vulkan limits lower than GLES minimum:
3633 VULKAN : dEQP-GLES31.functional.state_query.integer.max_uniform_buffer_bindings_get* = FAIL
3633 VULKAN : dEQP-GLES31.functional.state_query.integer.max_combined_uniform_blocks_get* = FAIL
3633 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.20 = FAIL
3633 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.31 = FAIL
// column/row_major specified on struct member: // column/row_major specified on struct member:
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.2 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.9 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.12 = FAIL 3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.12 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.16 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.23 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.25 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.29 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.33 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_shared_buffer.3 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_shared_buffer.11 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_shared_buffer.25 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_shared_buffer.39 = FAIL
3443 VULKAN : dEQP-GLES31.functional.ubo.random.all_shared_buffer.45 = FAIL
// Validation errors: // Validation errors:
// Optimal tiling not supported for format: // Optimal tiling not supported for format:
......
...@@ -536,23 +536,8 @@ ...@@ -536,23 +536,8 @@
3676 VULKAN : dEQP-GLES3.functional.implementation_limits.max_fragment_input_components = FAIL 3676 VULKAN : dEQP-GLES3.functional.implementation_limits.max_fragment_input_components = FAIL
3676 VULKAN : dEQP-GLES3.functional.implementation_limits.max_program_texel_offset = FAIL 3676 VULKAN : dEQP-GLES3.functional.implementation_limits.max_program_texel_offset = FAIL
3676 VULKAN : dEQP-GLES3.functional.implementation_limits.min_program_texel_offset = FAIL 3676 VULKAN : dEQP-GLES3.functional.implementation_limits.min_program_texel_offset = FAIL
// MAX_FRAGMENT_INPUT_COMPONENTS is 0
// Vulkan limits lower than GLES minimum: 3676 VULKAN : dEQP-GLES3.functional.state_query.integers.max_fragment_input_components_get* = FAIL
3633 VULKAN : dEQP-GLES3.functional.implementation_limits.max_uniform_buffer_bindings = FAIL
3633 VULKAN : dEQP-GLES3.functional.implementation_limits.max_combined_uniform_blocks = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers.max_uniform_buffer_bindings_getinteger64 = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers.max_uniform_buffer_bindings_getfloat = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers.max_combined_uniform_blocks_getinteger64 = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers.max_combined_uniform_blocks_getfloat = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers.max_fragment_input_components_get* = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_combined_vertex_uniform_components_getinteger = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_combined_vertex_uniform_components_getfloat = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_combined_fragment_uniform_components_getinteger = FAIL
3633 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_combined_fragment_uniform_components_getfloat = FAIL
3633 VULKAN : dEQP-GLES3.functional.ubo.random.all_shared_buffer.7 = FAIL
3633 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_arrays_instance_arrays.18 = FAIL
3633 ANDROID VULKAN : dEQP-GLES3.functional.implementation_limits.max_combined_texture_image_units = FAIL
3633 ANDROID VULKAN : dEQP-GLES3.functional.state_query.integers.max_combined_texture_image_units_get* = FAIL
// 3D texture: // 3D texture:
3188 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.3d* = SKIP 3188 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.3d* = SKIP
...@@ -667,7 +652,29 @@ ...@@ -667,7 +652,29 @@
// Shader support: // Shader support:
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL 3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.use_program = FAIL 3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.use_program = FAIL
// column/row_major specified on struct member:
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.10 = FAIL 3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.10 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.all_per_block_buffers.8 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.all_per_block_buffers.17 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.all_per_block_buffers.25 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.all_per_block_buffers.49 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.all_shared_buffer.11 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.all_shared_buffer.48 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.18 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.20 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.23 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.8 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_instance_arrays.13 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs.12 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs.17 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs.5 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_arrays.2 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_arrays.3 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_arrays.4 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_instance_arrays.12 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_instance_arrays.18 = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.nested_structs_instance_arrays.24 = FAIL
// New vertex attribute formats: // New vertex attribute formats:
3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.*.int2_10_10_10.* = SKIP 3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.*.int2_10_10_10.* = SKIP
......
...@@ -39,9 +39,6 @@ ...@@ -39,9 +39,6 @@
// GL_MIN/MAX_PROGRAM_TEXTURE_GATHER_OFFSET not set. // GL_MIN/MAX_PROGRAM_TEXTURE_GATHER_OFFSET not set.
3605 VULKAN : KHR-GLES31.core.texture_gather* = FAIL 3605 VULKAN : KHR-GLES31.core.texture_gather* = FAIL
// Vulkan limits lower than GLES minimum:
3633 VULKAN : KHR-GLES31.core.layout_binding.block_layout_binding_block_FragmentShader = FAIL
// Compute shaders // Compute shaders
3562 VULKAN : KHR-GLES31.core.constant_expressions.* = SKIP 3562 VULKAN : KHR-GLES31.core.constant_expressions.* = SKIP
3520 VULKAN : KHR-GLES31.core.compute_shader* = SKIP 3520 VULKAN : KHR-GLES31.core.compute_shader* = SKIP
......
...@@ -31,9 +31,6 @@ ...@@ -31,9 +31,6 @@
// For now we only log Vulkan test expectations. More back-ends can follow as we need them. // For now we only log Vulkan test expectations. More back-ends can follow as we need them.
// Vulkan limits lower than GLES minimum:
3633 VULKAN : KHR-GLES3.shaders.uniform_block.random.all_shared_buffer.1 = FAIL
// Crashes trying to load non-existent texture load function. // Crashes trying to load non-existent texture load function.
3455 VULKAN : KHR-GLES3.copy_tex_image_conversions.forbidden.* = SKIP 3455 VULKAN : KHR-GLES3.copy_tex_image_conversions.forbidden.* = SKIP
3455 VULKAN : KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_* = SKIP 3455 VULKAN : KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_* = SKIP
...@@ -50,5 +47,17 @@ ...@@ -50,5 +47,17 @@
// CopyTexImage conversion missing 2D Array and 3D texture support. // CopyTexImage conversion missing 2D Array and 3D texture support.
3458 VULKAN : KHR-GLES3.copy_tex_image_conversions.required.* = SKIP 3458 VULKAN : KHR-GLES3.copy_tex_image_conversions.required.* = SKIP
// column/row_major specified on struct member:
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.all_per_block_buffers.16 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.all_per_block_buffers.3 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.all_per_block_buffers.5 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.all_per_block_buffers.7 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.all_shared_buffer.0 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.basic_instance_arrays.0 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.basic_instance_arrays.4 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.basic_instance_arrays.5 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.nested_structs_arrays.7 = FAIL
3443 VULKAN : KHR-GLES3.shaders.uniform_block.random.nested_structs_arrays_instance_arrays.3 = FAIL
// Require 3D textures. // Require 3D textures.
3188 VULKAN : KHR-GLES3.packed_pixels.varied_rectangle.* = SKIP 3188 VULKAN : KHR-GLES3.packed_pixels.varied_rectangle.* = SKIP
...@@ -66,14 +66,20 @@ class VulkanUniformUpdatesTest : public ANGLETest ...@@ -66,14 +66,20 @@ class VulkanUniformUpdatesTest : public ANGLETest
programVk->getDynamicDescriptorPool(rx::kUniformsAndXfbDescriptorSetIndex); programVk->getDynamicDescriptorPool(rx::kUniformsAndXfbDescriptorSetIndex);
uniformPool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting); uniformPool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
rx::GetUniformBufferDescriptorCount()}; rx::kReservedDefaultUniformBindingCount};
(void)uniformPool->init(contextVk, &uniformSetSize, 1); (void)uniformPool->init(contextVk, &uniformSetSize, 1);
uint32_t textureCount =
static_cast<uint32_t>(programVk->getState().getSamplerBindings().size());
// To support the bindEmptyForUnusedDescriptorSets workaround.
textureCount = std::max(textureCount, 1u);
rx::vk::DynamicDescriptorPool *texturePool = rx::vk::DynamicDescriptorPool *texturePool =
programVk->getDynamicDescriptorPool(rx::kTextureDescriptorSetIndex); programVk->getDynamicDescriptorPool(rx::kTextureDescriptorSetIndex);
texturePool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting); texturePool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
contextVk->getRenderer()->getMaxActiveTextures()}; textureCount};
(void)texturePool->init(contextVk, &textureSetSize, 1); (void)texturePool->init(contextVk, &textureSetSize, 1);
} }
......
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