Commit 8ba78da0 by Lee Salzman Committed by Commit Bot

add support for EXT_blend_func_extended to D3D11

Change-Id: Id66868851a490d0a68a7e76280720825c4844a45 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1591192 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 3e62561c
...@@ -233,6 +233,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -233,6 +233,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
const char *sourcePath, const char *sourcePath,
ShShaderOutput outputType, ShShaderOutput outputType,
int numRenderTargets, int numRenderTargets,
int maxDualSourceDrawBuffers,
const std::vector<Uniform> &uniforms, const std::vector<Uniform> &uniforms,
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
sh::WorkGroupSize workGroupSize, sh::WorkGroupSize workGroupSize,
...@@ -249,6 +250,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -249,6 +250,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
mInsideFunction(false), mInsideFunction(false),
mInsideMain(false), mInsideMain(false),
mNumRenderTargets(numRenderTargets), mNumRenderTargets(numRenderTargets),
mMaxDualSourceDrawBuffers(maxDualSourceDrawBuffers),
mCurrentFunctionMetadata(nullptr), mCurrentFunctionMetadata(nullptr),
mWorkGroupSize(workGroupSize), mWorkGroupSize(workGroupSize),
mPerfDiagnostics(perfDiagnostics) mPerfDiagnostics(perfDiagnostics)
...@@ -276,6 +278,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -276,6 +278,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
mUsesNestedBreak = false; mUsesNestedBreak = false;
mRequiresIEEEStrictCompiling = false; mRequiresIEEEStrictCompiling = false;
mUseZeroArray = false; mUseZeroArray = false;
mUsesSecondaryColor = false;
mUniqueIndex = 0; mUniqueIndex = 0;
...@@ -630,6 +633,8 @@ void OutputHLSL::header(TInfoSinkBase &out, ...@@ -630,6 +633,8 @@ void OutputHLSL::header(TInfoSinkBase &out,
{ {
const bool usingMRTExtension = const bool usingMRTExtension =
IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers); IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers);
const bool usingBFEExtension =
IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_blend_func_extended);
out << "// Varyings\n"; out << "// Varyings\n";
writeReferencedVaryings(out); writeReferencedVaryings(out);
...@@ -664,6 +669,23 @@ void OutputHLSL::header(TInfoSinkBase &out, ...@@ -664,6 +669,23 @@ void OutputHLSL::header(TInfoSinkBase &out,
} }
out << "};\n"; out << "};\n";
if (usingBFEExtension && mUsesSecondaryColor)
{
out << "static float4 gl_SecondaryColor[" << mMaxDualSourceDrawBuffers
<< "] = \n"
"{\n";
for (int i = 0; i < mMaxDualSourceDrawBuffers; i++)
{
out << " float4(0, 0, 0, 0)";
if (i + 1 != mMaxDualSourceDrawBuffers)
{
out << ",";
}
out << "\n";
}
out << "};\n";
}
} }
if (mUsesFragDepth) if (mUsesFragDepth)
...@@ -781,6 +803,11 @@ void OutputHLSL::header(TInfoSinkBase &out, ...@@ -781,6 +803,11 @@ void OutputHLSL::header(TInfoSinkBase &out,
{ {
out << "#define GL_USES_FRAG_DATA\n"; out << "#define GL_USES_FRAG_DATA\n";
} }
if (mShaderVersion < 300 && usingBFEExtension && mUsesSecondaryColor)
{
out << "#define GL_USES_SECONDARY_COLOR\n";
}
} }
else if (mShaderType == GL_VERTEX_SHADER) else if (mShaderType == GL_VERTEX_SHADER)
{ {
...@@ -1118,6 +1145,16 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) ...@@ -1118,6 +1145,16 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
out << "gl_Color"; out << "gl_Color";
mUsesFragData = true; mUsesFragData = true;
} }
else if (qualifier == EvqSecondaryFragColorEXT)
{
out << "gl_SecondaryColor[0]";
mUsesSecondaryColor = true;
}
else if (qualifier == EvqSecondaryFragDataEXT)
{
out << "gl_SecondaryColor";
mUsesSecondaryColor = true;
}
else if (qualifier == EvqFragCoord) else if (qualifier == EvqFragCoord)
{ {
mUsesFragCoord = true; mUsesFragCoord = true;
......
...@@ -43,6 +43,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -43,6 +43,7 @@ class OutputHLSL : public TIntermTraverser
const char *sourcePath, const char *sourcePath,
ShShaderOutput outputType, ShShaderOutput outputType,
int numRenderTargets, int numRenderTargets,
int maxDualSourceDrawBuffers,
const std::vector<Uniform> &uniforms, const std::vector<Uniform> &uniforms,
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
sh::WorkGroupSize workGroupSize, sh::WorkGroupSize workGroupSize,
...@@ -207,8 +208,10 @@ class OutputHLSL : public TIntermTraverser ...@@ -207,8 +208,10 @@ class OutputHLSL : public TIntermTraverser
bool mUsesNestedBreak; bool mUsesNestedBreak;
bool mRequiresIEEEStrictCompiling; bool mRequiresIEEEStrictCompiling;
mutable bool mUseZeroArray; mutable bool mUseZeroArray;
bool mUsesSecondaryColor;
int mNumRenderTargets; int mNumRenderTargets;
int mMaxDualSourceDrawBuffers;
int mUniqueIndex; // For creating unique names int mUniqueIndex; // For creating unique names
......
...@@ -42,6 +42,8 @@ void TranslatorHLSL::translate(TIntermBlock *root, ...@@ -42,6 +42,8 @@ void TranslatorHLSL::translate(TIntermBlock *root,
{ {
const ShBuiltInResources &resources = getResources(); const ShBuiltInResources &resources = getResources();
int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
int maxDualSourceDrawBuffers =
resources.EXT_blend_func_extended ? resources.MaxDualSourceDrawBuffers : 0;
sh::AddDefaultReturnStatements(root); sh::AddDefaultReturnStatements(root);
...@@ -135,10 +137,10 @@ void TranslatorHLSL::translate(TIntermBlock *root, ...@@ -135,10 +137,10 @@ void TranslatorHLSL::translate(TIntermBlock *root,
sh::RewriteAtomicFunctionExpressions(root, &getSymbolTable(), getShaderVersion()); sh::RewriteAtomicFunctionExpressions(root, &getSymbolTable(), getShaderVersion());
} }
sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), sh::OutputHLSL outputHLSL(
getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), getShaderType(), getShaderVersion(), getExtensionBehavior(), getSourcePath(),
compileOptions, getComputeShaderLocalSize(), &getSymbolTable(), getOutputType(), numRenderTargets, maxDualSourceDrawBuffers, getUniforms(), compileOptions,
perfDiagnostics, mShaderStorageBlocks); getComputeShaderLocalSize(), &getSymbolTable(), perfDiagnostics, mShaderStorageBlocks);
outputHLSL.output(root, getInfoSink().obj); outputHLSL.output(root, getInfoSink().obj);
......
...@@ -59,7 +59,7 @@ HashStream &operator<<(HashStream &stream, const ProgramBindings &bindings) ...@@ -59,7 +59,7 @@ HashStream &operator<<(HashStream &stream, const ProgramBindings &bindings)
{ {
for (const auto &binding : bindings) for (const auto &binding : bindings)
{ {
stream << binding.first << binding.second; stream << binding.first << binding.second.location;
} }
return stream; return stream;
} }
......
...@@ -179,6 +179,11 @@ struct VariableLocation ...@@ -179,6 +179,11 @@ struct VariableLocation
void markUnused() { index = kUnused; } void markUnused() { index = kUnused; }
void markIgnored() { ignored = true; } void markIgnored() { ignored = true; }
bool operator==(const VariableLocation &other) const
{
return arrayIndex == other.arrayIndex && index == other.index;
}
// "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays.
unsigned int arrayIndex; unsigned int arrayIndex;
// "index" is an index of the variable. The variable contains the indices for other than the // "index" is an index of the variable. The variable contains the indices for other than the
...@@ -473,6 +478,16 @@ class ProgramState final : angle::NonCopyable ...@@ -473,6 +478,16 @@ class ProgramState final : angle::NonCopyable
ActiveTextureMask mActiveImagesMask; ActiveTextureMask mActiveImagesMask;
}; };
struct ProgramBinding
{
ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {}
ProgramBinding(GLuint index) : location(index), aliased(false) {}
GLuint location;
// Whether another binding was set that may potentially alias this.
bool aliased;
};
class ProgramBindings final : angle::NonCopyable class ProgramBindings final : angle::NonCopyable
{ {
public: public:
...@@ -480,14 +495,15 @@ class ProgramBindings final : angle::NonCopyable ...@@ -480,14 +495,15 @@ class ProgramBindings final : angle::NonCopyable
~ProgramBindings(); ~ProgramBindings();
void bindLocation(GLuint index, const std::string &name); void bindLocation(GLuint index, const std::string &name);
int getBinding(const std::string &name) const; int getBindingByName(const std::string &name) const;
int getBinding(const sh::VariableWithLocation &variable) const;
using const_iterator = std::unordered_map<std::string, GLuint>::const_iterator; using const_iterator = std::unordered_map<std::string, ProgramBinding>::const_iterator;
const_iterator begin() const; const_iterator begin() const;
const_iterator end() const; const_iterator end() const;
private: private:
std::unordered_map<std::string, GLuint> mBindings; std::unordered_map<std::string, ProgramBinding> mBindings;
}; };
struct ProgramVaryingRef struct ProgramVaryingRef
......
...@@ -32,20 +32,6 @@ LinkedUniform *FindUniform(std::vector<LinkedUniform> &list, const std::string & ...@@ -32,20 +32,6 @@ LinkedUniform *FindUniform(std::vector<LinkedUniform> &list, const std::string &
return nullptr; return nullptr;
} }
int GetUniformLocationBinding(const ProgramBindings &uniformLocationBindings,
const sh::Uniform &uniform)
{
int binding = uniformLocationBindings.getBinding(uniform.name);
if (uniform.isArray() && binding == -1)
{
// Bindings for array uniforms can be set either with or without [0] in the end.
ASSERT(angle::EndsWith(uniform.name, "[0]"));
std::string nameWithoutIndex = uniform.name.substr(0u, uniform.name.length() - 3u);
return uniformLocationBindings.getBinding(nameWithoutIndex);
}
return binding;
}
template <typename VarT> template <typename VarT>
void SetActive(std::vector<VarT> *list, const std::string &name, ShaderType shaderType, bool active) void SetActive(std::vector<VarT> *list, const std::string &name, ShaderType shaderType, bool active)
{ {
...@@ -664,7 +650,7 @@ bool UniformLinker::indexUniforms(InfoLog &infoLog, const ProgramBindings &unifo ...@@ -664,7 +650,7 @@ bool UniformLinker::indexUniforms(InfoLog &infoLog, const ProgramBindings &unifo
continue; continue;
} }
int preSetLocation = GetUniformLocationBinding(uniformLocationBindings, uniform); int preSetLocation = uniformLocationBindings.getBinding(uniform);
int shaderLocation = uniform.location; int shaderLocation = uniform.location;
if (shaderLocation != -1) if (shaderLocation != -1)
...@@ -740,7 +726,7 @@ bool UniformLinker::gatherUniformLocationsAndCheckConflicts( ...@@ -740,7 +726,7 @@ bool UniformLinker::gatherUniformLocationsAndCheckConflicts(
continue; continue;
} }
int apiBoundLocation = GetUniformLocationBinding(uniformLocationBindings, uniform); int apiBoundLocation = uniformLocationBindings.getBinding(uniform);
int shaderLocation = uniform.location; int shaderLocation = uniform.location;
if (shaderLocation != -1) if (shaderLocation != -1)
...@@ -785,7 +771,7 @@ bool UniformLinker::gatherUniformLocationsAndCheckConflicts( ...@@ -785,7 +771,7 @@ bool UniformLinker::gatherUniformLocationsAndCheckConflicts(
// from the shader. Other uniforms should not be assigned to those locations. // from the shader. Other uniforms should not be assigned to those locations.
for (const auto &locationBinding : uniformLocationBindings) for (const auto &locationBinding : uniformLocationBindings)
{ {
GLuint location = locationBinding.second; GLuint location = locationBinding.second.location;
if (reservedLocations.find(location) == reservedLocations.end()) if (reservedLocations.find(location) == reservedLocations.end())
{ {
ignoredLocations->insert(location); ignoredLocations->insert(location);
......
...@@ -97,13 +97,14 @@ void HLSLTypeString(std::ostringstream &ostream, GLenum type) ...@@ -97,13 +97,14 @@ void HLSLTypeString(std::ostringstream &ostream, GLenum type)
const PixelShaderOutputVariable *FindOutputAtLocation( const PixelShaderOutputVariable *FindOutputAtLocation(
const std::vector<PixelShaderOutputVariable> &outputVariables, const std::vector<PixelShaderOutputVariable> &outputVariables,
unsigned int location) unsigned int location,
size_t index = 0)
{ {
for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex) for (auto &outputVar : outputVariables)
{ {
if (outputVariables[variableIndex].outputIndex == location) if (outputVar.outputLocation == location && outputVar.outputIndex == index)
{ {
return &outputVariables[variableIndex]; return &outputVar;
} }
} }
...@@ -294,7 +295,9 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( ...@@ -294,7 +295,9 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(
{ {
numOutputs = 1u; numOutputs = 1u;
} }
const PixelShaderOutputVariable defaultOutput(GL_FLOAT_VEC4, "dummy", "float4(0, 0, 0, 1)", 0); const PixelShaderOutputVariable defaultOutput(GL_FLOAT_VEC4, "dummy", "float4(0, 0, 0, 1)", 0,
0);
size_t outputIndex = 0;
for (size_t layoutIndex = 0; layoutIndex < numOutputs; ++layoutIndex) for (size_t layoutIndex = 0; layoutIndex < numOutputs; ++layoutIndex)
{ {
...@@ -303,15 +306,16 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( ...@@ -303,15 +306,16 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(
if (binding != GL_NONE) if (binding != GL_NONE)
{ {
unsigned int location = (binding - GL_COLOR_ATTACHMENT0); unsigned int location = (binding - GL_COLOR_ATTACHMENT0);
outputIndex =
layoutIndex > 0 && binding == outputLayout[layoutIndex - 1] ? outputIndex + 1 : 0;
const PixelShaderOutputVariable *outputVariable = const PixelShaderOutputVariable *outputVariable =
outputLayout.empty() ? &defaultOutput outputLayout.empty() ? &defaultOutput
: FindOutputAtLocation(outputVariables, location); : FindOutputAtLocation(outputVariables, location, outputIndex);
// OpenGL ES 3.0 spec $4.2.1 // OpenGL ES 3.0 spec $4.2.1
// If [...] not all user-defined output variables are written, the values of fragment // If [...] not all user-defined output variables are written, the values of fragment
// colors // colors corresponding to unwritten variables are similarly undefined.
// corresponding to unwritten variables are similarly undefined.
if (outputVariable) if (outputVariable)
{ {
declarationStream << " "; declarationStream << " ";
...@@ -1204,10 +1208,26 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data, ...@@ -1204,10 +1208,26 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data,
outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex); outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
outputKeyVariable.source = outputKeyVariable.source =
broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]"; broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
outputKeyVariable.outputIndex = renderTargetIndex; outputKeyVariable.outputLocation = renderTargetIndex;
outPixelShaderKey->push_back(outputKeyVariable); outPixelShaderKey->push_back(outputKeyVariable);
} }
if (metadata.usesSecondaryColor())
{
for (unsigned int secondaryIndex = 0;
secondaryIndex < data.getExtensions().maxDualSourceDrawBuffers; secondaryIndex++)
{
PixelShaderOutputVariable outputKeyVariable;
outputKeyVariable.type = GL_FLOAT_VEC4;
outputKeyVariable.name = "gl_SecondaryColor" + Str(secondaryIndex);
outputKeyVariable.source = "gl_SecondaryColor[" + Str(secondaryIndex) + "]";
outputKeyVariable.outputLocation = secondaryIndex;
outputKeyVariable.outputIndex = 1;
outPixelShaderKey->push_back(outputKeyVariable);
}
}
} }
else else
{ {
...@@ -1238,7 +1258,39 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data, ...@@ -1238,7 +1258,39 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data,
outputKeyVariable.source = outputKeyVariable.source =
variableName + variableName +
(outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : ""); (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : "");
outputKeyVariable.outputIndex = outputLocationIndex; outputKeyVariable.outputLocation = outputLocationIndex;
outPixelShaderKey->push_back(outputKeyVariable);
}
// Now generate any secondary outputs...
for (size_t outputLocationIndex = 0u;
outputLocationIndex < programData.getSecondaryOutputLocations().size();
++outputLocationIndex)
{
const VariableLocation &outputLocation =
programData.getSecondaryOutputLocations().at(outputLocationIndex);
if (!outputLocation.used())
{
continue;
}
const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
const std::string &variableName = "out_" + outputVariable.name;
// Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6.
const std::string &elementString =
(outputVariable.isArray() ? Str(outputLocation.arrayIndex) : "");
ASSERT(outputVariable.active);
PixelShaderOutputVariable outputKeyVariable;
outputKeyVariable.type = outputVariable.type;
outputKeyVariable.name = variableName + elementString;
outputKeyVariable.source =
variableName +
(outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : "");
outputKeyVariable.outputLocation = outputLocationIndex;
outputKeyVariable.outputIndex = 1;
outPixelShaderKey->push_back(outputKeyVariable); outPixelShaderKey->push_back(outputKeyVariable);
} }
......
...@@ -67,13 +67,19 @@ struct PixelShaderOutputVariable ...@@ -67,13 +67,19 @@ struct PixelShaderOutputVariable
PixelShaderOutputVariable(GLenum typeIn, PixelShaderOutputVariable(GLenum typeIn,
const std::string &nameIn, const std::string &nameIn,
const std::string &sourceIn, const std::string &sourceIn,
size_t outputLocationIn,
size_t outputIndexIn) size_t outputIndexIn)
: type(typeIn), name(nameIn), source(sourceIn), outputIndex(outputIndexIn) : type(typeIn),
name(nameIn),
source(sourceIn),
outputLocation(outputLocationIn),
outputIndex(outputIndexIn)
{} {}
GLenum type = GL_NONE; GLenum type = GL_NONE;
std::string name; std::string name;
std::string source; std::string source;
size_t outputLocation = 0;
size_t outputIndex = 0; size_t outputIndex = 0;
}; };
......
...@@ -67,6 +67,20 @@ void GetDefaultInputLayoutFromShader(gl::Shader *vertexShader, gl::InputLayout * ...@@ -67,6 +67,20 @@ void GetDefaultInputLayoutFromShader(gl::Shader *vertexShader, gl::InputLayout *
} }
} }
size_t GetMaxOutputIndex(const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
size_t location)
{
size_t maxIndex = 0;
for (auto &outputVar : shaderOutputVars)
{
if (outputVar.outputLocation == location)
{
maxIndex = std::max(maxIndex, outputVar.outputIndex);
}
}
return maxIndex;
}
void GetDefaultOutputLayoutFromShader( void GetDefaultOutputLayoutFromShader(
const std::vector<PixelShaderOutputVariable> &shaderOutputVars, const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
std::vector<GLenum> *outputLayoutOut) std::vector<GLenum> *outputLayoutOut)
...@@ -75,8 +89,10 @@ void GetDefaultOutputLayoutFromShader( ...@@ -75,8 +89,10 @@ void GetDefaultOutputLayoutFromShader(
if (!shaderOutputVars.empty()) if (!shaderOutputVars.empty())
{ {
outputLayoutOut->push_back(GL_COLOR_ATTACHMENT0 + size_t location = shaderOutputVars[0].outputLocation;
static_cast<unsigned int>(shaderOutputVars[0].outputIndex)); size_t maxIndex = GetMaxOutputIndex(shaderOutputVars, location);
outputLayoutOut->assign(maxIndex + 1,
GL_COLOR_ATTACHMENT0 + static_cast<unsigned int>(location));
} }
} }
...@@ -477,6 +493,11 @@ bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const ...@@ -477,6 +493,11 @@ bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const
data.getClientMajorVersion() < 3); data.getClientMajorVersion() < 3);
} }
bool ProgramD3DMetadata::usesSecondaryColor() const
{
return mAttachedShaders[gl::ShaderType::Fragment]->usesSecondaryColor();
}
bool ProgramD3DMetadata::usesFragDepth() const bool ProgramD3DMetadata::usesFragDepth() const
{ {
return mAttachedShaders[gl::ShaderType::Fragment]->usesFragDepth(); return mAttachedShaders[gl::ShaderType::Fragment]->usesFragDepth();
...@@ -1166,6 +1187,7 @@ std::unique_ptr<rx::LinkEvent> ProgramD3D::load(const gl::Context *context, ...@@ -1166,6 +1187,7 @@ std::unique_ptr<rx::LinkEvent> ProgramD3D::load(const gl::Context *context,
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type); stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name); stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source); stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputLocation);
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
} }
...@@ -1449,6 +1471,7 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1449,6 +1471,7 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeInt(variable.type); stream->writeInt(variable.type);
stream->writeString(variable.name); stream->writeString(variable.name);
stream->writeString(variable.source); stream->writeString(variable.source);
stream->writeInt(variable.outputLocation);
stream->writeInt(variable.outputIndex); stream->writeInt(variable.outputIndex);
} }
...@@ -3048,7 +3071,11 @@ void ProgramD3D::updateCachedOutputLayout(const gl::Context *context, ...@@ -3048,7 +3071,11 @@ void ProgramD3D::updateCachedOutputLayout(const gl::Context *context,
{ {
auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0
: colorbuffer->getBinding(); : colorbuffer->getBinding();
mPixelShaderOutputLayoutCache.push_back(binding); size_t maxIndex = binding != GL_NONE ? GetMaxOutputIndex(mPixelShaderKey,
binding - GL_COLOR_ATTACHMENT0)
: 0;
mPixelShaderOutputLayoutCache.insert(mPixelShaderOutputLayoutCache.end(), maxIndex + 1,
binding);
} }
else else
{ {
......
...@@ -122,6 +122,7 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -122,6 +122,7 @@ class ProgramD3DMetadata final : angle::NonCopyable
int getRendererMajorShaderModel() const; int getRendererMajorShaderModel() const;
bool usesBroadcast(const gl::State &data) const; bool usesBroadcast(const gl::State &data) const;
bool usesSecondaryColor() const;
bool usesFragDepth() const; bool usesFragDepth() const;
bool usesPointCoord() const; bool usesPointCoord() const;
bool usesFragCoord() const; bool usesFragCoord() const;
......
...@@ -150,6 +150,7 @@ void ShaderD3D::uncompile() ...@@ -150,6 +150,7 @@ void ShaderD3D::uncompile()
mUsesMultipleRenderTargets = false; mUsesMultipleRenderTargets = false;
mUsesFragColor = false; mUsesFragColor = false;
mUsesFragData = false; mUsesFragData = false;
mUsesSecondaryColor = false;
mUsesFragCoord = false; mUsesFragCoord = false;
mUsesFrontFacing = false; mUsesFrontFacing = false;
mUsesPointSize = false; mUsesPointSize = false;
...@@ -272,6 +273,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderD3D::compile(const gl::Context *cont ...@@ -272,6 +273,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderD3D::compile(const gl::Context *cont
mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos; mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos;
mUsesFragColor = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos; mUsesFragColor = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos;
mUsesFragData = translatedSource.find("GL_USES_FRAG_DATA") != std::string::npos; mUsesFragData = translatedSource.find("GL_USES_FRAG_DATA") != std::string::npos;
mUsesSecondaryColor = translatedSource.find("GL_USES_SECONDARY_COLOR") != std::string::npos;
mUsesFragCoord = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos; mUsesFragCoord = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos;
mUsesFrontFacing = translatedSource.find("GL_USES_FRONT_FACING") != std::string::npos; mUsesFrontFacing = translatedSource.find("GL_USES_FRONT_FACING") != std::string::npos;
mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos; mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos;
......
...@@ -65,6 +65,7 @@ class ShaderD3D : public ShaderImpl ...@@ -65,6 +65,7 @@ class ShaderD3D : public ShaderImpl
bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; } bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; }
bool usesFragColor() const { return mUsesFragColor; } bool usesFragColor() const { return mUsesFragColor; }
bool usesFragData() const { return mUsesFragData; } bool usesFragData() const { return mUsesFragData; }
bool usesSecondaryColor() const { return mUsesSecondaryColor; }
bool usesFragCoord() const { return mUsesFragCoord; } bool usesFragCoord() const { return mUsesFragCoord; }
bool usesFrontFacing() const { return mUsesFrontFacing; } bool usesFrontFacing() const { return mUsesFrontFacing; }
bool usesPointSize() const { return mUsesPointSize; } bool usesPointSize() const { return mUsesPointSize; }
...@@ -81,6 +82,7 @@ class ShaderD3D : public ShaderImpl ...@@ -81,6 +82,7 @@ class ShaderD3D : public ShaderImpl
bool mUsesMultipleRenderTargets; bool mUsesMultipleRenderTargets;
bool mUsesFragColor; bool mUsesFragColor;
bool mUsesFragData; bool mUsesFragData;
bool mUsesSecondaryColor;
bool mUsesFragCoord; bool mUsesFragCoord;
bool mUsesFrontFacing; bool mUsesFrontFacing;
bool mUsesPointSize; bool mUsesPointSize;
......
...@@ -1649,6 +1649,8 @@ void GenerateCaps(ID3D11Device *device, ...@@ -1649,6 +1649,8 @@ void GenerateCaps(ID3D11Device *device,
extensions->textureBorderClamp = true; extensions->textureBorderClamp = true;
extensions->textureMultisample = true; extensions->textureMultisample = true;
extensions->provokingVertex = true; extensions->provokingVertex = true;
extensions->blendFuncExtended = true;
extensions->maxDualSourceDrawBuffers = 1;
// D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing. // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't
...@@ -1751,6 +1753,18 @@ D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) ...@@ -1751,6 +1753,18 @@ D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
case GL_SRC_ALPHA_SATURATE: case GL_SRC_ALPHA_SATURATE:
d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;
break; break;
case GL_SRC1_COLOR_EXT:
d3dBlend = (isAlpha ? D3D11_BLEND_SRC1_ALPHA : D3D11_BLEND_SRC1_COLOR);
break;
case GL_SRC1_ALPHA_EXT:
d3dBlend = D3D11_BLEND_SRC1_ALPHA;
break;
case GL_ONE_MINUS_SRC1_COLOR_EXT:
d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC1_COLOR);
break;
case GL_ONE_MINUS_SRC1_ALPHA_EXT:
d3dBlend = D3D11_BLEND_INV_SRC1_ALPHA;
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
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