@@ -1829,6 +1829,18 @@ class Converter : public BuildUtil
18291829 Stack breakBBs; // end of / after loop
18301830
18311831 Value *viewport;
1832+
1833+ struct VertexOutput {
1834+ VertexOutput (const tgsi::Instruction::DstRegister& d, int channel, Value *value, Value *pointer)
1835+ : dst(d), c(channel), val(value), ptr(pointer) {}
1836+
1837+ tgsi::Instruction::DstRegister dst;
1838+ int c;
1839+ Value *val;
1840+ Value *ptr;
1841+ };
1842+
1843+ std::vector<VertexOutput> vertexOutputs;
18321844};
18331845
18341846Symbol *
@@ -2248,7 +2260,8 @@ Converter::storeDst(const tgsi::Instruction::DstRegister dst, int c,
22482260 assert (!ptr);
22492261 mkOp2 (OP_WRSV , TYPE_U32 , NULL , dstToSym (dst, c), val);
22502262 } else
2251- if (f == TGSI_FILE_OUTPUT && prog->getType () != Program::TYPE_FRAGMENT ) {
2263+ if (f == TGSI_FILE_OUTPUT && prog->getType () != Program::TYPE_FRAGMENT && prog->getType () != Program::TYPE_VERTEX ) {
2264+ // This condition now excludes both fragment and vertex shaders
22522265
22532266 if (ptr || (info->out [idx].mask & (1 << c))) {
22542267 /* Save the viewport index into a scratch register so that it can be
@@ -2262,6 +2275,10 @@ Converter::storeDst(const tgsi::Instruction::DstRegister dst, int c,
22622275 info->out [idx].patch ;
22632276 }
22642277 } else
2278+ if (f == TGSI_FILE_OUTPUT && prog->getType () == Program::TYPE_VERTEX ) {
2279+ // For vertex shaders, collect outputs to emit later
2280+ vertexOutputs.push_back (VertexOutput (dst, c, val, ptr));
2281+ } else
22652282 if (f == TGSI_FILE_TEMPORARY ||
22662283 f == TGSI_FILE_ADDRESS ||
22672284 f == TGSI_FILE_OUTPUT ) {
@@ -3835,7 +3852,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
38353852 BasicBlock *epilogue = BasicBlock::get (func->cfgExit );
38363853 bb->cfg .attach (&epilogue->cfg , Graph::Edge::TREE );
38373854 setPosition (epilogue, true );
3838- if (prog->getType () == Program::TYPE_FRAGMENT )
3855+ if (prog->getType () == Program::TYPE_FRAGMENT || prog-> getType () == Program:: TYPE_VERTEX )
38393856 exportOutputs ();
38403857 if ((prog->getType () == Program::TYPE_VERTEX ||
38413858 prog->getType () == Program::TYPE_TESSELLATION_EVAL
@@ -4313,40 +4330,62 @@ Converter::handleUserClipPlanes()
43134330void
43144331Converter::exportOutputs ()
43154332{
4316- if (info->io .alphaRefBase ) {
4317- for (unsigned int i = 0 ; i < info->numOutputs ; ++i) {
4318- if (info->out [i].sn != TGSI_SEMANTIC_COLOR ||
4319- info->out [i].si != 0 )
4320- continue ;
4321- const unsigned int c = 3 ;
4322- if (!oData.exists (sub.cur ->values , i, c))
4323- continue ;
4324- Value *val = oData.load (sub.cur ->values , i, c, NULL );
4325- if (!val)
4326- continue ;
4327-
4328- Symbol *ref = mkSymbol (FILE_MEMORY_CONST , info->io .auxCBSlot ,
4329- TYPE_U32 , info->io .alphaRefBase );
4330- Value *pred = new_LValue (func, FILE_PREDICATE );
4331- mkCmp (OP_SET , CC_TR , TYPE_U32 , pred, TYPE_F32 , val,
4332- mkLoadv (TYPE_U32 , ref, NULL ))
4333- ->subOp = 1 ;
4334- mkOp (OP_DISCARD , TYPE_NONE , NULL )->setPredicate (CC_NOT_P , pred);
4335- }
4336- }
4333+ if (prog->getType () == Program::TYPE_FRAGMENT || prog->getType () == Program::TYPE_VERTEX ) {
4334+ if (prog->getType () == Program::TYPE_FRAGMENT ) {
4335+ if (info->io .alphaRefBase ) {
4336+ for (unsigned int i = 0 ; i < info->numOutputs ; ++i) {
4337+ if (info->out [i].sn != TGSI_SEMANTIC_COLOR ||
4338+ info->out [i].si != 0 )
4339+ continue ;
4340+ const unsigned int c = 3 ;
4341+ if (!oData.exists (sub.cur ->values , i, c))
4342+ continue ;
4343+ Value *val = oData.load (sub.cur ->values , i, c, NULL );
4344+ if (!val)
4345+ continue ;
4346+
4347+ Symbol *ref = mkSymbol (FILE_MEMORY_CONST , info->io .auxCBSlot ,
4348+ TYPE_U32 , info->io .alphaRefBase );
4349+ Value *pred = new_LValue (func, FILE_PREDICATE );
4350+ mkCmp (OP_SET , CC_TR , TYPE_U32 , pred, TYPE_F32 , val,
4351+ mkLoadv (TYPE_U32 , ref, NULL ))
4352+ ->subOp = 1 ;
4353+ mkOp (OP_DISCARD , TYPE_NONE , NULL )->setPredicate (CC_NOT_P , pred);
4354+ }
4355+ }
43374356
4338- for (unsigned int i = 0 ; i < info->numOutputs ; ++i) {
4339- for (unsigned int c = 0 ; c < 4 ; ++c) {
4340- if (!oData.exists (sub.cur ->values , i, c))
4341- continue ;
4342- Symbol *sym = mkSymbol (FILE_SHADER_OUTPUT , 0 , TYPE_F32 ,
4343- info->out [i].slot [c] * 4 );
4344- Value *val = oData.load (sub.cur ->values , i, c, NULL );
4345- if (val) {
4346- if (info->out [i].sn == TGSI_SEMANTIC_POSITION )
4347- mkOp1 (OP_SAT , TYPE_F32 , val, val);
4348- mkStore (OP_EXPORT , TYPE_F32 , sym, NULL , val);
4357+ for (unsigned int i = 0 ; i < info->numOutputs ; ++i) {
4358+ for (unsigned int c = 0 ; c < 4 ; ++c) {
4359+ if (!oData.exists (sub.cur ->values , i, c))
4360+ continue ;
4361+ Symbol *sym = mkSymbol (FILE_SHADER_OUTPUT , 0 , TYPE_F32 ,
4362+ info->out [i].slot [c] * 4 );
4363+ Value *val = oData.load (sub.cur ->values , i, c, NULL );
4364+ if (val) {
4365+ if (info->out [i].sn == TGSI_SEMANTIC_POSITION )
4366+ mkOp1 (OP_SAT , TYPE_F32 , val, val);
4367+ mkStore (OP_EXPORT , TYPE_F32 , sym, NULL , val);
4368+ }
4369+ }
4370+ }
4371+ } else if (prog->getType () == Program::TYPE_VERTEX ) {
4372+ // Emit all collected vertex outputs in the original format
4373+ for (size_t i = 0 ; i < vertexOutputs.size (); ++i) {
4374+ const VertexOutput &output = vertexOutputs[i];
4375+ const unsigned idx = output.dst .getIndex (0 );
4376+
4377+ if (output.ptr || (info->out [idx].mask & (1 << output.c ))) {
4378+ if (info->out [idx].sn == TGSI_SEMANTIC_VIEWPORT_INDEX &&
4379+ viewport != NULL ) {
4380+ mkOp1 (OP_MOV , TYPE_U32 , viewport, output.val );
4381+ } else {
4382+ mkStore (OP_EXPORT , TYPE_U32 , dstToSym (output.dst , output.c ),
4383+ output.ptr , output.val )->perPatch = info->out [idx].patch ;
4384+ }
4385+ }
43494386 }
4387+ // Clear the vector after emitting all outputs
4388+ vertexOutputs.clear ();
43504389 }
43514390 }
43524391}
0 commit comments