mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 17:40:39 +00:00
Use NaN-friendly behaviour for all mins and maxs in SPIR-V
* This matches the explicitly documented behaviour for D3D so it likely matches what GPUs do, and since SPIR-V leaves it undefined it's OK to do what we want. This does mean that there might be false negatives of cases where the GPU gets bad results and the simulation 'works', but this is preferable and less likely than false positives of the simulation going (legally) wrong when the GPU result is correct.
This commit is contained in:
@@ -306,6 +306,58 @@ static T GLSLMin(T x, T y)
|
||||
return y < x ? y : x;
|
||||
}
|
||||
|
||||
template <>
|
||||
static float GLSLMax(float x, float y)
|
||||
{
|
||||
const bool xnan = RDCISNAN(x);
|
||||
const bool ynan = RDCISNAN(y);
|
||||
if(xnan && !ynan)
|
||||
return y;
|
||||
else if(!xnan && ynan)
|
||||
return x;
|
||||
else
|
||||
return x < y ? y : x;
|
||||
}
|
||||
|
||||
template <>
|
||||
static float GLSLMin(float x, float y)
|
||||
{
|
||||
const bool xnan = RDCISNAN(x);
|
||||
const bool ynan = RDCISNAN(y);
|
||||
if(xnan && !ynan)
|
||||
return y;
|
||||
else if(!xnan && ynan)
|
||||
return x;
|
||||
else
|
||||
return y < x ? y : x;
|
||||
}
|
||||
|
||||
template <>
|
||||
static double GLSLMax(double x, double y)
|
||||
{
|
||||
const bool xnan = RDCISNAN(x);
|
||||
const bool ynan = RDCISNAN(y);
|
||||
if(xnan && !ynan)
|
||||
return y;
|
||||
else if(!xnan && ynan)
|
||||
return x;
|
||||
else
|
||||
return x < y ? y : x;
|
||||
}
|
||||
|
||||
template <>
|
||||
static double GLSLMin(double x, double y)
|
||||
{
|
||||
const bool xnan = RDCISNAN(x);
|
||||
const bool ynan = RDCISNAN(y);
|
||||
if(xnan && !ynan)
|
||||
return y;
|
||||
else if(!xnan && ynan)
|
||||
return x;
|
||||
else
|
||||
return y < x ? y : x;
|
||||
}
|
||||
|
||||
ShaderVariable FMax(ThreadState &state, uint32_t, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(2);
|
||||
@@ -852,30 +904,6 @@ ShaderVariable FindUMsb(ThreadState &state, uint32_t, const rdcarray<Id> ¶ms
|
||||
return x;
|
||||
}
|
||||
|
||||
static float GLSLNMax(float x, float y)
|
||||
{
|
||||
const bool xnan = RDCISNAN(x);
|
||||
const bool ynan = RDCISNAN(y);
|
||||
if(xnan && !ynan)
|
||||
return y;
|
||||
else if(!xnan && ynan)
|
||||
return x;
|
||||
else
|
||||
return x < y ? y : x;
|
||||
}
|
||||
|
||||
static float GLSLNMin(float x, float y)
|
||||
{
|
||||
const bool xnan = RDCISNAN(x);
|
||||
const bool ynan = RDCISNAN(y);
|
||||
if(xnan && !ynan)
|
||||
return y;
|
||||
else if(!xnan && ynan)
|
||||
return x;
|
||||
else
|
||||
return y < x ? y : x;
|
||||
}
|
||||
|
||||
ShaderVariable NMin(ThreadState &state, uint32_t, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(2);
|
||||
@@ -884,7 +912,7 @@ ShaderVariable NMin(ThreadState &state, uint32_t, const rdcarray<Id> ¶ms)
|
||||
ShaderVariable y = state.GetSrc(params[1]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] = GLSLNMin(var.value.fv[c], y.value.fv[c]);
|
||||
var.value.fv[c] = GLSLMin(var.value.fv[c], y.value.fv[c]);
|
||||
|
||||
return var;
|
||||
}
|
||||
@@ -897,7 +925,7 @@ ShaderVariable NMax(ThreadState &state, uint32_t, const rdcarray<Id> ¶ms)
|
||||
ShaderVariable y = state.GetSrc(params[1]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] = GLSLNMax(var.value.fv[c], y.value.fv[c]);
|
||||
var.value.fv[c] = GLSLMax(var.value.fv[c], y.value.fv[c]);
|
||||
|
||||
return var;
|
||||
}
|
||||
@@ -911,7 +939,7 @@ ShaderVariable NClamp(ThreadState &state, uint32_t, const rdcarray<Id> ¶ms)
|
||||
ShaderVariable maxVal = state.GetSrc(params[2]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] = GLSLNMin(GLSLNMax(var.value.fv[c], minVal.value.fv[c]), maxVal.value.fv[c]);
|
||||
var.value.fv[c] = GLSLMin(GLSLMax(var.value.fv[c], minVal.value.fv[c]), maxVal.value.fv[c]);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user