GPU/HW: Enable feedback loops for rendering

This commit is contained in:
Stenzek
2024-03-08 21:14:35 +10:00
parent 72ab669e70
commit 74f3c8d1aa
9 changed files with 322 additions and 218 deletions

View File

@ -249,7 +249,8 @@ public:
void PushUniformBuffer(const void* data, u32 data_size) override;
void* MapUniformBuffer(u32 size) override;
void UnmapUniformBuffer(u32 size) override;
void SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTexture* ds) override;
void SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTexture* ds,
GPUPipeline::RenderPassFlag feedback_loop) override;
void SetPipeline(GPUPipeline* pipeline) override;
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
@ -257,6 +258,7 @@ public:
void SetScissor(s32 x, s32 y, s32 width, s32 height) override;
void Draw(u32 vertex_count, u32 base_vertex) override;
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
bool GetHostRefreshRate(float* refresh_rate) override;

View File

@ -1721,8 +1721,10 @@ void MetalDevice::UnmapUniformBuffer(u32 size)
}
}
void MetalDevice::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTexture* ds)
void MetalDevice::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTexture* ds,
GPUPipeline::RenderPassFlag feedback_loop)
{
DebugAssert(!feedback_loop);
bool changed = (m_num_current_render_targets != num_rts || m_current_depth_target != ds);
bool needs_ds_clear = (ds && ds->IsClearedOrInvalidated());
bool needs_rt_clear = false;
@ -1843,7 +1845,7 @@ void MetalDevice::UnbindTexture(MetalTexture* tex)
if (m_current_render_targets[i] == tex)
{
Log_WarningPrint("Unbinding current RT");
SetRenderTargets(nullptr, 0, m_current_depth_target);
SetRenderTargets(nullptr, 0, m_current_depth_target, GPUPipeline::NoRenderPassFlags); // TODO: Wrong
break;
}
}
@ -1853,7 +1855,7 @@ void MetalDevice::UnbindTexture(MetalTexture* tex)
if (m_current_depth_target == tex)
{
Log_WarningPrint("Unbinding current DS");
SetRenderTargets(nullptr, 0, nullptr);
SetRenderTargets(nullptr, 0, nullptr, GPUPipeline::NoRenderPassFlags);
}
}
}
@ -2094,6 +2096,11 @@ void MetalDevice::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
baseInstance:0];
}
void MetalDevice::DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type)
{
Panic("Barriers are not supported");
}
id<MTLBlitCommandEncoder> MetalDevice::GetBlitEncoder(bool is_inline)
{
@autoreleasepool

View File

@ -1,12 +1,15 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "shadergen.h"
#include "common/assert.h"
#include "common/bitutils.h"
#include "common/log.h"
#include <cstdio>
#include <cstring>
#include <iomanip>
#ifdef ENABLE_OPENGL
#include "opengl_loader.h"
@ -660,20 +663,18 @@ void ShaderGen::DeclareFragmentEntryPoint(
}
}
std::string ShaderGen::GenerateScreenQuadVertexShader()
std::string ShaderGen::GenerateScreenQuadVertexShader(float z /* = 0.0f */)
{
std::stringstream ss;
WriteHeader(ss);
DeclareVertexEntryPoint(ss, {}, 0, 1, {}, true);
ss << R"(
{
v_tex0 = float2(float((v_id << 1) & 2u), float(v_id & 2u));
v_pos = float4(v_tex0 * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
#if API_OPENGL || API_OPENGL_ES || API_VULKAN
v_pos.y = -v_pos.y;
#endif
}
)";
ss << "{\n";
ss << " v_tex0 = float2(float((v_id << 1) & 2u), float(v_id & 2u));\n";
ss << " v_pos = float4(v_tex0 * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), " << std::fixed << z << "f, 1.0f);\n";
ss << " #if API_OPENGL || API_OPENGL_ES || API_VULKAN\n";
ss << " v_pos.y = -v_pos.y;\n";
ss << " #endif\n";
ss << "}\n";
return ss.str();
}

View File

@ -16,7 +16,7 @@ public:
static bool UseGLSLBindingLayout();
std::string GenerateScreenQuadVertexShader();
std::string GenerateScreenQuadVertexShader(float z = 0.0f);
std::string GenerateUVQuadVertexShader();
std::string GenerateFillFragmentShader();
std::string GenerateCopyFragmentShader();