Commit c07ef602 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Move xfb buffer decl to translator in emulation path

This makes @@ XFB-DECL @@ empty on this path. Ultimately, this is working towards removing both @@ XFB-DECL @@ and @@ XFB-OUT @@ macros for both the emulation and extension paths, allowing the shaders to be compiled at compile time rather than link time. Bug: angleproject:3606 Change-Id: If16e9d92c419a04ecd3094481ed546d0708cdb43 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2611305 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent a1b4a1f3
......@@ -26,7 +26,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 248
#define ANGLE_SH_VERSION 249
enum ShShaderSpec
{
......@@ -875,6 +875,9 @@ extern const char kLineRasterEmulationPosition[];
// Transform feedback emulation helper function
extern const char kXfbEmulationGetOffsetsFunctionName[];
extern const char kXfbEmulationBufferBlockName[];
extern const char kXfbEmulationBufferName[];
extern const char kXfbEmulationBufferFieldName[];
} // namespace vk
......
......@@ -140,6 +140,7 @@ class BitSetT final
constexpr static BitSetT Zero() { return BitSetT(); }
ParamT first() const;
ParamT last() const;
private:
// Produces a mask of ones up to the "x"th bit.
......@@ -460,6 +461,13 @@ ParamT BitSetT<N, BitsT, ParamT>::first() const
}
template <size_t N, typename BitsT, typename ParamT>
ParamT BitSetT<N, BitsT, ParamT>::last() const
{
ASSERT(!none());
return static_cast<ParamT>(gl::ScanReverse(mBits));
}
template <size_t N, typename BitsT, typename ParamT>
BitSetT<N, BitsT, ParamT>::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0)
{
if (bits.any())
......
......@@ -1163,6 +1163,13 @@ bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
return false;
}
}
ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
{
shaderTypes.reset(ShaderType::Fragment);
shaderTypes.reset(ShaderType::Compute);
return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
}
} // namespace gl
namespace egl
......
......@@ -247,6 +247,9 @@ enum class SrgbOverride
ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
// Given a set of shader stages, returns the last vertex processing stage. This is the stage that
// interfaces the fragment shader.
ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);
} // namespace gl
......
......@@ -793,6 +793,9 @@ const char kAtomicCountersBlockName[] = "ANGLEAtomicCounters";
const char kLineRasterEmulationPosition[] = "ANGLEPosition";
const char kXfbEmulationGetOffsetsFunctionName[] = "ANGLEGetXfbOffsets";
const char kXfbEmulationBufferBlockName[] = "ANGLEXfbBuffer";
const char kXfbEmulationBufferName[] = "ANGLEXfb";
const char kXfbEmulationBufferFieldName[] = "xfbOut";
} // namespace vk
......
......@@ -463,7 +463,9 @@ ANGLE_NO_DISCARD bool AddXfbEmulationSupport(TCompiler *compiler,
// return ANGLEUniforms.xfbBufferOffsets + xfbIndex * strides;
// }
const TType *ivec4Type = StaticType::GetBasic<EbtInt, 4>();
constexpr uint32_t kMaxXfbBuffers = 4;
const TType *ivec4Type = StaticType::GetBasic<EbtInt, kMaxXfbBuffers>();
// Create the parameter variable.
TVariable *stridesVar = new TVariable(symbolTable, ImmutableString("strides"), ivec4Type,
......@@ -506,9 +508,49 @@ ANGLE_NO_DISCARD bool AddXfbEmulationSupport(TCompiler *compiler,
CreateInternalFunctionDefinitionNode(*getOffsetsFunction, body);
// Insert the function declaration before main().
size_t mainIndex = FindMainIndex(root);
const size_t mainIndex = FindMainIndex(root);
root->insertChildNodes(mainIndex, {functionDef});
// Additionally, generate the following storage buffer declarations used to capture transform
// feedback output. Again, there's a maximum of four buffers.
//
// buffer ANGLEXfbBuffer0
// {
// float xfbOut[];
// } ANGLEXfb0;
// buffer ANGLEXfbBuffer1
// {
// float xfbOut[];
// } ANGLEXfb1;
// ...
for (uint32_t bufferIndex = 0; bufferIndex < kMaxXfbBuffers; ++bufferIndex)
{
TFieldList *fieldList = new TFieldList;
TType *xfbOutType = new TType(EbtFloat);
xfbOutType->makeArray(0);
TField *field = new TField(xfbOutType, ImmutableString(vk::kXfbEmulationBufferFieldName),
TSourceLoc(), SymbolType::AngleInternal);
fieldList->push_back(field);
static_assert(
kMaxXfbBuffers < 10,
"ImmutableStringBuilder memory size below needs to accomodate the number of buffers");
ImmutableStringBuilder blockName(strlen(vk::kXfbEmulationBufferBlockName) + 2);
blockName << vk::kXfbEmulationBufferBlockName;
blockName.appendDecimal(bufferIndex);
ImmutableStringBuilder varName(strlen(vk::kXfbEmulationBufferName) + 2);
varName << vk::kXfbEmulationBufferName;
varName.appendDecimal(bufferIndex);
DeclareInterfaceBlock(root, symbolTable, fieldList, EvqBuffer, TMemoryQualifier::Create(),
0, blockName, varName);
}
return compiler->validateAST(root);
}
......
......@@ -1250,32 +1250,24 @@ bool ProgramState::hasAttachedShader() const
ShaderType ProgramState::getFirstAttachedShaderStageType() const
{
if (mExecutable->getLinkedShaderStages().none())
const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages();
if (linkedStages.none())
{
return ShaderType::InvalidEnum;
}
return *mExecutable->getLinkedShaderStages().begin();
return linkedStages.first();
}
ShaderType ProgramState::getLastAttachedShaderStageType() const
{
for (int i = gl::kAllGraphicsShaderTypes.size() - 1; i >= 0; --i)
const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages();
if (linkedStages.none())
{
const gl::ShaderType shaderType = gl::kAllGraphicsShaderTypes[i];
if (mExecutable->hasLinkedShaderStage(shaderType))
{
return shaderType;
}
}
if (mExecutable->hasLinkedShaderStage(ShaderType::Compute))
{
return ShaderType::Compute;
return ShaderType::InvalidEnum;
}
return ShaderType::InvalidEnum;
return linkedStages.last();
}
ShaderType ProgramState::getAttachedTransformFeedbackStage() const
......
......@@ -489,15 +489,7 @@ bool ProgramExecutable::isYUVOutput() const
ShaderType ProgramExecutable::getLinkedTransformFeedbackStage() const
{
if (mLinkedGraphicsShaderStages[ShaderType::Geometry])
{
return ShaderType::Geometry;
}
if (mLinkedGraphicsShaderStages[ShaderType::TessEvaluation])
{
return ShaderType::TessEvaluation;
}
return ShaderType::Vertex;
return GetLastPreFragmentStage(mLinkedGraphicsShaderStages);
}
bool ProgramExecutable::linkMergedVaryings(
......
......@@ -338,8 +338,10 @@ void GenerateTransformFeedbackVaryingOutput(const gl::TransformFeedbackVarying &
{
for (int row = 0; row < info.rowCount; ++row)
{
*xfbOut << "xfbOut" << bufferIndex << "[xfbOffsets[" << bufferIndex << "] + "
<< offset << "] = " << info.glslAsFloat << "(" << varying.mappedName;
*xfbOut << sh::vk::kXfbEmulationBufferName << bufferIndex << "."
<< sh::vk::kXfbEmulationBufferFieldName << "[xfbOffsets[" << bufferIndex
<< "] + " << offset << "] = " << info.glslAsFloat << "("
<< varying.mappedName;
if (varying.isArray())
{
......@@ -363,6 +365,39 @@ void GenerateTransformFeedbackVaryingOutput(const gl::TransformFeedbackVarying &
}
}
void AssignTransformFeedbackEmulationBindings(gl::ShaderType shaderType,
const gl::ProgramState &programState,
bool isTransformFeedbackStage,
GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{
size_t bufferCount = 0;
if (isTransformFeedbackStage)
{
ASSERT(!programState.getLinkedTransformFeedbackVaryings().empty());
const bool isInterleaved =
programState.getTransformFeedbackBufferMode() == GL_INTERLEAVED_ATTRIBS;
bufferCount = isInterleaved ? 1 : programState.getLinkedTransformFeedbackVaryings().size();
}
// Add entries for the transform feedback buffers to the info map, so they can have correct
// set/binding.
for (uint32_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex)
{
AddResourceInfo(variableInfoMapOut, shaderType, GetXfbBufferName(bufferIndex),
programInterfaceInfo->uniformsAndXfbDescriptorSetIndex,
programInterfaceInfo->currentUniformBindingIndex);
++programInterfaceInfo->currentUniformBindingIndex;
}
// Remove inactive transform feedback buffers.
for (uint32_t bufferIndex = bufferCount;
bufferIndex < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; ++bufferIndex)
{
variableInfoMapOut->add(shaderType, GetXfbBufferName(bufferIndex));
}
}
void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &options,
gl::ShaderType shaderType,
const gl::ProgramState &programState,
......@@ -379,27 +414,6 @@ void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &optio
ASSERT(bufferCount > 0);
const std::string xfbSet = Str(programInterfaceInfo->uniformsAndXfbDescriptorSetIndex);
std::vector<std::string> xfbIndices(bufferCount);
std::string xfbDecl;
for (uint32_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex)
{
const std::string xfbBinding = Str(programInterfaceInfo->currentUniformBindingIndex);
xfbIndices[bufferIndex] = Str(bufferIndex);
std::string bufferName = GetXfbBufferName(bufferIndex);
xfbDecl += "layout(set = " + xfbSet + ", binding = " + xfbBinding + ") buffer " +
bufferName + " { float xfbOut" + Str(bufferIndex) + "[]; };\n";
// Add this entry to the info map, so we can easily assert that every resource has an entry
// in this map.
AddResourceInfo(variableInfoMapOut, shaderType, bufferName,
programInterfaceInfo->uniformsAndXfbDescriptorSetIndex,
programInterfaceInfo->currentUniformBindingIndex);
++programInterfaceInfo->currentUniformBindingIndex;
}
const std::string driverUniforms = std::string(sh::vk::kDriverUniformsVarName);
std::ostringstream xfbOut;
......@@ -430,7 +444,7 @@ void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &optio
// For every varying, output to the respective buffer packed. If interleaved, the output is
// always to the same buffer, but at different offsets.
const gl::UniformTypeInfo &info = gl::GetUniformTypeInfo(varying.type);
GenerateTransformFeedbackVaryingOutput(varying, info, outputOffset, xfbIndices[bufferIndex],
GenerateTransformFeedbackVaryingOutput(varying, info, outputOffset, Str(bufferIndex),
&xfbOut);
if (isInterleaved)
......@@ -440,7 +454,7 @@ void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &optio
}
xfbOut << "}\n";
*vertexShader = SubstituteTransformFeedbackMarkers(*vertexShader, xfbDecl, xfbOut.str());
*vertexShader = SubstituteTransformFeedbackMarkers(*vertexShader, "", xfbOut.str());
}
bool IsFirstRegisterOfVarying(const gl::PackedVaryingRegister &varyingReg, bool allowFields)
......@@ -2305,6 +2319,19 @@ bool SpirvTransformer::transformDebugInfo(const uint32_t *instruction, size_t wo
(id == mInputPerVertex.typeId && member > mInputPerVertex.maxActiveMember);
}
// In the case of ANGLEXfbN, unconditionally remove the variable names. If transform
// feedback is not active, the corresponding variables will be removed.
if (GetSpirvInstructionOp(instruction) == spv::OpName)
{
// SPIR-V 1.0 Section 3.32 Instructions, OpName
constexpr size_t kNameIndex = 2;
const char *name = reinterpret_cast<const char *>(&instruction[kNameIndex]);
if (angle::BeginsWith(name, sh::vk::kXfbEmulationBufferName))
{
return true;
}
}
return false;
}
......@@ -2540,6 +2567,20 @@ bool SpirvTransformer::transformVariable(const uint32_t *instruction, size_t wor
return false;
}
if (mOptions.isTransformFeedbackStage && storageClass == spv::StorageClassUniform)
{
// Exceptionally, the ANGLEXfbN variables are unconditionally generated and may be inactive.
// Remove these variables in that case.
ASSERT(mOptions.shaderType == gl::ShaderType::Vertex);
ASSERT(info == &mVariableInfoMap.get(mOptions.shaderType, GetXfbBufferName(0)) ||
info == &mVariableInfoMap.get(mOptions.shaderType, GetXfbBufferName(1)) ||
info == &mVariableInfoMap.get(mOptions.shaderType, GetXfbBufferName(2)) ||
info == &mVariableInfoMap.get(mOptions.shaderType, GetXfbBufferName(3)));
// Drop the declaration.
return true;
}
// Copy the declaration even though the variable is inactive for the separately compiled shader.
ASSERT(storageClass == spv::StorageClassOutput || storageClass == spv::StorageClassInput);
......@@ -3797,7 +3838,7 @@ std::string GlslangGetMappedSamplerName(const std::string &originalName)
std::string GetXfbBufferName(const uint32_t bufferIndex)
{
return "xfbBuffer" + Str(bufferIndex);
return sh::vk::kXfbEmulationBufferBlockName + Str(bufferIndex);
}
void GlslangGenTransformFeedbackEmulationOutputs(const GlslangSourceOptions &options,
......@@ -3812,13 +3853,16 @@ void GlslangGenTransformFeedbackEmulationOutputs(const GlslangSourceOptions &opt
}
void GlslangAssignLocations(const GlslangSourceOptions &options,
const gl::ProgramExecutable &programExecutable,
const gl::ProgramState &programState,
const gl::ProgramVaryingPacking &varyingPacking,
const gl::ShaderType shaderType,
const gl::ShaderType frontShaderType,
bool isTransformFeedbackStage,
GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{
const gl::ProgramExecutable &programExecutable = programState.getExecutable();
// Assign outputs to the fragment shader, if any.
if ((shaderType == gl::ShaderType::Fragment) &&
programExecutable.hasLinkedShaderStage(gl::ShaderType::Fragment))
......@@ -3866,6 +3910,12 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
variableInfoMapOut);
AssignNonTextureBindings(options, programExecutable, shaderType, programInterfaceInfo,
variableInfoMapOut);
if (options.emulateTransformFeedback && gl::ShaderTypeSupportsTransformFeedback(shaderType))
{
AssignTransformFeedbackEmulationBindings(shaderType, programState, isTransformFeedbackStage,
programInterfaceInfo, variableInfoMapOut);
}
}
void GlslangGetShaderSource(const GlslangSourceOptions &options,
......@@ -3929,8 +3979,10 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
for (const gl::ShaderType shaderType : programState.getExecutable().getLinkedShaderStages())
{
GlslangAssignLocations(options, programState.getExecutable(), resources.varyingPacking,
shaderType, frontShaderType, programInterfaceInfo,
const bool isXfbStage =
shaderType == xfbStage && !programState.getLinkedTransformFeedbackVaryings().empty();
GlslangAssignLocations(options, programState, resources.varyingPacking, shaderType,
frontShaderType, isXfbStage, programInterfaceInfo,
variableInfoMapOut);
frontShaderType = shaderType;
......
......@@ -158,7 +158,7 @@ void GlslangRelease();
bool GetImageNameWithoutIndices(std::string *name);
// Get the mapped sampler name after the soure is transformed by GlslangGetShaderSource()
// Get the mapped sampler name after the source is transformed by GlslangGetShaderSource()
std::string GetMappedSamplerNameOld(const std::string &originalName);
std::string GlslangGetMappedSamplerName(const std::string &originalName);
std::string GetXfbBufferName(const uint32_t bufferIndex);
......@@ -172,10 +172,11 @@ void GlslangGenTransformFeedbackEmulationOutputs(
ShaderInterfaceVariableInfoMap *variableInfoMapOut);
void GlslangAssignLocations(const GlslangSourceOptions &options,
const gl::ProgramExecutable &programExecutable,
const gl::ProgramState &programState,
const gl::ProgramVaryingPacking &varyingPacking,
const gl::ShaderType shaderType,
const gl::ShaderType frontShaderType,
bool isTransformFeedbackStage,
GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderInterfaceVariableInfoMap *variableInfoMapOut);
......
......@@ -414,6 +414,8 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
GlslangProgramInterfaceInfo programInterfaceInfo;
ResetGlslangProgramInterfaceInfo(&programInterfaceInfo);
options.emulateTransformFeedback = true;
rx::GlslangGetShaderSource(options, programState, resources, &programInterfaceInfo,
shaderSourcesOut, variableInfoMapOut);
......@@ -426,15 +428,17 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
GlslangProgramInterfaceInfo xfbOnlyInterfaceInfo;
ResetGlslangProgramInterfaceInfo(&xfbOnlyInterfaceInfo);
options.emulateTransformFeedback = true;
rx::GlslangGenTransformFeedbackEmulationOutputs(
options, programState, &xfbOnlyInterfaceInfo, xfbOnlyShaderSourceOut,
xfbOnlyVSVariableInfoMapOut);
GlslangAssignLocations(options, programState.getExecutable(), resources.varyingPacking,
const bool isTransformFeedbackStage =
!programState.getLinkedTransformFeedbackVaryings().empty();
GlslangAssignLocations(options, programState, resources.varyingPacking,
gl::ShaderType::Vertex, gl::ShaderType::InvalidEnum,
&xfbOnlyInterfaceInfo, xfbOnlyVSVariableInfoMapOut);
isTransformFeedbackStage, &xfbOnlyInterfaceInfo,
xfbOnlyVSVariableInfoMapOut);
}
}
......@@ -454,7 +458,8 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
for (const gl::ShaderType shaderType : linkedShaderStages)
{
GlslangSpirvOptions options;
options.shaderType = shaderType;
options.shaderType = shaderType;
options.isTransformFeedbackStage = shaderType == gl::ShaderType::Vertex;
angle::Result status = GlslangTransformSpirvCode(
[context](GlslangError error) { return HandleError(context, error); }, options,
......
......@@ -818,14 +818,15 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
gl_vk::kShaderStageMap[shaderType], nullptr);
mNumDefaultUniformDescriptors++;
}
bool hasVertexShader = glExecutable.hasLinkedShaderStage(gl::ShaderType::Vertex);
gl::ShaderType linkedTransformFeedbackStage = glExecutable.getLinkedTransformFeedbackStage();
bool hasXfbVaryings =
(programStates[gl::ShaderType::Vertex] &&
!programStates[gl::ShaderType::Vertex]->getLinkedTransformFeedbackVaryings().empty());
if (hasVertexShader && transformFeedback && hasXfbVaryings)
linkedTransformFeedbackStage != gl::ShaderType::InvalidEnum &&
!programStates[linkedTransformFeedbackStage]->getLinkedTransformFeedbackVaryings().empty();
if (transformFeedback && hasXfbVaryings)
{
const gl::ProgramExecutable &executable =
programStates[gl::ShaderType::Vertex]->getExecutable();
programStates[linkedTransformFeedbackStage]->getExecutable();
size_t xfbBufferCount = executable.getTransformFeedbackBufferCount();
TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback);
transformFeedbackVk->updateDescriptorSetLayout(contextVk, mVariableInfoMap, xfbBufferCount,
......
......@@ -56,9 +56,10 @@ angle::Result ProgramPipelineVk::link(const gl::Context *glContext,
const gl::ProgramMergedVaryings &mergedVaryings,
const gl::ProgramVaryingPacking &varyingPacking)
{
ContextVk *contextVk = vk::GetImpl(glContext);
const gl::State &glState = glContext->getState();
const gl::ProgramPipeline *glPipeline = glState.getProgramPipeline();
ContextVk *contextVk = vk::GetImpl(glContext);
const gl::State &glState = glContext->getState();
const gl::ProgramPipeline *glPipeline = glState.getProgramPipeline();
const gl::ProgramExecutable &glExecutable = glPipeline->getExecutable();
GlslangSourceOptions options =
GlslangWrapperVk::CreateSourceOptions(contextVk->getRenderer()->getFeatures());
GlslangProgramInterfaceInfo glslangProgramInterfaceInfo;
......@@ -68,8 +69,10 @@ angle::Result ProgramPipelineVk::link(const gl::Context *glContext,
// Now that the program pipeline has all of the programs attached, the various descriptor
// set/binding locations need to be re-assigned to their correct values.
const gl::ShaderType linkedTransformFeedbackStage =
glExecutable.getLinkedTransformFeedbackStage();
gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum;
for (const gl::ShaderType shaderType : glPipeline->getExecutable().getLinkedShaderStages())
for (const gl::ShaderType shaderType : glExecutable.getLinkedShaderStages())
{
gl::Program *glProgram =
const_cast<gl::Program *>(glPipeline->getShaderProgram(shaderType));
......@@ -83,9 +86,13 @@ angle::Result ProgramPipelineVk::link(const gl::Context *glContext,
glslangProgramInterfaceInfo.locationsUsedForXfbExtension =
programProgramInterfaceInfo.locationsUsedForXfbExtension;
GlslangAssignLocations(options, glProgram->getState().getExecutable(), varyingPacking,
shaderType, frontShaderType, &glslangProgramInterfaceInfo,
&mExecutable.mVariableInfoMap);
const bool isTransformFeedbackStage =
shaderType == linkedTransformFeedbackStage &&
!glProgram->getState().getLinkedTransformFeedbackVaryings().empty();
GlslangAssignLocations(options, glProgram->getState(), varyingPacking, shaderType,
frontShaderType, isTransformFeedbackStage,
&glslangProgramInterfaceInfo, &mExecutable.mVariableInfoMap);
frontShaderType = shaderType;
}
}
......
......@@ -22,7 +22,6 @@
namespace rx
{
TransformFeedbackVk::TransformFeedbackVk(const gl::TransformFeedbackState &state)
: TransformFeedbackImpl(state),
mRebindTransformFeedbackBuffer(false),
......@@ -208,7 +207,9 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const
{
if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
{
return;
}
for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{
......@@ -227,7 +228,9 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
VkDescriptorSet descSet) const
{
if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
{
return;
}
VkDescriptorBufferInfo *descriptorBufferInfo =
contextVk->allocDescriptorBufferInfos(xfbBufferCount);
......@@ -250,7 +253,9 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
VkDescriptorSet descSet) const
{
if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
{
return;
}
const gl::ProgramExecutable *executable = contextVk->getState().getProgramExecutable();
ASSERT(executable);
......@@ -284,7 +289,9 @@ void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
size_t offsetsSize) const
{
if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
{
return;
}
GLsizeiptr verticesDrawn = mState.getVerticesDrawn();
const std::vector<GLsizei> &bufferStrides =
......@@ -319,7 +326,7 @@ void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorBufferInfo *bufferInfo,
VkDescriptorSet descSet) const
{
ASSERT(contextVk->getFeatures().emulateTransformFeedback.enabled);
......@@ -336,7 +343,7 @@ void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk,
writeDescriptorInfo.descriptorCount = static_cast<uint32_t>(xfbBufferCount);
writeDescriptorInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writeDescriptorInfo.pImageInfo = nullptr;
writeDescriptorInfo.pBufferInfo = pBufferInfo;
writeDescriptorInfo.pBufferInfo = bufferInfo;
writeDescriptorInfo.pTexelBufferView = nullptr;
}
......
......@@ -98,7 +98,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl
void writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorBufferInfo *bufferInfo,
VkDescriptorSet descSet) const;
void initializeXFBBuffersDesc(ContextVk *contextVk, size_t xfbBufferCount);
......
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