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,
ANGLE_TRY(dynamicBuffer->flush(renderer->getDevice()));
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
ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
......@@ -303,14 +279,15 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
VkDevice device = contextVk->getDevice();
// Process vertex and fragment uniforms into std140 packing.
std::array<sh::BlockLayoutMap, MaxShaderIndex> layoutMap;
std::array<size_t, MaxShaderIndex> requiredBufferSize = {{0, 0}};
vk::ShaderMap<sh::BlockLayoutMap> layoutMap;
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),
&layoutMap[shaderIndex],
&requiredBufferSize[shaderIndex]));
gl::ShaderType glShaderType = static_cast<gl::ShaderType>(shaderType);
ANGLE_TRY(InitDefaultUniformBlock(glContext, mState.getAttachedShader(glShaderType),
&layoutMap[shaderType], &requiredBufferSize[shaderType]));
}
// Init the default block layout info.
......@@ -318,7 +295,7 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
const auto &uniforms = mState.getUniforms();
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];
if (location.used() && !location.ignored)
......@@ -337,45 +314,45 @@ gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
bool found = false;
for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex)
for (vk::ShaderType shaderType : vk::AllShaderTypes())
{
auto it = layoutMap[shaderIndex].find(uniformName);
if (it != layoutMap[shaderIndex].end())
auto it = layoutMap[shaderType].find(uniformName);
if (it != layoutMap[shaderType].end())
{
found = true;
layoutInfo[shaderIndex] = it->second;
layoutInfo[shaderType] = it->second;
}
}
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 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(
requiredBufferSize[shaderIndex]))
if (!mDefaultUniformBlocks[shaderType].uniformData.resize(
requiredBufferSize[shaderType]))
{
return gl::OutOfMemory() << "Memory allocation failure.";
}
size_t minAlignment = static_cast<size_t>(
renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
mDefaultUniformBlocks[shaderIndex].storage.init(minAlignment);
mDefaultUniformBlocks[shaderType].storage.init(minAlignment);
// Initialize uniform buffer memory to zero by default.
mDefaultUniformBlocks[shaderIndex].uniformData.fill(0);
mDefaultUniformBlocks[shaderIndex].uniformsDirty = true;
mDefaultUniformBlocks[shaderType].uniformData.fill(0);
mDefaultUniformBlocks[shaderType].uniformsDirty = true;
anyDirty = true;
}
......@@ -505,7 +482,7 @@ void ProgramVk::getUniformImpl(GLint location, T *v, GLenum entryPointType) cons
ASSERT(shaderType != gl::ShaderType::InvalidEnum);
const DefaultUniformBlock &uniformBlock =
mDefaultUniformBlocks[static_cast<GLuint>(shaderType)];
mDefaultUniformBlocks[static_cast<vk::ShaderType>(shaderType)];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
ASSERT(linkedUniform.typeInfo->componentType == entryPointType ||
......@@ -737,8 +714,8 @@ void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint
vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
{
if (!mDefaultUniformBlocks[VertexShader].uniformsDirty &&
!mDefaultUniformBlocks[FragmentShader].uniformsDirty)
if (!mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty &&
!mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty)
{
return vk::NoError();
}
......@@ -748,16 +725,16 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
// 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.
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)
{
bool bufferModified = false;
ANGLE_TRY(SyncDefaultUniformBlock(contextVk->getRenderer(), &uniformBlock.storage,
uniformBlock.uniformData,
&mUniformBlocksOffsets[index], &bufferModified));
&mUniformBlocksOffsets[shaderType], &bufferModified));
uniformBlock.uniformsDirty = false;
if (bufferModified)
......@@ -780,14 +757,14 @@ vk::Error ProgramVk::updateUniforms(ContextVk *contextVk)
vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
{
std::array<VkDescriptorBufferInfo, MaxShaderIndex> descriptorBufferInfo;
std::array<VkWriteDescriptorSet, MaxShaderIndex> writeDescriptorInfo;
uint32_t bufferCount = 0;
vk::ShaderMap<VkDescriptorBufferInfo> descriptorBufferInfo;
vk::ShaderMap<VkWriteDescriptorSet> writeDescriptorInfo;
for (auto &uniformBlock : mDefaultUniformBlocks)
for (vk::ShaderType shaderType : vk::AllShaderTypes())
{
auto &bufferInfo = descriptorBufferInfo[bufferCount];
auto &writeInfo = writeDescriptorInfo[bufferCount];
auto &uniformBlock = mDefaultUniformBlocks[shaderType];
auto &bufferInfo = descriptorBufferInfo[shaderType];
auto &writeInfo = writeDescriptorInfo[shaderType];
if (!uniformBlock.uniformData.empty())
{
......@@ -804,20 +781,18 @@ vk::Error ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfo.pNext = nullptr;
writeInfo.dstSet = mDescriptorSets[0];
writeInfo.dstBinding = bufferCount;
writeInfo.dstBinding = static_cast<uint32_t>(shaderType);
writeInfo.dstArrayElement = 0;
writeInfo.descriptorCount = 1;
writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
writeInfo.pImageInfo = nullptr;
writeInfo.pBufferInfo = &bufferInfo;
writeInfo.pTexelBufferView = nullptr;
bufferCount++;
}
VkDevice device = contextVk->getDevice();
vkUpdateDescriptorSets(device, bufferCount, writeDescriptorInfo.data(), 0, nullptr);
vkUpdateDescriptorSets(device, 2, writeDescriptorInfo.data(), 0, nullptr);
return vk::NoError();
}
......
......@@ -19,11 +19,6 @@
namespace rx
{
namespace
{
constexpr uint32_t kShaderTypeCount = 2;
} // anonymous namespace.
class ProgramVk : public ProgramImpl
{
public:
......@@ -163,8 +158,8 @@ class ProgramVk : public ProgramImpl
std::vector<sh::BlockMemberInfo> uniformLayout;
};
std::array<DefaultUniformBlock, kShaderTypeCount> mDefaultUniformBlocks;
std::array<uint32_t, kShaderTypeCount> mUniformBlocksOffsets;
vk::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
vk::ShaderMap<uint32_t> mUniformBlocksOffsets;
// 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,
......
......@@ -961,8 +961,10 @@ vk::Error RendererVk::getPipeline(const ProgramVk *programVk,
const gl::AttributesMask &activeAttribLocationsMask,
vk::PipelineAndSerial **pipelineOut)
{
ASSERT(programVk->getVertexModuleSerial() == desc.getShaderStageInfo()[0].moduleSerial);
ASSERT(programVk->getFragmentModuleSerial() == desc.getShaderStageInfo()[1].moduleSerial);
ASSERT(programVk->getVertexModuleSerial() ==
desc.getShaderStageInfo()[vk::ShaderType::VertexShader].moduleSerial);
ASSERT(programVk->getFragmentModuleSerial() ==
desc.getShaderStageInfo()[vk::ShaderType::FragmentShader].moduleSerial);
// Pull in a compatible RenderPass.
vk::RenderPass *compatibleRenderPass = nullptr;
......
......@@ -634,10 +634,10 @@ const ShaderStageInfo &PipelineDesc::getShaderStageInfo() const
void PipelineDesc::updateShaders(ProgramVk *programVk)
{
ASSERT(programVk->getVertexModuleSerial() < std::numeric_limits<uint32_t>::max());
mShaderStageInfo[0].moduleSerial =
mShaderStageInfo[ShaderType::VertexShader].moduleSerial =
static_cast<uint32_t>(programVk->getVertexModuleSerial().getValue());
ASSERT(programVk->getFragmentModuleSerial() < std::numeric_limits<uint32_t>::max());
mShaderStageInfo[1].moduleSerial =
mShaderStageInfo[ShaderType::FragmentShader].moduleSerial =
static_cast<uint32_t>(programVk->getFragmentModuleSerial().getValue());
}
......
......@@ -239,7 +239,7 @@ struct PackedColorBlendStateInfo final
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 VertexInputAttributes = gl::AttribArray<PackedVertexInputAttributeDesc>;
......
......@@ -18,6 +18,7 @@
#include "common/debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/Observer.h"
#include "libANGLE/PackedEnums.h"
#include "libANGLE/renderer/renderer_utils.h"
#define ANGLE_GL_OBJECTS_X(PROC) \
......@@ -649,6 +650,20 @@ Error AllocateImageMemory(VkDevice device,
size_t *requiredSizeOut);
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 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