Implement Shader Model 6.7 (#4260)
Shader Model 6.7 is still a work in progress. Thanks to multiple contributors at Microsoft for this work. Added support for additional advanced texture operations, including: Raw Gather, Programmable Offsets, SampleCmpLevel, and RWTexture2DMSAA. Added new QuadAny/QuadAll intrinsics to help with writing quad-uniform control flow. Added [WaveOpsIncludeHelperLanes] pixel shader entry attribute, changing the behavior of wave ops to treat helper lanes as active lanes.
This commit is contained in:
Родитель
74a1543493
Коммит
b338314f6e
|
@ -2318,6 +2318,10 @@ ID Name Description
|
|||
219 Unpack4x8 unpacks 4 8-bit signed or unsigned values into int32 or int16 vector
|
||||
220 Pack4x8 packs vector of 4 signed or unsigned values into a packed datatype, drops or clamps unused bits
|
||||
221 IsHelperLane returns true on helper lanes in pixel shaders
|
||||
222 QuadVote compares boolean accross a quad
|
||||
223 TextureGatherRaw Gather raw elements from 4 texels with no type conversions (SRV type is constrained)
|
||||
224 SampleCmpLevel samples a texture and compares a single component against the specified comparison value
|
||||
225 TextureStoreSample stores texel data at specified sample index
|
||||
=== ===================================================== =======================================================================================================================================================================================================================
|
||||
|
||||
|
||||
|
@ -3147,7 +3151,7 @@ SM.INSIDETESSFACTORSIZEMATCHDOMAIN InsideTessFactor rows, columns (%0, %1
|
|||
SM.INVALIDRESOURCECOMPTYPE Invalid resource return type.
|
||||
SM.INVALIDRESOURCEKIND Invalid resources kind.
|
||||
SM.INVALIDSAMPLERFEEDBACKTYPE Invalid sampler feedback type.
|
||||
SM.INVALIDTEXTUREKINDONUAV Texture2DMS[Array] or TextureCube[Array] resources are not supported with UAVs.
|
||||
SM.INVALIDTEXTUREKINDONUAV TextureCube[Array] resources are not supported with UAVs.
|
||||
SM.ISOLINEOUTPUTPRIMITIVEMISMATCH Hull Shader declared with IsoLine Domain must specify output primitive point or line. Triangle_cw or triangle_ccw output are not compatible with the IsoLine Domain.
|
||||
SM.MAXMSSMSIZE Total Thread Group Shared Memory storage is %0, exceeded %1.
|
||||
SM.MAXTGSMSIZE Total Thread Group Shared Memory storage is %0, exceeded %1.
|
||||
|
|
|
@ -3,6 +3,7 @@ include(HCT)
|
|||
add_hlsl_hctgen(HLSLIntrinsicOp OUTPUT HlslIntrinsicOp.h)
|
||||
|
||||
add_subdirectory(DXIL)
|
||||
add_subdirectory(DxilContainer)
|
||||
add_subdirectory(HLSL)
|
||||
add_subdirectory(Support)
|
||||
add_subdirectory(Tracing)
|
||||
|
|
|
@ -575,6 +575,7 @@ namespace DXIL {
|
|||
// Quad Wave Ops
|
||||
QuadOp = 123, // returns the result of a quad-level operation
|
||||
QuadReadLaneAt = 122, // reads from a lane in the quad
|
||||
QuadVote = 222, // compares boolean accross a quad
|
||||
|
||||
// Quaternary
|
||||
Bfi = 53, // Given a bit range from the LSB of a number, places that number of bits in another number at any offset
|
||||
|
@ -616,6 +617,7 @@ namespace DXIL {
|
|||
// Resources - gather
|
||||
TextureGather = 73, // gathers the four texels that would be used in a bi-linear filtering operation
|
||||
TextureGatherCmp = 74, // same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp
|
||||
TextureGatherRaw = 223, // Gather raw elements from 4 texels with no type conversions (SRV type is constrained)
|
||||
|
||||
// Resources - sample
|
||||
RenderTargetGetSampleCount = 77, // gets the number of samples for a render target
|
||||
|
@ -623,6 +625,7 @@ namespace DXIL {
|
|||
Sample = 60, // samples a texture
|
||||
SampleBias = 61, // samples a texture after applying the input bias to the mipmap level
|
||||
SampleCmp = 64, // samples a texture and compares a single component against the specified comparison value
|
||||
SampleCmpLevel = 224, // samples a texture and compares a single component against the specified comparison value
|
||||
SampleCmpLevelZero = 65, // samples a texture and compares a single component against the specified comparison value
|
||||
SampleGrad = 63, // samples a texture using a gradient to influence the way the sample location is calculated
|
||||
SampleLevel = 62, // samples a texture using a mipmap-level offset
|
||||
|
@ -641,6 +644,7 @@ namespace DXIL {
|
|||
RawBufferStore = 140, // writes to a RWByteAddressBuffer or RWStructuredBuffer
|
||||
TextureLoad = 66, // reads texel data without any filtering or sampling
|
||||
TextureStore = 67, // reads texel data without any filtering or sampling
|
||||
TextureStoreSample = 225, // stores texel data at specified sample index
|
||||
|
||||
// Sampler Feedback
|
||||
WriteSamplerFeedback = 174, // updates a feedback texture for a sampling operation
|
||||
|
@ -740,8 +744,9 @@ namespace DXIL {
|
|||
NumOpCodes_Dxil_1_4 = 165,
|
||||
NumOpCodes_Dxil_1_5 = 216,
|
||||
NumOpCodes_Dxil_1_6 = 222,
|
||||
NumOpCodes_Dxil_1_7 = 226,
|
||||
|
||||
NumOpCodes = 222 // exclusive last value of enumeration
|
||||
NumOpCodes = 226 // exclusive last value of enumeration
|
||||
};
|
||||
// OPCODE-ENUM:END
|
||||
|
||||
|
@ -882,6 +887,7 @@ namespace DXIL {
|
|||
// Quad Wave Ops
|
||||
QuadOp,
|
||||
QuadReadLaneAt,
|
||||
QuadVote,
|
||||
|
||||
// Quaternary
|
||||
Quaternary,
|
||||
|
@ -923,6 +929,7 @@ namespace DXIL {
|
|||
// Resources - gather
|
||||
TextureGather,
|
||||
TextureGatherCmp,
|
||||
TextureGatherRaw,
|
||||
|
||||
// Resources - sample
|
||||
RenderTargetGetSampleCount,
|
||||
|
@ -930,6 +937,7 @@ namespace DXIL {
|
|||
Sample,
|
||||
SampleBias,
|
||||
SampleCmp,
|
||||
SampleCmpLevel,
|
||||
SampleCmpLevelZero,
|
||||
SampleGrad,
|
||||
SampleLevel,
|
||||
|
@ -948,6 +956,7 @@ namespace DXIL {
|
|||
RawBufferStore,
|
||||
TextureLoad,
|
||||
TextureStore,
|
||||
TextureStoreSample,
|
||||
|
||||
// Sampler Feedback
|
||||
WriteSamplerFeedback,
|
||||
|
@ -1005,8 +1014,9 @@ namespace DXIL {
|
|||
NumOpClasses_Dxil_1_4 = 120,
|
||||
NumOpClasses_Dxil_1_5 = 143,
|
||||
NumOpClasses_Dxil_1_6 = 149,
|
||||
NumOpClasses_Dxil_1_7 = 153,
|
||||
|
||||
NumOpClasses = 149 // exclusive last value of enumeration
|
||||
NumOpClasses = 153 // exclusive last value of enumeration
|
||||
};
|
||||
// OPCODECLASS-ENUM:END
|
||||
|
||||
|
@ -1347,6 +1357,15 @@ namespace DXIL {
|
|||
};
|
||||
// SIGNEDOPKIND-ENUM:END
|
||||
|
||||
/* <py::lines('QUADVOTEOPKIND-ENUM')>hctdb_instrhelp.get_enum_decl("QuadVoteOpKind")</py>*/
|
||||
// QUADVOTEOPKIND-ENUM:BEGIN
|
||||
// Kind of cross-quad vote operation
|
||||
enum class QuadVoteOpKind : unsigned {
|
||||
All = 1, // true if all conditions are true in this quad
|
||||
Any = 0, // true if any condition is true in this quad
|
||||
};
|
||||
// QUADVOTEOPKIND-ENUM:END
|
||||
|
||||
// Kind of control flow hint
|
||||
enum class ControlFlowHint : unsigned {
|
||||
Undefined = 0,
|
||||
|
@ -1456,7 +1475,11 @@ namespace DXIL {
|
|||
|
||||
const uint64_t ShaderFeatureInfo_AtomicInt64OnHeapResource = 0x10000000;
|
||||
|
||||
const unsigned ShaderFeatureInfoCount = 29;
|
||||
// SM 6.7+
|
||||
const uint64_t ShaderFeatureInfo_AdvancedTextureOps = 0x20000000;
|
||||
const uint64_t ShaderFeatureInfo_WriteableMSAATextures = 0x40000000;
|
||||
|
||||
const unsigned ShaderFeatureInfoCount = 31;
|
||||
|
||||
// DxilSubobjectType must match D3D12_STATE_SUBOBJECT_TYPE, with
|
||||
// certain values reserved, since they cannot be used from Dxil.
|
||||
|
@ -1551,6 +1574,8 @@ namespace DXIL {
|
|||
|
||||
extern const char *kHostLayoutTypePrefix;
|
||||
|
||||
extern const char *kWaveOpsIncludeHelperLanesString;
|
||||
|
||||
} // namespace DXIL
|
||||
|
||||
} // namespace hlsl
|
||||
|
|
|
@ -7164,5 +7164,190 @@ struct DxilInst_IsHelperLane {
|
|||
// Metadata
|
||||
bool requiresUniformInputs() const { return false; }
|
||||
};
|
||||
|
||||
/// This instruction compares boolean accross a quad
|
||||
struct DxilInst_QuadVote {
|
||||
llvm::Instruction *Instr;
|
||||
// Construction and identification
|
||||
DxilInst_QuadVote(llvm::Instruction *pInstr) : Instr(pInstr) {}
|
||||
operator bool() const {
|
||||
return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::QuadVote);
|
||||
}
|
||||
// Validation support
|
||||
bool isAllowed() const { return true; }
|
||||
bool isArgumentListValid() const {
|
||||
if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
|
||||
return true;
|
||||
}
|
||||
// Metadata
|
||||
bool requiresUniformInputs() const { return false; }
|
||||
// Operand indexes
|
||||
enum OperandIdx {
|
||||
arg_cond = 1,
|
||||
arg_op = 2,
|
||||
};
|
||||
// Accessors
|
||||
llvm::Value *get_cond() const { return Instr->getOperand(1); }
|
||||
void set_cond(llvm::Value *val) { Instr->setOperand(1, val); }
|
||||
llvm::Value *get_op() const { return Instr->getOperand(2); }
|
||||
void set_op(llvm::Value *val) { Instr->setOperand(2, val); }
|
||||
int8_t get_op_val() const { return (int8_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(2))->getZExtValue()); }
|
||||
void set_op_val(int8_t val) { Instr->setOperand(2, llvm::Constant::getIntegerValue(llvm::IntegerType::get(Instr->getContext(), 8), llvm::APInt(8, (uint64_t)val))); }
|
||||
};
|
||||
|
||||
/// This instruction Gather raw elements from 4 texels with no type conversions (SRV type is constrained)
|
||||
struct DxilInst_TextureGatherRaw {
|
||||
llvm::Instruction *Instr;
|
||||
// Construction and identification
|
||||
DxilInst_TextureGatherRaw(llvm::Instruction *pInstr) : Instr(pInstr) {}
|
||||
operator bool() const {
|
||||
return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::TextureGatherRaw);
|
||||
}
|
||||
// Validation support
|
||||
bool isAllowed() const { return true; }
|
||||
bool isArgumentListValid() const {
|
||||
if (9 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
|
||||
return true;
|
||||
}
|
||||
// Metadata
|
||||
bool requiresUniformInputs() const { return false; }
|
||||
// Operand indexes
|
||||
enum OperandIdx {
|
||||
arg_srv = 1,
|
||||
arg_sampler = 2,
|
||||
arg_coord0 = 3,
|
||||
arg_coord1 = 4,
|
||||
arg_coord2 = 5,
|
||||
arg_coord3 = 6,
|
||||
arg_offset0 = 7,
|
||||
arg_offset1 = 8,
|
||||
};
|
||||
// Accessors
|
||||
llvm::Value *get_srv() const { return Instr->getOperand(1); }
|
||||
void set_srv(llvm::Value *val) { Instr->setOperand(1, val); }
|
||||
llvm::Value *get_sampler() const { return Instr->getOperand(2); }
|
||||
void set_sampler(llvm::Value *val) { Instr->setOperand(2, val); }
|
||||
llvm::Value *get_coord0() const { return Instr->getOperand(3); }
|
||||
void set_coord0(llvm::Value *val) { Instr->setOperand(3, val); }
|
||||
llvm::Value *get_coord1() const { return Instr->getOperand(4); }
|
||||
void set_coord1(llvm::Value *val) { Instr->setOperand(4, val); }
|
||||
llvm::Value *get_coord2() const { return Instr->getOperand(5); }
|
||||
void set_coord2(llvm::Value *val) { Instr->setOperand(5, val); }
|
||||
llvm::Value *get_coord3() const { return Instr->getOperand(6); }
|
||||
void set_coord3(llvm::Value *val) { Instr->setOperand(6, val); }
|
||||
llvm::Value *get_offset0() const { return Instr->getOperand(7); }
|
||||
void set_offset0(llvm::Value *val) { Instr->setOperand(7, val); }
|
||||
llvm::Value *get_offset1() const { return Instr->getOperand(8); }
|
||||
void set_offset1(llvm::Value *val) { Instr->setOperand(8, val); }
|
||||
};
|
||||
|
||||
/// This instruction samples a texture and compares a single component against the specified comparison value
|
||||
struct DxilInst_SampleCmpLevel {
|
||||
llvm::Instruction *Instr;
|
||||
// Construction and identification
|
||||
DxilInst_SampleCmpLevel(llvm::Instruction *pInstr) : Instr(pInstr) {}
|
||||
operator bool() const {
|
||||
return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::SampleCmpLevel);
|
||||
}
|
||||
// Validation support
|
||||
bool isAllowed() const { return true; }
|
||||
bool isArgumentListValid() const {
|
||||
if (12 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
|
||||
return true;
|
||||
}
|
||||
// Metadata
|
||||
bool requiresUniformInputs() const { return false; }
|
||||
// Operand indexes
|
||||
enum OperandIdx {
|
||||
arg_srv = 1,
|
||||
arg_sampler = 2,
|
||||
arg_coord0 = 3,
|
||||
arg_coord1 = 4,
|
||||
arg_coord2 = 5,
|
||||
arg_coord3 = 6,
|
||||
arg_offset0 = 7,
|
||||
arg_offset1 = 8,
|
||||
arg_offset2 = 9,
|
||||
arg_compareValue = 10,
|
||||
arg_lod = 11,
|
||||
};
|
||||
// Accessors
|
||||
llvm::Value *get_srv() const { return Instr->getOperand(1); }
|
||||
void set_srv(llvm::Value *val) { Instr->setOperand(1, val); }
|
||||
llvm::Value *get_sampler() const { return Instr->getOperand(2); }
|
||||
void set_sampler(llvm::Value *val) { Instr->setOperand(2, val); }
|
||||
llvm::Value *get_coord0() const { return Instr->getOperand(3); }
|
||||
void set_coord0(llvm::Value *val) { Instr->setOperand(3, val); }
|
||||
llvm::Value *get_coord1() const { return Instr->getOperand(4); }
|
||||
void set_coord1(llvm::Value *val) { Instr->setOperand(4, val); }
|
||||
llvm::Value *get_coord2() const { return Instr->getOperand(5); }
|
||||
void set_coord2(llvm::Value *val) { Instr->setOperand(5, val); }
|
||||
llvm::Value *get_coord3() const { return Instr->getOperand(6); }
|
||||
void set_coord3(llvm::Value *val) { Instr->setOperand(6, val); }
|
||||
llvm::Value *get_offset0() const { return Instr->getOperand(7); }
|
||||
void set_offset0(llvm::Value *val) { Instr->setOperand(7, val); }
|
||||
llvm::Value *get_offset1() const { return Instr->getOperand(8); }
|
||||
void set_offset1(llvm::Value *val) { Instr->setOperand(8, val); }
|
||||
llvm::Value *get_offset2() const { return Instr->getOperand(9); }
|
||||
void set_offset2(llvm::Value *val) { Instr->setOperand(9, val); }
|
||||
llvm::Value *get_compareValue() const { return Instr->getOperand(10); }
|
||||
void set_compareValue(llvm::Value *val) { Instr->setOperand(10, val); }
|
||||
llvm::Value *get_lod() const { return Instr->getOperand(11); }
|
||||
void set_lod(llvm::Value *val) { Instr->setOperand(11, val); }
|
||||
};
|
||||
|
||||
/// This instruction stores texel data at specified sample index
|
||||
struct DxilInst_TextureStoreSample {
|
||||
llvm::Instruction *Instr;
|
||||
// Construction and identification
|
||||
DxilInst_TextureStoreSample(llvm::Instruction *pInstr) : Instr(pInstr) {}
|
||||
operator bool() const {
|
||||
return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::TextureStoreSample);
|
||||
}
|
||||
// Validation support
|
||||
bool isAllowed() const { return true; }
|
||||
bool isArgumentListValid() const {
|
||||
if (11 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
|
||||
return true;
|
||||
}
|
||||
// Metadata
|
||||
bool requiresUniformInputs() const { return false; }
|
||||
// Operand indexes
|
||||
enum OperandIdx {
|
||||
arg_srv = 1,
|
||||
arg_coord0 = 2,
|
||||
arg_coord1 = 3,
|
||||
arg_coord2 = 4,
|
||||
arg_value0 = 5,
|
||||
arg_value1 = 6,
|
||||
arg_value2 = 7,
|
||||
arg_value3 = 8,
|
||||
arg_mask = 9,
|
||||
arg_sampleIdx = 10,
|
||||
};
|
||||
// Accessors
|
||||
llvm::Value *get_srv() const { return Instr->getOperand(1); }
|
||||
void set_srv(llvm::Value *val) { Instr->setOperand(1, val); }
|
||||
llvm::Value *get_coord0() const { return Instr->getOperand(2); }
|
||||
void set_coord0(llvm::Value *val) { Instr->setOperand(2, val); }
|
||||
llvm::Value *get_coord1() const { return Instr->getOperand(3); }
|
||||
void set_coord1(llvm::Value *val) { Instr->setOperand(3, val); }
|
||||
llvm::Value *get_coord2() const { return Instr->getOperand(4); }
|
||||
void set_coord2(llvm::Value *val) { Instr->setOperand(4, val); }
|
||||
llvm::Value *get_value0() const { return Instr->getOperand(5); }
|
||||
void set_value0(llvm::Value *val) { Instr->setOperand(5, val); }
|
||||
llvm::Value *get_value1() const { return Instr->getOperand(6); }
|
||||
void set_value1(llvm::Value *val) { Instr->setOperand(6, val); }
|
||||
llvm::Value *get_value2() const { return Instr->getOperand(7); }
|
||||
void set_value2(llvm::Value *val) { Instr->setOperand(7, val); }
|
||||
llvm::Value *get_value3() const { return Instr->getOperand(8); }
|
||||
void set_value3(llvm::Value *val) { Instr->setOperand(8, val); }
|
||||
llvm::Value *get_mask() const { return Instr->getOperand(9); }
|
||||
void set_mask(llvm::Value *val) { Instr->setOperand(9, val); }
|
||||
int8_t get_mask_val() const { return (int8_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(9))->getZExtValue()); }
|
||||
void set_mask_val(int8_t val) { Instr->setOperand(9, llvm::Constant::getIntegerValue(llvm::IntegerType::get(Instr->getContext(), 8), llvm::APInt(8, (uint64_t)val))); }
|
||||
llvm::Value *get_sampleIdx() const { return Instr->getOperand(10); }
|
||||
void set_sampleIdx(llvm::Value *val) { Instr->setOperand(10, val); }
|
||||
};
|
||||
// INSTR-HELPER:END
|
||||
} // namespace hlsl
|
||||
|
|
|
@ -276,6 +276,8 @@ public:
|
|||
bool GetDisableOptimization() const;
|
||||
void SetAllResourcesBound(bool resourcesBound);
|
||||
bool GetAllResourcesBound() const;
|
||||
void SetResMayAlias(bool resMayAlias);
|
||||
bool GetResMayAlias() const;
|
||||
|
||||
// Intermediate options that do not make it to DXIL
|
||||
void SetLegacyResourceReservation(bool legacyResourceReservation);
|
||||
|
@ -383,6 +385,7 @@ private:
|
|||
bool m_bDisableOptimizations;
|
||||
bool m_bUseMinPrecision;
|
||||
bool m_bAllResourcesBound;
|
||||
bool m_bResMayAlias;
|
||||
|
||||
// properties from HLModule that should not make it to the final DXIL
|
||||
uint32_t m_IntermediateFlags;
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace hlsl {
|
|||
|
||||
struct DxilResourceProperties {
|
||||
struct TypedProps {
|
||||
uint8_t CompType; // TypedBuffer/Image component type.
|
||||
uint8_t CompCount; // Number of components known to shader.
|
||||
uint8_t Reserved2;
|
||||
uint8_t CompType; // TypedBuffer/Image component type.
|
||||
uint8_t CompCount; // Number of components known to shader.
|
||||
uint8_t SampleCount; // Number of samples for multisample texture if defined in HLSL.
|
||||
uint8_t Reserved3;
|
||||
};
|
||||
|
||||
|
|
|
@ -132,6 +132,15 @@ namespace hlsl {
|
|||
void SetSamplerDescriptorHeapIndexing(bool flag) { m_bSamplerDescriptorHeapIndexing = flag; }
|
||||
bool GetSamplerDescriptorHeapIndexing() const { return m_bSamplerDescriptorHeapIndexing; }
|
||||
|
||||
void SetResMayNotAlias(bool flag) { m_bResMayNotAlias = flag; }
|
||||
bool GetResMayNotAlias() const { return m_bResMayNotAlias; }
|
||||
|
||||
void SetAdvancedTextureOps(bool flag) { m_bAdvancedTextureOps = flag; }
|
||||
bool GetAdvancedTextureOps() const { return m_bAdvancedTextureOps; }
|
||||
|
||||
void SetWriteableMSAATextures(bool flag) { m_bWriteableMSAATextures = flag; }
|
||||
bool GetWriteableMSAATextures() const { return m_bWriteableMSAATextures; }
|
||||
|
||||
private:
|
||||
unsigned m_bDisableOptimizations :1; // D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION
|
||||
unsigned m_bDisableMathRefactoring :1; //~D3D10_SB_GLOBAL_FLAG_REFACTORING_ALLOWED
|
||||
|
@ -180,7 +189,16 @@ namespace hlsl {
|
|||
|
||||
unsigned m_bAtomicInt64OnHeapResource : 1; // SHADER_FEATURE_ATOMIC_INT64_ON_DESCRIPTOR_HEAP_RESOURCE
|
||||
|
||||
uint32_t m_align1 : 31; // align to 64 bit.
|
||||
// Global flag indicating that any UAV may not alias any other UAV.
|
||||
// Set if UAVs are used, unless -res-may-alias was specified.
|
||||
// For modules compiled against validator version < 1.7, this flag will be
|
||||
// cleared, and it must be assumed that UAV resources may alias.
|
||||
unsigned m_bResMayNotAlias : 1;
|
||||
|
||||
unsigned m_bAdvancedTextureOps : 1; // SHADER_FEATURE_ADVANCED_TEXTURE_OPS
|
||||
unsigned m_bWriteableMSAATextures : 1; // SHADER_FEATURE_WRITEABLE_MSAA_TEXTURES
|
||||
|
||||
uint32_t m_align1 : 28; // align to 64 bit.
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace hlsl {
|
|||
class DxilSubobjects;
|
||||
|
||||
namespace RDAT {
|
||||
class SubobjectTableReader;
|
||||
class DxilRuntimeData;
|
||||
}
|
||||
|
||||
class DxilSubobject {
|
||||
|
@ -175,6 +175,6 @@ private:
|
|||
SubobjectStorage m_Subobjects;
|
||||
};
|
||||
|
||||
bool LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, RDAT::SubobjectTableReader *pSubobjectTableReader);
|
||||
bool LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, const RDAT::DxilRuntimeData &rdat);
|
||||
|
||||
} // namespace hlsl
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
add_hlsl_hctgen(RDAT_LibraryTypes OUTPUT RDAT_LibraryTypes.inl CODE_TAG)
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -18,6 +18,9 @@
|
|||
namespace hlsl {
|
||||
namespace RDAT {
|
||||
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_READER_IMPL
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
struct ResourceKey {
|
||||
uint32_t Class, ID;
|
||||
ResourceKey(uint32_t Class, uint32_t ID) : Class(Class), ID(ID) {}
|
||||
|
@ -92,22 +95,22 @@ public:
|
|||
|
||||
DxilRuntimeData::DxilRuntimeData() : DxilRuntimeData(nullptr, 0) {}
|
||||
|
||||
DxilRuntimeData::DxilRuntimeData(const void *ptr, size_t size)
|
||||
: m_StringReader(), m_IndexTableReader(), m_RawBytesReader(),
|
||||
m_ResourceTableReader(), m_FunctionTableReader(),
|
||||
m_SubobjectTableReader(), m_Context() {
|
||||
m_Context = {&m_StringReader, &m_IndexTableReader, &m_RawBytesReader,
|
||||
&m_ResourceTableReader, &m_FunctionTableReader,
|
||||
&m_SubobjectTableReader};
|
||||
m_ResourceTableReader.SetContext(&m_Context);
|
||||
m_FunctionTableReader.SetContext(&m_Context);
|
||||
m_SubobjectTableReader.SetContext(&m_Context);
|
||||
DxilRuntimeData::DxilRuntimeData(const void *ptr, size_t size) {
|
||||
InitFromRDAT(ptr, size);
|
||||
}
|
||||
|
||||
static void InitTable(RDATContext &ctx, CheckedReader &PR, RecordTableIndex tableIndex) {
|
||||
RuntimeDataTableHeader table = PR.Read<RuntimeDataTableHeader>();
|
||||
size_t tableSize = table.RecordCount * table.RecordStride;
|
||||
ctx.Table(tableIndex)
|
||||
.Init(PR.ReadArray<char>(tableSize), table.RecordCount,
|
||||
table.RecordStride);
|
||||
}
|
||||
|
||||
// initializing reader from RDAT. return true if no error has occured.
|
||||
bool DxilRuntimeData::InitFromRDAT(const void *pRDAT, size_t size) {
|
||||
if (pRDAT) {
|
||||
m_DataSize = size;
|
||||
try {
|
||||
CheckedReader Reader(pRDAT, size);
|
||||
RuntimeDataHeader RDATHeader = Reader.Read<RuntimeDataHeader>();
|
||||
|
@ -121,66 +124,167 @@ bool DxilRuntimeData::InitFromRDAT(const void *pRDAT, size_t size) {
|
|||
CheckedReader PR(Reader.ReadArray<char>(part.Size), part.Size);
|
||||
switch (part.Type) {
|
||||
case RuntimeDataPartType::StringBuffer: {
|
||||
m_StringReader = StringTableReader(
|
||||
PR.ReadArray<char>(part.Size), part.Size);
|
||||
m_Context.StringBuffer.Init(PR.ReadArray<char>(part.Size), part.Size);
|
||||
break;
|
||||
}
|
||||
case RuntimeDataPartType::IndexArrays: {
|
||||
uint32_t count = part.Size / sizeof(uint32_t);
|
||||
m_IndexTableReader = IndexTableReader(
|
||||
PR.ReadArray<uint32_t>(count), count);
|
||||
m_Context.IndexTable.Init(PR.ReadArray<uint32_t>(count), count);
|
||||
break;
|
||||
}
|
||||
case RuntimeDataPartType::RawBytes: {
|
||||
m_RawBytesReader = RawBytesReader(
|
||||
PR.ReadArray<char>(part.Size), part.Size);
|
||||
break;
|
||||
}
|
||||
case RuntimeDataPartType::ResourceTable: {
|
||||
RuntimeDataTableHeader table = PR.Read<RuntimeDataTableHeader>();
|
||||
size_t tableSize = table.RecordCount * table.RecordStride;
|
||||
m_ResourceTableReader.SetResourceInfo(PR.ReadArray<char>(tableSize),
|
||||
table.RecordCount, table.RecordStride);
|
||||
break;
|
||||
}
|
||||
case RuntimeDataPartType::FunctionTable: {
|
||||
RuntimeDataTableHeader table = PR.Read<RuntimeDataTableHeader>();
|
||||
size_t tableSize = table.RecordCount * table.RecordStride;
|
||||
m_FunctionTableReader.SetFunctionInfo(PR.ReadArray<char>(tableSize),
|
||||
table.RecordCount, table.RecordStride);
|
||||
break;
|
||||
}
|
||||
case RuntimeDataPartType::SubobjectTable: {
|
||||
RuntimeDataTableHeader table = PR.Read<RuntimeDataTableHeader>();
|
||||
size_t tableSize = table.RecordCount * table.RecordStride;
|
||||
m_SubobjectTableReader.SetSubobjectInfo(PR.ReadArray<char>(tableSize),
|
||||
table.RecordCount, table.RecordStride);
|
||||
m_Context.RawBytes.Init(PR.ReadArray<char>(part.Size), part.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
// Once per table.
|
||||
#define RDAT_STRUCT_TABLE(type, table) case RuntimeDataPartType::table: InitTable(m_Context, PR, RecordTableIndex::table); break;
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_DEFAULTS
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
default:
|
||||
continue; // Skip unrecognized parts
|
||||
}
|
||||
}
|
||||
#ifdef DBG
|
||||
return Validate();
|
||||
#else // DBG
|
||||
return true;
|
||||
#endif // DBG
|
||||
} catch(CheckedReader::exception e) {
|
||||
// TODO: error handling
|
||||
//throw hlsl::Exception(DXC_E_MALFORMED_CONTAINER, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_DataSize = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionTableReader *DxilRuntimeData::GetFunctionTableReader() {
|
||||
return &m_FunctionTableReader;
|
||||
// PRERELEASE-TODO: Incorporate field names and report errors in error stream
|
||||
|
||||
// PRERELEASE-TODO: Low-pri: Check other things like that all the index, string,
|
||||
// and binary buffer space is actually used.
|
||||
|
||||
template<typename _RecordType>
|
||||
static bool ValidateRecordRef(const RDATContext &ctx, uint32_t id) {
|
||||
if (id == RDAT_NULL_REF)
|
||||
return true;
|
||||
// id should be a valid index into the appropriate table
|
||||
auto &table = ctx.Table(RecordTraits<_RecordType>::TableIndex());
|
||||
if (id >= table.Count())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ResourceTableReader *DxilRuntimeData::GetResourceTableReader() {
|
||||
return &m_ResourceTableReader;
|
||||
static bool ValidateIndexArrayRef(const RDATContext &ctx, uint32_t id) {
|
||||
if (id == RDAT_NULL_REF)
|
||||
return true;
|
||||
uint32_t size = ctx.IndexTable.Count();
|
||||
// check that id < size of index array
|
||||
if (id >= size)
|
||||
return false;
|
||||
// check that array size fits in remaining index space
|
||||
if (id + ctx.IndexTable.Data()[id] >= size)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SubobjectTableReader *DxilRuntimeData::GetSubobjectTableReader() {
|
||||
return &m_SubobjectTableReader;
|
||||
template<typename _RecordType>
|
||||
static bool ValidateRecordArrayRef(const RDATContext &ctx, uint32_t id) {
|
||||
// Make sure index array is well-formed
|
||||
if (!ValidateIndexArrayRef(ctx, id))
|
||||
return false;
|
||||
// Make sure each record id is a valid record ref in the table
|
||||
auto ids = ctx.IndexTable.getRow(id);
|
||||
for (unsigned i = 0; i < ids.Count(); i++) {
|
||||
if (!ValidateRecordRef<_RecordType>(ctx, ids.At(i)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool ValidateStringRef(const RDATContext &ctx, uint32_t id) {
|
||||
if (id == RDAT_NULL_REF)
|
||||
return true;
|
||||
uint32_t size = ctx.StringBuffer.Size();
|
||||
if (id >= size)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
static bool ValidateStringArrayRef(const RDATContext &ctx, uint32_t id) {
|
||||
if (id == RDAT_NULL_REF)
|
||||
return true;
|
||||
// Make sure index array is well-formed
|
||||
if (!ValidateIndexArrayRef(ctx, id))
|
||||
return false;
|
||||
// Make sure each index is valid in string buffer
|
||||
auto ids = ctx.IndexTable.getRow(id);
|
||||
for (unsigned i = 0; i < ids.Count(); i++) {
|
||||
if (!ValidateStringRef(ctx, ids.At(i)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Specialized for each record type
|
||||
template<typename _RecordType>
|
||||
bool ValidateRecord(const RDATContext &ctx, const _RecordType *pRecord) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_STRUCT_VALIDATION
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
// This class ensures that all versions of record to latest one supported by
|
||||
// table stride are validated
|
||||
class RecursiveRecordValidator {
|
||||
const hlsl::RDAT::RDATContext &m_Context;
|
||||
uint32_t m_RecordStride;
|
||||
public:
|
||||
RecursiveRecordValidator(const hlsl::RDAT::RDATContext &ctx, uint32_t recordStride)
|
||||
: m_Context(ctx), m_RecordStride(recordStride) {}
|
||||
template<typename _RecordType>
|
||||
bool Validate(const _RecordType *pRecord) const {
|
||||
if (pRecord && sizeof(_RecordType) <= m_RecordStride) {
|
||||
if (!ValidateRecord(m_Context, pRecord))
|
||||
return false;
|
||||
return ValidateDerived<_RecordType>(pRecord);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Specialized for base type to recurse into derived
|
||||
template<typename _RecordType>
|
||||
bool ValidateDerived(const _RecordType *) const { return true; }
|
||||
};
|
||||
|
||||
template<typename _RecordType>
|
||||
static bool ValidateRecordTable(RDATContext &ctx, RecordTableIndex tableIndex) {
|
||||
// iterate through records, bounds-checking all refs and index arrays
|
||||
auto &table = ctx.Table(tableIndex);
|
||||
for (unsigned i = 0; i < table.Count(); i++) {
|
||||
RecursiveRecordValidator(ctx, table.Stride())
|
||||
.Validate<_RecordType>(table.Row<_RecordType>(i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DxilRuntimeData::Validate() {
|
||||
if (m_Context.StringBuffer.Size()) {
|
||||
if (m_Context.StringBuffer.Data()[m_Context.StringBuffer.Size() - 1] != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Once per table.
|
||||
#define RDAT_STRUCT_TABLE(type, table) ValidateRecordTable<type>(m_Context, RecordTableIndex::table);
|
||||
// As an assumption of the way record types are versioned, derived record
|
||||
// types must always be larger than base record types.
|
||||
#define RDAT_STRUCT_DERIVED(type, base) \
|
||||
static_assert(sizeof(type) > sizeof(base), \
|
||||
"otherwise, derived record type " #type \
|
||||
" is not larger than base record type " #base ".");
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_DEFAULTS
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
return true;
|
||||
}
|
||||
|
||||
}} // hlsl::RDAT
|
||||
|
@ -212,6 +316,7 @@ private:
|
|||
DxilRuntimeData m_RuntimeData;
|
||||
StringMap m_StringMap;
|
||||
BytesMap m_BytesMap;
|
||||
std::vector<uint32_t> m_IndexData;
|
||||
ResourceList m_Resources;
|
||||
FunctionList m_Functions;
|
||||
SubobjectList m_Subobjects;
|
||||
|
@ -226,14 +331,14 @@ private:
|
|||
const void *GetBytes(const void *ptr, size_t size);
|
||||
void InitializeReflection();
|
||||
const DxilResourceDesc * const*GetResourcesForFunction(DxilFunctionDesc &function,
|
||||
const FunctionReader &functionReader);
|
||||
const RuntimeDataFunctionInfo_Reader &functionReader);
|
||||
const wchar_t **GetDependenciesForFunction(DxilFunctionDesc &function,
|
||||
const FunctionReader &functionReader);
|
||||
const RuntimeDataFunctionInfo_Reader &functionReader);
|
||||
const wchar_t **GetExportsForAssociation(DxilSubobjectDesc &subobject,
|
||||
const SubobjectReader &subobjectReader);
|
||||
DxilResourceDesc *AddResource(const ResourceReader &resourceReader);
|
||||
DxilFunctionDesc *AddFunction(const FunctionReader &functionReader);
|
||||
DxilSubobjectDesc *AddSubobject(const SubobjectReader &subobjectReader);
|
||||
const RuntimeDataSubobjectInfo_Reader &reader);
|
||||
void AddResources();
|
||||
void AddFunctions();
|
||||
void AddSubobjects();
|
||||
|
||||
public:
|
||||
// TODO: Implement pipeline state validation with runtime data
|
||||
|
@ -269,6 +374,9 @@ const wchar_t *DxilRuntimeReflection_impl::GetWideString(const char *ptr) {
|
|||
}
|
||||
|
||||
const void *DxilRuntimeReflection_impl::GetBytes(const void *ptr, size_t size) {
|
||||
if (!ptr || !size)
|
||||
return nullptr;
|
||||
|
||||
auto it = m_BytesMap.find(ptr);
|
||||
if (it != m_BytesMap.end())
|
||||
return it->second.get();
|
||||
|
@ -282,6 +390,8 @@ const void *DxilRuntimeReflection_impl::GetBytes(const void *ptr, size_t size) {
|
|||
bool DxilRuntimeReflection_impl::InitFromRDAT(const void *pRDAT, size_t size) {
|
||||
assert(!m_initialized && "may only initialize once");
|
||||
m_initialized = m_RuntimeData.InitFromRDAT(pRDAT, size);
|
||||
if (!m_RuntimeData.Validate())
|
||||
return false;
|
||||
if (m_initialized)
|
||||
InitializeReflection();
|
||||
return m_initialized;
|
||||
|
@ -290,79 +400,59 @@ bool DxilRuntimeReflection_impl::InitFromRDAT(const void *pRDAT, size_t size) {
|
|||
const DxilLibraryDesc DxilRuntimeReflection_impl::GetLibraryReflection() {
|
||||
DxilLibraryDesc reflection = {};
|
||||
if (m_initialized) {
|
||||
reflection.NumResources =
|
||||
m_RuntimeData.GetResourceTableReader()->GetNumResources();
|
||||
reflection.NumResources = m_Resources.size();
|
||||
reflection.pResource = m_Resources.data();
|
||||
reflection.NumFunctions =
|
||||
m_RuntimeData.GetFunctionTableReader()->GetNumFunctions();
|
||||
reflection.NumFunctions = m_Functions.size();
|
||||
reflection.pFunction = m_Functions.data();
|
||||
reflection.NumSubobjects =
|
||||
m_RuntimeData.GetSubobjectTableReader()->GetCount();
|
||||
reflection.NumSubobjects = m_Subobjects.size();
|
||||
reflection.pSubobjects = m_Subobjects.data();
|
||||
}
|
||||
return reflection;
|
||||
}
|
||||
|
||||
void DxilRuntimeReflection_impl::InitializeReflection() {
|
||||
auto indexTable = m_RuntimeData.GetContext().IndexTable;
|
||||
m_IndexData.assign(indexTable.Data(), indexTable.Data() + indexTable.Count());
|
||||
|
||||
// First need to reserve spaces for resources because functions will need to
|
||||
// reference them via pointers.
|
||||
const ResourceTableReader *resourceTableReader = m_RuntimeData.GetResourceTableReader();
|
||||
m_Resources.reserve(resourceTableReader->GetNumResources());
|
||||
for (uint32_t i = 0; i < resourceTableReader->GetNumResources(); ++i) {
|
||||
ResourceReader resourceReader = resourceTableReader->GetItem(i);
|
||||
AddString(resourceReader.GetName());
|
||||
DxilResourceDesc *pResource = AddResource(resourceReader);
|
||||
if (pResource) {
|
||||
ResourceKey key(pResource->Class, pResource->ID);
|
||||
m_ResourceMap[key] = pResource;
|
||||
}
|
||||
}
|
||||
const FunctionTableReader *functionTableReader = m_RuntimeData.GetFunctionTableReader();
|
||||
m_Functions.reserve(functionTableReader->GetNumFunctions());
|
||||
for (uint32_t i = 0; i < functionTableReader->GetNumFunctions(); ++i) {
|
||||
FunctionReader functionReader = functionTableReader->GetItem(i);
|
||||
AddString(functionReader.GetName());
|
||||
AddFunction(functionReader);
|
||||
}
|
||||
const SubobjectTableReader *subobjectTableReader = m_RuntimeData.GetSubobjectTableReader();
|
||||
m_Subobjects.reserve(subobjectTableReader->GetCount());
|
||||
for (uint32_t i = 0; i < subobjectTableReader->GetCount(); ++i) {
|
||||
SubobjectReader subobjectReader = subobjectTableReader->GetItem(i);
|
||||
AddString(subobjectReader.GetName());
|
||||
AddSubobject(subobjectReader);
|
||||
}
|
||||
AddResources();
|
||||
AddFunctions();
|
||||
AddSubobjects();
|
||||
}
|
||||
|
||||
DxilResourceDesc *
|
||||
DxilRuntimeReflection_impl::AddResource(const ResourceReader &resourceReader) {
|
||||
assert(m_Resources.size() < m_Resources.capacity() && "Otherwise, number of resources was incorrect");
|
||||
if (!(m_Resources.size() < m_Resources.capacity()))
|
||||
return nullptr;
|
||||
m_Resources.emplace_back(DxilResourceDesc({}));
|
||||
DxilResourceDesc &resource = m_Resources.back();
|
||||
resource.Class = (uint32_t)resourceReader.GetResourceClass();
|
||||
resource.Kind = (uint32_t)resourceReader.GetResourceKind();
|
||||
resource.Space = resourceReader.GetSpace();
|
||||
resource.LowerBound = resourceReader.GetLowerBound();
|
||||
resource.UpperBound = resourceReader.GetUpperBound();
|
||||
resource.ID = resourceReader.GetID();
|
||||
resource.Flags = resourceReader.GetFlags();
|
||||
resource.Name = GetWideString(resourceReader.GetName());
|
||||
return &resource;
|
||||
void DxilRuntimeReflection_impl::AddResources() {
|
||||
auto table = m_RuntimeData.GetResourceTable();
|
||||
m_Resources.assign(table.Count(), {});
|
||||
for (uint32_t i = 0; i < table.Count(); ++i) {
|
||||
auto reader = table[i];
|
||||
DxilResourceDesc &desc = m_Resources[i];
|
||||
desc.Class = (uint32_t)reader.getClass();
|
||||
desc.Kind = (uint32_t)reader.getKind();
|
||||
desc.Space = reader.getSpace();
|
||||
desc.LowerBound = reader.getLowerBound();
|
||||
desc.UpperBound = reader.getUpperBound();
|
||||
desc.ID = reader.getID();
|
||||
desc.Flags = reader.getFlags();
|
||||
desc.Name = GetWideString(reader.getName());
|
||||
ResourceKey key(desc.Class, desc.ID);
|
||||
m_ResourceMap[key] = &desc;
|
||||
}
|
||||
}
|
||||
|
||||
const DxilResourceDesc * const*DxilRuntimeReflection_impl::GetResourcesForFunction(
|
||||
DxilFunctionDesc &function, const FunctionReader &functionReader) {
|
||||
if (!functionReader.GetNumResources())
|
||||
DxilFunctionDesc &function, const RuntimeDataFunctionInfo_Reader &functionReader) {
|
||||
auto resources = functionReader.getResources();
|
||||
if (!resources.Count())
|
||||
return nullptr;
|
||||
auto it = m_FuncToResMap.insert(std::make_pair(&function, ResourceRefList()));
|
||||
assert(it.second && "otherwise, collision");
|
||||
ResourceRefList &resourceList = it.first->second;
|
||||
resourceList.reserve(functionReader.GetNumResources());
|
||||
for (uint32_t i = 0; i < functionReader.GetNumResources(); ++i) {
|
||||
const ResourceReader resourceReader = functionReader.GetResource(i);
|
||||
ResourceKey key((uint32_t)resourceReader.GetResourceClass(),
|
||||
resourceReader.GetID());
|
||||
resourceList.reserve(resources.Count());
|
||||
for (uint32_t i = 0; i < resources.Count(); ++i) {
|
||||
auto resourceReader = functionReader.getResources()[i];
|
||||
ResourceKey key((uint32_t)resourceReader.getClass(),
|
||||
resourceReader.getID());
|
||||
auto it = m_ResourceMap.find(key);
|
||||
assert(it != m_ResourceMap.end() && it->second && "Otherwise, resource was not in map, or was null");
|
||||
resourceList.emplace_back(it->second);
|
||||
|
@ -371,97 +461,96 @@ const DxilResourceDesc * const*DxilRuntimeReflection_impl::GetResourcesForFuncti
|
|||
}
|
||||
|
||||
const wchar_t **DxilRuntimeReflection_impl::GetDependenciesForFunction(
|
||||
DxilFunctionDesc &function, const FunctionReader &functionReader) {
|
||||
DxilFunctionDesc &function, const RuntimeDataFunctionInfo_Reader &functionReader) {
|
||||
auto it = m_FuncToDependenciesMap.insert(std::make_pair(&function, WStringList()));
|
||||
assert(it.second && "otherwise, collision");
|
||||
WStringList &wStringList = it.first->second;
|
||||
for (uint32_t i = 0; i < functionReader.GetNumDependencies(); ++i) {
|
||||
wStringList.emplace_back(GetWideString(functionReader.GetDependency(i)));
|
||||
auto dependencies = functionReader.getFunctionDependencies();
|
||||
for (uint32_t i = 0; i < dependencies.Count(); ++i) {
|
||||
wStringList.emplace_back(GetWideString(dependencies[i]));
|
||||
}
|
||||
return wStringList.empty() ? nullptr : wStringList.data();
|
||||
}
|
||||
|
||||
DxilFunctionDesc *
|
||||
DxilRuntimeReflection_impl::AddFunction(const FunctionReader &functionReader) {
|
||||
assert(m_Functions.size() < m_Functions.capacity() && "Otherwise, number of functions was incorrect");
|
||||
if (!(m_Functions.size() < m_Functions.capacity()))
|
||||
return nullptr;
|
||||
m_Functions.emplace_back(DxilFunctionDesc({}));
|
||||
DxilFunctionDesc &function = m_Functions.back();
|
||||
function.Name = GetWideString(functionReader.GetName());
|
||||
function.UnmangledName = GetWideString(functionReader.GetUnmangledName());
|
||||
function.NumResources = functionReader.GetNumResources();
|
||||
function.Resources = GetResourcesForFunction(function, functionReader);
|
||||
function.NumFunctionDependencies = functionReader.GetNumDependencies();
|
||||
function.FunctionDependencies =
|
||||
GetDependenciesForFunction(function, functionReader);
|
||||
function.ShaderKind = (uint32_t)functionReader.GetShaderKind();
|
||||
function.PayloadSizeInBytes = functionReader.GetPayloadSizeInBytes();
|
||||
function.AttributeSizeInBytes = functionReader.GetAttributeSizeInBytes();
|
||||
function.FeatureInfo1 = functionReader.GetFeatureInfo1();
|
||||
function.FeatureInfo2 = functionReader.GetFeatureInfo2();
|
||||
function.ShaderStageFlag = functionReader.GetShaderStageFlag();
|
||||
function.MinShaderTarget = functionReader.GetMinShaderTarget();
|
||||
return &function;
|
||||
void DxilRuntimeReflection_impl::AddFunctions() {
|
||||
auto table = m_RuntimeData.GetFunctionTable();
|
||||
m_Functions.assign(table.Count(), {});
|
||||
for (uint32_t i = 0; i < table.Count(); ++i) {
|
||||
auto reader = table[i];
|
||||
auto &desc = m_Functions[i];
|
||||
desc.Name = GetWideString(reader.getName());
|
||||
desc.UnmangledName = GetWideString(reader.getUnmangledName());
|
||||
desc.NumResources = reader.getResources().Count();
|
||||
desc.Resources = GetResourcesForFunction(desc, reader);
|
||||
desc.NumFunctionDependencies = reader.getFunctionDependencies().Count();
|
||||
desc.FunctionDependencies = GetDependenciesForFunction(desc, reader);
|
||||
desc.ShaderKind = reader.getShaderKind();
|
||||
desc.PayloadSizeInBytes = reader.getPayloadSizeInBytes();
|
||||
desc.AttributeSizeInBytes = reader.getAttributeSizeInBytes();
|
||||
desc.FeatureInfo1 = reader.getFeatureInfo1();
|
||||
desc.FeatureInfo2 = reader.getFeatureInfo2();
|
||||
desc.ShaderStageFlag = reader.getShaderStageFlag();
|
||||
desc.MinShaderTarget = reader.getMinShaderTarget();
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t **DxilRuntimeReflection_impl::GetExportsForAssociation(
|
||||
DxilSubobjectDesc &subobject, const SubobjectReader &subobjectReader) {
|
||||
DxilSubobjectDesc &subobject, const RuntimeDataSubobjectInfo_Reader &reader) {
|
||||
auto it = m_SubobjectToExportsMap.insert(std::make_pair(&subobject, WStringList()));
|
||||
assert(it.second && "otherwise, collision");
|
||||
auto exports = reader.getSubobjectToExportsAssociation().getExports();
|
||||
WStringList &wStringList = it.first->second;
|
||||
for (uint32_t i = 0; i < subobjectReader.GetSubobjectToExportsAssociation_NumExports(); ++i) {
|
||||
wStringList.emplace_back(GetWideString(subobjectReader.GetSubobjectToExportsAssociation_Export(i)));
|
||||
for (uint32_t i = 0; i < exports.Count(); ++i) {
|
||||
wStringList.emplace_back(GetWideString(exports[i]));
|
||||
}
|
||||
return wStringList.empty() ? nullptr : wStringList.data();
|
||||
}
|
||||
|
||||
DxilSubobjectDesc *DxilRuntimeReflection_impl::AddSubobject(const SubobjectReader &subobjectReader) {
|
||||
assert(m_Subobjects.size() < m_Subobjects.capacity() && "Otherwise, number of subobjects was incorrect");
|
||||
if (!(m_Subobjects.size() < m_Subobjects.capacity()))
|
||||
return nullptr;
|
||||
m_Subobjects.emplace_back(DxilSubobjectDesc({}));
|
||||
DxilSubobjectDesc &subobject = m_Subobjects.back();
|
||||
subobject.Name = GetWideString(subobjectReader.GetName());
|
||||
subobject.Kind = (uint32_t)subobjectReader.GetKind();
|
||||
switch (subobjectReader.GetKind()) {
|
||||
case DXIL::SubobjectKind::StateObjectConfig:
|
||||
subobject.StateObjectConfig.Flags = subobjectReader.GetStateObjectConfig_Flags();
|
||||
break;
|
||||
case DXIL::SubobjectKind::GlobalRootSignature:
|
||||
case DXIL::SubobjectKind::LocalRootSignature:
|
||||
if (!subobjectReader.GetRootSignature(&subobject.RootSignature.pSerializedSignature, &subobject.RootSignature.SizeInBytes))
|
||||
return nullptr;
|
||||
subobject.RootSignature.pSerializedSignature = GetBytes(subobject.RootSignature.pSerializedSignature, subobject.RootSignature.SizeInBytes);
|
||||
break;
|
||||
case DXIL::SubobjectKind::SubobjectToExportsAssociation:
|
||||
subobject.SubobjectToExportsAssociation.Subobject =
|
||||
GetWideString(subobjectReader.GetSubobjectToExportsAssociation_Subobject());
|
||||
subobject.SubobjectToExportsAssociation.NumExports = subobjectReader.GetSubobjectToExportsAssociation_NumExports();
|
||||
subobject.SubobjectToExportsAssociation.Exports = GetExportsForAssociation(subobject, subobjectReader);
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingShaderConfig:
|
||||
subobject.RaytracingShaderConfig.MaxPayloadSizeInBytes = subobjectReader.GetRaytracingShaderConfig_MaxPayloadSizeInBytes();
|
||||
subobject.RaytracingShaderConfig.MaxAttributeSizeInBytes = subobjectReader.GetRaytracingShaderConfig_MaxAttributeSizeInBytes();
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig:
|
||||
subobject.RaytracingPipelineConfig.MaxTraceRecursionDepth = subobjectReader.GetRaytracingPipelineConfig_MaxTraceRecursionDepth();
|
||||
break;
|
||||
case DXIL::SubobjectKind::HitGroup:
|
||||
subobject.HitGroup.Type = (uint32_t)subobjectReader.GetHitGroup_Type();
|
||||
subobject.HitGroup.Intersection = GetWideString(subobjectReader.GetHitGroup_Intersection());
|
||||
subobject.HitGroup.AnyHit = GetWideString(subobjectReader.GetHitGroup_AnyHit());
|
||||
subobject.HitGroup.ClosestHit = GetWideString(subobjectReader.GetHitGroup_ClosestHit());
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
|
||||
subobject.RaytracingPipelineConfig1.MaxTraceRecursionDepth = subobjectReader.GetRaytracingPipelineConfig1_MaxTraceRecursionDepth();
|
||||
subobject.RaytracingPipelineConfig1.Flags = subobjectReader.GetRaytracingPipelineConfig1_Flags();
|
||||
break;
|
||||
default:
|
||||
// Ignore contents of unrecognized subobject type (forward-compat)
|
||||
break;
|
||||
void DxilRuntimeReflection_impl::AddSubobjects() {
|
||||
auto table = m_RuntimeData.GetSubobjectTable();
|
||||
m_Subobjects.assign(table.Count(), {});
|
||||
for (uint32_t i = 0; i < table.Count(); ++i) {
|
||||
auto reader = table[i];
|
||||
auto &desc = m_Subobjects[i];
|
||||
desc.Name = GetWideString(reader.getName());
|
||||
desc.Kind = reader.getKind();
|
||||
switch (reader.getKind()) {
|
||||
case DXIL::SubobjectKind::StateObjectConfig:
|
||||
desc.StateObjectConfig.Flags = reader.getStateObjectConfig().getFlags();
|
||||
break;
|
||||
case DXIL::SubobjectKind::GlobalRootSignature:
|
||||
case DXIL::SubobjectKind::LocalRootSignature:
|
||||
desc.RootSignature.SizeInBytes = reader.getRootSignature().sizeData();
|
||||
desc.RootSignature.pSerializedSignature = GetBytes(reader.getRootSignature().getData(), desc.RootSignature.SizeInBytes);
|
||||
break;
|
||||
case DXIL::SubobjectKind::SubobjectToExportsAssociation:
|
||||
desc.SubobjectToExportsAssociation.Subobject =
|
||||
GetWideString(reader.getSubobjectToExportsAssociation().getSubobject());
|
||||
desc.SubobjectToExportsAssociation.NumExports = reader.getSubobjectToExportsAssociation().getExports().Count();
|
||||
desc.SubobjectToExportsAssociation.Exports = GetExportsForAssociation(desc, reader);
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingShaderConfig:
|
||||
desc.RaytracingShaderConfig.MaxPayloadSizeInBytes = reader.getRaytracingShaderConfig().getMaxPayloadSizeInBytes();
|
||||
desc.RaytracingShaderConfig.MaxAttributeSizeInBytes = reader.getRaytracingShaderConfig().getMaxAttributeSizeInBytes();
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig:
|
||||
desc.RaytracingPipelineConfig.MaxTraceRecursionDepth = reader.getRaytracingPipelineConfig().getMaxTraceRecursionDepth();
|
||||
break;
|
||||
case DXIL::SubobjectKind::HitGroup:
|
||||
desc.HitGroup.Type = reader.getHitGroup().getType();
|
||||
desc.HitGroup.Intersection = GetWideString(reader.getHitGroup().getIntersection());
|
||||
desc.HitGroup.AnyHit = GetWideString(reader.getHitGroup().getAnyHit());
|
||||
desc.HitGroup.ClosestHit = GetWideString(reader.getHitGroup().getClosestHit());
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
|
||||
desc.RaytracingPipelineConfig1.MaxTraceRecursionDepth = reader.getRaytracingPipelineConfig1().getMaxTraceRecursionDepth();
|
||||
desc.RaytracingPipelineConfig1.Flags = reader.getRaytracingPipelineConfig1().getFlags();
|
||||
break;
|
||||
default:
|
||||
// Ignore contents of unrecognized subobject type (forward-compat)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return &subobject;
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// RDAT_LibraryTypes.inl //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Defines types used in Dxil Library Runtime Data (RDAT). //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef DEF_RDAT_ENUMS
|
||||
|
||||
RDAT_ENUM_START(DxilResourceFlag, uint32_t)
|
||||
RDAT_ENUM_VALUE(None, 0)
|
||||
RDAT_ENUM_VALUE(UAVGloballyCoherent, 1 << 0)
|
||||
RDAT_ENUM_VALUE(UAVCounter, 1 << 1)
|
||||
RDAT_ENUM_VALUE(UAVRasterizerOrderedView, 1 << 2)
|
||||
RDAT_ENUM_VALUE(DynamicIndexing, 1 << 3)
|
||||
RDAT_ENUM_VALUE(Atomics64Use, 1 << 4)
|
||||
RDAT_ENUM_END()
|
||||
|
||||
#endif // DEF_RDAT_ENUMS
|
||||
|
||||
#ifdef DEF_DXIL_ENUMS
|
||||
|
||||
// Enums using RDAT_DXIL_ENUM_START use existing definitions of enums, rather
|
||||
// than redefining the enum locally. The definition here is mainly to
|
||||
// implement the ToString function.
|
||||
// A static_assert under DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL is used to
|
||||
// check one enum value that would change if the enum were to be updated,
|
||||
// making sure this definition is updated as well.
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::ResourceClass, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(SRV)
|
||||
RDAT_ENUM_VALUE_NODEF(UAV)
|
||||
RDAT_ENUM_VALUE_NODEF(CBuffer)
|
||||
RDAT_ENUM_VALUE_NODEF(Sampler)
|
||||
RDAT_ENUM_VALUE_NODEF(Invalid)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::ResourceClass::Invalid == 4, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::ResourceKind, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(Invalid)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture1D)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture2D)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture2DMS)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture3D)
|
||||
RDAT_ENUM_VALUE_NODEF(TextureCube)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture1DArray)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture2DArray)
|
||||
RDAT_ENUM_VALUE_NODEF(Texture2DMSArray)
|
||||
RDAT_ENUM_VALUE_NODEF(TextureCubeArray)
|
||||
RDAT_ENUM_VALUE_NODEF(TypedBuffer)
|
||||
RDAT_ENUM_VALUE_NODEF(RawBuffer)
|
||||
RDAT_ENUM_VALUE_NODEF(StructuredBuffer)
|
||||
RDAT_ENUM_VALUE_NODEF(CBuffer)
|
||||
RDAT_ENUM_VALUE_NODEF(Sampler)
|
||||
RDAT_ENUM_VALUE_NODEF(TBuffer)
|
||||
RDAT_ENUM_VALUE_NODEF(RTAccelerationStructure)
|
||||
RDAT_ENUM_VALUE_NODEF(FeedbackTexture2D)
|
||||
RDAT_ENUM_VALUE_NODEF(FeedbackTexture2DArray)
|
||||
RDAT_ENUM_VALUE_NODEF(NumEntries)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::ResourceKind::NumEntries == 19, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::ShaderKind, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(Pixel)
|
||||
RDAT_ENUM_VALUE_NODEF(Vertex)
|
||||
RDAT_ENUM_VALUE_NODEF(Geometry)
|
||||
RDAT_ENUM_VALUE_NODEF(Hull)
|
||||
RDAT_ENUM_VALUE_NODEF(Domain)
|
||||
RDAT_ENUM_VALUE_NODEF(Compute)
|
||||
RDAT_ENUM_VALUE_NODEF(Library)
|
||||
RDAT_ENUM_VALUE_NODEF(RayGeneration)
|
||||
RDAT_ENUM_VALUE_NODEF(Intersection)
|
||||
RDAT_ENUM_VALUE_NODEF(AnyHit)
|
||||
RDAT_ENUM_VALUE_NODEF(ClosestHit)
|
||||
RDAT_ENUM_VALUE_NODEF(Miss)
|
||||
RDAT_ENUM_VALUE_NODEF(Callable)
|
||||
RDAT_ENUM_VALUE_NODEF(Mesh)
|
||||
RDAT_ENUM_VALUE_NODEF(Amplification)
|
||||
RDAT_ENUM_VALUE_NODEF(Invalid)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::ShaderKind::Invalid == 15, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::SemanticKind, uint32_t)
|
||||
/* <py::lines('SemanticKind-ENUM')>hctdb_instrhelp.get_rdat_enum_decl("SemanticKind", nodef=True)</py>*/
|
||||
// SemanticKind-ENUM:BEGIN
|
||||
RDAT_ENUM_VALUE_NODEF(Arbitrary)
|
||||
RDAT_ENUM_VALUE_NODEF(VertexID)
|
||||
RDAT_ENUM_VALUE_NODEF(InstanceID)
|
||||
RDAT_ENUM_VALUE_NODEF(Position)
|
||||
RDAT_ENUM_VALUE_NODEF(RenderTargetArrayIndex)
|
||||
RDAT_ENUM_VALUE_NODEF(ViewPortArrayIndex)
|
||||
RDAT_ENUM_VALUE_NODEF(ClipDistance)
|
||||
RDAT_ENUM_VALUE_NODEF(CullDistance)
|
||||
RDAT_ENUM_VALUE_NODEF(OutputControlPointID)
|
||||
RDAT_ENUM_VALUE_NODEF(DomainLocation)
|
||||
RDAT_ENUM_VALUE_NODEF(PrimitiveID)
|
||||
RDAT_ENUM_VALUE_NODEF(GSInstanceID)
|
||||
RDAT_ENUM_VALUE_NODEF(SampleIndex)
|
||||
RDAT_ENUM_VALUE_NODEF(IsFrontFace)
|
||||
RDAT_ENUM_VALUE_NODEF(Coverage)
|
||||
RDAT_ENUM_VALUE_NODEF(InnerCoverage)
|
||||
RDAT_ENUM_VALUE_NODEF(Target)
|
||||
RDAT_ENUM_VALUE_NODEF(Depth)
|
||||
RDAT_ENUM_VALUE_NODEF(DepthLessEqual)
|
||||
RDAT_ENUM_VALUE_NODEF(DepthGreaterEqual)
|
||||
RDAT_ENUM_VALUE_NODEF(StencilRef)
|
||||
RDAT_ENUM_VALUE_NODEF(DispatchThreadID)
|
||||
RDAT_ENUM_VALUE_NODEF(GroupID)
|
||||
RDAT_ENUM_VALUE_NODEF(GroupIndex)
|
||||
RDAT_ENUM_VALUE_NODEF(GroupThreadID)
|
||||
RDAT_ENUM_VALUE_NODEF(TessFactor)
|
||||
RDAT_ENUM_VALUE_NODEF(InsideTessFactor)
|
||||
RDAT_ENUM_VALUE_NODEF(ViewID)
|
||||
RDAT_ENUM_VALUE_NODEF(Barycentrics)
|
||||
RDAT_ENUM_VALUE_NODEF(ShadingRate)
|
||||
RDAT_ENUM_VALUE_NODEF(CullPrimitive)
|
||||
RDAT_ENUM_VALUE_NODEF(Invalid)
|
||||
// SemanticKind-ENUM:END
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::ComponentType, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(Invalid)
|
||||
RDAT_ENUM_VALUE_NODEF(I1)
|
||||
RDAT_ENUM_VALUE_NODEF(I16)
|
||||
RDAT_ENUM_VALUE_NODEF(U16)
|
||||
RDAT_ENUM_VALUE_NODEF(I32)
|
||||
RDAT_ENUM_VALUE_NODEF(U32)
|
||||
RDAT_ENUM_VALUE_NODEF(I64)
|
||||
RDAT_ENUM_VALUE_NODEF(U64)
|
||||
RDAT_ENUM_VALUE_NODEF(F16)
|
||||
RDAT_ENUM_VALUE_NODEF(F32)
|
||||
RDAT_ENUM_VALUE_NODEF(F64)
|
||||
RDAT_ENUM_VALUE_NODEF(SNormF16)
|
||||
RDAT_ENUM_VALUE_NODEF(UNormF16)
|
||||
RDAT_ENUM_VALUE_NODEF(SNormF32)
|
||||
RDAT_ENUM_VALUE_NODEF(UNormF32)
|
||||
RDAT_ENUM_VALUE_NODEF(SNormF64)
|
||||
RDAT_ENUM_VALUE_NODEF(UNormF64)
|
||||
RDAT_ENUM_VALUE_NODEF(PackedS8x32)
|
||||
RDAT_ENUM_VALUE_NODEF(PackedU8x32)
|
||||
RDAT_ENUM_VALUE_NODEF(LastEntry)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::ComponentType::LastEntry == 19, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::InterpolationMode, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(Undefined)
|
||||
RDAT_ENUM_VALUE_NODEF(Constant)
|
||||
RDAT_ENUM_VALUE_NODEF(Linear)
|
||||
RDAT_ENUM_VALUE_NODEF(LinearCentroid)
|
||||
RDAT_ENUM_VALUE_NODEF(LinearNoperspective)
|
||||
RDAT_ENUM_VALUE_NODEF(LinearNoperspectiveCentroid)
|
||||
RDAT_ENUM_VALUE_NODEF(LinearSample)
|
||||
RDAT_ENUM_VALUE_NODEF(LinearNoperspectiveSample)
|
||||
RDAT_ENUM_VALUE_NODEF(Invalid)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::InterpolationMode::Invalid == 8, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
#endif // DEF_DXIL_ENUMS
|
||||
|
||||
#ifdef DEF_RDAT_TYPES
|
||||
|
||||
#define RECORD_TYPE RuntimeDataResourceInfo
|
||||
RDAT_STRUCT_TABLE(RuntimeDataResourceInfo, ResourceTable)
|
||||
RDAT_ENUM(uint32_t, hlsl::DXIL::ResourceClass, Class)
|
||||
RDAT_ENUM(uint32_t, hlsl::DXIL::ResourceKind, Kind)
|
||||
RDAT_VALUE(uint32_t, ID)
|
||||
RDAT_VALUE(uint32_t, Space)
|
||||
RDAT_VALUE(uint32_t, LowerBound)
|
||||
RDAT_VALUE(uint32_t, UpperBound)
|
||||
RDAT_STRING(Name)
|
||||
RDAT_FLAGS(uint32_t, DxilResourceFlag, Flags)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE RuntimeDataFunctionInfo
|
||||
RDAT_STRUCT_TABLE(RuntimeDataFunctionInfo, FunctionTable)
|
||||
// full function name
|
||||
RDAT_STRING(Name)
|
||||
// unmangled function name
|
||||
RDAT_STRING(UnmangledName)
|
||||
// list of global resources used by this function
|
||||
RDAT_RECORD_ARRAY_REF(RuntimeDataResourceInfo, Resources)
|
||||
// list of external function names this function calls
|
||||
RDAT_STRING_ARRAY_REF(FunctionDependencies)
|
||||
// Shader type, or library function
|
||||
RDAT_ENUM(uint32_t, hlsl::DXIL::ShaderKind, ShaderKind)
|
||||
// Payload Size:
|
||||
// 1) any/closest hit or miss shader: payload size
|
||||
// 2) call shader: parameter size
|
||||
RDAT_VALUE(uint32_t, PayloadSizeInBytes)
|
||||
// attribute size for closest hit and any hit
|
||||
RDAT_VALUE(uint32_t, AttributeSizeInBytes)
|
||||
// first 32 bits of feature flag
|
||||
RDAT_VALUE(uint32_t, FeatureInfo1)
|
||||
// second 32 bits of feature flag
|
||||
RDAT_VALUE(uint32_t, FeatureInfo2)
|
||||
// valid shader stage flag.
|
||||
RDAT_VALUE(uint32_t, ShaderStageFlag)
|
||||
// minimum shader target.
|
||||
RDAT_VALUE(uint32_t, MinShaderTarget)
|
||||
|
||||
#if DEF_RDAT_TYPES == DEF_RDAT_TYPES_USE_HELPERS
|
||||
// void SetFeatureFlags(uint64_t flags) convenience method
|
||||
void SetFeatureFlags(uint64_t flags) {
|
||||
FeatureInfo1 = flags & 0xffffffff;
|
||||
FeatureInfo2 = (flags >> 32) & 0xffffffff;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEF_RDAT_TYPES == DEF_RDAT_READER_DECL
|
||||
// uint64_t GetFeatureFlags() convenience method
|
||||
uint64_t GetFeatureFlags();
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_READER_IMPL
|
||||
// uint64_t GetFeatureFlags() convenience method
|
||||
uint64_t RuntimeDataFunctionInfo_Reader::GetFeatureFlags() {
|
||||
return asRecord() ? (((uint64_t)asRecord()->FeatureInfo2 << 32) |
|
||||
(uint64_t)asRecord()->FeatureInfo1)
|
||||
: 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#endif // DEF_RDAT_TYPES
|
|
@ -0,0 +1,392 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// RDAT_Macros.inl //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Defines macros use to define types Dxil Library Runtime Data (RDAT). //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Pay attention to alignment when organizing structures.
|
||||
// RDAT_STRING and *_REF types are always 4 bytes.
|
||||
// RDAT_BYTES is 2 * 4 bytes.
|
||||
|
||||
// These are the modes set to DEF_RDAT_TYPES and/or DEF_RDAT_ENUMS that drive
|
||||
// macro expansion for types and enums which define the necessary declarations
|
||||
// and code.
|
||||
// While some of associated macros sets are not defined in this file, these
|
||||
// definitions allow custom paths in the type definition files in certain cases.
|
||||
#define DEF_RDAT_DEFAULTS 1 // DEF_RDAT_TYPES and DEF_RDAT_ENUMS - define empty macros for anything not already defined
|
||||
#define DEF_RDAT_TYPES_BASIC_STRUCT 2 // DEF_RDAT_TYPES - define structs with basic types, matching RDAT format
|
||||
#define DEF_RDAT_TYPES_USE_HELPERS 3 // DEF_RDAT_TYPES - define structs using helpers, matching RDAT format
|
||||
#define DEF_RDAT_DUMP_DECL 4 // DEF_RDAT_TYPES and DEF_RDAT_ENUMS - write dump declarations
|
||||
#define DEF_RDAT_DUMP_IMPL 5 // DEF_RDAT_TYPES and DEF_RDAT_ENUMS - write dump implementation
|
||||
#define DEF_RDAT_TYPES_USE_POINTERS 6 // DEF_RDAT_TYPES - define deserialized version using pointers instead of offsets
|
||||
#define DEF_RDAT_ENUM_CLASS 7 // DEF_RDAT_ENUMS - declare enums with enum class
|
||||
#define DEF_RDAT_TRAITS 8 // DEF_RDAT_TYPES - define type traits
|
||||
#define DEF_RDAT_TYPES_FORWARD_DECL 9 // DEF_RDAT_TYPES - forward declare type struct/class
|
||||
#define DEF_RDAT_READER_DECL 10 // DEF_RDAT_TYPES and DEF_RDAT_ENUMS - write reader classes
|
||||
#define DEF_RDAT_READER_IMPL 11 // DEF_RDAT_TYPES and DEF_RDAT_ENUMS - write reader classes
|
||||
#define DEF_RDAT_STRUCT_VALIDATION 13 // DEF_RDAT_TYPES and DEF_RDAT_ENUMS - define structural validation
|
||||
// PRERELEASE-TODO: deeper validation for DxilValidation (limiting enum values and other such things)
|
||||
|
||||
#define GLUE2(a, b) a##b
|
||||
#define GLUE(a, b) GLUE2(a, b)
|
||||
|
||||
#ifdef DEF_RDAT_TYPES
|
||||
|
||||
#if DEF_RDAT_TYPES == DEF_RDAT_TYPES_FORWARD_DECL
|
||||
|
||||
#define RDAT_STRUCT(type) struct type; class type##_Reader;
|
||||
#define RDAT_STRUCT_DERIVED(type, base) RDAT_STRUCT(type)
|
||||
#define RDAT_WRAP_ARRAY(type, count, type_name) struct type_name { type arr[count]; };
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_TYPES_BASIC_STRUCT
|
||||
|
||||
#define RDAT_STRUCT(type) struct type {
|
||||
#define RDAT_STRUCT_DERIVED(type, base) \
|
||||
struct type : public base {
|
||||
#define RDAT_STRUCT_END() };
|
||||
#define RDAT_UNION() union {
|
||||
#define RDAT_UNION_END() };
|
||||
#define RDAT_RECORD_REF(type, name) uint32_t name;
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) uint32_t name;
|
||||
#define RDAT_RECORD_VALUE(type, name) type name;
|
||||
#define RDAT_STRING(name) uint32_t name;
|
||||
#define RDAT_STRING_ARRAY_REF(name) uint32_t name;
|
||||
#define RDAT_VALUE(type, name) type name;
|
||||
#define RDAT_INDEX_ARRAY_REF(name) uint32_t name;
|
||||
#define RDAT_ENUM(sTy, eTy, name) sTy name;
|
||||
#define RDAT_FLAGS(sTy, eTy, name) sTy name;
|
||||
#define RDAT_BYTES(name) uint32_t name; uint32_t name##_Size; name;
|
||||
#define RDAT_ARRAY_VALUE(type, count, type_name, name) type_name name;
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_TYPES_USE_HELPERS
|
||||
|
||||
#define RDAT_STRUCT(type) struct type {
|
||||
#define RDAT_STRUCT_DERIVED(type, base) struct type : public base {
|
||||
#define RDAT_STRUCT_END() };
|
||||
#define RDAT_UNION() union {
|
||||
#define RDAT_UNION_END() };
|
||||
#define RDAT_RECORD_REF(type, name) RecordRef<type> name;
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) RecordArrayRef<type> name;
|
||||
#define RDAT_RECORD_VALUE(type, name) type name;
|
||||
#define RDAT_STRING(name) RDATString name;
|
||||
#define RDAT_STRING_ARRAY_REF(name) RDATStringArray name;
|
||||
#define RDAT_VALUE(type, name) type name;
|
||||
#define RDAT_INDEX_ARRAY_REF(name) IndexArrayRef name;
|
||||
#define RDAT_ENUM(sTy, eTy, name) sTy name;
|
||||
#define RDAT_FLAGS(sTy, eTy, name) sTy name;
|
||||
#define RDAT_BYTES(name) hlsl::RDAT::BytesRef name;
|
||||
#define RDAT_ARRAY_VALUE(type, count, type_name, name) type_name name;
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_READER_DECL
|
||||
|
||||
#define RDAT_STRUCT(type) \
|
||||
class type##_Reader : public RecordReader<type##_Reader> { \
|
||||
public: \
|
||||
typedef type RecordType; \
|
||||
type##_Reader(const BaseRecordReader &reader); \
|
||||
type##_Reader() : RecordReader<type##_Reader>() {} \
|
||||
const RecordType *asRecord() const; \
|
||||
const RecordType *operator->() const { return asRecord(); }
|
||||
#define RDAT_STRUCT_DERIVED(type, base) \
|
||||
class type##_Reader : public base##_Reader { \
|
||||
public: \
|
||||
typedef type RecordType; \
|
||||
type##_Reader(const BaseRecordReader &reader); \
|
||||
type##_Reader(); \
|
||||
const RecordType *asRecord() const; \
|
||||
const RecordType *operator->() const { return asRecord(); }
|
||||
#define RDAT_STRUCT_END() };
|
||||
#define RDAT_UNION_IF(name, expr) bool has##name() const;
|
||||
#define RDAT_UNION_ELIF(name, expr) RDAT_UNION_IF(name, expr)
|
||||
#define RDAT_RECORD_REF(type, name) type##_Reader get##name() const;
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) RecordArrayReader<type##_Reader> get##name() const;
|
||||
#define RDAT_RECORD_VALUE(type, name) type##_Reader get##name() const;
|
||||
#define RDAT_STRING(name) const char *get##name() const;
|
||||
#define RDAT_STRING_ARRAY_REF(name) StringArrayReader get##name() const;
|
||||
#define RDAT_VALUE(type, name) type get##name() const;
|
||||
#define RDAT_INDEX_ARRAY_REF(name) IndexTableReader::IndexRow get##name() const;
|
||||
#define RDAT_ENUM(sTy, eTy, name) eTy get##name() const;
|
||||
#define RDAT_FLAGS(sTy, eTy, name) sTy get##name() const;
|
||||
#define RDAT_BYTES(name) const void *get##name() const; \
|
||||
uint32_t size##name() const;
|
||||
#define RDAT_ARRAY_VALUE(type, count, type_name, name) type_name get##name() const;
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_READER_IMPL
|
||||
|
||||
#define RDAT_STRUCT(type) \
|
||||
type##_Reader::type##_Reader(const BaseRecordReader &reader) : RecordReader<type##_Reader>(reader) {} \
|
||||
const type *type##_Reader::asRecord() const { return BaseRecordReader::asRecord<type>(); }
|
||||
#define RDAT_STRUCT_DERIVED(type, base) \
|
||||
type##_Reader::type##_Reader(const BaseRecordReader &reader) : base##_Reader(reader) { \
|
||||
if ((m_pContext || m_pRecord) && m_Size < sizeof(type)) \
|
||||
InvalidateReader(); \
|
||||
} \
|
||||
type##_Reader::type##_Reader() : base##_Reader() {} \
|
||||
const type *type##_Reader::asRecord() const { return BaseRecordReader::asRecord<type>(); }
|
||||
#define RDAT_STRUCT_TABLE(type, table) RDAT_STRUCT(type)
|
||||
#define RDAT_STRUCT_TABLE_DERIVED(type, base, table) RDAT_STRUCT_DERIVED(type, base)
|
||||
#define RDAT_UNION_IF(name, expr) bool GLUE(RECORD_TYPE,_Reader)::has##name() const { if (auto *pRecord = asRecord()) return !!(expr); return false; }
|
||||
#define RDAT_UNION_ELIF(name, expr) RDAT_UNION_IF(name, expr)
|
||||
#define RDAT_RECORD_REF(type, name) type##_Reader GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_RecordRef<type##_Reader> (&(asRecord()->name)); }
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) \
|
||||
RecordArrayReader<type##_Reader> GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_RecordArrayRef<type##_Reader> (&(asRecord()->name)); }
|
||||
#define RDAT_RECORD_VALUE(type, name) type##_Reader GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_RecordValue<type##_Reader> (&(asRecord()->name)); }
|
||||
#define RDAT_STRING(name) const char *GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_String (&(asRecord()->name)); }
|
||||
#define RDAT_STRING_ARRAY_REF(name) StringArrayReader GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_StringArray (&(asRecord()->name)); }
|
||||
#define RDAT_VALUE(type, name) type GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_Value<type, type> (&(asRecord()->name)); }
|
||||
#define RDAT_INDEX_ARRAY_REF(name) IndexTableReader::IndexRow GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_IndexArray (&(asRecord()->name)); }
|
||||
#define RDAT_ENUM(sTy, eTy, name) eTy GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_Value<eTy, sTy> (&(asRecord()->name)); }
|
||||
#define RDAT_FLAGS(sTy, eTy, name) sTy GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_Value<sTy, sTy> (&(asRecord()->name)); }
|
||||
#define RDAT_BYTES(name) const void *GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_Bytes (&(asRecord()->name)); } \
|
||||
uint32_t GLUE(RECORD_TYPE,_Reader)::size##name() const { return GetField_BytesSize (&(asRecord()->name)); }
|
||||
#define RDAT_ARRAY_VALUE(type, count, type_name, name) \
|
||||
type_name GLUE(RECORD_TYPE,_Reader)::get##name() const { return GetField_Value<type_name, type_name> (&(asRecord()->name)); }
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_STRUCT_VALIDATION
|
||||
|
||||
#define RDAT_STRUCT(type) \
|
||||
template<> bool ValidateRecord<type>(const RDATContext &ctx, const type *pRecord) { \
|
||||
type##_Reader reader(BaseRecordReader(&ctx, (void*)pRecord, (uint32_t)RecordTraits<type>::RecordSize()));
|
||||
#define RDAT_STRUCT_DERIVED(type, base) RDAT_STRUCT(type)
|
||||
#define RDAT_STRUCT_END() return true; }
|
||||
#define RDAT_UNION_IF(name, expr) if (reader.has##name()) {
|
||||
#define RDAT_UNION_ELIF(name, expr) } else if (reader.has##name()) {
|
||||
#define RDAT_UNION_ENDIF() }
|
||||
#define RDAT_RECORD_REF(type, name) if (!ValidateRecordRef<type>(ctx, pRecord->name)) return false;
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) if (!ValidateRecordArrayRef<type>(ctx, pRecord->name)) return false;
|
||||
#define RDAT_RECORD_VALUE(type, name) if (!ValidateRecord<type>(ctx, &pRecord->name)) return false;
|
||||
#define RDAT_STRING(name) if (!ValidateStringRef(ctx, pRecord->name)) return false;
|
||||
#define RDAT_STRING_ARRAY_REF(name) if (!ValidateStringArrayRef(ctx, pRecord->name)) return false;
|
||||
#define RDAT_INDEX_ARRAY_REF(name) if (!ValidateIndexArrayRef(ctx, pRecord->name)) return false;
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_DUMP_IMPL
|
||||
|
||||
#define RDAT_STRUCT(type) \
|
||||
template <> \
|
||||
void RecordDumper<hlsl::RDAT::type>::Dump( \
|
||||
const hlsl::RDAT::RDATContext &ctx, DumpContext &d) const { \
|
||||
d.Indent(); \
|
||||
const hlsl::RDAT::type *pRecord = this; \
|
||||
type##_Reader reader(BaseRecordReader( \
|
||||
&ctx, (void *)pRecord, (uint32_t)RecordTraits<type>::RecordSize()));
|
||||
#define RDAT_STRUCT_DERIVED(type, base) \
|
||||
const char *RecordRefDumper<hlsl::RDAT::base>::TypeNameDerived( \
|
||||
const hlsl::RDAT::RDATContext &ctx) const { \
|
||||
return TypeName<hlsl::RDAT::type>(ctx); \
|
||||
} \
|
||||
void RecordRefDumper<hlsl::RDAT::base>::DumpDerived( \
|
||||
const hlsl::RDAT::RDATContext &ctx, DumpContext &d) const { \
|
||||
Dump<hlsl::RDAT::type>(ctx, d); \
|
||||
} \
|
||||
template <> \
|
||||
void DumpWithBase<hlsl::RDAT::type>(const hlsl::RDAT::RDATContext &ctx, \
|
||||
DumpContext &d, \
|
||||
const hlsl::RDAT::type *pRecord) { \
|
||||
DumpWithBase<hlsl::RDAT::base>(ctx, d, pRecord); \
|
||||
static_cast<const RecordDumper<hlsl::RDAT::type> *>(pRecord)->Dump(ctx, \
|
||||
d); \
|
||||
} \
|
||||
RDAT_STRUCT(type)
|
||||
#define RDAT_STRUCT_END() d.Dedent(); }
|
||||
#define RDAT_UNION_IF(name, expr) if (reader.has##name()) {
|
||||
#define RDAT_UNION_ELIF(name, expr) } else if (reader.has##name()) {
|
||||
#define RDAT_UNION_ENDIF() }
|
||||
#define RDAT_RECORD_REF(type, name) DumpRecordRef(ctx, d, #type, #name, name);
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) DumpRecordArrayRef(ctx, d, #type, #name, name);
|
||||
#define RDAT_RECORD_VALUE(type, name) DumpRecordValue(ctx, d, #type, #name, &name);
|
||||
#define RDAT_STRING(name) d.WriteLn(#name ": ", QuotedStringValue(name.Get(ctx)));
|
||||
#define RDAT_STRING_ARRAY_REF(name) DumpStringArray(ctx, d, #name, name);
|
||||
#define RDAT_VALUE(type, name) d.WriteLn(#name ": ", name);
|
||||
#define RDAT_INDEX_ARRAY_REF(name) DumpIndexArray(ctx, d, #name, name);
|
||||
#define RDAT_ENUM(sTy, eTy, name) d.DumpEnum<eTy>(#name, (eTy)name);
|
||||
#define RDAT_FLAGS(sTy, eTy, name) d.DumpFlags<eTy, sTy>(#name, name);
|
||||
#define RDAT_BYTES(name) DumpBytesRef(ctx, d, #name, name);
|
||||
#define RDAT_ARRAY_VALUE(type, count, type_name, name) DumpValueArray<type>(d, #name, #type, &name, count);
|
||||
|
||||
#elif DEF_RDAT_TYPES == DEF_RDAT_TRAITS
|
||||
|
||||
#define RDAT_STRUCT(type) \
|
||||
template<> constexpr const char *RecordTraits<type>::TypeName() { return #type; }
|
||||
#define RDAT_STRUCT_DERIVED(type, base) RDAT_STRUCT(type)
|
||||
#define RDAT_STRUCT_TABLE(type, table) \
|
||||
RDAT_STRUCT(type) \
|
||||
template<> constexpr RecordTableIndex RecordTraits<type>::TableIndex() { return RecordTableIndex::table; }
|
||||
#define RDAT_STRUCT_TABLE_DERIVED(type, base, table) \
|
||||
RDAT_STRUCT_DERIVED(type, base) \
|
||||
template<> constexpr RecordTableIndex RecordTraits<type>::TableIndex() { return RecordTableIndex::table; }
|
||||
|
||||
#endif // DEF_RDAT_TYPES cases
|
||||
|
||||
// Define any undefined macros to defaults
|
||||
#ifndef RDAT_STRUCT
|
||||
#define RDAT_STRUCT(type)
|
||||
#endif
|
||||
#ifndef RDAT_STRUCT_DERIVED
|
||||
#define RDAT_STRUCT_DERIVED(type, base)
|
||||
#endif
|
||||
#ifndef RDAT_STRUCT_TABLE
|
||||
#define RDAT_STRUCT_TABLE(type, table) RDAT_STRUCT(type)
|
||||
#endif
|
||||
#ifndef RDAT_STRUCT_TABLE_DERIVED
|
||||
#define RDAT_STRUCT_TABLE_DERIVED(type, base, table) RDAT_STRUCT_DERIVED(type, base)
|
||||
#endif
|
||||
#ifndef RDAT_STRUCT_END
|
||||
#define RDAT_STRUCT_END()
|
||||
#endif
|
||||
#ifndef RDAT_UNION
|
||||
#define RDAT_UNION()
|
||||
#endif
|
||||
#ifndef RDAT_UNION_IF
|
||||
#define RDAT_UNION_IF(name, expr) // In expr: 'this' is reader; pRecord is record struct
|
||||
#endif
|
||||
#ifndef RDAT_UNION_ELIF
|
||||
#define RDAT_UNION_ELIF(name, expr) // In expr: 'this' is reader; pRecord is record struct
|
||||
#endif
|
||||
#ifndef RDAT_UNION_ENDIF
|
||||
#define RDAT_UNION_ENDIF()
|
||||
#endif
|
||||
#ifndef RDAT_UNION_END
|
||||
#define RDAT_UNION_END()
|
||||
#endif
|
||||
#ifndef RDAT_RECORD_REF
|
||||
#define RDAT_RECORD_REF(type, name) // always use base record type in RDAT_RECORD_REF
|
||||
#endif
|
||||
#ifndef RDAT_RECORD_ARRAY_REF
|
||||
#define RDAT_RECORD_ARRAY_REF(type, name) // always use base record type in RDAT_RECORD_ARRAY_REF
|
||||
#endif
|
||||
#ifndef RDAT_RECORD_VALUE
|
||||
#define RDAT_RECORD_VALUE(type, name)
|
||||
#endif
|
||||
#ifndef RDAT_STRING
|
||||
#define RDAT_STRING(name)
|
||||
#endif
|
||||
#ifndef RDAT_STRING_ARRAY_REF
|
||||
#define RDAT_STRING_ARRAY_REF(name)
|
||||
#endif
|
||||
#ifndef RDAT_VALUE
|
||||
#define RDAT_VALUE(type, name)
|
||||
#endif
|
||||
#ifndef RDAT_INDEX_ARRAY_REF
|
||||
#define RDAT_INDEX_ARRAY_REF(name) // ref to array of uint32_t values
|
||||
#endif
|
||||
#ifndef RDAT_ENUM
|
||||
#define RDAT_ENUM(sTy, eTy, name)
|
||||
#endif
|
||||
#ifndef RDAT_FLAGS
|
||||
#define RDAT_FLAGS(sTy, eTy, name)
|
||||
#endif
|
||||
#ifndef RDAT_BYTES
|
||||
#define RDAT_BYTES(name)
|
||||
#endif
|
||||
#ifndef RDAT_WRAP_ARRAY
|
||||
#define RDAT_WRAP_ARRAY(type, count, type_name) // define struct-wrapped array type here
|
||||
#endif
|
||||
#ifndef RDAT_ARRAY_VALUE
|
||||
#define RDAT_ARRAY_VALUE(type, count, type_name, name) // define struct-wrapped array member
|
||||
#endif
|
||||
|
||||
#endif // DEF_RDAT_TYPES defined
|
||||
|
||||
|
||||
#if defined(DEF_RDAT_ENUMS) || defined(DEF_DXIL_ENUMS)
|
||||
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_ENUM_CLASS
|
||||
|
||||
#define RDAT_ENUM_START(eTy, sTy) enum class eTy : sTy {
|
||||
// No RDAT_DXIL_ENUM_START, DXIL enums are defined elsewhere
|
||||
#define RDAT_ENUM_VALUE(name, value) name = value,
|
||||
#define RDAT_ENUM_VALUE_ALIAS(name, value) name = value,
|
||||
#define RDAT_ENUM_VALUE_NODEF(name) name,
|
||||
#define RDAT_ENUM_END() };
|
||||
|
||||
#elif DEF_RDAT_ENUMS == DEF_RDAT_DUMP_DECL
|
||||
|
||||
#define RDAT_ENUM_START(eTy, sTy) const char *ToString(eTy e);
|
||||
#define RDAT_DXIL_ENUM_START(eTy, sTy) const char *ToString(eTy e);
|
||||
|
||||
#elif DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
|
||||
//#define RDAT_ENUM_START(eTy, sTy) \
|
||||
// const char *ToString(eTy e) { \
|
||||
// switch((sTy)e) {
|
||||
//#define RDAT_ENUM_VALUE(name, value) case value: return #name;
|
||||
#define RDAT_ENUM_START(eTy, sTy) \
|
||||
const char *ToString(eTy e) { \
|
||||
typedef eTy thisEnumTy; \
|
||||
switch(e) {
|
||||
#define RDAT_DXIL_ENUM_START(eTy, sTy) \
|
||||
const char *ToString(eTy e) { \
|
||||
typedef eTy thisEnumTy; \
|
||||
switch(e) {
|
||||
#define RDAT_ENUM_VALUE_NODEF(name) case thisEnumTy::name: return #name;
|
||||
#define RDAT_ENUM_VALUE(name, value) RDAT_ENUM_VALUE_NODEF(name)
|
||||
#define RDAT_ENUM_END() \
|
||||
default: return nullptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif // DEF_RDAT_ENUMS cases
|
||||
|
||||
// Define any undefined macros to defaults
|
||||
#ifndef RDAT_ENUM_START
|
||||
#define RDAT_ENUM_START(eTy, sTy)
|
||||
#endif
|
||||
#ifndef RDAT_DXIL_ENUM_START
|
||||
#define RDAT_DXIL_ENUM_START(eTy, sTy)
|
||||
#endif
|
||||
#ifndef RDAT_ENUM_VALUE
|
||||
#define RDAT_ENUM_VALUE(name, value) // value only used during declaration
|
||||
#endif
|
||||
#ifndef RDAT_ENUM_VALUE_ALIAS
|
||||
#define RDAT_ENUM_VALUE_ALIAS(name, value) // secondary enum names that alias to the same value as another name in the enum
|
||||
#endif
|
||||
#ifndef RDAT_ENUM_VALUE_NODEF
|
||||
#define RDAT_ENUM_VALUE_NODEF(name) // enum names that have no explicitly defined value, or are defined elsewhere
|
||||
#endif
|
||||
#ifndef RDAT_ENUM_END
|
||||
#define RDAT_ENUM_END()
|
||||
#endif
|
||||
|
||||
#endif // DEF_RDAT_ENUMS or DEF_DXIL_ENUMS defined
|
||||
|
||||
#include "RDAT_SubobjectTypes.inl"
|
||||
#include "RDAT_LibraryTypes.inl"
|
||||
|
||||
#undef DEF_RDAT_TYPES
|
||||
#undef DEF_RDAT_ENUMS
|
||||
#undef DEF_DXIL_ENUMS
|
||||
|
||||
#undef RDAT_STRUCT
|
||||
#undef RDAT_STRUCT_DERIVED
|
||||
#undef RDAT_STRUCT_TABLE
|
||||
#undef RDAT_STRUCT_TABLE_DERIVED
|
||||
#undef RDAT_STRUCT_END
|
||||
#undef RDAT_UNION
|
||||
#undef RDAT_UNION_IF
|
||||
#undef RDAT_UNION_ELIF
|
||||
#undef RDAT_UNION_ENDIF
|
||||
#undef RDAT_UNION_END
|
||||
#undef RDAT_RECORD_REF
|
||||
#undef RDAT_RECORD_ARRAY_REF
|
||||
#undef RDAT_RECORD_VALUE
|
||||
#undef RDAT_STRING
|
||||
#undef RDAT_STRING_ARRAY_REF
|
||||
#undef RDAT_VALUE
|
||||
#undef RDAT_INDEX_ARRAY_REF
|
||||
#undef RDAT_ENUM
|
||||
#undef RDAT_FLAGS
|
||||
#undef RDAT_BYTES
|
||||
#undef RDAT_WRAP_ARRAY
|
||||
#undef RDAT_ARRAY_VALUE
|
||||
|
||||
#undef RDAT_ENUM_START
|
||||
#undef RDAT_DXIL_ENUM_START
|
||||
#undef RDAT_ENUM_VALUE
|
||||
#undef RDAT_ENUM_VALUE_ALIAS
|
||||
#undef RDAT_ENUM_VALUE_NODEF
|
||||
#undef RDAT_ENUM_END
|
|
@ -0,0 +1,151 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// RDAT_SubobjectTypes.inl //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Defines types used in Dxil Library Runtime Data (RDAT). //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef DEF_RDAT_ENUMS
|
||||
|
||||
// Nothing yet
|
||||
|
||||
#endif // DEF_RDAT_ENUMS
|
||||
|
||||
#ifdef DEF_DXIL_ENUMS
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::SubobjectKind, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(StateObjectConfig)
|
||||
RDAT_ENUM_VALUE_NODEF(GlobalRootSignature)
|
||||
RDAT_ENUM_VALUE_NODEF(LocalRootSignature)
|
||||
RDAT_ENUM_VALUE_NODEF(SubobjectToExportsAssociation)
|
||||
RDAT_ENUM_VALUE_NODEF(RaytracingShaderConfig)
|
||||
RDAT_ENUM_VALUE_NODEF(RaytracingPipelineConfig)
|
||||
RDAT_ENUM_VALUE_NODEF(HitGroup)
|
||||
RDAT_ENUM_VALUE_NODEF(RaytracingPipelineConfig1)
|
||||
// No need to define this here
|
||||
//RDAT_ENUM_VALUE_NODEF(NumKinds)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::SubobjectKind::NumKinds == 13, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::StateObjectFlags, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(AllowLocalDependenciesOnExternalDefinitions)
|
||||
RDAT_ENUM_VALUE_NODEF(AllowExternalDependenciesOnLocalDefinitions)
|
||||
RDAT_ENUM_VALUE_NODEF(AllowStateObjectAdditions)
|
||||
// No need to define these masks here
|
||||
//RDAT_ENUM_VALUE_NODEF(ValidMask_1_4)
|
||||
//RDAT_ENUM_VALUE_NODEF(ValidMask)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::StateObjectFlags::ValidMask == 0x7, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::HitGroupType, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(Triangle)
|
||||
RDAT_ENUM_VALUE_NODEF(ProceduralPrimitive)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::HitGroupType::LastEntry == 2, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
RDAT_DXIL_ENUM_START(hlsl::DXIL::RaytracingPipelineFlags, uint32_t)
|
||||
RDAT_ENUM_VALUE_NODEF(None)
|
||||
RDAT_ENUM_VALUE_NODEF(SkipTriangles)
|
||||
RDAT_ENUM_VALUE_NODEF(SkipProceduralPrimitives)
|
||||
// No need to define mask here
|
||||
//RDAT_ENUM_VALUE_NODEF(ValidMask)
|
||||
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
|
||||
static_assert((unsigned)hlsl::DXIL::RaytracingPipelineFlags::ValidMask == 0x300, "otherwise, RDAT_DXIL_ENUM definition needs updating");
|
||||
#endif
|
||||
RDAT_ENUM_END()
|
||||
|
||||
#endif // DEF_DXIL_ENUMS
|
||||
|
||||
#ifdef DEF_RDAT_TYPES
|
||||
|
||||
#define RECORD_TYPE StateObjectConfig_t
|
||||
RDAT_STRUCT(StateObjectConfig_t)
|
||||
RDAT_FLAGS(uint32_t, hlsl::DXIL::StateObjectFlags, Flags)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE RootSignature_t
|
||||
RDAT_STRUCT(RootSignature_t)
|
||||
RDAT_BYTES(Data)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE SubobjectToExportsAssociation_t
|
||||
RDAT_STRUCT(SubobjectToExportsAssociation_t)
|
||||
RDAT_STRING(Subobject)
|
||||
RDAT_STRING_ARRAY_REF(Exports)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE RaytracingShaderConfig_t
|
||||
RDAT_STRUCT(RaytracingShaderConfig_t)
|
||||
RDAT_VALUE(uint32_t, MaxPayloadSizeInBytes)
|
||||
RDAT_VALUE(uint32_t, MaxAttributeSizeInBytes)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE RaytracingPipelineConfig_t
|
||||
RDAT_STRUCT(RaytracingPipelineConfig_t)
|
||||
RDAT_VALUE(uint32_t, MaxTraceRecursionDepth)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE HitGroup_t
|
||||
RDAT_STRUCT(HitGroup_t)
|
||||
RDAT_ENUM(uint32_t, hlsl::DXIL::HitGroupType, Type)
|
||||
RDAT_STRING(AnyHit)
|
||||
RDAT_STRING(ClosestHit)
|
||||
RDAT_STRING(Intersection)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE RaytracingPipelineConfig1_t
|
||||
RDAT_STRUCT(RaytracingPipelineConfig1_t)
|
||||
RDAT_VALUE(uint32_t, MaxTraceRecursionDepth)
|
||||
RDAT_FLAGS(uint32_t, hlsl::DXIL::RaytracingPipelineFlags, Flags)
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#define RECORD_TYPE RuntimeDataSubobjectInfo
|
||||
RDAT_STRUCT_TABLE(RuntimeDataSubobjectInfo, SubobjectTable)
|
||||
RDAT_ENUM(uint32_t, hlsl::DXIL::SubobjectKind, Kind)
|
||||
RDAT_STRING(Name)
|
||||
RDAT_UNION()
|
||||
RDAT_UNION_IF(StateObjectConfig, ((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::StateObjectConfig))
|
||||
RDAT_RECORD_VALUE(StateObjectConfig_t, StateObjectConfig)
|
||||
RDAT_UNION_ELIF(RootSignature,
|
||||
((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::GlobalRootSignature) ||
|
||||
((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::LocalRootSignature))
|
||||
RDAT_RECORD_VALUE(RootSignature_t, RootSignature)
|
||||
RDAT_UNION_ELIF(SubobjectToExportsAssociation, ((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::SubobjectToExportsAssociation))
|
||||
RDAT_RECORD_VALUE(SubobjectToExportsAssociation_t, SubobjectToExportsAssociation)
|
||||
RDAT_UNION_ELIF(RaytracingShaderConfig, ((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::RaytracingShaderConfig))
|
||||
RDAT_RECORD_VALUE(RaytracingShaderConfig_t, RaytracingShaderConfig)
|
||||
RDAT_UNION_ELIF(RaytracingPipelineConfig, ((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::RaytracingPipelineConfig))
|
||||
RDAT_RECORD_VALUE(RaytracingPipelineConfig_t, RaytracingPipelineConfig)
|
||||
RDAT_UNION_ELIF(HitGroup, ((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::HitGroup))
|
||||
RDAT_RECORD_VALUE(HitGroup_t, HitGroup)
|
||||
RDAT_UNION_ELIF(RaytracingPipelineConfig1, ((uint32_t)pRecord->Kind == (uint32_t)hlsl::DXIL::SubobjectKind::RaytracingPipelineConfig1))
|
||||
RDAT_RECORD_VALUE(RaytracingPipelineConfig1_t, RaytracingPipelineConfig1)
|
||||
RDAT_UNION_ENDIF()
|
||||
RDAT_UNION_END()
|
||||
|
||||
// Note: this is how one could inject custom code into one of the definition modes:
|
||||
#if DEF_RDAT_TYPES == DEF_RDAT_READER
|
||||
// Add custom code here that only gets added to the reader class definition
|
||||
#endif
|
||||
|
||||
RDAT_STRUCT_END()
|
||||
#undef RECORD_TYPE
|
||||
|
||||
#endif // DEF_RDAT_TYPES
|
|
@ -69,7 +69,8 @@ struct HLOptions {
|
|||
unsigned bFXCCompatMode : 1;
|
||||
unsigned bLegacyResourceReservation : 1;
|
||||
unsigned bForceZeroStoreLifetimes : 1;
|
||||
unsigned unused : 20;
|
||||
unsigned bResMayAlias : 1;
|
||||
unsigned unused : 19;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<const llvm::Function *, std::unique_ptr<DxilFunctionProps>> DxilFunctionPropsMap;
|
||||
|
|
|
@ -291,6 +291,11 @@ const unsigned kSampleLLevelArgIndex = 4;
|
|||
const unsigned kSampleLOffsetArgIndex = 5;
|
||||
const unsigned kSampleLStatusArgIndex = 6;
|
||||
|
||||
// SampleCmpLevel
|
||||
// the rest are the same as SampleCmp
|
||||
const unsigned kSampleCmpLLevelArgIndex = 5;
|
||||
const unsigned kSampleCmpLOffsetArgIndex = 6;
|
||||
|
||||
// SampleCmpLevelZero.
|
||||
const unsigned kSampleCmpLZCmpValArgIndex = 4;
|
||||
const unsigned kSampleCmpLZOffsetArgIndex = 5;
|
||||
|
|
|
@ -60,6 +60,8 @@ enum class IntrinsicOp { IOP_AcceptHitAndEndSearch,
|
|||
IOP_ProcessTriTessFactorsAvg,
|
||||
IOP_ProcessTriTessFactorsMax,
|
||||
IOP_ProcessTriTessFactorsMin,
|
||||
IOP_QuadAll,
|
||||
IOP_QuadAny,
|
||||
IOP_QuadReadAcrossDiagonal,
|
||||
IOP_QuadReadAcrossX,
|
||||
IOP_QuadReadAcrossY,
|
||||
|
@ -242,6 +244,7 @@ enum class IntrinsicOp { IOP_AcceptHitAndEndSearch,
|
|||
MOP_Sample,
|
||||
MOP_SampleBias,
|
||||
MOP_SampleCmp,
|
||||
MOP_SampleCmpLevel,
|
||||
MOP_SampleCmpLevelZero,
|
||||
MOP_SampleGrad,
|
||||
MOP_SampleLevel,
|
||||
|
@ -254,6 +257,7 @@ enum class IntrinsicOp { IOP_AcceptHitAndEndSearch,
|
|||
MOP_GatherCmpGreen,
|
||||
MOP_GatherCmpRed,
|
||||
MOP_GatherGreen,
|
||||
MOP_GatherRaw,
|
||||
MOP_GatherRed,
|
||||
MOP_GetSamplePosition,
|
||||
MOP_Load2,
|
||||
|
|
|
@ -12,16 +12,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "dxc/Support/Global.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
#include "DumpContext.h"
|
||||
#include "dxc/Support/WinIncludes.h"
|
||||
#include "dxc/dxcapi.h"
|
||||
#include <d3d12shader.h>
|
||||
#include "dxc/DxilContainer/DxilContainer.h"
|
||||
|
||||
namespace refl_dump {
|
||||
namespace hlsl {
|
||||
namespace dump {
|
||||
|
||||
LPCSTR ToString(D3D_CBUFFER_TYPE CBType);
|
||||
LPCSTR ToString(D3D_SHADER_INPUT_TYPE Type);
|
||||
|
@ -43,121 +39,14 @@ LPCSTR ToString(D3D_REGISTER_COMPONENT_TYPE CompTy);
|
|||
LPCSTR ToString(D3D_MIN_PRECISION MinPrec);
|
||||
LPCSTR CompMaskToString(unsigned CompMask);
|
||||
|
||||
template<typename _T>
|
||||
struct EnumValue {
|
||||
public:
|
||||
EnumValue(const _T &e) : eValue(e) {}
|
||||
_T eValue;
|
||||
};
|
||||
|
||||
template<typename _T, typename _StoreT = uint32_t>
|
||||
struct FlagsValue {
|
||||
public:
|
||||
FlagsValue(const _StoreT &f) : Flags(f) {}
|
||||
_StoreT Flags;
|
||||
};
|
||||
|
||||
template<typename _T>
|
||||
std::ostream& operator<<(std::ostream& out, const EnumValue<_T> &obj) {
|
||||
if (LPCSTR szValue = ToString(obj.eValue))
|
||||
return out << szValue;
|
||||
else
|
||||
return out << "<unknown: " << std::hex << std::showbase << (UINT)obj.eValue << ">";
|
||||
}
|
||||
|
||||
template<typename _T, typename _StoreT>
|
||||
std::ostream& operator<<(std::ostream& out, const FlagsValue<_T, _StoreT> &obj) {
|
||||
_StoreT Flags = obj.Flags;
|
||||
if (!Flags) {
|
||||
LPCSTR szValue = ToString((_T)0);
|
||||
if (szValue)
|
||||
return out << "0 (" << szValue << ")";
|
||||
else
|
||||
return out << "0";
|
||||
}
|
||||
uint32_t flag = 0;
|
||||
out << "(";
|
||||
while (Flags) {
|
||||
if (flag)
|
||||
out << " | ";
|
||||
flag = (Flags & ~(Flags - 1));
|
||||
Flags ^= flag;
|
||||
out << EnumValue<_T>((_T)flag);
|
||||
}
|
||||
out << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
class DumperBase {
|
||||
private:
|
||||
std::ostream &m_out;
|
||||
unsigned m_indent = 0;
|
||||
bool m_bCheckByName = false;
|
||||
std::ostream &DoIndent() {
|
||||
return m_out << std::setfill(' ')
|
||||
<< std::setw(std::min(m_indent * 2, (unsigned)32))
|
||||
<< "";
|
||||
}
|
||||
|
||||
public:
|
||||
DumperBase(std::ostream &outStream) : m_out(outStream) {}
|
||||
|
||||
void Indent() { if (m_indent < (1 << 30)) m_indent++; }
|
||||
void Dedent() { if (m_indent > 0) m_indent--; }
|
||||
|
||||
template<typename _T>
|
||||
std::ostream &Write(std::ostream &out, _T t) {
|
||||
return out << t;
|
||||
}
|
||||
template<typename _T, typename... Args>
|
||||
std::ostream &Write(std::ostream &out, _T t, Args... args) {
|
||||
return Write(out << t, args...);
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
std::ostream &WriteLn(_T t) {
|
||||
return Write(DoIndent(), t) << std::endl
|
||||
<< std::resetiosflags(std::ios_base::basefield | std::ios_base::showbase);
|
||||
}
|
||||
template<typename _T, typename... Args>
|
||||
std::ostream &WriteLn(_T t, Args... args) {
|
||||
return Write(Write(DoIndent(), t), args...) << std::endl
|
||||
<< std::resetiosflags(std::ios_base::basefield | std::ios_base::showbase);
|
||||
}
|
||||
|
||||
template <typename _T>
|
||||
std::ostream &WriteEnumValue(_T eValue) {
|
||||
LPCSTR szValue = ToString(eValue);
|
||||
if (szValue)
|
||||
return Write(szValue);
|
||||
else
|
||||
return Write("<unknown: ", std::hex, std::showbase, (UINT)eValue, ">");
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
void DumpEnum(const char *Name, _T eValue) {
|
||||
WriteLn(Name, ": ", EnumValue<_T>(eValue));
|
||||
}
|
||||
template<typename _T, typename _StoreT = uint32_t>
|
||||
void DumpFlags(const char *Name, _StoreT Flags) {
|
||||
WriteLn(Name, ": ", FlagsValue<_T, _StoreT>(Flags));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Failure(Args... args) {
|
||||
WriteLn("Failed: ", args...);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class D3DReflectionDumper : public DumperBase {
|
||||
class D3DReflectionDumper : public DumpContext {
|
||||
private:
|
||||
bool m_bCheckByName = false;
|
||||
const char *m_LastName = nullptr;
|
||||
void SetLastName(const char *Name = nullptr) { m_LastName = Name ? Name : "<nullptr>"; }
|
||||
|
||||
public:
|
||||
D3DReflectionDumper(std::ostream &outStream) : DumperBase(outStream) {}
|
||||
D3DReflectionDumper(std::ostream &outStream) : DumpContext(outStream) {}
|
||||
void SetCheckByName(bool bCheckByName) { m_bCheckByName = bCheckByName; }
|
||||
|
||||
void DumpShaderVersion(UINT Version);
|
||||
|
@ -183,4 +72,5 @@ public:
|
|||
|
||||
};
|
||||
|
||||
} // namespace refl_dump
|
||||
} // namespace dump
|
||||
} // namespace hlsl
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DumpContext.h //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Context for dumping structured data, enums, and flags for use in tests. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dxc/Support/Global.h"
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace hlsl {
|
||||
namespace dump {
|
||||
|
||||
template<typename _T>
|
||||
struct EnumValue {
|
||||
public:
|
||||
EnumValue(const _T &e) : eValue(e) {}
|
||||
_T eValue;
|
||||
};
|
||||
|
||||
template<typename _T, typename _StoreT = uint32_t>
|
||||
struct FlagsValue {
|
||||
public:
|
||||
FlagsValue(const _StoreT &f) : Flags(f) {}
|
||||
_StoreT Flags;
|
||||
};
|
||||
|
||||
struct QuotedStringValue {
|
||||
public:
|
||||
QuotedStringValue(const char *str) : Str(str) {}
|
||||
const char *Str;
|
||||
};
|
||||
|
||||
class DumpContext {
|
||||
private:
|
||||
std::ostream &m_out;
|
||||
unsigned m_indent = 0;
|
||||
bool m_bCheckByName = false;
|
||||
std::unordered_set<size_t> m_visited;
|
||||
|
||||
std::ostream &DoIndent() {
|
||||
return m_out << std::setfill(' ')
|
||||
<< std::setw((m_indent > 16) ? 32 : m_indent * 2)
|
||||
<< "";
|
||||
}
|
||||
|
||||
public:
|
||||
DumpContext(std::ostream &outStream) : m_out(outStream) {}
|
||||
|
||||
void Indent() { if (m_indent < (1 << 30)) m_indent++; }
|
||||
void Dedent() { if (m_indent > 0) m_indent--; }
|
||||
|
||||
template<typename _T>
|
||||
std::ostream &Write(_T t) {
|
||||
return Write(m_out, t);
|
||||
}
|
||||
template<typename _T, typename... Args>
|
||||
std::ostream &Write(_T t, Args... args) {
|
||||
return Write(Write(m_out, t), args...);
|
||||
}
|
||||
template<typename _T>
|
||||
std::ostream &Write(std::ostream &out, _T t) {
|
||||
return out << t;
|
||||
}
|
||||
template<>
|
||||
std::ostream &Write<uint8_t>(std::ostream &out, uint8_t t) {
|
||||
return out << (unsigned)t;
|
||||
}
|
||||
template<typename _T, typename... Args>
|
||||
std::ostream &Write(std::ostream &out, _T t, Args... args) {
|
||||
return Write(Write(out, t), args...);
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
std::ostream &WriteLn(_T t) {
|
||||
return Write(DoIndent(), t) << std::endl
|
||||
<< std::resetiosflags(std::ios_base::basefield | std::ios_base::showbase);
|
||||
}
|
||||
template<typename _T, typename... Args>
|
||||
std::ostream &WriteLn(_T t, Args... args) {
|
||||
return Write(Write(DoIndent(), t), args...) << std::endl
|
||||
<< std::resetiosflags(std::ios_base::basefield | std::ios_base::showbase);
|
||||
}
|
||||
|
||||
template <typename _T>
|
||||
std::ostream &WriteEnumValue(_T eValue) {
|
||||
const char *szValue = ToString(eValue);
|
||||
if (szValue)
|
||||
return Write(szValue);
|
||||
else
|
||||
return Write("<unknown: ", std::hex, std::showbase, (UINT)eValue, ">");
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
void DumpEnum(const char *Name, _T eValue) {
|
||||
WriteLn(Name, ": ", EnumValue<_T>(eValue));
|
||||
}
|
||||
template<typename _T, typename _StoreT = uint32_t>
|
||||
void DumpFlags(const char *Name, _StoreT Flags) {
|
||||
WriteLn(Name, ": ", FlagsValue<_T, _StoreT>(Flags));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Failure(Args... args) {
|
||||
WriteLn("Failed: ", args...);
|
||||
}
|
||||
|
||||
// Return true if ptr has not yet been visited, prevents recursive dumping
|
||||
bool Visit(size_t value) { return m_visited.insert(value).second; }
|
||||
bool Visit(const void *ptr) { return Visit((size_t)ptr); }
|
||||
void VisitReset() { m_visited.clear(); }
|
||||
};
|
||||
|
||||
// Copied from llvm/ADT/StringExtras.h
|
||||
inline char hexdigit(unsigned X, bool LowerCase = false) {
|
||||
const char HexChar = LowerCase ? 'a' : 'A';
|
||||
return X < 10 ? '0' + X : HexChar + X - 10;
|
||||
}
|
||||
// Copied from lib/IR/AsmWriter.cpp
|
||||
// EscapedString - Print each character of the specified string, escaping
|
||||
// it if it is not printable or if it is an escape char.
|
||||
inline std::string EscapedString(const char *text) {
|
||||
std::ostringstream ss;
|
||||
size_t size = strlen(text);
|
||||
for (unsigned i = 0, e = size; i != e; ++i) {
|
||||
unsigned char C = text[i];
|
||||
if (isprint(C) && C != '\\' && C != '"')
|
||||
ss << C;
|
||||
else
|
||||
ss << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
std::ostream& operator<<(std::ostream& out, const EnumValue<_T> &obj) {
|
||||
if (const char *szValue = ToString(obj.eValue))
|
||||
return out << szValue;
|
||||
else
|
||||
return out << "<unknown: " << std::hex << std::showbase << (UINT)obj.eValue << ">";
|
||||
}
|
||||
|
||||
template<typename _T, typename _StoreT>
|
||||
std::ostream& operator<<(std::ostream& out, const FlagsValue<_T, _StoreT> &obj) {
|
||||
_StoreT Flags = obj.Flags;
|
||||
if (!Flags) {
|
||||
const char *szValue = ToString((_T)0);
|
||||
if (szValue)
|
||||
return out << "0 (" << szValue << ")";
|
||||
else
|
||||
return out << "0";
|
||||
}
|
||||
uint32_t flag = 0;
|
||||
out << "(";
|
||||
while (Flags) {
|
||||
if (flag)
|
||||
out << " | ";
|
||||
flag = (Flags & ~(Flags - 1));
|
||||
Flags ^= flag;
|
||||
out << EnumValue<_T>((_T)flag);
|
||||
}
|
||||
out << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const QuotedStringValue &obj) {
|
||||
if (!obj.Str)
|
||||
return out << "<null string pointer>";
|
||||
return out << "\"" << EscapedString(obj.Str) << "\"";
|
||||
}
|
||||
|
||||
} // namespace dump
|
||||
} // namespace hlsl
|
|
@ -0,0 +1,106 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// RDATDumper.h //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Use this to dump DxilRuntimeData (RDAT) for testing. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DumpContext.h"
|
||||
#include "dxc/Support/WinIncludes.h"
|
||||
#include "dxc/DxilContainer/DxilRuntimeReflection.h"
|
||||
|
||||
namespace hlsl {
|
||||
using namespace RDAT;
|
||||
|
||||
namespace dump {
|
||||
|
||||
void DumpRuntimeData(const RDAT::DxilRuntimeData &RDAT, DumpContext &d);
|
||||
template<typename RecordType>
|
||||
void DumpRecordTable(const RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tableName, const RDAT::TableReader &table);
|
||||
template<typename RecordType>
|
||||
void DumpRecordTableEntry(const RDAT::RDATContext &ctx, DumpContext &d,
|
||||
uint32_t i);
|
||||
|
||||
template<typename _RecordType>
|
||||
class RecordDumper : public _RecordType {
|
||||
public:
|
||||
void Dump(const hlsl::RDAT::RDATContext &ctx, DumpContext &d) const;
|
||||
};
|
||||
|
||||
// Dump record starting at base fields, ending at the type specified.
|
||||
// Specialized for derived records
|
||||
template<typename _RecordType>
|
||||
void DumpWithBase(const hlsl::RDAT::RDATContext &ctx, DumpContext &d, const _RecordType *pRecord) {
|
||||
static_cast< const RecordDumper<_RecordType>* >(pRecord)->Dump(ctx, d);
|
||||
}
|
||||
|
||||
template<typename _RecordType>
|
||||
class RecordRefDumper : public hlsl::RDAT::RecordRef<_RecordType> {
|
||||
public:
|
||||
RecordRefDumper(uint32_t index) { Index = index; }
|
||||
template<typename _DumpTy = _RecordType>
|
||||
const char *TypeName(const hlsl::RDAT::RDATContext &ctx) const {
|
||||
if (const char *name = RecordRefDumper<_DumpTy>(Index).TypeNameDerived(ctx))
|
||||
return name;
|
||||
RecordRef<_DumpTy> rr = { Index };
|
||||
if (rr.Get(ctx))
|
||||
return RecordTraits<_DumpTy>::TypeName();
|
||||
return nullptr;
|
||||
}
|
||||
template<typename _DumpTy = _RecordType>
|
||||
void Dump(const hlsl::RDAT::RDATContext &ctx, DumpContext &d) const {
|
||||
RecordRefDumper<_DumpTy> rrDumper(Index);
|
||||
if (const _DumpTy *ptr = rrDumper.Get(ctx)) {
|
||||
static_cast< const RecordDumper<_DumpTy>* >(ptr)->Dump(ctx, d);
|
||||
rrDumper.DumpDerived(ctx, d);
|
||||
}
|
||||
}
|
||||
// Specialized for base type to recurse into derived
|
||||
const char *TypeNameDerived(const hlsl::RDAT::RDATContext &ctx) const { return nullptr; }
|
||||
void DumpDerived(const hlsl::RDAT::RDATContext &ctx, DumpContext &d) const {}
|
||||
};
|
||||
|
||||
template<typename _T>
|
||||
void DumpRecordValue(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tyName, const char *memberName,
|
||||
const _T *memberPtr);
|
||||
|
||||
template<typename _T>
|
||||
void DumpRecordRef(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tyName, const char *memberName,
|
||||
hlsl::RDAT::RecordRef<_T> rr);
|
||||
|
||||
template<typename _T>
|
||||
void DumpRecordArrayRef(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tyName, const char *memberName,
|
||||
hlsl::RDAT::RecordArrayRef<_T> rar);
|
||||
|
||||
void DumpStringArray(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *memberName,
|
||||
hlsl::RDAT::RDATStringArray sa);
|
||||
|
||||
void DumpIndexArray(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *memberName, uint32_t index);
|
||||
|
||||
void DumpBytesRef(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *memberName,
|
||||
hlsl::RDAT::BytesRef bytesRef);
|
||||
|
||||
template<typename _T>
|
||||
void DumpValueArray(DumpContext &d, const char *memberName,
|
||||
const char *typeName, const void *valueArray,
|
||||
unsigned arraySize);
|
||||
|
||||
#define DEF_RDAT_ENUMS DEF_RDAT_DUMP_DECL
|
||||
#define DEF_DXIL_ENUMS DEF_RDAT_DUMP_DECL
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
} // namespace dump
|
||||
} // namespace hlsl
|
|
@ -173,8 +173,9 @@ bool CountDxilOp_tex_bias(unsigned op) {
|
|||
return op == 61;
|
||||
}
|
||||
bool CountDxilOp_tex_cmp(unsigned op) {
|
||||
// Instructions: SampleCmp=64, SampleCmpLevelZero=65, TextureGatherCmp=74
|
||||
return (64 <= op && op <= 65) || op == 74;
|
||||
// Instructions: SampleCmp=64, SampleCmpLevelZero=65, TextureGatherCmp=74,
|
||||
// SampleCmpLevel=224
|
||||
return (64 <= op && op <= 65) || op == 74 || op == 224;
|
||||
}
|
||||
bool CountDxilOp_tex_grad(unsigned op) {
|
||||
// Instructions: SampleGrad=63
|
||||
|
@ -185,14 +186,16 @@ bool CountDxilOp_tex_load(unsigned op) {
|
|||
return op == 66 || op == 68 || op == 139;
|
||||
}
|
||||
bool CountDxilOp_tex_norm(unsigned op) {
|
||||
// Instructions: Sample=60, SampleLevel=62, TextureGather=73
|
||||
return op == 60 || op == 62 || op == 73;
|
||||
// Instructions: Sample=60, SampleLevel=62, TextureGather=73,
|
||||
// TextureGatherRaw=223
|
||||
return op == 60 || op == 62 || op == 73 || op == 223;
|
||||
}
|
||||
bool CountDxilOp_tex_store(unsigned op) {
|
||||
// Instructions: TextureStore=67, BufferStore=69, RawBufferStore=140,
|
||||
// WriteSamplerFeedback=174, WriteSamplerFeedbackBias=175,
|
||||
// WriteSamplerFeedbackLevel=176, WriteSamplerFeedbackGrad=177
|
||||
return op == 67 || op == 69 || op == 140 || (174 <= op && op <= 177);
|
||||
// WriteSamplerFeedbackLevel=176, WriteSamplerFeedbackGrad=177,
|
||||
// TextureStoreSample=225
|
||||
return op == 67 || op == 69 || op == 140 || (174 <= op && op <= 177) || op == 225;
|
||||
}
|
||||
bool CountDxilOp_uints(unsigned op) {
|
||||
// Instructions: Bfrev=30, Countbits=31, FirstbitLo=32, FirstbitHi=33,
|
||||
|
|
|
@ -84,6 +84,8 @@ const char *kDxBreakMDName = "dx.break.br";
|
|||
const char *kDxIsHelperGlobalName = "dx.ishelper";
|
||||
|
||||
const char *kHostLayoutTypePrefix = "hostlayout.";
|
||||
|
||||
const char* kWaveOpsIncludeHelperLanesString = "waveops-include-helper-lanes";
|
||||
}
|
||||
|
||||
void SetDxilHook(Module &M);
|
||||
|
@ -579,6 +581,14 @@ bool DxilModule::GetAllResourcesBound() const {
|
|||
return m_bAllResourcesBound;
|
||||
}
|
||||
|
||||
void DxilModule::SetResMayAlias(bool resMayAlias) {
|
||||
m_bResMayAlias = resMayAlias;
|
||||
}
|
||||
|
||||
bool DxilModule::GetResMayAlias() const {
|
||||
return m_bResMayAlias;
|
||||
}
|
||||
|
||||
void DxilModule::SetLegacyResourceReservation(bool legacyResourceReservation) {
|
||||
m_IntermediateFlags &= ~LegacyResourceReservation;
|
||||
if (legacyResourceReservation) m_IntermediateFlags |= LegacyResourceReservation;
|
||||
|
@ -1551,6 +1561,7 @@ void DxilModule::LoadDxilMetadata() {
|
|||
m_bUseMinPrecision = !m_ShaderFlags.GetUseNativeLowPrecision();
|
||||
m_bDisableOptimizations = m_ShaderFlags.GetDisableOptimizations();
|
||||
m_bAllResourcesBound = m_ShaderFlags.GetAllResourcesBound();
|
||||
m_bResMayAlias = !m_ShaderFlags.GetResMayNotAlias();
|
||||
}
|
||||
|
||||
// Now that we have the UseMinPrecision flag, set shader model:
|
||||
|
|
|
@ -404,6 +404,18 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
|
|||
|
||||
// Helper Lanes void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
|
||||
{ OC::IsHelperLane, "IsHelperLane", OCC::IsHelperLane, "isHelperLane", { false, false, false, false, true, false, false, false, false, false, false}, Attribute::ReadOnly, },
|
||||
|
||||
// Quad Wave Ops void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
|
||||
{ OC::QuadVote, "QuadVote", OCC::QuadVote, "quadVote", { false, false, false, false, true, false, false, false, false, false, false}, Attribute::None, },
|
||||
|
||||
// Resources - gather void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
|
||||
{ OC::TextureGatherRaw, "TextureGatherRaw", OCC::TextureGatherRaw, "textureGatherRaw", { false, false, false, false, false, false, true, true, true, false, false}, Attribute::ReadOnly, },
|
||||
|
||||
// Resources - sample void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
|
||||
{ OC::SampleCmpLevel, "SampleCmpLevel", OCC::SampleCmpLevel, "sampleCmpLevel", { false, true, true, false, false, false, false, false, false, false, false}, Attribute::ReadOnly, },
|
||||
|
||||
// Resources void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
|
||||
{ OC::TextureStoreSample, "TextureStoreSample", OCC::TextureStoreSample, "textureStoreSample", { false, true, true, false, false, false, true, true, false, false, false}, Attribute::None, },
|
||||
};
|
||||
// OPCODE-OLOADS:END
|
||||
|
||||
|
@ -604,8 +616,8 @@ bool OP::IsDxilOpWave(OpCode C) {
|
|||
// WaveReadLaneFirst=118, WaveActiveOp=119, WaveActiveBit=120,
|
||||
// WavePrefixOp=121, QuadReadLaneAt=122, QuadOp=123, WaveAllBitCount=135,
|
||||
// WavePrefixBitCount=136, WaveMatch=165, WaveMultiPrefixOp=166,
|
||||
// WaveMultiPrefixBitCount=167
|
||||
return (110 <= op && op <= 123) || (135 <= op && op <= 136) || (165 <= op && op <= 167);
|
||||
// WaveMultiPrefixBitCount=167, QuadVote=222
|
||||
return (110 <= op && op <= 123) || (135 <= op && op <= 136) || (165 <= op && op <= 167) || op == 222;
|
||||
// OPCODE-WAVE:END
|
||||
}
|
||||
|
||||
|
@ -841,12 +853,37 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
|
|||
mask = SFLAG(Mesh);
|
||||
return;
|
||||
}
|
||||
// Instructions: AnnotateHandle=216, CreateHandleFromBinding=217,
|
||||
// CreateHandleFromHeap=218, Unpack4x8=219, Pack4x8=220, IsHelperLane=221
|
||||
if ((216 <= op && op <= 221)) {
|
||||
// Instructions: CreateHandleFromHeap=218, Unpack4x8=219, Pack4x8=220,
|
||||
// IsHelperLane=221
|
||||
if ((218 <= op && op <= 221)) {
|
||||
major = 6; minor = 6;
|
||||
return;
|
||||
}
|
||||
// Instructions: AnnotateHandle=216, CreateHandleFromBinding=217
|
||||
if ((216 <= op && op <= 217)) {
|
||||
if (bWithTranslation) {
|
||||
major = 6; minor = 0;
|
||||
} else {
|
||||
major = 6; minor = 6;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Instructions: TextureGatherRaw=223, SampleCmpLevel=224,
|
||||
// TextureStoreSample=225
|
||||
if ((223 <= op && op <= 225)) {
|
||||
major = 6; minor = 7;
|
||||
return;
|
||||
}
|
||||
// Instructions: QuadVote=222
|
||||
if (op == 222) {
|
||||
if (bWithTranslation) {
|
||||
major = 6; minor = 0;
|
||||
} else {
|
||||
major = 6; minor = 7;
|
||||
}
|
||||
mask = SFLAG(Library) | SFLAG(Compute) | SFLAG(Amplification) | SFLAG(Mesh) | SFLAG(Pixel);
|
||||
return;
|
||||
}
|
||||
// OPCODE-SMMASK:END
|
||||
}
|
||||
|
||||
|
@ -904,6 +941,17 @@ void OP::GetMinShaderModelAndMask(const llvm::CallInst *CI, bool bWithTranslatio
|
|||
minor = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// AnnotateHandle and CreateHandleFromBinding can be translated down to
|
||||
// SM 6.0, but this wasn't set properly in validator version 6.6, so make it
|
||||
// match when using that version.
|
||||
else if (bWithTranslation &&
|
||||
DXIL::CompareVersions(valMajor, valMinor, 1, 6) == 0 &&
|
||||
(opcode == DXIL::OpCode::AnnotateHandle ||
|
||||
opcode == DXIL::OpCode::CreateHandleFromBinding)) {
|
||||
major = 6;
|
||||
minor = 6;
|
||||
}
|
||||
}
|
||||
#undef SFLAG
|
||||
|
||||
|
@ -1433,6 +1481,18 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
|
|||
|
||||
// Helper Lanes
|
||||
case OpCode::IsHelperLane: A(pI1); A(pI32); break;
|
||||
|
||||
// Quad Wave Ops
|
||||
case OpCode::QuadVote: A(pI1); A(pI32); A(pI1); A(pI8); break;
|
||||
|
||||
// Resources - gather
|
||||
case OpCode::TextureGatherRaw: RRT(pETy); A(pI32); A(pRes); A(pRes); A(pF32); A(pF32); A(pF32); A(pF32); A(pI32); A(pI32); break;
|
||||
|
||||
// Resources - sample
|
||||
case OpCode::SampleCmpLevel: RRT(pETy); A(pI32); A(pRes); A(pRes); A(pF32); A(pF32); A(pF32); A(pF32); A(pI32); A(pI32); A(pI32); A(pF32); A(pF32); break;
|
||||
|
||||
// Resources
|
||||
case OpCode::TextureStoreSample: A(pV); A(pI32); A(pRes); A(pI32); A(pI32); A(pI32); A(pETy); A(pETy); A(pETy); A(pETy); A(pI8); A(pI32); break;
|
||||
// OPCODE-OLOAD-FUNCS:END
|
||||
default: DXASSERT(false, "otherwise unhandled case"); break;
|
||||
}
|
||||
|
@ -1564,6 +1624,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
|
|||
DXASSERT_NOMSG(FT->getNumParams() > 1);
|
||||
return FT->getParamType(1);
|
||||
case OpCode::TextureStore:
|
||||
case OpCode::TextureStoreSample:
|
||||
DXASSERT_NOMSG(FT->getNumParams() > 5);
|
||||
return FT->getParamType(5);
|
||||
case OpCode::TraceRay:
|
||||
|
@ -1691,6 +1752,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
|
|||
case OpCode::RayQuery_CandidateTriangleFrontFace:
|
||||
case OpCode::RayQuery_CommittedTriangleFrontFace:
|
||||
case OpCode::IsHelperLane:
|
||||
case OpCode::QuadVote:
|
||||
return IntegerType::get(Ctx, 1);
|
||||
case OpCode::CBufferLoadLegacy:
|
||||
case OpCode::Sample:
|
||||
|
@ -1705,6 +1767,8 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
|
|||
case OpCode::TextureGatherCmp:
|
||||
case OpCode::RawBufferLoad:
|
||||
case OpCode::Unpack4x8:
|
||||
case OpCode::TextureGatherRaw:
|
||||
case OpCode::SampleCmpLevel:
|
||||
{
|
||||
StructType *ST = cast<StructType>(Ty);
|
||||
return ST->getElementType(0);
|
||||
|
|
|
@ -59,6 +59,9 @@ ShaderFlags::ShaderFlags():
|
|||
, m_bResourceDescriptorHeapIndexing(false)
|
||||
, m_bSamplerDescriptorHeapIndexing(false)
|
||||
, m_bAtomicInt64OnHeapResource(false)
|
||||
, m_bResMayNotAlias(false)
|
||||
, m_bAdvancedTextureOps(false)
|
||||
, m_bWriteableMSAATextures(false)
|
||||
, m_align1(0)
|
||||
{
|
||||
// Silence unused field warnings
|
||||
|
@ -116,6 +119,9 @@ uint64_t ShaderFlags::GetFeatureInfo() const {
|
|||
Flags |= m_bSamplerDescriptorHeapIndexing ? hlsl::DXIL::ShaderFeatureInfo_SamplerDescriptorHeapIndexing : 0;
|
||||
Flags |= m_bAtomicInt64OnHeapResource ? hlsl::DXIL::ShaderFeatureInfo_AtomicInt64OnHeapResource : 0;
|
||||
|
||||
Flags |= m_bAdvancedTextureOps ? hlsl::DXIL::ShaderFeatureInfo_AdvancedTextureOps : 0;
|
||||
Flags |= m_bWriteableMSAATextures ? hlsl::DXIL::ShaderFeatureInfo_WriteableMSAATextures : 0;
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
|
@ -175,6 +181,9 @@ uint64_t ShaderFlags::GetShaderFlagsRawForCollection() {
|
|||
Flags.SetResourceDescriptorHeapIndexing(true);
|
||||
Flags.SetSamplerDescriptorHeapIndexing(true);
|
||||
Flags.SetAtomicInt64OnHeapResource(true);
|
||||
Flags.SetResMayNotAlias(true);
|
||||
Flags.SetAdvancedTextureOps(true);
|
||||
Flags.SetWriteableMSAATextures(true);
|
||||
return Flags.GetShaderFlagsRaw();
|
||||
}
|
||||
|
||||
|
@ -368,6 +377,12 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
|
|||
bool hasSamplerDescriptorHeapIndexing = false;
|
||||
bool hasAtomicInt64OnHeapResource = false;
|
||||
|
||||
// Used to determine whether to set ResMayNotAlias flag.
|
||||
bool hasUAVs = M->GetUAVs().size() > 0;
|
||||
|
||||
bool hasAdvancedTextureOps = false;
|
||||
bool hasWriteableMSAATextures = false;
|
||||
|
||||
// Try to maintain compatibility with a v1.0 validator if that's what we have.
|
||||
uint32_t valMajor, valMinor;
|
||||
M->GetValidatorVersion(valMajor, valMinor);
|
||||
|
@ -385,6 +400,9 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
|
|||
ResourceKey key = {(uint8_t)res->GetClass(), res->GetSpaceID(),
|
||||
res->GetLowerBound(), res->GetUpperBound()};
|
||||
resMap.insert({key, res.get()});
|
||||
if (res->GetKind() == DXIL::ResourceKind::Texture2DMS ||
|
||||
res->GetKind() == DXIL::ResourceKind::Texture2DMSArray)
|
||||
hasWriteableMSAATextures = true;
|
||||
}
|
||||
|
||||
for (const BasicBlock &BB : F->getBasicBlockList()) {
|
||||
|
@ -452,11 +470,16 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
|
|||
case DXIL::OpCode::Msad:
|
||||
hasMSAD = true;
|
||||
break;
|
||||
case DXIL::OpCode::BufferLoad:
|
||||
case DXIL::OpCode::TextureLoad: {
|
||||
case DXIL::OpCode::TextureLoad:
|
||||
if (!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureLoadOffset0OpIdx)) ||
|
||||
!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureLoadOffset1OpIdx)) ||
|
||||
!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureLoadOffset2OpIdx)))
|
||||
hasAdvancedTextureOps = true;
|
||||
__fallthrough;
|
||||
case DXIL::OpCode::BufferLoad: {
|
||||
if (hasMulticomponentUAVLoads) continue;
|
||||
// This is the old-style computation (overestimating requirements).
|
||||
Value *resHandle = CI->getArgOperand(DXIL::OperandIndex::kBufferStoreHandleOpIdx);
|
||||
Value *resHandle = CI->getArgOperand(DXIL::OperandIndex::kBufferLoadHandleOpIdx);
|
||||
CallInst *handleCall = FindCallToCreateHandle(resHandle);
|
||||
// Check if this is a library handle or general create handle
|
||||
if (handleCall) {
|
||||
|
@ -507,14 +530,27 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case DXIL::OpCode::SampleGrad:
|
||||
case DXIL::OpCode::SampleLevel:
|
||||
case DXIL::OpCode::SampleCmpLevelZero:
|
||||
if (!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureSampleOffset0OpIdx)) ||
|
||||
!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureSampleOffset1OpIdx)) ||
|
||||
!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureSampleOffset2OpIdx)))
|
||||
hasAdvancedTextureOps = true;
|
||||
break;
|
||||
case DXIL::OpCode::Sample:
|
||||
case DXIL::OpCode::SampleBias:
|
||||
case DXIL::OpCode::SampleCmp:
|
||||
if (!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureSampleOffset0OpIdx)) ||
|
||||
!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureSampleOffset1OpIdx)) ||
|
||||
!isa<Constant>(CI->getArgOperand(DXIL::OperandIndex::kTextureSampleOffset2OpIdx)))
|
||||
hasAdvancedTextureOps = true;
|
||||
__fallthrough;
|
||||
case DXIL::OpCode::DerivFineX:
|
||||
case DXIL::OpCode::DerivFineY:
|
||||
case DXIL::OpCode::DerivCoarseX:
|
||||
case DXIL::OpCode::DerivCoarseY:
|
||||
case DXIL::OpCode::CalculateLOD:
|
||||
case DXIL::OpCode::Sample:
|
||||
case DXIL::OpCode::SampleBias:
|
||||
case DXIL::OpCode::SampleCmp: {
|
||||
case DXIL::OpCode::CalculateLOD: {
|
||||
const ShaderModel *pSM = M->GetShaderModel();
|
||||
if (pSM->IsAS() || pSM->IsMS())
|
||||
hasDerivativesInMeshAndAmpShaders = true;
|
||||
|
@ -522,11 +558,26 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
|
|||
case DXIL::OpCode::CreateHandleFromHeap: {
|
||||
ConstantInt *isSamplerVal = dyn_cast<ConstantInt>(
|
||||
CI->getArgOperand(DXIL::OperandIndex::kCreateHandleFromHeapSamplerHeapOpIdx));
|
||||
if (isSamplerVal->getLimitedValue())
|
||||
if (isSamplerVal->getLimitedValue()) {
|
||||
hasSamplerDescriptorHeapIndexing = true;
|
||||
else
|
||||
} else {
|
||||
hasResourceDescriptorHeapIndexing = true;
|
||||
if (!hasUAVs) {
|
||||
// If not already marked, check if UAV.
|
||||
DxilResourceProperties RP = GetResourcePropertyFromHandleCall(
|
||||
M, const_cast<CallInst *>(CI));
|
||||
if (RP.isUAV())
|
||||
hasUAVs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
case DXIL::OpCode::TextureStoreSample:
|
||||
hasWriteableMSAATextures = true;
|
||||
__fallthrough;
|
||||
case DXIL::OpCode::SampleCmpLevel:
|
||||
case DXIL::OpCode::TextureGatherRaw:
|
||||
hasAdvancedTextureOps = true;
|
||||
break;
|
||||
default:
|
||||
// Normal opcodes.
|
||||
break;
|
||||
|
@ -640,6 +691,12 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
|
|||
flag.SetResourceDescriptorHeapIndexing(hasResourceDescriptorHeapIndexing);
|
||||
flag.SetSamplerDescriptorHeapIndexing(hasSamplerDescriptorHeapIndexing);
|
||||
flag.SetAtomicInt64OnHeapResource(hasAtomicInt64OnHeapResource);
|
||||
flag.SetAdvancedTextureOps(hasAdvancedTextureOps);
|
||||
flag.SetWriteableMSAATextures(hasWriteableMSAATextures);
|
||||
|
||||
// Only bother setting the flag when there are UAVs.
|
||||
flag.SetResMayNotAlias(DXIL::CompareVersions(valMajor, valMinor, 1, 7) >= 0 &&
|
||||
hasUAVs && !M->GetResMayAlias());
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
|
|
@ -343,74 +343,5 @@ DxilSubobject &DxilSubobjects::CreateSubobject(Kind kind, llvm::StringRef Name)
|
|||
return ref;
|
||||
}
|
||||
|
||||
bool LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, RDAT::SubobjectTableReader *pSubobjectTableReader) {
|
||||
if (!pSubobjectTableReader)
|
||||
return false;
|
||||
bool result = true;
|
||||
for (unsigned i = 0; i < pSubobjectTableReader->GetCount(); ++i) {
|
||||
try {
|
||||
auto reader = pSubobjectTableReader->GetItem(i);
|
||||
DXIL::SubobjectKind kind = reader.GetKind();
|
||||
bool bLocalRS = false;
|
||||
switch (kind) {
|
||||
case DXIL::SubobjectKind::StateObjectConfig:
|
||||
subobjects.CreateStateObjectConfig(reader.GetName(),
|
||||
reader.GetStateObjectConfig_Flags());
|
||||
break;
|
||||
case DXIL::SubobjectKind::LocalRootSignature:
|
||||
bLocalRS = true;
|
||||
case DXIL::SubobjectKind::GlobalRootSignature: {
|
||||
const void *pOutBytes;
|
||||
uint32_t OutSizeInBytes;
|
||||
if (!reader.GetRootSignature(&pOutBytes, &OutSizeInBytes)) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
subobjects.CreateRootSignature(reader.GetName(), bLocalRS, pOutBytes, OutSizeInBytes);
|
||||
break;
|
||||
}
|
||||
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
|
||||
uint32_t NumExports = reader.GetSubobjectToExportsAssociation_NumExports();
|
||||
std::vector<llvm::StringRef> Exports;
|
||||
Exports.resize(NumExports);
|
||||
for (unsigned i = 0; i < NumExports; ++i) {
|
||||
Exports[i] = reader.GetSubobjectToExportsAssociation_Export(i);
|
||||
}
|
||||
subobjects.CreateSubobjectToExportsAssociation(reader.GetName(),
|
||||
reader.GetSubobjectToExportsAssociation_Subobject(),
|
||||
Exports.data(), NumExports);
|
||||
break;
|
||||
}
|
||||
case DXIL::SubobjectKind::RaytracingShaderConfig:
|
||||
subobjects.CreateRaytracingShaderConfig(reader.GetName(),
|
||||
reader.GetRaytracingShaderConfig_MaxPayloadSizeInBytes(),
|
||||
reader.GetRaytracingShaderConfig_MaxAttributeSizeInBytes());
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig:
|
||||
subobjects.CreateRaytracingPipelineConfig(reader.GetName(),
|
||||
reader.GetRaytracingPipelineConfig_MaxTraceRecursionDepth());
|
||||
break;
|
||||
case DXIL::SubobjectKind::HitGroup:
|
||||
subobjects.CreateHitGroup(reader.GetName(),
|
||||
reader.GetHitGroup_Type(),
|
||||
reader.GetHitGroup_AnyHit(),
|
||||
reader.GetHitGroup_ClosestHit(),
|
||||
reader.GetHitGroup_Intersection());
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
|
||||
subobjects.CreateRaytracingPipelineConfig1(
|
||||
reader.GetName(),
|
||||
reader.GetRaytracingPipelineConfig1_MaxTraceRecursionDepth(),
|
||||
reader.GetRaytracingPipelineConfig1_Flags());
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (hlsl::Exception &) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace hlsl
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ add_llvm_library(LLVMDxilContainer
|
|||
DxilContainerReader.cpp
|
||||
DxcContainerBuilder.cpp
|
||||
DxilRuntimeReflection.cpp
|
||||
RDATDxilSubobjects.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include "dxc/DxilContainer/DxilContainerAssembler.h"
|
||||
#include "dxc/DXIL/DxilUtil.h"
|
||||
#include "dxc/DXIL/DxilFunctionProps.h"
|
||||
#include "dxc/DXIL/DxilEntryProps.h"
|
||||
#include "dxc/DXIL/DxilOperations.h"
|
||||
#include "dxc/DXIL/DxilInstructions.h"
|
||||
#include "dxc/Support/Global.h"
|
||||
|
@ -931,46 +933,69 @@ public:
|
|||
// Most RDAT parts are tables each containing a list of structures of same type.
|
||||
// Exceptions are string table and index table because each string or list of
|
||||
// indicies can be of different sizes.
|
||||
template <class T>
|
||||
class RDATTable : public RDATPart {
|
||||
protected:
|
||||
std::vector<T> m_rows;
|
||||
// m_map is map of records to their index.
|
||||
// Used to alias identical records.
|
||||
std::unordered_map<std::string, uint32_t> m_map;
|
||||
std::vector<StringRef> m_rows;
|
||||
size_t m_RecordStride = 0;
|
||||
bool m_bDeduplicationEnabled = false;
|
||||
RuntimeDataPartType m_Type = RuntimeDataPartType::Invalid;
|
||||
public:
|
||||
virtual void Insert(T *data) {}
|
||||
virtual ~RDATTable() {}
|
||||
|
||||
void Insert(const T &data) {
|
||||
m_rows.push_back(data);
|
||||
void SetType(RuntimeDataPartType type) { m_Type = type; }
|
||||
RuntimeDataPartType GetType() const { return m_Type; }
|
||||
void SetRecordStride(size_t RecordStride) {
|
||||
DXASSERT(m_rows.empty(), "record stride is fixed for the entire table");
|
||||
m_RecordStride = RecordStride;
|
||||
}
|
||||
size_t GetRecordStride() const { return m_RecordStride; }
|
||||
void SetDeduplication(bool bEnabled = true) { m_bDeduplicationEnabled = bEnabled; }
|
||||
|
||||
uint32_t Count() {
|
||||
size_t count = m_rows.size();
|
||||
return (count < UINT32_MAX) ? count : 0;
|
||||
}
|
||||
|
||||
template<typename RecordType>
|
||||
uint32_t Insert(const RecordType &data) {
|
||||
IFTBOOL(m_RecordStride <= sizeof(RecordType), DXC_E_GENERAL_INTERNAL_ERROR);
|
||||
size_t count = m_rows.size();
|
||||
if (count < (UINT32_MAX - 1)) {
|
||||
const char *pData = (const char*)(const void *)&data;
|
||||
auto result = m_map.insert(std::make_pair(std::string(pData, pData + m_RecordStride), count));
|
||||
if (!m_bDeduplicationEnabled || result.second) {
|
||||
m_rows.emplace_back(result.first->first);
|
||||
return count;
|
||||
} else {
|
||||
return result.first->second;
|
||||
}
|
||||
}
|
||||
return RDAT_NULL_REF;
|
||||
}
|
||||
|
||||
void Write(void *ptr) {
|
||||
char *pCur = (char*)ptr;
|
||||
RuntimeDataTableHeader &header = *reinterpret_cast<RuntimeDataTableHeader*>(pCur);
|
||||
header.RecordCount = m_rows.size();
|
||||
header.RecordStride = sizeof(T);
|
||||
header.RecordStride = m_RecordStride;
|
||||
pCur += sizeof(RuntimeDataTableHeader);
|
||||
memcpy(pCur, m_rows.data(), header.RecordCount * header.RecordStride);
|
||||
for (auto &record : m_rows) {
|
||||
DXASSERT_NOMSG(record.size() == m_RecordStride);
|
||||
memcpy(pCur, record.data(), m_RecordStride);
|
||||
pCur += m_RecordStride;
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t GetPartSize() const {
|
||||
if (m_rows.empty())
|
||||
return 0;
|
||||
return sizeof(RuntimeDataTableHeader) + m_rows.size() * sizeof(T);
|
||||
return sizeof(RuntimeDataTableHeader) + m_rows.size() * m_RecordStride;
|
||||
}
|
||||
};
|
||||
|
||||
// Resource table will contain a list of RuntimeDataResourceInfo in order of
|
||||
// CBuffer, Sampler, SRV, and UAV resource classes.
|
||||
class ResourceTable : public RDATTable<RuntimeDataResourceInfo> {
|
||||
public:
|
||||
RuntimeDataPartType GetType() const { return RuntimeDataPartType::ResourceTable; }
|
||||
};
|
||||
|
||||
class FunctionTable : public RDATTable<RuntimeDataFunctionInfo> {
|
||||
public:
|
||||
RuntimeDataPartType GetType() const { return RuntimeDataPartType::FunctionTable; }
|
||||
};
|
||||
|
||||
class StringBufferPart : public RDATPart {
|
||||
private:
|
||||
StringMap<uint32_t> m_StringMap;
|
||||
|
@ -1077,11 +1102,6 @@ public:
|
|||
void Write(void *ptr) { memcpy(ptr, m_DataBuffer.data(), m_DataBuffer.size()); }
|
||||
};
|
||||
|
||||
class SubobjectTable : public RDATTable<RuntimeDataSubobjectInfo> {
|
||||
public:
|
||||
RuntimeDataPartType GetType() const { return RuntimeDataPartType::SubobjectTable; }
|
||||
};
|
||||
|
||||
using namespace DXIL;
|
||||
|
||||
class DxilRDATWriter : public DxilPartWriter {
|
||||
|
@ -1244,14 +1264,16 @@ private:
|
|||
}
|
||||
|
||||
void UpdateFunctionInfo(const DxilModule &DM) {
|
||||
llvm::Module *M = DM.GetModule();
|
||||
// We must select the appropriate shader mask for the validator version,
|
||||
// so we don't set any bits the validator doesn't recognize.
|
||||
unsigned ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Amplification + 1)) - 1;
|
||||
if (DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 5) < 0) {
|
||||
ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Callable + 1)) - 1;
|
||||
}
|
||||
for (auto &function : DM.GetModule()->getFunctionList()) {
|
||||
if (function.isDeclaration() && !function.isIntrinsic()) {
|
||||
for (auto &function : M->getFunctionList()) {
|
||||
if (function.isDeclaration() && !function.isIntrinsic() &&
|
||||
function.getLinkage() == llvm::GlobalValue::LinkageTypes::ExternalLinkage) {
|
||||
if (OP::IsDxilOpFunc(&function)) {
|
||||
// update min shader model and shader stage mask per function
|
||||
UpdateFunctionToShaderCompat(&function);
|
||||
|
@ -1261,15 +1283,17 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
for (auto &function : DM.GetModule()->getFunctionList()) {
|
||||
|
||||
|
||||
for (auto &function : M->getFunctionList()) {
|
||||
if (!function.isDeclaration()) {
|
||||
StringRef mangled = function.getName();
|
||||
StringRef unmangled = hlsl::dxilutil::DemangleFunctionName(function.getName());
|
||||
uint32_t mangledIndex = m_pStringBufferPart->Insert(mangled);
|
||||
uint32_t unmangledIndex = m_pStringBufferPart->Insert(unmangled);
|
||||
// Update resource Index
|
||||
uint32_t resourceIndex = UINT_MAX;
|
||||
uint32_t functionDependencies = UINT_MAX;
|
||||
uint32_t resourceIndex = RDAT_NULL_REF;
|
||||
uint32_t functionDependencies = RDAT_NULL_REF;
|
||||
uint32_t payloadSizeInBytes = 0;
|
||||
uint32_t attrSizeInBytes = 0;
|
||||
uint32_t shaderKind = static_cast<uint32_t>(DXIL::ShaderKind::Library);
|
||||
|
@ -1282,8 +1306,10 @@ private:
|
|||
functionDependencies =
|
||||
m_pIndexArraysPart->AddIndex(m_FuncToDependencies[&function].begin(),
|
||||
m_FuncToDependencies[&function].end());
|
||||
RuntimeDataFunctionInfo info = {};
|
||||
ShaderFlags flags = ShaderFlags::CollectShaderFlags(&function, &DM);
|
||||
if (DM.HasDxilFunctionProps(&function)) {
|
||||
auto props = DM.GetDxilFunctionProps(&function);
|
||||
const auto &props = DM.GetDxilFunctionProps(&function);
|
||||
if (props.IsClosestHit() || props.IsAnyHit()) {
|
||||
payloadSizeInBytes = props.ShaderProps.Ray.payloadSizeInBytes;
|
||||
attrSizeInBytes = props.ShaderProps.Ray.attributeSizeInBytes;
|
||||
|
@ -1296,8 +1322,6 @@ private:
|
|||
}
|
||||
shaderKind = (uint32_t)props.shaderKind;
|
||||
}
|
||||
ShaderFlags flags = ShaderFlags::CollectShaderFlags(&function, &DM);
|
||||
RuntimeDataFunctionInfo info = {};
|
||||
info.Name = mangledIndex;
|
||||
info.UnmangledName = unmangledIndex;
|
||||
info.ShaderKind = shaderKind;
|
||||
|
@ -1305,9 +1329,7 @@ private:
|
|||
info.FunctionDependencies = functionDependencies;
|
||||
info.PayloadSizeInBytes = payloadSizeInBytes;
|
||||
info.AttributeSizeInBytes = attrSizeInBytes;
|
||||
uint64_t featureFlags = flags.GetFeatureInfo();
|
||||
info.FeatureInfo1 = featureFlags & 0xffffffff;
|
||||
info.FeatureInfo2 = (featureFlags >> 32) & 0xffffffff;
|
||||
info.SetFeatureFlags(flags.GetFeatureInfo());
|
||||
// Init min target 6.0
|
||||
unsigned minMajor = 6, minMinor = 0;
|
||||
// Increase min target based on feature flags:
|
||||
|
@ -1358,9 +1380,9 @@ private:
|
|||
__fallthrough;
|
||||
case DXIL::SubobjectKind::GlobalRootSignature: {
|
||||
const void *Data;
|
||||
obj.GetRootSignature(bLocalRS, Data, info.RootSignature.SizeInBytes);
|
||||
info.RootSignature.RawBytesOffset =
|
||||
m_pRawBytesPart->Insert(Data, info.RootSignature.SizeInBytes);
|
||||
obj.GetRootSignature(bLocalRS, Data, info.RootSignature.Data.Size);
|
||||
info.RootSignature.Data.Offset =
|
||||
m_pRawBytesPart->Insert(Data, info.RootSignature.Data.Size);
|
||||
break;
|
||||
}
|
||||
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
|
||||
|
@ -1413,24 +1435,41 @@ private:
|
|||
}
|
||||
|
||||
void CreateParts() {
|
||||
#define ADD_PART(type) \
|
||||
m_Parts.emplace_back(llvm::make_unique<type>()); \
|
||||
m_p##type = reinterpret_cast<type*>(m_Parts.back().get());
|
||||
bool bRecordDeduplicationEnabled = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 7) >= 0;
|
||||
RuntimeDataPartType maxPartID = RDAT::MaxPartTypeForValVer(m_ValMajor, m_ValMinor);
|
||||
|
||||
#define ADD_PART(type) \
|
||||
m_Parts.emplace_back(llvm::make_unique<type>()); \
|
||||
m_p##type = reinterpret_cast<type *>(m_Parts.back().get());
|
||||
|
||||
#define ADD_TABLE(type, table) \
|
||||
if (RuntimeDataPartType::table <= maxPartID) { \
|
||||
m_Parts.emplace_back(llvm::make_unique<RDATTable>()); \
|
||||
m_p##table = reinterpret_cast<RDATTable *>(m_Parts.back().get()); \
|
||||
m_p##table->SetRecordStride(sizeof(type)); \
|
||||
m_p##table->SetType(RuntimeDataPartType::table); \
|
||||
m_p##table->SetDeduplication(bRecordDeduplicationEnabled); \
|
||||
}
|
||||
|
||||
ADD_PART(StringBufferPart);
|
||||
ADD_PART(ResourceTable);
|
||||
ADD_PART(FunctionTable);
|
||||
ADD_TABLE(RuntimeDataResourceInfo, ResourceTable);
|
||||
ADD_TABLE(RuntimeDataFunctionInfo, FunctionTable);
|
||||
ADD_PART(IndexArraysPart);
|
||||
ADD_PART(RawBytesPart);
|
||||
ADD_PART(SubobjectTable);
|
||||
ADD_TABLE(RuntimeDataSubobjectInfo, SubobjectTable);
|
||||
|
||||
#undef ADD_PART
|
||||
#undef ADD_TABLE
|
||||
}
|
||||
|
||||
StringBufferPart *m_pStringBufferPart;
|
||||
IndexArraysPart *m_pIndexArraysPart;
|
||||
RawBytesPart *m_pRawBytesPart;
|
||||
FunctionTable *m_pFunctionTable;
|
||||
ResourceTable *m_pResourceTable;
|
||||
SubobjectTable *m_pSubobjectTable;
|
||||
|
||||
// Once per table.
|
||||
#define RDAT_STRUCT_TABLE(type, table) RDATTable *m_p##table = nullptr;
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_DEFAULTS
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
public:
|
||||
DxilRDATWriter(const DxilModule &mod)
|
||||
|
@ -1441,7 +1480,8 @@ public:
|
|||
CreateParts();
|
||||
UpdateResourceInfo(mod);
|
||||
UpdateFunctionInfo(mod);
|
||||
UpdateSubobjectInfo(mod);
|
||||
if (m_pSubobjectTable)
|
||||
UpdateSubobjectInfo(mod);
|
||||
|
||||
// Delete any empty parts:
|
||||
std::vector<std::unique_ptr<RDATPart>>::iterator it = m_Parts.begin();
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
type = Library
|
||||
name = DxilContainer
|
||||
parent = Libraries
|
||||
required_libraries = BitReader BitWriter Core DxcSupport IPA Support
|
||||
required_libraries = BitReader BitWriter Core DxcSupport IPA Support DXIL
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// RDATDxilSubobjects.cpp //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Implement LoadSubobjectsFromRDAT, depending on both DXIL and RDAT libs. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dxc/Support/Global.h"
|
||||
#include "dxc/Support/Unicode.h"
|
||||
#include "dxc/Support/WinIncludes.h"
|
||||
#include "dxc/DXIL/DxilSubobject.h"
|
||||
#include "dxc/DxilContainer/DxilRuntimeReflection.h"
|
||||
|
||||
namespace hlsl {
|
||||
|
||||
bool LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, const RDAT::DxilRuntimeData &rdat) {
|
||||
auto table = rdat.GetSubobjectTable();
|
||||
if (!table)
|
||||
return false;
|
||||
bool result = true;
|
||||
for (unsigned i = 0; i < table.Count(); ++i) {
|
||||
try {
|
||||
auto reader = table[i];
|
||||
DXIL::SubobjectKind kind = reader.getKind();
|
||||
bool bLocalRS = false;
|
||||
switch (kind) {
|
||||
case DXIL::SubobjectKind::StateObjectConfig:
|
||||
subobjects.CreateStateObjectConfig(reader.getName(),
|
||||
reader.getStateObjectConfig().getFlags());
|
||||
break;
|
||||
case DXIL::SubobjectKind::LocalRootSignature:
|
||||
bLocalRS = true;
|
||||
case DXIL::SubobjectKind::GlobalRootSignature:
|
||||
if (!reader.getRootSignature()) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
subobjects.CreateRootSignature(reader.getName(), bLocalRS,
|
||||
reader.getRootSignature().getData(),
|
||||
reader.getRootSignature().sizeData());
|
||||
break;
|
||||
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
|
||||
auto association = reader.getSubobjectToExportsAssociation();
|
||||
auto exports = association.getExports();
|
||||
uint32_t NumExports = exports.Count();
|
||||
std::vector<llvm::StringRef> Exports;
|
||||
Exports.resize(NumExports);
|
||||
for (unsigned i = 0; i < NumExports; ++i) {
|
||||
Exports[i] = exports[i];
|
||||
}
|
||||
subobjects.CreateSubobjectToExportsAssociation(reader.getName(),
|
||||
association.getSubobject(), Exports.data(), NumExports);
|
||||
break;
|
||||
}
|
||||
case DXIL::SubobjectKind::RaytracingShaderConfig:
|
||||
subobjects.CreateRaytracingShaderConfig(reader.getName(),
|
||||
reader.getRaytracingShaderConfig().getMaxPayloadSizeInBytes(),
|
||||
reader.getRaytracingShaderConfig().getMaxAttributeSizeInBytes());
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig:
|
||||
subobjects.CreateRaytracingPipelineConfig(reader.getName(),
|
||||
reader.getRaytracingPipelineConfig().getMaxTraceRecursionDepth());
|
||||
break;
|
||||
case DXIL::SubobjectKind::HitGroup:
|
||||
subobjects.CreateHitGroup(reader.getName(),
|
||||
reader.getHitGroup().getType(),
|
||||
reader.getHitGroup().getAnyHit(),
|
||||
reader.getHitGroup().getClosestHit(),
|
||||
reader.getHitGroup().getIntersection());
|
||||
break;
|
||||
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
|
||||
subobjects.CreateRaytracingPipelineConfig1(
|
||||
reader.getName(),
|
||||
reader.getRaytracingPipelineConfig1().getMaxTraceRecursionDepth(),
|
||||
reader.getRaytracingPipelineConfig1().getFlags());
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (hlsl::Exception &) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace hlsl
|
||||
|
|
@ -44,8 +44,6 @@
|
|||
|
||||
// Remove this workaround once newer version of d3dcommon.h can be compiled against
|
||||
#define ADD_16_64_BIT_TYPES
|
||||
// Disable warning about value not being valid in enum
|
||||
#pragma warning( disable : 4063 )
|
||||
|
||||
const GUID IID_ID3D11ShaderReflection_43 = {
|
||||
0x0a233719,
|
||||
|
@ -90,6 +88,8 @@ class CShaderReflectionType;
|
|||
enum class PublicAPI { D3D12 = 0, D3D11_47 = 1, D3D11_43 = 2 };
|
||||
|
||||
#ifdef ADD_16_64_BIT_TYPES
|
||||
// Disable warning about value not being valid in enum
|
||||
#pragma warning( disable : 4063 )
|
||||
#define D3D_SVT_INT16 ((D3D_SHADER_VARIABLE_TYPE)58)
|
||||
#define D3D_SVT_UINT16 ((D3D_SHADER_VARIABLE_TYPE)59)
|
||||
#define D3D_SVT_FLOAT16 ((D3D_SHADER_VARIABLE_TYPE)60)
|
||||
|
@ -2681,32 +2681,51 @@ HRESULT CFunctionReflection::GetResourceBindingDescByName(LPCSTR Name,
|
|||
// DxilLibraryReflection
|
||||
|
||||
void DxilLibraryReflection::AddResourceDependencies() {
|
||||
RDAT::FunctionTableReader *functionTable = m_RDAT.GetFunctionTableReader();
|
||||
auto functionTable = m_RDAT.GetFunctionTable();
|
||||
m_FunctionVector.clear();
|
||||
m_FunctionVector.reserve(functionTable->GetNumFunctions());
|
||||
m_FunctionVector.reserve(functionTable.Count());
|
||||
std::map<StringRef, CFunctionReflection*> orderedMap;
|
||||
|
||||
RDAT::ResourceTableReader *resourceTable = m_RDAT.GetResourceTableReader();
|
||||
unsigned SamplersStart = resourceTable->GetNumCBuffers();
|
||||
unsigned SRVsStart = SamplersStart + resourceTable->GetNumSamplers();
|
||||
unsigned UAVsStart = SRVsStart + resourceTable->GetNumSRVs();
|
||||
IFTBOOL(resourceTable->GetNumResources() == m_Resources.size(),
|
||||
auto resourceTable = m_RDAT.GetResourceTable();
|
||||
unsigned SamplersStart = 0;
|
||||
unsigned SRVsStart = 0;
|
||||
unsigned UAVsStart = 0;
|
||||
DXIL::ResourceClass prevClass = DXIL::ResourceClass::CBuffer;
|
||||
for (unsigned i = 0; i < resourceTable.Count(); i++) {
|
||||
auto resource = resourceTable[i];
|
||||
if (prevClass != resource.getClass()) {
|
||||
prevClass = resource.getClass();
|
||||
switch (prevClass) {
|
||||
case DXIL::ResourceClass::Sampler:
|
||||
SamplersStart = i;
|
||||
__fallthrough;
|
||||
case DXIL::ResourceClass::SRV:
|
||||
SRVsStart = i;
|
||||
__fallthrough;
|
||||
case DXIL::ResourceClass::UAV:
|
||||
UAVsStart = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IFTBOOL(resourceTable.Count() == m_Resources.size(),
|
||||
DXC_E_INCORRECT_DXIL_METADATA);
|
||||
|
||||
for (unsigned iFunc = 0; iFunc < functionTable->GetNumFunctions(); ++iFunc) {
|
||||
RDAT::FunctionReader FR = functionTable->GetItem(iFunc);
|
||||
auto &func = m_FunctionMap[FR.GetName()];
|
||||
for (unsigned iFunc = 0; iFunc < functionTable.Count(); ++iFunc) {
|
||||
auto FR = functionTable[iFunc];
|
||||
auto &func = m_FunctionMap[FR.getName()];
|
||||
DXASSERT(!func.get(), "otherwise duplicate named functions");
|
||||
Function *F = m_pModule->getFunction(FR.GetName());
|
||||
Function *F = m_pModule->getFunction(FR.getName());
|
||||
func.reset(new CFunctionReflection());
|
||||
func->Initialize(this, F);
|
||||
m_FunctionsByPtr[F] = func.get();
|
||||
orderedMap[FR.GetName()] = func.get();
|
||||
orderedMap[FR.getName()] = func.get();
|
||||
|
||||
for (unsigned iRes = 0; iRes < FR.GetNumResources(); ++iRes) {
|
||||
RDAT::ResourceReader RR = FR.GetResource(iRes);
|
||||
unsigned id = RR.GetID();
|
||||
switch (RR.GetResourceClass()) {
|
||||
for (unsigned iRes = 0; iRes < FR.getResources().Count(); ++iRes) {
|
||||
auto RR = FR.getResources()[iRes];
|
||||
unsigned id = RR.getID();
|
||||
switch (RR.getClass()) {
|
||||
case DXIL::ResourceClass::CBuffer:
|
||||
func->AddResourceReference(id);
|
||||
func->AddCBReference(id);
|
||||
|
@ -2716,20 +2735,20 @@ void DxilLibraryReflection::AddResourceDependencies() {
|
|||
break;
|
||||
case DXIL::ResourceClass::SRV:
|
||||
func->AddResourceReference(SRVsStart + id);
|
||||
if (DXIL::IsStructuredBuffer(RR.GetResourceKind())) {
|
||||
auto it = m_StructuredBufferCBsByName.find(RR.GetName());
|
||||
if (DXIL::IsStructuredBuffer(RR.getKind())) {
|
||||
auto it = m_StructuredBufferCBsByName.find(RR.getName());
|
||||
if (it != m_StructuredBufferCBsByName.end())
|
||||
func->AddCBReference(it->second);
|
||||
} else if (RR.GetResourceKind() == DXIL::ResourceKind::TBuffer) {
|
||||
auto it = m_CBsByName.find(RR.GetName());
|
||||
} else if (RR.getKind() == DXIL::ResourceKind::TBuffer) {
|
||||
auto it = m_CBsByName.find(RR.getName());
|
||||
if (it != m_CBsByName.end())
|
||||
func->AddCBReference(it->second);
|
||||
}
|
||||
break;
|
||||
case DXIL::ResourceClass::UAV:
|
||||
func->AddResourceReference(UAVsStart + id);
|
||||
if (DXIL::IsStructuredBuffer(RR.GetResourceKind())) {
|
||||
auto it = m_StructuredBufferCBsByName.find(RR.GetName());
|
||||
if (DXIL::IsStructuredBuffer(RR.getKind())) {
|
||||
auto it = m_StructuredBufferCBsByName.find(RR.getName());
|
||||
if (it != m_StructuredBufferCBsByName.end())
|
||||
func->AddCBReference(it->second);
|
||||
}
|
||||
|
|
|
@ -172,6 +172,7 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, bool HasDebugInfo) {
|
|||
M.EmitLLVMUsed();
|
||||
|
||||
M.SetAllResourcesBound(H.GetHLOptions().bAllResourcesBound);
|
||||
M.SetResMayAlias(H.GetHLOptions().bResMayAlias);
|
||||
|
||||
M.SetAutoBindingSpace(H.GetAutoBindingSpace());
|
||||
|
||||
|
|
|
@ -85,6 +85,10 @@ public:
|
|||
// Run simple optimization to legalize offsets.
|
||||
LegalizeOffsets(ssaIllegalOffsets);
|
||||
|
||||
// If 6.7 or more, permit remaining "illegal" offsets
|
||||
if (DM.GetShaderModel()->IsSM67Plus())
|
||||
return true;
|
||||
|
||||
FinalCheck(F, hlslOP);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -173,11 +173,14 @@ static void TransferEntryFunctionAttributes(Function *F, Function *NewFunc) {
|
|||
attrKind = attribute.getKindAsString();
|
||||
attrValue = attribute.getValueAsString();
|
||||
}
|
||||
bool helperLane = attributeSet.hasAttribute(AttributeSet::FunctionIndex, DXIL::kWaveOpsIncludeHelperLanesString);
|
||||
if (F == NewFunc) {
|
||||
NewFunc->removeAttributes(AttributeSet::FunctionIndex, attributeSet);
|
||||
}
|
||||
if (!attrKind.empty() && !attrValue.empty())
|
||||
NewFunc->addFnAttr(attrKind, attrValue);
|
||||
if (helperLane)
|
||||
NewFunc->addFnAttr(DXIL::kWaveOpsIncludeHelperLanesString);
|
||||
}
|
||||
|
||||
// If this returns non-null, the old function F has been stripped and can be deleted.
|
||||
|
@ -610,6 +613,54 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void convertQuadVote(Module &M, hlsl::OP *hlslOP) {
|
||||
for (auto FnIt : hlslOP->GetOpFuncList(DXIL::OpCode::QuadVote)) {
|
||||
Function *F = FnIt.second;
|
||||
if (!F)
|
||||
continue;
|
||||
for (auto UserIt = F->user_begin(); UserIt != F->user_end();) {
|
||||
CallInst *CI = cast<CallInst>(*(UserIt++));
|
||||
|
||||
IRBuilder<> B(CI);
|
||||
DXASSERT_NOMSG(CI->getOperand(1)->getType() ==
|
||||
Type::getInt1Ty(M.getContext()));
|
||||
|
||||
Type *i32Ty = Type::getInt32Ty(M.getContext());
|
||||
Value *Cond = B.CreateSExt(CI->getOperand(1), i32Ty);
|
||||
|
||||
Function *QuadOpFn = hlslOP->GetOpFunc(DXIL::OpCode::QuadOp, i32Ty);
|
||||
const std::string &OpName = hlslOP->GetOpCodeName(DXIL::OpCode::QuadOp);
|
||||
|
||||
Value *refArgs[] = {hlslOP->GetU32Const((unsigned)DXIL::OpCode::QuadOp),
|
||||
Cond, nullptr};
|
||||
refArgs[2] =
|
||||
hlslOP->GetI8Const((unsigned)DXIL::QuadOpKind::ReadAcrossX);
|
||||
Value *X = B.CreateCall(QuadOpFn, refArgs, OpName);
|
||||
refArgs[2] =
|
||||
hlslOP->GetI8Const((unsigned)DXIL::QuadOpKind::ReadAcrossY);
|
||||
Value *Y = B.CreateCall(QuadOpFn, refArgs, OpName);
|
||||
refArgs[2] =
|
||||
hlslOP->GetI8Const((unsigned)DXIL::QuadOpKind::ReadAcrossDiagonal);
|
||||
Value *Z = B.CreateCall(QuadOpFn, refArgs, OpName);
|
||||
Value *Result = nullptr;
|
||||
|
||||
uint64_t OpKind = cast<ConstantInt>(CI->getOperand(2))->getZExtValue();
|
||||
|
||||
if (OpKind == (uint64_t)DXIL::QuadVoteOpKind::All) {
|
||||
Value *XY = B.CreateAnd(X, Y);
|
||||
Result = B.CreateAnd(XY, Z);
|
||||
} else {
|
||||
DXASSERT_NOMSG(OpKind == (uint64_t)DXIL::QuadVoteOpKind::Any);
|
||||
Value *XY = B.CreateOr(X, Y);
|
||||
Result = B.CreateOr(XY, Z);
|
||||
}
|
||||
Value *Res = B.CreateTrunc(Result, Type::getInt1Ty(M.getContext()));
|
||||
CI->replaceAllUsesWith(Res);
|
||||
CI->eraseFromParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace llvm.lifetime.start/.end intrinsics with undef or zeroinitializer
|
||||
// stores (for earlier validator versions) unless the pointer is a global
|
||||
// that has an initializer.
|
||||
|
@ -734,6 +785,11 @@ public:
|
|||
patchDxil_1_6(M, hlslOP, ValMajor, ValMinor);
|
||||
}
|
||||
|
||||
// Convert quad vote
|
||||
if (DXIL::CompareVersions(DxilMajor, DxilMinor, 1, 7) < 0) {
|
||||
convertQuadVote(M, DM.GetOP());
|
||||
}
|
||||
|
||||
// Remove store undef output.
|
||||
RemoveStoreUndefOutput(M, hlslOP);
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@ uint32_t ValueTable::lookupOrAddCall(CallInst *C) {
|
|||
case DXIL::OpCode::Sample:
|
||||
case DXIL::OpCode::SampleBias:
|
||||
case DXIL::OpCode::SampleCmp:
|
||||
case DXIL::OpCode::SampleCmpLevel:
|
||||
case DXIL::OpCode::SampleCmpLevelZero:
|
||||
case DXIL::OpCode::SampleGrad:
|
||||
case DXIL::OpCode::CheckAccessFullyMapped:
|
||||
|
|
|
@ -887,10 +887,14 @@ static void ValidateCalcLODResourceDimensionCoord(CallInst *CI, DXIL::ResourceKi
|
|||
static void ValidateResourceOffset(CallInst *CI, DXIL::ResourceKind resKind,
|
||||
ArrayRef<Value *> offsets,
|
||||
ValidationContext &ValCtx) {
|
||||
const ShaderModel *pSM = ValCtx.DxilMod.GetShaderModel();
|
||||
|
||||
unsigned numOffsets = DxilResource::GetNumOffsets(resKind);
|
||||
bool hasOffset = !isa<UndefValue>(offsets[0]);
|
||||
|
||||
auto validateOffset = [&](Value *offset) {
|
||||
// 6.7 Advanced Textures allow programmable offsets
|
||||
if (pSM->IsSM67Plus()) return;
|
||||
if (ConstantInt *cOffset = dyn_cast<ConstantInt>(offset)) {
|
||||
int offset = cOffset->getValue().getSExtValue();
|
||||
if (offset > 7 || offset < -8) {
|
||||
|
@ -1631,6 +1635,16 @@ static void ValidateResourceDxilOp(CallInst *CI, DXIL::OpCode opcode,
|
|||
/*IsSampleC*/ true, ValCtx);
|
||||
ValidateDerivativeOp(CI, ValCtx);
|
||||
} break;
|
||||
case DXIL::OpCode::SampleCmpLevel: {
|
||||
// sampler must be comparison mode.
|
||||
DxilInst_SampleCmpLevel sample(CI);
|
||||
ValidateSampleInst(
|
||||
CI, sample.get_srv(), sample.get_sampler(),
|
||||
{sample.get_coord0(), sample.get_coord1(), sample.get_coord2(),
|
||||
sample.get_coord3()},
|
||||
{sample.get_offset0(), sample.get_offset1(), sample.get_offset2()},
|
||||
/*IsSampleC*/ true, ValCtx);
|
||||
} break;
|
||||
case DXIL::OpCode::SampleCmpLevelZero: {
|
||||
// sampler must be comparison mode.
|
||||
DxilInst_SampleCmpLevelZero sample(CI);
|
||||
|
@ -1769,6 +1783,8 @@ static void ValidateResourceDxilOp(CallInst *CI, DXIL::OpCode opcode,
|
|||
case DXIL::ResourceKind::Texture1DArray:
|
||||
case DXIL::ResourceKind::Texture2D:
|
||||
case DXIL::ResourceKind::Texture2DArray:
|
||||
case DXIL::ResourceKind::Texture2DMS:
|
||||
case DXIL::ResourceKind::Texture2DMSArray:
|
||||
case DXIL::ResourceKind::Texture3D:
|
||||
break;
|
||||
default:
|
||||
|
@ -1830,7 +1846,8 @@ static void ValidateResourceDxilOp(CallInst *CI, DXIL::OpCode opcode,
|
|||
ValCtx.EmitInstrError(CI, ValidationRule::InstrOffsetOnUAVLoad);
|
||||
}
|
||||
if (!isa<UndefValue>(mipLevel)) {
|
||||
ValCtx.EmitInstrError(CI, ValidationRule::InstrMipOnUAVLoad);
|
||||
if (resKind != DXIL::ResourceKind::Texture2DMS && resKind != DXIL::ResourceKind::Texture2DMSArray )
|
||||
ValCtx.EmitInstrError(CI, ValidationRule::InstrMipOnUAVLoad);
|
||||
}
|
||||
} else {
|
||||
if (resClass != DXIL::ResourceClass::SRV) {
|
||||
|
@ -2038,6 +2055,7 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
|
|||
case DXIL::OpCode::TextureGatherCmp:
|
||||
case DXIL::OpCode::Sample:
|
||||
case DXIL::OpCode::SampleCmp:
|
||||
case DXIL::OpCode::SampleCmpLevel:
|
||||
case DXIL::OpCode::SampleCmpLevelZero:
|
||||
case DXIL::OpCode::SampleBias:
|
||||
case DXIL::OpCode::SampleGrad:
|
||||
|
@ -2836,7 +2854,8 @@ static void ValidateFunctionAttribute(Function *F, ValidationContext &ValCtx) {
|
|||
continue;
|
||||
}
|
||||
StringRef kind = AttrIter->getKindAsString();
|
||||
if (!kind.equals(DXIL::kFP32DenormKindString)) {
|
||||
if (!kind.equals(DXIL::kFP32DenormKindString) &&
|
||||
!kind.equals(DXIL::kWaveOpsIncludeHelperLanesString)) {
|
||||
ValCtx.EmitFnAttributeError(F, AttrIter->getKindAsString(),
|
||||
AttrIter->getValueAsString());
|
||||
}
|
||||
|
@ -3879,8 +3898,6 @@ static void ValidateResources(ValidationContext &ValCtx) {
|
|||
}
|
||||
}
|
||||
switch (uav->GetKind()) {
|
||||
case DXIL::ResourceKind::Texture2DMS:
|
||||
case DXIL::ResourceKind::Texture2DMSArray:
|
||||
case DXIL::ResourceKind::TextureCube:
|
||||
case DXIL::ResourceKind::TextureCubeArray:
|
||||
ValCtx.EmitResourceError(uav.get(),
|
||||
|
@ -5491,16 +5508,17 @@ static void VerifyRDATMatches(_In_ ValidationContext &ValCtx,
|
|||
// otherwise, load subobject into DxilModule to generate reference RDAT.
|
||||
if (!ValCtx.DxilMod.GetSubobjects()) {
|
||||
RDAT::DxilRuntimeData rdat(pRDATData, RDATSize);
|
||||
auto *pSubobjReader = rdat.GetSubobjectTableReader();
|
||||
if (pSubobjReader && pSubobjReader->GetCount() > 0) {
|
||||
auto table = rdat.GetSubobjectTable();
|
||||
if (table && table.Count() > 0) {
|
||||
ValCtx.DxilMod.ResetSubobjects(new DxilSubobjects());
|
||||
if (!LoadSubobjectsFromRDAT(*ValCtx.DxilMod.GetSubobjects(), pSubobjReader)) {
|
||||
if (!LoadSubobjectsFromRDAT(*ValCtx.DxilMod.GetSubobjects(), rdat)) {
|
||||
ValCtx.EmitFormatError(ValidationRule::ContainerPartMatches, { PartName });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement deep validation, instead of binary comparison before 1.7 release.
|
||||
unique_ptr<DxilPartWriter> pWriter(NewRDATWriter(ValCtx.DxilMod));
|
||||
VerifyBlobPartMatches(ValCtx, PartName, pWriter.get(), pRDATData, RDATSize);
|
||||
|
||||
|
@ -5632,6 +5650,10 @@ HRESULT ValidateDxilContainerParts(llvm::Module *pModule,
|
|||
// Runtime Data (RDAT) for libraries
|
||||
case DFCC_RuntimeData:
|
||||
if (ValCtx.isLibProfile) {
|
||||
// TODO: validate without exact binary comparison of serialized data
|
||||
// - support earlier versions
|
||||
// - verify no newer record versions than known here (size no larger than newest version)
|
||||
// - verify all data makes sense and matches expectations based on module
|
||||
VerifyRDATMatches(ValCtx, GetDxilPartData(pPart), pPart->PartSize);
|
||||
} else {
|
||||
ValCtx.EmitFormatError(ValidationRule::ContainerPartInvalid, { szFourCC });
|
||||
|
|
|
@ -38,6 +38,7 @@ using namespace llvm;
|
|||
using namespace hlsl;
|
||||
|
||||
struct HLOperationLowerHelper {
|
||||
HLModule &M;
|
||||
OP &hlslOP;
|
||||
Type *voidTy;
|
||||
Type *f32Ty;
|
||||
|
@ -53,7 +54,7 @@ struct HLOperationLowerHelper {
|
|||
};
|
||||
|
||||
HLOperationLowerHelper::HLOperationLowerHelper(HLModule &HLM)
|
||||
: hlslOP(*HLM.GetOP()), dxilTypeSys(HLM.GetTypeSystem()),
|
||||
: M(HLM), hlslOP(*HLM.GetOP()), dxilTypeSys(HLM.GetTypeSystem()),
|
||||
dataLayout(DataLayout(HLM.GetHLOptions().bUseMinPrecision
|
||||
? hlsl::DXIL::kLegacyLayoutString
|
||||
: hlsl::DXIL::kNewLayoutString)) {
|
||||
|
@ -1044,6 +1045,31 @@ Value *TranslateQuadReadLaneAt(CallInst *CI, IntrinsicOp IOP,
|
|||
return TrivialDxilOperation(DXIL::OpCode::QuadReadLaneAt, refArgs,
|
||||
CI->getOperand(1)->getType(), CI, hlslOP);
|
||||
}
|
||||
|
||||
// Quad intrinsics of the form fn(val,QuadOpKind)->val
|
||||
Value *TranslateQuadAnyAll(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
|
||||
HLOperationLowerHelper &helper,
|
||||
HLObjectOperationLowerHelper *pObjHelper,
|
||||
bool &Translated) {
|
||||
hlsl::OP *hlslOP = &helper.hlslOP;
|
||||
DXIL::QuadVoteOpKind opKind;
|
||||
switch (IOP) {
|
||||
case IntrinsicOp::IOP_QuadAll:
|
||||
opKind = DXIL::QuadVoteOpKind::All;
|
||||
break;
|
||||
case IntrinsicOp::IOP_QuadAny:
|
||||
opKind = DXIL::QuadVoteOpKind::Any;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable(
|
||||
"QuadAny/QuadAll translation called with wrong isntruction");
|
||||
}
|
||||
Constant *OpArg = hlslOP->GetI8Const((unsigned)opKind);
|
||||
Value *refArgs[] = {nullptr, CI->getOperand(1), OpArg};
|
||||
return TrivialDxilOperation(DXIL::OpCode::QuadVote, refArgs,
|
||||
CI->getOperand(1)->getType(), CI, hlslOP);
|
||||
}
|
||||
|
||||
// Wave intrinsics of the form fn(val,QuadOpKind)->val
|
||||
Value *TranslateQuadReadAcross(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
|
||||
HLOperationLowerHelper &helper, HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
|
||||
|
@ -2830,6 +2856,12 @@ SampleHelper::SampleHelper(
|
|||
SetClamp(CI, HLOperandIndex::kSampleCmpClampArgIndex - cube);
|
||||
SetStatus(CI, HLOperandIndex::kSampleCmpStatusArgIndex - cube);
|
||||
break;
|
||||
case OP::OpCode::SampleCmpLevel:
|
||||
SetCompareValue(CI, HLOperandIndex::kSampleCmpCmpValArgIndex);
|
||||
TranslateOffset(CI, cube ? HLOperandIndex::kInvalidIdx : HLOperandIndex::kSampleCmpLOffsetArgIndex);
|
||||
SetLOD(CI, HLOperandIndex::kSampleCmpLLevelArgIndex);
|
||||
SetStatus(CI, HLOperandIndex::kSampleCmpStatusArgIndex - cube);
|
||||
break;
|
||||
case OP::OpCode::SampleCmpLevelZero:
|
||||
SetCompareValue(CI, HLOperandIndex::kSampleCmpLZCmpValArgIndex);
|
||||
TranslateOffset(CI, cube ? HLOperandIndex::kInvalidIdx : HLOperandIndex::kSampleCmpLZOffsetArgIndex);
|
||||
|
@ -3011,6 +3043,20 @@ Value *TranslateSample(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
|
|||
sampleHelper.clamp};
|
||||
GenerateDxilSample(CI, F, sampleArgs, sampleHelper.status, hlslOP);
|
||||
} break;
|
||||
case OP::OpCode::SampleCmpLevel: {
|
||||
Value *sampleArgs[] = {
|
||||
opArg, sampleHelper.texHandle, sampleHelper.samplerHandle,
|
||||
// Coord.
|
||||
sampleHelper.coord[0], sampleHelper.coord[1], sampleHelper.coord[2],
|
||||
sampleHelper.coord[3],
|
||||
// Offset.
|
||||
sampleHelper.offset[0], sampleHelper.offset[1], sampleHelper.offset[2],
|
||||
// CmpVal.
|
||||
sampleHelper.compareValue,
|
||||
// LOD.
|
||||
sampleHelper.lod};
|
||||
GenerateDxilSample(CI, F, sampleArgs, sampleHelper.status, hlslOP);
|
||||
} break;
|
||||
case OP::OpCode::SampleCmpLevelZero:
|
||||
default: {
|
||||
DXASSERT(opcode == OP::OpCode::SampleCmpLevelZero, "invalid sample opcode");
|
||||
|
@ -3208,6 +3254,16 @@ GatherHelper::GatherHelper(
|
|||
}
|
||||
SetStatus(CI, statusIdx);
|
||||
} break;
|
||||
case OP::OpCode::TextureGatherRaw: {
|
||||
unsigned statusIdx;
|
||||
TranslateOffset(CI, HLOperandIndex::kGatherOffsetArgIndex, offsetSize);
|
||||
// Gather all don't have sample offset version overload.
|
||||
DXASSERT(ch == GatherChannel::GatherAll, "Raw gather must use all channels");
|
||||
DXASSERT(!cube, "Raw gather can't be used with cube textures");
|
||||
DXASSERT(!hasSampleOffsets, "Raw gather doesn't support individual offsets");
|
||||
statusIdx = HLOperandIndex::kGatherStatusArgIndex;
|
||||
SetStatus(CI, statusIdx);
|
||||
} break;
|
||||
default:
|
||||
DXASSERT(0, "invalid opcode for Gather");
|
||||
break;
|
||||
|
@ -3268,6 +3324,7 @@ Value *TranslateGather(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
|
|||
switch (IOP) {
|
||||
case IntrinsicOp::MOP_Gather:
|
||||
case IntrinsicOp::MOP_GatherCmp:
|
||||
case IntrinsicOp::MOP_GatherRaw:
|
||||
ch = GatherHelper::GatherChannel::GatherAll;
|
||||
break;
|
||||
case IntrinsicOp::MOP_GatherRed:
|
||||
|
@ -3331,6 +3388,17 @@ Value *TranslateGather(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
|
|||
gatherHelper.special};
|
||||
GenerateDxilGather(CI, F, gatherArgs, gatherHelper, hlslOP);
|
||||
} break;
|
||||
case OP::OpCode::TextureGatherRaw: {
|
||||
Value *gatherArgs[] = {
|
||||
opArg, gatherHelper.texHandle, gatherHelper.samplerHandle,
|
||||
// Coord.
|
||||
gatherHelper.coord[0], gatherHelper.coord[1], gatherHelper.coord[2],
|
||||
gatherHelper.coord[3],
|
||||
// Offset.
|
||||
gatherHelper.offset[0], gatherHelper.offset[1]};
|
||||
GenerateDxilGather(CI, F, gatherArgs, gatherHelper, hlslOP);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DXASSERT(0, "invalid opcode for Gather");
|
||||
break;
|
||||
|
@ -3416,8 +3484,6 @@ static Value* TranslateWriteSamplerFeedback(CallInst* CI, IntrinsicOp IOP, OP::O
|
|||
struct ResLoadHelper {
|
||||
ResLoadHelper(CallInst *CI, DxilResource::Kind RK, DxilResourceBase::Class RC,
|
||||
Value *h, IntrinsicOp IOP, bool bForSubscript=false);
|
||||
ResLoadHelper(CallInst *CI, DxilResource::Kind RK, DxilResourceBase::Class RC,
|
||||
Value *h, Value *mip);
|
||||
// For double subscript.
|
||||
ResLoadHelper(Instruction *ldInst, Value *h, Value *idx, Value *mip)
|
||||
: opcode(OP::OpCode::TextureLoad),
|
||||
|
@ -3495,6 +3561,16 @@ ResLoadHelper::ResLoadHelper(CallInst *CI, DxilResource::Kind RK,
|
|||
|
||||
if (argc > statusIdx)
|
||||
status = CI->getArgOperand(statusIdx);
|
||||
} else if (RC == DxilResourceBase::Class::UAV &&
|
||||
(RK == DxilResource::Kind::Texture2DMS ||
|
||||
RK == DxilResource::Kind::Texture2DMSArray)) {
|
||||
unsigned statusIdx = HLOperandIndex::kTex2DMSLoadStatusOpIdx;
|
||||
mipLevel =
|
||||
CI->getArgOperand(HLOperandIndex::kTex2DMSLoadSampleIdxOpIdx);
|
||||
|
||||
if (argc > statusIdx)
|
||||
status = CI->getArgOperand(statusIdx);
|
||||
|
||||
} else {
|
||||
const unsigned kStatusIdx = HLOperandIndex::kRWTexLoadStatusOpIdx;
|
||||
|
||||
|
@ -3508,30 +3584,6 @@ ResLoadHelper::ResLoadHelper(CallInst *CI, DxilResource::Kind RK,
|
|||
}
|
||||
}
|
||||
|
||||
ResLoadHelper::ResLoadHelper(CallInst *CI, DxilResource::Kind RK,
|
||||
DxilResourceBase::Class RC, Value *hdl, Value *mip)
|
||||
: handle(hdl), offset(nullptr), status(nullptr) {
|
||||
DXASSERT(RK != DxilResource::Kind::RawBuffer &&
|
||||
RK != DxilResource::Kind::TypedBuffer &&
|
||||
RK != DxilResource::Kind::Invalid,
|
||||
"invalid resource kind");
|
||||
opcode = OP::OpCode::TextureLoad;
|
||||
|
||||
retVal = CI;
|
||||
mipLevel = mip;
|
||||
|
||||
const unsigned kAddrIdx = HLOperandIndex::kMipLoadAddrOpIdx;
|
||||
addr = CI->getArgOperand(kAddrIdx);
|
||||
unsigned argc = CI->getNumArgOperands();
|
||||
|
||||
const unsigned kOffsetIdx = HLOperandIndex::kMipLoadOffsetOpIdx;
|
||||
const unsigned kStatusIdx = HLOperandIndex::kMipLoadStatusOpIdx;
|
||||
if (argc > kOffsetIdx)
|
||||
offset = CI->getArgOperand(kOffsetIdx);
|
||||
|
||||
if (argc > kStatusIdx)
|
||||
status = CI->getArgOperand(kStatusIdx);
|
||||
}
|
||||
|
||||
void TranslateStructBufSubscript(CallInst *CI, Value *handle, Value *status,
|
||||
hlsl::OP *OP, HLResource::Kind RK, const DataLayout &DL);
|
||||
|
@ -3819,7 +3871,8 @@ void Split64bitValForStore(Type *EltTy, ArrayRef<Value *> vals, unsigned size,
|
|||
}
|
||||
|
||||
void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
|
||||
Value *offset, IRBuilder<> &Builder, hlsl::OP *OP) {
|
||||
Value *offset, IRBuilder<> &Builder, hlsl::OP *OP,
|
||||
Value *sampIdx = nullptr) {
|
||||
Type *Ty = val->getType();
|
||||
|
||||
// This function is no longer used for lowering stores to a
|
||||
|
@ -3838,12 +3891,17 @@ void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
|
|||
case DxilResource::Kind::Invalid:
|
||||
DXASSERT(0, "invalid resource kind");
|
||||
break;
|
||||
case DxilResource::Kind::Texture2DMS:
|
||||
case DxilResource::Kind::Texture2DMSArray:
|
||||
opcode = OP::OpCode::TextureStoreSample;
|
||||
break;
|
||||
default:
|
||||
opcode = OP::OpCode::TextureStore;
|
||||
break;
|
||||
}
|
||||
|
||||
bool isTyped = opcode == OP::OpCode::TextureStore ||
|
||||
opcode == OP::OpCode::TextureStoreSample ||
|
||||
RK == DxilResource::Kind::TypedBuffer;
|
||||
|
||||
Type *i32Ty = Builder.getInt32Ty();
|
||||
|
@ -3996,7 +4054,7 @@ void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
|
|||
size = std::min((j + 1) * MaxStoreElemCount, Ty->getVectorNumElements()) - (j * MaxStoreElemCount);
|
||||
}
|
||||
DXASSERT(size <= 2, "raw/typed buffer only allow 4 dwords");
|
||||
unsigned val0OpIdx = opcode == DXIL::OpCode::TextureStore
|
||||
unsigned val0OpIdx = opcode == DXIL::OpCode::TextureStore || opcode == DXIL::OpCode::TextureStoreSample
|
||||
? DXIL::OperandIndex::kTextureStoreVal0OpIdx
|
||||
: DXIL::OperandIndex::kBufferStoreVal0OpIdx;
|
||||
Value* V0 = storeArgsList[j][val0OpIdx];
|
||||
|
@ -4024,6 +4082,9 @@ void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
|
|||
storeArgsList[j].emplace_back(OP->GetU8Const(mask)); // mask
|
||||
if (opcode == DXIL::OpCode::RawBufferStore)
|
||||
storeArgsList[j].emplace_back(Alignment); // alignment only for raw buffer
|
||||
else if (opcode == DXIL::OpCode::TextureStoreSample) {
|
||||
storeArgsList[j].emplace_back(sampIdx?sampIdx:Builder.getInt32(0)); // sample idx only for MS textures
|
||||
}
|
||||
Builder.CreateCall(F, storeArgsList[j]);
|
||||
}
|
||||
}
|
||||
|
@ -5498,6 +5559,8 @@ IntrinsicLower gLowerTable[] = {
|
|||
{IntrinsicOp::IOP_ProcessTriTessFactorsAvg, TranslateProcessTessFactors, DXIL::OpCode::NumOpCodes},
|
||||
{IntrinsicOp::IOP_ProcessTriTessFactorsMax, TranslateProcessTessFactors, DXIL::OpCode::NumOpCodes},
|
||||
{IntrinsicOp::IOP_ProcessTriTessFactorsMin, TranslateProcessTessFactors, DXIL::OpCode::NumOpCodes},
|
||||
{IntrinsicOp::IOP_QuadAll, TranslateQuadAnyAll, DXIL::OpCode::QuadVote},
|
||||
{IntrinsicOp::IOP_QuadAny, TranslateQuadAnyAll, DXIL::OpCode::QuadVote},
|
||||
{IntrinsicOp::IOP_QuadReadAcrossDiagonal, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
|
||||
{IntrinsicOp::IOP_QuadReadAcrossX, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
|
||||
{IntrinsicOp::IOP_QuadReadAcrossY, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
|
||||
|
@ -5674,6 +5737,7 @@ IntrinsicLower gLowerTable[] = {
|
|||
{IntrinsicOp::MOP_Sample, TranslateSample, DXIL::OpCode::Sample},
|
||||
{IntrinsicOp::MOP_SampleBias, TranslateSample, DXIL::OpCode::SampleBias},
|
||||
{IntrinsicOp::MOP_SampleCmp, TranslateSample, DXIL::OpCode::SampleCmp},
|
||||
{IntrinsicOp::MOP_SampleCmpLevel, TranslateSample, DXIL::OpCode::SampleCmpLevel},
|
||||
{IntrinsicOp::MOP_SampleCmpLevelZero, TranslateSample, DXIL::OpCode::SampleCmpLevelZero},
|
||||
{IntrinsicOp::MOP_SampleGrad, TranslateSample, DXIL::OpCode::SampleGrad},
|
||||
{IntrinsicOp::MOP_SampleLevel, TranslateSample, DXIL::OpCode::SampleLevel},
|
||||
|
@ -5686,6 +5750,7 @@ IntrinsicLower gLowerTable[] = {
|
|||
{IntrinsicOp::MOP_GatherCmpGreen, TranslateGather, DXIL::OpCode::TextureGatherCmp},
|
||||
{IntrinsicOp::MOP_GatherCmpRed, TranslateGather, DXIL::OpCode::TextureGatherCmp},
|
||||
{IntrinsicOp::MOP_GatherGreen, TranslateGather, DXIL::OpCode::TextureGather},
|
||||
{IntrinsicOp::MOP_GatherRaw, TranslateGather, DXIL::OpCode::TextureGatherRaw},
|
||||
{IntrinsicOp::MOP_GatherRed, TranslateGather, DXIL::OpCode::TextureGather},
|
||||
{IntrinsicOp::MOP_GetSamplePosition, TranslateGetSamplePosition, DXIL::OpCode::NumOpCodes},
|
||||
{IntrinsicOp::MOP_Load2, TranslateResourceLoad, DXIL::OpCode::NumOpCodes},
|
||||
|
@ -7841,13 +7906,20 @@ void TranslateHLSubscript(CallInst *CI, HLSubscriptOpcode opcode,
|
|||
CI->getArgOperand(HLOperandIndex::kDoubleSubscriptMipLevelOpIdx);
|
||||
|
||||
auto U = CI->user_begin();
|
||||
DXASSERT(CI->hasOneUse(), "subscript should only has one use");
|
||||
// TODO: support store.
|
||||
Instruction *ldInst = cast<Instruction>(*U);
|
||||
ResLoadHelper ldHelper(ldInst, handle, coord, mipLevel);
|
||||
DXASSERT(CI->hasOneUse(), "subscript should only have one use");
|
||||
IRBuilder<> Builder(CI);
|
||||
TranslateLoad(ldHelper, RK, Builder, hlslOP, helper.dataLayout);
|
||||
ldInst->eraseFromParent();
|
||||
if (LoadInst *ldInst = dyn_cast<LoadInst>(*U)) {
|
||||
ResLoadHelper ldHelper(ldInst, handle, coord, mipLevel);
|
||||
TranslateLoad(ldHelper, RK, Builder, hlslOP, helper.dataLayout);
|
||||
ldInst->eraseFromParent();
|
||||
} else {
|
||||
StoreInst *stInst = cast<StoreInst>(*U);
|
||||
Value *val = stInst->getValueOperand();
|
||||
TranslateStore(RK, handle, val,
|
||||
CI->getArgOperand(HLOperandIndex::kStoreOffsetOpIdx),
|
||||
Builder, hlslOP, mipLevel);
|
||||
stInst->eraseFromParent();
|
||||
}
|
||||
Translated = true;
|
||||
return;
|
||||
} else {
|
||||
|
|
|
@ -10,6 +10,7 @@ add_dxilconv_project_test_library(dxilconv-tests SHARED
|
|||
|
||||
target_link_libraries(dxilconv-tests PRIVATE
|
||||
HLSLTestLib
|
||||
LLVMDxilContainer # for RDAT used by HLSLTestLib
|
||||
LLVMDxcSupport
|
||||
LLVMMSSupport
|
||||
LLVMSupport
|
||||
|
|
|
@ -912,6 +912,11 @@ def HLSLWaveSize : InheritableAttr {
|
|||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def HLSLWaveOpsIncludeHelperLanes : InheritableAttr {
|
||||
let Spellings = [CXX11<"", "waveopsincludehelperlanes", 2015>];
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
// HLSL Change Ends
|
||||
|
||||
// SPIRV Change Starts
|
||||
|
|
|
@ -703,7 +703,7 @@ CXXRecordDecl* hlsl::DeclareTemplateTypeWithHandleInDeclContext(
|
|||
// Only need array type for inputpatch and outputpatch.
|
||||
// Avoid Texture2DMS which may use 0 count.
|
||||
// TODO: use hlsl types to do the check.
|
||||
!name.startswith("Texture")) {
|
||||
!name.startswith("Texture") && !name.startswith("RWTexture")) {
|
||||
Expr *countExpr = DeclRefExpr::Create(
|
||||
context, NestedNameSpecifierLoc(), NoLoc, countTemplateParamDecl, false,
|
||||
DeclarationNameInfo(countTemplateParamDecl->getDeclName(), NoLoc),
|
||||
|
|
|
@ -388,6 +388,7 @@ CGMSHLSLRuntime::CGMSHLSLRuntime(CodeGenModule &CGM)
|
|||
opts.bDisableOptimizations = CGM.getCodeGenOpts().DisableLLVMOpts;
|
||||
opts.bLegacyCBufferLoad = !CGM.getCodeGenOpts().HLSLNotUseLegacyCBufLoad;
|
||||
opts.bAllResourcesBound = CGM.getCodeGenOpts().HLSLAllResourcesBound;
|
||||
opts.bResMayAlias = CGM.getCodeGenOpts().HLSLResMayAlias;
|
||||
opts.PackingStrategy = CGM.getCodeGenOpts().HLSLSignaturePackingStrategy;
|
||||
opts.bLegacyResourceReservation = CGM.getCodeGenOpts().HLSLLegacyResourceReservation;
|
||||
opts.bForceZeroStoreLifetimes = CGM.getCodeGenOpts().HLSLForceZeroStoreLifetimes;
|
||||
|
@ -1558,6 +1559,12 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
|
|||
}
|
||||
|
||||
const ShaderModel *SM = m_pHLModule->GetShaderModel();
|
||||
if (auto *Attr = FD->getAttr<HLSLWaveOpsIncludeHelperLanesAttr>()) {
|
||||
if (SM->IsSM67Plus() &&
|
||||
(funcProps->shaderKind == DXIL::ShaderKind::Pixel ||
|
||||
(isEntry && SM->GetKind() == DXIL::ShaderKind::Pixel)))
|
||||
F->addFnAttr(DXIL::kWaveOpsIncludeHelperLanesString);
|
||||
}
|
||||
if (isEntry) {
|
||||
funcProps->shaderKind = SM->GetKind();
|
||||
if (funcProps->shaderKind == DXIL::ShaderKind::Mesh) {
|
||||
|
|
|
@ -216,12 +216,18 @@ enum ArBasicKind {
|
|||
// Heap Resource
|
||||
AR_OBJECT_HEAP_RESOURCE,
|
||||
AR_OBJECT_HEAP_SAMPLER,
|
||||
|
||||
AR_OBJECT_RWTEXTURE2DMS,
|
||||
AR_OBJECT_RWTEXTURE2DMS_ARRAY,
|
||||
|
||||
AR_BASIC_MAXIMUM_COUNT
|
||||
};
|
||||
|
||||
#define AR_BASIC_TEXTURE_MS_CASES \
|
||||
case AR_OBJECT_TEXTURE2DMS: \
|
||||
case AR_OBJECT_TEXTURE2DMS_ARRAY
|
||||
case AR_OBJECT_TEXTURE2DMS_ARRAY: \
|
||||
case AR_OBJECT_RWTEXTURE2DMS: \
|
||||
case AR_OBJECT_RWTEXTURE2DMS_ARRAY
|
||||
|
||||
#define AR_BASIC_NON_TEXTURE_MS_CASES \
|
||||
case AR_OBJECT_TEXTURE1D: \
|
||||
|
@ -506,6 +512,10 @@ const UINT g_uBasicKindProps[] =
|
|||
0, //AR_OBJECT_RAY_QUERY,
|
||||
0, //AR_OBJECT_HEAP_RESOURCE,
|
||||
0, //AR_OBJECT_HEAP_SAMPLER,
|
||||
|
||||
BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE2DMS
|
||||
BPROP_OBJECT | BPROP_RWBUFFER, // AR_OBJECT_RWTEXTURE2DMS_ARRAY
|
||||
|
||||
// AR_BASIC_MAXIMUM_COUNT
|
||||
};
|
||||
|
||||
|
@ -1427,6 +1437,9 @@ const ArBasicKind g_ArBasicKindsAsTypes[] =
|
|||
AR_OBJECT_RAY_QUERY,
|
||||
AR_OBJECT_HEAP_RESOURCE,
|
||||
AR_OBJECT_HEAP_SAMPLER,
|
||||
|
||||
AR_OBJECT_RWTEXTURE2DMS, // RWTexture2DMS
|
||||
AR_OBJECT_RWTEXTURE2DMS_ARRAY, // RWTexture2DMSArray
|
||||
};
|
||||
|
||||
// Count of template arguments for basic kind of objects that look like templates (one or more type arguments).
|
||||
|
@ -1519,6 +1532,9 @@ const uint8_t g_ArBasicKindsTemplateCount[] =
|
|||
1, // AR_OBJECT_RAY_QUERY,
|
||||
0, // AR_OBJECT_HEAP_RESOURCE,
|
||||
0, // AR_OBJECT_HEAP_SAMPLER,
|
||||
|
||||
2, // AR_OBJECT_RWTEXTURE2DMS
|
||||
2, // AR_OBJECT_RWTEXTURE2DMS_ARRAY
|
||||
};
|
||||
|
||||
C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsTemplateCount));
|
||||
|
@ -1621,6 +1637,9 @@ const SubscriptOperatorRecord g_ArBasicKindsSubscripts[] =
|
|||
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_RAY_QUERY,
|
||||
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_HEAP_RESOURCE,
|
||||
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_HEAP_SAMPLER,
|
||||
|
||||
{ 2, MipsFalse, SampleTrue }, // AR_OBJECT_RWTEXTURE2DMS (RWTexture2DMS)
|
||||
{ 3, MipsFalse, SampleTrue }, // AR_OBJECT_RWTEXTURE2DMS_ARRAY (RWTexture2DMSArray)
|
||||
};
|
||||
|
||||
C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsSubscripts));
|
||||
|
@ -1746,6 +1765,9 @@ const char* g_ArBasicTypeNames[] =
|
|||
"RayQuery",
|
||||
"HEAP_Resource",
|
||||
"HEAP_Sampler",
|
||||
|
||||
"RWTexture2DMS",
|
||||
"RWTexture2DMSArray",
|
||||
};
|
||||
|
||||
C_ASSERT(_countof(g_ArBasicTypeNames) == AR_BASIC_MAXIMUM_COUNT);
|
||||
|
@ -2380,6 +2402,14 @@ void GetIntrinsicMethods(ArBasicKind kind, _Outptr_result_buffer_(*intrinsicCoun
|
|||
*intrinsics = g_RayQueryMethods;
|
||||
*intrinsicCount = _countof(g_RayQueryMethods);
|
||||
break;
|
||||
case AR_OBJECT_RWTEXTURE2DMS:
|
||||
*intrinsics = g_RWTexture2DMSMethods;
|
||||
*intrinsicCount = _countof(g_RWTexture2DMSMethods);
|
||||
break;
|
||||
case AR_OBJECT_RWTEXTURE2DMS_ARRAY:
|
||||
*intrinsics = g_RWTexture2DMSArrayMethods;
|
||||
*intrinsicCount = _countof(g_RWTexture2DMSArrayMethods);
|
||||
break;
|
||||
// SPIRV change starts
|
||||
#ifdef ENABLE_SPIRV_CODEGEN
|
||||
case AR_OBJECT_VK_SUBPASS_INPUT:
|
||||
|
@ -3386,8 +3416,8 @@ private:
|
|||
"of the position parameter");
|
||||
|
||||
bool isReadWrite = GetBasicKindProps(kind) & BPROP_RWBUFFER;
|
||||
DXASSERT(!isReadWrite || (op.HasMips == false && op.HasSample == false),
|
||||
"read/write objects don't have .mips or .sample members");
|
||||
DXASSERT(!isReadWrite || (op.HasMips == false),
|
||||
"read/write objects don't have .mips members");
|
||||
|
||||
// Return early if there is no work to be done.
|
||||
if (op.SubscriptCardinality == 0) {
|
||||
|
@ -4340,6 +4370,8 @@ public:
|
|||
case AR_OBJECT_ACCELERATION_STRUCT:
|
||||
case AR_OBJECT_RAY_DESC:
|
||||
case AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES:
|
||||
case AR_OBJECT_RWTEXTURE2DMS:
|
||||
case AR_OBJECT_RWTEXTURE2DMS_ARRAY:
|
||||
{
|
||||
const ArBasicKind* match = std::find(g_ArBasicKindsAsTypes, &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], kind);
|
||||
DXASSERT(match != &g_ArBasicKindsAsTypes[_countof(g_ArBasicKindsAsTypes)], "otherwise can't find constant in basic kinds");
|
||||
|
@ -5708,12 +5740,18 @@ HLSLExternalSource::IsValidateObjectElement(const HLSL_INTRINSIC *pIntrinsic,
|
|||
case IntrinsicOp::MOP_Sample:
|
||||
case IntrinsicOp::MOP_SampleBias:
|
||||
case IntrinsicOp::MOP_SampleCmp:
|
||||
case IntrinsicOp::MOP_SampleCmpLevel:
|
||||
case IntrinsicOp::MOP_SampleCmpLevelZero:
|
||||
case IntrinsicOp::MOP_SampleGrad:
|
||||
case IntrinsicOp::MOP_SampleLevel: {
|
||||
ArBasicKind kind = GetTypeElementKind(objectElement);
|
||||
UINT uBits = GET_BPROP_BITS(kind);
|
||||
return IS_BASIC_FLOAT(kind) && uBits != BPROP_BITS64;
|
||||
}
|
||||
case IntrinsicOp::MOP_GatherRaw: {
|
||||
ArBasicKind kind = GetTypeElementKind(objectElement);
|
||||
UINT numEles = GetNumElements(objectElement);
|
||||
return IS_BASIC_UINT(kind) && numEles == 1;
|
||||
} break;
|
||||
default:
|
||||
return true;
|
||||
|
@ -9831,8 +9869,11 @@ Sema::TemplateDeductionResult HLSLExternalSource::DeduceTemplateArgumentsForHLSL
|
|||
FunctionTemplate->getCanonicalDecl());
|
||||
|
||||
if (IsBuiltinTable(tableName) && !IsValidateObjectElement(*cursor, objectElement)) {
|
||||
UINT numEles = GetNumElements(objectElement);
|
||||
std::string typeName(g_ArBasicTypeNames[GetTypeElementKind(objectElement)]);
|
||||
if (numEles > 1) typeName += std::to_string(numEles);
|
||||
m_sema->Diag(Args[0]->getExprLoc(), diag::err_hlsl_invalid_resource_type_on_intrinsic) <<
|
||||
nameIdentifier << g_ArBasicTypeNames[GetTypeElementKind(objectElement)];
|
||||
nameIdentifier << typeName;
|
||||
}
|
||||
return Sema::TemplateDeductionResult::TDK_Success;
|
||||
}
|
||||
|
@ -12063,6 +12104,9 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
|
|||
declAttr = ::new (S.Context) HLSLWaveSizeAttr(A.getRange(), S.Context,
|
||||
ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
|
||||
break;
|
||||
case AttributeList::AT_HLSLWaveOpsIncludeHelperLanes:
|
||||
declAttr = ::new (S.Context) HLSLWaveOpsIncludeHelperLanesAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
|
||||
break;
|
||||
default:
|
||||
Handled = false;
|
||||
break; // SPIRV Change: was return;
|
||||
|
|
|
@ -2669,6 +2669,7 @@
|
|||
<Shader Name="CS66" Target="cs_6_6" EntryPoint="CSMain65" Text="@CS"/>
|
||||
<Shader Name="VS" Target="vs_6_0" EntryPoint="VSMain" Text="@CS"/>
|
||||
<Shader Name="PS" Target="ps_6_0" EntryPoint="PSMain" Text="@CS"/>
|
||||
<Shader Name="PS67" Target="ps_6_7" EntryPoint="PSMain65" Text="@CS"/>
|
||||
<Shader Name="CS" Target="cs_6_0" EntryPoint="CSMain">
|
||||
<![CDATA[
|
||||
#ifdef ISHELPERLANE_PLACEHOLDER
|
||||
|
@ -2873,6 +2874,9 @@
|
|||
return uint4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 1);
|
||||
}
|
||||
|
||||
#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 7)
|
||||
[waveopsincludehelperlanes]
|
||||
#endif
|
||||
uint4 PSMain65(PSInput input) : SV_TARGET {
|
||||
HelperLaneWaveTestResult tr;
|
||||
tr.sm60_wave = RunHelperLaneWaveTests60();
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
// RUN: %dxc -T lib_6_7 %s | %D3DReflect %s | FileCheck %s
|
||||
|
||||
|
||||
// CHECK:DxilRuntimeData (size = 180 bytes):
|
||||
// CHECK: StringBuffer (size = 24 bytes)
|
||||
// CHECK: IndexTable (size = 8 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 32 bytes) ResourceTable[1] = {
|
||||
// CHECK: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: TypedBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 0
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "g_tex"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[1] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "amplification"
|
||||
// CHECK: UnmangledName: "amplification"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: TypedBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 0
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "g_tex"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Amplification
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 16384
|
||||
// CHECK: MinShaderTarget: 917605
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK:ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
// CHECK: Flags: 0
|
||||
// CHECK: FunctionCount: 1
|
||||
// CHECK: ID3D12FunctionReflection:
|
||||
// CHECK: D3D12_FUNCTION_DESC: Name: amplification
|
||||
// CHECK: Shader Version: Amplification 6.7
|
||||
// CHECK: Flags: 0
|
||||
// CHECK: ConstantBuffers: 0
|
||||
// CHECK: BoundResources: 1
|
||||
// CHECK: FunctionParameterCount: 0
|
||||
// CHECK: HasReturn: FALSE
|
||||
// CHECK: Bound Resources:
|
||||
// CHECK: D3D12_SHADER_INPUT_BIND_DESC: Name: g_tex
|
||||
// CHECK: Type: D3D_SIT_TEXTURE
|
||||
// CHECK: uID: 0
|
||||
// CHECK: BindCount: 1
|
||||
// CHECK: BindPoint: 0
|
||||
// CHECK: Space: 0
|
||||
// CHECK: ReturnType: D3D_RETURN_TYPE_FLOAT
|
||||
// CHECK: Dimension: D3D_SRV_DIMENSION_BUFFER
|
||||
// CHECK: NumSamples (or stride): 4294967295
|
||||
// CHECK: uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
|
||||
|
||||
struct MeshPayload
|
||||
{
|
||||
float4 data;
|
||||
};
|
||||
|
||||
groupshared MeshPayload pld;
|
||||
groupshared float4 gs_bias;
|
||||
Buffer<float4> g_tex : register(t0);
|
||||
|
||||
[shader("amplification")]
|
||||
[numthreads(4,1,1)]
|
||||
void amplification(uint gtid : SV_GroupIndex)
|
||||
{
|
||||
pld.data = g_tex[gtid]*gs_bias;
|
||||
gs_bias += 0.1;
|
||||
DispatchMesh(1,1,1,pld);
|
||||
}
|
|
@ -5,6 +5,76 @@
|
|||
|
||||
// CHECK-NOT: CBufUnused
|
||||
|
||||
// CHECK: DxilRuntimeData (size = 320 bytes):
|
||||
// CHECK: StringBuffer (size = 44 bytes)
|
||||
// CHECK: IndexTable (size = 20 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 32 bytes) ResourceTable[3] = {
|
||||
// CHECK: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: CBuffer
|
||||
// CHECK: Kind: CBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "CBuf0"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: CBuffer
|
||||
// CHECK: Kind: CBuffer
|
||||
// CHECK: ID: 1
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 1
|
||||
// CHECK: UpperBound: 1
|
||||
// CHECK: Name: "CBuf1"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <2:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: CBuffer
|
||||
// CHECK: Kind: CBuffer
|
||||
// CHECK: ID: 2
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 2
|
||||
// CHECK: UpperBound: 4294967295
|
||||
// CHECK: Name: "CBuf2"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[2] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?foo@@YAMXZ"
|
||||
// CHECK: UnmangledName: "foo"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "main"
|
||||
// CHECK: UnmangledName: "main"
|
||||
// CHECK: Resources: <2:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <2:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Vertex
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 2
|
||||
// CHECK: MinShaderTarget: 65632
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf1
|
||||
// CHECK: Num Variables: 1
|
||||
// CHECK: D3D12_SHADER_VARIABLE_DESC: Name: CBuf1
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// RUN: %dxc -T lib_6_5 %s | %D3DReflect %s | FileCheck %s
|
||||
|
||||
// CHECK:DxilRuntimeData (size = 220 bytes):
|
||||
// CHECK: StringBuffer (size = 28 bytes)
|
||||
// CHECK: IndexTable (size = 12 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 32 bytes) ResourceTable[2] = {
|
||||
// CHECK: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: TypedBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 0
|
||||
// CHECK: LowerBound: 1
|
||||
// CHECK: UpperBound: 1
|
||||
// CHECK: Name: "inputs"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: UAV
|
||||
// CHECK: Kind: TypedBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 0
|
||||
// CHECK: LowerBound: 1
|
||||
// CHECK: UpperBound: 1
|
||||
// CHECK: Name: "g_Intensities"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[1] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "main"
|
||||
// CHECK: UnmangledName: "main"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Compute
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32
|
||||
// CHECK: MinShaderTarget: 327776
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK:ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
// CHECK: Creator: <nullptr>
|
||||
// CHECK: Flags: 0
|
||||
// CHECK: FunctionCount: 1
|
||||
// CHECK: ID3D12FunctionReflection:
|
||||
// CHECK: D3D12_FUNCTION_DESC: Name: main
|
||||
// CHECK: Shader Version: Compute 6.5
|
||||
// CHECK: Creator: <nullptr>
|
||||
// CHECK: Flags: 0
|
||||
// CHECK: ConstantBuffers: 0
|
||||
// CHECK: BoundResources: 2
|
||||
// CHECK: FunctionParameterCount: 0
|
||||
// CHECK: HasReturn: FALSE
|
||||
// CHECK: Bound Resources:
|
||||
// CHECK: D3D12_SHADER_INPUT_BIND_DESC: Name: inputs
|
||||
// CHECK: Type: D3D_SIT_TEXTURE
|
||||
// CHECK: uID: 0
|
||||
// CHECK: BindCount: 1
|
||||
// CHECK: BindPoint: 1
|
||||
// CHECK: Space: 0
|
||||
// CHECK: ReturnType: D3D_RETURN_TYPE_SINT
|
||||
// CHECK: Dimension: D3D_SRV_DIMENSION_BUFFER
|
||||
// CHECK: NumSamples (or stride): 4294967295
|
||||
// CHECK: uFlags: 0
|
||||
// CHECK: D3D12_SHADER_INPUT_BIND_DESC: Name: g_Intensities
|
||||
// CHECK: Type: D3D_SIT_UAV_RWTYPED
|
||||
// CHECK: uID: 0
|
||||
// CHECK: BindCount: 1
|
||||
// CHECK: BindPoint: 1
|
||||
// CHECK: Space: 0
|
||||
// CHECK: ReturnType: D3D_RETURN_TYPE_SINT
|
||||
// CHECK: Dimension: D3D_SRV_DIMENSION_BUFFER
|
||||
// CHECK: NumSamples (or stride): 4294967295
|
||||
// CHECK: uFlags: 0
|
||||
|
||||
struct Foo {
|
||||
int a[2];
|
||||
int d[2];
|
||||
};
|
||||
|
||||
Buffer<Foo> inputs : register(t1);
|
||||
RWBuffer< int > g_Intensities : register(u1);
|
||||
|
||||
groupshared Foo sharedData;
|
||||
|
||||
[ numthreads( 64, 2, 2 ) ]
|
||||
void main( uint GI : SV_GroupIndex)
|
||||
{
|
||||
if (GI==0)
|
||||
sharedData = inputs[GI];
|
||||
int rtn;
|
||||
InterlockedAdd(sharedData.d[0], g_Intensities[GI], rtn);
|
||||
g_Intensities[GI] = rtn + sharedData.d[0];
|
||||
}
|
|
@ -21,7 +21,91 @@ float4 PSMain(int idx : INDEX) : SV_Target {
|
|||
return T2[T0.Load(idx)].f;
|
||||
}
|
||||
|
||||
|
||||
// CHECK: DxilRuntimeData (size = 444 bytes):
|
||||
// CHECK: StringBuffer (size = 124 bytes)
|
||||
// CHECK: IndexTable (size = 20 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 32 bytes) ResourceTable[3] = {
|
||||
// CHECK: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: TypedBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "T0"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: Texture2D
|
||||
// CHECK: ID: 1
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 1
|
||||
// CHECK: UpperBound: 1
|
||||
// CHECK: Name: "T1"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <2:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: StructuredBuffer
|
||||
// CHECK: ID: 2
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 2
|
||||
// CHECK: UpperBound: 2
|
||||
// CHECK: Name: "T2"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[3] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?VS_RENAMED@@YA?AV?$vector@M$03@@V?$vector@H$02@@@Z"
|
||||
// CHECK: UnmangledName: "VS_RENAMED"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?PS_RENAMED@@YA?AV?$vector@M$03@@H@Z"
|
||||
// CHECK: UnmangledName: "PS_RENAMED"
|
||||
// CHECK: Resources: <2:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <2:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <2:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "PS_RENAMED"
|
||||
// CHECK: UnmangledName: "PS_RENAMED"
|
||||
// CHECK: Resources: <2:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <2:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Pixel
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 1
|
||||
// CHECK: MinShaderTarget: 96
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
|
|
|
@ -26,6 +26,94 @@ void RayGen() {
|
|||
U0.Store(idx.y * dim.x * 4 + idx.x * 4, idx.x ^ idx.y);
|
||||
}
|
||||
|
||||
// CHECK: DxilRuntimeData (size = 456 bytes):
|
||||
// CHECK: StringBuffer (size = 128 bytes)
|
||||
// CHECK: IndexTable (size = 16 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 32 bytes) ResourceTable[2] = {
|
||||
// CHECK: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: Texture2D
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "T1"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: UAV
|
||||
// CHECK: Kind: RawBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "U0"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[4] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?RayGen1@@YAXXZ"
|
||||
// CHECK: UnmangledName: "RayGen1"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: RayGeneration
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 128
|
||||
// CHECK: MinShaderTarget: 458851
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?VS_RENAMED@@YA?AV?$vector@M$03@@V?$vector@H$02@@@Z"
|
||||
// CHECK: UnmangledName: "VS_RENAMED"
|
||||
// CHECK: Resources: <2:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <2:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?RayGen2@@YAXXZ"
|
||||
// CHECK: UnmangledName: "RayGen2"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: RayGeneration
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 128
|
||||
// CHECK: MinShaderTarget: 458851
|
||||
// CHECK: }
|
||||
// CHECK: <3:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "VSMain"
|
||||
// CHECK: UnmangledName: "VSMain"
|
||||
// CHECK: Resources: <2:RecordArrayRef<RuntimeDataResourceInfo>[1]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Vertex
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 2
|
||||
// CHECK: MinShaderTarget: 65632
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
|
|
|
@ -17,6 +17,130 @@ float4 PSMain(int idx : INDEX) : SV_Target {
|
|||
return T2[T0.Load(idx)].f;
|
||||
}
|
||||
|
||||
// CHECK: DxilRuntimeData (size = 572 bytes):
|
||||
// CHECK: StringBuffer (size = 160 bytes)
|
||||
// CHECK: IndexTable (size = 12 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 32 bytes) ResourceTable[2] = {
|
||||
// CHECK: <0:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: TypedBuffer
|
||||
// CHECK: ID: 0
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 0
|
||||
// CHECK: UpperBound: 0
|
||||
// CHECK: Name: "T0"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataResourceInfo> = {
|
||||
// CHECK: Class: SRV
|
||||
// CHECK: Kind: StructuredBuffer
|
||||
// CHECK: ID: 1
|
||||
// CHECK: Space: 13
|
||||
// CHECK: LowerBound: 1
|
||||
// CHECK: UpperBound: 1
|
||||
// CHECK: Name: "T2"
|
||||
// CHECK: Flags: 0 (None)
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[6] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?PSMain@@YA?AV?$vector@M$03@@H@Z"
|
||||
// CHECK: UnmangledName: "PSMain"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?PSMain_Clone1@@YA?AV?$vector@M$03@@H@Z"
|
||||
// CHECK: UnmangledName: "PSMain_Clone1"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <2:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?PSMain_Clone2@@YA?AV?$vector@M$03@@H@Z"
|
||||
// CHECK: UnmangledName: "PSMain_Clone2"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <3:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "PSMain"
|
||||
// CHECK: UnmangledName: "PSMain"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Pixel
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 1
|
||||
// CHECK: MinShaderTarget: 96
|
||||
// CHECK: }
|
||||
// CHECK: <4:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "PSMain_Clone1"
|
||||
// CHECK: UnmangledName: "PSMain_Clone1"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Pixel
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 1
|
||||
// CHECK: MinShaderTarget: 96
|
||||
// CHECK: }
|
||||
// CHECK: <5:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "PSMain_Clone2"
|
||||
// CHECK: UnmangledName: "PSMain_Clone2"
|
||||
// CHECK: Resources: <0:RecordArrayRef<RuntimeDataResourceInfo>[2]> = {
|
||||
// CHECK: [0]: <0:RuntimeDataResourceInfo>
|
||||
// CHECK: [1]: <1:RuntimeDataResourceInfo>
|
||||
// CHECK: }
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Pixel
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 1
|
||||
// CHECK: MinShaderTarget: 96
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
|
|
|
@ -90,6 +90,78 @@ HSPerPatchData HSPerPatchFunc1()
|
|||
return d;
|
||||
}
|
||||
|
||||
// CHECK: DxilRuntimeData (size = 436 bytes):
|
||||
// CHECK: StringBuffer (size = 176 bytes)
|
||||
// CHECK: IndexTable (size = 0 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[5] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?HSMain1@@YAXIV?$InputPatch@UPSSceneIn@@$02@@@Z"
|
||||
// CHECK: UnmangledName: "HSMain1"
|
||||
// CHECK: Resources: <RecordArrayRef<RuntimeDataResourceInfo>[0]> = {}
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <1:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?HSMain3@@YAXIV?$InputPatch@UPSSceneIn@@$02@@@Z"
|
||||
// CHECK: UnmangledName: "HSMain3"
|
||||
// CHECK: Resources: <RecordArrayRef<RuntimeDataResourceInfo>[0]> = {}
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 32767
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: <2:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "HSMain1"
|
||||
// CHECK: UnmangledName: "HSMain1"
|
||||
// CHECK: Resources: <RecordArrayRef<RuntimeDataResourceInfo>[0]> = {}
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Hull
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 8
|
||||
// CHECK: MinShaderTarget: 196704
|
||||
// CHECK: }
|
||||
// CHECK: <3:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "HSMain3"
|
||||
// CHECK: UnmangledName: "HSMain3"
|
||||
// CHECK: Resources: <RecordArrayRef<RuntimeDataResourceInfo>[0]> = {}
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Hull
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 8
|
||||
// CHECK: MinShaderTarget: 196704
|
||||
// CHECK: }
|
||||
// CHECK: <4:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "\01?HSPerPatchFunc1@@YA?AUHSPerPatchData@@XZ"
|
||||
// CHECK: UnmangledName: "HSPerPatchFunc1"
|
||||
// CHECK: Resources: <RecordArrayRef<RuntimeDataResourceInfo>[0]> = {}
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Library
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 0
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 8
|
||||
// CHECK: MinShaderTarget: 393312
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
// CHECK: FunctionCount: 5
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
// RUN: %dxc -T lib_6_7 %s | %D3DReflect %s | FileCheck %s
|
||||
|
||||
// CHECK:DxilRuntimeData (size = 92 bytes):
|
||||
// CHECK: StringBuffer (size = 8 bytes)
|
||||
// CHECK: IndexTable (size = 0 bytes)
|
||||
// CHECK: RawBytes (size = 0 bytes)
|
||||
// CHECK: RecordTable (stride = 44 bytes) FunctionTable[1] = {
|
||||
// CHECK: <0:RuntimeDataFunctionInfo> = {
|
||||
// CHECK: Name: "main"
|
||||
// CHECK: UnmangledName: "main"
|
||||
// CHECK: Resources: <RecordArrayRef<RuntimeDataResourceInfo>[0]> = {}
|
||||
// CHECK: FunctionDependencies: <string[0]> = {}
|
||||
// CHECK: ShaderKind: Mesh
|
||||
// CHECK: PayloadSizeInBytes: 0
|
||||
// CHECK: AttributeSizeInBytes: 0
|
||||
// CHECK: FeatureInfo1: 65536
|
||||
// CHECK: FeatureInfo2: 0
|
||||
// CHECK: ShaderStageFlag: 8192
|
||||
// CHECK: MinShaderTarget: 852069
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK:ID3D12LibraryReflection:
|
||||
// CHECK: D3D12_LIBRARY_DESC:
|
||||
// CHECK: Creator: <nullptr>
|
||||
// CHECK: Flags: 0
|
||||
// CHECK: FunctionCount: 1
|
||||
// CHECK: ID3D12FunctionReflection:
|
||||
// CHECK: D3D12_FUNCTION_DESC: Name: main
|
||||
// CHECK: Shader Version: Mesh 6.7
|
||||
// CHECK: Creator: <nullptr>
|
||||
// CHECK: Flags: 0
|
||||
// CHECK: ConstantBuffers: 0
|
||||
// CHECK: BoundResources: 0
|
||||
// CHECK: FunctionParameterCount: 0
|
||||
// CHECK: HasReturn: FALSE
|
||||
|
||||
#define MAX_VERT 32
|
||||
#define MAX_PRIM 16
|
||||
#define NUM_THREADS 32
|
||||
struct MeshPerVertex {
|
||||
float4 position : SV_Position;
|
||||
float color[4] : COLOR;
|
||||
};
|
||||
|
||||
struct MeshPerPrimitive {
|
||||
float normal : NORMAL;
|
||||
};
|
||||
|
||||
struct MeshPayload {
|
||||
float normal;
|
||||
int4 data;
|
||||
bool2x2 mat;
|
||||
};
|
||||
|
||||
groupshared float gsMem[MAX_PRIM];
|
||||
|
||||
[numthreads(NUM_THREADS, 1, 1)]
|
||||
[shader("mesh")]
|
||||
[outputtopology("triangle")]
|
||||
void main(
|
||||
out indices uint3 primIndices[MAX_PRIM],
|
||||
out vertices MeshPerVertex verts[MAX_VERT],
|
||||
out primitives MeshPerPrimitive prims[MAX_PRIM],
|
||||
in payload MeshPayload mpl,
|
||||
in uint tig : SV_GroupIndex,
|
||||
in uint vid : SV_ViewID
|
||||
)
|
||||
{
|
||||
SetMeshOutputCounts(MAX_VERT, MAX_PRIM);
|
||||
MeshPerVertex ov;
|
||||
if (vid % 2) {
|
||||
ov.position = float4(4.0,5.0,6.0,7.0);
|
||||
ov.color[0] = 4.0;
|
||||
ov.color[1] = 5.0;
|
||||
ov.color[2] = 6.0;
|
||||
ov.color[3] = 7.0;
|
||||
} else {
|
||||
ov.position = float4(14.0,15.0,16.0,17.0);
|
||||
ov.color[0] = 14.0;
|
||||
ov.color[1] = 15.0;
|
||||
ov.color[2] = 16.0;
|
||||
ov.color[3] = 17.0;
|
||||
}
|
||||
if (tig % 3) {
|
||||
primIndices[tig / 3] = uint3(tig, tig + 1, tig + 2);
|
||||
MeshPerPrimitive op;
|
||||
op.normal = dot(mpl.normal.xx, mul(mpl.data.xy, mpl.mat));
|
||||
gsMem[tig / 3] = op.normal;
|
||||
prims[tig / 3] = op;
|
||||
}
|
||||
verts[tig] = ov;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// RUN: %dxc -T ps_6_7 %s -fcgl | FileCheck -check-prefixes=ENTRY,CHECK %s
|
||||
// RUN: %dxc -T ps_6_7 %s | FileCheck -check-prefix=ENTRY %s
|
||||
// RUN: %dxc -T ps_6_6 %s -fcgl | FileCheck -check-prefix=IGNORED %s
|
||||
// RUN: %dxc -T cs_6_7 %s | FileCheck -check-prefix=IGNORED %s
|
||||
|
||||
// IGNORED-NOT: waveops-include-helper-lanes
|
||||
|
||||
#if __SHADER_TARGET_STAGE == __SHADER_STAGE_COMPUTE
|
||||
|
||||
[WaveOpsIncludeHelperLanes]
|
||||
[numthreads(1,1,1)]
|
||||
void main() {
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
[WaveOpsIncludeHelperLanes]
|
||||
float cast(int X) {
|
||||
return (float)X;
|
||||
}
|
||||
|
||||
[WaveOpsIncludeHelperLanes]
|
||||
float main(int N : A, int C : B) : SV_TARGET {
|
||||
return cast(N);
|
||||
}
|
||||
|
||||
// ENTRY: define {{(float)|(void)}} @main({{.*}}) #[[MainAttr:[0-9]+]]
|
||||
// CHECK: define internal float @{{.*}}cast{{.*}}(i32 %{{.*}}) #[[CastAttr:[0-9]+]]
|
||||
|
||||
// ENTRY: attributes #[[MainAttr]] = {{.*}}"waveops-include-helper-lanes"{{.*}}
|
||||
// CHECK-NOT: attribtes #[[CastAttr]] = {{.*}}"waveops-include-helper-lanes"{{.*}}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %dxc -T lib_6_7 %s | FileCheck %s
|
||||
// RUN: %dxc -T lib_6_6 %s | FileCheck -check-prefix=IGNORED %s
|
||||
|
||||
// IGNORED-NOT: waveops-include-helper-lanes
|
||||
|
||||
[WaveOpsIncludeHelperLanes]
|
||||
[shader("compute")]
|
||||
[numthreads(1,1,1)]
|
||||
void cs_main() {
|
||||
}
|
||||
|
||||
|
||||
[WaveOpsIncludeHelperLanes]
|
||||
[shader("pixel")]
|
||||
float ps_main(int N : A, int C : B) : SV_TARGET {
|
||||
return (float)N;
|
||||
}
|
||||
|
||||
// CHECK: define void @cs_main() #[[CSMainAttr:[0-9]+]]
|
||||
// CHECK: define void @ps_main() #[[PSMainAttr:[0-9]+]]
|
||||
|
||||
// CHECK-NOT: attribtes #[[CSMainAttr]] = {{.*}}"waveops-include-helper-lanes"{{.*}}
|
||||
// CHECK: attributes #[[PSMainAttr]] = {{.*}}"waveops-include-helper-lanes"{{.*}}
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_7 %s | FileCheck %s -check-prefixes=CHECK,NOALIAS
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_7 -res-may-alias %s | FileCheck %s -check-prefixes=CHECK,ALIAS
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_0 %s | FileCheck %s -check-prefixes=CHECK,NOALIAS
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_0 -res-may-alias %s | FileCheck %s -check-prefixes=CHECK,ALIAS
|
||||
// RUN: %dxilver 1.5 | %dxc -E main -T ps_6_0 -validator-version 1.5 %s | FileCheck %s -check-prefixes=CHECK,ALIAS
|
||||
// RUN: %dxilver 1.5 | %dxc -E main -T ps_6_0 -validator-version 1.5 -res-may-alias %s | FileCheck %s -check-prefixes=CHECK,ALIAS
|
||||
|
||||
// flag masked off when validator version < 1.7, meaning resources may alias.
|
||||
// CHECK: = !{void ()* @main, !"main", !{{.*}}, !{{.*}}, ![[flags:[0-9]+]]}
|
||||
// ALIAS: ![[flags]] = !{i32 0, i64 16}
|
||||
// NOALIAS: ![[flags]] = !{i32 0, i64 8589934608}
|
||||
|
||||
RWStructuredBuffer<float> FBUF;
|
||||
RWStructuredBuffer<int> IBUF;
|
||||
|
||||
float4 main(float4 a : A) : SV_Target
|
||||
{
|
||||
float f = FBUF[0];
|
||||
IBUF[a.w] = -27;
|
||||
return f + FBUF[0];
|
||||
}
|
|
@ -5,6 +5,12 @@
|
|||
// RUN: %dxc -E VarOffset -T ps_6_0 -DOFFSETS=constOffsets %s | FileCheck %s -check-prefix=CHK_VAROFF
|
||||
// RUN: %dxc -E VarOffset -T ps_6_0 -DOFFSETS=validOffsets %s | FileCheck %s -check-prefix=CHK_VALID
|
||||
|
||||
// RUN: %dxc -E VarOffset -T ps_6_7 -DOFFSETS=argOffsets %s | FileCheck %s -check-prefixes=CHK_VALID,SM67CHCK
|
||||
// RUN: %dxc -E VarOffset -T ps_6_7 -DOFFSETS=cbufOffsets %s | FileCheck %s -check-prefixes=CHK_VALID,SM67CHCK
|
||||
// RUN: %dxc -E VarOffset -T ps_6_7 -DOFFSETS=constOffsets %s | FileCheck %s -check-prefixes=CHK_VALID,SM67CHCK
|
||||
|
||||
//SM67CHK: Advanced Texture Ops
|
||||
|
||||
// CHK_RANGE: error: Offsets to texture access operations must be between -8 and 7.
|
||||
// CHK_RANGE: error: Offsets to texture access operations must be between -8 and 7.
|
||||
// CHK_RANGE: error: Offsets to texture access operations must be between -8 and 7.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// CHECK: call float @dx.op.dot2AddHalf.f32(i32 162,
|
||||
|
||||
float2 main(half4 inputs : Inputs0, float acc : Acc0) : SV_Target {
|
||||
float2 main(half4 inputs : Inputs0, int acc : Acc0) : SV_Target {
|
||||
acc = dot2add(inputs.xy, inputs.zw, acc);
|
||||
return acc;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// RUN: %dxc -E main -T cs_6_6 -Od %s | FileCheck -check-prefixes=CHECK,SM66 %s
|
||||
// RUN: %dxc -E main -T cs_6_7 -Od %s | FileCheck -check-prefixes=CHECK,SM67 %s
|
||||
|
||||
// In Shader Model 6.6 and earlier the QuadAny and QuadAll intrinsics will
|
||||
// expand out to quadOp instructions reading from each of the 3 other lanes and
|
||||
// bitwise & or | instructions to compute the result.
|
||||
|
||||
// SM66: [[cond:%[a-z0-9]+]] = sext i1 %{{[a-z0-9]+}} to i32
|
||||
// SM66-NEXT: [[x:%[a-zA-Z0-9]+]] = call i32 @dx.op.quadOp.i32(i32 123, i32 [[cond]], i8 0)
|
||||
// SM66-NEXT: [[y:%[a-zA-Z0-9]+]] = call i32 @dx.op.quadOp.i32(i32 123, i32 [[cond]], i8 1)
|
||||
// SM66-NEXT: [[z:%[a-zA-Z0-9]+]] = call i32 @dx.op.quadOp.i32(i32 123, i32 [[cond]], i8 2)
|
||||
// SM66-NEXT: [[xy:%[a-z0-9]+]] = or i32 [[x]], [[y]]
|
||||
// SM66-NEXT: [[wide:%[a-z0-9]+]] = or i32 [[xy]], [[z]]
|
||||
// SM66-NEXT: [[any:%[a-z0-9]+]] = trunc i32 [[wide]] to i1
|
||||
|
||||
// SM67: [[cond:%[a-z0-9]+]] = icmp ne i1 %{{[a-z0-9]+}}, false
|
||||
// SM67-NEXT: [[any:%[a-zA-Z0-9]+]] = call i1 @dx.op.quadVote.i1(i32 222, i1 [[cond]], i8 0)
|
||||
|
||||
// CHECK: select i1 [[any]], float 1.000000e+00, float 2.000000e+00
|
||||
|
||||
|
||||
// SM66: [[cond:%[a-z0-9]+]] = sext i1 {{%[a-z0-9]+}} to i32
|
||||
// SM66-NEXT: [[x:%[a-zA-Z0-9]+]] = call i32 @dx.op.quadOp.i32(i32 123, i32 [[cond]], i8 0)
|
||||
// SM66-NEXT: [[y:%[a-zA-Z0-9]+]] = call i32 @dx.op.quadOp.i32(i32 123, i32 [[cond]], i8 1)
|
||||
// SM66-NEXT: [[z:%[a-zA-Z0-9]+]] = call i32 @dx.op.quadOp.i32(i32 123, i32 [[cond]], i8 2)
|
||||
// SM66-NEXT: [[xy:%[a-z0-9]+]] = and i32 [[x]], [[y]]
|
||||
// SM66-NEXT: [[wide:%[a-z0-9]+]] = and i32 [[xy]], [[z]]
|
||||
// SM66-NEXT: [[all:%[a-z0-9]+]] = trunc i32 [[wide]] to i1
|
||||
|
||||
// SM67: [[cond:%[a-z0-9]+]] = icmp ne i1 %{{[a-z0-9]+}}, false
|
||||
// SM67-NEXT: [[all:%[a-zA-Z0-9]+]] = call i1 @dx.op.quadVote.i1(i32 222, i1 [[cond]], i8 1)
|
||||
|
||||
// CHECK: select i1 [[all]], float 3.000000e+00, float 4.000000e+00
|
||||
|
||||
RWStructuredBuffer<float4> Values;
|
||||
|
||||
[numthreads(8, 8, 1)]
|
||||
void main(uint3 ID: SV_DispatchThreadID) {
|
||||
uint OutIdx = (ID.y * 8) + ID.x;
|
||||
Values[OutIdx].x = QuadAny(OutIdx % 4 == 0) ? 1.0 : 2.0;
|
||||
Values[OutIdx].y = QuadAll(OutIdx % 2 == 0) ? 3.0 : 4.0;
|
||||
Values[OutIdx].z = 0.0;
|
||||
Values[OutIdx].w = 0.0;
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
// RUN: %dxilver 1.1 | %dxc -E main -T cs_6_0 -not_use_legacy_cbuf_load %s | FileCheck %s
|
||||
// RUN: %dxilver 1.1 | %dxc -E main -T cs_6_0 -validator-version 1.1 -not_use_legacy_cbuf_load %s | FileCheck %s -check-prefixes=CHECK,CHECK61
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T cs_6_0 -not_use_legacy_cbuf_load %s | FileCheck %s -check-prefixes=CHECK,CHECK67
|
||||
|
||||
// CHECK: 64-Bit integer
|
||||
// CHECK: dx.op.bufferStore.i32
|
||||
// CHECK: dx.op.bufferStore.i32
|
||||
// CHECK: !{i32 0, i64 1048576
|
||||
// CHECK61: !{i32 0, i64 1048576
|
||||
// CHECK67: !{i32 0, i64 8590983168
|
||||
|
||||
// Note: a change in the internal layout will produce
|
||||
// a difference in the serialized flags, eg:
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
// RUN: %dxc -T ps_6_7 %s | FileCheck %s
|
||||
|
||||
// Test for RWTexture2DMS and RWTexture2DMSArray types and their operations
|
||||
|
||||
RWTexture2DMS<float4,8> g_rw_t2dms;
|
||||
RWTexture2DMSArray<uint,8> g_rw_t2dmsa;
|
||||
|
||||
|
||||
//CHECK: Advanced Texture Ops
|
||||
//CHECK: Writeable MSAA Textures
|
||||
|
||||
float4 test2DMS(uint sampleSlice, uint2 pos2, uint3 pos3) {
|
||||
uint w, h, s, w2, h2, s2, e;
|
||||
uint fw, fh, fs, fw2, fh2, fs2, fe;
|
||||
uint status;
|
||||
|
||||
g_rw_t2dms.GetDimensions(w, h, s);
|
||||
g_rw_t2dmsa.GetDimensions(w2, h2, e, s2);
|
||||
|
||||
float4 res = uint4(w, h + s, w2 + e, h2 + s2);
|
||||
|
||||
g_rw_t2dms.GetDimensions(fw, fh, fs);
|
||||
g_rw_t2dmsa.GetDimensions(fw2, fh2, fe, fs2);
|
||||
|
||||
res *= float4(fw, fh + fs, fw2 + fe, fh2 + fs2);
|
||||
|
||||
res -= g_rw_t2dms.GetSamplePosition(sampleSlice).xyxy;
|
||||
res -= g_rw_t2dmsa.GetSamplePosition(sampleSlice).xyxy;
|
||||
|
||||
res += g_rw_t2dms.Load(pos2 + 1, sampleSlice + 1);
|
||||
res += g_rw_t2dmsa.Load(pos3 + 1, sampleSlice + 1);
|
||||
|
||||
res += g_rw_t2dms.Load(pos2 + 2, sampleSlice + 2, status);
|
||||
res += status;
|
||||
res += g_rw_t2dmsa.Load(pos3 + 2, sampleSlice + 2, status);
|
||||
res += status;
|
||||
|
||||
res += g_rw_t2dms[pos2];
|
||||
res += g_rw_t2dmsa[pos3];
|
||||
|
||||
res += g_rw_t2dms.sample[sampleSlice][pos2];
|
||||
res += g_rw_t2dmsa.sample[sampleSlice][pos3];
|
||||
|
||||
g_rw_t2dms[pos2] = res;
|
||||
g_rw_t2dmsa[pos3] = res.x;
|
||||
|
||||
g_rw_t2dms.sample[sampleSlice][pos2] = res;
|
||||
g_rw_t2dmsa.sample[sampleSlice][pos3] = res.x;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
float4 main(uint sampleSlice : S, uint2 pos2 : PP, uint3 pos3 : PPP) : SV_Target {
|
||||
float4 res = 0.0;
|
||||
// Collect important param values
|
||||
// CHECK: [[POS3X:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 0, i32 undef)
|
||||
// CHECK: [[POS3Y:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 1, i32 undef)
|
||||
// CHECK: [[POS3Z:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 2, i32 undef)
|
||||
// CHECK: [[POS2X:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
// CHECK: [[POS2Y:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 1, i32 undef)
|
||||
// CHECK: [[SLICE:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
|
||||
// Test with constant values
|
||||
//CHECK: @dx.op.getDimensions(i32 72
|
||||
//CHECK: @dx.op.getDimensions(i32 72
|
||||
//CHECK: @dx.op.texture2DMSGetSamplePosition(i32 75, %dx.types.Handle %{{.*}}, i32 1)
|
||||
//CHECK: @dx.op.texture2DMSGetSamplePosition(i32 75, %dx.types.Handle %{{.*}}, i32 1)
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 2, i32 3, i32 4
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 2, i32 5, i32 6, i32 7
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 3, i32 4, i32 5
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 3, i32 6, i32 7, i32 8
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 0, i32 2, i32 3
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 0, i32 4, i32 5, i32 6
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 1, i32 2, i32 3
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 1, i32 4, i32 5, i32 6
|
||||
// CHECK: @dx.op.textureStoreSample.f32(i32 225, %dx.types.Handle %{{.*}}, i32 2, i32 3, i32 undef, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, i8 15, i32 0)
|
||||
// CHECK: @dx.op.textureStoreSample.i32(i32 225, %dx.types.Handle %{{.*}}, i32 4, i32 5, i32 6, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i8 15, i32 0)
|
||||
// CHECK: @dx.op.textureStoreSample.f32(i32 225, %dx.types.Handle %{{.*}}, i32 2, i32 3, i32 undef, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, i8 15, i32 1)
|
||||
// CHECK: @dx.op.textureStoreSample.i32(i32 225, %dx.types.Handle %{{.*}}, i32 4, i32 5, i32 6, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i8 15, i32 1)
|
||||
|
||||
res += test2DMS(1, uint2(2,3), uint3(4,5,6));
|
||||
|
||||
// Test with params
|
||||
//CHECK: @dx.op.getDimensions(i32 72
|
||||
//CHECK: @dx.op.getDimensions(i32 72
|
||||
//CHECK: @dx.op.texture2DMSGetSamplePosition(i32 75, %dx.types.Handle %{{.*}}, i32 [[SLICE]])
|
||||
//CHECK: @dx.op.texture2DMSGetSamplePosition(i32 75, %dx.types.Handle %{{.*}}, i32 [[SLICE]])
|
||||
//CHECK: [[SLICEp1:%.*]] = add i32 [[SLICE]], 1
|
||||
//CHECK: [[POS2Xp1:%.*]] = add i32 [[POS2X]], 1
|
||||
//CHECK: [[POS2Yp1:%.*]] = add i32 [[POS2Y]], 1
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 [[SLICEp1]], i32 [[POS2Xp1]], i32 [[POS2Yp1]]
|
||||
//CHECK: [[POS3Xp1:%.*]] = add i32 [[POS3X]], 1
|
||||
//CHECK: [[POS3Yp1:%.*]] = add i32 [[POS3Y]], 1
|
||||
//CHECK: [[POS3Zp1:%.*]] = add i32 [[POS3Z]], 1
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 [[SLICEp1]], i32 [[POS3Xp1]], i32 [[POS3Yp1]], i32 [[POS3Zp1]]
|
||||
//CHECK: [[SLICEp2:%.*]] = add i32 [[SLICE]], 2
|
||||
//CHECK: [[POS2Xp2:%.*]] = add i32 [[POS2X]], 2
|
||||
//CHECK: [[POS2Yp2:%.*]] = add i32 [[POS2Y]], 2
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 [[SLICEp2]], i32 [[POS2Xp2]], i32 [[POS2Yp2]]
|
||||
//CHECK: [[POS3Xp2:%.*]] = add i32 [[POS3X]], 2
|
||||
//CHECK: [[POS3Yp2:%.*]] = add i32 [[POS3Y]], 2
|
||||
//CHECK: [[POS3Zp2:%.*]] = add i32 [[POS3Z]], 2
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 [[SLICEp2]], i32 [[POS3Xp2]], i32 [[POS3Yp2]], i32 [[POS3Zp2]]
|
||||
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 0, i32 [[POS2X]], i32 [[POS2Y]]
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 0, i32 [[POS3X]], i32 [[POS3Y]], i32 [[POS3Z]]
|
||||
|
||||
//CHECK: @dx.op.textureLoad.f32(i32 66, %dx.types.Handle %{{.*}}, i32 [[SLICE]], i32 [[POS2X]], i32 [[POS2Y]]
|
||||
//CHECK: @dx.op.textureLoad.i32(i32 66, %dx.types.Handle %{{.*}}, i32 [[SLICE]], i32 [[POS3X]], i32 [[POS3Y]], i32 [[POS3Z]]
|
||||
|
||||
// CHECK: @dx.op.textureStoreSample.f32(i32 225, %dx.types.Handle %{{.*}}, i32 [[POS2X]], i32 [[POS2Y]], i32 undef, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, i8 15, i32 0)
|
||||
// CHECK: @dx.op.textureStoreSample.i32(i32 225, %dx.types.Handle %{{.*}}, i32 [[POS3X]], i32 [[POS3Y]], i32 [[POS3Z]], i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i8 15, i32 0)
|
||||
// CHECK: @dx.op.textureStoreSample.f32(i32 225, %dx.types.Handle %{{.*}}, i32 [[POS2X]], i32 [[POS2Y]], i32 undef, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, i8 15, i32 [[SLICE]])
|
||||
// CHECK: @dx.op.textureStoreSample.i32(i32 225, %dx.types.Handle %{{.*}}, i32 [[POS3X]], i32 [[POS3Y]], i32 [[POS3Z]], i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i8 15, i32 [[SLICE]])
|
||||
|
||||
res += test2DMS(sampleSlice, pos2, pos3);
|
||||
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// RUN: %dxc -T ps_6_7 -enable-16bit-types %s | FileCheck %s
|
||||
|
||||
//CHECK: Advanced Texture Ops
|
||||
|
||||
|
||||
// CHECK: call %dx.types.ResRet.i16 @dx.op.textureGatherRaw.i16
|
||||
// CHECK: call %dx.types.ResRet.i16 @dx.op.textureGatherRaw.i16
|
||||
// CHECK: call %dx.types.ResRet.i16 @dx.op.textureGatherRaw.i16
|
||||
// CHECK: call %dx.types.ResRet.i16 @dx.op.textureGatherRaw.i16
|
||||
// CHECK: call %dx.types.ResRet.i16 @dx.op.textureGatherRaw.i16
|
||||
// CHECK: call %dx.types.ResRet.i16 @dx.op.textureGatherRaw.i16
|
||||
|
||||
// CHECK: call %dx.types.ResRet.i32 @dx.op.textureGatherRaw.i32
|
||||
// CHECK: call %dx.types.ResRet.i32 @dx.op.textureGatherRaw.i32
|
||||
// CHECK: call %dx.types.ResRet.i32 @dx.op.textureGatherRaw.i32
|
||||
// CHECK: call %dx.types.ResRet.i32 @dx.op.textureGatherRaw.i32
|
||||
// CHECK: call %dx.types.ResRet.i32 @dx.op.textureGatherRaw.i32
|
||||
// CHECK: call %dx.types.ResRet.i32 @dx.op.textureGatherRaw.i32
|
||||
|
||||
// CHECK: call %dx.types.ResRet.i64 @dx.op.textureGatherRaw.i64
|
||||
// CHECK: call %dx.types.ResRet.i64 @dx.op.textureGatherRaw.i64
|
||||
// CHECK: call %dx.types.ResRet.i64 @dx.op.textureGatherRaw.i64
|
||||
// CHECK: call %dx.types.ResRet.i64 @dx.op.textureGatherRaw.i64
|
||||
// CHECK: call %dx.types.ResRet.i64 @dx.op.textureGatherRaw.i64
|
||||
// CHECK: call %dx.types.ResRet.i64 @dx.op.textureGatherRaw.i64
|
||||
|
||||
Texture2D<uint16_t> g_tex16 : register(t1);
|
||||
Texture2D<uint32_t> g_tex32 : register(t2);
|
||||
Texture2D<uint64_t> g_tex64 : register(t3);
|
||||
|
||||
Texture2DArray<uint16_t> g_texArr16 : register(t4);
|
||||
Texture2DArray<uint32_t> g_texArr32 : register(t5);
|
||||
Texture2DArray<uint64_t> g_texArr64 : register(t6);
|
||||
|
||||
SamplerState g_samp : register(s5);
|
||||
|
||||
float4 main(float2 a : A) : SV_Target
|
||||
{
|
||||
uint status;
|
||||
uint16_t4 r16 = 0;
|
||||
float3 b = float3(a.x, a.y, 1.0);
|
||||
r16 += g_tex16.GatherRaw(g_samp, a);
|
||||
r16 += g_tex16.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r16 += g_tex16.GatherRaw(g_samp, a, uint2(-3, 2), status); r16 += !!status;
|
||||
|
||||
r16 += g_texArr16.GatherRaw(g_samp, b);
|
||||
r16 += g_texArr16.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r16 += g_texArr16.GatherRaw(g_samp, b, uint2(-3, 2), status); r16 += !!status;
|
||||
|
||||
uint32_t4 r32 = 0;
|
||||
r32 += g_tex32.GatherRaw(g_samp, a);
|
||||
r32 += g_tex32.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r32 += g_tex32.GatherRaw(g_samp, a, uint2(-3, 2), status); r32 += !!status;
|
||||
|
||||
r32 += g_texArr32.GatherRaw(g_samp, b);
|
||||
r32 += g_texArr32.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r32 += g_texArr32.GatherRaw(g_samp, b, uint2(-3, 2), status); r32 += !!status;
|
||||
|
||||
uint64_t4 r64 = 0;
|
||||
r64 += g_tex64.GatherRaw(g_samp, a);
|
||||
r64 += g_tex64.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r64 += g_tex64.GatherRaw(g_samp, a, uint2(-3, 2), status); r64 += !!status;
|
||||
|
||||
r64 += g_texArr64.GatherRaw(g_samp, b);
|
||||
r64 += g_texArr64.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r64 += g_texArr64.GatherRaw(g_samp, b, uint2(-3, 2), status); r64 += !!status;
|
||||
|
||||
return r16 + r32 + (r64 & 0xFFFFFFFF) + (r64 >> 32);
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
// RUN: %dxc -T ps_6_7 -enable-16bit-types %s | FileCheck %s
|
||||
|
||||
Texture2D<float16_t> g_texf16 : register(t1);
|
||||
Texture2D<float32_t> g_texf32 : register(t2);
|
||||
Texture2D<float64_t> g_texf64 : register(t3);
|
||||
|
||||
Texture2DArray<float16_t> g_texArrf16 : register(t4);
|
||||
Texture2DArray<float32_t> g_texArrf32 : register(t5);
|
||||
Texture2DArray<float64_t> g_texArrf64 : register(t6);
|
||||
|
||||
Texture2D<uint16_t4> g_tex16 : register(t7);
|
||||
Texture2D<uint32_t2> g_tex32 : register(t8);
|
||||
Texture2D<uint64_t3> g_tex64 : register(t9);
|
||||
|
||||
Texture2DArray<uint16_t2> g_texArr16 : register(t10);
|
||||
Texture2DArray<uint32_t3> g_texArr32 : register(t11);
|
||||
Texture2DArray<uint64_t4> g_texArr64 : register(t12);
|
||||
|
||||
SamplerState g_samp : register(s5);
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing half
|
||||
//CHECK: error: cannot GatherRaw from resource containing half
|
||||
//CHECK: error: cannot GatherRaw from resource containing half
|
||||
//CHECK: error: cannot GatherRaw from resource containing half
|
||||
//CHECK: error: cannot GatherRaw from resource containing half
|
||||
//CHECK: error: cannot GatherRaw from resource containing half
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing float
|
||||
//CHECK: error: cannot GatherRaw from resource containing float
|
||||
//CHECK: error: cannot GatherRaw from resource containing float
|
||||
//CHECK: error: cannot GatherRaw from resource containing float
|
||||
//CHECK: error: cannot GatherRaw from resource containing float
|
||||
//CHECK: error: cannot GatherRaw from resource containing float
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing double
|
||||
//CHECK: error: cannot GatherRaw from resource containing double
|
||||
//CHECK: error: cannot GatherRaw from resource containing double
|
||||
//CHECK: error: cannot GatherRaw from resource containing double
|
||||
//CHECK: error: cannot GatherRaw from resource containing double
|
||||
//CHECK: error: cannot GatherRaw from resource containing double
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing ushort4
|
||||
//CHECK: error: cannot GatherRaw from resource containing ushort4
|
||||
//CHECK: error: cannot GatherRaw from resource containing ushort4
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing ushort2
|
||||
//CHECK: error: cannot GatherRaw from resource containing ushort2
|
||||
//CHECK: error: cannot GatherRaw from resource containing ushort2
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing uint2
|
||||
//CHECK: error: cannot GatherRaw from resource containing uint2
|
||||
//CHECK: error: cannot GatherRaw from resource containing uint2
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing uint3
|
||||
//CHECK: error: cannot GatherRaw from resource containing uint3
|
||||
//CHECK: error: cannot GatherRaw from resource containing uint3
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing ulong3
|
||||
//CHECK: error: cannot GatherRaw from resource containing ulong3
|
||||
//CHECK: error: cannot GatherRaw from resource containing ulong3
|
||||
|
||||
//CHECK: error: cannot GatherRaw from resource containing ulong4
|
||||
//CHECK: error: cannot GatherRaw from resource containing ulong4
|
||||
//CHECK: error: cannot GatherRaw from resource containing ulong4
|
||||
|
||||
float4 main(float2 a : A) : SV_Target
|
||||
{
|
||||
uint status;
|
||||
uint16_t4 r16 = 0;
|
||||
float3 b = float3(a.x, a.y, 1.0);
|
||||
r16 += g_texf16.GatherRaw(g_samp, a);
|
||||
r16 += g_texf16.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r16 += g_texf16.GatherRaw(g_samp, a, uint2(-3, 2), status); r16 += !!status;
|
||||
|
||||
r16 += g_texArrf16.GatherRaw(g_samp, b);
|
||||
r16 += g_texArrf16.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r16 += g_texArrf16.GatherRaw(g_samp, b, uint2(-3, 2), status); r16 += !!status;
|
||||
|
||||
uint32_t4 r32 = 0;
|
||||
r32 += g_texf32.GatherRaw(g_samp, a);
|
||||
r32 += g_texf32.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r32 += g_texf32.GatherRaw(g_samp, a, uint2(-3, 2), status); r32 += !!status;
|
||||
|
||||
r32 += g_texArrf32.GatherRaw(g_samp, b);
|
||||
r32 += g_texArrf32.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r32 += g_texArrf32.GatherRaw(g_samp, b, uint2(-3, 2), status); r32 += !!status;
|
||||
|
||||
uint64_t4 r64 = 0;
|
||||
r64 += g_texf64.GatherRaw(g_samp, a);
|
||||
r64 += g_texf64.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r64 += g_texf64.GatherRaw(g_samp, a, uint2(-3, 2), status); r64 += !!status;
|
||||
|
||||
r64 += g_texArrf64.GatherRaw(g_samp, b);
|
||||
r64 += g_texArrf64.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r64 += g_texArrf64.GatherRaw(g_samp, b, uint2(-3, 2), status); r64 += !!status;
|
||||
|
||||
r16 += g_tex16.GatherRaw(g_samp, a);
|
||||
r16 += g_tex16.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r16 += g_tex16.GatherRaw(g_samp, a, uint2(-3, 2), status); r16 += !!status;
|
||||
|
||||
r16 += g_texArr16.GatherRaw(g_samp, b);
|
||||
r16 += g_texArr16.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r16 += g_texArr16.GatherRaw(g_samp, b, uint2(-3, 2), status); r16 += !!status;
|
||||
|
||||
r32 += g_tex32.GatherRaw(g_samp, a);
|
||||
r32 += g_tex32.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r32 += g_tex32.GatherRaw(g_samp, a, uint2(-3, 2), status); r32 += !!status;
|
||||
|
||||
r32 += g_texArr32.GatherRaw(g_samp, b);
|
||||
r32 += g_texArr32.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r32 += g_texArr32.GatherRaw(g_samp, b, uint2(-3, 2), status); r32 += !!status;
|
||||
|
||||
r64 += g_tex64.GatherRaw(g_samp, a);
|
||||
r64 += g_tex64.GatherRaw(g_samp, a, uint2(-5, 7));
|
||||
r64 += g_tex64.GatherRaw(g_samp, a, uint2(-3, 2), status); r64 += !!status;
|
||||
|
||||
r64 += g_texArr64.GatherRaw(g_samp, b);
|
||||
r64 += g_texArr64.GatherRaw(g_samp, b, uint2(-5, 7));
|
||||
r64 += g_texArr64.GatherRaw(g_samp, b, uint2(-3, 2), status); r64 += !!status;
|
||||
|
||||
return r16 + r32 + (r64 & 0xFFFFFFFF) + (r64 >> 32);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_7 -DTYPE=float4 %s | FileCheck %s
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_7 -DTYPE=half4 -enable-16bit-types %s | FileCheck %s
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T ps_6_7 -DTYPE=min16float4 -enable-16bit-types %s | FileCheck %s
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T cs_6_7 -DTYPE=float4 %s | FileCheck %s
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T cs_6_7 -DTYPE=half4 -enable-16bit-types %s | FileCheck %s
|
||||
// RUN: %dxilver 1.7 | %dxc -E main -T cs_6_7 -DTYPE=min16float4 -enable-16bit-types %s | FileCheck %s
|
||||
|
||||
SamplerComparisonState samp1 : register(s5);
|
||||
Texture1D<TYPE> tx1d : register(t0);
|
||||
Texture1DArray<TYPE> tx1dArr : register(t1);
|
||||
Texture2D<TYPE> tx2d : register(t2);
|
||||
Texture2DArray<TYPE> tx2dArr : register(t3);
|
||||
TextureCube<TYPE> txc : register(t4);
|
||||
TextureCubeArray<TYPE> txcArr : register(t5);
|
||||
|
||||
RWBuffer<TYPE> buf1;
|
||||
|
||||
float cmpVal;
|
||||
|
||||
//CHECK: Advanced Texture Ops
|
||||
|
||||
float doit(float4 a, float lod) {
|
||||
uint status;
|
||||
float r = 0;
|
||||
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx1d.SampleCmpLevel(samp1, a.x, cmpVal, lod);
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx1d.SampleCmpLevel(samp1, a.x, cmpVal, lod, uint1(-5));
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx1d.SampleCmpLevel(samp1, a.x, cmpVal, lod, uint1(-3), status);
|
||||
r += CheckAccessFullyMapped(status);
|
||||
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx1dArr.SampleCmpLevel(samp1, a.xy, cmpVal, lod);
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx1dArr.SampleCmpLevel(samp1, a.xy, cmpVal, lod, uint1(-5));
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx1dArr.SampleCmpLevel(samp1, a.xy, cmpVal, lod, uint1(-3), status);
|
||||
r += CheckAccessFullyMapped(status);
|
||||
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx2d.SampleCmpLevel(samp1, a.xy, cmpVal, lod);
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx2d.SampleCmpLevel(samp1, a.xy, cmpVal, lod, uint2(-5, 7));
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx2d.SampleCmpLevel(samp1, a.xy, cmpVal, lod, uint2(-3, 2), status);
|
||||
r += CheckAccessFullyMapped(status);
|
||||
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx2dArr.SampleCmpLevel(samp1, a.xyz, cmpVal, lod);
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx2dArr.SampleCmpLevel(samp1, a.xyz, cmpVal, lod, uint2(-5, 7));
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += tx2dArr.SampleCmpLevel(samp1, a.xyz, cmpVal, lod, uint2(-3, 2), status);
|
||||
r += CheckAccessFullyMapped(status);
|
||||
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += txc.SampleCmpLevel(samp1, a.xyz, cmpVal, lod);
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += txc.SampleCmpLevel(samp1, a.zyx, cmpVal, lod, status);
|
||||
r += CheckAccessFullyMapped(status);
|
||||
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += txcArr.SampleCmpLevel(samp1, a, cmpVal, lod);
|
||||
// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224,
|
||||
r += txcArr.SampleCmpLevel(samp1, a.wzyx, cmpVal, lod, status);
|
||||
r += CheckAccessFullyMapped(status);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#if __SHADER_TARGET_STAGE == __SHADER_STAGE_COMPUTE
|
||||
[numthreads(8, 8, 8)]
|
||||
void main(uint dtID : SV_DispatchThreadID) {
|
||||
float4 a = buf1[dtID];
|
||||
float lod = buf1[dtID].z;
|
||||
buf1[dtID] = doit(a, lod);
|
||||
}
|
||||
#else
|
||||
float main(float4 a : A, float lod : L) : SV_Target {
|
||||
return doit(a, lod);
|
||||
}
|
||||
#endif
|
|
@ -23,6 +23,7 @@ add_clang_executable(dxa
|
|||
|
||||
target_link_libraries(dxa
|
||||
dxcompiler
|
||||
HLSLTestLib
|
||||
)
|
||||
|
||||
set_target_properties(dxa PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION})
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dxc/Support/HLSLOptions.h"
|
||||
#include "dxc/DxilContainer/DxilContainer.h"
|
||||
#include "dxc/DxilRootSignature/DxilRootSignature.h"
|
||||
#include "dxc/test/RDATDumper.h"
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support//MSFileSystem.h"
|
||||
|
@ -59,12 +60,17 @@ static cl::opt<bool> DumpRootSig("dumprs",
|
|||
cl::desc("Dump root signature"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> DumpRDAT("dumprdat",
|
||||
cl::desc("Dump RDAT"),
|
||||
cl::init(false));
|
||||
|
||||
class DxaContext {
|
||||
|
||||
private:
|
||||
DxcDllSupport &m_dxcSupport;
|
||||
HRESULT FindModule(hlsl::DxilFourCC fourCC, IDxcBlob *pSource, IDxcLibrary *pLibrary, IDxcBlob **ppTarget);
|
||||
bool ExtractPart(uint32_t Part, IDxcBlob **ppTargetBlob);
|
||||
bool ExtractPart(IDxcBlob* pSource, uint32_t Part, IDxcBlob **ppTargetBlob);
|
||||
public:
|
||||
DxaContext(DxcDllSupport &dxcSupport) : m_dxcSupport(dxcSupport) {}
|
||||
|
||||
|
@ -74,6 +80,7 @@ public:
|
|||
void ListFiles();
|
||||
void ListParts();
|
||||
void DumpRS();
|
||||
void DumpRDAT();
|
||||
};
|
||||
|
||||
void DxaContext::Assemble() {
|
||||
|
@ -197,10 +204,14 @@ bool DxaContext::ExtractFile(const char *pName) {
|
|||
}
|
||||
|
||||
bool DxaContext::ExtractPart(uint32_t PartKind, IDxcBlob **ppTargetBlob) {
|
||||
CComPtr<IDxcContainerReflection> pReflection;
|
||||
CComPtr<IDxcBlobEncoding> pSource;
|
||||
UINT32 partCount;
|
||||
ReadFileIntoBlob(m_dxcSupport, StringRefWide(InputFilename), &pSource);
|
||||
return ExtractPart(pSource, PartKind, ppTargetBlob);
|
||||
}
|
||||
|
||||
bool DxaContext::ExtractPart(IDxcBlob* pSource, uint32_t PartKind, IDxcBlob **ppTargetBlob) {
|
||||
CComPtr<IDxcContainerReflection> pReflection;
|
||||
UINT32 partCount;
|
||||
IFT(m_dxcSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection));
|
||||
IFT(pReflection->Load(pSource));
|
||||
IFT(pReflection->GetPartCount(&partCount));
|
||||
|
@ -333,6 +344,41 @@ void DxaContext::DumpRS() {
|
|||
}
|
||||
}
|
||||
|
||||
void DxaContext::DumpRDAT() {
|
||||
CComPtr<IDxcBlob> pPart;
|
||||
CComPtr<IDxcBlobEncoding> pSource;
|
||||
ReadFileIntoBlob(m_dxcSupport, StringRefWide(InputFilename), &pSource);
|
||||
if (pSource->GetBufferSize() < sizeof(hlsl::RDAT::RuntimeDataHeader)) {
|
||||
printf("Invalid input file, use binary DxilContainer or raw RDAT part.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If DXBC, extract part, otherwise, try to read raw RDAT binary.
|
||||
if (hlsl::DFCC_Container == *(UINT *)pSource->GetBufferPointer()) {
|
||||
if (!ExtractPart(pSource, hlsl::DFCC_RuntimeData, &pPart)) {
|
||||
printf("cannot find RDAT part");
|
||||
return;
|
||||
}
|
||||
} else if (hlsl::RDAT::RDAT_Version_10 != *(UINT *)pSource->GetBufferPointer()) {
|
||||
printf("Invalid input file, use binary DxilContainer or raw RDAT part.");
|
||||
return;
|
||||
} else {
|
||||
pPart = pSource; // Try assuming the source is pure RDAT part
|
||||
}
|
||||
|
||||
hlsl::RDAT::DxilRuntimeData rdat;
|
||||
if (!rdat.InitFromRDAT(pPart->GetBufferPointer(), pPart->GetBufferSize())) {
|
||||
// If any error occurred trying to read as RDAT, assume it's not the right kind of input.
|
||||
printf("Invalid input file, use binary DxilContainer or raw RDAT part.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
hlsl::dump::DumpContext d(ss);
|
||||
hlsl::dump::DumpRuntimeData(rdat, d);
|
||||
printf("%s", ss.str().c_str());
|
||||
}
|
||||
|
||||
using namespace hlsl::options;
|
||||
|
||||
int __cdecl main(int argc, _In_reads_z_(argc) char **argv) {
|
||||
|
@ -387,6 +433,9 @@ int __cdecl main(int argc, _In_reads_z_(argc) char **argv) {
|
|||
} else if (DumpRootSig) {
|
||||
pStage = "Dump root sig";
|
||||
context.DumpRS();
|
||||
} else if (DumpRDAT) {
|
||||
pStage = "Dump RDAT";
|
||||
context.DumpRDAT();
|
||||
}
|
||||
else {
|
||||
pStage = "Assembling";
|
||||
|
|
|
@ -347,6 +347,8 @@ PCSTR g_pFeatureInfoNames[] = {
|
|||
"Sampler descriptor heap indexing",
|
||||
"<RESERVED>",
|
||||
"64-bit Atomics on Heap Resources",
|
||||
"Advanced Texture Ops",
|
||||
"Writeable MSAA Textures",
|
||||
};
|
||||
static_assert(_countof(g_pFeatureInfoNames) == ShaderFeatureInfoCount, "g_pFeatureInfoNames needs to be updated");
|
||||
|
||||
|
@ -1705,10 +1707,9 @@ HRESULT Disassemble(IDxcBlob *pProgram, raw_string_ostream &Stream) {
|
|||
if (pRDATPart) {
|
||||
RDAT::DxilRuntimeData runtimeData(GetDxilPartData(pRDATPart), pRDATPart->PartSize);
|
||||
// TODO: Print the rest of the RDAT info
|
||||
if (RDAT::SubobjectTableReader *pSubobjectTableReader =
|
||||
runtimeData.GetSubobjectTableReader()) {
|
||||
if (runtimeData.GetSubobjectTable()) {
|
||||
dxilModule.ResetSubobjects(new DxilSubobjects());
|
||||
if (!LoadSubobjectsFromRDAT(*dxilModule.GetSubobjects(), pSubobjectTableReader)) {
|
||||
if (!LoadSubobjectsFromRDAT(*dxilModule.GetSubobjects(), runtimeData)) {
|
||||
Stream << "; error occurred while loading Subobjects from RDAT.\n";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ if (WIN32)
|
|||
target_link_libraries(clang-hlsl-tests PRIVATE
|
||||
dxcompiler
|
||||
HLSLTestLib
|
||||
LLVMDxilContainer
|
||||
LLVMDxilDia
|
||||
${TAEF_LIBRARIES}
|
||||
${DIASDK_LIBRARIES}
|
||||
|
|
|
@ -1005,61 +1005,61 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT) {
|
|||
// Validate using DxilRuntimeData
|
||||
DxilRuntimeData context;
|
||||
context.InitFromRDAT((char *)pBlob->GetBufferPointer(), pBlob->GetBufferSize());
|
||||
FunctionTableReader *funcTableReader = context.GetFunctionTableReader();
|
||||
ResourceTableReader *resTableReader = context.GetResourceTableReader();
|
||||
VERIFY_ARE_EQUAL(funcTableReader->GetNumFunctions(), 4);
|
||||
auto funcTable = context.GetFunctionTable();
|
||||
auto resTable = context.GetResourceTable();
|
||||
VERIFY_ARE_EQUAL(funcTable.Count(), 4);
|
||||
std::string str("function");
|
||||
for (uint32_t j = 0; j < funcTableReader->GetNumFunctions(); ++j) {
|
||||
FunctionReader funcReader = funcTableReader->GetItem(j);
|
||||
std::string funcName(funcReader.GetUnmangledName());
|
||||
for (uint32_t j = 0; j < funcTable.Count(); ++j) {
|
||||
auto funcReader = funcTable[j];
|
||||
std::string funcName(funcReader.getUnmangledName());
|
||||
VERIFY_IS_TRUE(str.compare(funcName.substr(0,8)) == 0);
|
||||
std::string cur_str = str;
|
||||
cur_str.push_back('0' + j);
|
||||
if (cur_str.compare("function0") == 0) {
|
||||
VERIFY_ARE_EQUAL(funcReader.GetNumResources(), 1);
|
||||
VERIFY_ARE_EQUAL(funcReader.getResources().Count(), 1);
|
||||
hlsl::ShaderFlags flag;
|
||||
flag.SetUAVLoadAdditionalFormats(true);
|
||||
flag.SetLowPrecisionPresent(true);
|
||||
uint64_t rawFlag = flag.GetFeatureInfo();
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlag(), rawFlag);
|
||||
ResourceReader resReader = funcReader.GetResource(0);
|
||||
VERIFY_ARE_EQUAL(resReader.GetResourceClass(), hlsl::DXIL::ResourceClass::UAV);
|
||||
VERIFY_ARE_EQUAL(resReader.GetResourceKind(), hlsl::DXIL::ResourceKind::Texture1D);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlags(), rawFlag);
|
||||
auto resReader = funcReader.getResources()[0];
|
||||
VERIFY_ARE_EQUAL(resReader.getClass(), hlsl::DXIL::ResourceClass::UAV);
|
||||
VERIFY_ARE_EQUAL(resReader.getKind(), hlsl::DXIL::ResourceKind::Texture1D);
|
||||
}
|
||||
else if (cur_str.compare("function1") == 0) {
|
||||
hlsl::ShaderFlags flag;
|
||||
flag.SetLowPrecisionPresent(true);
|
||||
uint64_t rawFlag = flag.GetFeatureInfo();
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlag(), rawFlag);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetNumResources(), 3);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlags(), rawFlag);
|
||||
VERIFY_ARE_EQUAL(funcReader.getResources().Count(), 3);
|
||||
}
|
||||
else if (cur_str.compare("function2") == 0) {
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlag() & 0xffffffffffffffff, 0);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetNumResources(), 0);
|
||||
std::string dependency = funcReader.GetDependency(0);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlags() & 0xffffffffffffffff, 0);
|
||||
VERIFY_ARE_EQUAL(funcReader.getResources().Count(), 0);
|
||||
std::string dependency = funcReader.getFunctionDependencies()[0];
|
||||
VERIFY_IS_TRUE(dependency.find("function_import") != std::string::npos);
|
||||
}
|
||||
else if (cur_str.compare("function3") == 0) {
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlag() & 0xffffffffffffffff, 0);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetNumResources(), numResFlagCheck);
|
||||
for (unsigned i = 0; i < funcReader.GetNumResources(); ++i) {
|
||||
ResourceReader resReader = funcReader.GetResource(0);
|
||||
VERIFY_ARE_EQUAL(resReader.GetResourceClass(), hlsl::DXIL::ResourceClass::UAV);
|
||||
VERIFY_ARE_EQUAL(funcReader.GetFeatureFlags() & 0xffffffffffffffff, 0);
|
||||
VERIFY_ARE_EQUAL(funcReader.getResources().Count(), numResFlagCheck);
|
||||
for (unsigned i = 0; i < funcReader.getResources().Count(); ++i) {
|
||||
auto resReader = funcReader.getResources()[0];
|
||||
VERIFY_ARE_EQUAL(resReader.getClass(), hlsl::DXIL::ResourceClass::UAV);
|
||||
unsigned j = 0;
|
||||
for (; j < numResFlagCheck; ++j) {
|
||||
if (resFlags[j].name.compare(resReader.GetName()) == 0)
|
||||
if (resFlags[j].name.compare(resReader.getName()) == 0)
|
||||
break;
|
||||
}
|
||||
VERIFY_IS_LESS_THAN(j, numResFlagCheck);
|
||||
VERIFY_ARE_EQUAL(resReader.GetResourceKind(), resFlags[j].kind);
|
||||
VERIFY_ARE_EQUAL(resReader.GetFlags(), static_cast<uint32_t>(resFlags[j].flag));
|
||||
VERIFY_ARE_EQUAL(resReader.getKind(), resFlags[j].kind);
|
||||
VERIFY_ARE_EQUAL(resReader.getFlags(), static_cast<uint32_t>(resFlags[j].flag));
|
||||
}
|
||||
}
|
||||
else {
|
||||
IFTBOOLMSG(false, E_FAIL, "unknown function name");
|
||||
}
|
||||
}
|
||||
VERIFY_ARE_EQUAL(resTableReader->GetNumResources(), 8);
|
||||
VERIFY_ARE_EQUAL(resTable.Count(), 8);
|
||||
// This is validation test for DxilRuntimeReflection implemented on DxilRuntimeReflection.inl
|
||||
unique_ptr<DxilRuntimeReflection> pReflection(CreateDxilRuntimeReflection());
|
||||
VERIFY_IS_TRUE(pReflection->InitFromRDAT(pBlob->GetBufferPointer(), pBlob->GetBufferSize()));
|
||||
|
@ -1184,19 +1184,19 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT2) {
|
|||
IFT(pReflection->GetPartContent(i, &pBlob));
|
||||
DxilRuntimeData context;
|
||||
context.InitFromRDAT((char *)pBlob->GetBufferPointer(), pBlob->GetBufferSize());
|
||||
FunctionTableReader *funcTableReader = context.GetFunctionTableReader();
|
||||
ResourceTableReader *resTableReader = context.GetResourceTableReader();
|
||||
VERIFY_IS_TRUE(funcTableReader->GetNumFunctions() == 1);
|
||||
VERIFY_IS_TRUE(resTableReader->GetNumResources() == 3);
|
||||
FunctionReader funcReader = funcTableReader->GetItem(0);
|
||||
llvm::StringRef name(funcReader.GetUnmangledName());
|
||||
auto funcTable = context.GetFunctionTable();
|
||||
auto resTable = context.GetResourceTable();
|
||||
VERIFY_IS_TRUE(funcTable.Count() == 1);
|
||||
VERIFY_IS_TRUE(resTable.Count() == 3);
|
||||
auto funcReader = funcTable[0];
|
||||
llvm::StringRef name(funcReader.getUnmangledName());
|
||||
VERIFY_IS_TRUE(name.compare("RayGenMain") == 0);
|
||||
VERIFY_IS_TRUE(funcReader.GetShaderKind() ==
|
||||
VERIFY_IS_TRUE(funcReader.getShaderKind() ==
|
||||
hlsl::DXIL::ShaderKind::RayGeneration);
|
||||
VERIFY_IS_TRUE(funcReader.GetNumResources() == 3);
|
||||
VERIFY_IS_TRUE(funcReader.GetNumDependencies() == 1);
|
||||
VERIFY_IS_TRUE(funcReader.getResources().Count() == 3);
|
||||
VERIFY_IS_TRUE(funcReader.getFunctionDependencies().Count() == 1);
|
||||
llvm::StringRef dependencyName =
|
||||
hlsl::dxilutil::DemangleFunctionName(funcReader.GetDependency(0));
|
||||
hlsl::dxilutil::DemangleFunctionName(funcReader.getFunctionDependencies()[0]);
|
||||
VERIFY_IS_TRUE(dependencyName.compare("function1") == 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -480,6 +480,7 @@ public:
|
|||
D3D_SHADER_MODEL_6_4 = 0x64,
|
||||
D3D_SHADER_MODEL_6_5 = 0x65,
|
||||
D3D_SHADER_MODEL_6_6 = 0x66,
|
||||
D3D_SHADER_MODEL_6_7 = 0x67,
|
||||
} D3D_SHADER_MODEL;
|
||||
|
||||
#if WDK_NTDDI_VERSION == NTDDI_WIN10_RS2
|
||||
|
@ -9307,6 +9308,15 @@ HelperLaneWaveTestResult HelperLane_PSAfterDiscard_ExpectedResults = {
|
|||
{ {0xA, 0, 0, 0}, 1, 2, 4, 1, 0, 0 }
|
||||
};
|
||||
|
||||
HelperLaneWaveTestResult IncludesHelperLane_PS_ExpectedResults = {
|
||||
// HelperLaneWaveTestResult60
|
||||
{ 1, 0, { 0xF, 0, 0, 0 }, 4, 0, 4, 16, 256, 0, 1, 1, 1, 10, 3, 64, 8 },
|
||||
// HelperLaneQuadTestResult
|
||||
{ 0, 1, 0, 1 },
|
||||
// HelperLaneWaveTestResult65
|
||||
{ {0xF, 0, 0, 0}, 3, 8, 64, 0, 1, 1 }
|
||||
};
|
||||
|
||||
bool HelperLaneResultLogAndVerify(const wchar_t* testDesc, uint32_t expectedValue, uint32_t actualValue) {
|
||||
bool matches = (expectedValue == actualValue);
|
||||
LogCommentFmt(L"%s%s, expected = %u, actual = %u", matches ? L" - " : L"FAILED: ", testDesc, expectedValue, actualValue);
|
||||
|
@ -9415,7 +9425,7 @@ TEST_F(ExecutionTest, HelperLaneTestWave) {
|
|||
|
||||
bool testPassed = true;
|
||||
|
||||
D3D_SHADER_MODEL TestShaderModels[] = { D3D_SHADER_MODEL_6_0, D3D_SHADER_MODEL_6_5, D3D_SHADER_MODEL_6_6 };
|
||||
D3D_SHADER_MODEL TestShaderModels[] = { D3D_SHADER_MODEL_6_0, D3D_SHADER_MODEL_6_5, D3D_SHADER_MODEL_6_6, D3D_SHADER_MODEL_6_7 };
|
||||
for (unsigned i = 0; i < _countof(TestShaderModels); i++) {
|
||||
D3D_SHADER_MODEL sm = TestShaderModels[i];
|
||||
LogCommentFmt(L"\r\nVerifying IsHelperLane using Wave intrinsics in shader model 6.%1u", ((UINT)sm & 0x0f));
|
||||
|
@ -9460,6 +9470,13 @@ TEST_F(ExecutionTest, HelperLaneTestWave) {
|
|||
pShaderOp->CS = CS66;
|
||||
pShaderOp->VS = VS66;
|
||||
pShaderOp->PS = PS66;
|
||||
} else if (sm == D3D_SHADER_MODEL_6_7) {
|
||||
// Reassign shader stages to 6.7 versions
|
||||
LPCSTR PS67 = nullptr;
|
||||
for (st::ShaderOpShader& S : pShaderOp->Shaders) {
|
||||
if (!strcmp(S.Name, "PS67")) PS67 = S.Name;
|
||||
}
|
||||
pShaderOp->PS = PS67;
|
||||
}
|
||||
|
||||
const unsigned CS_INDEX = 0, VS_INDEX = 0, PS_INDEX = 1, PS_INDEX_AFTER_DISCARD = 2;
|
||||
|
@ -9475,7 +9492,15 @@ TEST_F(ExecutionTest, HelperLaneTestWave) {
|
|||
LogCommentFmt(L"\r\nCompute shader");
|
||||
smPassed &= VerifyHelperLaneWaveResults(sm, pTestResults[CS_INDEX], HelperLane_CS_ExpectedResults, true);
|
||||
}
|
||||
|
||||
|
||||
HelperLaneWaveTestResult &PS_ExpectedResults =
|
||||
(sm >= D3D_SHADER_MODEL_6_7) ? IncludesHelperLane_PS_ExpectedResults
|
||||
: HelperLane_PS_ExpectedResults;
|
||||
HelperLaneWaveTestResult &PSAfterDiscard_ExpectedResults =
|
||||
(sm >= D3D_SHADER_MODEL_6_7)
|
||||
? IncludesHelperLane_PS_ExpectedResults
|
||||
: HelperLane_PSAfterDiscard_ExpectedResults;
|
||||
|
||||
// Test Vertex + Pixel shader
|
||||
{
|
||||
pShaderOp->CS = nullptr;
|
||||
|
@ -9487,9 +9512,9 @@ TEST_F(ExecutionTest, HelperLaneTestWave) {
|
|||
LogCommentFmt(L"\r\nVertex shader");
|
||||
smPassed &= VerifyHelperLaneWaveResults(sm, pTestResults[VS_INDEX], HelperLane_VS_ExpectedResults, false);
|
||||
LogCommentFmt(L"\r\nPixel shader");
|
||||
smPassed &= VerifyHelperLaneWaveResults(sm, pTestResults[PS_INDEX], HelperLane_PS_ExpectedResults, true);
|
||||
smPassed &= VerifyHelperLaneWaveResults(sm, pTestResults[PS_INDEX], PS_ExpectedResults, true);
|
||||
LogCommentFmt(L"\r\nPixel shader with discarded pixel");
|
||||
smPassed &= VerifyHelperLaneWaveResults(sm, pTestResults[PS_INDEX_AFTER_DISCARD], HelperLane_PSAfterDiscard_ExpectedResults, true);
|
||||
smPassed &= VerifyHelperLaneWaveResults(sm, pTestResults[PS_INDEX_AFTER_DISCARD], PSAfterDiscard_ExpectedResults, true);
|
||||
|
||||
MappedData renderData;
|
||||
test->Test->GetReadBackData("RTarget", &renderData);
|
||||
|
|
|
@ -8,10 +8,12 @@ add_clang_library(HLSLTestLib
|
|||
DxcTestUtils.cpp
|
||||
FileCheckerTest.cpp
|
||||
FileCheckForTest.cpp
|
||||
RDATDumper.cpp
|
||||
)
|
||||
else(WIN32)
|
||||
set(HLSL_IGNORE_SOURCES
|
||||
D3DReflectionDumper.cpp
|
||||
RDATDumper.cpp
|
||||
)
|
||||
add_clang_library(HLSLTestLib
|
||||
DxcTestUtils.cpp
|
||||
|
|
|
@ -13,35 +13,14 @@
|
|||
#include "dxc/DXIL/DxilConstants.h"
|
||||
#include "dxc/test/D3DReflectionDumper.h"
|
||||
#include "dxc/DxilContainer/DxilContainer.h"
|
||||
#include "dxc/dxcapi.h"
|
||||
#include <sstream>
|
||||
|
||||
// Remove this workaround once newer version of d3dcommon.h can be compiled against
|
||||
#define ADD_16_64_BIT_TYPES
|
||||
// Disable warning about value not being valid in enum
|
||||
#pragma warning( disable : 4063 )
|
||||
|
||||
// Copied from llvm/ADT/StringExtras.h
|
||||
static inline char hexdigit(unsigned X, bool LowerCase = false) {
|
||||
const char HexChar = LowerCase ? 'a' : 'A';
|
||||
return X < 10 ? '0' + X : HexChar + X - 10;
|
||||
}
|
||||
// Copied from lib/IR/AsmWriter.cpp
|
||||
// PrintEscapedString - Print each character of the specified string, escaping
|
||||
// it if it is not printable or if it is an escape char.
|
||||
static std::string EscapedString(const char *text) {
|
||||
std::ostringstream ss;
|
||||
size_t size = strlen(text);
|
||||
for (unsigned i = 0, e = size; i != e; ++i) {
|
||||
unsigned char C = text[i];
|
||||
if (isprint(C) && C != '\\' && C != '"')
|
||||
ss << C;
|
||||
else
|
||||
ss << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
namespace refl_dump {
|
||||
namespace hlsl {
|
||||
namespace dump {
|
||||
|
||||
LPCSTR ToString(D3D_CBUFFER_TYPE CBType) {
|
||||
switch (CBType) {
|
||||
|
@ -235,6 +214,8 @@ LPCSTR ToString(D3D_SHADER_VARIABLE_CLASS Class) {
|
|||
}
|
||||
|
||||
#ifdef ADD_16_64_BIT_TYPES
|
||||
// Disable warning about value not being valid in enum
|
||||
#pragma warning( disable : 4063 )
|
||||
#define D3D_SVT_INT16 ((D3D_SHADER_VARIABLE_TYPE)58)
|
||||
#define D3D_SVT_UINT16 ((D3D_SHADER_VARIABLE_TYPE)59)
|
||||
#define D3D_SVT_FLOAT16 ((D3D_SHADER_VARIABLE_TYPE)60)
|
||||
|
@ -852,4 +833,5 @@ void D3DReflectionDumper::Dump(ID3D12LibraryReflection *pLibraryReflection) {
|
|||
Dedent();
|
||||
}
|
||||
|
||||
} // namespace refl_dump
|
||||
} // namespace dump
|
||||
} // namespace hlsl
|
||||
|
|
|
@ -44,9 +44,11 @@
|
|||
|
||||
#ifdef _WIN32 // Reflection unsupported
|
||||
#include "dxc/Test/D3DReflectionDumper.h"
|
||||
#include "dxc/DxilContainer/DxilRuntimeReflection.h"
|
||||
#include "dxc/Test/RDATDumper.h"
|
||||
|
||||
#include "d3d12shader.h"
|
||||
using namespace refl_dump;
|
||||
using namespace hlsl::dump;
|
||||
#endif // WIN32 - Reflection unsupported
|
||||
|
||||
using namespace std;
|
||||
|
@ -713,6 +715,13 @@ FileRunCommandResult FileRunCommandPart::RunD3DReflect(dxc::DxcDllSupport &DllSu
|
|||
else
|
||||
VERIFY_SUCCEEDED(containerReflection->GetPartReflection(i, IID_PPV_ARGS(&pShaderReflection)));
|
||||
break;
|
||||
} else if (kind == (uint32_t)hlsl::DxilFourCC::DFCC_RuntimeData) {
|
||||
CComPtr<IDxcBlob> pPart;
|
||||
IFT(containerReflection->GetPartContent(i, &pPart));
|
||||
hlsl::RDAT::DxilRuntimeData rdat(pPart->GetBufferPointer(),
|
||||
pPart->GetBufferSize());
|
||||
DumpContext d(ss);
|
||||
DumpRuntimeData(rdat, d);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// RDATDumper.cpp //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Use this to dump DxilRuntimeData (RDAT) for testing. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dxc/Support/Global.h"
|
||||
#include "dxc/test/RDATDumper.h"
|
||||
|
||||
using namespace hlsl;
|
||||
using namespace RDAT;
|
||||
|
||||
namespace hlsl {
|
||||
namespace dump {
|
||||
|
||||
void DumpRuntimeData(const RDAT::DxilRuntimeData &RDAT, DumpContext &d) {
|
||||
const RDATContext &ctx = RDAT.GetContext();
|
||||
d.WriteLn("DxilRuntimeData (size = ", RDAT.GetDataSize(), " bytes):");
|
||||
d.Indent();
|
||||
|
||||
d.WriteLn("StringBuffer (size = ", ctx.StringBuffer.Size(), " bytes)");
|
||||
d.WriteLn("IndexTable (size = ", ctx.IndexTable.Count() * 4, " bytes)");
|
||||
d.WriteLn("RawBytes (size = ", ctx.RawBytes.Size(), " bytes)");
|
||||
|
||||
// Once per table.
|
||||
#define RDAT_STRUCT_TABLE(type, table) DumpRecordTable<type>(ctx, d, #table, ctx.Table(RecordTableIndex::table));
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_DEFAULTS
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
d.Dedent();
|
||||
}
|
||||
|
||||
template<typename RecordType>
|
||||
void DumpRecordTable(const RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tableName, const RDAT::TableReader &table) {
|
||||
if (!table.Count())
|
||||
return;
|
||||
d.WriteLn("RecordTable (stride = ", table.Stride(), " bytes) ", tableName, "[", table.Count(), "] = {");
|
||||
d.Indent();
|
||||
for (unsigned i = 0; i < table.Count(); i++) {
|
||||
DumpRecordTableEntry<RecordType>(ctx, d, i);
|
||||
}
|
||||
d.Dedent();
|
||||
d.WriteLn("}");
|
||||
}
|
||||
|
||||
template<typename RecordType>
|
||||
void DumpRecordTableEntry(const RDAT::RDATContext &ctx, DumpContext &d,
|
||||
uint32_t i) {
|
||||
// Visit() will prevent recursive/repeated reference expansion. Resetting
|
||||
// for each top-level table entry prevents a record from dumping differently
|
||||
// depending on differences in other unrelated records.
|
||||
d.VisitReset();
|
||||
|
||||
// RecordRefDumper handles derived types.
|
||||
RecordRefDumper<RecordType> rrDumper(i);
|
||||
|
||||
d.WriteLn("<", i, ":", rrDumper.TypeName(ctx), "> = {");
|
||||
rrDumper.Dump(ctx, d);
|
||||
d.WriteLn("}");
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
void DumpRecordValue(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tyName, const char *memberName,
|
||||
const _T *memberPtr) {
|
||||
d.WriteLn(memberName, ": <", tyName, ">");
|
||||
DumpWithBase(ctx, d, memberPtr);
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
void DumpRecordRef(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tyName, const char *memberName,
|
||||
hlsl::RDAT::RecordRef<_T> rr) {
|
||||
RecordRefDumper<_T> rrDumper(rr.Index);
|
||||
const char *storedTypeName = rrDumper.TypeName(ctx);
|
||||
if (nullptr == storedTypeName)
|
||||
storedTypeName = tyName;
|
||||
// Unique visit location is based on end of struct so derived are not skipped
|
||||
if (d.Visit(rr.Get(ctx))) {
|
||||
d.WriteLn(memberName, ": <", rr.Index, ":", storedTypeName, "> = {");
|
||||
rrDumper.Dump(ctx, d);
|
||||
d.WriteLn("}");
|
||||
} else {
|
||||
d.WriteLn(memberName, ": <", rr.Index, ":", storedTypeName, ">");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
void DumpRecordArrayRef(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *tyName, const char *memberName,
|
||||
hlsl::RDAT::RecordArrayRef<_T> rar) {
|
||||
auto row = ctx.IndexTable.getRow(rar.Index);
|
||||
if (row.Count()) {
|
||||
d.WriteLn(memberName, ": <", rar.Index, ":RecordArrayRef<", tyName, ">[", row.Count(), "]> = {");
|
||||
d.Indent();
|
||||
for (uint32_t i = 0; i < row.Count(); ++i) {
|
||||
RecordRefDumper<_T> rrDumper(row.At(i));
|
||||
if (rrDumper.Get(ctx)) {
|
||||
if (d.Visit(rrDumper.Get(ctx))) {
|
||||
d.WriteLn("[", i, "]: <", rrDumper.Index, ":", rrDumper.TypeName(ctx), "> = {");
|
||||
rrDumper.Dump(ctx, d);
|
||||
d.WriteLn("}");
|
||||
} else {
|
||||
d.WriteLn("[", i, "]: <", rrDumper.Index, ":", rrDumper.TypeName(ctx), ">");
|
||||
}
|
||||
} else {
|
||||
d.WriteLn("[", i, "]: <", row.At(i), ":", tyName, "> = <nullptr>");
|
||||
}
|
||||
}
|
||||
d.Dedent();
|
||||
d.WriteLn("}");
|
||||
} else {
|
||||
d.WriteLn(memberName, ": <RecordArrayRef<", tyName, ">[0]> = {}");
|
||||
}
|
||||
}
|
||||
|
||||
void DumpStringArray(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *memberName,
|
||||
hlsl::RDAT::RDATStringArray sa) {
|
||||
auto sar = sa.Get(ctx);
|
||||
if (sar && sar.Count()) {
|
||||
d.WriteLn(memberName, ": <", sa.Index, ":string[", sar.Count(), "]> = {");
|
||||
d.Indent();
|
||||
for (uint32_t _i = 0; _i < (uint32_t)sar.Count(); ++_i) {
|
||||
const char *str = sar[_i];
|
||||
if (str) {
|
||||
d.WriteLn("[", _i, "]: ", QuotedStringValue(str));
|
||||
} else {
|
||||
d.WriteLn("[", _i, "]: <nullptr>");
|
||||
}
|
||||
}
|
||||
d.Dedent();
|
||||
d.WriteLn("}");
|
||||
} else {
|
||||
d.WriteLn(memberName, ": <string[0]> = {}");
|
||||
}
|
||||
}
|
||||
|
||||
// Currently dumps index array inline
|
||||
void DumpIndexArray(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *memberName, uint32_t index) {
|
||||
auto indexArray = ctx.IndexTable.getRow(index);
|
||||
unsigned arraySize = indexArray.Count();
|
||||
std::ostringstream oss;
|
||||
std::ostream &os = oss;
|
||||
d.Write(os, memberName, ": <", index, ":array[", arraySize, "]> = { ");
|
||||
for (unsigned i = 0; i < arraySize; ++i) {
|
||||
d.Write(os, indexArray[i]);
|
||||
if (i < arraySize - 1)
|
||||
d.Write(os, ", ");
|
||||
}
|
||||
d.Write(os, " }");
|
||||
d.WriteLn(oss.str());
|
||||
}
|
||||
|
||||
void DumpBytesRef(const hlsl::RDAT::RDATContext &ctx, DumpContext &d,
|
||||
const char *memberName,
|
||||
hlsl::RDAT::BytesRef bytesRef) {
|
||||
d.WriteLn(memberName, ": <", bytesRef.Offset, ":bytes[", bytesRef.Size, "]>");
|
||||
}
|
||||
|
||||
template<typename _T>
|
||||
void DumpValueArray(DumpContext &d, const char *memberName,
|
||||
const char *typeName, const void *valueArray,
|
||||
unsigned arraySize) {
|
||||
d.WriteLn(memberName, ": ", typeName, "[", arraySize, "] = { ");
|
||||
for (unsigned i = 0; i < arraySize; i++) {
|
||||
d.Write(((const _T*)valueArray)[i]);
|
||||
if (i < arraySize - 1)
|
||||
d.Write(", ");
|
||||
}
|
||||
d.WriteLn(" }");
|
||||
}
|
||||
|
||||
#define DEF_RDAT_TYPES DEF_RDAT_DUMP_IMPL
|
||||
#define DEF_RDAT_ENUMS DEF_RDAT_DUMP_IMPL
|
||||
#define DEF_DXIL_ENUMS DEF_RDAT_DUMP_IMPL
|
||||
#include "dxc/DxilContainer/RDAT_Macros.inl"
|
||||
|
||||
} // namespace dump
|
||||
} // namespace hlsl
|
|
@ -300,6 +300,8 @@ $type1 [[]] QuadReadLaneAt(in numeric<> value, in uint quadLane);
|
|||
$type1 [[]] QuadReadAcrossX(in numeric<> value);
|
||||
$type1 [[]] QuadReadAcrossY(in numeric<> value);
|
||||
$type1 [[]] QuadReadAcrossDiagonal(in numeric<> value);
|
||||
bool [[]] QuadAny(in bool cond);
|
||||
bool [[]] QuadAll(in bool cond);
|
||||
|
||||
// Raytracing
|
||||
void [[]] TraceRay(in acceleration_struct AccelerationStructure, in uint RayFlags, in uint InstanceInclusionMask, in uint RayContributionToHitGroupIndex, in uint MultiplierForGeometryContributionToHitGroupIndex, in uint MissShaderIndex, in ray_desc Ray, inout udt Payload);
|
||||
|
@ -409,6 +411,8 @@ $classT [[ro]] SampleBias(in sampler s, in float<1> x, in float bias) : tex1d_t_
|
|||
$classT [[ro]] SampleBias(in sampler s, in float<1> x, in float bias, in int<1> o) : tex1d_t_bias_o;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue) : tex1d_t_comp;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o) : tex1d_t_comp_o;
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<1> x, in float compareValue, in float lod);
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<1> x, in float compareValue, in float lod, in int<1> o);
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<1> x, in float compareValue) : tex1d_t_comp_lz;
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o) : tex1d_t_comp_lz_o;
|
||||
$classT [[ro]] SampleGrad(in sampler s, in float<1> x, in $type2 ddx, in $type2 ddy) : tex1d_t_dd;
|
||||
|
@ -419,6 +423,7 @@ $classT [[ro]] Sample(in sampler s, in float<1> x, in int<1> o, in float clamp)
|
|||
$classT [[]] Sample(in sampler s, in float<1> x, in int<1> o, in float clamp, out uint_only status) : tex1d_t_o_cl_s;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o, in float clamp) : tex1d_t_comp_o_cl;
|
||||
float_like [[]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_o_cl_s;
|
||||
float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<1> x, in float compareValue, in float lod, in int<1> o, out uint_only status);
|
||||
float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o, out uint_only status) : tex1d_t_comp_o_s;
|
||||
$classT [[]] SampleLevel(in sampler s, in float<1> x, in float lod, in int<1> o, out uint_only status) : tex1d_t_lod_o_s;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<1> x, in float bias, in int<1> o, in float clamp) : tex1d_t_bias_o_cl;
|
||||
|
@ -444,6 +449,8 @@ $classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias) : tex1d_t_
|
|||
$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<1> o) : tex1d_t_bias_array_o;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue) : tex1d_t_comp_array;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o) : tex1d_t_comp_array_o;
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod);
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<1> o);
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue) : tex1d_t_comp_lz_array;
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o) : tex1d_t_comp_lz_array_o;
|
||||
$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy) : tex1d_t_dd_array;
|
||||
|
@ -454,6 +461,7 @@ $classT [[ro]] Sample(in sampler s, in float<2> x, in int<1> o, in float clamp)
|
|||
$classT [[]] Sample(in sampler s, in float<2> x, in int<1> o, in float clamp, out uint_only status) : tex1d_t_array_o_cl_s;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o, in float clamp) : tex1d_t_comp_array_o_cl;
|
||||
float_like [[]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_array_o_cl_s;
|
||||
float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<1> o, out uint_only status);
|
||||
float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o, out uint_only status) : tex1d_t_comp_array_o_s;
|
||||
$classT [[]] SampleLevel(in sampler s, in float<2> x, in float lod, in int<1> o, out uint_only status) : tex1d_t_lod_array_o_s;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<1> o, in float clamp) : tex1d_t_bias_array_o_cl;
|
||||
|
@ -507,6 +515,8 @@ $classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias) : tex2d_t_
|
|||
$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<2> o) : tex2d_t_bias_o;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_comp;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_comp_o;
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod);
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<2> o);
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_comp_lz;
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_comp_lz_o;
|
||||
$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $type2 ddx, in $type2 ddy) : tex2d_t_dd;
|
||||
|
@ -517,6 +527,7 @@ $classT [[ro]] Sample(in sampler s, in float<2> x, in int<2> o, in float clamp)
|
|||
$classT [[]] Sample(in sampler s, in float<2> x, in int<2> o, in float clamp, out uint_only status) : tex2d_t_o_cl_s;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, in float clamp) : tex2d_t_comp_o_cl;
|
||||
float_like [[]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_o_cl_s;
|
||||
float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<2> o, out uint_only status);
|
||||
float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_comp_o_s;
|
||||
$classT [[]] SampleLevel(in sampler s, in float<2> x, in float lod, in int<2> o, out uint_only status) : tex2d_t_lod_o_s;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<2> o, in float clamp) : tex2d_t_bias_o_cl;
|
||||
|
@ -543,6 +554,9 @@ $match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<2> x, in floa
|
|||
$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_green_o4_s;
|
||||
$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_blue_o4_s;
|
||||
$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_alpha_o4_s;
|
||||
$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<2> x);
|
||||
$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<2> x, in int<2> o);
|
||||
$match<0, -1> void<4> [[]] GatherRaw(in sampler s, in float<2> x, in int<2> o, out uint_only status);
|
||||
} namespace
|
||||
|
||||
namespace Texture2DMSMethods {
|
||||
|
@ -601,6 +615,8 @@ $classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias) : tex2d_t_
|
|||
$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in int<2> o) : tex2d_t_bias_array_o;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_comp_array;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_comp_array_o;
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod);
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod, in int<2> o);
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_comp_lz_array;
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_comp_lz_array_o;
|
||||
$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy) : tex2d_t_dd_array;
|
||||
|
@ -611,6 +627,7 @@ $classT [[ro]] Sample(in sampler s, in float<3> x, in int<2> o, in float clamp)
|
|||
$classT [[]] Sample(in sampler s, in float<3> x, in int<2> o, in float clamp, out uint_only status) : tex2d_t_array_o_cl_s;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, in float clamp) : tex2d_t_comp_array_o_cl;
|
||||
float_like [[]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_array_o_cl_s;
|
||||
float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod, in int<2> o, out uint_only status);
|
||||
float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_comp_array_o_s;
|
||||
$classT [[]] SampleLevel(in sampler s, in float<3> x, in float lod, in int<2> o, out uint_only status) : tex2d_t_lod_array_o_s;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in int<2> o, in float clamp) : tex2d_t_bias_array_o_cl;
|
||||
|
@ -635,6 +652,9 @@ $match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<3> x, in floa
|
|||
$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_green_array_o4_s;
|
||||
$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_blue_array_o4_s;
|
||||
$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_alpha_array_o4_s;
|
||||
$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<3> x);
|
||||
$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<3> x, in int<2> o);
|
||||
$match<0, -1> void<4> [[]] GatherRaw(in sampler s, in float<3> x, in int<2> o, out uint_only status);
|
||||
} namespace
|
||||
|
||||
namespace Texture2DArrayMSMethods {
|
||||
|
@ -697,6 +717,7 @@ void [[]] GetDimensions(out float_like width, out $type1 height) : resinfo_o;
|
|||
$classT [[ro]] Sample(in sampler s, in float<3> x) : texcube_t;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias) : texcube_t_bias;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float c) : texcube_t_comp;
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float c, in float lod);
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float c) : texcube_t_comp_lz;
|
||||
$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy) : texcube_t_dd;
|
||||
$classT [[ro]] SampleLevel(in sampler s, in float<3> x, in float lod) : texcube_t_lod;
|
||||
|
@ -704,6 +725,7 @@ $classT [[ro]] Sample(in sampler s, in float<3> x, in float clamp) : texcube_t_c
|
|||
$classT [[]] Sample(in sampler s, in float<3> x, in float clamp, out uint_only status) : texcube_t_cl_s;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in float clamp) : texcube_t_comp_cl;
|
||||
float_like [[]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in float clamp, out uint_only status) : texcube_t_comp_cl_s;
|
||||
float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod, out uint_only status);
|
||||
float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_comp_s;
|
||||
$classT [[]] SampleLevel(in sampler s, in float<3> x, in float lod, out uint_only status) : texcube_t_lod_s;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in float clamp) : texcube_t_bias_cl;
|
||||
|
@ -743,6 +765,7 @@ void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elem
|
|||
$classT [[ro]] Sample(in sampler s, in float<4> x) : texcube_t_array;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<4> x, in float bias) : texcube_t_bias_array;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<4> x, in float c) : texcube_t_comp_array;
|
||||
float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<4> x, in float c, in float lod);
|
||||
float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<4> x, in float c) : texcube_t_comp_lz_array;
|
||||
$classT [[ro]] SampleGrad(in sampler s, in float<4> x, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy) : texcube_t_dd_array;
|
||||
$classT [[ro]] SampleLevel(in sampler s, in float<4> x, in float lod) : texcube_t_lod_array;
|
||||
|
@ -750,6 +773,7 @@ $classT [[ro]] Sample(in sampler s, in float<4> x, in float clamp) : texcube_t_a
|
|||
$classT [[]] Sample(in sampler s, in float<4> x, in float clamp, out uint_only status) : texcube_t_array_cl_s;
|
||||
float_like [[ro]] SampleCmp(in sampler_cmp s, in float<4> x, in float compareValue, in float clamp) : texcube_t_comp_array_cl;
|
||||
float_like [[]] SampleCmp(in sampler_cmp s, in float<4> x, in float compareValue, in float clamp, out uint_only status) : texcube_t_comp_array_cl_s;
|
||||
float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<4> x, in float compareValue, in float lod, out uint_only status);
|
||||
float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_comp_array_s;
|
||||
$classT [[]] SampleLevel(in sampler s, in float<4> x, in float lod, out uint_only status) : texcube_t_lod_array_s;
|
||||
$classT [[ro]] SampleBias(in sampler s, in float<4> x, in float bias, in float clamp) : texcube_t_bias_array_cl;
|
||||
|
@ -808,6 +832,24 @@ $classT [[ro]] Load(in int<3> x) : rwtex2d_load_array;
|
|||
$classT [[]] Load(in int<3> x, out uint_only status) : rwtex2d_load_array_s;
|
||||
} namespace
|
||||
|
||||
namespace RWTexture2DMSMethods {
|
||||
|
||||
void [[]] GetDimensions(out uint_only width, out $type1 height, out $type2 samples);
|
||||
void [[]] GetDimensions(out float_like width, out $type1 height, out $type2 samples);
|
||||
float_like<2> [[ro]] GetSamplePosition(in int s);
|
||||
$classT [[ro]] Load(in int<2> x, in int s);
|
||||
$classT [[]] Load(in int<2> x, in int s, out uint_only status);
|
||||
} namespace
|
||||
|
||||
namespace RWTexture2DMSArrayMethods {
|
||||
|
||||
void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 elements, out $type1 samples);
|
||||
void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elements, out $type1 samples);
|
||||
float_like<2> [[ro]] GetSamplePosition(in int s);
|
||||
$classT [[ro]] Load(in int<3> x, in int s);
|
||||
$classT [[]] Load(in int<3> x, in int s, out uint_only status);
|
||||
} namespace
|
||||
|
||||
namespace RWTexture3DMethods {
|
||||
|
||||
void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 depth) : resinfo_uint_o;
|
||||
|
|
|
@ -384,7 +384,7 @@ exit /b 0
|
|||
echo Builds HLSL solutions and the product and test binaries for the current
|
||||
echo flavor and architecture.
|
||||
echo.
|
||||
echo hctbuild [-s or -b] [-alldef] [-analyze] [-official] [-fv] [-fvloc <path>] [-rel] [-arm or -arm64 or -x86 or -x64] [-Release] [-Debug] [-vs2017] [-vs2019] [-ninja] [-tblgen path] [-speak-up] [-no-parallel] [-no-dxilconv] [-update-generated-soures]
|
||||
echo hctbuild [-s or -b] [-alldef] [-analyze] [-official] [-fv] [-fvloc <path>] [-rel] [-arm or -arm64 or -x86 or -x64] [-Release] [-Debug] [-vs2017] [-vs2019] [-ninja] [-tblgen path] [-speak-up] [-no-parallel] [-no-dxilconv] [-update-generated-sources]
|
||||
echo.
|
||||
echo -s creates the projects only, without building
|
||||
echo -b builds the existing project
|
||||
|
|
|
@ -288,15 +288,15 @@ class db_dxil(object):
|
|||
self.name_idx[i].category = "Quaternary"
|
||||
for i in "Dot2,Dot3,Dot4".split(","):
|
||||
self.name_idx[i].category = "Dot"
|
||||
for i in "CreateHandle,CBufferLoad,CBufferLoadLegacy,TextureLoad,TextureStore,BufferLoad,BufferStore,BufferUpdateCounter,CheckAccessFullyMapped,GetDimensions,RawBufferLoad,RawBufferStore".split(","):
|
||||
for i in "CreateHandle,CBufferLoad,CBufferLoadLegacy,TextureLoad,TextureStore,TextureStoreSample,BufferLoad,BufferStore,BufferUpdateCounter,CheckAccessFullyMapped,GetDimensions,RawBufferLoad,RawBufferStore".split(","):
|
||||
self.name_idx[i].category = "Resources"
|
||||
for i in "Sample,SampleBias,SampleLevel,SampleGrad,SampleCmp,SampleCmpLevelZero,Texture2DMSGetSamplePosition,RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","):
|
||||
for i in "Sample,SampleBias,SampleLevel,SampleGrad,SampleCmp,SampleCmpLevelZero,SampleCmpLevel,Texture2DMSGetSamplePosition,RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","):
|
||||
self.name_idx[i].category = "Resources - sample"
|
||||
for i in "Sample,SampleBias,SampleCmp".split(","):
|
||||
self.name_idx[i].shader_stages = ("library", "pixel", "compute", "amplification", "mesh")
|
||||
for i in "RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","):
|
||||
self.name_idx[i].shader_stages = ("pixel",)
|
||||
for i in "TextureGather,TextureGatherCmp".split(","):
|
||||
for i in "TextureGather,TextureGatherCmp,TextureGatherRaw".split(","):
|
||||
self.name_idx[i].category = "Resources - gather"
|
||||
for i in "AtomicBinOp,AtomicCompareExchange,Barrier".split(","):
|
||||
self.name_idx[i].category = "Synchronization"
|
||||
|
@ -411,6 +411,8 @@ class db_dxil(object):
|
|||
for i in "AnnotateHandle,CreateHandleFromBinding,CreateHandleFromHeap".split(","):
|
||||
self.name_idx[i].category = "Get handle from heap"
|
||||
self.name_idx[i].shader_model = 6,6
|
||||
for i in "AnnotateHandle,CreateHandleFromBinding".split(","):
|
||||
self.name_idx[i].shader_model_translated = 6,0
|
||||
for i in "Dot4AddU8Packed,Dot4AddI8Packed,Dot2AddHalf".split(","):
|
||||
self.name_idx[i].category = "Dot product with accumulate"
|
||||
self.name_idx[i].shader_model = 6,4
|
||||
|
@ -452,6 +454,10 @@ class db_dxil(object):
|
|||
for i in "IsHelperLane".split(","):
|
||||
self.name_idx[i].category = "Helper Lanes"
|
||||
self.name_idx[i].shader_model = 6,6
|
||||
for i in "QuadVote,TextureGatherRaw,SampleCmpLevel,TextureStoreSample".split(","):
|
||||
self.name_idx[i].shader_model = 6,7
|
||||
for i in "QuadVote".split(","):
|
||||
self.name_idx[i].shader_model_translated = 6,0
|
||||
|
||||
def populate_llvm_instructions(self):
|
||||
# Add instructions that map to LLVM instructions.
|
||||
|
@ -1869,6 +1875,63 @@ class db_dxil(object):
|
|||
self.set_op_count_for_version(1, 6, next_op_idx)
|
||||
assert next_op_idx == 222, "222 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx
|
||||
|
||||
self.add_enum_type("QuadVoteOpKind", "Kind of cross-quad vote operation", [
|
||||
(0, "Any", "true if any condition is true in this quad"),
|
||||
(1, "All", "true if all conditions are true in this quad")])
|
||||
self.add_dxil_op("QuadVote", next_op_idx, "QuadVote", "compares boolean accross a quad", "1", "", [
|
||||
db_dxil_param(0, "i1", "", "result - uniform across quad"),
|
||||
db_dxil_param(2, "i1", "cond", "condition"),
|
||||
db_dxil_param(3, "i8", "op", "QuadVoteOpKind: 0=Any, 1=All", enum_name="QuadVoteOpKind", is_const=True)])
|
||||
next_op_idx += 1
|
||||
|
||||
self.add_dxil_op("TextureGatherRaw", next_op_idx, "TextureGatherRaw", "Gather raw elements from 4 texels with no type conversions (SRV type is constrained)", "wil", "ro", [
|
||||
db_dxil_param(0, "$r", "", "four raw texture elements gathered"),
|
||||
db_dxil_param(2, "res", "srv", "handle of type-matched SRV to gather from"),
|
||||
db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
|
||||
db_dxil_param(4, "f", "coord0", "coordinate"),
|
||||
db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
|
||||
db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
|
||||
db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
|
||||
db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
|
||||
db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray")],
|
||||
counters=('tex_norm',))
|
||||
next_op_idx += 1
|
||||
|
||||
self.add_dxil_op("SampleCmpLevel", next_op_idx, "SampleCmpLevel", "samples a texture and compares a single component against the specified comparison value", "hf", "ro", [
|
||||
db_dxil_param(0, "$r", "", "the result of the filtered comparisons"),
|
||||
db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
|
||||
db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
|
||||
db_dxil_param(4, "f", "coord0", "coordinate"),
|
||||
db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
|
||||
db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
|
||||
db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
|
||||
db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
|
||||
db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
|
||||
db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
|
||||
db_dxil_param(11, "f", "compareValue", "the value to compare with"),
|
||||
db_dxil_param(12, "f", "lod", "level of detail, biggest map if less than or equal to zero; fraction used to interpolate across levels")],
|
||||
counters=('tex_cmp',))
|
||||
next_op_idx += 1
|
||||
|
||||
self.add_dxil_op("TextureStoreSample", next_op_idx, "TextureStoreSample", "stores texel data at specified sample index", "hfwi", "", [
|
||||
db_dxil_param(0, "v", "", ""),
|
||||
db_dxil_param(2, "res", "srv", "handle of Texture2DMS[Array] UAV to store to"),
|
||||
db_dxil_param(3, "i32", "coord0", "coordinate"),
|
||||
db_dxil_param(4, "i32", "coord1", "coordinate"),
|
||||
db_dxil_param(5, "i32", "coord2", "coordinate"),
|
||||
db_dxil_param(6, "$o", "value0", "value"),
|
||||
db_dxil_param(7, "$o", "value1", "value"),
|
||||
db_dxil_param(8, "$o", "value2", "value"),
|
||||
db_dxil_param(9, "$o", "value3", "value"),
|
||||
db_dxil_param(10,"i8", "mask", "written value mask", is_const=True),
|
||||
db_dxil_param(11, "i32", "sampleIdx", "sample index")],
|
||||
counters=('tex_store',))
|
||||
next_op_idx += 1
|
||||
|
||||
# End of DXIL 1.7 opcodes.
|
||||
self.set_op_count_for_version(1, 7, next_op_idx)
|
||||
assert next_op_idx == 226, "226 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx
|
||||
|
||||
# Set interesting properties.
|
||||
self.build_indices()
|
||||
for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp".split(","):
|
||||
|
@ -2618,7 +2681,7 @@ class db_dxil(object):
|
|||
self.add_valrule("Sm.GSValidInputPrimitive", "GS input primitive unrecognized.")
|
||||
self.add_valrule("Sm.GSValidOutputPrimitiveTopology", "GS output primitive topology unrecognized.")
|
||||
self.add_valrule("Sm.AppendAndConsumeOnSameUAV", "BufferUpdateCounter inc and dec on a given UAV (%d) cannot both be in the same shader for shader model less than 5.1.")
|
||||
self.add_valrule("Sm.InvalidTextureKindOnUAV", "Texture2DMS[Array] or TextureCube[Array] resources are not supported with UAVs.")
|
||||
self.add_valrule("Sm.InvalidTextureKindOnUAV", "TextureCube[Array] resources are not supported with UAVs.")
|
||||
self.add_valrule("Sm.InvalidResourceKind", "Invalid resources kind.")
|
||||
self.add_valrule("Sm.InvalidResourceCompType","Invalid resource return type.")
|
||||
self.add_valrule("Sm.InvalidSamplerFeedbackType","Invalid sampler feedback type.")
|
||||
|
|
|
@ -335,6 +335,14 @@ class db_enumhelp_gen:
|
|||
print(" " + lastName + " = " + str(len(sorted_values)) + " // exclusive last value of enumeration")
|
||||
print("};")
|
||||
|
||||
def print_rdat_enum(self, e, **kwargs):
|
||||
nodef = kwargs.get("nodef", False)
|
||||
for v in e.values:
|
||||
line_format = "RDAT_ENUM_VALUE_NODEF({name})" if nodef else "RDAT_ENUM_VALUE({value}, {name})"
|
||||
if v.doc:
|
||||
line_format += " // {doc}"
|
||||
print(line_format.format(name=v.name, value=v.value, doc=v.doc))
|
||||
|
||||
def print_content(self):
|
||||
for e in sorted(self.db.enums, key=lambda e : e.name):
|
||||
self.print_enum(e)
|
||||
|
@ -823,6 +831,11 @@ def get_enum_decl(name, **kwargs):
|
|||
gen = db_enumhelp_gen(db)
|
||||
return run_with_stdout(lambda: gen.print_enum(db.enum_idx[name], **kwargs))
|
||||
|
||||
def get_rdat_enum_decl(name, **kwargs):
|
||||
db = get_db_dxil()
|
||||
gen = db_enumhelp_gen(db)
|
||||
return run_with_stdout(lambda: gen.print_rdat_enum(db.enum_idx[name], **kwargs))
|
||||
|
||||
def get_valrule_enum():
|
||||
return get_enum_decl("ValidationRule", hide_val=True)
|
||||
|
||||
|
@ -1484,6 +1497,7 @@ if __name__ == "__main__":
|
|||
'include/dxc/DXIL/DxilCounters.h',
|
||||
'lib/DXIL/DxilCounters.cpp',
|
||||
'lib/DXIL/DxilMetadataHelper.cpp',
|
||||
'include/dxc/DxilContainer/RDAT_LibraryTypes.inl',
|
||||
]
|
||||
for relative_file_path in files:
|
||||
RunCodeTagUpdate(pj(hlsl_src_dir, relative_file_path))
|
||||
|
|
|
@ -23,7 +23,8 @@ parser.add_argument('mode', choices=['HLSLIntrinsicOp',
|
|||
'DxilPIXPasses',
|
||||
'DxcDisassembler',
|
||||
'DxilCounters',
|
||||
'DxilMetadata'
|
||||
'DxilMetadata',
|
||||
'RDAT_LibraryTypes'
|
||||
])
|
||||
parser.add_argument('--output', required=True)
|
||||
parser.add_argument('--input', default=None)
|
||||
|
|
Загрузка…
Ссылка в новой задаче