Skip to content
Merged
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
31 changes: 26 additions & 5 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ void DeclResultIdMapper::createCounterVarForDecl(const DeclaratorDecl *decl) {

if (!counterVars.count(decl) && isRWAppendConsumeSBuffer(declType)) {
createCounterVar(decl, /*declId=*/0, /*isAlias=*/true);
} else if (!fieldCounterVars.count(decl) && declType->isStructureType() &&
} else if (!fieldCounterVars.count(decl) && declType->isRecordType() &&
// Exclude other resource types which are represented as structs
!hlsl::IsHLSLResourceType(declType)) {
createFieldCounterVars(decl);
Expand Down Expand Up @@ -1886,14 +1886,33 @@ void DeclResultIdMapper::createCounterVar(
counterVars[decl] = {counterInstr, isAlias};
}

void DeclResultIdMapper::createFieldCounterVars(const DeclaratorDecl *decl) {
llvm::SmallVector<uint32_t, 4> indices;
const QualType type = getTypeOrFnRetType(decl);
createFieldCounterVars(decl, type, &indices);
}

void DeclResultIdMapper::createFieldCounterVars(
const DeclaratorDecl *rootDecl, const DeclaratorDecl *decl,
const DeclaratorDecl *rootDecl, const QualType type,
llvm::SmallVector<uint32_t, 4> *indices) {
const QualType type = getTypeOrFnRetType(decl);
const auto *recordType = type->getAs<RecordType>();
assert(recordType);
const auto *recordDecl = recordType->getDecl();

// Handle base classes first
if (const auto *cxxRecordDecl = dyn_cast<CXXRecordDecl>(recordDecl)) {
// HLSL has at most one base class.
assert(cxxRecordDecl->getNumBases() <= 1 &&
"HLSL should have at most one base class.");
if (cxxRecordDecl->getNumBases() > 0) {
const auto &base = *cxxRecordDecl->bases().begin();
indices->push_back(0);
createFieldCounterVars(rootDecl, base.getType(), indices);
indices->pop_back();
}
}

// Now handle the fields of the current class (non-inherited fields)
for (const auto *field : recordDecl->fields()) {
// Build up the index chain
indices->push_back(getNumBaseClasses(type) + field->getFieldIndex());
Expand All @@ -1902,9 +1921,11 @@ void DeclResultIdMapper::createFieldCounterVars(
if (isRWAppendConsumeSBuffer(fieldType))
createCounterVar(rootDecl, /*declId=*/0, /*isAlias=*/true, indices);
else if (fieldType->isStructureType() &&
!hlsl::IsHLSLResourceType(fieldType))
!hlsl::IsHLSLResourceType(fieldType)) {
// Go recursively into all nested structs
createFieldCounterVars(rootDecl, field, indices);
const QualType type = getTypeOrFnRetType(field);
createFieldCounterVars(rootDecl, type, indices);
}

indices->pop_back();
}
Expand Down
9 changes: 2 additions & 7 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -912,9 +912,9 @@ class DeclResultIdMapper {
/// Creates all assoicated counter variables by recursively visiting decl's
/// fields. Handles AssocCounter#3 and AssocCounter#4 (see the comment of
/// CounterVarFields).
inline void createFieldCounterVars(const DeclaratorDecl *decl);
void createFieldCounterVars(const DeclaratorDecl *decl);
void createFieldCounterVars(const DeclaratorDecl *rootDecl,
const DeclaratorDecl *decl,
const QualType type,
llvm::SmallVector<uint32_t, 4> *indices);

/// Decorates varInstr of the given asType with proper interpolation modes
Expand Down Expand Up @@ -1197,11 +1197,6 @@ void DeclResultIdMapper::createFnParamCounterVar(const VarDecl *param) {
createCounterVarForDecl(param);
}

void DeclResultIdMapper::createFieldCounterVars(const DeclaratorDecl *decl) {
llvm::SmallVector<uint32_t, 4> indices;
createFieldCounterVars(decl, decl, &indices);
}

} // end namespace spirv
} // end namespace clang

Expand Down
30 changes: 22 additions & 8 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4957,10 +4957,6 @@ SpirvEmitter::incDecRWACSBufferCounter(const CXXMemberCallExpr *expr,

bool SpirvEmitter::tryToAssignCounterVar(const DeclaratorDecl *dstDecl,
const Expr *srcExpr) {
// We are handling associated counters here. Casts should not alter which
// associated counter to manipulate.
srcExpr = srcExpr->IgnoreParenCasts();

// For parameters of forward-declared functions. We must make sure the
// associated counter variable is created. But for forward-declared functions,
// the translation of the real definition may not be started yet.
Expand Down Expand Up @@ -5061,9 +5057,10 @@ SpirvEmitter::getFinalACSBufferCounterInstruction(const Expr *expr) {
llvm::SmallVector<SpirvInstruction *, 2> indexes;
if (const auto *arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(expr)) {
indexes.push_back(doExpr(arraySubscriptExpr->getIdx()));
} else if (isResourceDescriptorHeap(expr->getType())) {
} else if (isResourceDescriptorHeap(expr->IgnoreParenCasts()->getType())) {
const Expr *index = nullptr;
getDescriptorHeapOperands(expr, /* base= */ nullptr, &index);
getDescriptorHeapOperands(expr->IgnoreParenCasts(), /* base= */ nullptr,
&index);
assert(index != nullptr && "operator[] had no indices.");
indexes.push_back(doExpr(index));
}
Expand All @@ -5081,9 +5078,10 @@ SpirvEmitter::getFinalACSBufferCounter(const Expr *expr) {
if (const auto *decl = getReferencedDef(expr))
return declIdMapper.createOrGetCounterIdAliasPair(decl);

if (isResourceDescriptorHeap(expr->getType())) {
const Expr *expr_withoutcasts = expr->IgnoreParenCasts();
if (isResourceDescriptorHeap(expr_withoutcasts->getType())) {
const Expr *base = nullptr;
getDescriptorHeapOperands(expr, &base, /* index= */ nullptr);
getDescriptorHeapOperands(expr_withoutcasts, &base, /* index= */ nullptr);
return declIdMapper.createOrGetCounterIdAliasPair(getReferencedDef(base));
}

Expand Down Expand Up @@ -8860,7 +8858,23 @@ const Expr *SpirvEmitter::collectArrayStructIndices(
return collectArrayStructIndices(subExpr, rawIndex, rawIndices,
indices, isMSOutAttribute);
}
} else if (castExpr->getCastKind() == CK_UncheckedDerivedToBase ||
castExpr->getCastKind() == CK_HLSLDerivedToBase) {
llvm::SmallVector<uint32_t, 4> BaseIdx;
getBaseClassIndices(castExpr, &BaseIdx);
if (rawIndex) {
rawIndices->append(BaseIdx.begin(), BaseIdx.end());
} else {
for (uint32_t Idx : BaseIdx)
indices->push_back(spvBuilder.getConstantInt(astContext.IntTy,
llvm::APInt(32, Idx)));
}

return collectArrayStructIndices(castExpr->getSubExpr(), rawIndex,
rawIndices, indices, isMSOutAttribute);
}
return collectArrayStructIndices(castExpr->getSubExpr(), rawIndex,
rawIndices, indices, isMSOutAttribute);
}
}

Expand Down
29 changes: 29 additions & 0 deletions tools/clang/test/CodeGenSPIRV/class-with-counter.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %dxc -T cs_6_8 -E main %s -spirv -fspv-target-env=vulkan1.3 | FileCheck %s

class A {
RWStructuredBuffer<uint> a;
};

class B : A {
RWStructuredBuffer<uint> b;
};

RWStructuredBuffer<uint> input;
RWStructuredBuffer<uint> output;

[numthreads(1, 1, 1)]
void main()
{
B x;

// CHECK: [[val1_ptr:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_StorageBuffer_uint %input %int_0 %uint_1
// CHECK-NEXT: [[val1:%[a-zA-Z0-9_]+]] = OpLoad %uint [[val1_ptr]]
// CHECK-NEXT: [[val2_ptr:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_StorageBuffer_uint %output %int_0 %uint_2
// CHECK-NEXT: [[val2:%[a-zA-Z0-9_]+]] = OpLoad %uint [[val2_ptr]]
// CHECK-NEXT: [[add_res:%[a-zA-Z0-9_]+]] = OpIAdd %uint [[val1]] [[val2]]
// CHECK-NEXT: [[target_ptr:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_StorageBuffer_uint %output %int_0 %uint_0
// CHECK-NEXT: OpStore [[target_ptr]] [[add_res]]
x.a = input;
x.b = output;
output[0] = x.a[1] + x.b[2];
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ struct Base {

struct Child : Base {
float load(in uint offset) {
// CHECK: %param_this = OpFunctionParameter %_ptr_Function_Child
// CHECK: [[base:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Function_Base %param_this %uint_0
// CHECK: [[ptrToBuffer:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Function__ptr_Uniform_type_ByteAddressBuffer [[base]] %int_0
// CHECK: %param_this = OpFunctionParameter %_ptr_Function_Child
// CHECK: [[ptrToBuffer:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Function__ptr_Uniform_type_ByteAddressBuffer %param_this %int_0 %int_0

// This test case is mainly intended to confirm that we emit the following instruction
// CHECK: [[buffer:%[a-zA-Z0-9_]+]] = OpLoad %_ptr_Uniform_type_ByteAddressBuffer [[ptrToBuffer]]
Expand Down
30 changes: 12 additions & 18 deletions tools/clang/test/CodeGenSPIRV/oo.inheritance.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ float4 main() : SV_Target {
Derived d;

// Accessing a field from the implicit base object
// CHECK: [[base:%[0-9]+]] = OpAccessChain %_ptr_Function_Base %d %uint_0
// CHECK-NEXT: [[base_a:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[base]] %int_0
// CHECK: [[base_a:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %d %int_0 %int_0
// CHECK-NEXT: OpStore [[base_a]] {{%[0-9]+}}
d.a = 1.;

Expand All @@ -54,13 +53,11 @@ float4 main() : SV_Target {
DerivedAgain dd;

// Accessing a field from the deep implicit base object
// CHECK-NEXT: [[base_0:%[0-9]+]] = OpAccessChain %_ptr_Function_Base %dd %uint_0 %uint_0
// CHECK-NEXT: [[base_a_0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[base_0]] %int_0
// CHECK-NEXT: [[base_a_0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %dd %int_0 %int_0 %int_0
// CHECK-NEXT: OpStore [[base_a_0]] {{%[0-9]+}}
dd.a = 6.;
// Accessing a field from the immediate implicit base object
// CHECK-NEXT: [[drv:%[0-9]+]] = OpAccessChain %_ptr_Function_Derived %dd %uint_0
// CHECK-NEXT: [[drv_b:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[drv]] %int_1
// CHECK-NEXT: [[drv_b:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %dd %int_0 %int_1
// CHECK-NEXT: OpStore [[drv_b]] {{%[0-9]+}}
dd.b = 7.;
// Accessing fields from the derived object (shadowing)
Expand All @@ -87,18 +84,15 @@ float4 main() : SV_Target {
(Base)dd2 = (Base)d;

// Make sure reads are good
// CHECK: [[base_1:%[0-9]+]] = OpAccessChain %_ptr_Function_Base %d %uint_0
// CHECK-NEXT: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float [[base_1]] %int_0
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_2
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_3 %int_0
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_3 %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_0 %int_0
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_2
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_3 %int_0
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %d %int_3 %int_1
return d.a + d.b + d.c + d.x.a + d.x.b +
// CHECK: [[base_2:%[0-9]+]] = OpAccessChain %_ptr_Function_Base %dd %uint_0 %uint_0
// CHECK-NEXT: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float [[base_2]] %int_0
// CHECK: [[drv_0:%[0-9]+]] = OpAccessChain %_ptr_Function_Derived %dd %uint_0
// CHECK-NEXT: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float [[drv_0]] %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %dd %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %dd %int_2
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %dd %int_0 %int_0 %int_0
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %dd %int_0 %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %dd %int_1
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_v4float %dd %int_2
dd.a + dd.b + dd.c + dd.d;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ struct C : B {

float4 main() : SV_Target {
B b;
// CHECK: [[A_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_A %b %uint_0
// CHECK: [[base_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[A_ptr]] %int_0
// CHECK: [[base_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %b %int_0 %int_0
// CHECK: OpStore [[base_ptr]] {{%[0-9]+}}
b.base = float4(1, 1, 0, 1);
// CHECK: [[derived_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %b %int_1
Expand All @@ -42,12 +41,10 @@ float4 main() : SV_Target {
b.SetDerived(float4(1, 0, 1, 1));

C c;
// CHECK: [[A_ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_A %c %uint_0 %uint_0
// CHECK: [[base_ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[A_ptr_0]] %int_0
// CHECK: [[base_ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %c %int_0 %int_0 %int_0
// CHECK: OpStore [[base_ptr_0]] {{%[0-9]+}}
c.base = float4(0,0,0,0);
// CHECK: [[B_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_B %c %uint_0
// CHECK: [[derived_ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[B_ptr]] %int_1
// CHECK: [[derived_ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %c %int_0 %int_1
// CHECK: OpStore [[derived_ptr_0]] {{%[0-9]+}}
c.derived = float4(0,0,0,0);
// CHECK: [[c_value_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %c %int_1
Expand Down Expand Up @@ -76,8 +73,7 @@ float4 main() : SV_Target {
// CHECK-NEXT: %v = OpFunctionParameter %_ptr_Function_v4float
// CHECK-NEXT: %bb_entry_0 = OpLabel
// CHECK-NEXT: [[v:%[0-9]+]] = OpLoad %v4float %v
// CHECK-NEXT: [[A_ptr_1:%[0-9]+]] = OpAccessChain %_ptr_Function_A %param_this %uint_0
// CHECK-NEXT: [[base_ptr_1:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[A_ptr_1]] %int_0
// CHECK-NEXT: [[base_ptr_1:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %param_this %int_0 %int_0
// CHECK-NEXT: OpStore [[base_ptr_1]] [[v]]
// CHECK-NEXT: OpReturn
// CHECK-NEXT: OpFunctionEnd
Expand All @@ -100,8 +96,7 @@ float4 main() : SV_Target {
// CHECK-NEXT: %v_1 = OpFunctionParameter %_ptr_Function_v4float
// CHECK-NEXT: %bb_entry_2 = OpLabel
// CHECK-NEXT: [[v_1:%[0-9]+]] = OpLoad %v4float %v_1
// CHECK-NEXT: [[A_ptr_2:%[0-9]+]] = OpAccessChain %_ptr_Function_A %param_this_1 %uint_0 %uint_0
// CHECK-NEXT: [[base_ptr_2:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[A_ptr_2]] %int_0
// CHECK-NEXT: [[base_ptr_2:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %param_this_1 %int_0 %int_0 %int_0
// CHECK-NEXT: OpStore [[base_ptr_2]] [[v_1]]
// CHECK-NEXT: OpReturn
// CHECK-NEXT: OpFunctionEnd
Expand All @@ -112,8 +107,7 @@ float4 main() : SV_Target {
// CHECK-NEXT: %v_2 = OpFunctionParameter %_ptr_Function_v4float
// CHECK-NEXT: %bb_entry_3 = OpLabel
// CHECK-NEXT: [[v_2:%[0-9]+]] = OpLoad %v4float %v_2
// CHECK-NEXT: [[B_ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_B %param_this_2 %uint_0
// CHECK-NEXT: [[derived_ptr_2:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[B_ptr_0]] %int_1
// CHECK-NEXT: [[derived_ptr_2:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %param_this_2 %int_0 %int_1
// CHECK-NEXT: OpStore [[derived_ptr_2]] [[v_2]]
// CHECK-NEXT: OpReturn
// CHECK-NEXT: OpFunctionEnd
Expand All @@ -133,8 +127,7 @@ float4 main() : SV_Target {
// CHECK: %B_GetBase = OpFunction
// CHECK-NEXT: %param_this_4 = OpFunctionParameter %_ptr_Function_B
// CHECK-NEXT: %bb_entry_5 = OpLabel
// CHECK-NEXT: [[A_ptr_3:%[0-9]+]] = OpAccessChain %_ptr_Function_A %param_this_4 %uint_0
// CHECK-NEXT: [[base_ptr_3:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[A_ptr_3]] %int_0
// CHECK-NEXT: [[base_ptr_3:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %param_this_4 %int_0 %int_0
// CHECK-NEXT: [[base:%[0-9]+]] = OpLoad %v4float [[base_ptr_3]]
// CHECK-NEXT: OpReturnValue [[base]]
// CHECK-NEXT: OpFunctionEnd
Expand All @@ -152,8 +145,7 @@ float4 main() : SV_Target {
// CHECK: %C_GetBase = OpFunction
// CHECK-NEXT: %param_this_6 = OpFunctionParameter %_ptr_Function_C
// CHECK-NEXT: %bb_entry_7 = OpLabel
// CHECK-NEXT: [[A_ptr_4:%[0-9]+]] = OpAccessChain %_ptr_Function_A %param_this_6 %uint_0 %uint_0
// CHECK-NEXT: [[base_ptr_4:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[A_ptr_4]] %int_0
// CHECK-NEXT: [[base_ptr_4:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %param_this_6 %int_0 %int_0 %int_0
// CHECK-NEXT: [[base_0:%[0-9]+]] = OpLoad %v4float [[base_ptr_4]]
// CHECK-NEXT: OpReturnValue [[base_0]]
// CHECK-NEXT: OpFunctionEnd
Expand All @@ -162,8 +154,7 @@ float4 main() : SV_Target {
// CHECK: %C_GetDerived = OpFunction
// CHECK-NEXT: %param_this_7 = OpFunctionParameter %_ptr_Function_C
// CHECK-NEXT: %bb_entry_8 = OpLabel
// CHECK-NEXT: [[B_ptr_1:%[0-9]+]] = OpAccessChain %_ptr_Function_B %param_this_7 %uint_0
// CHECK-NEXT: [[derived_ptr_4:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float [[B_ptr_1]] %int_1
// CHECK-NEXT: [[derived_ptr_4:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %param_this_7 %int_0 %int_1
// CHECK-NEXT: [[derived_0:%[0-9]+]] = OpLoad %v4float [[derived_ptr_4]]
// CHECK-NEXT: OpReturnValue [[derived_0]]
// CHECK-NEXT: OpFunctionEnd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ void main(uint3 dispatchThreadId : SV_DispatchThreadID) {
// CHECK: [[p:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_Derived_0 Function
Derived p;

// CHECK: [[tmp:%[0-9]+]] = OpAccessChain %_ptr_Function_Base_0 [[p]] %uint_0
// CHECK: [[tmp_0:%[0-9]+]] = OpAccessChain %_ptr_Function_uint [[tmp]] %int_0
// CHECK: OpStore [[tmp_0]] %uint_5
// CHECK: [[tmp:%[0-9]+]] = OpAccessChain %_ptr_Function_uint [[p]] %int_0 %int_0
// CHECK: OpStore [[tmp]] %uint_5
p.base = 5;

// CHECK: [[tmp_1:%[0-9]+]] = OpAccessChain %_ptr_Function_uint [[p]] %int_1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ float main(PSInput input) : SV_TARGET
// CHECK: [[input:%[0-9]+]] = OpCompositeConstruct %PSInput [[parent]]


// CHECK: [[access0:%[0-9]+]] = OpAccessChain %_ptr_Function_Parent %input %uint_0
// CHECK: [[access1:%[0-9]+]] = OpAccessChain %_ptr_Function_float [[access0]] %int_0
// CHECK: [[load1:%[0-9]+]] = OpLoad %float [[access1]]
// CHECK: [[access:%[0-9]+]] = OpAccessChain %_ptr_Function_float %input %int_0 %int_0
// CHECK: [[load1:%[0-9]+]] = OpLoad %float [[access]]
return input.clipDistance;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// RUN: %dxc -T cs_6_6 -E main %s -spirv 2>&1 | FileCheck %s

RWStructuredBuffer<uint> Buf1;
RWStructuredBuffer<uint> Buf2;

Comment thread
s-perron marked this conversation as resolved.
struct A
{
RWStructuredBuffer<uint> Buffer;
void Increment() { Buffer.IncrementCounter(); }
};

struct B : A {};
struct C : B {};

[numthreads(64, 1, 1)]
void main()
{
B b;
b.Buffer = Buf1;

C c;
c.Buffer = Buf2;

// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %counter_var_Buf1 %uint_0
// CHECK: OpAtomicIAdd %int [[ac]] %uint_1 %uint_0 %int_1
b.Increment();

// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %counter_var_Buf2 %uint_0
// CHECK: OpAtomicIAdd %int [[ac]] %uint_1 %uint_0 %int_1
c.Increment();
}