@@ -6664,13 +6664,76 @@ void EmitPass::emitPSSGV(GenIntrinsicInst* inst)
6664
6664
{
6665
6665
if (psProgram->GetPhase() == PSPHASE_PIXEL || psProgram->GetPhase() == PSPHASE_COARSE)
6666
6666
{
6667
- e_interpolation mode = EINTERPOLATION_LINEAR;
6668
- CVariable* bary = psProgram->GetBaryReg(mode);
6669
- CVariable* delta =
6670
- (usage == POSITION_Z) ? psProgram->GetZDelta() : psProgram->GetWDelta();
6671
- m_encoder->SetSrcRegion(0, 0, 4, 1);
6672
- m_encoder->Pln(m_destination, delta, bary);
6667
+ // source depth:
6668
+ // src_z = (x - xstart)*z_cx + (y - ystart)*z_cy + z_c0
6669
+ // source w:
6670
+ // src_w = 1/((x - xstart)*1w_cx + (y - ystart)*1w_cy + 1w_c0)
6671
+ CVariable* delta = psProgram->GetZWDelta();
6672
+
6673
+ CVariable* floatR1 = psProgram->BitCast(psProgram->GetR1(), ISA_TYPE_F);
6674
+
6675
+ // Returns (x - xstart) or (y - ystart) in float.
6676
+ auto getPixelPositionDelta = [this, psProgram, delta, floatR1](const uint component)->CVariable*
6677
+ {
6678
+ assert(component < 2);
6679
+ CVariable* uintPixelPosition =
6680
+ m_currShader->GetNewVariable(numLanes(m_currShader->m_SIMDSize), ISA_TYPE_UW, EALIGN_GRF);
6681
+ getPixelPosition(uintPixelPosition, component);
6682
+
6683
+ CVariable* floatPixelPosition =
6684
+ m_currShader->GetNewVariable(numLanes(m_currShader->m_SIMDSize), ISA_TYPE_F, EALIGN_GRF);
6685
+ m_encoder->Cast(floatPixelPosition, uintPixelPosition);
6686
+ m_encoder->Push();
6687
+
6688
+ CVariable* floatPixelPositionDelta = floatPixelPosition; //reuse the same variable for the final delta
6689
+
6690
+ m_encoder->SetSrcRegion(1, 0, 1, 0);
6691
+ CVariable* startCoordinate = floatR1;
6692
+ uint topLeftVertexStartSubReg = (component == 0 ? 1 : 6); // R1.1 for XStart and R1.6 for YStart
6693
+ if (psProgram->m_Platform->hasStartCoordinatesDeliveredWithDeltas())
6694
+ {
6695
+ startCoordinate = delta;
6696
+ topLeftVertexStartSubReg = (component == 0 ? 2 : 6);
6697
+ }
6698
+
6699
+ m_encoder->SetSrcSubReg(1, topLeftVertexStartSubReg);
6700
+ m_encoder->SetSrcModifier(1, EMOD_NEG);
6701
+ m_encoder->Add(floatPixelPositionDelta, floatPixelPosition, startCoordinate);
6702
+ m_encoder->Push();
6703
+
6704
+ return floatPixelPositionDelta;
6705
+ };
6706
+ const uint componentX = 0;
6707
+ const uint componentY = 1;
6708
+ // (x - xstart)
6709
+ CVariable* floatPixelPositionDeltaX = getPixelPositionDelta(componentX);
6710
+ // (y - ystart)
6711
+ CVariable* floatPixelPositionDeltaY = getPixelPositionDelta(componentY);
6712
+
6713
+ // (y - ystart)*z_cy + z_c0
6714
+ {
6715
+ m_encoder->SetSrcRegion(1, 0, 1, 0);
6716
+ m_encoder->SetSrcRegion(2, 0, 1, 0);
6717
+ }
6718
+ m_encoder->SetSrcSubReg(1, usage == POSITION_Z ? 0 : 4);
6719
+ m_encoder->SetSrcSubReg(2, usage == POSITION_Z ? 3 : 7);
6720
+ m_encoder->Mad(floatPixelPositionDeltaY, floatPixelPositionDeltaY, delta, delta);
6673
6721
m_encoder->Push();
6722
+
6723
+ // (x - xstart)*z_cx + (y - ystart)*z_cy + z_c0
6724
+ {
6725
+ m_encoder->SetSrcRegion(1, 0, 1, 0);
6726
+ }
6727
+ m_encoder->SetSrcSubReg(1, usage == POSITION_Z ? 1 : 5);
6728
+ m_encoder->Mad(m_destination, floatPixelPositionDeltaX, delta, floatPixelPositionDeltaY);
6729
+ m_encoder->Push();
6730
+
6731
+ if (usage == POSITION_W)
6732
+ {
6733
+ // 1/w -> w
6734
+ m_encoder->Inv(m_destination, m_destination);
6735
+ m_encoder->Push();
6736
+ }
6674
6737
}
6675
6738
else
6676
6739
{
@@ -6897,20 +6960,27 @@ void EmitPass::emitHSSGV(llvm::GenIntrinsicInst* pInst)
6897
6960
}
6898
6961
}
6899
6962
6900
- void EmitPass::emitPixelPosition(llvm::GenIntrinsicInst* inst)
6963
+
6964
+ // Store integer pixel position in the destination variable.
6965
+ // Only X and Y components are handled here!
6966
+ void EmitPass::getPixelPosition(CVariable* destination, const uint component)
6901
6967
{
6968
+ assert(component < 2);
6969
+ assert(destination && m_encoder->IsIntegerType(destination->GetType()));
6970
+
6971
+ const bool getX = (component == 0);
6972
+
6902
6973
CPixelShader* psProgram = static_cast<CPixelShader*>(m_currShader);
6903
- GenISAIntrinsic::ID IID = inst->getIntrinsicID();
6904
6974
CVariable* imm = m_currShader->ImmToVariable(
6905
- IID == GenISAIntrinsic::GenISA_PixelPositionX ? 0x10101010 : 0x11001100, ISA_TYPE_V);
6975
+ getX ? 0x10101010 : 0x11001100, ISA_TYPE_V);
6906
6976
CVariable* pixelSize = nullptr;
6907
6977
if (psProgram->GetPhase() == PSPHASE_COARSE)
6908
6978
{
6909
6979
CVariable* CPSize = m_currShader->BitCast(psProgram->GetR1(), ISA_TYPE_UB);
6910
6980
pixelSize =
6911
6981
m_currShader->GetNewVariable(numLanes(m_currShader->m_SIMDSize), ISA_TYPE_UW, EALIGN_GRF);
6912
6982
m_encoder->SetSrcRegion(0, 0, 1, 0);
6913
- m_encoder->SetSrcSubReg(0, IID == GenISAIntrinsic::GenISA_PixelPositionX ? 0 : 1);
6983
+ m_encoder->SetSrcSubReg(0, getX ? 0 : 1);
6914
6984
m_encoder->Mul(pixelSize, CPSize, imm);
6915
6985
m_encoder->Push();
6916
6986
}
@@ -6921,11 +6991,19 @@ void EmitPass::emitPixelPosition(llvm::GenIntrinsicInst* inst)
6921
6991
CVariable* position = m_currShader->BitCast(psProgram->GetR1(), ISA_TYPE_UW);
6922
6992
m_encoder->SetSrcRegion(0, 2, 4, 0);
6923
6993
// subreg 4 as position_x and subreg 5 as position_y
6924
- m_encoder->SetSrcSubReg(0, IID == GenISAIntrinsic::GenISA_PixelPositionX ? 4 : 5);
6925
- m_encoder->Add(m_destination , position, pixelSize);
6994
+ m_encoder->SetSrcSubReg(0, getX ? 4 : 5);
6995
+ m_encoder->Add(destination , position, pixelSize);
6926
6996
m_encoder->Push();
6927
6997
}
6928
6998
6999
+
7000
+ void EmitPass::emitPixelPosition(llvm::GenIntrinsicInst* inst)
7001
+ {
7002
+ const GenISAIntrinsic::ID IID = inst->getIntrinsicID();
7003
+ const uint component = IID == GenISAIntrinsic::GenISA_PixelPositionX ? 0 : 1;
7004
+ getPixelPosition(m_destination, component);
7005
+ }
7006
+
6929
7007
void EmitPass::emitSGV(SGVIntrinsic* inst)
6930
7008
{
6931
7009
switch (m_currShader->GetShaderType())
0 commit comments