Skip to content

Commit

Permalink
amdilc, mantle: handle basic atomic counter buffer functionality
Browse files Browse the repository at this point in the history
Added support for APPEND_BUF_ALLOC, APPEND_BUF_CONSUME instructions, added support for grCmdInitAtomicCounters which is used by Battlefield 4.
  • Loading branch information
Cherser-s committed Oct 24, 2021
1 parent 01ed9a1 commit 5534fe1
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/amdilc/amdilc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

// TODO get rid of this
#define ILC_BASE_RESOURCE_ID (16) // Samplers use 0-15
#define ILC_BASE_APPEND_COUNTER_RESOURCE_ID (0xFFFF)

#define ILC_MAX_STRIDE_CONSTANTS (8)

Expand Down
69 changes: 69 additions & 0 deletions src/amdilc/amdilc_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
typedef enum {
RES_TYPE_GENERIC,
RES_TYPE_LDS,
RES_TYPE_ATOMIC_BUFFER,
} IlcResourceType;

typedef enum {
Expand Down Expand Up @@ -2494,6 +2495,70 @@ static void emitLdsStoreVec(
}
}

static void emitUavAppendBufAlloc(
IlcCompiler* compiler,
const Instruction* instr)
{
uint8_t ilResourceId = GET_BITS(instr->control, 0, 14);
bool increment = instr->opcode == IL_OP_APPEND_BUF_ALLOC;
//ilResourceId is always 0
const IlcResource* resource = findResource(compiler, RES_TYPE_ATOMIC_BUFFER, 0);
if (resource == NULL) {
IlcSpvId arrayId = ilcSpvPutRuntimeArrayType(compiler->module, compiler->uintId, true);
IlcSpvId structId = ilcSpvPutUniqueStructType(compiler->module, 1, &arrayId);
IlcSpvId pCounterId = ilcSpvPutPointerType(compiler->module, SpvStorageClassStorageBuffer, structId);
IlcSpvId resourceId = ilcSpvPutVariable(compiler->module, pCounterId, SpvStorageClassStorageBuffer);

IlcSpvWord arrayStride = sizeof(unsigned);
IlcSpvWord memberOffset = 0;
ilcSpvPutDecoration(compiler->module, arrayId, SpvDecorationArrayStride, 1, &arrayStride);
ilcSpvPutDecoration(compiler->module, structId, SpvDecorationBlock, 0, NULL);
ilcSpvPutMemberDecoration(compiler->module, structId, 0, SpvDecorationOffset, 1, &memberOffset);

const IlcResource resourceInfo = {
.resType = RES_TYPE_ATOMIC_BUFFER,
.id = resourceId,
.typeId = structId,
.texelTypeId = compiler->uintId,
.ilId = 0,
.ilType = IL_USAGE_PIXTEX_UNKNOWN,
.strideId = 0,
.structured = false,
};

emitBinding(compiler, resourceId, ILC_BASE_APPEND_COUNTER_RESOURCE_ID, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
NO_STRIDE_INDEX);

addResource(compiler, &resourceInfo);
resource = findResource(compiler, RES_TYPE_ATOMIC_BUFFER, 0);
if (resource == NULL) {
LOGE("failed to find counter resource after creation");
return;
}
}
const Destination* dst = &instr->dsts[0];

IlcSpvId zeroId = ilcSpvPutConstant(compiler->module, compiler->uintId, ZERO_LITERAL);
IlcSpvId counterIndexId = ilcSpvPutConstant(compiler->module, compiler->uintId, ilResourceId);
IlcSpvId scopeId = ilcSpvPutConstant(compiler->module, compiler->intId, SpvScopeDevice);

IlcSpvId ptrTypeId = ilcSpvPutPointerType(compiler->module, SpvStorageClassStorageBuffer, resource->texelTypeId);

IlcSpvId indexIds[] = { zeroId, counterIndexId };
IlcSpvId ptrId = ilcSpvPutAccessChain(compiler->module, ptrTypeId, resource->id,
2, indexIds);
IlcSpvId semanticsId = ilcSpvPutConstant(compiler->module, compiler->intId,
SpvMemorySemanticsAcquireReleaseMask |
SpvMemorySemanticsUniformMemoryMask);
IlcSpvId readId = ilcSpvPutAtomicOpWithoutValue(compiler->module, increment ? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement,
resource->texelTypeId, ptrId, scopeId, semanticsId);

IlcSpvId constituents[4] = { readId, zeroId, zeroId, zeroId};
IlcSpvId loadId = ilcSpvPutCompositeConstruct(compiler->module, compiler->uint4Id,
4, constituents);
storeDestination(compiler, dst, loadId, compiler->uint4Id);
}

static void emitUavLoad(
IlcCompiler* compiler,
const Instruction* instr)
Expand Down Expand Up @@ -3135,6 +3200,10 @@ static void emitInstr(
case IL_OP_LDS_READ_UMAX:
emitLdsAtomicOp(compiler, instr);
break;
case IL_OP_APPEND_BUF_ALLOC:
case IL_OP_APPEND_BUF_CONSUME:
emitUavAppendBufAlloc(compiler, instr);
break;
case IL_OP_DCL_RAW_SRV:
case IL_OP_DCL_STRUCT_SRV:
emitSrv(compiler, instr);
Expand Down
28 changes: 28 additions & 0 deletions src/amdilc/amdilc_spirv.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,14 @@ IlcSpvId ilcSpvPutRuntimeArrayType(
return putType(module, SpvOpTypeRuntimeArray, 1, &typeId, true, unique);
}

IlcSpvId ilcSpvPutUniqueStructType(
IlcSpvModule* module,
unsigned memberTypeIdCount,
const IlcSpvId* memberTypeId)
{
return putType(module, SpvOpTypeStruct, memberTypeIdCount, memberTypeId, true, true);
}

IlcSpvId ilcSpvPutStructType(
IlcSpvModule* module,
unsigned memberTypeIdCount,
Expand Down Expand Up @@ -889,6 +897,26 @@ IlcSpvId ilcSpvPutOp4(
return id;
}

IlcSpvId ilcSpvPutAtomicOpWithoutValue(
IlcSpvModule* module,
SpvOp op,
IlcSpvId resultTypeId,
IlcSpvId pointerId,
IlcSpvWord memoryId,
IlcSpvWord semanticsId)
{
IlcSpvBuffer* buffer = &module->buffer[ID_CODE];

IlcSpvId id = ilcSpvAllocId(module);
putInstr(buffer, op, 6);
putWord(buffer, resultTypeId);
putWord(buffer, id);
putWord(buffer, pointerId);
putWord(buffer, memoryId);
putWord(buffer, semanticsId);
return id;
}

IlcSpvId ilcSpvPutAtomicOp(
IlcSpvModule* module,
SpvOp op,
Expand Down
13 changes: 13 additions & 0 deletions src/amdilc/amdilc_spirv.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ IlcSpvId ilcSpvPutRuntimeArrayType(
IlcSpvId typeId,
bool unique);

IlcSpvId ilcSpvPutUniqueStructType(
IlcSpvModule* module,
unsigned memberTypeIdCount,
const IlcSpvId* memberTypeId);

IlcSpvId ilcSpvPutStructType(
IlcSpvModule* module,
unsigned memberTypeIdCount,
Expand Down Expand Up @@ -318,6 +323,14 @@ IlcSpvId ilcSpvPutAtomicOp(
IlcSpvWord semanticsId,
IlcSpvId valueId);

IlcSpvId ilcSpvPutAtomicOpWithoutValue(
IlcSpvModule* module,
SpvOp op,
IlcSpvId resultTypeId,
IlcSpvId pointerId,
IlcSpvWord memoryId,
IlcSpvWord semanticsId);

IlcSpvId ilcSpvPutBitcast(
IlcSpvModule* module,
IlcSpvId resultTypeId,
Expand Down
Loading

0 comments on commit 5534fe1

Please sign in to comment.