Fix auto-conversion of vertex inputs in vulkan shader debugging

This commit is contained in:
baldurk
2021-05-13 15:36:45 +01:00
parent c715d2c7ad
commit 3685ca1c09
3 changed files with 154 additions and 18 deletions
@@ -852,7 +852,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *api, const ShaderStage s
// now write it into the appropiate elements in the destination ShaderValue
for(uint32_t r = 0; r < var.rows; r++)
copyComp(var, r * var.columns + c, tmp, r, var.type);
copyComp(var, r * var.columns + c, tmp, r);
}
}
else
@@ -1577,7 +1577,7 @@ ShaderVariable Debugger::ReadFromPointer(const ShaderVariable &ptr) const
// transpose into our row major storage
for(uint8_t r = 0; r < var.rows; r++)
for(uint8_t c = 0; c < var.columns; c++)
copyComp(var, r * var.columns + c, tmp, c * var.rows + r, var.type);
copyComp(var, r * var.columns + c, tmp, c * var.rows + r);
}
}
else if(type.type == DataType::VectorType)
@@ -1736,11 +1736,12 @@ void Debugger::WriteThroughPointer(const ShaderVariable &ptr, const ShaderVariab
else
{
ShaderVariable tmp;
tmp.type = var.type;
// transpose from our row major storage
for(uint8_t r = 0; r < var.rows; r++)
for(uint8_t c = 0; c < var.columns; c++)
copyComp(tmp, c * var.rows + r, var, r * var.columns + c, var.type);
copyComp(tmp, c * var.rows + r, var, r * var.columns + c);
// read column-wise
for(uint8_t c = 0; c < var.columns; c++)
@@ -204,16 +204,120 @@ inline void set0001(ShaderVariable &result)
}
inline void copyComp(ShaderVariable &dst, uint32_t dstComp, const ShaderVariable &src,
uint32_t srcComp, VarType type = VarType::Unknown)
uint32_t srcComp)
{
if(type == VarType::Unknown)
// fast path for same-sized inputs, which is common (e.g. float declared variables with float
// inputs)
if(dst.type == src.type)
{
RDCASSERTEQUAL(dst.type, src.type);
type = src.type;
const uint32_t sz = VarTypeByteSize(src.type);
memcpy(((byte *)dst.value.u8v.data()) + sz * dstComp,
((byte *)src.value.u8v.data()) + sz * srcComp, sz);
return;
}
else
{
// otherwise we convert the component here
const uint32_t srcSz = VarTypeByteSize(src.type);
const uint32_t dstSz = VarTypeByteSize(dst.type);
if(srcSz <= 4 && dstSz <= 4)
{
// if the types are no more than 4-byte, we can use the helpers above without truncation
if(VarTypeCompType(src.type) == CompType::Float)
setFloatComp(dst, dstComp, floatComp(src, srcComp));
else if(VarTypeCompType(src.type) == CompType::SInt)
setIntComp(dst, dstComp, intComp(src, srcComp));
else
setUintComp(dst, dstComp, uintComp(src, srcComp));
}
else
{
// if there's a 64-bit type somewhere we need to go through double/int64
double d = 0.0;
uint64_t u = 0;
int64_t i = 0;
switch(src.type)
{
case VarType::Float:
case VarType::Half:
{
d = floatComp(src, srcComp);
break;
}
case VarType::Double:
{
d = src.value.f64v[srcComp];
break;
}
case VarType::SInt:
case VarType::SShort:
case VarType::SByte:
{
i = intComp(src, srcComp);
break;
}
case VarType::SLong:
{
i = src.value.s64v[srcComp];
break;
}
case VarType::ULong:
{
u = src.value.u64v[srcComp];
break;
}
default:
{
// all other case are uints or invalid types
u = uintComp(src, srcComp);
break;
}
}
// valid SPIR-V should match the base type in any case where we're copying components,
// conversions between are done separately. So we just assume that d/u/i was filled above and
// read from it to the output
switch(src.type)
{
case VarType::Float:
case VarType::Half:
{
setFloatComp(dst, dstComp, float(d));
break;
}
case VarType::Double:
{
dst.value.f64v[dstComp] = d;
break;
}
case VarType::SInt:
case VarType::SShort:
case VarType::SByte:
{
setIntComp(dst, dstComp, int32_t(i));
break;
}
case VarType::SLong:
{
dst.value.s64v[dstComp] = i;
break;
}
case VarType::ULong:
{
dst.value.u64v[dstComp] = u;
break;
}
default:
{
// all other case are uints or invalid types
setUintComp(dst, dstComp, uint32_t(u));
break;
}
}
}
}
const uint32_t sz = VarTypeByteSize(type);
memcpy(((byte *)dst.value.u8v.data()) + sz * dstComp,
((byte *)src.value.u8v.data()) + sz * srcComp, sz);
}
#define IMPL_FOR_FLOAT_TYPES_FOR_TYPE(impl, type) \
+39 -8
View File
@@ -444,21 +444,20 @@ public:
if(location < location_inputs.size())
{
const uint32_t typeSize = VarTypeByteSize(var.type);
if(var.rows == 1)
{
if(component + var.columns > 4)
RDCERR("Unexpected component %u for column count %u", component, var.columns);
for(uint8_t c = 0; c < var.columns; c++)
copyComp(var, c, location_inputs[location], component + c, var.type);
copyComp(var, c, location_inputs[location], component + c);
}
else
{
RDCASSERTEQUAL(component, 0);
for(uint8_t r = 0; r < var.rows; r++)
for(uint8_t c = 0; c < var.columns; c++)
copyComp(var, r * var.columns + c, location_inputs[location + c], r, var.type);
copyComp(var, r * var.columns + c, location_inputs[location + c], r);
}
return;
}
@@ -486,16 +485,21 @@ public:
DerivativeDeltas ret;
ret.ddxcoarse.type = type;
ret.ddxfine.type = type;
ret.ddycoarse.type = type;
ret.ddyfine.type = type;
RDCASSERT(component < 4, component);
// rebase from component into [0]..
for(uint32_t src = component, dst = 0; src < 4; src++, dst++)
{
copyComp(ret.ddxcoarse, dst, deriv.ddxcoarse, src, type);
copyComp(ret.ddxfine, dst, deriv.ddxfine, src, type);
copyComp(ret.ddycoarse, dst, deriv.ddycoarse, src, type);
copyComp(ret.ddyfine, dst, deriv.ddyfine, src, type);
copyComp(ret.ddxcoarse, dst, deriv.ddxcoarse, src);
copyComp(ret.ddxfine, dst, deriv.ddxfine, src);
copyComp(ret.ddycoarse, dst, deriv.ddycoarse, src);
copyComp(ret.ddyfine, dst, deriv.ddyfine, src);
}
return ret;
@@ -3871,7 +3875,30 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u
}
else
{
var.type = VarType::Float;
var.type = VarType::UInt;
if(fmt.compType == CompType::UInt)
{
if(fmt.compByteWidth == 1)
var.type = VarType::UByte;
else if(fmt.compByteWidth == 2)
var.type = VarType::UShort;
else if(fmt.compByteWidth == 4)
var.type = VarType::UInt;
else if(fmt.compByteWidth == 8)
var.type = VarType::ULong;
}
else if(fmt.compType == CompType::SInt)
{
if(fmt.compByteWidth == 1)
var.type = VarType::SByte;
else if(fmt.compByteWidth == 2)
var.type = VarType::SShort;
else if(fmt.compByteWidth == 4)
var.type = VarType::SInt;
else if(fmt.compByteWidth == 8)
var.type = VarType::SLong;
}
RDCASSERTEQUAL(fmt.compByteWidth, VarTypeByteSize(var.type));
memcpy(var.value.u8v.data(), data.data(), fmt.compByteWidth * fmt.compCount);
@@ -4533,6 +4560,10 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
builtin ? apiWrapper->builtin_derivatives[param.systemValue]
: apiWrapper->location_derivatives[param.regIndex];
var.rows = 1;
var.columns = param.compCount & 0xff;
var.type = param.varType;
const uint32_t comp = Bits::CountTrailingZeroes(uint32_t(param.regChannelMask));
const uint32_t elemSize = VarTypeByteSize(param.varType);