set viewport and scissor

This commit is contained in:
Samuliak 2024-07-31 20:50:24 +02:00
parent be8a560496
commit 1fbd6ad376
4 changed files with 91 additions and 12 deletions

View File

@ -186,7 +186,7 @@ MTL::VertexFormat GetMtlVertexFormat(uint8 format)
case FMT_2_10_10_10: case FMT_2_10_10_10:
return MTL::VertexFormatUInt; // verified to match OpenGL return MTL::VertexFormatUInt; // verified to match OpenGL
default: default:
printf("unsupported vertex format: %u\n", (uint32)format); printf("unsupported vertex format %u\n", (uint32)format);
assert_dbg(); assert_dbg();
return MTL::VertexFormatInvalid; return MTL::VertexFormatInvalid;
} }
@ -201,7 +201,7 @@ MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType)
case Renderer::INDEX_TYPE::U32: case Renderer::INDEX_TYPE::U32:
return MTL::IndexTypeUInt32; return MTL::IndexTypeUInt32;
default: default:
printf("unsupported index type: %u\n", (uint32)indexType); printf("unsupported index type %u\n", (uint32)indexType);
assert_dbg(); assert_dbg();
return MTL::IndexTypeUInt32; return MTL::IndexTypeUInt32;
} }

View File

@ -3,9 +3,11 @@
const size_t BUFFER_ALLOCATION_SIZE = 8 * 1024 * 1024; const size_t BUFFER_ALLOCATION_SIZE = 8 * 1024 * 1024;
// TODO: uncomment everything
MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size) MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size)
{ {
// First, try to find a free range // First, try to find a free range
/*
for (uint32 i = 0; i < m_freeBufferRanges.size(); i++) for (uint32 i = 0; i < m_freeBufferRanges.size(); i++)
{ {
auto& range = m_freeBufferRanges[i]; auto& range = m_freeBufferRanges[i];
@ -27,9 +29,10 @@ MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size)
return allocation; return allocation;
} }
} }
*/
// If no free range was found, allocate a new buffer // If no free range was found, allocate a new buffer
MTL::Buffer* buffer = m_mtlr->GetDevice()->newBuffer(std::max(size, BUFFER_ALLOCATION_SIZE), MTL::ResourceStorageModeShared); MTL::Buffer* buffer = m_mtlr->GetDevice()->newBuffer(/*std::max(*/size/*, BUFFER_ALLOCATION_SIZE)*/, MTL::ResourceStorageModeShared);
MetalBufferAllocation allocation; MetalBufferAllocation allocation;
allocation.bufferIndex = m_buffers.size(); allocation.bufferIndex = m_buffers.size();
@ -39,6 +42,7 @@ MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size)
m_buffers.push_back(buffer); m_buffers.push_back(buffer);
// If the buffer is larger than the requested size, add the remaining space to the free buffer ranges // If the buffer is larger than the requested size, add the remaining space to the free buffer ranges
/*
if (size < BUFFER_ALLOCATION_SIZE) if (size < BUFFER_ALLOCATION_SIZE)
{ {
MetalBufferRange range; MetalBufferRange range;
@ -48,6 +52,7 @@ MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size)
m_freeBufferRanges.push_back(range); m_freeBufferRanges.push_back(range);
} }
*/
return allocation; return allocation;
} }

View File

@ -11,6 +11,7 @@
#include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/FetchShader.h"
#include "Cafe/HW/Latte/Core/LatteShader.h" #include "Cafe/HW/Latte/Core/LatteShader.h"
#include "Cafe/HW/Latte/Core/LatteIndices.h" #include "Cafe/HW/Latte/Core/LatteIndices.h"
#include "Cemu/Logging/CemuDebugLogging.h"
#include "Foundation/NSTypes.hpp" #include "Foundation/NSTypes.hpp"
#include "Metal/MTLRenderCommandEncoder.hpp" #include "Metal/MTLRenderCommandEncoder.hpp"
#include "gui/guiWrapper.h" #include "gui/guiWrapper.h"
@ -171,7 +172,8 @@ void MetalRenderer::Flush(bool waitIdle)
void MetalRenderer::NotifyLatteCommandProcessorIdle() void MetalRenderer::NotifyLatteCommandProcessorIdle()
{ {
printf("MetalRenderer::NotifyLatteCommandProcessorIdle not implemented\n"); // TODO: should we?
CommitCommandBuffer();
} }
void MetalRenderer::AppendOverlayDebugInfo() void MetalRenderer::AppendOverlayDebugInfo()
@ -181,12 +183,20 @@ void MetalRenderer::AppendOverlayDebugInfo()
void MetalRenderer::renderTarget_setViewport(float x, float y, float width, float height, float nearZ, float farZ, bool halfZ) void MetalRenderer::renderTarget_setViewport(float x, float y, float width, float height, float nearZ, float farZ, bool halfZ)
{ {
printf("MetalRenderer::renderTarget_setViewport not implemented\n"); m_state.viewport = MTL::Viewport{x, y + height, width, -height, nearZ, farZ};
if (m_encoderType == MetalEncoderType::Render)
{
static_cast<MTL::RenderCommandEncoder*>(m_commandEncoder)->setViewport(m_state.viewport);
}
} }
void MetalRenderer::renderTarget_setScissor(sint32 scissorX, sint32 scissorY, sint32 scissorWidth, sint32 scissorHeight) void MetalRenderer::renderTarget_setScissor(sint32 scissorX, sint32 scissorY, sint32 scissorWidth, sint32 scissorHeight)
{ {
printf("MetalRenderer::renderTarget_setScissor not implemented\n"); m_state.scissor = MTL::ScissorRect{NS::UInteger(scissorX), NS::UInteger(scissorY), NS::UInteger(scissorWidth), NS::UInteger(scissorHeight)};
if (m_encoderType == MetalEncoderType::Render)
{
static_cast<MTL::RenderCommandEncoder*>(m_commandEncoder)->setScissorRect(m_state.scissor);
}
} }
LatteCachedFBO* MetalRenderer::rendertarget_createCachedFBO(uint64 key) LatteCachedFBO* MetalRenderer::rendertarget_createCachedFBO(uint64 key)
@ -456,7 +466,7 @@ void MetalRenderer::draw_beginSequence()
LatteSHRC_UpdateActiveShaders(); LatteSHRC_UpdateActiveShaders();
if (LatteGPUState.activeShaderHasError) if (LatteGPUState.activeShaderHasError)
{ {
debug_printf("Skipping drawcalls due to shader error\n"); printf("Skipping drawcalls due to shader error\n");
m_state.skipDrawSequence = true; m_state.skipDrawSequence = true;
cemu_assert_debug(false); cemu_assert_debug(false);
return; return;
@ -469,14 +479,14 @@ void MetalRenderer::draw_beginSequence()
LatteGPUState.repeatTextureInitialization = false; LatteGPUState.repeatTextureInitialization = false;
if (!LatteMRT::UpdateCurrentFBO()) if (!LatteMRT::UpdateCurrentFBO())
{ {
debug_printf("Rendertarget invalid\n"); printf("Rendertarget invalid\n");
m_state.skipDrawSequence = true; m_state.skipDrawSequence = true;
return; // no render target return; // no render target
} }
if (!hasValidFramebufferAttached) if (!hasValidFramebufferAttached)
{ {
debug_printf("Drawcall with no color buffer or depth buffer attached\n"); printf("Drawcall with no color buffer or depth buffer attached\n");
m_state.skipDrawSequence = true; m_state.skipDrawSequence = true;
return; // no render target return; // no render target
} }
@ -540,6 +550,11 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
LatteSHRC_UpdateActiveShaders(); LatteSHRC_UpdateActiveShaders();
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader(); LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader(); LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader();
if (!vertexShader)
{
printf("no vertex function, skipping draw\n");
return;
}
auto fetchShader = vertexShader->compatibleFetchShader; auto fetchShader = vertexShader->compatibleFetchShader;
@ -648,8 +663,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
if (vertexBufferRange.needsRebind) if (vertexBufferRange.needsRebind)
{ {
renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), vertexBufferRange.offset, GET_MTL_VERTEX_BUFFER_INDEX(i)); renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), vertexBufferRange.offset, GET_MTL_VERTEX_BUFFER_INDEX(i));
// TODO: uncomment vertexBufferRange.needsRebind = false;
//vertexBufferRange.needsRebind = false;
} }
} }
@ -671,7 +685,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
void MetalRenderer::draw_endSequence() void MetalRenderer::draw_endSequence()
{ {
printf("MetalRenderer::draw_endSequence not implemented\n"); // TODO: do something?
} }
void* MetalRenderer::indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex) void* MetalRenderer::indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex)
@ -878,3 +892,56 @@ void MetalRenderer::BindStageResources(MTL::RenderCommandEncoder* renderCommandE
} }
} }
} }
void MetalRenderer::RebindRenderState(MTL::RenderCommandEncoder* renderCommandEncoder)
{
// Viewport
if (m_state.viewport.width != 0.0)
{
printf("setting previous viewport X: %f Y: %f width: %f height %f\n", m_state.viewport.originX, m_state.viewport.originY, m_state.viewport.width, m_state.viewport.height);
renderCommandEncoder->setViewport(m_state.viewport);
}
else
{
// Find the framebuffer dimensions
uint32 framebufferWidth = 0, framebufferHeight = 0;
if (m_state.activeFBO->hasDepthBuffer())
{
framebufferHeight = m_state.activeFBO->depthBuffer.texture->baseTexture->width;
framebufferHeight = m_state.activeFBO->depthBuffer.texture->baseTexture->height;
}
else
{
for (uint8 i = 0; i < 8; i++)
{
auto texture = m_state.activeFBO->colorBuffer[i].texture;
if (texture)
{
framebufferWidth = texture->baseTexture->width;
framebufferHeight = texture->baseTexture->height;
}
}
}
MTL::Viewport viewport{0, (double)framebufferHeight, (double)framebufferWidth, -(double)framebufferHeight, 0.0, 1.0};
printf("setting default viewport X: %f Y: %f width: %f height %f\n", viewport.originX, viewport.originY, viewport.width, viewport.height);
renderCommandEncoder->setViewport(viewport);
}
// Scissor
if (m_state.scissor.width != 0)
{
renderCommandEncoder->setScissorRect(m_state.scissor);
}
// Vertex buffers
for (uint8 i = 0; i < MAX_MTL_BUFFERS; i++)
{
auto& vertexBufferRange = m_state.vertexBuffers[i];
if (vertexBufferRange.offset != -1)
{
renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), vertexBufferRange.offset, GET_MTL_VERTEX_BUFFER_INDEX(i));
vertexBufferRange.needsRebind = false;
}
}
}

View File

@ -32,6 +32,8 @@ struct MetalState
class LatteTextureViewMtl* textures[MAX_MTL_TEXTURES] = {nullptr}; class LatteTextureViewMtl* textures[MAX_MTL_TEXTURES] = {nullptr};
MTL::Texture* colorRenderTargets[8] = {nullptr}; MTL::Texture* colorRenderTargets[8] = {nullptr};
MTL::Texture* depthRenderTarget = nullptr; MTL::Texture* depthRenderTarget = nullptr;
MTL::Viewport viewport = {0, 0, 0, 0, 0, 0};
MTL::ScissorRect scissor = {0, 0, 0, 0};
}; };
enum class MetalEncoderType enum class MetalEncoderType
@ -272,6 +274,9 @@ private:
m_commandEncoder = renderCommandEncoder; m_commandEncoder = renderCommandEncoder;
m_encoderType = MetalEncoderType::Render; m_encoderType = MetalEncoderType::Render;
// Rebind all the render state
RebindRenderState(renderCommandEncoder);
return renderCommandEncoder; return renderCommandEncoder;
} }
@ -342,4 +347,6 @@ private:
} }
void BindStageResources(MTL::RenderCommandEncoder* renderCommandEncoder, LatteDecompilerShader* shader); void BindStageResources(MTL::RenderCommandEncoder* renderCommandEncoder, LatteDecompilerShader* shader);
void RebindRenderState(MTL::RenderCommandEncoder* renderCommandEncoder);
}; };