Implement more rounding-related GLSL extended instructions

This commit is contained in:
baldurk
2020-04-15 14:34:28 +01:00
parent 39ed21c12f
commit 26f5b6a4b4
2 changed files with 167 additions and 1 deletions
@@ -37,6 +37,40 @@ namespace glsl
return ShaderVariable(); \
}
ShaderVariable RoundEven(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
ShaderVariable var = state.GetSrc(params[0]);
for(uint32_t c = 0; c < var.columns; c++)
{
float x = var.value.fv[c];
if(!isinf(x) && !isnan(x))
var.value.fv[c] = x - remainderf(x, 1.0f);
}
return var;
}
ShaderVariable Round(ThreadState &state, const rdcarray<Id> &params)
{
// for now do as the spec allows and implement this as RoundEven
return RoundEven(state, params);
}
ShaderVariable Trunc(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
ShaderVariable var = state.GetSrc(params[0]);
for(uint32_t c = 0; c < var.columns; c++)
var.value.fv[c] = truncf(var.value.fv[c]);
return var;
}
ShaderVariable FAbs(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
@@ -61,6 +95,41 @@ ShaderVariable SAbs(ThreadState &state, const rdcarray<Id> &params)
return var;
}
ShaderVariable FSign(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
ShaderVariable var = state.GetSrc(params[0]);
for(uint32_t c = 0; c < var.columns; c++)
{
if(var.value.fv[c] > 0.0f)
var.value.fv[c] = 1.0f;
else if(var.value.fv[c] < 0.0f)
var.value.fv[c] = -1.0f;
}
return var;
}
ShaderVariable SSign(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
ShaderVariable var = state.GetSrc(params[0]);
for(uint32_t c = 0; c < var.columns; c++)
{
if(var.value.iv[c] > 0)
var.value.iv[c] = 1;
else if(var.value.iv[c] < 0)
var.value.iv[c] = -1;
// 0 is left alone
}
return var;
}
ShaderVariable Floor(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
@@ -73,6 +142,30 @@ ShaderVariable Floor(ThreadState &state, const rdcarray<Id> &params)
return var;
}
ShaderVariable Ceil(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
ShaderVariable var = state.GetSrc(params[0]);
for(uint32_t c = 0; c < var.columns; c++)
var.value.fv[c] = ceilf(var.value.fv[c]);
return var;
}
ShaderVariable Fract(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(1);
ShaderVariable var = state.GetSrc(params[0]);
for(uint32_t c = 0; c < var.columns; c++)
var.value.fv[c] = var.value.fv[c] - floorf(var.value.fv[c]);
return var;
}
ShaderVariable Pow(ThreadState &state, const rdcarray<Id> &params)
{
CHECK_PARAMS(2);
@@ -349,10 +442,20 @@ void ConfigureGLSLStd450(ExtInstDispatcher &extinst)
extinst.functions.resize(extinst.names.size());
#define EXT(func) extinst.functions[(uint32_t)GLSLstd450::func] = &glsl::func;
#define EXT(func) \
extinst.functions[(uint32_t)GLSLstd450::func] = &glsl::func; \
uint32_t noduplicate##func; \
(void)noduplicate##func;
EXT(Round);
EXT(RoundEven);
EXT(Trunc);
EXT(FAbs);
EXT(SAbs);
EXT(FSign);
EXT(SSign);
EXT(Floor);
EXT(Ceil);
EXT(Fract);
EXT(Pow);
EXT(FMin);
EXT(UMin);
@@ -508,6 +508,69 @@ void main()
Color = vec4(push.data);
break;
}
case 57:
{
Color = vec4(roundEven(posone*2.5f), roundEven(posone*3.5f), roundEven(posone*4.5f), roundEven(posone*5.1f));
break;
}
case 58:
{
Color = vec4(roundEven(negone*2.5f), roundEven(negone*3.5f), roundEven(negone*4.5f), roundEven(negone*5.1f));
break;
}
case 59:
{
// avoid implementation-defined behaviour at half-way points
Color = vec4(round(posone*2.4f), round(posone*3.6f), round(posone*4.6f), round(posone*5.1f));
break;
}
case 60:
{
Color = vec4(round(negone*2.6f), round(negone*3.6f), round(negone*4.6f), round(posone*5.1f));
break;
}
case 61:
{
Color = vec4(trunc(posone*2.4f), trunc(posone*2.5f), trunc(posone*2.6f), trunc(posone*5.1f));
break;
}
case 62:
{
Color = vec4(trunc(negone*2.4f), trunc(negone*2.5f), trunc(negone*2.6f), trunc(negone*3.1f));
break;
}
case 63:
{
Color = vec4(fract(posone*2.4f), fract(posone*2.5f), fract(posone*2.6f), fract(posone*3.1f));
break;
}
case 64:
{
Color = vec4(fract(negone*2.4f), fract(negone*2.5f), fract(negone*2.6f), fract(negone*3.1f));
break;
}
case 65:
{
Color = vec4(ceil(posone*2.4f), ceil(posone*2.5f), ceil(posone*2.6f), ceil(posone*3.1f));
break;
}
case 66:
{
Color = vec4(ceil(negone*2.4f), ceil(negone*2.5f), ceil(negone*2.6f), ceil(negone*3.1f));
break;
}
case 67:
{
Color = vec4(sign(negone*2.4f), sign(posone*2.4f), sign(posinf), sign(neginf));
break;
}
case 68:
{
int onei = zeroi+1;
int negi = zeroi-1;
Color = vec4(float(sign(onei*2)), float(sign(negi*2)), float(sign(0)), 1.0f);
break;
}
default: break;
}
}