Skip to content

Longvec mega change #7188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 46 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
5304402
[SM6.9] Allow native vectors longer than 4
pow2clk Nov 21, 2024
e010223
Produce errors for long vectors in invalid contexts
pow2clk Dec 5, 2024
cd72abe
fix assert for tesselation patch template args
pow2clk Feb 18, 2025
4d5c2a2
Merge remote-tracking branch 'refs/remotes/origin/main' into longvec_…
pow2clk Mar 3, 2025
1f12a3f
Refactor builtin type detection with attributes
pow2clk Mar 3, 2025
de6ac33
Respond to feedback
pow2clk Feb 21, 2025
76dde0d
Reaname and consolidate longvecs tests
pow2clk Mar 3, 2025
765ab1c
Refactor, clarify, and expand testing
pow2clk Mar 3, 2025
fb6538e
clang-format
pow2clk Mar 3, 2025
19633b2
Handle subclasses and templates of longvector structs
pow2clk Feb 25, 2025
466bb14
chore: autopublish 2025-03-05T20:50:11Z
github-actions[bot] Mar 5, 2025
66bb772
Identify matrices and vectors by attributes
pow2clk Mar 6, 2025
20c2609
Use constant vector limit value for cached types
pow2clk Mar 4, 2025
1b3ad42
Use definitiondata bits to determine long vector presence
pow2clk Mar 3, 2025
d3fec83
Test for incomplete types in a number of builtin template-like objects
pow2clk Mar 6, 2025
50d1af5
Respond to feedback
pow2clk Mar 10, 2025
eedab25
clang-format
pow2clk Mar 10, 2025
e9cf3d2
Respond to feedback from a different PR
pow2clk Mar 10, 2025
1602bb1
Allow native vectors for LLVM operations
pow2clk Dec 3, 2024
b69d67c
Create new raw buffer load lowering function
pow2clk Jan 27, 2025
d01056b
Allow structuredbuf load lowering in new load lowering code
pow2clk Feb 13, 2025
5061d8c
Refactor resloadhelper constructors
pow2clk Mar 10, 2025
9287299
add scalars test for load/store
pow2clk Mar 10, 2025
92b861e
Typed buf load lowering in new load lowering code
pow2clk Feb 13, 2025
69b7cf7
refactor GenerateRawBufLd and TranslateBufLd interface
pow2clk Mar 10, 2025
a90b420
Enable native vector DXIL intrinsic overload for vector load/store
pow2clk Feb 13, 2025
50ea061
Generate native vector raw buffers load/stores
pow2clk Mar 10, 2025
b90a97d
Add sm69 load store test
pow2clk Mar 7, 2025
faa7dbd
Consolidate buffer store translation
pow2clk Mar 8, 2025
35e39f4
actually allow the given ops to take vectors
pow2clk Dec 3, 2024
2051eb5
get min/max/clamp working
pow2clk Dec 3, 2024
82c3b58
initial commit of longvec intrinsics test
pow2clk Dec 3, 2024
a41e0a6
Disallow swizzles on long vectors
pow2clk Dec 18, 2024
f88e010
Make dot product work for long vecs
pow2clk Jan 6, 2025
13ae80f
Allow vectors on or/and intrinsics
pow2clk Jan 13, 2025
e1aca97
Enable native vector rawbuffer stores
pow2clk Mar 10, 2025
ed52646
clumsy addition of packed types
pow2clk Mar 13, 2025
f3ac271
NFC: Make hlsl::IntrinsicOp enum values stable (#7231)
tex3d Mar 20, 2025
aebbbc8
Add extended and vector overload support for DXIL
tex3d Mar 22, 2025
b06f5f4
update intrinsics to new vector param notation
pow2clk Mar 25, 2025
4e94388
regenerate dxiloperations
pow2clk Mar 26, 2025
645e24b
REVISED: Add extended and vector overload support for DXIL
tex3d Mar 22, 2025
9fb3d83
regenerate DxilOperations.cpp
pow2clk Mar 26, 2025
0bc07ce
Fix warnings about missing braces in clang
pow2clk Mar 26, 2025
5bf2d91
update Dxiloperations.cpp again
pow2clk Mar 26, 2025
5674a18
Update extended and vector overload support for DXIL
tex3d Mar 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,8 @@ add_subdirectory(include/dxc)
# really depend on anything else in the build it is safe.
list(APPEND LLVM_COMMON_DEPENDS HCTGen)

add_subdirectory(utils/hct)

if(EXISTS "${LLVM_MAIN_SRC_DIR}/external")
add_subdirectory(external) # SPIRV change
endif()
Expand Down
23 changes: 21 additions & 2 deletions include/dxc/DXIL/DxilConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,19 @@ const unsigned kMaxMSTotalSigRows = 32;
const unsigned kMaxMSSMSize = 1024 * 28;
const unsigned kMinWaveSize = 4;
const unsigned kMaxWaveSize = 128;
const unsigned kDefaultMaxVectorLength = 4;
const unsigned kSM69MaxVectorLength = 1024;

const float kMaxMipLodBias = 15.99f;
const float kMinMipLodBias = -16.0f;

const unsigned kResRetStatusIndex = 4;

/* <py::lines('OLOAD_DIMS-TEXT')>hctdb_instrhelp.get_max_oload_dims()</py>*/
// OLOAD_DIMS-TEXT:BEGIN
const unsigned kDxilMaxOloadDims = 2;
// OLOAD_DIMS-TEXT:END

enum class ComponentType : uint32_t {
Invalid = 0,
I1,
Expand Down Expand Up @@ -463,6 +470,11 @@ inline bool IsTBuffer(DXIL::ResourceKind ResourceKind) {
return ResourceKind == DXIL::ResourceKind::TBuffer;
}

inline bool IsCTBuffer(DXIL::ResourceKind ResourceKind) {
return ResourceKind == DXIL::ResourceKind::CBuffer ||
ResourceKind == DXIL::ResourceKind::TBuffer;
}

/// Whether the resource kind is a FeedbackTexture.
inline bool IsFeedbackTexture(DXIL::ResourceKind ResourceKind) {
return ResourceKind == DXIL::ResourceKind::FeedbackTexture2D ||
Expand All @@ -475,6 +487,9 @@ inline bool IsFeedbackTexture(DXIL::ResourceKind ResourceKind) {
// Enumeration for operations specified by DXIL
enum class OpCode : unsigned {
//
RawBufferVectorLoad = 303, // reads from a raw buffer and structured buffer
RawBufferVectorStore =
304, // writes to a RWByteAddressBuffer or RWStructuredBuffer
Reserved0 = 226, // Reserved
Reserved1 = 227, // Reserved
Reserved10 = 236, // Reserved
Expand Down Expand Up @@ -1029,8 +1044,9 @@ enum class OpCode : unsigned {
NumOpCodes_Dxil_1_6 = 222,
NumOpCodes_Dxil_1_7 = 226,
NumOpCodes_Dxil_1_8 = 258,
NumOpCodes_Dxil_1_9 = 305,

NumOpCodes = 303 // exclusive last value of enumeration
NumOpCodes = 305 // exclusive last value of enumeration
};
// OPCODE-ENUM:END

Expand All @@ -1042,6 +1058,8 @@ enum class OpCode : unsigned {
// Groups for DXIL operations with equivalent function templates
enum class OpCodeClass : unsigned {
//
RawBufferVectorLoad,
RawBufferVectorStore,
Reserved,

// Amplification shader instructions
Expand Down Expand Up @@ -1337,8 +1355,9 @@ enum class OpCodeClass : unsigned {
NumOpClasses_Dxil_1_6 = 149,
NumOpClasses_Dxil_1_7 = 153,
NumOpClasses_Dxil_1_8 = 174,
NumOpClasses_Dxil_1_9 = 177,

NumOpClasses = 175 // exclusive last value of enumeration
NumOpClasses = 177 // exclusive last value of enumeration
};
// OPCODECLASS-ENUM:END

Expand Down
129 changes: 129 additions & 0 deletions include/dxc/DXIL/DxilInstructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,42 @@ struct LlvmInst_VAArg {
bool isAllowed() const { return false; }
};

/// This instruction extracts from vector
struct LlvmInst_ExtractElement {
llvm::Instruction *Instr;
// Construction and identification
LlvmInst_ExtractElement(llvm::Instruction *pInstr) : Instr(pInstr) {}
operator bool() const {
return Instr->getOpcode() == llvm::Instruction::ExtractElement;
}
// Validation support
bool isAllowed() const { return true; }
};

/// This instruction inserts into vector
struct LlvmInst_InsertElement {
llvm::Instruction *Instr;
// Construction and identification
LlvmInst_InsertElement(llvm::Instruction *pInstr) : Instr(pInstr) {}
operator bool() const {
return Instr->getOpcode() == llvm::Instruction::InsertElement;
}
// Validation support
bool isAllowed() const { return true; }
};

/// This instruction Shuffle two vectors
struct LlvmInst_ShuffleVector {
llvm::Instruction *Instr;
// Construction and identification
LlvmInst_ShuffleVector(llvm::Instruction *pInstr) : Instr(pInstr) {}
operator bool() const {
return Instr->getOpcode() == llvm::Instruction::ShuffleVector;
}
// Validation support
bool isAllowed() const { return true; }
};

/// This instruction extracts from aggregate
struct LlvmInst_ExtractValue {
llvm::Instruction *Instr;
Expand Down Expand Up @@ -8813,5 +8849,98 @@ struct DxilInst_AllocateRayQuery2 {
llvm::APInt(32, (uint64_t)val)));
}
};

/// This instruction reads from a raw buffer and structured buffer
struct DxilInst_RawBufferVectorLoad {
llvm::Instruction *Instr;
// Construction and identification
DxilInst_RawBufferVectorLoad(llvm::Instruction *pInstr) : Instr(pInstr) {}
operator bool() const {
return hlsl::OP::IsDxilOpFuncCallInst(
Instr, hlsl::OP::OpCode::RawBufferVectorLoad);
}
// Validation support
bool isAllowed() const { return true; }
bool isArgumentListValid() const {
if (5 != 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_index = 2,
arg_elementOffset = 3,
arg_alignment = 4,
};
// Accessors
llvm::Value *get_srv() const { return Instr->getOperand(1); }
void set_srv(llvm::Value *val) { Instr->setOperand(1, val); }
llvm::Value *get_index() const { return Instr->getOperand(2); }
void set_index(llvm::Value *val) { Instr->setOperand(2, val); }
llvm::Value *get_elementOffset() const { return Instr->getOperand(3); }
void set_elementOffset(llvm::Value *val) { Instr->setOperand(3, val); }
llvm::Value *get_alignment() const { return Instr->getOperand(4); }
void set_alignment(llvm::Value *val) { Instr->setOperand(4, val); }
int32_t get_alignment_val() const {
return (int32_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(4))
->getZExtValue());
}
void set_alignment_val(int32_t val) {
Instr->setOperand(4, llvm::Constant::getIntegerValue(
llvm::IntegerType::get(Instr->getContext(), 32),
llvm::APInt(32, (uint64_t)val)));
}
};

/// This instruction writes to a RWByteAddressBuffer or RWStructuredBuffer
struct DxilInst_RawBufferVectorStore {
llvm::Instruction *Instr;
// Construction and identification
DxilInst_RawBufferVectorStore(llvm::Instruction *pInstr) : Instr(pInstr) {}
operator bool() const {
return hlsl::OP::IsDxilOpFuncCallInst(
Instr, hlsl::OP::OpCode::RawBufferVectorStore);
}
// Validation support
bool isAllowed() const { return true; }
bool isArgumentListValid() const {
if (6 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
return false;
return true;
}
// Metadata
bool requiresUniformInputs() const { return false; }
// Operand indexes
enum OperandIdx {
arg_uav = 1,
arg_index = 2,
arg_elementOffset = 3,
arg_value0 = 4,
arg_alignment = 5,
};
// Accessors
llvm::Value *get_uav() const { return Instr->getOperand(1); }
void set_uav(llvm::Value *val) { Instr->setOperand(1, val); }
llvm::Value *get_index() const { return Instr->getOperand(2); }
void set_index(llvm::Value *val) { Instr->setOperand(2, val); }
llvm::Value *get_elementOffset() const { return Instr->getOperand(3); }
void set_elementOffset(llvm::Value *val) { Instr->setOperand(3, val); }
llvm::Value *get_value0() const { return Instr->getOperand(4); }
void set_value0(llvm::Value *val) { Instr->setOperand(4, val); }
llvm::Value *get_alignment() const { return Instr->getOperand(5); }
void set_alignment(llvm::Value *val) { Instr->setOperand(5, val); }
int32_t get_alignment_val() const {
return (int32_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(5))
->getZExtValue());
}
void set_alignment_val(int32_t val) {
Instr->setOperand(5, llvm::Constant::getIntegerValue(
llvm::IntegerType::get(Instr->getContext(), 32),
llvm::APInt(32, (uint64_t)val)));
}
};
// INSTR-HELPER:END
} // namespace hlsl
40 changes: 38 additions & 2 deletions include/dxc/DXIL/DxilOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@ class OP {
void RefreshCache();

llvm::Function *GetOpFunc(OpCode OpCode, llvm::Type *pOverloadType);
llvm::Function *GetOpFunc(OpCode OpCode,
llvm::ArrayRef<llvm::Type *> ExtendedOverloads);
const llvm::SmallMapVector<llvm::Type *, llvm::Function *, 8> &
GetOpFuncList(OpCode OpCode) const;
bool IsDxilOpUsed(OpCode opcode) const;
void RemoveFunction(llvm::Function *F);
llvm::LLVMContext &GetCtx() { return m_Ctx; }
llvm::Module *GetModule() { return m_pModule; }
llvm::Type *GetHandleType() const;
llvm::Type *GetNodeHandleType() const;
llvm::Type *GetNodeRecordHandleType() const;
Expand All @@ -83,6 +86,10 @@ class OP {
llvm::Type *GetVectorType(unsigned numElements, llvm::Type *pOverloadType);
bool IsResRetType(llvm::Type *Ty);

// Construct an unnamed struct type containing the set of member types.
llvm::StructType *
GetExtendedOverloadType(llvm::ArrayRef<llvm::Type *> OverloadTypes);

// Try to get the opcode class for a function.
// Return true and set `opClass` if the given function is a dxil function.
// Return false if the given function is not a dxil function.
Expand Down Expand Up @@ -140,6 +147,8 @@ class OP {
unsigned valMinor, unsigned &major,
unsigned &minor, unsigned &mask);

static bool IsDxilOpExtendedOverload(OpCode C);

private:
// Per-module properties.
llvm::LLVMContext &m_Ctx;
Expand All @@ -164,8 +173,10 @@ class OP {

static const unsigned kUserDefineTypeSlot = 9;
static const unsigned kObjectTypeSlot = 10;
static const unsigned kVectorTypeSlot = 11;
static const unsigned kExtendedTypeSlot = 12;
static const unsigned kNumTypeOverloads =
11; // void, h,f,d, i1, i8,i16,i32,i64, udt, obj
13; // void, h,f,d, i1, i8,i16,i32,i64, udt, obj, vec, extended

llvm::Type *m_pResRetType[kNumTypeOverloads];
llvm::Type *m_pCBufferRetType[kNumTypeOverloads];
Expand All @@ -179,14 +190,39 @@ class OP {

private:
// Static properties.
struct OverloadMask {
// mask of type slot bits as (1 << TypeSlot)
uint16_t SlotMask;
static_assert(kNumTypeOverloads <= (sizeof(SlotMask) * 8));
bool operator[](unsigned TypeSlot) const {
return (TypeSlot < kNumTypeOverloads) ? (bool)(SlotMask & (1 << TypeSlot))
: 0;
}
operator bool() const { return SlotMask != 0; }
};
struct OpCodeProperty {
OpCode opCode;
const char *pOpCodeName;
OpCodeClass opCodeClass;
const char *pOpCodeClassName;
bool bAllowOverload[kNumTypeOverloads]; // void, h,f,d, i1, i8,i16,i32,i64,
// udt
// udt, obj, vec, extended
llvm::Attribute::AttrKind FuncAttr;

// Extended Type Overloads:
// This is an encoding for a multi-dimensional overload.
// 1. Only bAllowOverload[kExtendedTypeSlot] is set to true
// 2. ExtendedOverloads defines allowed types for each overload index
// 3. AllowedVectorElements defines allowed vector component types,
// when kVectorTypeSlot bit is set for the corresponding overload index.
// This includes when a single vector overload type is specified with
// bAllowOverload[kVectorTypeSlot].

// A bit mask of allowed type slots per extended overload
OverloadMask ExtendedOverloads[DXIL::kDxilMaxOloadDims];
// A bit mask of allowed vector element types for the vector overload
// or each corresponding extended vector overload.
OverloadMask AllowedVectorElements[DXIL::kDxilMaxOloadDims];
};
static const OpCodeProperty m_OpCodeProps[(unsigned)OpCode::NumOpCodes];

Expand Down
Loading
Loading