|
34 | 34 |
|
35 | 35 | namespace Slang {
|
36 | 36 |
|
| 37 | +bool isCPUTarget(TargetRequest* targetReq); |
| 38 | +bool isCUDATarget(TargetRequest* targetReq); |
| 39 | + |
37 | 40 | struct CLikeSourceEmitter::ComputeEmitActionsContext
|
38 | 41 | {
|
39 | 42 | IRInst* moduleInst;
|
@@ -352,6 +355,43 @@ void CLikeSourceEmitter::_emitType(IRType* type, DeclaratorInfo* declarator)
|
352 | 355 | }
|
353 | 356 | }
|
354 | 357 |
|
| 358 | +void CLikeSourceEmitter::_emitSwizzleStorePerElement(IRInst* inst) |
| 359 | +{ |
| 360 | + auto subscriptOuter = getInfo(EmitOp::General); |
| 361 | + auto subscriptPrec = getInfo(EmitOp::Postfix); |
| 362 | + |
| 363 | + auto ii = cast<IRSwizzledStore>(inst); |
| 364 | + |
| 365 | + UInt elementCount = ii->getElementCount(); |
| 366 | + UInt dstIndex = 0; |
| 367 | + for (UInt ee = 0; ee < elementCount; ++ee) |
| 368 | + { |
| 369 | + bool needCloseSubscript = maybeEmitParens(subscriptOuter, subscriptPrec); |
| 370 | + |
| 371 | + emitDereferenceOperand(ii->getDest(), leftSide(subscriptOuter, subscriptPrec)); |
| 372 | + m_writer->emit("."); |
| 373 | + |
| 374 | + IRInst* irElementIndex = ii->getElementIndex(ee); |
| 375 | + SLANG_RELEASE_ASSERT(irElementIndex->getOp() == kIROp_IntLit); |
| 376 | + |
| 377 | + IRConstant* irConst = (IRConstant*)irElementIndex; |
| 378 | + |
| 379 | + UInt elementIndex = (UInt)irConst->value.intVal; |
| 380 | + SLANG_RELEASE_ASSERT(elementIndex < 4); |
| 381 | + |
| 382 | + char const* kComponents[] = { "x", "y", "z", "w" }; |
| 383 | + m_writer->emit(kComponents[elementIndex]); |
| 384 | + |
| 385 | + maybeCloseParens(needCloseSubscript); |
| 386 | + |
| 387 | + m_writer->emit(" = "); |
| 388 | + emitOperand(ii->getSource(), getInfo(EmitOp::General)); |
| 389 | + m_writer->emit("."); |
| 390 | + m_writer->emit(kComponents[dstIndex++]); |
| 391 | + m_writer->emit(";\n"); |
| 392 | + } |
| 393 | +} |
| 394 | + |
355 | 395 | void CLikeSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable)
|
356 | 396 | {
|
357 | 397 | SLANG_UNUSED(witnessTable);
|
@@ -1494,6 +1534,19 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
|
1494 | 1534 | }
|
1495 | 1535 | }
|
1496 | 1536 | }
|
| 1537 | + |
| 1538 | + // For cuda and cpu targets don't support swizzle on the left-hand-side |
| 1539 | + // variable, e.g. vec4.xy = vec2 is not allowed. |
| 1540 | + // Therefore, we don't want to fold the right-hand-side expression. |
| 1541 | + // Instead, the right-hand-side expression should be generated as a separable |
| 1542 | + // statement and stored in a temporary varible, then assign to the left-hand-side |
| 1543 | + // variable per element. E.g. vec4.x = vec2.x; vec4.y = vec2.y. |
| 1544 | + if (as<IRSwizzledStore>(user)) |
| 1545 | + { |
| 1546 | + if (isCPUTarget(getTargetReq()) || isCUDATarget(getTargetReq())) |
| 1547 | + return false; |
| 1548 | + } |
| 1549 | + |
1497 | 1550 | // We'd like to figure out if it is safe to fold our instruction into `user`
|
1498 | 1551 |
|
1499 | 1552 | // First, let's make sure they are in the same block/parent:
|
@@ -2760,32 +2813,41 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
|
2760 | 2813 |
|
2761 | 2814 | case kIROp_SwizzledStore:
|
2762 | 2815 | {
|
2763 |
| - auto subscriptOuter = getInfo(EmitOp::General); |
2764 |
| - auto subscriptPrec = getInfo(EmitOp::Postfix); |
2765 |
| - bool needCloseSubscript = maybeEmitParens(subscriptOuter, subscriptPrec); |
| 2816 | + // cpp and cuda target don't support swizzle on the left handside, so we |
| 2817 | + // have to assign the element one by one. |
| 2818 | + if (isCPUTarget(getTargetReq()) || isCUDATarget(getTargetReq())) |
| 2819 | + { |
| 2820 | + _emitSwizzleStorePerElement(inst); |
| 2821 | + } |
| 2822 | + else |
| 2823 | + { |
2766 | 2824 |
|
| 2825 | + auto subscriptOuter = getInfo(EmitOp::General); |
| 2826 | + auto subscriptPrec = getInfo(EmitOp::Postfix); |
| 2827 | + bool needCloseSubscript = maybeEmitParens(subscriptOuter, subscriptPrec); |
2767 | 2828 |
|
2768 |
| - auto ii = cast<IRSwizzledStore>(inst); |
2769 |
| - emitDereferenceOperand(ii->getDest(), leftSide(subscriptOuter, subscriptPrec)); |
2770 |
| - m_writer->emit("."); |
2771 |
| - UInt elementCount = ii->getElementCount(); |
2772 |
| - for (UInt ee = 0; ee < elementCount; ++ee) |
2773 |
| - { |
2774 |
| - IRInst* irElementIndex = ii->getElementIndex(ee); |
2775 |
| - SLANG_RELEASE_ASSERT(irElementIndex->getOp() == kIROp_IntLit); |
2776 |
| - IRConstant* irConst = (IRConstant*)irElementIndex; |
| 2829 | + auto ii = cast<IRSwizzledStore>(inst); |
| 2830 | + emitDereferenceOperand(ii->getDest(), leftSide(subscriptOuter, subscriptPrec)); |
| 2831 | + m_writer->emit("."); |
| 2832 | + UInt elementCount = ii->getElementCount(); |
| 2833 | + for (UInt ee = 0; ee < elementCount; ++ee) |
| 2834 | + { |
| 2835 | + IRInst* irElementIndex = ii->getElementIndex(ee); |
| 2836 | + SLANG_RELEASE_ASSERT(irElementIndex->getOp() == kIROp_IntLit); |
| 2837 | + IRConstant* irConst = (IRConstant*)irElementIndex; |
2777 | 2838 |
|
2778 |
| - UInt elementIndex = (UInt)irConst->value.intVal; |
2779 |
| - SLANG_RELEASE_ASSERT(elementIndex < 4); |
| 2839 | + UInt elementIndex = (UInt)irConst->value.intVal; |
| 2840 | + SLANG_RELEASE_ASSERT(elementIndex < 4); |
2780 | 2841 |
|
2781 |
| - char const* kComponents[] = { "x", "y", "z", "w" }; |
2782 |
| - m_writer->emit(kComponents[elementIndex]); |
2783 |
| - } |
2784 |
| - maybeCloseParens(needCloseSubscript); |
| 2842 | + char const* kComponents[] = { "x", "y", "z", "w" }; |
| 2843 | + m_writer->emit(kComponents[elementIndex]); |
| 2844 | + } |
| 2845 | + maybeCloseParens(needCloseSubscript); |
2785 | 2846 |
|
2786 |
| - m_writer->emit(" = "); |
2787 |
| - emitOperand(ii->getSource(), getInfo(EmitOp::General)); |
2788 |
| - m_writer->emit(";\n"); |
| 2847 | + m_writer->emit(" = "); |
| 2848 | + emitOperand(ii->getSource(), getInfo(EmitOp::General)); |
| 2849 | + m_writer->emit(";\n"); |
| 2850 | + } |
2789 | 2851 | }
|
2790 | 2852 | break;
|
2791 | 2853 |
|
|
0 commit comments