mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-06 03:25:36 +00:00
PostProcessing/FX: Allow use of fixed-size render targets
Also obey the ClearRenderTarget flag.
This commit is contained in:
parent
4e7fdc8dbd
commit
80cfe59dbe
@ -1104,17 +1104,25 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
|
|||||||
for (const reshadefx::texture& ti : mod.textures)
|
for (const reshadefx::texture& ti : mod.textures)
|
||||||
{
|
{
|
||||||
Texture tex;
|
Texture tex;
|
||||||
|
tex.storage_access = false;
|
||||||
|
tex.render_target = false;
|
||||||
|
tex.render_target_width = 0;
|
||||||
|
tex.render_target_height = 0;
|
||||||
|
|
||||||
if (!ti.semantic.empty())
|
if (!ti.semantic.empty())
|
||||||
{
|
{
|
||||||
DEV_LOG("Ignoring semantic {} texture {}", ti.semantic, ti.unique_name);
|
DEV_LOG("Ignoring semantic {} texture {}", ti.semantic, ti.unique_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ti.render_target)
|
if (ti.render_target || ti.storage_access)
|
||||||
{
|
{
|
||||||
tex.rt_scale = 1.0f;
|
|
||||||
tex.format = MapTextureFormat(ti.format);
|
tex.format = MapTextureFormat(ti.format);
|
||||||
DEV_LOG("Creating render target '{}' {}", ti.unique_name, GPUTexture::GetFormatName(tex.format));
|
tex.render_target = true;
|
||||||
|
tex.storage_access = ti.storage_access;
|
||||||
|
tex.render_target_width = ti.width;
|
||||||
|
tex.render_target_height = ti.height;
|
||||||
|
DEV_LOG("Creating {}x{} render target{} '{}' {}", ti.width, ti.height,
|
||||||
|
ti.storage_access ? " with storage access" : "", ti.unique_name, GPUTexture::GetFormatName(tex.format));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1140,7 +1148,6 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tex.rt_scale = 0.0f;
|
|
||||||
tex.texture = g_gpu_device->FetchTexture(image.GetWidth(), image.GetHeight(), 1, 1, 1, GPUTexture::Type::Texture,
|
tex.texture = g_gpu_device->FetchTexture(image.GetWidth(), image.GetHeight(), 1, 1, 1, GPUTexture::Type::Texture,
|
||||||
GPUTexture::Format::RGBA8, GPUTexture::Flags::None, image.GetPixels(),
|
GPUTexture::Format::RGBA8, GPUTexture::Flags::None, image.GetPixels(),
|
||||||
image.GetPitch(), error);
|
image.GetPitch(), error);
|
||||||
@ -1162,6 +1169,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
|
|||||||
|
|
||||||
Pass pass;
|
Pass pass;
|
||||||
pass.num_vertices = pi.num_vertices;
|
pass.num_vertices = pi.num_vertices;
|
||||||
|
pass.clear_render_targets = pi.clear_render_targets;
|
||||||
|
|
||||||
if (is_final)
|
if (is_final)
|
||||||
{
|
{
|
||||||
@ -1195,8 +1203,11 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Texture new_rt;
|
Texture new_rt;
|
||||||
new_rt.rt_scale = 1.0f;
|
|
||||||
new_rt.format = backbuffer_format;
|
new_rt.format = backbuffer_format;
|
||||||
|
new_rt.render_target = true;
|
||||||
|
new_rt.storage_access = false;
|
||||||
|
new_rt.render_target_width = 0;
|
||||||
|
new_rt.render_target_height = 0;
|
||||||
pass.render_targets.push_back(static_cast<TextureID>(m_textures.size()));
|
pass.render_targets.push_back(static_cast<TextureID>(m_textures.size()));
|
||||||
m_textures.push_back(std::move(new_rt));
|
m_textures.push_back(std::move(new_rt));
|
||||||
}
|
}
|
||||||
@ -1450,15 +1461,16 @@ bool PostProcessing::ReShadeFXShader::ResizeOutput(GPUTexture::Format format, u3
|
|||||||
|
|
||||||
for (Texture& tex : m_textures)
|
for (Texture& tex : m_textures)
|
||||||
{
|
{
|
||||||
if (tex.rt_scale == 0.0f)
|
if (!tex.render_target)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
g_gpu_device->RecycleTexture(std::move(tex.texture));
|
g_gpu_device->RecycleTexture(std::move(tex.texture));
|
||||||
|
|
||||||
const u32 t_width = std::max(static_cast<u32>(static_cast<float>(width) * tex.rt_scale), 1u);
|
const u32 t_width = (tex.render_target_width > 0) ? tex.render_target_width : width;
|
||||||
const u32 t_height = std::max(static_cast<u32>(static_cast<float>(height) * tex.rt_scale), 1u);
|
const u32 t_height = (tex.render_target_height > 0) ? tex.render_target_height : height;
|
||||||
tex.texture = g_gpu_device->FetchTexture(t_width, t_height, 1, 1, 1, GPUTexture::Type::RenderTarget, tex.format,
|
tex.texture = g_gpu_device->FetchTexture(
|
||||||
GPUTexture::Flags::None, nullptr, 0, error);
|
t_width, t_height, 1, 1, 1, GPUTexture::Type::RenderTarget, tex.format,
|
||||||
|
tex.storage_access ? GPUTexture::Flags::AllowBindAsImage : GPUTexture::Flags::None, nullptr, 0, error);
|
||||||
if (!tex.texture)
|
if (!tex.texture)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -1477,9 +1489,6 @@ GPUDevice::PresentResult PostProcessing::ReShadeFXShader::Apply(GPUTexture* inpu
|
|||||||
|
|
||||||
m_frame_count++;
|
m_frame_count++;
|
||||||
|
|
||||||
// Reshade always draws at full size.
|
|
||||||
g_gpu_device->SetViewportAndScissor(GSVector4i(0, 0, target_width, target_height));
|
|
||||||
|
|
||||||
// Reshade timer variable is in milliseconds.
|
// Reshade timer variable is in milliseconds.
|
||||||
time *= 1000.0f;
|
time *= 1000.0f;
|
||||||
|
|
||||||
@ -1763,9 +1772,12 @@ GPUDevice::PresentResult PostProcessing::ReShadeFXShader::Apply(GPUTexture* inpu
|
|||||||
if (pass.render_targets.size() == 1 && pass.render_targets[0] == OUTPUT_COLOR_TEXTURE && !final_target)
|
if (pass.render_targets.size() == 1 && pass.render_targets[0] == OUTPUT_COLOR_TEXTURE && !final_target)
|
||||||
{
|
{
|
||||||
// Special case: drawing to final buffer.
|
// Special case: drawing to final buffer.
|
||||||
const GPUDevice::PresentResult pres = g_gpu_device->BeginPresent(g_gpu_device->GetMainSwapChain());
|
GPUSwapChain* swap_chain = g_gpu_device->GetMainSwapChain();
|
||||||
|
const GPUDevice::PresentResult pres = g_gpu_device->BeginPresent(swap_chain);
|
||||||
if (pres != GPUDevice::PresentResult::OK)
|
if (pres != GPUDevice::PresentResult::OK)
|
||||||
return pres;
|
return pres;
|
||||||
|
|
||||||
|
g_gpu_device->SetViewportAndScissor(GSVector4i::loadh(swap_chain->GetSizeVec()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1776,9 +1788,14 @@ GPUDevice::PresentResult PostProcessing::ReShadeFXShader::Apply(GPUTexture* inpu
|
|||||||
GetTextureNameForID(pass.render_targets[i]));
|
GetTextureNameForID(pass.render_targets[i]));
|
||||||
render_targets[i] = GetTextureByID(pass.render_targets[i], input_color, input_depth, final_target);
|
render_targets[i] = GetTextureByID(pass.render_targets[i], input_color, input_depth, final_target);
|
||||||
DebugAssert(render_targets[i]);
|
DebugAssert(render_targets[i]);
|
||||||
|
|
||||||
|
if (pass.clear_render_targets)
|
||||||
|
g_gpu_device->ClearRenderTarget(render_targets[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_gpu_device->SetRenderTargets(render_targets.data(), static_cast<u32>(pass.render_targets.size()), nullptr);
|
g_gpu_device->SetRenderTargets(render_targets.data(), static_cast<u32>(pass.render_targets.size()), nullptr);
|
||||||
|
if (!pass.render_targets.empty())
|
||||||
|
g_gpu_device->SetViewportAndScissor(GSVector4i::loadh(render_targets[0]->GetSizeVec()));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_gpu_device->SetPipeline(pass.pipeline.get());
|
g_gpu_device->SetPipeline(pass.pipeline.get());
|
||||||
|
@ -116,7 +116,10 @@ private:
|
|||||||
std::unique_ptr<GPUTexture> texture;
|
std::unique_ptr<GPUTexture> texture;
|
||||||
std::string reshade_name; // TODO: we might be able to drop this
|
std::string reshade_name; // TODO: we might be able to drop this
|
||||||
GPUTexture::Format format;
|
GPUTexture::Format format;
|
||||||
float rt_scale;
|
u32 render_target_width;
|
||||||
|
u32 render_target_height;
|
||||||
|
bool render_target;
|
||||||
|
bool storage_access;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sampler
|
struct Sampler
|
||||||
@ -133,6 +136,7 @@ private:
|
|||||||
llvm::SmallVector<TextureID, GPUDevice::MAX_RENDER_TARGETS> render_targets;
|
llvm::SmallVector<TextureID, GPUDevice::MAX_RENDER_TARGETS> render_targets;
|
||||||
llvm::SmallVector<Sampler, GPUDevice::MAX_TEXTURE_SAMPLERS> samplers;
|
llvm::SmallVector<Sampler, GPUDevice::MAX_TEXTURE_SAMPLERS> samplers;
|
||||||
u32 num_vertices;
|
u32 num_vertices;
|
||||||
|
bool clear_render_targets;
|
||||||
|
|
||||||
#ifdef ENABLE_GPU_OBJECT_NAMES
|
#ifdef ENABLE_GPU_OBJECT_NAMES
|
||||||
std::string name;
|
std::string name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user