Skip to content

Commit 5603f11

Browse files
committed
amdilc/compiler: handle multiple clip and cull distance values
1 parent d071016 commit 5603f11

File tree

1 file changed

+92
-22
lines changed

1 file changed

+92
-22
lines changed

src/amdilc/amdilc_compiler.c

Lines changed: 92 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,28 +1015,14 @@ static void emitOutput(
10151015
unsigned outputComponentCount = 0;
10161016
const char* outputPrefix = NULL;
10171017

1018-
if (dst->registerType == IL_REGTYPE_OUTPUT && importUsage == IL_IMPORTUSAGE_CLIPDISTANCE) {
1019-
// Clip distance is an array of one element
1020-
IlcSpvId oneId = ilcSpvPutConstant(compiler->module, compiler->intId, 1);
1021-
IlcSpvId arrayTypeId = ilcSpvPutArrayType(compiler->module, compiler->floatId, oneId);
1022-
IlcSpvId arrayId = emitVariable(compiler, arrayTypeId, SpvStorageClassOutput);
1023-
1024-
IlcSpvWord builtInType = SpvBuiltInClipDistance;
1025-
ilcSpvPutDecoration(compiler->module, arrayId, SpvDecorationBuiltIn, 1, &builtInType);
1026-
1027-
// The output register points to the first element in the array
1028-
outputTypeId = compiler->floatId;
1029-
IlcSpvId ptrTypeId = ilcSpvPutPointerType(compiler->module, SpvStorageClassOutput,
1030-
outputTypeId);
1031-
IlcSpvId indexId = ilcSpvPutConstant(compiler->module, compiler->intId, 0);
1032-
outputId = ilcSpvPutAccessChain(compiler->module, ptrTypeId, arrayId, 1, &indexId);
1033-
outputInterfaceId = arrayId;
1034-
outputComponentTypeId = compiler->floatId;
1035-
outputComponentCount = 1;
1036-
outputPrefix = "o";
1037-
} else if (dst->registerType == IL_REGTYPE_OUTPUT) {
1018+
if (dst->registerType == IL_REGTYPE_OUTPUT) {
10381019
outputTypeId = compiler->float4Id;
1039-
outputId = emitVariable(compiler, outputTypeId, SpvStorageClassOutput);
1020+
if (importUsage == IL_IMPORTUSAGE_CLIPDISTANCE || importUsage == IL_IMPORTUSAGE_CULLDISTANCE) {
1021+
// store it later
1022+
outputId = emitVariable(compiler, outputTypeId, SpvStorageClassPrivate);
1023+
} else {
1024+
outputId = emitVariable(compiler, outputTypeId, SpvStorageClassOutput);
1025+
}
10401026
outputInterfaceId = outputId;
10411027
outputComponentTypeId = compiler->floatId;
10421028
outputComponentCount = 4;
@@ -1048,7 +1034,7 @@ static void emitOutput(
10481034
} else if (importUsage == IL_IMPORTUSAGE_GENERIC) {
10491035
IlcSpvWord locationIdx = dst->registerNum;
10501036
ilcSpvPutDecoration(compiler->module, outputId, SpvDecorationLocation, 1, &locationIdx);
1051-
} else {
1037+
} else if (importUsage != IL_IMPORTUSAGE_CLIPDISTANCE && importUsage != IL_IMPORTUSAGE_CULLDISTANCE) {
10521038
LOGW("unhandled import usage %d\n", importUsage);
10531039
}
10541040
} else if (dst->registerType == IL_REGTYPE_DEPTH) {
@@ -3246,6 +3232,90 @@ static void finalizeVertexStage(
32463232

32473233
addRegister(compiler, &reg, "oPos");
32483234
}
3235+
3236+
const IlcRegister* cullRegs[2] = { NULL, NULL };
3237+
unsigned cullRegCount = 0;
3238+
const IlcRegister* clipRegs[2] = { NULL, NULL };
3239+
unsigned clipRegCount = 0;
3240+
for (int i = 0; i < compiler->regCount; i++) {
3241+
const IlcRegister* reg = &compiler->regs[i];
3242+
3243+
if (reg->ilType != IL_REGTYPE_OUTPUT) {
3244+
continue;
3245+
}
3246+
if (reg->ilImportUsage == IL_IMPORTUSAGE_CULLDISTANCE && cullRegCount < 2) {
3247+
cullRegs[cullRegCount++] = reg;
3248+
} else if (reg->ilImportUsage == IL_IMPORTUSAGE_CLIPDISTANCE && clipRegCount < 2) {
3249+
clipRegs[clipRegCount++] = reg;
3250+
}
3251+
}
3252+
3253+
if (clipRegCount == 0 && clipRegCount == 0) {
3254+
return;
3255+
}
3256+
IlcSpvId typeId = ilcSpvPutRuntimeArrayType(compiler->module, compiler->floatId, true);
3257+
IlcSpvId ptrTypeId = ilcSpvPutPointerType(compiler->module, SpvStorageClassOutput, typeId);
3258+
IlcSpvId compPtrTypeId = ilcSpvPutPointerType(compiler->module, SpvStorageClassOutput, compiler->floatId);
3259+
if (cullRegCount > 0) {
3260+
IlcSpvId cullBuiltInId = ilcSpvPutVariable(compiler->module, ptrTypeId, SpvStorageClassOutput);
3261+
IlcSpvWord builtInType = SpvBuiltInCullDistance;
3262+
ilcSpvPutDecoration(compiler->module, cullBuiltInId, SpvDecorationBuiltIn, 1, &builtInType);
3263+
for (unsigned i = 0; i < cullRegCount; ++i) {
3264+
IlcSpvId valId = ilcSpvPutLoad(compiler->module, cullRegs[i]->typeId, cullRegs[i]->id);
3265+
for (unsigned j = 0; j < 4; j++) {
3266+
if (cullRegs[i]->ilComponentMask[j] != IL_MODCOMP_WRITE) {
3267+
continue;
3268+
}
3269+
IlcSpvId compId = ilcSpvPutCompositeExtract(compiler->module, cullRegs[i]->componentTypeId, valId, 1, &j);
3270+
IlcSpvId indexId = ilcSpvPutConstant(compiler->module, compiler->intId, i * 4 + j);
3271+
IlcSpvId indexPtrId = ilcSpvPutAccessChain(compiler->module, compPtrTypeId, cullBuiltInId, 1, &indexId);
3272+
ilcSpvPutStore(compiler->module, indexPtrId, compId);
3273+
}
3274+
}
3275+
const IlcRegister cullBuiltInReg = {
3276+
.id = cullBuiltInId,
3277+
.interfaceId = cullBuiltInId,
3278+
.typeId = typeId,
3279+
.componentTypeId = compiler->floatId,
3280+
.componentCount = 1,
3281+
.ilType = IL_REGTYPE_OUTPUT,
3282+
.ilNum = 0,//idk what to place here (not needed :) )
3283+
.ilImportUsage = IL_IMPORTUSAGE_LAST,
3284+
.ilInterpMode = 0,
3285+
};
3286+
3287+
addRegister(compiler, &cullBuiltInReg, "gl_CullDistance");
3288+
}
3289+
if (clipRegCount > 0) {
3290+
IlcSpvId clipBuiltInId = ilcSpvPutVariable(compiler->module, ptrTypeId, SpvStorageClassOutput);
3291+
IlcSpvWord builtInType = SpvBuiltInClipDistance;
3292+
ilcSpvPutDecoration(compiler->module, clipBuiltInId, SpvDecorationBuiltIn, 1, &builtInType);
3293+
for (unsigned i = 0; i < clipRegCount; ++i) {
3294+
IlcSpvId valId = ilcSpvPutLoad(compiler->module, clipRegs[i]->typeId, clipRegs[i]->id);
3295+
for (unsigned j = 0; j < 4; j++) {
3296+
if (clipRegs[i]->ilComponentMask[j] != IL_MODCOMP_WRITE) {
3297+
continue;
3298+
}
3299+
IlcSpvId compId = ilcSpvPutCompositeExtract(compiler->module, clipRegs[i]->componentTypeId, valId, 1, &j);
3300+
IlcSpvId indexId = ilcSpvPutConstant(compiler->module, compiler->intId, i * 4 + j);
3301+
IlcSpvId indexPtrId = ilcSpvPutAccessChain(compiler->module, compPtrTypeId, clipBuiltInId, 1, &indexId);
3302+
ilcSpvPutStore(compiler->module, indexPtrId, compId);
3303+
}
3304+
}
3305+
const IlcRegister clipBuiltInReg = {
3306+
.id = clipBuiltInId,
3307+
.interfaceId = clipBuiltInId,
3308+
.typeId = typeId,
3309+
.componentTypeId = compiler->floatId,
3310+
.componentCount = 1,
3311+
.ilType = IL_REGTYPE_OUTPUT,
3312+
.ilNum = 0,//idk what to place here (not needed :) )
3313+
.ilImportUsage = IL_IMPORTUSAGE_LAST,
3314+
.ilInterpMode = 0,
3315+
};
3316+
3317+
addRegister(compiler, &clipBuiltInReg, "gl_ClipDistance");
3318+
}
32493319
}
32503320

32513321
static void emitImplicitInput(

0 commit comments

Comments
 (0)