mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-01-08 08:00:44 +01:00
fix: texture updates and buffer bindings
This commit is contained in:
parent
f11526a244
commit
d64e64e5ef
@ -170,7 +170,7 @@ void LatteTexture_UnregisterTextureMemoryOccupancy(LatteTexture* texture)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculate the actually accessed data range
|
// 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)
|
void LatteTexture_EstimateMipSliceAccessedDataRange(LatteTexture* texture, sint32 sliceIndex, sint32 mipIndex, LatteTextureSliceMipInfo* sliceMipInfo)
|
||||||
{
|
{
|
||||||
uint32 estAddrStart;
|
uint32 estAddrStart;
|
||||||
@ -222,7 +222,7 @@ void LatteTexture_InitSliceAndMipInfo(LatteTexture* texture)
|
|||||||
LatteAddrLib::AddrSurfaceInfo_OUT surfaceInfo;
|
LatteAddrLib::AddrSurfaceInfo_OUT surfaceInfo;
|
||||||
LatteAddrLib::GX2CalculateSurfaceInfo(texture->format, texture->width, texture->height, texture->depth, texture->dim, Latte::MakeGX2TileMode(texture->tileMode), 0, mipIndex, &surfaceInfo);
|
LatteAddrLib::GX2CalculateSurfaceInfo(texture->format, texture->width, texture->height, texture->depth, texture->dim, Latte::MakeGX2TileMode(texture->tileMode), 0, mipIndex, &surfaceInfo);
|
||||||
sliceMipInfo->tileMode = surfaceInfo.hwTileMode;
|
sliceMipInfo->tileMode = surfaceInfo.hwTileMode;
|
||||||
|
|
||||||
if (mipIndex == 0)
|
if (mipIndex == 0)
|
||||||
sliceMipInfo->pitch = texture->pitch; // for the base level, use the pitch value configured in hardware
|
sliceMipInfo->pitch = texture->pitch; // for the base level, use the pitch value configured in hardware
|
||||||
else
|
else
|
||||||
@ -352,6 +352,7 @@ void LatteTexture_CopySlice(LatteTexture* srcTexture, sint32 srcSlice, sint32 sr
|
|||||||
if (srcTexture->isDepth != dstTexture->isDepth)
|
if (srcTexture->isDepth != dstTexture->isDepth)
|
||||||
{
|
{
|
||||||
g_renderer->surfaceCopy_copySurfaceWithFormatConversion(srcTexture, srcMip, srcSlice, dstTexture, dstMip, dstSlice, width, height);
|
g_renderer->surfaceCopy_copySurfaceWithFormatConversion(srcTexture, srcMip, srcSlice, dstTexture, dstMip, dstSlice, width, height);
|
||||||
|
throw std::runtime_error("1");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// rescale copy size
|
// 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, "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);
|
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");
|
//cemuLog_logDebug(LogType::Force, "If these textures are not meant to share data you can ignore this");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -877,7 +879,7 @@ VIEWCOMPATIBILITY LatteTexture_CanTextureBeRepresentedAsView(LatteTexture* baseT
|
|||||||
// check pitch
|
// check pitch
|
||||||
if(sliceMipInfo->pitch != pitch)
|
if(sliceMipInfo->pitch != pitch)
|
||||||
continue;
|
continue;
|
||||||
// check all slices
|
// check all slices
|
||||||
if(LatteAddrLib::TM_IsThickAndMacroTiled(baseTexture->tileMode))
|
if(LatteAddrLib::TM_IsThickAndMacroTiled(baseTexture->tileMode))
|
||||||
continue; // todo - check only every 4th slice?
|
continue; // todo - check only every 4th slice?
|
||||||
for (sint32 s=0; s<baseTexture->GetMipDepth(m); s++)
|
for (sint32 s=0; s<baseTexture->GetMipDepth(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
|
// note: When creating an existing texture, we only allow mip and slice expansion at the end
|
||||||
cemu_assert_debug(depth);
|
cemu_assert_debug(depth);
|
||||||
|
|
||||||
cemu_assert_debug(!(depth > 1 && dimBase == Latte::E_DIM::DIM_2D));
|
cemu_assert_debug(!(depth > 1 && dimBase == Latte::E_DIM::DIM_2D));
|
||||||
cemu_assert_debug(!(numSlice > 1 && dimView == Latte::E_DIM::DIM_2D));
|
cemu_assert_debug(!(numSlice > 1 && dimView == Latte::E_DIM::DIM_2D));
|
||||||
// todo, depth and numSlice are redundant
|
// todo, depth and numSlice are redundant
|
||||||
|
@ -261,7 +261,7 @@ namespace LatteDecompiler
|
|||||||
// generate pixel outputs for pixel shader
|
// generate pixel outputs for pixel shader
|
||||||
for (uint32 i = 0; i < LATTE_NUM_COLOR_TARGET; i++)
|
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);
|
src->addFmt("float4 passPixelColor{} [[color({})]];" _CRLF, i, i);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,8 @@ MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode mode)
|
|||||||
case LattePrimitiveMode::TRIANGLE_STRIP:
|
case LattePrimitiveMode::TRIANGLE_STRIP:
|
||||||
return MTL::PrimitiveTypeTriangleStrip;
|
return MTL::PrimitiveTypeTriangleStrip;
|
||||||
default:
|
default:
|
||||||
printf("unimplemented primitive type %u\n", (uint32)mode);
|
// TODO: uncomment
|
||||||
|
//printf("unimplemented primitive type %u\n", (uint32)mode);
|
||||||
return MTL::PrimitiveTypeTriangle;
|
return MTL::PrimitiveTypeTriangle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS
|
|||||||
|
|
||||||
uint32 bufferIndex = bufferGroup.attributeBufferIndex;
|
uint32 bufferIndex = bufferGroup.attributeBufferIndex;
|
||||||
uint32 bufferBaseRegisterIndex = mmSQ_VTX_ATTRIBUTE_BLOCK_START + bufferIndex * 7;
|
uint32 bufferBaseRegisterIndex = mmSQ_VTX_ATTRIBUTE_BLOCK_START + bufferIndex * 7;
|
||||||
// TODO: is LatteGPUState.contextNew correct?
|
|
||||||
uint32 bufferStride = (LatteGPUState.contextNew.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF;
|
uint32 bufferStride = (LatteGPUState.contextNew.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF;
|
||||||
|
|
||||||
auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex));
|
auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex));
|
||||||
|
@ -561,7 +561,6 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, depthRenderTarget);
|
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, depthRenderTarget);
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
LatteSHRC_UpdateActiveShaders();
|
|
||||||
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
|
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
|
||||||
LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader();
|
LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader();
|
||||||
if (!vertexShader || !static_cast<RendererShaderMtl*>(vertexShader->shader)->GetFunction())
|
if (!vertexShader || !static_cast<RendererShaderMtl*>(vertexShader->shader)->GetFunction())
|
||||||
@ -627,7 +626,16 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
|
|
||||||
void MetalRenderer::draw_endSequence()
|
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)
|
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)
|
if (shader->resourceMapping.uniformBuffersBindingPoint[i] >= 0)
|
||||||
{
|
{
|
||||||
uint32 binding = shader->resourceMapping.uniformBuffersBindingPoint[i];
|
uint32 binding = shader->resourceMapping.uniformBuffersBindingPoint[i];
|
||||||
if (binding >= MAX_MTL_BUFFERS)
|
if (binding >= MAX_MTL_BUFFERS)
|
||||||
{
|
{
|
||||||
debug_printf("too big buffer index (%u), skipping binding\n", binding);
|
debug_printf("too big buffer index (%u), skipping binding\n", binding);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
size_t offset = m_state.uniformBufferOffsets[(uint32)shader->shaderType][binding];
|
size_t offset = m_state.uniformBufferOffsets[(uint32)shader->shaderType][i];
|
||||||
if (offset != INVALID_OFFSET)
|
if (offset != INVALID_OFFSET)
|
||||||
{
|
{
|
||||||
switch (shader->shaderType)
|
switch (shader->shaderType)
|
||||||
{
|
{
|
||||||
case LatteConst::ShaderType::Vertex:
|
case LatteConst::ShaderType::Vertex:
|
||||||
{
|
{
|
||||||
renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), offset, binding);
|
renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), offset, binding);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LatteConst::ShaderType::Pixel:
|
case LatteConst::ShaderType::Pixel:
|
||||||
{
|
{
|
||||||
renderCommandEncoder->setFragmentBuffer(m_memoryManager->GetBufferCache(), offset, binding);
|
renderCommandEncoder->setFragmentBuffer(m_memoryManager->GetBufferCache(), offset, binding);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
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)
|
void MetalRenderer::RebindRenderState(MTL::RenderCommandEncoder* renderCommandEncoder)
|
||||||
|
Loading…
Reference in New Issue
Block a user