mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 21:44:17 +01:00
set viewport and scissor
This commit is contained in:
parent
be8a560496
commit
1fbd6ad376
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user