@@ -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
32513321static void emitImplicitInput (
0 commit comments