Support for fragment output location
Fragment output layout qualifiers may contain location,
which was currently ignored by SwiftShader. Pre-declared
fragment outputs that have a valid location at the correct
location within the fragmentOutputs array to solve this.
Fixes all failures in WebGL 2 tests:
all/deqp/functional/gles3/fragmentoutput/*
Change-Id: I30e004449fb90713984b3481abb24c5d0cd6e867
Reviewed-on: https://swiftshader-review.googlesource.com/16788
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 5f05e46..fbdc113 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -676,6 +676,9 @@
declareVarying(symbol, -1);
}
break;
+ case EvqFragmentOut:
+ declareFragmentOutput(symbol);
+ break;
default:
break;
}
@@ -3148,6 +3151,34 @@
}
}
+ void OutputASM::declareFragmentOutput(TIntermTyped *fragmentOutput)
+ {
+ int requestedLocation = fragmentOutput->getType().getLayoutQualifier().location;
+ if((requestedLocation >= 0) && (requestedLocation < sw::RENDERTARGETS))
+ {
+ if(fragmentOutputs.size() <= requestedLocation)
+ {
+ while(fragmentOutputs.size() < requestedLocation)
+ {
+ fragmentOutputs.push_back(nullptr);
+ }
+ fragmentOutputs.push_back(fragmentOutput);
+ }
+ else if(!fragmentOutputs[requestedLocation])
+ {
+ fragmentOutputs[requestedLocation] = fragmentOutput;
+ }
+ else
+ {
+ mContext.error(fragmentOutput->getLine(), "Fragment output location aliasing", "fragment shader");
+ }
+ }
+ else if(requestedLocation >= sw::RENDERTARGETS)
+ {
+ mContext.error(fragmentOutput->getLine(), "Fragment output location larger or equal to MAX_DRAW_BUFFERS", "fragment shader");
+ }
+ }
+
int OutputASM::uniformRegister(TIntermTyped *uniform)
{
const TType &type = uniform->getType();
diff --git a/src/OpenGL/compiler/OutputASM.h b/src/OpenGL/compiler/OutputASM.h
index 642508a..c315ef1 100644
--- a/src/OpenGL/compiler/OutputASM.h
+++ b/src/OpenGL/compiler/OutputASM.h
@@ -297,6 +297,7 @@
void setPixelShaderInputs(const TType& type, int var, bool flat);
void declareVarying(TIntermTyped *varying, int reg);
void declareVarying(const TType &type, const TString &name, int registerIndex);
+ void declareFragmentOutput(TIntermTyped *fragmentOutput);
int uniformRegister(TIntermTyped *uniform);
int attributeRegister(TIntermTyped *attribute);
int fragmentOutputRegister(TIntermTyped *fragmentOutput);