Add support for misc math GLSL opcodes that don't have struct variants

* step, smoothstep
* ldexp
* fma
* faceforward, reflect
This commit is contained in:
baldurk
2020-04-16 11:21:38 +01:00
parent 0df63aa8d0
commit 217a693487
3 changed files with 162 additions and 0 deletions
@@ -407,6 +407,54 @@ ShaderVariable FMix(ThreadState &state, uint32_t, const rdcarray<Id> &params)
return var;
}
ShaderVariable Step(ThreadState &state, uint32_t, const rdcarray<Id> &params)
{
CHECK_PARAMS(2);
ShaderVariable edge = state.GetSrc(params[0]);
ShaderVariable x = state.GetSrc(params[1]);
for(uint32_t c = 0; c < x.columns; c++)
x.value.fv[c] = x.value.fv[c] < edge.value.fv[c] ? 0.0f : 1.0f;
return x;
}
ShaderVariable SmoothStep(ThreadState &state, uint32_t, const rdcarray<Id> &params)
{
CHECK_PARAMS(3);
ShaderVariable edge0 = state.GetSrc(params[0]);
ShaderVariable edge1 = state.GetSrc(params[1]);
ShaderVariable x = state.GetSrc(params[2]);
for(uint32_t c = 0; c < x.columns; c++)
{
const float edge0f = edge0.value.fv[c];
const float edge1f = edge1.value.fv[c];
const float xf = x.value.fv[c];
const float t = GLSLMin(GLSLMax((xf - edge0f) / (edge1f - edge0f), 0.0f), 1.0f);
x.value.fv[c] = t * t * (3 - 2 * t);
}
return x;
}
ShaderVariable Ldexp(ThreadState &state, uint32_t, const rdcarray<Id> &params)
{
CHECK_PARAMS(2);
ShaderVariable x = state.GetSrc(params[0]);
ShaderVariable exp = state.GetSrc(params[1]);
for(uint8_t c = 0; c < x.columns; c++)
x.value.fv[c] = ldexpf(x.value.fv[c], exp.value.iv[c]);
return x;
}
ShaderVariable Cross(ThreadState &state, uint32_t, const rdcarray<Id> &params)
{
CHECK_PARAMS(2);
@@ -425,6 +473,44 @@ ShaderVariable Cross(ThreadState &state, uint32_t, const rdcarray<Id> &params)
return var;
}
ShaderVariable FaceForward(ThreadState &state, uint32_t, const rdcarray<Id> &params)
{
CHECK_PARAMS(3);
ShaderVariable N = state.GetSrc(params[0]);
ShaderVariable I = state.GetSrc(params[1]);
ShaderVariable Nref = state.GetSrc(params[1]);
float dot = 0;
for(uint8_t c = 0; c < Nref.columns; c++)
dot += Nref.value.fv[c] * I.value.fv[c];
if(dot >= 0.0f)
{
for(uint8_t c = 0; c < Nref.columns; c++)
N.value.fv[c] = -N.value.fv[c];
}
return N;
}
ShaderVariable Reflect(ThreadState &state, uint32_t, const rdcarray<Id> &params)
{
CHECK_PARAMS(2);
ShaderVariable I = state.GetSrc(params[0]);
ShaderVariable N = state.GetSrc(params[1]);
float dot = 0;
for(uint8_t c = 0; c < N.columns; c++)
dot += N.value.fv[c] * I.value.fv[c];
for(uint8_t c = 0; c < N.columns; c++)
N.value.fv[c] = I.value.fv[c] - 2.0f * dot * N.value.fv[c];
return N;
}
static float GLSLNMax(float x, float y)
{
const bool xnan = isnan(x);
@@ -541,7 +627,12 @@ void ConfigureGLSLStd450(ExtInstDispatcher &extinst)
EXT(UClamp);
EXT(SClamp);
EXT(FMix);
EXT(Step);
EXT(SmoothStep);
EXT(Ldexp);
EXT(Cross);
EXT(FaceForward);
EXT(Reflect);
EXT(NMin);
EXT(NMax);
EXT(NClamp);
@@ -572,6 +663,7 @@ void ConfigureGLSLStd450(ExtInstDispatcher &extinst)
GPU_EXT(Log2)
GPU_EXT(Sqrt)
GPU_EXT(InverseSqrt)
GPU_EXT(Fma)
GPU_EXT(Length);
GPU_EXT(Distance);
GPU_EXT(Normalize);
@@ -1166,6 +1166,19 @@ private:
rdcspv::Id zerof = editor.AddConstantImmediate<float>(0.0f);
{
rdcspv::GLSLstd450 op = rdcspv::GLSLstd450::Fma;
rdcspv::Id label = editor.MakeId();
targets.push_back({(uint32_t)op, label});
cases.add(rdcspv::OpLabel(label));
rdcspv::Id result =
cases.add(rdcspv::OpGLSL450(v4f32, editor.MakeId(), glsl450, op, {a, b, c}));
cases.add(rdcspv::OpStore(outVar, result));
cases.add(rdcspv::OpBranch(breakLabel));
}
// these ones are special
{
rdcspv::GLSLstd450 op = rdcspv::GLSLstd450::Length;
@@ -478,6 +478,8 @@ void main()
Color = fwidthCoarse(vec4(inpos, inposIncreased));
break;
}
)EOSHADER"
R"EOSHADER(
case 51:
{
Color = fwidthFine(vec4(inpos, inposIncreased));
@@ -698,6 +700,61 @@ void main()
Color = refract(a, b, zerof+3.1f);
break;
}
case 89:
{
Color = vec4(fma(zerof+2.4f, posone*0.1f, posone*8.3f),
fma(zerof+2.4f, posone*0.0f, posone*8.3f),
fma(zerof+3.675f, posone*9.703f, posone*1.45f),
((zerof+3.675f) * (posone*9.703f)) + posone*1.45f);
break;
}
case 90:
{
Color = vec4(step(posone*2.6f, zerof+2.4f),
step(posone*2.6f, zerof+2.5f),
step(posone*2.6f, zerof+2.6f),
step(posone*2.6f, zerof+2.7f));
break;
}
case 91:
{
Color = vec4(smoothstep(posone*2.0f, posone*2.6f, zerof+1.9f),
smoothstep(posone*2.0f, posone*2.6f, zerof+2.0f),
smoothstep(posone*2.0f, posone*2.6f, zerof+2.1f),
smoothstep(posone*2.0f, posone*2.6f, zerof+2.3f));
break;
}
case 92:
{
Color = vec4(smoothstep(posone*2.0f, posone*2.6f, zerof+2.4f),
smoothstep(posone*2.0f, posone*2.6f, zerof+2.5f),
smoothstep(posone*2.0f, posone*2.6f, zerof+2.6f),
smoothstep(posone*2.0f, posone*2.6f, zerof+2.8f));
break;
}
case 93:
{
vec4 N = vec4(posone*1.4f, posone*2.8f, posone*5.6f, posone*4.4f);
vec4 I = vec4(posone*3.7f, posone*2.2f, posone*6.1f, posone*9.5f);
vec4 Nref = vec4(posone*6.4f, posone*7.5f, posone*8.3f, posone*0.9f);
Color = faceforward(N, I, Nref);
break;
}
case 94:
{
vec4 N = vec4(posone*1.4f, posone*2.8f, posone*5.6f, posone*4.4f);
vec4 I = vec4(posone*3.7f, posone*2.2f, posone*6.1f, posone*9.5f);
Color = reflect(N, I);
break;
}
case 95:
{
Color = vec4(ldexp(posone*1.4f, zeroi-3),
ldexp(posone*2.8f, zeroi+0),
ldexp(posone*5.6f, zeroi+3),
ldexp(posone*4.4f, zeroi+7));
break;
}
default: break;
}
}