in renderdoc/driver/shaders/dxbc/dxbc_debug.cpp [246:446]
bool OperationFlushing(const DXBCBytecode::OpcodeType &op)
{
switch(op)
{
// float mathematical operations all flush denorms
case OPCODE_ADD:
case OPCODE_MUL:
case OPCODE_DIV:
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_MAD:
case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_SINCOS:
case OPCODE_FRC:
case OPCODE_ROUND_PI:
case OPCODE_ROUND_Z:
case OPCODE_ROUND_NE:
case OPCODE_ROUND_NI:
case OPCODE_RCP:
case OPCODE_RSQ:
case OPCODE_SQRT:
case OPCODE_LOG:
case OPCODE_EXP:
case OPCODE_LT:
case OPCODE_GE:
case OPCODE_EQ:
case OPCODE_NE: return true;
// can't generate denorms, or denorm inputs are implicitly rounded to 0, so don't bother
// flushing
case OPCODE_ITOF:
case OPCODE_UTOF:
case OPCODE_FTOI:
case OPCODE_FTOU: return false;
// we have to flush this manually since the input is halves encoded in uints
case OPCODE_F16TOF32:
case OPCODE_F32TOF16: return false;
// implementation defined if this should flush or not, we choose not.
case OPCODE_DTOF:
case OPCODE_FTOD: return false;
// any I/O or data movement operation that does not manipulate the data, such as using the
// ld(22.4.6) instruction to access Resource data, or executing mov instruction or conditional
// move/swap instruction (excluding min or max instructions), must not alter data at all (so a
// denorm remains denorm).
case OPCODE_MOV:
case OPCODE_MOVC:
case OPCODE_LD:
case OPCODE_LD_MS: return false;
// sample operations flush denorms
case OPCODE_SAMPLE:
case OPCODE_SAMPLE_L:
case OPCODE_SAMPLE_B:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
case OPCODE_SAMPLE_D:
case OPCODE_GATHER4:
case OPCODE_GATHER4_C:
case OPCODE_GATHER4_PO:
case OPCODE_GATHER4_PO_C: return true;
// don't flush eval ops as some inputs may be uint
case OPCODE_EVAL_CENTROID:
case OPCODE_EVAL_SAMPLE_INDEX:
case OPCODE_EVAL_SNAPPED: return false;
// don't flush samplepos since an operand is scalar
case OPCODE_SAMPLE_POS: return false;
// unclear if these flush and it's unlikely denorms will come up, so conservatively flush
case OPCODE_SAMPLE_INFO:
case OPCODE_LOD:
case OPCODE_DERIV_RTX:
case OPCODE_DERIV_RTX_COARSE:
case OPCODE_DERIV_RTX_FINE:
case OPCODE_DERIV_RTY:
case OPCODE_DERIV_RTY_COARSE:
case OPCODE_DERIV_RTY_FINE: return true;
// operations that don't work on floats don't flush
case OPCODE_RESINFO:
case OPCODE_BUFINFO:
case OPCODE_LOOP:
case OPCODE_CONTINUE:
case OPCODE_CONTINUEC:
case OPCODE_ENDLOOP:
case OPCODE_SWITCH:
case OPCODE_CASE:
case OPCODE_DEFAULT:
case OPCODE_ENDSWITCH:
case OPCODE_ELSE:
case OPCODE_ENDIF:
case OPCODE_RET:
case OPCODE_RETC:
case OPCODE_DISCARD:
case OPCODE_NOP:
case OPCODE_CUSTOMDATA:
case OPCODE_OPAQUE_CUSTOMDATA:
case OPCODE_SHADER_MESSAGE:
case OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER:
case OPCODE_SYNC:
case OPCODE_STORE_UAV_TYPED:
case OPCODE_STORE_RAW:
case OPCODE_STORE_STRUCTURED: return false;
// integer operations don't flush
case OPCODE_AND:
case OPCODE_OR:
case OPCODE_IADD:
case OPCODE_IMUL:
case OPCODE_IMAD:
case OPCODE_ISHL:
case OPCODE_IGE:
case OPCODE_IEQ:
case OPCODE_ILT:
case OPCODE_ISHR:
case OPCODE_IBFE:
case OPCODE_INE:
case OPCODE_INEG:
case OPCODE_IMAX:
case OPCODE_IMIN:
case OPCODE_SWAPC:
case OPCODE_BREAK:
case OPCODE_BREAKC:
case OPCODE_IF:
case OPCODE_DTOI:
case OPCODE_ATOMIC_IADD:
case OPCODE_ATOMIC_IMAX:
case OPCODE_ATOMIC_IMIN:
case OPCODE_IMM_ATOMIC_IADD:
case OPCODE_IMM_ATOMIC_IMAX:
case OPCODE_IMM_ATOMIC_IMIN:
case OPCODE_ATOMIC_AND:
case OPCODE_ATOMIC_OR:
case OPCODE_ATOMIC_XOR:
case OPCODE_ATOMIC_CMP_STORE:
case OPCODE_ATOMIC_UMAX:
case OPCODE_ATOMIC_UMIN:
case OPCODE_IMM_ATOMIC_AND:
case OPCODE_IMM_ATOMIC_OR:
case OPCODE_IMM_ATOMIC_XOR:
case OPCODE_IMM_ATOMIC_EXCH:
case OPCODE_IMM_ATOMIC_CMP_EXCH:
case OPCODE_IMM_ATOMIC_UMAX:
case OPCODE_IMM_ATOMIC_UMIN:
case OPCODE_BFREV:
case OPCODE_COUNTBITS:
case OPCODE_FIRSTBIT_HI:
case OPCODE_FIRSTBIT_LO:
case OPCODE_FIRSTBIT_SHI:
case OPCODE_UADDC:
case OPCODE_USUBB:
case OPCODE_UMAD:
case OPCODE_UMUL:
case OPCODE_UMIN:
case OPCODE_IMM_ATOMIC_ALLOC:
case OPCODE_IMM_ATOMIC_CONSUME:
case OPCODE_UMAX:
case OPCODE_UDIV:
case OPCODE_USHR:
case OPCODE_ULT:
case OPCODE_UGE:
case OPCODE_BFI:
case OPCODE_UBFE:
case OPCODE_NOT:
case OPCODE_XOR:
case OPCODE_LD_RAW:
case OPCODE_LD_UAV_TYPED:
case OPCODE_LD_STRUCTURED:
case OPCODE_DTOU: return false;
// doubles do not flush
case OPCODE_DADD:
case OPCODE_DMAX:
case OPCODE_DMIN:
case OPCODE_DMUL:
case OPCODE_DEQ:
case OPCODE_DNE:
case OPCODE_DGE:
case OPCODE_DLT:
case OPCODE_DMOV:
case OPCODE_DMOVC:
case OPCODE_DDIV:
case OPCODE_DFMA:
case OPCODE_DRCP:
case OPCODE_ITOD:
case OPCODE_UTOD: return false;
case OPCODE_AMD_U64_ATOMIC:
case OPCODE_NV_U64_ATOMIC: return false;
default: RDCERR("Unhandled operation %d in shader debugging", op); break;
}
return false;
}