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:
Tex Riddell 2022-02-15 11:38:42 -08:00 коммит произвёл GitHub
Родитель 74a1543493
Коммит b338314f6e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
76 изменённых файлов: 4380 добавлений и 1027 удалений

Просмотреть файл

@ -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)