Skip to content

Commit 671db09

Browse files
committed
amdilc, mantle: handle basic atomic counter buffer functionality
Added support for APPEND_BUF_ALLOC, APPEND_BUF_CONSUME instructions, added support for grCmdInitAtomicCounters which is used by Battlefield 4.
1 parent 9e7994c commit 671db09

File tree

8 files changed

+328
-30
lines changed

8 files changed

+328
-30
lines changed

src/amdilc/amdilc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
// TODO get rid of this
1010
#define ILC_BASE_RESOURCE_ID (16) // Samplers use 0-15
11+
#define ILC_BASE_APPEND_COUNTER_RESOURCE_ID (0xFFFF)
1112

1213
#define ILC_MAX_STRIDE_CONSTANTS (8)
1314

src/amdilc/amdilc_compiler.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
typedef enum {
2424
RES_TYPE_GENERIC,
2525
RES_TYPE_LDS,
26+
RES_TYPE_ATOMIC_BUFFER,
2627
} IlcResourceType;
2728

2829
typedef enum {
@@ -2494,6 +2495,70 @@ static void emitLdsStoreVec(
24942495
}
24952496
}
24962497

2498+
static void emitUavAppendBufAlloc(
2499+
IlcCompiler* compiler,
2500+
const Instruction* instr)
2501+
{
2502+
uint8_t ilResourceId = GET_BITS(instr->control, 0, 14);
2503+
bool increment = instr->opcode == IL_OP_APPEND_BUF_ALLOC;
2504+
//ilResourceId is always 0
2505+
const IlcResource* resource = findResource(compiler, RES_TYPE_ATOMIC_BUFFER, 0);
2506+
if (resource == NULL) {
2507+
IlcSpvId arrayId = ilcSpvPutRuntimeArrayType(compiler->module, compiler->uintId, true);
2508+
IlcSpvId structId = ilcSpvPutUniqueStructType(compiler->module, 1, &arrayId);
2509+
IlcSpvId pCounterId = ilcSpvPutPointerType(compiler->module, SpvStorageClassStorageBuffer, structId);
2510+
IlcSpvId resourceId = ilcSpvPutVariable(compiler->module, pCounterId, SpvStorageClassStorageBuffer);
2511+
2512+
IlcSpvWord arrayStride = sizeof(unsigned);
2513+
IlcSpvWord memberOffset = 0;
2514+
ilcSpvPutDecoration(compiler->module, arrayId, SpvDecorationArrayStride, 1, &arrayStride);
2515+
ilcSpvPutDecoration(compiler->module, structId, SpvDecorationBlock, 0, NULL);
2516+
ilcSpvPutMemberDecoration(compiler->module, structId, 0, SpvDecorationOffset, 1, &memberOffset);
2517+
2518+
const IlcResource resourceInfo = {
2519+
.resType = RES_TYPE_ATOMIC_BUFFER,
2520+
.id = resourceId,
2521+
.typeId = structId,
2522+
.texelTypeId = compiler->uintId,
2523+
.ilId = 0,
2524+
.ilType = IL_USAGE_PIXTEX_UNKNOWN,
2525+
.strideId = 0,
2526+
.structured = false,
2527+
};
2528+
2529+
emitBinding(compiler, resourceId, ILC_BASE_APPEND_COUNTER_RESOURCE_ID, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2530+
NO_STRIDE_INDEX);
2531+
2532+
addResource(compiler, &resourceInfo);
2533+
resource = findResource(compiler, RES_TYPE_ATOMIC_BUFFER, 0);
2534+
if (resource == NULL) {
2535+
LOGE("failed to find counter resource after creation");
2536+
return;
2537+
}
2538+
}
2539+
const Destination* dst = &instr->dsts[0];
2540+
2541+
IlcSpvId zeroId = ilcSpvPutConstant(compiler->module, compiler->uintId, ZERO_LITERAL);
2542+
IlcSpvId counterIndexId = ilcSpvPutConstant(compiler->module, compiler->uintId, ilResourceId);
2543+
IlcSpvId scopeId = ilcSpvPutConstant(compiler->module, compiler->intId, SpvScopeDevice);
2544+
2545+
IlcSpvId ptrTypeId = ilcSpvPutPointerType(compiler->module, SpvStorageClassStorageBuffer, resource->texelTypeId);
2546+
2547+
IlcSpvId indexIds[] = { zeroId, counterIndexId };
2548+
IlcSpvId ptrId = ilcSpvPutAccessChain(compiler->module, ptrTypeId, resource->id,
2549+
2, indexIds);
2550+
IlcSpvId semanticsId = ilcSpvPutConstant(compiler->module, compiler->intId,
2551+
SpvMemorySemanticsAcquireReleaseMask |
2552+
SpvMemorySemanticsUniformMemoryMask);
2553+
IlcSpvId readId = ilcSpvPutAtomicOpWithoutValue(compiler->module, increment ? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement,
2554+
resource->texelTypeId, ptrId, scopeId, semanticsId);
2555+
2556+
IlcSpvId constituents[4] = { readId, zeroId, zeroId, zeroId};
2557+
IlcSpvId loadId = ilcSpvPutCompositeConstruct(compiler->module, compiler->uint4Id,
2558+
4, constituents);
2559+
storeDestination(compiler, dst, loadId, compiler->uint4Id);
2560+
}
2561+
24972562
static void emitUavLoad(
24982563
IlcCompiler* compiler,
24992564
const Instruction* instr)
@@ -3135,6 +3200,10 @@ static void emitInstr(
31353200
case IL_OP_LDS_READ_UMAX:
31363201
emitLdsAtomicOp(compiler, instr);
31373202
break;
3203+
case IL_OP_APPEND_BUF_ALLOC:
3204+
case IL_OP_APPEND_BUF_CONSUME:
3205+
emitUavAppendBufAlloc(compiler, instr);
3206+
break;
31383207
case IL_OP_DCL_RAW_SRV:
31393208
case IL_OP_DCL_STRUCT_SRV:
31403209
emitSrv(compiler, instr);

src/amdilc/amdilc_spirv.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,14 @@ IlcSpvId ilcSpvPutRuntimeArrayType(
419419
return putType(module, SpvOpTypeRuntimeArray, 1, &typeId, true, unique);
420420
}
421421

422+
IlcSpvId ilcSpvPutUniqueStructType(
423+
IlcSpvModule* module,
424+
unsigned memberTypeIdCount,
425+
const IlcSpvId* memberTypeId)
426+
{
427+
return putType(module, SpvOpTypeStruct, memberTypeIdCount, memberTypeId, true, true);
428+
}
429+
422430
IlcSpvId ilcSpvPutStructType(
423431
IlcSpvModule* module,
424432
unsigned memberTypeIdCount,
@@ -889,6 +897,26 @@ IlcSpvId ilcSpvPutOp4(
889897
return id;
890898
}
891899

900+
IlcSpvId ilcSpvPutAtomicOpWithoutValue(
901+
IlcSpvModule* module,
902+
SpvOp op,
903+
IlcSpvId resultTypeId,
904+
IlcSpvId pointerId,
905+
IlcSpvWord memoryId,
906+
IlcSpvWord semanticsId)
907+
{
908+
IlcSpvBuffer* buffer = &module->buffer[ID_CODE];
909+
910+
IlcSpvId id = ilcSpvAllocId(module);
911+
putInstr(buffer, op, 6);
912+
putWord(buffer, resultTypeId);
913+
putWord(buffer, id);
914+
putWord(buffer, pointerId);
915+
putWord(buffer, memoryId);
916+
putWord(buffer, semanticsId);
917+
return id;
918+
}
919+
892920
IlcSpvId ilcSpvPutAtomicOp(
893921
IlcSpvModule* module,
894922
SpvOp op,

src/amdilc/amdilc_spirv.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ IlcSpvId ilcSpvPutRuntimeArrayType(
128128
IlcSpvId typeId,
129129
bool unique);
130130

131+
IlcSpvId ilcSpvPutUniqueStructType(
132+
IlcSpvModule* module,
133+
unsigned memberTypeIdCount,
134+
const IlcSpvId* memberTypeId);
135+
131136
IlcSpvId ilcSpvPutStructType(
132137
IlcSpvModule* module,
133138
unsigned memberTypeIdCount,
@@ -318,6 +323,14 @@ IlcSpvId ilcSpvPutAtomicOp(
318323
IlcSpvWord semanticsId,
319324
IlcSpvId valueId);
320325

326+
IlcSpvId ilcSpvPutAtomicOpWithoutValue(
327+
IlcSpvModule* module,
328+
SpvOp op,
329+
IlcSpvId resultTypeId,
330+
IlcSpvId pointerId,
331+
IlcSpvWord memoryId,
332+
IlcSpvWord semanticsId);
333+
321334
IlcSpvId ilcSpvPutBitcast(
322335
IlcSpvModule* module,
323336
IlcSpvId resultTypeId,

0 commit comments

Comments
 (0)