Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 20 additions & 45 deletions docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ line upon naming the release. Refer to previous for appropriate section names.
available.
- Removed work graph support from Shader Model 6.10, and DXIL 1.10
[microsoft/hlsl-specs#915](https://github.com/microsoft/hlsl-specs/issues/915).
- Fixed the set of numeric types allowed in LinAlg matrix intrinsics
[#8271](https://github.com/microsoft/DirectXShaderCompiler/issues/8271).
- Corrected the parameter order of `InterlockedAccumulate`
[microsoft/hlsl-specs#869](https://github.com/microsoft/hlsl-specs/issues/869).
- Added validation of LinAlg matrix builtin parameters and result K dimension
[#8491](https://github.com/microsoft/DirectXShaderCompiler/issues/8491).
- Restricted the component types allowed in LinAlg matrices
[#8494](https://github.com/microsoft/DirectXShaderCompiler/issues/8494).
- Added `BFloat16` to the ComponentType enum in DxilConstants and the linalg
header [#8722](https://github.com/microsoft/DirectXShaderCompiler/issues/8722).

#### HLSL Language

- Starting with HLSL 202x, the count in `[unroll(N)]` is a partial-unroll hint
and no longer limits the number of loop iterations
[#8789](https://github.com/microsoft/DirectXShaderCompiler/issues/8789).
- Casting a scalar to a struct or array containing a resource is now an error
instead of crashing
[#6661](https://github.com/microsoft/DirectXShaderCompiler/issues/6661).
- Added the `-Whlsl-2026-compat` warning group for identifying issues
with language changes introduced in HLSL 2026.
- The legacy effects syntax support is removed in HLSL 202x
[#8480](https://github.com/microsoft/DirectXShaderCompiler/issues/8480).
- The `shared` and `uniform` keywords are removed in HLSL 202x, with
compatibility warnings available for earlier language versions
[#8482](https://github.com/microsoft/DirectXShaderCompiler/issues/8482).
Expand All @@ -56,31 +56,11 @@ line upon naming the release. Refer to previous for appropriate section names.
[#8484](https://github.com/microsoft/DirectXShaderCompiler/issues/8484).
- Starting with HLSL 202x, `cbuffer` and `tbuffer` declarations and their
members belong to their enclosing namespace.
- HLSL 202x supports `const`-qualified instance methods and rejects calls
to non-`const` methods on `const` objects, including objects in constant
buffers
[#8964](https://github.com/microsoft/DirectXShaderCompiler/issues/8964).
- Add `static_assert` matching C++11 and C++17 under HLSL 202x
([#8910](https://github.com/microsoft/DirectXShaderCompiler/issues/8910)).

#### Bug Fixes

- Fixed an optimizer crash when scalarizing an out-of-bounds vector access
[#8940](https://github.com/microsoft/DirectXShaderCompiler/issues/8940).

### Upcoming Preview Release

These changes apply to experimental preview shader models only and will not be
part of the next non-preview release.

#### Experimental Shader Model 6.11

- Added experimental Shader Model 6.11 target profiles.

### Version 1.9.2609

#### Bug Fixes

- Fixed derivative operations being moved into divergent control flow, which
Comment on lines 62 to 64
could produce incorrect results
[#8001](https://github.com/microsoft/DirectXShaderCompiler/issues/8001).
Expand All @@ -104,22 +84,7 @@ part of the next non-preview release.
- Fixed internal compiler errors when a member method is called on a ray payload
or on one of its fields with payload access qualifiers enabled
[#6464](https://github.com/microsoft/DirectXShaderCompiler/issues/6464).
- Fixed undefined behavior in DXC IntelliSense caused by the uninitialized
`ExpandTokPastingArg` preprocessor option, which made token-pasting
behavior indeterminate.

#### HLSL Language

- Starting with HLSL 202x, the count in `[unroll(N)]` is a partial-unroll hint
and no longer limits the number of loop iterations
[#8789](https://github.com/microsoft/DirectXShaderCompiler/issues/8789).
- Casting a scalar to a struct or array containing a resource is now an error
instead of crashing
[#6661](https://github.com/microsoft/DirectXShaderCompiler/issues/6661).
- Added the `-Whlsl-2026-compat` warning group for identifying issues
with language changes introduced in HLSL 2026.
- The legacy effects syntax support is removed in HLSL 202x
[#8480](https://github.com/microsoft/DirectXShaderCompiler/issues/8480).

#### SPIR-V

Expand All @@ -138,6 +103,16 @@ part of the next non-preview release.
`vk::RawBufferStore` intrinsics
[#8572](https://github.com/microsoft/DirectXShaderCompiler/issues/8572).

### Upcoming Preview Release

These changes apply to experimental preview shader models only and will not be
part of the next non-preview release.

#### Experimental Shader Model 6.11

- Added experimental Shader Model 6.11 target profiles.


### Version 1.9.2607

#### HLSL Language
Expand Down
2 changes: 0 additions & 2 deletions include/dxc/dxcapi.internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ static const UINT INTRIN_FLAG_READ_ONLY = 1U << 0;
static const UINT INTRIN_FLAG_READ_NONE = 1U << 1;
static const UINT INTRIN_FLAG_IS_WAVE = 1U << 2;
static const UINT INTRIN_FLAG_STATIC_MEMBER = 1U << 3;
// Method mutates the object (cannot be called on a const-qualified instance).
static const UINT INTRIN_FLAG_MUTABLE_METHOD = 1U << 4;

struct HLSL_INTRINSIC {
UINT Op; // Intrinsic Op ID
Expand Down
18 changes: 18 additions & 0 deletions lib/DxilPIXPasses/DxilAnnotateWithVirtualRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
m_MST.reset(new llvm::ModuleSlotTracker(&M));
auto functions = m_DM->GetExportedFunctions();
for (auto &fn : functions) {
// A module that names no entry point reports a null one here, e.g. a
// library whose only export is a helper function.
if (fn == nullptr)
continue;
m_MST->incorporateFunction(*fn);
}
}
Expand All @@ -128,6 +132,12 @@ PrintableSubsetOfMangledFunctionName(llvm::StringRef mangled) {
}

bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
// Inline first, so each ordinal this pass hands out belongs to a function
// that PIX can attribute to an invocation.
llvm::SmallVector<llvm::Function *, 4> UninlinedFunctions;
PIXPassHelpers::InlineNonEntryFunctions(M.GetOrCreateDxilModule(),
&UninlinedFunctions);
Comment on lines +137 to +139

Init(M);
if (m_DM == nullptr) {
return false;
Expand Down Expand Up @@ -218,6 +228,14 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
}

if (OSOverride != nullptr) {
// Name each function that survives inlining. Its instruction range is
// advertised above, but no trace record arrives for it, so PIX must not
// offer it as somewhere to step into.
for (llvm::Function *F : UninlinedFunctions) {
*OSOverride << "UninlinedFunction:"
<< PrintableSubsetOfMangledFunctionName(F->getName()) << "\n";
}

// Print a set of strings of the exemplary form "InstructionCount: <n>
// <fnName>"
if (m_DM->GetShaderModel()->GetKind() == hlsl::ShaderModel::Kind::Library)
Expand Down
14 changes: 14 additions & 0 deletions lib/DxilPIXPasses/DxilDbgValueToDbgDeclare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <utility>

#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DXIL/DxilMetadataHelper.h"
#include "dxc/DXIL/DxilModule.h"
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/DXIL/DxilResourceBase.h"
Expand Down Expand Up @@ -593,6 +594,19 @@ GlobalStorageMap GatherGlobalEmbeddedArrayStorage(llvm::Module &M) {
}

bool DxilDbgValueToDbgDeclare::runOnModule(llvm::Module &M) {
// Inline before any shadow storage exists. The stores this pass emits carry
// no debug location on purpose, and llvm::InlineFunction stamps the call site
// location onto each inlined instruction that carries none. Inlining first
// therefore keeps a helper local readable, because its stores stay attributed
// to the helper instead of to the line of the call.
//
// This pass also runs over a plain LLVM module that carries debug info and no
// DXIL, which has no call graph to root the inlining on.
if (M.HasDxilModule() ||
M.getNamedMetadata(hlsl::DxilMDHelper::kDxilVersionMDName) != nullptr) {
PIXPassHelpers::InlineNonEntryFunctions(M.GetOrCreateDxilModule());
}

auto GlobalEmbeddedArrayStorage = GatherGlobalEmbeddedArrayStorage(M);

bool Changed = false;
Comment on lines +605 to 612
Expand Down
146 changes: 103 additions & 43 deletions lib/DxilPIXPasses/DxilDebugInstrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,28 @@ class DxilDebugInstrumentation : public ModulePass {
CountBlockPayloadBytes(std::vector<InstructionToInstrument> const &IsAndTs);
};

static bool IsInstrumentableShaderKind(DXIL::ShaderKind shaderKind) {
switch (shaderKind) {
case DXIL::ShaderKind::Amplification:
case DXIL::ShaderKind::Mesh:
case DXIL::ShaderKind::Vertex:
case DXIL::ShaderKind::Geometry:
case DXIL::ShaderKind::Pixel:
case DXIL::ShaderKind::Compute:
case DXIL::ShaderKind::RayGeneration:
case DXIL::ShaderKind::Hull:
case DXIL::ShaderKind::Domain:
case DXIL::ShaderKind::Intersection:
case DXIL::ShaderKind::AnyHit:
case DXIL::ShaderKind::ClosestHit:
case DXIL::ShaderKind::Miss:
case DXIL::ShaderKind::Node:
return true;
default:
return false;
}
}

void DxilDebugInstrumentation::applyOptions(PassOptions O) {
GetPassOptionUnsigned(O, "FirstInstruction", &m_FirstInstruction, 0);
GetPassOptionUnsigned(O, "LastInstruction", &m_LastInstruction,
Expand Down Expand Up @@ -813,9 +835,17 @@ void DxilDebugInstrumentation::addInvocationSelectionProlog(
case DXIL::ShaderKind::Vertex:
ParameterTestResult = addVertexShaderProlog(BC, SVIndices);
break;
case DXIL::ShaderKind::Hull:
ParameterTestResult = addHullhaderProlog(BC);
break;
case DXIL::ShaderKind::Hull: {
// OutputControlPointID only means something in the control point phase, so
// the patch-constant function is selected by primitive alone.
llvm::Function *function = BC.Builder.GetInsertBlock()->getParent();
if (function == BC.DM.GetPatchConstantFunction()) {
ParameterTestResult =
addComparePrimitiveIdProlog(BC, m_Parameters.HullShader.PrimitiveId);
} else {
ParameterTestResult = addHullhaderProlog(BC);
}
} break;
case DXIL::ShaderKind::Domain:
ParameterTestResult =
addComparePrimitiveIdProlog(BC, m_Parameters.DomainShader.PrimitiveId);
Expand Down Expand Up @@ -993,11 +1023,17 @@ uint32_t DxilDebugInstrumentation::addDebugEntryValue(BuilderContext &BC,
BC.Builder.CreateFPCast(TheValue, Type::getFloatTy(BC.Ctx), "AsFloat");
BytesToBeEmitted += addDebugEntryValue(BC, AsFloat);
} else {
// RawBufferStore is only legal from shader model 6.2 onwards. PIX also
// instruments 6.0 and 6.1 shaders, so fall back to BufferStore (legal from
// 6.0) on those. The two differ only in the trailing alignment operand.
const bool SupportsRawBufferStore = BC.DM.GetShaderModel()->IsSM62Plus();
Comment on lines +1026 to +1029
const OP::OpCode StoreOpCode = SupportsRawBufferStore
? OP::OpCode::RawBufferStore
: OP::OpCode::BufferStore;
Function *StoreValue =
BC.HlslOP->GetOpFunc(OP::OpCode::RawBufferStore,
BC.HlslOP->GetOpFunc(StoreOpCode,
TheValue->getType()); // Type::getInt32Ty(BC.Ctx));
Constant *StoreValueOpcode =
BC.HlslOP->GetU32Const((unsigned)DXIL::OpCode::RawBufferStore);
Constant *StoreValueOpcode = BC.HlslOP->GetU32Const((unsigned)StoreOpCode);
UndefValue *Undef32Arg = UndefValue::get(Type::getInt32Ty(BC.Ctx));
UndefValue *UndefArg = nullptr;
if (TheValueTypeID == Type::TypeID::IntegerTyID) {
Expand All @@ -1014,16 +1050,21 @@ uint32_t DxilDebugInstrumentation::addDebugEntryValue(BuilderContext &BC,
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
Constant *RawBufferStoreAlignment = BC.HlslOP->GetU32Const(4);

(void)BC.Builder.CreateCall(
StoreValue, {StoreValueOpcode, // i32 opcode
values.UAVHandle, // %dx.types.Handle, ; resource handle
values.CurrentIndex, // i32 c0: index in bytes into UAV
Undef32Arg, // i32 c1: unused
TheValue,
UndefArg, // unused values
UndefArg, // unused values
UndefArg, // unused values
WriteMask_X, RawBufferStoreAlignment});
SmallVector<Value *, 10> StoreArgs{
StoreValueOpcode, // i32 opcode
values.UAVHandle, // %dx.types.Handle, ; resource handle
values.CurrentIndex, // i32 c0: index in bytes into UAV
Undef32Arg, // i32 c1: unused
TheValue,
UndefArg, // unused values
UndefArg, // unused values
UndefArg, // unused values
WriteMask_X};
if (SupportsRawBufferStore) {
StoreArgs.push_back(RawBufferStoreAlignment);
}

(void)BC.Builder.CreateCall(StoreValue, StoreArgs);

assert(m_RemainingReservedSpaceInBytes >= 4); // check for underflow
m_RemainingReservedSpaceInBytes -= 4;
Expand Down Expand Up @@ -1313,19 +1354,54 @@ bool DxilDebugInstrumentation::runOnModule(Module &M) {
auto ShaderModel = DM.GetShaderModel();
auto shaderKind = ShaderModel->GetKind();
auto HLSLBindId = 0;
auto *uav = PIXPassHelpers::CreateGlobalUAVResource(DM, HLSLBindId, "PIXUAV");
bool modified = false;

std::vector<llvm::Function *> functionsToInstrument;
if (shaderKind == DXIL::ShaderKind::Library) {
auto instrumentableFunctions =
PIXPassHelpers::GetAllInstrumentableFunctions(DM);
for (auto *F : instrumentableFunctions) {
if (RunOnFunction(M, DM, uav, F)) {
modified = true;
}
}
functionsToInstrument = PIXPassHelpers::GetAllInstrumentableFunctions(DM);
} else {
// Only the functions that the runtime itself invokes are instrumented. A
// helper that the entry point calls is not one of them, and cannot become
// one: PIX names an invocation by a record stream in the debug UAV and maps
// that stream to a single function, so instrumenting a helper produces a
// second invocation for one thread whose records PIX then discards. The
// annotation pass inlines such helpers away before anything is numbered.
// See PIXPassHelpers::InlineNonEntryFunctions.
llvm::Function *entryFunction = PIXPassHelpers::GetEntryFunction(DM);
modified = RunOnFunction(M, DM, uav, entryFunction);
functionsToInstrument.push_back(entryFunction);

// The runtime invokes a hull shader patch-constant function rather than the
// entry point does, so it survives inlining and is numbered and advertised
// to PIX as a steppable range of its own. Instrument it too, or a user who
// steps into it sees instructions with no values behind them.
llvm::Function *patchConstantFunction = DM.GetPatchConstantFunction();
if (patchConstantFunction != nullptr &&
patchConstantFunction != entryFunction) {
functionsToInstrument.push_back(patchConstantFunction);
}
}

functionsToInstrument.erase(
std::remove_if(functionsToInstrument.begin(), functionsToInstrument.end(),
[&DM](llvm::Function *function) {
return function == nullptr ||
!IsInstrumentableShaderKind(
PIXPassHelpers::GetFunctionShaderKind(
DM, function));
}),
functionsToInstrument.end());

// Creating the UAV modifies the module, so nothing may be created before the
// pass knows it has something to instrument.
if (functionsToInstrument.empty()) {
return false;
}

auto *uav = PIXPassHelpers::CreateGlobalUAVResource(DM, HLSLBindId, "PIXUAV");
bool modified = false;
for (auto *function : functionsToInstrument) {
if (RunOnFunction(M, DM, uav, function)) {
modified = true;
}
}
return modified;
}
Expand Down Expand Up @@ -1496,23 +1572,7 @@ bool DxilDebugInstrumentation::RunOnFunction(Module &M, DxilModule &DM,
DXIL::ShaderKind shaderKind =
PIXPassHelpers::GetFunctionShaderKind(DM, function);

switch (shaderKind) {
case DXIL::ShaderKind::Amplification:
case DXIL::ShaderKind::Mesh:
case DXIL::ShaderKind::Vertex:
case DXIL::ShaderKind::Geometry:
case DXIL::ShaderKind::Pixel:
case DXIL::ShaderKind::Compute:
case DXIL::ShaderKind::RayGeneration:
case DXIL::ShaderKind::Hull:
case DXIL::ShaderKind::Domain:
case DXIL::ShaderKind::Intersection:
case DXIL::ShaderKind::AnyHit:
case DXIL::ShaderKind::ClosestHit:
case DXIL::ShaderKind::Miss:
case DXIL::ShaderKind::Node:
break;
default:
if (!IsInstrumentableShaderKind(shaderKind)) {
return false;
}
llvm::SmallPtrSet<Value *, 16> RayQueryHandles;
Expand Down
Loading
Loading