diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp index ae6ca8f3..0e55ffa1 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp @@ -802,7 +802,7 @@ static void _emitOperandInputCode(LatteDecompilerShaderContext* shaderContext, L if( currentRegisterElementType == LATTE_DECOMPILER_DTYPE_SIGNED_INT ) { // need to convert (not cast) from int bits to float - src->add("as_type("); + src->add("bitCast("); } else if( currentRegisterElementType == LATTE_DECOMPILER_DTYPE_FLOAT ) { @@ -872,7 +872,7 @@ static void _emitOperandInputCode(LatteDecompilerShaderContext* shaderContext, L src->add(_FormatFloatAsConstant(*(float*)&constVal)); } else - src->addFmt("as_type(0x{:08x})", constVal); + src->addFmt("bitCast(0x{:08x})", constVal); } } else if( GPU7_ALU_SRC_IS_CFILE(aluInstruction->sourceOperand[operandIndex].sel) ) @@ -919,11 +919,11 @@ void _emitTypeConversionPrefixMSL(LatteDecompilerShaderContext* shaderContext, s return; StringBuf* src = shaderContext->shaderSource; if (sourceType == LATTE_DECOMPILER_DTYPE_FLOAT && destinationType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->add("as_type("); + src->add("bitCast("); else if (sourceType == LATTE_DECOMPILER_DTYPE_FLOAT && destinationType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT) - src->add("as_type("); + src->add("bitCast("); else if( sourceType == LATTE_DECOMPILER_DTYPE_SIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_FLOAT ) - src->add("as_type("); + src->add("bitCast("); else if( sourceType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_SIGNED_INT ) src->add("int("); else if( sourceType == LATTE_DECOMPILER_DTYPE_SIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT ) @@ -1026,7 +1026,7 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte src->add(" = "); if( outputType != LATTE_DECOMPILER_DTYPE_SIGNED_INT ) debugBreakpoint(); // todo - src->add("as_type(tempResultf)"); + src->add("bitCast(tempResultf)"); src->add(";" _CRLF); } else if( aluInstruction->opcode == ALU_OP2_INST_MOVA_INT ) @@ -1123,9 +1123,9 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte _emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT); src->add(");" _CRLF); // INF becomes 0.0 - src->add("if( isinf(tempResultf) == true && (as_type(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF); + src->add("if( isinf(tempResultf) == true && (bitCast(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF); // -INF becomes -0.0 - src->add("else if( isinf(tempResultf) == true && (as_type(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF); + src->add("else if( isinf(tempResultf) == true && (bitCast(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF); // assign result to output _emitInstructionOutputVariableName(shaderContext, aluInstruction); src->add(" = "); @@ -1145,14 +1145,14 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_CLAMPED) { // note: if( -INF < 0.0 ) does not resolve to true - src->add("if( isinf(tempResultf) == true && (as_type(tempResultf)&0x80000000) != 0 ) tempResultf = -3.40282347E+38F;" _CRLF); - src->add("else if( isinf(tempResultf) == true && (as_type(tempResultf)&0x80000000) == 0 ) tempResultf = 3.40282347E+38F;" _CRLF); + src->add("if( isinf(tempResultf) == true && (bitCast(tempResultf)&0x80000000) != 0 ) tempResultf = -3.40282347E+38F;" _CRLF); + src->add("else if( isinf(tempResultf) == true && (bitCast(tempResultf)&0x80000000) == 0 ) tempResultf = 3.40282347E+38F;" _CRLF); } else if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_FF) { // untested (BotW bombs) - src->add("if( isinf(tempResultf) == true && (as_type(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF); - src->add("else if( isinf(tempResultf) == true && (as_type(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF); + src->add("if( isinf(tempResultf) == true && (bitCast(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF); + src->add("else if( isinf(tempResultf) == true && (bitCast(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF); } // assign result to output _emitInstructionOutputVariableName(shaderContext, aluInstruction); @@ -2002,7 +2002,7 @@ static void _emitALUClauseCode(LatteDecompilerShaderContext* shaderContext, Latt { _emitInstructionOutputVariableName(shaderContext, &aluInstruction); src->add(" = "); - src->add("as_type(as_type("); + src->add("bitCast(bitCast("); _emitInstructionOutputVariableName(shaderContext, &aluInstruction); src->add(")"); if( aluInstruction.omod == 1 ) @@ -2099,9 +2099,9 @@ static void _emitTEXSampleCoordInputComponent(LatteDecompilerShaderContext* shad if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_SIGNED_INT ) { if( elementSel == 4 ) - src->add("as_type(0.0)"); + src->add("bitCast(0.0)"); else if( elementSel == 5 ) - src->add("as_type(1.0)"); + src->add("bitCast(1.0)"); } else if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_FLOAT ) { @@ -2116,7 +2116,7 @@ static const char* _texGprAccessElemTable[8] = {"x","y","z","w","_","_","_","_"} static char* _getTexGPRAccess(LatteDecompilerShaderContext* shaderContext, sint32 gprIndex, uint32 dataType, sint8 selX, sint8 selY, sint8 selZ, sint8 selW, char* tempBuffer) { - // as_type(R{}i.w) + // bitCast(R{}i.w) *tempBuffer = '\0'; uint8 elemCount = (selX > 0 ? 1 : 0) + (selY > 0 ? 1 : 0) + (selZ > 0 ? 1 : 0) + (selW > 0 ? 1 : 0); if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) @@ -2124,7 +2124,7 @@ static char* _getTexGPRAccess(LatteDecompilerShaderContext* shaderContext, sint3 if (dataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) ; // no conversion else if (dataType == LATTE_DECOMPILER_DTYPE_FLOAT) - strcat(tempBuffer, "as_type("); + strcat(tempBuffer, "bitCast("); else cemu_assert_unimplemented(); strcat(tempBuffer, _getRegisterVarName(shaderContext, gprIndex)); @@ -2233,13 +2233,13 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex shaderContext->shaderSource->addFmt(" = int{}(", numWrittenElements); } else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) - src->add(" = as_type("); + src->add(" = bitCast("); } else { // float samplers if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->add(" = as_type("); + src->add(" = bitCast("); else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->add(" = ("); } @@ -2665,14 +2665,14 @@ static void _emitTEXGetCompTexLodCode(LatteDecompilerShaderContext* shaderContex if(shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt("float4(textureQueryLod(tex{}, {}.{}{}{}),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]); else - src->addFmt("float4(textureQueryLod(tex{}, as_type({}.{}{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]); + src->addFmt("float4(textureQueryLod(tex{}, bitCast({}.{}{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]); } else { if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt("float4(textureQueryLod(tex{}, {}.{}{}),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]); else - src->addFmt("float4(textureQueryLod(tex{}, as_type({}.{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]); + src->addFmt("float4(textureQueryLod(tex{}, bitCast({}.{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]); debugBreakpoint(); } @@ -2706,7 +2706,7 @@ static void _emitTEXSetCubemapIndexCode(LatteDecompilerShaderContext* shaderCont const char* resultElemTable[4] = {"x","y","z","w"}; if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->addFmt(" = as_type(R{}i.{});" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]); + src->addFmt(" = bitCast(R{}i.{});" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]); else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt(" = R{}f.{};" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]); else @@ -2880,7 +2880,7 @@ static void _emitTEXVFetchCode(LatteDecompilerShaderContext* shaderContext, Latt src->add(" = "); if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->add("as_type("); + src->add("bitCast("); else src->add("("); @@ -2889,7 +2889,7 @@ static void _emitTEXVFetchCode(LatteDecompilerShaderContext* shaderContext, Latt if( shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT ) src->addFmt("{}.{}", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]); else - src->addFmt("as_type({}.{})", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]); + src->addFmt("bitCast({}.{})", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]); src->add("]."); @@ -2921,7 +2921,7 @@ static void _emitTEXReadMemCode(LatteDecompilerShaderContext* shaderContext, Lat src->add(" = "); if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->add("as_type("); + src->add("bitCast("); else src->add("("); @@ -3735,6 +3735,22 @@ void LatteDecompiler_emitHelperFunctions(LatteDecompilerShaderContext* shaderCon "return float2(as_type(ushort(as_type(x) & 0x00FF)), as_type(ushort((as_type(x) & 0xFF00) >> 16)));\r\n" "}\r\n"); + // Bit cast + + // Scalar + fCStr_shaderSource->add("" + "template\r\n" + "ResultT bitCast(T x) {\r\n" + "return as_type(x);\r\n" + "}\r\n"); + + // Vector + fCStr_shaderSource->add("" + "template\r\n" + "vec bitCast(vec x) {\r\n" + "return as_type>(x);\r\n" + "}\r\n"); + // mul non-ieee way (0*NaN/INF => 0.0) if (shaderContext->options->strictMul) { @@ -3742,7 +3758,7 @@ void LatteDecompiler_emitHelperFunctions(LatteDecompilerShaderContext* shaderCon //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(a*b,0.0,a==0.0||b==0.0); }" STR_LINEBREAK); //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(vec2(a*b,0.0),vec2(0.0,0.0),(equal(vec2(a),vec2(0.0,0.0))||equal(vec2(b),vec2(0.0,0.0)))).x; }" STR_LINEBREAK); //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" STR_LINEBREAK); - //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){float r = a*b;r = as_type(floatBitsToInt(r)&(((floatBitsToInt(a) != 0) && (floatBitsToInt(b) != 0))?0xFFFFFFFF:0));return r;}" STR_LINEBREAK); works + //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){float r = a*b;r = bitCast(floatBitsToInt(r)&(((floatBitsToInt(a) != 0) && (floatBitsToInt(b) != 0))?0xFFFFFFFF:0));return r;}" STR_LINEBREAK); works // for "min" it used to be: float mul_nonIEEE(float a, float b){ return min(a*b,min(abs(a)*3.40282347E+38F,abs(b)*3.40282347E+38F)); } @@ -3978,7 +3994,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) src->addFmt("{} = int4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0)); else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) - src->addFmt("{} = float4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0)); // TODO: as_type(float4(vid, 0, 0, iid))? + src->addFmt("{} = float4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0)); // TODO: bitCast(float4(vid, 0, 0, iid))? else cemu_assert_unimplemented(); } @@ -4021,7 +4037,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt("{} = in.position.xyxy;" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex)); else - src->addFmt("{} = as_type(gl_PointCoord.xyxy);" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex)); + src->addFmt("{} = bitCast(gl_PointCoord.xyxy);" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex)); } for (sint32 i = 0; i < psInputTable->count; i++) @@ -4038,7 +4054,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt("{} = GET_FRAGCOORD();" _CRLF, _getRegisterVarName(shaderContext, gprIndex)); else - src->addFmt("{} = as_type(GET_FRAGCOORD());" _CRLF, _getRegisterVarName(shaderContext, gprIndex)); + src->addFmt("{} = bitCast(GET_FRAGCOORD());" _CRLF, _getRegisterVarName(shaderContext, gprIndex)); continue; } @@ -4056,7 +4072,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, { // import from vertex shader if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->addFmt("{} = as_type(in.passParameterSem{});" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId); + src->addFmt("{} = bitCast(in.passParameterSem{});" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId); else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt("{} = in.passParameterSem{};" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId); else @@ -4071,7 +4087,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, if (frontFace_allBits) cemu_assert_debug(false); if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT) - src->addFmt("{}.{} = as_type(frontFacing?1.0:0.0);" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan)); + src->addFmt("{}.{} = bitCast(frontFacing?1.0:0.0);" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan)); else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT) src->addFmt("{}.{} = frontFacing ? 1.0 : 0.0;" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan)); else diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLAttrDecoder.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLAttrDecoder.cpp index cb90e45d..a9993964 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLAttrDecoder.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLAttrDecoder.cpp @@ -255,7 +255,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext { // seen in Giana Sisters: Twisted Dreams _readLittleEndianAttributeU16x4(shaderContext, src, attributeInputIndex); - src->add("attrDecoder.xyzw = as_type(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF); + // TODO: uint4? + src->add("attrDecoder.xyzw = as_type(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF); } else if (attrib->format == FMT_16_16 && attrib->nfa == 0 && attrib->isSigned != 0) { @@ -305,7 +306,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 2 && attrib->isSigned == 0 ) { // seen in One Piece - src->addFmt("attrDecoder.xyzw = as_type(float4(in.attrDataSem{}.xyzw));" _CRLF, attributeInputIndex); + // TODO: uint4? + src->addFmt("attrDecoder.xyzw = as_type(float4(in.attrDataSem{}.xyzw));" _CRLF, attributeInputIndex); } else if (attrib->format == FMT_8_8 && attrib->nfa == 0 && attrib->isSigned == 0) { @@ -391,7 +393,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext if( attrib->format == FMT_16_16_16_16_FLOAT && attrib->nfa == 2 ) { _readBigEndianAttributeU16x4(shaderContext, src, attributeInputIndex); - src->add("attrDecoder.xyzw = as_type(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF); + // TODO: uint4? + src->add("attrDecoder.xyzw = as_type(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF); } else if (attrib->format == FMT_16_16_16_16 && attrib->nfa == 0 && attrib->isSigned != 0) { diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index aeedcd82..de8282fe 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -161,7 +161,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput MTL::Texture* colorRenderTargets[8] = {nullptr}; colorRenderTargets[0] = m_drawable->texture(); // If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen - auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false); + auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false, false); // Draw to Metal layer renderCommandEncoder->setRenderPipelineState(m_presentPipeline); @@ -393,7 +393,7 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl MTL::Texture* colorRenderTargets[8] = {nullptr}; colorRenderTargets[0] = mtlTexture; - GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr); + GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true); } // TODO: use sliceIndex and mipIndex @@ -420,7 +420,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl } MTL::Texture* colorRenderTargets[8] = {nullptr}; - GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture); + GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture, true); } LatteTexture* MetalRenderer::texture_createTextureEx(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index 5e6d6995..8ac87118 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -232,36 +232,40 @@ private: } } - MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool rebindStateIfNewEncoder = true) + // Some render passes clear the attachments, forceRecreate is supposed to be used in those cases + MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool forceRecreate = false, bool rebindStateIfNewEncoder = true) { EnsureCommandBuffer(); // Check if we need to begin a new render pass if (m_commandEncoder) { - if (m_encoderType == MetalEncoderType::Render) + if (!forceRecreate) { - bool needsNewRenderPass = false; - for (uint8 i = 0; i < 8; i++) + if (m_encoderType == MetalEncoderType::Render) { - if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.colorRenderTargets[i])) + bool needsNewRenderPass = false; + for (uint8 i = 0; i < 8; i++) { - needsNewRenderPass = true; - break; + if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.colorRenderTargets[i])) + { + needsNewRenderPass = true; + break; + } } - } - if (!needsNewRenderPass) - { - if (depthRenderTarget && (depthRenderTarget != m_state.depthRenderTarget)) + if (!needsNewRenderPass) { - needsNewRenderPass = true; + if (depthRenderTarget && (depthRenderTarget != m_state.depthRenderTarget)) + { + needsNewRenderPass = true; + } } - } - if (!needsNewRenderPass) - { - return (MTL::RenderCommandEncoder*)m_commandEncoder; + if (!needsNewRenderPass) + { + return (MTL::RenderCommandEncoder*)m_commandEncoder; + } } }