Commit 33318de4 by Jamie Madill Committed by Commit Bot

Vulkan: Use ShaderType enum.

This re-uses the same machinery as the GL front-end. It saves a lot of custom casting and array sizing. Currently we only support vertex and fragment shaders in Vulkan. Because of the Pipeline cache sizing, it's easier to stick with just VS/FS and introduce the full set of shaders when we move to packing the cache better. Bug: angleproject:2522 Bug: angleproject:2455 Change-Id: I21432a335c741885af87970d8ee52b4a36338304 Reviewed-on: https://chromium-review.googlesource.com/1036927Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJiawei Shao <jiawei.shao@intel.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent d8ffd756
...@@ -129,30 +129,6 @@ vk::Error SyncDefaultUniformBlock(RendererVk *renderer, ...@@ -129,30 +129,6 @@ vk::Error SyncDefaultUniformBlock(RendererVk *renderer,
ANGLE_TRY(dynamicBuffer->flush(renderer->getDevice())); ANGLE_TRY(dynamicBuffer->flush(renderer->getDevice()));
return vk::NoError(); return vk::NoError();
} }
// TODO(jiawei.shao@intel.com): Fully remove this enum by gl::ShaderType. (BUG=angleproject:2169)
enum ShaderIndex : uint32_t
{
MinShaderIndex = 0,
VertexShader = MinShaderIndex,
FragmentShader = 1,
MaxShaderIndex = kShaderTypeCount,
};
gl::Shader *GetShader(const gl::ProgramState &programState, uint32_t shaderIndex)
{
switch (shaderIndex)
{
case VertexShader:
return programState.getAttachedShader(gl::ShaderType::Vertex);
case FragmentShader:
return programState.getAttachedShader(gl::ShaderType::Fragment);
default:
UNREACHABLE();
return nullptr;
}
}
} // anonymous namespace } // anonymous namespace
ProgramVk::DefaultUniformBlock::DefaultUniformBlock() ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
...@@ -303,14 +279,15 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -303,14 +279,15 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
VkDevice device = contextVk->getDevice(); VkDevice device = contextVk->getDevice();
// Process vertex and fragment uniforms into std140 packing. // Process vertex and fragment uniforms into std140 packing.
std::array<sh::BlockLayoutMap, MaxShaderIndex> layoutMap; vk::ShaderMap<sh::BlockLayoutMap> layoutMap;
std::array<size_t, MaxShaderIndex> requiredBufferSize = {{0, 0}}; vk::ShaderMap<size_t> requiredBufferSize;
requiredBufferSize.fill(0);
for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
ANGLE_TRY(InitDefaultUniformBlock(glContext, GetShader(mState, shaderIndex), gl::ShaderType glShaderType = static_cast<gl::ShaderType>(shaderType);
&layoutMap[shaderIndex], ANGLE_TRY(InitDefaultUniformBlock(glContext, mState.getAttachedShader(glShaderType),
&requiredBufferSize[shaderIndex])); &layoutMap[shaderType], &requiredBufferSize[shaderType]));
} }
// Init the default block layout info. // Init the default block layout info.
...@@ -318,7 +295,7 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -318,7 +295,7 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
const auto &uniforms = mState.getUniforms(); const auto &uniforms = mState.getUniforms();
for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex) for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex)
{ {
std::array<sh::BlockMemberInfo, MaxShaderIndex> layoutInfo; vk::ShaderMap<sh::BlockMemberInfo> layoutInfo;
const auto &location = locations[locationIndex]; const auto &location = locations[locationIndex];
if (location.used() && !location.ignored) if (location.used() && !location.ignored)
...@@ -337,45 +314,45 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -337,45 +314,45 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
bool found = false; bool found = false;
for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
auto it = layoutMap[shaderIndex].find(uniformName); auto it = layoutMap[shaderType].find(uniformName);
if (it != layoutMap[shaderIndex].end()) if (it != layoutMap[shaderType].end())
{ {
found = true; found = true;
layoutInfo[shaderIndex] = it->second; layoutInfo[shaderType] = it->second;
} }
} }
ASSERT(found); ASSERT(found);
} }
for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]); mDefaultUniformBlocks[shaderType].uniformLayout.push_back(layoutInfo[shaderType]);
} }
} }
bool anyDirty = false; bool anyDirty = false;
bool allDirty = true; bool allDirty = true;
for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
if (requiredBufferSize[shaderIndex] > 0) if (requiredBufferSize[shaderType] > 0)
{ {
if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize( if (!mDefaultUniformBlocks[shaderType].uniformData.resize(
requiredBufferSize[shaderIndex])) requiredBufferSize[shaderType]))
{ {
return gl::OutOfMemory() << "Memory allocation failure."; return gl::OutOfMemory() << "Memory allocation failure.";
} }
size_t minAlignment = static_cast<size_t>( size_t minAlignment = static_cast<size_t>(
renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment); renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
mDefaultUniformBlocks[shaderIndex].storage.init(minAlignment); mDefaultUniformBlocks[shaderType].storage.init(minAlignment);
// Initialize uniform buffer memory to zero by default. // Initialize uniform buffer memory to zero by default.
mDefaultUniformBlocks[shaderIndex].uniformData.fill(0); mDefaultUniformBlocks[shaderType].uniformData.fill(0);
mDefaultUniformBlocks[shaderIndex].uniformsDirty = true; mDefaultUniformBlocks[shaderType].uniformsDirty = true;
anyDirty = true; anyDirty = true;
} }
...@@ -505,7 +482,7 @@ void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) cons ...@@ -505,7 +482,7 @@ void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) cons
ASSERT(shaderType != gl::ShaderType::InvalidEnum); ASSERT(shaderType != gl::ShaderType::InvalidEnum);
const DefaultUniformBlock &uniformBlock = const DefaultUniformBlock &uniformBlock =
mDefaultUniformBlocks[static_cast<GLuint>(shaderType)]; mDefaultUniformBlocks[static_cast<vk::ShaderType>(shaderType)];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location]; const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
ASSERT(linkedUniform.typeInfo->componentType == entryPointType || ASSERT(linkedUniform.typeInfo->componentType == entryPointType ||
...@@ -737,8 +714,8 @@ void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint ...@@ -737,8 +714,8 @@ void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint
vk::Error ProgramVk::updateUniforms(ContextVk *contextVk) vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
{ {
if (!mDefaultUniformBlocks[VertexShader].uniformsDirty && if (!mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty &&
!mDefaultUniformBlocks[FragmentShader].uniformsDirty) !mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty)
{ {
return vk::NoError(); return vk::NoError();
} }
...@@ -748,16 +725,16 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk) ...@@ -748,16 +725,16 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
// Update buffer memory by immediate mapping. This immediate update only works once. // Update buffer memory by immediate mapping. This immediate update only works once.
// TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers. // TODO(jmadill): Handle inserting updates into the command stream, or use dynamic buffers.
bool anyNewBufferAllocated = false; bool anyNewBufferAllocated = false;
for (size_t index = 0; index < mDefaultUniformBlocks.size(); index++) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[index]; DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
if (uniformBlock.uniformsDirty) if (uniformBlock.uniformsDirty)
{ {
bool bufferModified = false; bool bufferModified = false;
ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage, ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage,
uniformBlock.uniformData, uniformBlock.uniformData,
&mUniformBlocksOffsets[index], &bufferModified)); &mUniformBlocksOffsets[shaderType], &bufferModified));
uniformBlock.uniformsDirty = false; uniformBlock.uniformsDirty = false;
if (bufferModified) if (bufferModified)
...@@ -780,14 +757,14 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk) ...@@ -780,14 +757,14 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk) vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
{ {
std::array<VkDescriptorBufferInfo, MaxShaderIndex> descriptorBufferInfo; vk::ShaderMap<VkDescriptorBufferInfo> descriptorBufferInfo;
std::array<VkWriteDescriptorSet, MaxShaderIndex> writeDescriptorInfo; vk::ShaderMap<VkWriteDescriptorSet> writeDescriptorInfo;
uint32_t bufferCount = 0;
for (auto &uniformBlock : mDefaultUniformBlocks) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
auto &bufferInfo = descriptorBufferInfo[bufferCount]; auto &uniformBlock = mDefaultUniformBlocks[shaderType];
auto &writeInfo = writeDescriptorInfo[bufferCount]; auto &bufferInfo = descriptorBufferInfo[shaderType];
auto &writeInfo = writeDescriptorInfo[shaderType];
if (!uniformBlock.uniformData.empty()) if (!uniformBlock.uniformData.empty())
{ {
...@@ -804,20 +781,18 @@ vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk) ...@@ -804,20 +781,18 @@ vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfo.pNext = nullptr; writeInfo.pNext = nullptr;
writeInfo.dstSet = mDescriptorSets[0]; writeInfo.dstSet = mDescriptorSets[0];
writeInfo.dstBinding = bufferCount; writeInfo.dstBinding = static_cast<uint32_t>(shaderType);
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.pBufferInfo = &bufferInfo; writeInfo.pBufferInfo = &bufferInfo;
writeInfo.pTexelBufferView = nullptr; writeInfo.pTexelBufferView = nullptr;
bufferCount++;
} }
VkDevice device = contextVk->getDevice(); VkDevice device = contextVk->getDevice();
vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr); vkUpdateDescriptorSets(device, 2, writeDescriptorInfo.data(), 0, nullptr);
return vk::NoError(); return vk::NoError();
} }
......
...@@ -19,11 +19,6 @@ ...@@ -19,11 +19,6 @@
namespace rx namespace rx
{ {
namespace
{
constexpr uint32_t kShaderTypeCount = 2;
} // anonymous namespace.
class ProgramVk : public ProgramImpl class ProgramVk : public ProgramImpl
{ {
public: public:
...@@ -163,8 +158,8 @@ class ProgramVk : public ProgramImpl ...@@ -163,8 +158,8 @@ class ProgramVk : public ProgramImpl
std::vector<sh::BlockMemberInfo> uniformLayout; std::vector<sh::BlockMemberInfo> uniformLayout;
}; };
std::array<DefaultUniformBlock, kShaderTypeCount> mDefaultUniformBlocks; vk::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
std::array<uint32_t, kShaderTypeCount> mUniformBlocksOffsets; vk::ShaderMap<uint32_t> mUniformBlocksOffsets;
// 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,
......
...@@ -961,8 +961,10 @@ vk::Error RendererVk::getPipeline(const ProgramVk *programVk, ...@@ -961,8 +961,10 @@ vk::Error RendererVk::getPipeline(const ProgramVk *programVk,
const gl::AttributesMask &activeAttribLocationsMask, const gl::AttributesMask &activeAttribLocationsMask,
vk::PipelineAndSerial **pipelineOut) vk::PipelineAndSerial **pipelineOut)
{ {
ASSERT(programVk->getVertexModuleSerial() == desc.getShaderStageInfo()[0].moduleSerial); ASSERT(programVk->getVertexModuleSerial() ==
ASSERT(programVk->getFragmentModuleSerial() == desc.getShaderStageInfo()[1].moduleSerial); desc.getShaderStageInfo()[vk::ShaderType::VertexShader].moduleSerial);
ASSERT(programVk->getFragmentModuleSerial() ==
desc.getShaderStageInfo()[vk::ShaderType::FragmentShader].moduleSerial);
// Pull in a compatible RenderPass. // Pull in a compatible RenderPass.
vk::RenderPass *compatibleRenderPass = nullptr; vk::RenderPass *compatibleRenderPass = nullptr;
......
...@@ -634,10 +634,10 @@ const ShaderStageInfo &PipelineDesc::getShaderStageInfo() const ...@@ -634,10 +634,10 @@ const ShaderStageInfo &PipelineDesc::getShaderStageInfo() const
void PipelineDesc::updateShaders(ProgramVk *programVk) void PipelineDesc::updateShaders(ProgramVk *programVk)
{ {
ASSERT(programVk->getVertexModuleSerial() < std::numeric_limits<uint32_t>::max()); ASSERT(programVk->getVertexModuleSerial() < std::numeric_limits<uint32_t>::max());
mShaderStageInfo[0].moduleSerial = mShaderStageInfo[ShaderType::VertexShader].moduleSerial =
static_cast<uint32_t>(programVk->getVertexModuleSerial().getValue()); static_cast<uint32_t>(programVk->getVertexModuleSerial().getValue());
ASSERT(programVk->getFragmentModuleSerial() < std::numeric_limits<uint32_t>::max()); ASSERT(programVk->getFragmentModuleSerial() < std::numeric_limits<uint32_t>::max());
mShaderStageInfo[1].moduleSerial = mShaderStageInfo[ShaderType::FragmentShader].moduleSerial =
static_cast<uint32_t>(programVk->getFragmentModuleSerial().getValue()); static_cast<uint32_t>(programVk->getFragmentModuleSerial().getValue());
} }
......
...@@ -239,7 +239,7 @@ struct PackedColorBlendStateInfo final ...@@ -239,7 +239,7 @@ struct PackedColorBlendStateInfo final
static_assert(sizeof(PackedColorBlendStateInfo) == 96, "Size check failed"); static_assert(sizeof(PackedColorBlendStateInfo) == 96, "Size check failed");
using ShaderStageInfo = std::array<PackedShaderStageInfo, 2>; using ShaderStageInfo = vk::ShaderMap<PackedShaderStageInfo>;
using VertexInputBindings = gl::AttribArray<PackedVertexInputBindingDesc>; using VertexInputBindings = gl::AttribArray<PackedVertexInputBindingDesc>;
using VertexInputAttributes = gl::AttribArray<PackedVertexInputAttributeDesc>; using VertexInputAttributes = gl::AttribArray<PackedVertexInputAttributeDesc>;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/Observer.h" #include "libANGLE/Observer.h"
#include "libANGLE/PackedEnums.h"
#include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/renderer_utils.h"
#define ANGLE_GL_OBJECTS_X(PROC) \ #define ANGLE_GL_OBJECTS_X(PROC) \
...@@ -649,6 +650,20 @@ Error AllocateImageMemory(VkDevice device, ...@@ -649,6 +650,20 @@ Error AllocateImageMemory(VkDevice device,
size_t *requiredSizeOut); size_t *requiredSizeOut);
using ShaderAndSerial = ObjectAndSerial<ShaderModule>; using ShaderAndSerial = ObjectAndSerial<ShaderModule>;
// TODO(jmadill): Use gl::ShaderType when possible. http://anglebug.com/2522
enum class ShaderType
{
VertexShader,
FragmentShader,
EnumCount,
InvalidEnum = EnumCount,
};
template <typename T>
using ShaderMap = angle::PackedEnumMap<ShaderType, T>;
using AllShaderTypes = angle::AllEnums<vk::ShaderType>;
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
......
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