зеркало из https://github.com/mozilla/gecko-dev.git
Bug 771406 - Add emulation for GLSL faceForward() to ANGLE - r=bjacob
This commit is contained in:
Родитель
678dc6693c
Коммит
c94de51f41
|
@ -31,6 +31,12 @@ const char* kFunctionEmulationVertexSource[] = {
|
|||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
// |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
|
||||
"#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
|
||||
"#error no emulation for faceforward(vec2, vec2, vec2)",
|
||||
"#error no emulation for faceforward(vec3, vec3, vec3)",
|
||||
"#error no emulation for faceforward(vec4, vec4, vec4)",
|
||||
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
|
@ -63,6 +69,12 @@ const char* kFunctionEmulationFragmentSource[] = {
|
|||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
// |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
|
||||
"#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
|
||||
"#error no emulation for faceforward(vec2, vec2, vec2)",
|
||||
"#error no emulation for faceforward(vec3, vec3, vec3)",
|
||||
"#error no emulation for faceforward(vec4, vec4, vec4)",
|
||||
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
|
@ -94,6 +106,10 @@ const bool kFunctionEmulationVertexMask[] = {
|
|||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
true, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
|
@ -120,6 +136,10 @@ const bool kFunctionEmulationVertexMask[] = {
|
|||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
false, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
|
@ -151,6 +171,10 @@ const bool kFunctionEmulationFragmentMask[] = {
|
|||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
true, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
|
@ -177,6 +201,10 @@ const bool kFunctionEmulationFragmentMask[] = {
|
|||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
false, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
|
@ -244,15 +272,27 @@ public:
|
|||
return true;
|
||||
};
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
// Right now we only handle built-in functions with two parameters.
|
||||
if (sequence.size() != 2)
|
||||
bool needToEmulate = false;
|
||||
|
||||
if (sequence.size() == 2) {
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
if (!param1 || !param2)
|
||||
return true;
|
||||
needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType());
|
||||
} else if (sequence.size() == 3) {
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
TIntermTyped* param3 = sequence[2]->getAsTyped();
|
||||
if (!param1 || !param2 || !param3)
|
||||
return true;
|
||||
needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType(), param3->getType());
|
||||
} else {
|
||||
return true;
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
if (!param1 || !param2)
|
||||
return true;
|
||||
bool needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType());
|
||||
}
|
||||
|
||||
if (needToEmulate)
|
||||
node->setUseEmulatedFunction();
|
||||
}
|
||||
|
@ -290,6 +330,13 @@ bool BuiltInFunctionEmulator::SetFunctionCalled(
|
|||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param1, param2, param3);
|
||||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
BuiltInFunctionEmulator::TBuiltInFunction function) {
|
||||
if (function == TFunctionUnknown || mFunctionMask[function] == false)
|
||||
|
@ -382,6 +429,34 @@ BuiltInFunctionEmulator::IdentifyFunction(
|
|||
return static_cast<TBuiltInFunction>(function);
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::TBuiltInFunction
|
||||
BuiltInFunctionEmulator::IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
{
|
||||
// Check that all params have the same type, length,
|
||||
// and that they're not too large.
|
||||
if (param1.isVector() != param2.isVector() ||
|
||||
param2.isVector() != param3.isVector() ||
|
||||
param1.getNominalSize() != param2.getNominalSize() ||
|
||||
param2.getNominalSize() != param3.getNominalSize() ||
|
||||
param1.getNominalSize() > 4)
|
||||
return TFunctionUnknown;
|
||||
|
||||
unsigned int function = TFunctionUnknown;
|
||||
switch (op) {
|
||||
case EOpFaceForward:
|
||||
function = TFunctionFaceForward1_1_1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (function == TFunctionUnknown)
|
||||
return TFunctionUnknown;
|
||||
if (param1.isVector())
|
||||
function += param1.getNominalSize() - 1;
|
||||
return static_cast<TBuiltInFunction>(function);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
|
||||
TIntermNode* root)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
bool SetFunctionCalled(TOperator op, const TType& param);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
// Output function emulation definition. This should be before any other
|
||||
// shader source.
|
||||
|
@ -60,6 +62,11 @@ private:
|
|||
TFunctionDot3_3, // vec3 dot(vec3, vec3);
|
||||
TFunctionDot4_4, // vec4 dot(vec4, vec4);
|
||||
|
||||
TFunctionFaceForward1_1_1, // float faceforward(float, float, float);
|
||||
TFunctionFaceForward2_2_2, // vec2 faceforward(vec2, vec2, vec2);
|
||||
TFunctionFaceForward3_3_3, // vec3 faceforward(vec3, vec3, vec3);
|
||||
TFunctionFaceForward4_4_4, // vec4 faceforward(vec4, vec4, vec4);
|
||||
|
||||
TFunctionLength1, // float length(float);
|
||||
TFunctionLength2, // float length(vec2);
|
||||
TFunctionLength3, // float length(vec3);
|
||||
|
@ -81,6 +88,8 @@ private:
|
|||
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
bool SetFunctionCalled(TBuiltInFunction function);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче