Skip to content

Commit

Permalink
Vulkan: Implement basic geometry shader feature
Browse files Browse the repository at this point in the history
Enable the default behavior of the geometry shader

Bug: angleproject:3571
Test: dEQP-GLES31.functional.geometry_shading.input.basic_primitive.points
      dEQP-GLES31.functional.geometry_shading.input.basic_primitive.lines
      dEQP-GLES31.functional.geometry_shading.input.basic_primitive.line_loop
      dEQP-GLES31.functional.geometry_shading.input.basic_primitive.line_strip
      dEQP-GLES31.functional.geometry_shading.input.basic_primitive.triangles
      dEQP-GLES31.functional.geometry_shading.input.basic_primitive.triangle_strip
      dEQP-GLES31.functional.geometry_shading.input.basic_primitive.triangle_fan
Change-Id: I65708d19bbfe6a0ad8ca392a1d6b3609b1410ef4
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1793753
Commit-Queue: Jamie Madill <[email protected]>
Reviewed-by: Jamie Madill <[email protected]>
  • Loading branch information
Jaedon Lee authored and Commit Bot committed Sep 27, 2019
1 parent f8bb908 commit a0159c0
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 56 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ Samsung Electronics, Inc.
Kyeongmin Kim
Minkyu Jeong
Mohan Maiya
Sangwon Park

Arm Ltd.
Fei Yang
8 changes: 8 additions & 0 deletions src/compiler/translator/TranslatorVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,14 @@ bool TranslatorVulkan::translate(TIntermBlock *root,
return false;
}
}
else if (getShaderType() == GL_GEOMETRY_SHADER)
{
AddANGLEPositionVarying(root, &getSymbolTable());

WriteGeometryShaderLayoutQualifiers(
sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
}
else
{
ASSERT(getShaderType() == GL_COMPUTE_SHADER);
Expand Down
28 changes: 13 additions & 15 deletions src/libANGLE/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,8 @@ angle::Result Program::link(const Context *context)
unlink();

// Re-link shaders after the unlink call.
ASSERT(linkValidateShaders(mInfoLog));
bool result = linkValidateShaders(mInfoLog);
ASSERT(result);

std::unique_ptr<ProgramLinkedResources> resources;
if (mState.mAttachedShaders[ShaderType::Compute])
Expand Down Expand Up @@ -4043,7 +4044,7 @@ bool Program::linkValidateGlobalNames(InfoLog &infoLog) const
uniformBlockFieldMap[field.name];
for (const auto &prevBlockFieldPair : prevBlockFieldPairs)
{
const sh::InterfaceBlock *prevUniformBlock = prevBlockFieldPair.first;
const sh::InterfaceBlock *prevUniformBlock = prevBlockFieldPair.first;
const sh::ShaderVariable *prevUniformBlockField = prevBlockFieldPair.second;

if (uniformBlock.isSameInterfaceBlockAtLinkTime(*prevUniformBlock))
Expand Down Expand Up @@ -4139,21 +4140,18 @@ ProgramMergedVaryings Program::getMergedVaryings() const
{
ProgramMergedVaryings merged;

Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
if (vertexShader)
{
for (const sh::ShaderVariable &varying : vertexShader->getOutputVaryings())
{
merged[varying.name].vertex = &varying;
}
}

Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
if (fragmentShader)
for (Shader *shader : mState.mAttachedShaders)
{
for (const sh::ShaderVariable &varying : fragmentShader->getInputVaryings())
if (shader)
{
merged[varying.name].fragment = &varying;
for (const sh::ShaderVariable &varying : shader->getOutputVaryings())
{
merged[varying.name].frontShader = &varying;
}
for (const sh::ShaderVariable &varying : shader->getInputVaryings())
{
merged[varying.name].backShader = &varying;
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/libANGLE/Program.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,10 +544,10 @@ class ProgramBindings final : angle::NonCopyable

struct ProgramVaryingRef
{
const sh::ShaderVariable *get() const { return vertex ? vertex : fragment; }
const sh::ShaderVariable *get() const { return frontShader ? frontShader : backShader; }

const sh::ShaderVariable *vertex = nullptr;
const sh::ShaderVariable *fragment = nullptr;
const sh::ShaderVariable *frontShader = nullptr;
const sh::ShaderVariable *backShader = nullptr;
};

using ProgramMergedVaryings = std::map<std::string, ProgramVaryingRef>;
Expand Down
5 changes: 3 additions & 2 deletions src/libANGLE/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ void Shader::resolveCompile()
{
mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
// TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
mState.mActiveOutputVariables =
Expand Down Expand Up @@ -610,7 +610,8 @@ const std::vector<sh::ShaderVariable> &Shader::getActiveOutputVariables()
std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName)
{
// TODO([email protected]): support transform feedback on geometry shader.
ASSERT(mState.getShaderType() == ShaderType::Vertex);
ASSERT(mState.getShaderType() == ShaderType::Vertex ||
mState.getShaderType() == ShaderType::Geometry);
const auto &varyings = getOutputVaryings();
auto bracketPos = tfVaryingName.find("[");
if (bracketPos != std::string::npos)
Expand Down
7 changes: 3 additions & 4 deletions src/libANGLE/VaryingPacking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,

for (const auto &ref : mergedVaryings)
{
const sh::ShaderVariable *input = ref.second.vertex;
const sh::ShaderVariable *output = ref.second.fragment;
const sh::ShaderVariable *input = ref.second.frontShader;
const sh::ShaderVariable *output = ref.second.backShader;

// Only pack statically used varyings that have a matched input or output, plus special
// builtins. Note that we pack all statically used user-defined varyings even if they are
Expand All @@ -313,7 +313,7 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
// variable is taken from the fragment shader.
if (varying->isStruct())
{
ASSERT(!varying->isArray());
ASSERT(!(varying->isArray() && varying == input));
for (GLuint fieldIndex = 0; fieldIndex < varying->fields.size(); ++fieldIndex)
{
const sh::ShaderVariable &field = varying->fields[fieldIndex];
Expand Down Expand Up @@ -406,7 +406,6 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog,
const std::vector<PackedVarying> &packedVaryings)
{

// "Variables are packed into the registers one at a time so that they each occupy a contiguous
// subrectangle. No splitting of variables is permitted."
for (const PackedVarying &packedVarying : packedVaryings)
Expand Down
5 changes: 4 additions & 1 deletion src/libANGLE/renderer/gl/ProgramGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,11 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
std::vector<std::string> transformFeedbackVaryingMappedNames;
for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames())
{
gl::ShaderType tfShaderType = mState.hasLinkedShaderStage(gl::ShaderType::Geometry)
? gl::ShaderType::Geometry
: gl::ShaderType::Vertex;
std::string tfVaryingMappedName =
mState.getAttachedShader(gl::ShaderType::Vertex)
mState.getAttachedShader(tfShaderType)
->getTransformFeedbackVaryingMappedName(tfVarying);
transformFeedbackVaryingMappedNames.push_back(tfVaryingMappedName);
}
Expand Down
51 changes: 47 additions & 4 deletions src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class IntermediateShaderSource final : angle::NonCopyable
void init(const std::string &source);
bool empty() const { return mTokens.empty(); }

bool findTokenName(const std::string &name);
// Find @@ LAYOUT-name(extra, args) @@ and replace it with:
//
// layout(specifier, extra, args)
Expand Down Expand Up @@ -280,6 +281,18 @@ void IntermediateShaderSource::init(const std::string &source)
}
}

bool IntermediateShaderSource::findTokenName(const std::string &name)
{
for (Token &block : mTokens)
{
if (block.text == name)
{
return true;
}
}
return false;
}

void IntermediateShaderSource::insertLayoutSpecifier(const std::string &name,
const std::string &specifier)
{
Expand Down Expand Up @@ -567,7 +580,8 @@ void AssignOutputLocations(const gl::ProgramState &programState,
}
}

void AssignVaryingLocations(const gl::ProgramLinkedResources &resources,
void AssignVaryingLocations(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
IntermediateShaderSource *outStageSource,
IntermediateShaderSource *inStageSource)
{
Expand Down Expand Up @@ -607,6 +621,16 @@ void AssignVaryingLocations(const gl::ProgramLinkedResources &resources,
const std::string &name =
varying.isStructField() ? varying.parentStructName : varying.varying->name;

// Varings are from 3 stage of shader sources
// To match pair of (out - in) qualifier, varying should be in the pair of shader source
if (!outStageSource->findTokenName(name) || !inStageSource->findTokenName(name))
{
// Pair can be unmatching at transform feedback case,
// But it requires qualifier.
if (!varying.vertexOnly)
continue;
}

outStageSource->insertLayoutSpecifier(name, locationString);
inStageSource->insertLayoutSpecifier(name, locationString);

Expand Down Expand Up @@ -939,18 +963,29 @@ void GlslangWrapper::GetShaderSource(bool useOldRewriteStructSamplers,

IntermediateShaderSource *vertexSource = &intermediateSources[gl::ShaderType::Vertex];
IntermediateShaderSource *fragmentSource = &intermediateSources[gl::ShaderType::Fragment];
IntermediateShaderSource *geometrySource = &intermediateSources[gl::ShaderType::Geometry];

if (!vertexSource->empty())
if (!geometrySource->empty())
{
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(programState, resources, geometrySource, fragmentSource);
if (!vertexSource->empty())
{
AssignAttributeLocations(programState, vertexSource);
AssignVaryingLocations(programState, resources, vertexSource, geometrySource);
}
}
else if (!vertexSource->empty())
{
AssignAttributeLocations(programState, vertexSource);
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(resources, vertexSource, fragmentSource);
AssignVaryingLocations(programState, resources, vertexSource, fragmentSource);
}
else if (!fragmentSource->empty())
{
AssignAttributeLocations(programState, fragmentSource);
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(resources, vertexSource, fragmentSource);
AssignVaryingLocations(programState, resources, vertexSource, fragmentSource);
}
AssignUniformBindings(&intermediateSources);
AssignTextureBindings(useOldRewriteStructSamplers, programState, &intermediateSources);
Expand Down Expand Up @@ -1005,6 +1040,14 @@ angle::Result GlslangWrapper::GetShaderCode(vk::Context *context,
kVersionDefine, kLineRasterDefine),
VK_ERROR_INVALID_SHADER_NV);

if (!shaderSources[gl::ShaderType::Geometry].empty())
{
ANGLE_VK_CHECK(context,
angle::ReplaceSubstring(&patchedSources[gl::ShaderType::Geometry],
kVersionDefine, kLineRasterDefine),
VK_ERROR_INVALID_SHADER_NV);
}

return GetShaderCodeImpl(context, glCaps, patchedSources, shaderCodeOut);
}
else
Expand Down
1 change: 1 addition & 0 deletions src/libANGLE/renderer/vulkan/RendererVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,7 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics;
enabledFeatures.features.fragmentStoresAndAtomics =
mPhysicalDeviceFeatures.fragmentStoresAndAtomics;
enabledFeatures.features.geometryShader = mPhysicalDeviceFeatures.geometryShader;
if (!vk::CommandBuffer::ExecutesInline())
{
enabledFeatures.features.inheritedQueries = mPhysicalDeviceFeatures.inheritedQueries;
Expand Down
47 changes: 32 additions & 15 deletions src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,19 @@ void UnpackBlendAttachmentState(const vk::PackedColorBlendAttachmentState &packe
stateOut->alphaBlendOp = static_cast<VkBlendOp>(packedState.alphaBlendOp);
}

void SetPipelineShaderStageInfo(const VkStructureType type,
const VkShaderStageFlagBits stage,
const VkShaderModule module,
VkPipelineShaderStageCreateInfo *shaderStage)
{
shaderStage->sType = type;
shaderStage->flags = 0;
shaderStage->stage = stage;
shaderStage->module = module;
shaderStage->pName = "main";
shaderStage->pSpecializationInfo = nullptr;
}

angle::Result InitializeRenderPassFromDesc(vk::Context *context,
const RenderPassDesc &desc,
const AttachmentOpsArray &ops,
Expand Down Expand Up @@ -601,9 +614,10 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
const gl::ComponentTypeMask &programAttribsTypeMask,
const ShaderModule *vertexModule,
const ShaderModule *fragmentModule,
const ShaderModule *geometryModule,
Pipeline *pipelineOut) const
{
angle::FixedVector<VkPipelineShaderStageCreateInfo, 2> shaderStages;
angle::FixedVector<VkPipelineShaderStageCreateInfo, 3> shaderStages;
VkPipelineVertexInputStateCreateInfo vertexInputState = {};
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {};
VkPipelineViewportStateCreateInfo viewportState = {};
Expand All @@ -618,25 +632,27 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
// Vertex shader is always expected to be present.
ASSERT(vertexModule != nullptr);
VkPipelineShaderStageCreateInfo vertexStage = {};
vertexStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertexStage.flags = 0;
vertexStage.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertexStage.module = vertexModule->getHandle();
vertexStage.pName = "main";
vertexStage.pSpecializationInfo = nullptr;
SetPipelineShaderStageInfo(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
VK_SHADER_STAGE_VERTEX_BIT, vertexModule->getHandle(), &vertexStage);
shaderStages.push_back(vertexStage);

if (geometryModule)
{
VkPipelineShaderStageCreateInfo geometryStage = {};
SetPipelineShaderStageInfo(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
VK_SHADER_STAGE_GEOMETRY_BIT, geometryModule->getHandle(),
&geometryStage);
shaderStages.push_back(geometryStage);
}

// Fragment shader is optional.
// anglebug.com/3509 - Don't compile the fragment shader if rasterizationDiscardEnable = true
if (fragmentModule && !mRasterizationAndMultisampleStateInfo.bits.rasterizationDiscardEnable)
{
VkPipelineShaderStageCreateInfo fragmentStage = {};
fragmentStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragmentStage.flags = 0;
fragmentStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragmentStage.module = fragmentModule->getHandle();
fragmentStage.pName = "main";
fragmentStage.pSpecializationInfo = nullptr;
SetPipelineShaderStageInfo(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
VK_SHADER_STAGE_FRAGMENT_BIT, fragmentModule->getHandle(),
&fragmentStage);
shaderStages.push_back(fragmentStage);
}

Expand Down Expand Up @@ -1494,7 +1510,7 @@ void PipelineLayoutDesc::updatePushConstantRange(gl::ShaderType shaderType,
uint32_t size)
{
ASSERT(shaderType == gl::ShaderType::Vertex || shaderType == gl::ShaderType::Fragment ||
shaderType == gl::ShaderType::Compute);
shaderType == gl::ShaderType::Geometry || shaderType == gl::ShaderType::Compute);
PackedPushConstantRange &packed = mPushConstantRanges[shaderType];
packed.offset = offset;
packed.size = size;
Expand Down Expand Up @@ -1705,6 +1721,7 @@ angle::Result GraphicsPipelineCache::insertPipeline(
const gl::ComponentTypeMask &programAttribsTypeMask,
const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule,
const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut)
Expand All @@ -1718,7 +1735,7 @@ angle::Result GraphicsPipelineCache::insertPipeline(
ANGLE_TRY(desc.initializePipeline(contextVk, pipelineCacheVk, compatibleRenderPass,
pipelineLayout, activeAttribLocationsMask,
programAttribsTypeMask, vertexModule, fragmentModule,
&newPipeline));
geometryModule, &newPipeline));
}

// The Serial will be updated outside of this query.
Expand Down
Loading

0 comments on commit a0159c0

Please sign in to comment.