mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 10:00:40 +00:00
DXIL Debugger internal helper methods
DXILDebug::Id GetSSAId(DXIL::Value *value); bool OperationFlushing(const Operation op, DXOp dxOpCode); ShaderEvents AssignValue(ShaderVariable &result, const ShaderVariable &src, bool flushDenorm); uint8_t GetElementByteSize(VarType type); DXBC::ResourceRetType ConvertComponentTypeToResourceRetType(const ComponentType compType); DXBCBytecode::ResourceDimension ConvertResourceKindToResourceDimension(const ResourceKind kind); DXBCBytecode::SamplerMode ConvertSamplerKindToSamplerMode(const SamplerKind kind); VarType ConvertDXILTypeToVarType(const Type *type); void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const ShaderValue &value); ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte *d); void FillViewFmt(VarType type, DXILDebug::GlobalState::ViewFmt &fmt);
This commit is contained in:
@@ -25,10 +25,928 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxil_debug.h"
|
||||
#include "maths/formatpacking.h"
|
||||
|
||||
using namespace DXIL;
|
||||
using namespace DXDebug;
|
||||
|
||||
const uint32_t DXIL_INVALID_ID = ~0U;
|
||||
|
||||
DXILDebug::Id GetSSAId(DXIL::Value *value)
|
||||
{
|
||||
if(const Instruction *inst = cast<Instruction>(value))
|
||||
return inst->slot;
|
||||
|
||||
RDCERR("Unhandled DXIL::Value type");
|
||||
return DXIL_INVALID_ID;
|
||||
}
|
||||
|
||||
bool OperationFlushing(const Operation op, DXOp dxOpCode)
|
||||
{
|
||||
if(dxOpCode != DXOp::NumOpCodes)
|
||||
{
|
||||
RDCASSERTEQUAL(op, Operation::Call);
|
||||
|
||||
switch(dxOpCode)
|
||||
{
|
||||
// sample operations flush denorms
|
||||
case DXOp::Sample:
|
||||
case DXOp::SampleBias:
|
||||
case DXOp::SampleLevel:
|
||||
case DXOp::SampleGrad:
|
||||
case DXOp::SampleCmp:
|
||||
case DXOp::SampleCmpBias:
|
||||
case DXOp::SampleCmpLevel:
|
||||
case DXOp::SampleCmpGrad:
|
||||
case DXOp::SampleCmpLevelZero:
|
||||
case DXOp::TextureGather:
|
||||
case DXOp::TextureGatherCmp:
|
||||
case DXOp::TextureGatherRaw: return true;
|
||||
|
||||
// unclear if these flush and it's unlikely denorms will come up, conservatively flush
|
||||
case DXOp::CalculateLOD:
|
||||
case DXOp::DerivCoarseX:
|
||||
case DXOp::DerivCoarseY:
|
||||
case DXOp::DerivFineX:
|
||||
case DXOp::DerivFineY:
|
||||
case DXOp::EvalSampleIndex: return true;
|
||||
|
||||
// Float mathematical operations all flush denorms
|
||||
case DXOp::FAbs:
|
||||
case DXOp::Cos:
|
||||
case DXOp::Sin:
|
||||
case DXOp::Tan:
|
||||
case DXOp::Acos:
|
||||
case DXOp::Asin:
|
||||
case DXOp::Atan:
|
||||
case DXOp::Hcos:
|
||||
case DXOp::Hsin:
|
||||
case DXOp::Htan:
|
||||
case DXOp::Exp:
|
||||
case DXOp::Frc:
|
||||
case DXOp::Log:
|
||||
case DXOp::Sqrt:
|
||||
case DXOp::Rsqrt:
|
||||
case DXOp::Round_ne:
|
||||
case DXOp::Round_ni:
|
||||
case DXOp::Round_pi:
|
||||
case DXOp::Round_z:
|
||||
case DXOp::FMax:
|
||||
case DXOp::FMin:
|
||||
case DXOp::FMad:
|
||||
case DXOp::Fma:
|
||||
case DXOp::Dot2:
|
||||
case DXOp::Dot3:
|
||||
case DXOp::Dot4: return true;
|
||||
|
||||
// Not floating point operations, no need to flush
|
||||
case DXOp::TempRegLoad:
|
||||
case DXOp::TempRegStore:
|
||||
case DXOp::MinPrecXRegLoad:
|
||||
case DXOp::MinPrecXRegStore:
|
||||
case DXOp::LoadInput:
|
||||
case DXOp::StoreOutput:
|
||||
case DXOp::Saturate:
|
||||
case DXOp::IsNaN:
|
||||
case DXOp::IsInf:
|
||||
case DXOp::IsFinite:
|
||||
case DXOp::IsNormal:
|
||||
case DXOp::Bfrev:
|
||||
case DXOp::Countbits:
|
||||
case DXOp::FirstbitLo:
|
||||
case DXOp::FirstbitHi:
|
||||
case DXOp::FirstbitSHi:
|
||||
case DXOp::IMax:
|
||||
case DXOp::IMin:
|
||||
case DXOp::UMax:
|
||||
case DXOp::UMin:
|
||||
case DXOp::IMul:
|
||||
case DXOp::UMul:
|
||||
case DXOp::UDiv:
|
||||
case DXOp::UAddc:
|
||||
case DXOp::USubb:
|
||||
case DXOp::IMad:
|
||||
case DXOp::UMad:
|
||||
case DXOp::Msad:
|
||||
case DXOp::Ibfe:
|
||||
case DXOp::Ubfe:
|
||||
case DXOp::Bfi:
|
||||
case DXOp::CreateHandle:
|
||||
case DXOp::CBufferLoad:
|
||||
case DXOp::CBufferLoadLegacy:
|
||||
case DXOp::TextureLoad:
|
||||
case DXOp::TextureStore:
|
||||
case DXOp::BufferLoad:
|
||||
case DXOp::BufferStore:
|
||||
case DXOp::BufferUpdateCounter:
|
||||
case DXOp::CheckAccessFullyMapped:
|
||||
case DXOp::GetDimensions:
|
||||
case DXOp::Texture2DMSGetSamplePosition:
|
||||
case DXOp::RenderTargetGetSamplePosition:
|
||||
case DXOp::RenderTargetGetSampleCount:
|
||||
case DXOp::AtomicBinOp:
|
||||
case DXOp::AtomicCompareExchange:
|
||||
case DXOp::Barrier:
|
||||
case DXOp::Discard:
|
||||
case DXOp::EvalSnapped:
|
||||
case DXOp::EvalCentroid:
|
||||
case DXOp::SampleIndex:
|
||||
case DXOp::Coverage:
|
||||
case DXOp::InnerCoverage:
|
||||
case DXOp::ThreadId:
|
||||
case DXOp::GroupId:
|
||||
case DXOp::ThreadIdInGroup:
|
||||
case DXOp::FlattenedThreadIdInGroup:
|
||||
case DXOp::EmitStream:
|
||||
case DXOp::CutStream:
|
||||
case DXOp::EmitThenCutStream:
|
||||
case DXOp::GSInstanceID:
|
||||
case DXOp::MakeDouble:
|
||||
case DXOp::SplitDouble:
|
||||
case DXOp::LoadOutputControlPoint:
|
||||
case DXOp::LoadPatchConstant:
|
||||
case DXOp::DomainLocation:
|
||||
case DXOp::StorePatchConstant:
|
||||
case DXOp::OutputControlPointID:
|
||||
case DXOp::PrimitiveID:
|
||||
case DXOp::CycleCounterLegacy:
|
||||
case DXOp::WaveIsFirstLane:
|
||||
case DXOp::WaveGetLaneIndex:
|
||||
case DXOp::WaveGetLaneCount:
|
||||
case DXOp::WaveAnyTrue:
|
||||
case DXOp::WaveAllTrue:
|
||||
case DXOp::WaveActiveAllEqual:
|
||||
case DXOp::WaveActiveBallot:
|
||||
case DXOp::WaveReadLaneAt:
|
||||
case DXOp::WaveReadLaneFirst:
|
||||
case DXOp::WaveActiveOp:
|
||||
case DXOp::WaveActiveBit:
|
||||
case DXOp::WavePrefixOp:
|
||||
case DXOp::QuadReadLaneAt:
|
||||
case DXOp::QuadOp:
|
||||
case DXOp::BitcastI16toF16:
|
||||
case DXOp::BitcastF16toI16:
|
||||
case DXOp::BitcastI32toF32:
|
||||
case DXOp::BitcastF32toI32:
|
||||
case DXOp::BitcastI64toF64:
|
||||
case DXOp::BitcastF64toI64:
|
||||
case DXOp::LegacyF32ToF16:
|
||||
case DXOp::LegacyF16ToF32:
|
||||
case DXOp::LegacyDoubleToFloat:
|
||||
case DXOp::LegacyDoubleToSInt32:
|
||||
case DXOp::LegacyDoubleToUInt32:
|
||||
case DXOp::WaveAllBitCount:
|
||||
case DXOp::WavePrefixBitCount:
|
||||
case DXOp::AttributeAtVertex:
|
||||
case DXOp::ViewID:
|
||||
case DXOp::RawBufferLoad:
|
||||
case DXOp::RawBufferStore:
|
||||
case DXOp::InstanceID:
|
||||
case DXOp::InstanceIndex:
|
||||
case DXOp::HitKind:
|
||||
case DXOp::RayFlags:
|
||||
case DXOp::DispatchRaysIndex:
|
||||
case DXOp::DispatchRaysDimensions:
|
||||
case DXOp::WorldRayOrigin:
|
||||
case DXOp::WorldRayDirection:
|
||||
case DXOp::ObjectRayOrigin:
|
||||
case DXOp::ObjectRayDirection:
|
||||
case DXOp::ObjectToWorld:
|
||||
case DXOp::WorldToObject:
|
||||
case DXOp::RayTMin:
|
||||
case DXOp::RayTCurrent:
|
||||
case DXOp::IgnoreHit:
|
||||
case DXOp::AcceptHitAndEndSearch:
|
||||
case DXOp::TraceRay:
|
||||
case DXOp::ReportHit:
|
||||
case DXOp::CallShader:
|
||||
case DXOp::CreateHandleForLib:
|
||||
case DXOp::PrimitiveIndex:
|
||||
case DXOp::Dot2AddHalf:
|
||||
case DXOp::Dot4AddI8Packed:
|
||||
case DXOp::Dot4AddU8Packed:
|
||||
case DXOp::WaveMatch:
|
||||
case DXOp::WaveMultiPrefixOp:
|
||||
case DXOp::WaveMultiPrefixBitCount:
|
||||
case DXOp::SetMeshOutputCounts:
|
||||
case DXOp::EmitIndices:
|
||||
case DXOp::GetMeshPayload:
|
||||
case DXOp::StoreVertexOutput:
|
||||
case DXOp::StorePrimitiveOutput:
|
||||
case DXOp::DispatchMesh:
|
||||
case DXOp::WriteSamplerFeedback:
|
||||
case DXOp::WriteSamplerFeedbackBias:
|
||||
case DXOp::WriteSamplerFeedbackLevel:
|
||||
case DXOp::WriteSamplerFeedbackGrad:
|
||||
case DXOp::AllocateRayQuery:
|
||||
case DXOp::RayQuery_TraceRayInline:
|
||||
case DXOp::RayQuery_Proceed:
|
||||
case DXOp::RayQuery_Abort:
|
||||
case DXOp::RayQuery_CommitNonOpaqueTriangleHit:
|
||||
case DXOp::RayQuery_CommitProceduralPrimitiveHit:
|
||||
case DXOp::RayQuery_CommittedStatus:
|
||||
case DXOp::RayQuery_CandidateType:
|
||||
case DXOp::RayQuery_CandidateObjectToWorld3x4:
|
||||
case DXOp::RayQuery_CandidateWorldToObject3x4:
|
||||
case DXOp::RayQuery_CommittedObjectToWorld3x4:
|
||||
case DXOp::RayQuery_CommittedWorldToObject3x4:
|
||||
case DXOp::RayQuery_CandidateProceduralPrimitiveNonOpaque:
|
||||
case DXOp::RayQuery_CandidateTriangleFrontFace:
|
||||
case DXOp::RayQuery_CommittedTriangleFrontFace:
|
||||
case DXOp::RayQuery_CandidateTriangleBarycentrics:
|
||||
case DXOp::RayQuery_CommittedTriangleBarycentrics:
|
||||
case DXOp::RayQuery_RayFlags:
|
||||
case DXOp::RayQuery_WorldRayOrigin:
|
||||
case DXOp::RayQuery_WorldRayDirection:
|
||||
case DXOp::RayQuery_RayTMin:
|
||||
case DXOp::RayQuery_CandidateTriangleRayT:
|
||||
case DXOp::RayQuery_CommittedRayT:
|
||||
case DXOp::RayQuery_CandidateInstanceIndex:
|
||||
case DXOp::RayQuery_CandidateInstanceID:
|
||||
case DXOp::RayQuery_CandidateGeometryIndex:
|
||||
case DXOp::RayQuery_CandidatePrimitiveIndex:
|
||||
case DXOp::RayQuery_CandidateObjectRayOrigin:
|
||||
case DXOp::RayQuery_CandidateObjectRayDirection:
|
||||
case DXOp::RayQuery_CommittedInstanceIndex:
|
||||
case DXOp::RayQuery_CommittedInstanceID:
|
||||
case DXOp::RayQuery_CommittedGeometryIndex:
|
||||
case DXOp::RayQuery_CommittedPrimitiveIndex:
|
||||
case DXOp::RayQuery_CommittedObjectRayOrigin:
|
||||
case DXOp::RayQuery_CommittedObjectRayDirection:
|
||||
case DXOp::GeometryIndex:
|
||||
case DXOp::RayQuery_CandidateInstanceContributionToHitGroupIndex:
|
||||
case DXOp::RayQuery_CommittedInstanceContributionToHitGroupIndex:
|
||||
case DXOp::AnnotateHandle:
|
||||
case DXOp::CreateHandleFromBinding:
|
||||
case DXOp::CreateHandleFromHeap:
|
||||
case DXOp::Unpack4x8:
|
||||
case DXOp::Pack4x8:
|
||||
case DXOp::IsHelperLane:
|
||||
case DXOp::QuadVote:
|
||||
case DXOp::TextureStoreSample:
|
||||
case DXOp::WaveMatrix_Annotate:
|
||||
case DXOp::WaveMatrix_Depth:
|
||||
case DXOp::WaveMatrix_Fill:
|
||||
case DXOp::WaveMatrix_LoadRawBuf:
|
||||
case DXOp::WaveMatrix_LoadGroupShared:
|
||||
case DXOp::WaveMatrix_StoreRawBuf:
|
||||
case DXOp::WaveMatrix_StoreGroupShared:
|
||||
case DXOp::WaveMatrix_Multiply:
|
||||
case DXOp::WaveMatrix_MultiplyAccumulate:
|
||||
case DXOp::WaveMatrix_ScalarOp:
|
||||
case DXOp::WaveMatrix_SumAccumulate:
|
||||
case DXOp::WaveMatrix_Add:
|
||||
case DXOp::AllocateNodeOutputRecords:
|
||||
case DXOp::GetNodeRecordPtr:
|
||||
case DXOp::IncrementOutputCount:
|
||||
case DXOp::OutputComplete:
|
||||
case DXOp::GetInputRecordCount:
|
||||
case DXOp::FinishedCrossGroupSharing:
|
||||
case DXOp::BarrierByMemoryType:
|
||||
case DXOp::BarrierByMemoryHandle:
|
||||
case DXOp::BarrierByNodeRecordHandle:
|
||||
case DXOp::CreateNodeOutputHandle:
|
||||
case DXOp::IndexNodeHandle:
|
||||
case DXOp::AnnotateNodeHandle:
|
||||
case DXOp::CreateNodeInputRecordHandle:
|
||||
case DXOp::AnnotateNodeRecordHandle:
|
||||
case DXOp::NodeOutputIsValid:
|
||||
case DXOp::GetRemainingRecursionLevels:
|
||||
case DXOp::StartVertexLocation:
|
||||
case DXOp::StartInstanceLocation: return false;
|
||||
case DXOp::NumOpCodes:
|
||||
RDCERR("Unhandled DXOpCode %s in DXIL shader debugger", ToStr(dxOpCode).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(op)
|
||||
{
|
||||
// Float mathematical operations all flush denorms including comparisons
|
||||
case Operation::FAdd:
|
||||
case Operation::FSub:
|
||||
case Operation::FMul:
|
||||
case Operation::FDiv:
|
||||
case Operation::FRem:
|
||||
case Operation::FPTrunc:
|
||||
case Operation::FPExt:
|
||||
case Operation::FOrdFalse:
|
||||
case Operation::FOrdEqual:
|
||||
case Operation::FOrdGreater:
|
||||
case Operation::FOrdGreaterEqual:
|
||||
case Operation::FOrdLess:
|
||||
case Operation::FOrdLessEqual:
|
||||
case Operation::FOrdNotEqual:
|
||||
case Operation::FOrd:
|
||||
case Operation::FUnord:
|
||||
case Operation::FUnordEqual:
|
||||
case Operation::FUnordGreater:
|
||||
case Operation::FUnordGreaterEqual:
|
||||
case Operation::FUnordLess:
|
||||
case Operation::FUnordLessEqual:
|
||||
case Operation::FUnordNotEqual:
|
||||
case Operation::FOrdTrue: return true;
|
||||
|
||||
// Casts do not flush
|
||||
case Operation::Trunc:
|
||||
case Operation::SExt:
|
||||
case Operation::ZExt:
|
||||
case Operation::PtrToI:
|
||||
case Operation::IToPtr:
|
||||
case Operation::Bitcast:
|
||||
case Operation::AddrSpaceCast: return false;
|
||||
|
||||
// Integer operations do not flush
|
||||
case Operation::IEqual:
|
||||
case Operation::INotEqual:
|
||||
case Operation::UGreater:
|
||||
case Operation::UGreaterEqual:
|
||||
case Operation::ULess:
|
||||
case Operation::ULessEqual:
|
||||
case Operation::SGreater:
|
||||
case Operation::SGreaterEqual:
|
||||
case Operation::SLess:
|
||||
case Operation::SLessEqual: return false;
|
||||
|
||||
// Can't generate denorms or denorm inputs are implicitly rounded to 0, no need to flush
|
||||
case Operation::FToU:
|
||||
case Operation::FToS:
|
||||
case Operation::UToF:
|
||||
case Operation::SToF: return false;
|
||||
|
||||
// Non arithmetic operations do not flush
|
||||
case Operation::NoOp:
|
||||
case Operation::Call:
|
||||
case Operation::ExtractVal:
|
||||
case Operation::Ret:
|
||||
case Operation::Unreachable:
|
||||
case Operation::Alloca:
|
||||
case Operation::GetElementPtr:
|
||||
case Operation::Branch:
|
||||
case Operation::Fence:
|
||||
case Operation::Switch:
|
||||
case Operation::Load:
|
||||
case Operation::Store:
|
||||
case Operation::Select:
|
||||
case Operation::ExtractElement:
|
||||
case Operation::InsertElement:
|
||||
case Operation::ShuffleVector:
|
||||
case Operation::InsertValue:
|
||||
case Operation::Phi:
|
||||
case Operation::CompareExchange: return false;
|
||||
|
||||
// Integer operations do not flush
|
||||
case Operation::Add:
|
||||
case Operation::Sub:
|
||||
case Operation::Mul:
|
||||
case Operation::UDiv:
|
||||
case Operation::SDiv:
|
||||
case Operation::URem:
|
||||
case Operation::SRem:
|
||||
case Operation::ShiftLeft:
|
||||
case Operation::LogicalShiftRight:
|
||||
case Operation::ArithShiftRight:
|
||||
case Operation::And:
|
||||
case Operation::Or:
|
||||
case Operation::Xor:
|
||||
case Operation::LoadAtomic:
|
||||
case Operation::StoreAtomic:
|
||||
case Operation::AtomicExchange:
|
||||
case Operation::AtomicAdd:
|
||||
case Operation::AtomicSub:
|
||||
case Operation::AtomicAnd:
|
||||
case Operation::AtomicNand:
|
||||
case Operation::AtomicOr:
|
||||
case Operation::AtomicXor:
|
||||
case Operation::AtomicMax:
|
||||
case Operation::AtomicMin:
|
||||
case Operation::AtomicUMax:
|
||||
case Operation::AtomicUMin: return false;
|
||||
default: RDCERR("Unhandled LLVM OpCode %s in DXIL shader debugger", ToStr(op).c_str()); break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ShaderEvents AssignValue(ShaderVariable &result, const ShaderVariable &src, bool flushDenorm)
|
||||
{
|
||||
RDCASSERTEQUAL(result.type, src.type);
|
||||
|
||||
ShaderEvents flags = ShaderEvents::NoEvent;
|
||||
|
||||
if(result.type == VarType::Float)
|
||||
{
|
||||
float ft = src.value.f32v[0];
|
||||
if(!RDCISFINITE(ft))
|
||||
flags |= ShaderEvents::GeneratedNanOrInf;
|
||||
}
|
||||
else if(result.type == VarType::Double)
|
||||
{
|
||||
double dt = src.value.f64v[0];
|
||||
if(!RDCISFINITE(dt))
|
||||
flags |= ShaderEvents::GeneratedNanOrInf;
|
||||
}
|
||||
|
||||
result.value.u32v[0] = src.value.u32v[0];
|
||||
|
||||
if(flushDenorm)
|
||||
{
|
||||
if(result.type == VarType::Float)
|
||||
result.value.f32v[0] = flush_denorm(src.value.f32v[0]);
|
||||
else if(result.type == VarType::Double)
|
||||
RDCERR("Unhandled flushing denormalised double");
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint8_t GetElementByteSize(VarType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case VarType::SLong:
|
||||
case VarType::ULong:
|
||||
case VarType::Double: return 8; break;
|
||||
case VarType::SInt:
|
||||
case VarType::UInt:
|
||||
case VarType::Float: return 4; break;
|
||||
case VarType::SShort:
|
||||
case VarType::UShort:
|
||||
case VarType::Half: return 2; break;
|
||||
case VarType::SByte:
|
||||
case VarType::UByte: return 1; break;
|
||||
case VarType::Bool:
|
||||
case VarType::Enum:
|
||||
case VarType::Struct:
|
||||
case VarType::GPUPointer:
|
||||
case VarType::ConstantBlock:
|
||||
case VarType::ReadOnlyResource:
|
||||
case VarType::ReadWriteResource:
|
||||
case VarType::Sampler:
|
||||
case VarType::Unknown: RDCERR("Unhandled VarType %s", ToStr(type).c_str()); break;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
DXBC::ResourceRetType ConvertComponentTypeToResourceRetType(const ComponentType compType)
|
||||
{
|
||||
switch(compType)
|
||||
{
|
||||
case ComponentType::I32: return DXBC::ResourceRetType::RETURN_TYPE_SINT;
|
||||
case ComponentType::U32: return DXBC::ResourceRetType::RETURN_TYPE_UINT;
|
||||
case ComponentType::F32: return DXBC::ResourceRetType::RETURN_TYPE_FLOAT;
|
||||
case ComponentType::F64: return DXBC::ResourceRetType::RETURN_TYPE_DOUBLE;
|
||||
case ComponentType::SNormF32: return DXBC ::ResourceRetType::RETURN_TYPE_SNORM;
|
||||
case ComponentType::UNormF32: return DXBC::ResourceRetType::RETURN_TYPE_UNORM;
|
||||
case ComponentType::I1:
|
||||
case ComponentType::I16:
|
||||
case ComponentType::U16:
|
||||
case ComponentType::F16:
|
||||
case ComponentType::SNormF16:
|
||||
case ComponentType::UNormF16:
|
||||
case ComponentType::I64:
|
||||
case ComponentType::U64:
|
||||
case ComponentType::SNormF64:
|
||||
case ComponentType::UNormF64:
|
||||
case ComponentType::Invalid: return DXBC::ResourceRetType::RETURN_TYPE_UNKNOWN;
|
||||
};
|
||||
return DXBC::ResourceRetType::RETURN_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
DXBCBytecode::ResourceDimension ConvertResourceKindToResourceDimension(const ResourceKind kind)
|
||||
{
|
||||
switch(kind)
|
||||
{
|
||||
case ResourceKind::Texture1D:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE1D;
|
||||
case ResourceKind::Texture1DArray:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE1DARRAY;
|
||||
case ResourceKind::Texture2D:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2D;
|
||||
case ResourceKind::Texture2DArray:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2DARRAY;
|
||||
case ResourceKind::Texture2DMS:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2DMS;
|
||||
case ResourceKind::Texture2DMSArray:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2DMSARRAY;
|
||||
case ResourceKind::Texture3D:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE3D;
|
||||
case ResourceKind::TextureCube:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURECUBE;
|
||||
case ResourceKind::TextureCubeArray:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURECUBEARRAY;
|
||||
case ResourceKind::TypedBuffer:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_BUFFER;
|
||||
case ResourceKind::RawBuffer:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_RAW_BUFFER;
|
||||
case ResourceKind::StructuredBuffer:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_STRUCTURED_BUFFER;
|
||||
case ResourceKind::Unknown:
|
||||
case ResourceKind::CBuffer:
|
||||
case ResourceKind::Sampler:
|
||||
case ResourceKind::TBuffer:
|
||||
case ResourceKind::RTAccelerationStructure:
|
||||
case ResourceKind::FeedbackTexture2D:
|
||||
case ResourceKind::FeedbackTexture2DArray:
|
||||
case ResourceKind::StructuredBufferWithCounter:
|
||||
case ResourceKind::SamplerComparison:
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_UNKNOWN;
|
||||
}
|
||||
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_UNKNOWN;
|
||||
}
|
||||
|
||||
DXBCBytecode::SamplerMode ConvertSamplerKindToSamplerMode(const SamplerKind kind)
|
||||
{
|
||||
switch(kind)
|
||||
{
|
||||
case SamplerKind::Comparison: return DXBCBytecode::SAMPLER_MODE_COMPARISON;
|
||||
case SamplerKind::Mono: return DXBCBytecode::SAMPLER_MODE_MONO;
|
||||
case SamplerKind::Default: return DXBCBytecode::SAMPLER_MODE_DEFAULT;
|
||||
case SamplerKind::Invalid: return DXBCBytecode::NUM_SAMPLERS;
|
||||
}
|
||||
return DXBCBytecode::SamplerMode::NUM_SAMPLERS;
|
||||
}
|
||||
|
||||
static VarType ConvertDXILTypeToVarType(const Type *type)
|
||||
{
|
||||
if(type->type == Type::TypeKind::Struct)
|
||||
return VarType::Struct;
|
||||
if(type->type == Type::TypeKind::Vector)
|
||||
return ConvertDXILTypeToVarType(type->inner);
|
||||
if(type->type == Type::TypeKind::Array)
|
||||
return ConvertDXILTypeToVarType(type->inner);
|
||||
if(type->type == Type::TypeKind::Pointer)
|
||||
return VarType::GPUPointer;
|
||||
|
||||
RDCASSERTEQUAL(type->type, Type::TypeKind::Scalar);
|
||||
if(type->scalarType == Type::ScalarKind::Int)
|
||||
{
|
||||
if(type->bitWidth == 64)
|
||||
return VarType::SLong;
|
||||
else if(type->bitWidth == 32)
|
||||
return VarType::SInt;
|
||||
else if(type->bitWidth == 16)
|
||||
return VarType::SShort;
|
||||
else if(type->bitWidth == 8)
|
||||
return VarType::SByte;
|
||||
else if(type->bitWidth == 1)
|
||||
return VarType::Bool;
|
||||
}
|
||||
else if(type->scalarType == Type::ScalarKind::Float)
|
||||
{
|
||||
if(type->bitWidth == 64)
|
||||
return VarType::Double;
|
||||
else if(type->bitWidth == 32)
|
||||
return VarType::Float;
|
||||
else if(type->bitWidth == 16)
|
||||
return VarType::Half;
|
||||
}
|
||||
return VarType::Unknown;
|
||||
}
|
||||
|
||||
void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const ShaderValue &value)
|
||||
{
|
||||
if(fmt.byteWidth == 10)
|
||||
{
|
||||
uint32_t u = 0;
|
||||
|
||||
if(fmt.fmt == CompType::UInt)
|
||||
{
|
||||
u |= (value.u32v[0] & 0x3ff) << 0;
|
||||
u |= (value.u32v[1] & 0x3ff) << 10;
|
||||
u |= (value.u32v[2] & 0x3ff) << 20;
|
||||
u |= (value.u32v[3] & 0x3) << 30;
|
||||
}
|
||||
else if(fmt.fmt == CompType::UNorm)
|
||||
{
|
||||
u = ConvertToR10G10B10A2(Vec4f(value.f32v[0], value.f32v[1], value.f32v[2], value.f32v[3]));
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected format type on buffer resource");
|
||||
}
|
||||
memcpy(d, &u, sizeof(uint32_t));
|
||||
}
|
||||
else if(fmt.byteWidth == 11)
|
||||
{
|
||||
uint32_t u = ConvertToR11G11B10(Vec3f(value.f32v[0], value.f32v[1], value.f32v[2]));
|
||||
memcpy(d, &u, sizeof(uint32_t));
|
||||
}
|
||||
else if(fmt.byteWidth == 4)
|
||||
{
|
||||
uint32_t *u = (uint32_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
u[c] = value.u32v[c];
|
||||
}
|
||||
else if(fmt.byteWidth == 2)
|
||||
{
|
||||
if(fmt.fmt == CompType::Float)
|
||||
{
|
||||
uint16_t *u = (uint16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
u[c] = ConvertToHalf(value.f32v[c]);
|
||||
}
|
||||
else if(fmt.fmt == CompType::UInt)
|
||||
{
|
||||
uint16_t *u = (uint16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
u[c] = value.u32v[c] & 0xffff;
|
||||
}
|
||||
else if(fmt.fmt == CompType::SInt)
|
||||
{
|
||||
int16_t *i = (int16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
i[c] = (int16_t)RDCCLAMP(value.s32v[c], (int32_t)INT16_MIN, (int32_t)INT16_MAX);
|
||||
}
|
||||
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
|
||||
{
|
||||
uint16_t *u = (uint16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
{
|
||||
float f = RDCCLAMP(value.f32v[c], 0.0f, 1.0f) * float(0xffff) + 0.5f;
|
||||
u[c] = uint16_t(f);
|
||||
}
|
||||
}
|
||||
else if(fmt.fmt == CompType::SNorm)
|
||||
{
|
||||
int16_t *i = (int16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
{
|
||||
float f = RDCCLAMP(value.f32v[c], -1.0f, 1.0f) * 0x7fff;
|
||||
|
||||
if(f < 0.0f)
|
||||
i[c] = int16_t(f - 0.5f);
|
||||
else
|
||||
i[c] = int16_t(f + 0.5f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected format type on buffer resource");
|
||||
}
|
||||
}
|
||||
else if(fmt.byteWidth == 1)
|
||||
{
|
||||
if(fmt.fmt == CompType::UInt)
|
||||
{
|
||||
uint8_t *u = (uint8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
u[c] = value.u32v[c] & 0xff;
|
||||
}
|
||||
else if(fmt.fmt == CompType::SInt)
|
||||
{
|
||||
int8_t *i = (int8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
i[c] = (int8_t)RDCCLAMP(value.s32v[c], (int32_t)INT8_MIN, (int32_t)INT8_MAX);
|
||||
}
|
||||
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
|
||||
{
|
||||
uint8_t *u = (uint8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
{
|
||||
float f = RDCCLAMP(value.f32v[c], 0.0f, 1.0f) * float(0xff) + 0.5f;
|
||||
u[c] = uint8_t(f);
|
||||
}
|
||||
}
|
||||
else if(fmt.fmt == CompType::SNorm)
|
||||
{
|
||||
int8_t *i = (int8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
{
|
||||
float f = RDCCLAMP(value.f32v[c], -1.0f, 1.0f) * 0x7f;
|
||||
|
||||
if(f < 0.0f)
|
||||
i[c] = int8_t(f - 0.5f);
|
||||
else
|
||||
i[c] = int8_t(f + 0.5f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected format type on buffer resource");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte *d)
|
||||
{
|
||||
ShaderValue result;
|
||||
result.f32v[0] = 0.0f;
|
||||
result.f32v[1] = 0.0f;
|
||||
result.f32v[2] = 0.0f;
|
||||
result.f32v[3] = 0.0f;
|
||||
|
||||
if(fmt.byteWidth == 10)
|
||||
{
|
||||
uint32_t u;
|
||||
memcpy(&u, d, sizeof(uint32_t));
|
||||
|
||||
if(fmt.fmt == CompType::UInt)
|
||||
{
|
||||
result.u32v[0] = (u >> 0) & 0x3ff;
|
||||
result.u32v[1] = (u >> 10) & 0x3ff;
|
||||
result.u32v[2] = (u >> 20) & 0x3ff;
|
||||
result.u32v[3] = (u >> 30) & 0x003;
|
||||
}
|
||||
else if(fmt.fmt == CompType::UNorm)
|
||||
{
|
||||
Vec4f res = ConvertFromR10G10B10A2(u);
|
||||
result.f32v[0] = res.x;
|
||||
result.f32v[1] = res.y;
|
||||
result.f32v[2] = res.z;
|
||||
result.f32v[3] = res.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected format type on buffer resource");
|
||||
}
|
||||
}
|
||||
else if(fmt.byteWidth == 11)
|
||||
{
|
||||
uint32_t u;
|
||||
memcpy(&u, d, sizeof(uint32_t));
|
||||
|
||||
Vec3f res = ConvertFromR11G11B10(u);
|
||||
result.f32v[0] = res.x;
|
||||
result.f32v[1] = res.y;
|
||||
result.f32v[2] = res.z;
|
||||
result.f32v[3] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fmt.byteWidth == 4)
|
||||
{
|
||||
const uint32_t *u = (const uint32_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.u32v[c] = u[c];
|
||||
}
|
||||
else if(fmt.byteWidth == 2)
|
||||
{
|
||||
if(fmt.fmt == CompType::Float)
|
||||
{
|
||||
const uint16_t *u = (const uint16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.f32v[c] = ConvertFromHalf(u[c]);
|
||||
}
|
||||
else if(fmt.fmt == CompType::UInt)
|
||||
{
|
||||
const uint16_t *u = (const uint16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.u32v[c] = u[c];
|
||||
}
|
||||
else if(fmt.fmt == CompType::SInt)
|
||||
{
|
||||
const int16_t *in = (const int16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.s32v[c] = in[c];
|
||||
}
|
||||
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
|
||||
{
|
||||
const uint16_t *u = (const uint16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.f32v[c] = float(u[c]) / float(0xffff);
|
||||
}
|
||||
else if(fmt.fmt == CompType::SNorm)
|
||||
{
|
||||
const int16_t *in = (const int16_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
{
|
||||
// -32768 is mapped to -1, then -32767 to -32767 are mapped to -1 to 1
|
||||
if(in[c] == -32768)
|
||||
result.f32v[c] = -1.0f;
|
||||
else
|
||||
result.f32v[c] = float(in[c]) / 32767.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected format type on buffer resource");
|
||||
}
|
||||
}
|
||||
else if(fmt.byteWidth == 1)
|
||||
{
|
||||
if(fmt.fmt == CompType::UInt)
|
||||
{
|
||||
const uint8_t *u = (const uint8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.u32v[c] = u[c];
|
||||
}
|
||||
else if(fmt.fmt == CompType::SInt)
|
||||
{
|
||||
const int8_t *in = (const int8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.s32v[c] = in[c];
|
||||
}
|
||||
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
|
||||
{
|
||||
const uint8_t *u = (const uint8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
result.f32v[c] = float(u[c]) / float(0xff);
|
||||
}
|
||||
else if(fmt.fmt == CompType::SNorm)
|
||||
{
|
||||
const int8_t *in = (const int8_t *)d;
|
||||
|
||||
for(int c = 0; c < fmt.numComps; c++)
|
||||
{
|
||||
// -128 is mapped to -1, then -127 to -127 are mapped to -1 to 1
|
||||
if(in[c] == -128)
|
||||
result.f32v[c] = -1.0f;
|
||||
else
|
||||
result.f32v[c] = float(in[c]) / 127.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected format type on buffer resource");
|
||||
}
|
||||
}
|
||||
|
||||
// fill in alpha with 1.0 or 1 as appropriate
|
||||
if(fmt.numComps < 4)
|
||||
{
|
||||
if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB ||
|
||||
fmt.fmt == CompType::SNorm || fmt.fmt == CompType::Float)
|
||||
result.f32v[3] = 1.0f;
|
||||
else
|
||||
result.u32v[3] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FillViewFmt(VarType type, DXILDebug::GlobalState::ViewFmt &fmt)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Float:
|
||||
fmt.byteWidth = 4;
|
||||
fmt.fmt = CompType::Float;
|
||||
break;
|
||||
case VarType::Double:
|
||||
fmt.byteWidth = 8;
|
||||
fmt.fmt = CompType::Float;
|
||||
break;
|
||||
case VarType::Half:
|
||||
fmt.byteWidth = 2;
|
||||
fmt.fmt = CompType::Float;
|
||||
break;
|
||||
case VarType::SInt:
|
||||
fmt.byteWidth = 4;
|
||||
fmt.fmt = CompType::SInt;
|
||||
break;
|
||||
case VarType::UInt:
|
||||
fmt.byteWidth = 4;
|
||||
fmt.fmt = CompType::UInt;
|
||||
break;
|
||||
case VarType::SShort:
|
||||
fmt.byteWidth = 2;
|
||||
fmt.fmt = CompType::SInt;
|
||||
break;
|
||||
case VarType::UShort:
|
||||
fmt.byteWidth = 2;
|
||||
fmt.fmt = CompType::UInt;
|
||||
break;
|
||||
case VarType::SLong:
|
||||
fmt.byteWidth = 8;
|
||||
fmt.fmt = CompType::SInt;
|
||||
break;
|
||||
case VarType::ULong:
|
||||
fmt.byteWidth = 2;
|
||||
fmt.fmt = CompType::UInt;
|
||||
break;
|
||||
case VarType::SByte:
|
||||
fmt.byteWidth = 1;
|
||||
fmt.fmt = CompType::SInt;
|
||||
break;
|
||||
case VarType::UByte:
|
||||
fmt.byteWidth = 1;
|
||||
fmt.fmt = CompType::UInt;
|
||||
break;
|
||||
default: RDCERR("Unhandled Result Type %s", ToStr(type).c_str()); break;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DXILDebug
|
||||
{
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include "driver/shaders/dxbc/dxbc_bytecode.h"
|
||||
#include "driver/shaders/dxbc/dxbc_container.h"
|
||||
#include "dxil_bytecode.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user