mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 21:44:17 +01:00
fix: viewport and scissor
This commit is contained in:
parent
1fbd6ad376
commit
d4564c18f2
@ -80,6 +80,11 @@ void MetalMemoryManager::InitBufferCache(size_t size)
|
||||
|
||||
void MetalMemoryManager::UploadToBufferCache(const void* data, size_t offset, size_t size)
|
||||
{
|
||||
if ((offset + size) > m_bufferCache->length())
|
||||
{
|
||||
throw std::runtime_error(std::to_string(offset) + " + " + std::to_string(size) + " > " + std::to_string(m_bufferCache->length()));
|
||||
}
|
||||
|
||||
if (!m_bufferCache)
|
||||
{
|
||||
printf("MetalMemoryManager::UploadToBufferCache: buffer cache not initialized\n");
|
||||
|
@ -29,6 +29,15 @@ MetalRenderer::MetalRenderer()
|
||||
m_nearestSampler = m_device->newSamplerState(samplerDescriptor);
|
||||
|
||||
m_memoryManager = new MetalMemoryManager(this);
|
||||
|
||||
// Initialize state
|
||||
for (uint32 i = 0; i < (uint32)LatteConst::ShaderType::TotalCount; i++)
|
||||
{
|
||||
for (uint32 j = 0; j < MAX_MTL_BUFFERS; j++)
|
||||
{
|
||||
m_state.uniformBufferOffsets[i][j] = INVALID_OFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MetalRenderer::~MetalRenderer()
|
||||
@ -149,7 +158,8 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
||||
|
||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||
colorRenderTargets[0] = m_drawable->texture();
|
||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr);
|
||||
// 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);
|
||||
|
||||
// Draw to Metal layer
|
||||
renderCommandEncoder->setRenderPipelineState(m_presentPipeline);
|
||||
@ -435,7 +445,7 @@ void MetalRenderer::buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, u
|
||||
|
||||
void MetalRenderer::buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size)
|
||||
{
|
||||
printf("MetalRenderer::buffer_bindUniformBuffer not implemented\n");
|
||||
m_state.uniformBufferOffsets[(uint32)shaderType][bufferIndex] = offset;
|
||||
}
|
||||
|
||||
RendererShader* MetalRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool isGameShader, bool isGfxPackShader)
|
||||
@ -872,22 +882,29 @@ void MetalRenderer::BindStageResources(MTL::RenderCommandEncoder* renderCommandE
|
||||
if (shader->resourceMapping.uniformBuffersBindingPoint[i] >= 0)
|
||||
{
|
||||
uint32 binding = shader->resourceMapping.uniformBuffersBindingPoint[i];
|
||||
// TODO: don't hardcode
|
||||
size_t offset = 0;
|
||||
switch (shader->shaderType)
|
||||
if (binding >= MAX_MTL_BUFFERS)
|
||||
{
|
||||
case LatteConst::ShaderType::Vertex:
|
||||
{
|
||||
renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), offset, binding);
|
||||
break;
|
||||
printf("too big buffer index (%u), skipping binding\n", binding);
|
||||
continue;
|
||||
}
|
||||
case LatteConst::ShaderType::Pixel:
|
||||
size_t offset = m_state.uniformBufferOffsets[(uint32)shader->shaderType][binding];
|
||||
if (offset != INVALID_OFFSET)
|
||||
{
|
||||
renderCommandEncoder->setFragmentBuffer(m_memoryManager->GetBufferCache(), offset, binding);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -896,10 +913,10 @@ 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);
|
||||
//if (m_state.viewport.width != 0.0)
|
||||
//{
|
||||
renderCommandEncoder->setViewport(m_state.viewport);
|
||||
/*
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -919,26 +936,27 @@ void MetalRenderer::RebindRenderState(MTL::RenderCommandEncoder* renderCommandEn
|
||||
{
|
||||
framebufferWidth = texture->baseTexture->width;
|
||||
framebufferHeight = texture->baseTexture->height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
//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)
|
||||
if (vertexBufferRange.offset != INVALID_OFFSET)
|
||||
{
|
||||
renderCommandEncoder->setVertexBuffer(m_memoryManager->GetBufferCache(), vertexBufferRange.offset, GET_MTL_VERTEX_BUFFER_INDEX(i));
|
||||
vertexBufferRange.needsRebind = false;
|
||||
|
@ -18,10 +18,12 @@
|
||||
|
||||
#define MAX_MTL_TEXTURES 31
|
||||
|
||||
constexpr size_t INVALID_OFFSET = std::numeric_limits<size_t>::max();
|
||||
|
||||
struct MetalBoundBuffer
|
||||
{
|
||||
bool needsRebind = false;
|
||||
sint32 offset = -1;
|
||||
size_t offset = INVALID_OFFSET;
|
||||
};
|
||||
|
||||
struct MetalState
|
||||
@ -30,6 +32,7 @@ struct MetalState
|
||||
class CachedFBOMtl* activeFBO = nullptr;
|
||||
MetalBoundBuffer vertexBuffers[MAX_MTL_BUFFERS] = {{}};
|
||||
class LatteTextureViewMtl* textures[MAX_MTL_TEXTURES] = {nullptr};
|
||||
size_t uniformBufferOffsets[(uint32)LatteConst::ShaderType::TotalCount][MAX_MTL_BUFFERS];
|
||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||
MTL::Texture* depthRenderTarget = nullptr;
|
||||
MTL::Viewport viewport = {0, 0, 0, 0, 0, 0};
|
||||
@ -210,7 +213,7 @@ private:
|
||||
MTL::CommandBuffer* m_commandBuffer = nullptr;
|
||||
MetalEncoderType m_encoderType = MetalEncoderType::None;
|
||||
MTL::CommandEncoder* m_commandEncoder = nullptr;
|
||||
CA::MetalDrawable* m_drawable;
|
||||
CA::MetalDrawable* m_drawable = nullptr;
|
||||
|
||||
// State
|
||||
MetalState m_state;
|
||||
@ -227,7 +230,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget)
|
||||
MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool rebindStateIfNewEncoder = true)
|
||||
{
|
||||
EnsureCommandBuffer();
|
||||
|
||||
@ -274,8 +277,11 @@ private:
|
||||
m_commandEncoder = renderCommandEncoder;
|
||||
m_encoderType = MetalEncoderType::Render;
|
||||
|
||||
// Rebind all the render state
|
||||
RebindRenderState(renderCommandEncoder);
|
||||
if (rebindStateIfNewEncoder)
|
||||
{
|
||||
// Rebind all the render state
|
||||
RebindRenderState(renderCommandEncoder);
|
||||
}
|
||||
|
||||
return renderCommandEncoder;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user