diff --git a/src/Cafe/HW/Latte/Core/LatteTexture.cpp b/src/Cafe/HW/Latte/Core/LatteTexture.cpp index d8852891..18e686ac 100644 --- a/src/Cafe/HW/Latte/Core/LatteTexture.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTexture.cpp @@ -170,7 +170,7 @@ void LatteTexture_UnregisterTextureMemoryOccupancy(LatteTexture* texture) } // calculate the actually accessed data range -// the resulting range is an estimate and may be smaller than the actual slice size (but not larger) +// the resulting range is an estimate and may be smaller than the actual slice size (but not larger) void LatteTexture_EstimateMipSliceAccessedDataRange(LatteTexture* texture, sint32 sliceIndex, sint32 mipIndex, LatteTextureSliceMipInfo* sliceMipInfo) { uint32 estAddrStart; @@ -222,7 +222,7 @@ void LatteTexture_InitSliceAndMipInfo(LatteTexture* texture) LatteAddrLib::AddrSurfaceInfo_OUT surfaceInfo; LatteAddrLib::GX2CalculateSurfaceInfo(texture->format, texture->width, texture->height, texture->depth, texture->dim, Latte::MakeGX2TileMode(texture->tileMode), 0, mipIndex, &surfaceInfo); sliceMipInfo->tileMode = surfaceInfo.hwTileMode; - + if (mipIndex == 0) sliceMipInfo->pitch = texture->pitch; // for the base level, use the pitch value configured in hardware else @@ -352,6 +352,7 @@ void LatteTexture_CopySlice(LatteTexture* srcTexture, sint32 srcSlice, sint32 sr if (srcTexture->isDepth != dstTexture->isDepth) { g_renderer->surfaceCopy_copySurfaceWithFormatConversion(srcTexture, srcMip, srcSlice, dstTexture, dstMip, dstSlice, width, height); + throw std::runtime_error("1"); return; } // rescale copy size @@ -384,6 +385,7 @@ void LatteTexture_CopySlice(LatteTexture* srcTexture, sint32 srcSlice, sint32 sr cemuLog_log(LogType::Force, "Source: {:08x} origResolution {:4}/{:4} effectiveResolution {:4}/{:4} fmt {:04x} mipIndex {} ratioW/H: {:.4}/{:.4}", srcTexture->physAddress, srcTexture->width, srcTexture->height, effectiveWidth_src, effectiveHeight_src, (uint32)srcTexture->format, srcMip, ratioWidth_src, ratioHeight_src); cemuLog_log(LogType::Force, "Destination: {:08x} origResolution {:4}/{:4} effectiveResolution {:4}/{:4} fmt {:04x} mipIndex {} ratioW/H: {:.4}/{:.4}", dstTexture->physAddress, dstTexture->width, dstTexture->height, effectiveWidth_dst, effectiveHeight_dst, (uint32)dstTexture->format, dstMip, ratioWidth_dst, ratioHeight_dst); } + throw std::runtime_error("2"); //cemuLog_logDebug(LogType::Force, "If these textures are not meant to share data you can ignore this"); return; } @@ -877,7 +879,7 @@ VIEWCOMPATIBILITY LatteTexture_CanTextureBeRepresentedAsView(LatteTexture* baseT // check pitch if(sliceMipInfo->pitch != pitch) continue; - // check all slices + // check all slices if(LatteAddrLib::TM_IsThickAndMacroTiled(baseTexture->tileMode)) continue; // todo - check only every 4th slice? for (sint32 s=0; sGetMipDepth(m); s++) @@ -978,7 +980,7 @@ LatteTextureView* LatteTexture_CreateMapping(MPTR physAddr, MPTR physMipAddr, si } // note: When creating an existing texture, we only allow mip and slice expansion at the end cemu_assert_debug(depth); - + cemu_assert_debug(!(depth > 1 && dimBase == Latte::E_DIM::DIM_2D)); cemu_assert_debug(!(numSlice > 1 && dimView == Latte::E_DIM::DIM_2D)); // todo, depth and numSlice are redundant diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp index b3380d31..92a5fb13 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp @@ -261,7 +261,7 @@ namespace LatteDecompiler // generate pixel outputs for pixel shader for (uint32 i = 0; i < LATTE_NUM_COLOR_TARGET; i++) { - if ((decompilerContext->shader->pixelColorOutputMask&(1 << i)) != 0) + if ((decompilerContext->shader->pixelColorOutputMask & (1 << i)) != 0) { src->addFmt("float4 passPixelColor{} [[color({})]];" _CRLF, i, i); } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp index a60539dc..f522439c 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp @@ -260,7 +260,8 @@ MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode mode) case LattePrimitiveMode::TRIANGLE_STRIP: return MTL::PrimitiveTypeTriangleStrip; default: - printf("unimplemented primitive type %u\n", (uint32)mode); + // TODO: uncomment + //printf("unimplemented primitive type %u\n", (uint32)mode); return MTL::PrimitiveTypeTriangle; } } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp index d6976a8d..049d738b 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp @@ -58,7 +58,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS uint32 bufferIndex = bufferGroup.attributeBufferIndex; uint32 bufferBaseRegisterIndex = mmSQ_VTX_ATTRIBUTE_BLOCK_START + bufferIndex * 7; - // TODO: is LatteGPUState.contextNew correct? uint32 bufferStride = (LatteGPUState.contextNew.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF; auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex)); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 2a3707b6..e8ce23f3 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -561,7 +561,6 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, depthRenderTarget); // Shaders - LatteSHRC_UpdateActiveShaders(); LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader(); LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader(); if (!vertexShader || !static_cast(vertexShader->shader)->GetFunction()) @@ -627,7 +626,16 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 void MetalRenderer::draw_endSequence() { - // TODO: do something? + LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader(); + // post-drawcall logic + if (pixelShader) + LatteRenderTarget_trackUpdates(); + bool hasReadback = LatteTextureReadback_Update(); + //m_recordedDrawcalls++; + //if (m_recordedDrawcalls >= m_submitThreshold || hasReadback) + //{ + // SubmitCommandBuffer(); + //} } void* MetalRenderer::indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex) @@ -1095,33 +1103,39 @@ void MetalRenderer::BindStageResources(MTL::RenderCommandEncoder* renderCommandE { if (shader->resourceMapping.uniformBuffersBindingPoint[i] >= 0) { - uint32 binding = shader->resourceMapping.uniformBuffersBindingPoint[i]; - if (binding >= MAX_MTL_BUFFERS) - { - debug_printf("too big buffer index (%u), skipping binding\n", binding); - continue; - } - size_t offset = m_state.uniformBufferOffsets[(uint32)shader->shaderType][binding]; - if (offset != INVALID_OFFSET) - { - switch (shader->shaderType) - { - case LatteConst::ShaderType::Vertex: - { + uint32 binding = shader->resourceMapping.uniformBuffersBindingPoint[i]; + if (binding >= MAX_MTL_BUFFERS) + { + debug_printf("too big buffer index (%u), skipping binding\n", binding); + continue; + } + size_t offset = m_state.uniformBufferOffsets[(uint32)shader->shaderType][i]; + if (offset != INVALID_OFFSET) + { + switch (shader->shaderType) + { + case LatteConst::ShaderType::Vertex: + { renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), offset, binding); break; - } - case LatteConst::ShaderType::Pixel: - { - renderCommandEncoder->setFragmentBuffer(m_memoryManager->GetBufferCache(), offset, binding); + } + case LatteConst::ShaderType::Pixel: + { + renderCommandEncoder->setFragmentBuffer(m_memoryManager->GetBufferCache(), offset, binding); break; - } - default: + } + default: UNREACHABLE; - } - } + } + } } } + + // Storage buffer + if (shader->resourceMapping.tfStorageBindingPoint >= 0) + { + debug_printf("storage buffer not implemented, index: %i\n", shader->resourceMapping.tfStorageBindingPoint); + } } void MetalRenderer::RebindRenderState(MTL::RenderCommandEncoder* renderCommandEncoder)