fix: sample compare component count

This commit is contained in:
Samuliak 2025-01-18 19:40:22 +01:00
parent f0cf61461c
commit 86f364889a
No known key found for this signature in database

View file

@ -2295,6 +2295,10 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
} }
else else
{ {
// sample_compare returns a float, need to convert to float4
if (isCompare)
src->addFmt("float4(");
if (emulateCompare) if (emulateCompare)
{ {
cemu_assert_debug(!isGather); cemu_assert_debug(!isGather);
@ -2306,24 +2310,24 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
if (!emulateCompare) if (!emulateCompare)
{ {
src->add("."); src->add(".");
if (isRead) if (isRead)
{ {
if (hasOffset) if (hasOffset)
cemu_assert_unimplemented(); cemu_assert_unimplemented();
src->add("read("); src->add("read(");
unnormalizationHandled = true; unnormalizationHandled = true;
useTexelCoordinates = true; useTexelCoordinates = true;
} }
else else
{ {
if (isGather) if (isGather)
src->add("gather"); src->add("gather");
else else
src->add("sample"); src->add("sample");
if (isCompare) if (isCompare)
src->add("_compare"); src->add("_compare");
src->addFmt("(samplr{}, ", texInstruction->textureFetch.textureIndex); src->addFmt("(samplr{}, ", texInstruction->textureFetch.textureIndex);
} }
} }
else else
{ {
@ -2555,65 +2559,63 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
src->add(")"); src->add(")");
} }
// sample_compare doesn't return a float if (isCompare)
if (!isCompare) src->add(")");
{
if( texOpcode == GPU7_TEX_INST_SAMPLE_C || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
{
src->add(".");
if (numWrittenElements > 1) if (texOpcode == GPU7_TEX_INST_SAMPLE_C || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ)
{ {
// result is copied into multiple channels src->add(".");
for (sint32 f = 0; f < numWrittenElements; f++)
{ if (numWrittenElements > 1)
cemu_assert_debug(texInstruction->dstSel[f] == 0); // only x component is defined {
src->add("x"); // result is copied into multiple channels
} for (sint32 f = 0; f < numWrittenElements; f++)
} {
else cemu_assert_debug(texInstruction->dstSel[f] == 0); // only x component is defined
{ src->add("x");
src->add("x"); }
} }
} else
else {
{ src->add("x");
src->add("."); }
for (sint32 f = 0; f < 4; f++) }
{ else
if( texInstruction->dstSel[f] < 4 ) {
{ src->add(".");
uint8 elemIndex = texInstruction->dstSel[f]; for (sint32 f = 0; f < 4; f++)
if (isGather) {
if (texInstruction->dstSel[f] < 4)
{
uint8 elemIndex = texInstruction->dstSel[f];
if (isGather)
{
// 's textureGather() and GPU7's FETCH4 instruction have a different order of elements
// xyzw: top-left, top-right, bottom-right, bottom-left
// textureGather xyzw
// fetch4 yzxw
// translate index from fetch4 to textureGather order
static uint8 fetchToGather[4] =
{ {
// 's textureGather() and GPU7's FETCH4 instruction have a different order of elements 2, // x -> z
// xyzw: top-left, top-right, bottom-right, bottom-left 0, // y -> x
// textureGather xyzw 1, // z -> y
// fetch4 yzxw 3, // w -> w
// translate index from fetch4 to textureGather order };
static uint8 fetchToGather[4] = elemIndex = fetchToGather[elemIndex];
{ }
2, // x -> z src->add(resultElemTable[elemIndex]);
0, // y -> x }
1, // z -> y else if (texInstruction->dstSel[f] == 7)
3, // w -> w {
}; // masked and not written
elemIndex = fetchToGather[elemIndex]; }
} else
src->add(resultElemTable[elemIndex]); {
numWrittenElements++; cemu_assert_unimplemented();
} }
else if( texInstruction->dstSel[f] == 7 ) }
{ }
// masked and not written
}
else
{
cemu_assert_unimplemented();
}
}
}
}
src->add(");"); src->add(");");
// debug // debug