зеркало из https://github.com/AvaloniaUI/angle.git
Proper support for fragment output variables for GLSL ES shader version 300.
TRAC #22704 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens Authored-by: Jamie Madill
This commit is contained in:
Родитель
05a80cebc3
Коммит
46131a3832
|
@ -37,7 +37,7 @@ extern "C" {
|
||||||
|
|
||||||
// Version number for shader translation API.
|
// Version number for shader translation API.
|
||||||
// It is incremented everytime the API changes.
|
// It is incremented everytime the API changes.
|
||||||
#define ANGLE_SH_VERSION 113
|
#define ANGLE_SH_VERSION 114
|
||||||
|
|
||||||
//
|
//
|
||||||
// The names of the following enums have been derived by replacing GL prefix
|
// The names of the following enums have been derived by replacing GL prefix
|
||||||
|
@ -132,6 +132,7 @@ typedef enum {
|
||||||
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004,
|
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004,
|
||||||
SH_SHADER_VERSION = 0x6005,
|
SH_SHADER_VERSION = 0x6005,
|
||||||
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
|
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
|
||||||
|
SH_ACTIVE_OUTPUT_VARIABLES_ARRAY = 0x6007,
|
||||||
} ShShaderInfo;
|
} ShShaderInfo;
|
||||||
|
|
||||||
// Compile options.
|
// Compile options.
|
||||||
|
|
|
@ -156,6 +156,11 @@ const ActiveInterfaceBlocks &OutputHLSL::getInterfaceBlocks() const
|
||||||
return mActiveInterfaceBlocks;
|
return mActiveInterfaceBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ActiveShaderVariables &OutputHLSL::getOutputVariables() const
|
||||||
|
{
|
||||||
|
return mActiveOutputVariables;
|
||||||
|
}
|
||||||
|
|
||||||
int OutputHLSL::vectorSize(const TType &type) const
|
int OutputHLSL::vectorSize(const TType &type) const
|
||||||
{
|
{
|
||||||
int elementSize = type.isMatrix() ? type.getCols() : 1;
|
int elementSize = type.isMatrix() ? type.getCols() : 1;
|
||||||
|
@ -391,23 +396,44 @@ void OutputHLSL::header()
|
||||||
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
|
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
|
||||||
const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
|
const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
|
||||||
|
|
||||||
const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
|
|
||||||
|
|
||||||
out << "// Varyings\n";
|
out << "// Varyings\n";
|
||||||
out << varyings;
|
out << varyings;
|
||||||
out << "\n"
|
out << "\n";
|
||||||
"static float4 gl_Color[" << numColorValues << "] =\n"
|
|
||||||
"{\n";
|
if (mContext.getShaderVersion() >= 300)
|
||||||
for (unsigned int i = 0; i < numColorValues; i++)
|
|
||||||
{
|
{
|
||||||
out << " float4(0, 0, 0, 0)";
|
for (auto outputVariableIt = mReferencedOutputVariables.begin(); outputVariableIt != mReferencedOutputVariables.end(); outputVariableIt++)
|
||||||
if (i + 1 != numColorValues)
|
|
||||||
{
|
{
|
||||||
out << ",";
|
const TString &variableName = outputVariableIt->first;
|
||||||
|
const TType &variableType = outputVariableIt->second->getType();
|
||||||
|
const TLayoutQualifier &layoutQualifier = variableType.getLayoutQualifier();
|
||||||
|
|
||||||
|
out << "static " + typeString(variableType) + " out_" + variableName + arrayString(variableType) +
|
||||||
|
" = " + initializer(variableType) + ";\n";
|
||||||
|
|
||||||
|
ShaderVariable outputVar(glVariableType(variableType), glVariablePrecision(variableType), variableName.c_str(),
|
||||||
|
(unsigned int)variableType.getArraySize(), layoutQualifier.location);
|
||||||
|
mActiveOutputVariables.push_back(outputVar);
|
||||||
}
|
}
|
||||||
out << "\n";
|
|
||||||
}
|
}
|
||||||
out << "};\n";
|
else
|
||||||
|
{
|
||||||
|
const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
|
||||||
|
|
||||||
|
out << "static float4 gl_Color[" << numColorValues << "] =\n"
|
||||||
|
"{\n";
|
||||||
|
for (unsigned int i = 0; i < numColorValues; i++)
|
||||||
|
{
|
||||||
|
out << " float4(0, 0, 0, 0)";
|
||||||
|
if (i + 1 != numColorValues)
|
||||||
|
{
|
||||||
|
out << ",";
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "};\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (mUsesFragCoord)
|
if (mUsesFragCoord)
|
||||||
{
|
{
|
||||||
|
@ -1407,7 +1433,12 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
|
||||||
mReferencedVaryings[name] = node;
|
mReferencedVaryings[name] = node;
|
||||||
out << decorate(name);
|
out << decorate(name);
|
||||||
}
|
}
|
||||||
else if (qualifier == EvqFragColor || qualifier == EvqFragmentOutput)
|
else if (qualifier == EvqFragmentOutput)
|
||||||
|
{
|
||||||
|
mReferencedOutputVariables[name] = node;
|
||||||
|
out << "out_" << name;
|
||||||
|
}
|
||||||
|
else if (qualifier == EvqFragColor)
|
||||||
{
|
{
|
||||||
out << "gl_Color[0]";
|
out << "gl_Color[0]";
|
||||||
mUsesFragColor = true;
|
mUsesFragColor = true;
|
||||||
|
|
|
@ -34,6 +34,7 @@ class OutputHLSL : public TIntermTraverser
|
||||||
TInfoSinkBase &getBodyStream();
|
TInfoSinkBase &getBodyStream();
|
||||||
const ActiveUniforms &getUniforms();
|
const ActiveUniforms &getUniforms();
|
||||||
const ActiveInterfaceBlocks &getInterfaceBlocks() const;
|
const ActiveInterfaceBlocks &getInterfaceBlocks() const;
|
||||||
|
const ActiveShaderVariables &getOutputVariables() const;
|
||||||
|
|
||||||
TString typeString(const TType &type);
|
TString typeString(const TType &type);
|
||||||
TString textureString(const TType &type);
|
TString textureString(const TType &type);
|
||||||
|
@ -88,6 +89,7 @@ class OutputHLSL : public TIntermTraverser
|
||||||
ReferencedSymbols mReferencedInterfaceBlocks;
|
ReferencedSymbols mReferencedInterfaceBlocks;
|
||||||
ReferencedSymbols mReferencedAttributes;
|
ReferencedSymbols mReferencedAttributes;
|
||||||
ReferencedSymbols mReferencedVaryings;
|
ReferencedSymbols mReferencedVaryings;
|
||||||
|
ReferencedSymbols mReferencedOutputVariables;
|
||||||
|
|
||||||
// Parameters determining what goes in the header output
|
// Parameters determining what goes in the header output
|
||||||
bool mUsesTexture2D;
|
bool mUsesTexture2D;
|
||||||
|
@ -192,6 +194,7 @@ class OutputHLSL : public TIntermTraverser
|
||||||
|
|
||||||
ActiveUniforms mActiveUniforms;
|
ActiveUniforms mActiveUniforms;
|
||||||
ActiveInterfaceBlocks mActiveInterfaceBlocks;
|
ActiveInterfaceBlocks mActiveInterfaceBlocks;
|
||||||
|
ActiveShaderVariables mActiveOutputVariables;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2028,6 +2028,11 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, TS
|
||||||
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
|
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
|
||||||
recover();
|
recover();
|
||||||
}
|
}
|
||||||
|
else if (baseExpression->getQualifier() == EvqFragmentOutput)
|
||||||
|
{
|
||||||
|
error(location, "", "[", "array indexes for output variables must be constant integeral expressions");
|
||||||
|
recover();
|
||||||
|
}
|
||||||
|
|
||||||
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
|
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,6 +379,9 @@ void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
|
||||||
case SH_ACTIVE_INTERFACE_BLOCKS_ARRAY:
|
case SH_ACTIVE_INTERFACE_BLOCKS_ARRAY:
|
||||||
*params = (void*)&translator->getInterfaceBlocks();
|
*params = (void*)&translator->getInterfaceBlocks();
|
||||||
break;
|
break;
|
||||||
|
case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY:
|
||||||
|
*params = (void*)&translator->getOutputVariables();
|
||||||
|
break;
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,5 @@ void TranslatorHLSL::translate(TIntermNode *root)
|
||||||
outputHLSL.output();
|
outputHLSL.output();
|
||||||
mActiveUniforms = outputHLSL.getUniforms();
|
mActiveUniforms = outputHLSL.getUniforms();
|
||||||
mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks();
|
mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks();
|
||||||
|
mActiveOutputVariables = outputHLSL.getOutputVariables();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,14 @@ public:
|
||||||
virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
|
virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
|
||||||
const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
|
const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
|
||||||
const sh::ActiveInterfaceBlocks &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
|
const sh::ActiveInterfaceBlocks &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
|
||||||
|
const sh::ActiveShaderVariables &getOutputVariables() { return mActiveOutputVariables; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void translate(TIntermNode* root);
|
virtual void translate(TIntermNode* root);
|
||||||
|
|
||||||
sh::ActiveUniforms mActiveUniforms;
|
sh::ActiveUniforms mActiveUniforms;
|
||||||
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
|
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
|
||||||
|
sh::ActiveShaderVariables mActiveOutputVariables;
|
||||||
ShShaderOutput mOutputType;
|
ShShaderOutput mOutputType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,15 @@
|
||||||
namespace sh
|
namespace sh
|
||||||
{
|
{
|
||||||
|
|
||||||
|
ShaderVariable::ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location)
|
||||||
|
: type(type),
|
||||||
|
precision(precision),
|
||||||
|
name(name),
|
||||||
|
arraySize(arraySize),
|
||||||
|
location(location)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex)
|
Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex)
|
||||||
{
|
{
|
||||||
this->type = type;
|
this->type = type;
|
||||||
|
|
|
@ -17,6 +17,19 @@
|
||||||
namespace sh
|
namespace sh
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct ShaderVariable
|
||||||
|
{
|
||||||
|
ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location);
|
||||||
|
|
||||||
|
GLenum type;
|
||||||
|
GLenum precision;
|
||||||
|
std::string name;
|
||||||
|
unsigned int arraySize;
|
||||||
|
int location;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<ShaderVariable> ActiveShaderVariables;
|
||||||
|
|
||||||
struct Uniform
|
struct Uniform
|
||||||
{
|
{
|
||||||
Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex);
|
Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex);
|
||||||
|
|
|
@ -41,6 +41,11 @@ std::string arrayString(int i)
|
||||||
return "[" + str(i) + "]";
|
return "[" + str(i) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string arrayString(unsigned int i)
|
||||||
|
{
|
||||||
|
return (i == GL_INVALID_INDEX ? "" : "[" + str(i) + "]");
|
||||||
|
}
|
||||||
|
|
||||||
namespace gl_d3d
|
namespace gl_d3d
|
||||||
{
|
{
|
||||||
std::string TypeString(GLenum type)
|
std::string TypeString(GLenum type)
|
||||||
|
@ -1055,6 +1060,32 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], F
|
||||||
return registers;
|
return registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProgramBinary::defineOutputVariables(FragmentShader *fragmentShader)
|
||||||
|
{
|
||||||
|
const sh::ActiveShaderVariables &outputVars = fragmentShader->getOutputVariables();
|
||||||
|
|
||||||
|
for (unsigned int outputVariableIndex = 0; outputVariableIndex < outputVars.size(); outputVariableIndex++)
|
||||||
|
{
|
||||||
|
const sh::ShaderVariable &outputVariable = outputVars[outputVariableIndex];
|
||||||
|
const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location;
|
||||||
|
|
||||||
|
if (outputVariable.arraySize > 0)
|
||||||
|
{
|
||||||
|
for (unsigned int elementIndex = 0; elementIndex < outputVariable.arraySize; elementIndex++)
|
||||||
|
{
|
||||||
|
const int location = baseLocation + elementIndex;
|
||||||
|
ASSERT(mOutputVariables.count(location) == 0);
|
||||||
|
mOutputVariables[location] = VariableLocation(outputVariable.name, elementIndex, outputVariableIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(mOutputVariables.count(baseLocation) == 0);
|
||||||
|
mOutputVariables[baseLocation] = VariableLocation(outputVariable.name, GL_INVALID_INDEX, outputVariableIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4],
|
bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4],
|
||||||
std::string& pixelHLSL, std::string& vertexHLSL,
|
std::string& pixelHLSL, std::string& vertexHLSL,
|
||||||
FragmentShader *fragmentShader, VertexShader *vertexShader)
|
FragmentShader *fragmentShader, VertexShader *vertexShader)
|
||||||
|
@ -1355,9 +1386,28 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
|
||||||
"struct PS_OUTPUT\n"
|
"struct PS_OUTPUT\n"
|
||||||
"{\n";
|
"{\n";
|
||||||
|
|
||||||
for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
|
if (mShaderVersion < 300)
|
||||||
{
|
{
|
||||||
pixelHLSL += " float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n";
|
for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
|
||||||
|
{
|
||||||
|
pixelHLSL += " float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
defineOutputVariables(fragmentShader);
|
||||||
|
|
||||||
|
const sh::ActiveShaderVariables &outputVars = fragmentShader->getOutputVariables();
|
||||||
|
for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
|
||||||
|
{
|
||||||
|
const VariableLocation &outputLocation = locationIt->second;
|
||||||
|
const sh::ShaderVariable &outputVariable = outputVars[outputLocation.index];
|
||||||
|
const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : str(outputLocation.element));
|
||||||
|
|
||||||
|
pixelHLSL += " " + gl_d3d::TypeString(outputVariable.type) +
|
||||||
|
" out_" + outputLocation.name + elementString +
|
||||||
|
" : " + targetSemantic + str(locationIt->first) + ";\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pixelHLSL += "};\n"
|
pixelHLSL += "};\n"
|
||||||
|
@ -1473,11 +1523,26 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
|
||||||
"\n"
|
"\n"
|
||||||
" PS_OUTPUT output;\n";
|
" PS_OUTPUT output;\n";
|
||||||
|
|
||||||
for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
|
if (mShaderVersion < 300)
|
||||||
{
|
{
|
||||||
unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex;
|
for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
|
||||||
|
{
|
||||||
|
unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex;
|
||||||
|
|
||||||
pixelHLSL += " output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n";
|
pixelHLSL += " output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
|
||||||
|
{
|
||||||
|
const VariableLocation &outputLocation = locationIt->second;
|
||||||
|
const std::string &variableName = "out_" + outputLocation.name;
|
||||||
|
const std::string &outVariableName = variableName + (outputLocation.element == GL_INVALID_INDEX ? "" : str(outputLocation.element));
|
||||||
|
const std::string &staticVariableName = variableName + arrayString(outputLocation.element);
|
||||||
|
|
||||||
|
pixelHLSL += " output." + outVariableName + " = " + staticVariableName + ";\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pixelHLSL += "\n"
|
pixelHLSL += "\n"
|
||||||
|
|
|
@ -164,7 +164,8 @@ class ProgramBinary : public RefCountObject
|
||||||
void defineUniformBlockMembers(const sh::ActiveUniforms &uniforms, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes);
|
void defineUniformBlockMembers(const sh::ActiveUniforms &uniforms, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes);
|
||||||
bool defineUniformBlock(InfoLog &infoLog, GLenum shader, const sh::InterfaceBlock &interfaceBlock);
|
bool defineUniformBlock(InfoLog &infoLog, GLenum shader, const sh::InterfaceBlock &interfaceBlock);
|
||||||
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex);
|
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex);
|
||||||
|
void defineOutputVariables(FragmentShader *fragmentShader);
|
||||||
|
|
||||||
std::string generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
|
std::string generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
|
||||||
std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
|
std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
|
||||||
|
|
||||||
|
@ -206,6 +207,8 @@ class ProgramBinary : public RefCountObject
|
||||||
UniformBlockArray mUniformBlocks;
|
UniformBlockArray mUniformBlocks;
|
||||||
typedef std::vector<VariableLocation> UniformIndex;
|
typedef std::vector<VariableLocation> UniformIndex;
|
||||||
UniformIndex mUniformIndex;
|
UniformIndex mUniformIndex;
|
||||||
|
typedef std::map<int, VariableLocation> ShaderVariableIndex;
|
||||||
|
ShaderVariableIndex mOutputVariables;
|
||||||
|
|
||||||
bool mValidated;
|
bool mValidated;
|
||||||
|
|
||||||
|
|
|
@ -706,5 +706,26 @@ void FragmentShader::compile()
|
||||||
compileToHLSL(mFragmentCompiler);
|
compileToHLSL(mFragmentCompiler);
|
||||||
parseVaryings();
|
parseVaryings();
|
||||||
mVaryings.sort(compareVarying);
|
mVaryings.sort(compareVarying);
|
||||||
|
|
||||||
|
const char *hlsl = getHLSL();
|
||||||
|
if (hlsl)
|
||||||
|
{
|
||||||
|
void *activeOutputVariables;
|
||||||
|
ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables);
|
||||||
|
mActiveOutputVariables = *(sh::ActiveShaderVariables*)activeOutputVariables;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FragmentShader::uncompile()
|
||||||
|
{
|
||||||
|
Shader::uncompile();
|
||||||
|
|
||||||
|
mActiveOutputVariables.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const sh::ActiveShaderVariables &FragmentShader::getOutputVariables() const
|
||||||
|
{
|
||||||
|
return mActiveOutputVariables;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,9 +188,13 @@ class FragmentShader : public Shader
|
||||||
|
|
||||||
virtual GLenum getType();
|
virtual GLenum getType();
|
||||||
virtual void compile();
|
virtual void compile();
|
||||||
|
virtual void uncompile();
|
||||||
|
const sh::ActiveShaderVariables &getOutputVariables() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(FragmentShader);
|
DISALLOW_COPY_AND_ASSIGN(FragmentShader);
|
||||||
|
|
||||||
|
sh::ActiveShaderVariables mActiveOutputVariables;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче