GPU/HW: Expose depth buffer to internal postprocessing

This commit is contained in:
Stenzek
2024-03-24 19:49:16 +10:00
parent e39a2d00bf
commit 34d5cdec96
14 changed files with 288 additions and 85 deletions

View File

@ -1770,7 +1770,6 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm
GL_OBJECT_NAME(vso, "Display Vertex Shader");
GL_OBJECT_NAME_FMT(fso, "Display Fragment Shader [{}]",
Settings::GetDisplayScalingName(g_settings.display_scaling));
plconfig.vertex_shader = vso.get();
plconfig.fragment_shader = fso.get();
if (!(m_display_pipeline = g_gpu_device->CreatePipeline(plconfig)))
@ -1913,10 +1912,12 @@ void GPU::ClearDisplayTexture()
m_display_texture_view_height = 0;
}
void GPU::SetDisplayTexture(GPUTexture* texture, s32 view_x, s32 view_y, s32 view_width, s32 view_height)
void GPU::SetDisplayTexture(GPUTexture* texture, GPUTexture* depth_buffer, s32 view_x, s32 view_y, s32 view_width,
s32 view_height)
{
DebugAssert(texture);
m_display_texture = texture;
m_display_depth_buffer = depth_buffer;
m_display_texture_view_x = view_x;
m_display_texture_view_y = view_y;
m_display_texture_view_width = view_width;
@ -1957,10 +1958,10 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
// Now we can apply the post chain.
GPUTexture* post_output_texture = PostProcessing::InternalChain.GetOutputTexture();
if (PostProcessing::InternalChain.Apply(display_texture, post_output_texture, 0, 0, display_texture_view_width,
display_texture_view_height, display_texture_view_width,
display_texture_view_height, m_crtc_state.display_width,
m_crtc_state.display_height))
if (PostProcessing::InternalChain.Apply(display_texture, m_display_depth_buffer, post_output_texture, 0, 0,
display_texture_view_width, display_texture_view_height,
display_texture_view_width, display_texture_view_height,
m_crtc_state.display_width, m_crtc_state.display_height))
{
display_texture_view_x = 0;
display_texture_view_y = 0;
@ -2075,7 +2076,7 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
const s32 orig_width = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_width) * upscale_x));
const s32 orig_height = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_height) * upscale_y));
return PostProcessing::DisplayChain.Apply(PostProcessing::DisplayChain.GetInputTexture(), target,
return PostProcessing::DisplayChain.Apply(PostProcessing::DisplayChain.GetInputTexture(), nullptr, target,
real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
real_draw_rect.GetHeight(), orig_width, orig_height,
m_crtc_state.display_width, m_crtc_state.display_height);
@ -2113,7 +2114,7 @@ bool GPU::Deinterlace(u32 field, u32 line_skip)
if (!DeinterlaceExtractField(0, src, x, y, width, height, line_skip)) [[unlikely]]
return false;
SetDisplayTexture(m_deinterlace_buffers[0].get(), 0, 0, width, height);
SetDisplayTexture(m_deinterlace_buffers[0].get(), m_display_depth_buffer, 0, 0, width, height);
return true;
}
@ -2139,7 +2140,7 @@ bool GPU::Deinterlace(u32 field, u32 line_skip)
g_gpu_device->Draw(3, 0);
m_deinterlace_texture->MakeReadyForSampling();
SetDisplayTexture(m_deinterlace_texture.get(), 0, 0, width, full_height);
SetDisplayTexture(m_deinterlace_texture.get(), m_display_depth_buffer, 0, 0, width, full_height);
return true;
}
@ -2171,7 +2172,7 @@ bool GPU::Deinterlace(u32 field, u32 line_skip)
g_gpu_device->Draw(3, 0);
m_deinterlace_texture->MakeReadyForSampling();
SetDisplayTexture(m_deinterlace_texture.get(), 0, 0, width, height);
SetDisplayTexture(m_deinterlace_texture.get(), m_display_depth_buffer, 0, 0, width, height);
return true;
}
@ -2206,7 +2207,7 @@ bool GPU::Deinterlace(u32 field, u32 line_skip)
g_gpu_device->Draw(3, 0);
m_deinterlace_texture->MakeReadyForSampling();
SetDisplayTexture(m_deinterlace_texture.get(), 0, 0, width, full_height);
SetDisplayTexture(m_deinterlace_texture.get(), m_display_depth_buffer, 0, 0, width, full_height);
return true;
}
@ -2309,7 +2310,7 @@ bool GPU::ApplyChromaSmoothing()
g_gpu_device->Draw(3, 0);
m_chroma_smoothing_texture->MakeReadyForSampling();
SetDisplayTexture(m_chroma_smoothing_texture.get(), 0, 0, width, height);
SetDisplayTexture(m_chroma_smoothing_texture.get(), m_display_depth_buffer, 0, 0, width, height);
return true;
}

View File

@ -603,7 +603,8 @@ protected:
u32 m_fifo_size = 128;
void ClearDisplayTexture();
void SetDisplayTexture(GPUTexture* texture, s32 view_x, s32 view_y, s32 view_width, s32 view_height);
void SetDisplayTexture(GPUTexture* texture, GPUTexture* depth_texture, s32 view_x, s32 view_y, s32 view_width,
s32 view_height);
bool RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx);
@ -624,6 +625,7 @@ protected:
std::unique_ptr<GPUPipeline> m_display_pipeline;
GPUTexture* m_display_texture = nullptr;
GPUTexture* m_display_depth_buffer = nullptr;
s32 m_display_texture_view_x = 0;
s32 m_display_texture_view_y = 0;
s32 m_display_texture_view_width = 0;

View File

@ -34,6 +34,7 @@ Log_SetChannel(GPU_HW);
static constexpr GPUTexture::Format VRAM_RT_FORMAT = GPUTexture::Format::RGBA8;
static constexpr GPUTexture::Format VRAM_DS_FORMAT = GPUTexture::Format::D16;
static constexpr GPUTexture::Format VRAM_DS_DEPTH_FORMAT = GPUTexture::Format::D32F;
static constexpr GPUTexture::Format VRAM_DS_EXTRACT_FORMAT = GPUTexture::Format::R32F;
#ifdef _DEBUG
static u32 s_draw_number = 0;
@ -414,6 +415,7 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
{
m_pgxp_depth_buffer = g_settings.UsingPGXPDepthBuffer();
m_batch.use_depth_buffer = false;
m_depth_was_copied = false;
// might be null when resizing
if (m_vram_depth_texture)
@ -722,8 +724,10 @@ bool GPU_HW::CreateBuffers()
if (!(m_vram_texture = g_gpu_device->FetchTexture(texture_width, texture_height, 1, 1, samples,
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
(needs_depth_buffer &&
!(m_vram_depth_texture = g_gpu_device->FetchTexture(texture_width, texture_height, 1, 1, samples,
GPUTexture::Type::DepthStencil, GetDepthBufferFormat()))) ||
(!(m_vram_depth_texture = g_gpu_device->FetchTexture(texture_width, texture_height, 1, 1, samples,
GPUTexture::Type::DepthStencil, GetDepthBufferFormat())) ||
!(m_vram_depth_copy_texture = g_gpu_device->FetchTexture(
texture_width, texture_height, 1, 1, samples, GPUTexture::Type::RenderTarget, VRAM_DS_EXTRACT_FORMAT)))) ||
!(m_vram_read_texture =
g_gpu_device->FetchTexture(texture_width, texture_height, 1, 1, 1, read_texture_type, VRAM_RT_FORMAT)) ||
!(m_vram_readback_texture = g_gpu_device->FetchTexture(VRAM_WIDTH / 2, VRAM_HEIGHT, 1, 1, 1,
@ -802,8 +806,10 @@ void GPU_HW::DestroyBuffers()
m_vram_upload_buffer.reset();
m_vram_readback_download_texture.reset();
g_gpu_device->RecycleTexture(std::move(m_downsample_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_extract_depth_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_extract_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_read_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_depth_copy_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_depth_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_texture));
g_gpu_device->RecycleTexture(std::move(m_vram_readback_texture));
@ -1289,23 +1295,50 @@ bool GPU_HW::CompilePipelines()
// Display
{
for (u8 depth_24 = 0; depth_24 < 2; depth_24++)
for (u8 shader = 0; shader < 3; shader++)
{
// 24-bit doesn't give you a depth buffer.
const bool color_24bit = (shader == 1);
const bool depth_extract = (shader == 2);
if (depth_extract && !m_pgxp_depth_buffer)
continue;
std::unique_ptr<GPUShader> fs =
g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(),
shadergen.GenerateVRAMExtractFragmentShader(ConvertToBoolUnchecked(depth_24)));
shadergen.GenerateVRAMExtractFragmentShader(color_24bit, depth_extract));
if (!fs)
return false;
plconfig.fragment_shader = fs.get();
if (!(m_vram_extract_pipeline[depth_24] = g_gpu_device->CreatePipeline(plconfig)))
plconfig.layout = depth_extract ? GPUPipeline::Layout::MultiTextureAndPushConstants :
GPUPipeline::Layout::SingleTextureAndPushConstants;
plconfig.color_formats[1] = depth_extract ? VRAM_DS_EXTRACT_FORMAT : GPUTexture::Format::Unknown;
if (!(m_vram_extract_pipeline[shader] = g_gpu_device->CreatePipeline(plconfig)))
return false;
progress.Increment();
}
}
plconfig.layout = GPUPipeline::Layout::SingleTextureAndPushConstants;
if (m_pgxp_depth_buffer)
{
std::unique_ptr<GPUShader> fs = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(),
shadergen.GenerateCopyFragmentShader());
if (!fs)
return false;
plconfig.fragment_shader = fs.get();
plconfig.SetTargetFormats(VRAM_DS_EXTRACT_FORMAT);
if (!(m_copy_depth_pipeline = g_gpu_device->CreatePipeline(plconfig)))
return false;
}
plconfig.SetTargetFormats(VRAM_RT_FORMAT);
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
{
std::unique_ptr<GPUShader> vs = g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(),
@ -1419,6 +1452,8 @@ void GPU_HW::DestroyPipelines()
destroy(m_downsample_blur_pass_pipeline);
destroy(m_downsample_composite_pass_pipeline);
m_downsample_composite_sampler.reset();
m_copy_depth_pipeline.reset();
}
GPU_HW::BatchRenderMode GPU_HW::BatchConfig::GetRenderMode() const
@ -1515,10 +1550,40 @@ void GPU_HW::UpdateDepthBufferFromMaskBit()
SetScissor();
}
void GPU_HW::CopyAndClearDepthBuffer()
{
if (!m_depth_was_copied)
{
// Take a copy of the current depth buffer so it can be used when the previous frame/buffer gets scanned out.
// Don't bother when we're not postprocessing, it'd just be a wasted copy.
if (PostProcessing::InternalChain.NeedsDepthBuffer())
{
// TODO: Shrink this to only the active area.
GL_SCOPE("Copy Depth Buffer");
m_vram_texture->MakeReadyForSampling();
g_gpu_device->InvalidateRenderTarget(m_vram_depth_copy_texture.get());
g_gpu_device->SetRenderTarget(m_vram_depth_copy_texture.get());
g_gpu_device->SetViewportAndScissor(0, 0, m_vram_depth_texture->GetWidth(), m_vram_depth_texture->GetHeight());
g_gpu_device->SetTextureSampler(0, m_vram_depth_texture.get(), g_gpu_device->GetNearestSampler());
g_gpu_device->SetPipeline(m_copy_depth_pipeline.get());
const float uniforms[4] = {0.0f, 0.0f, 1.0f, 1.0f};
g_gpu_device->PushUniformBuffer(uniforms, sizeof(uniforms));
g_gpu_device->Draw(3, 0);
RestoreDeviceContext();
}
m_depth_was_copied = true;
}
ClearDepthBuffer();
}
void GPU_HW::ClearDepthBuffer()
{
GL_SCOPE("GPU_HW::ClearDepthBuffer()");
DebugAssert(m_pgxp_depth_buffer);
g_gpu_device->ClearDepth(m_vram_depth_texture.get(), 1.0f);
m_last_depth_z = 1.0f;
}
@ -1911,13 +1976,9 @@ void GPU_HW::CheckForDepthClear(const BatchVertex* vertices, u32 num_vertices)
if ((average_z - m_last_depth_z) >= g_settings.gpu_pgxp_depth_clear_threshold)
{
if (m_batch_index_count > 0)
{
FlushRender();
EnsureVertexBufferSpaceForCurrentCommand();
}
ClearDepthBuffer();
FlushRender();
CopyAndClearDepthBuffer();
EnsureVertexBufferSpaceForCurrentCommand();
}
m_last_depth_z = average_z;
@ -3204,7 +3265,11 @@ void GPU_HW::DispatchRenderCommand()
SetScissor();
if (m_pgxp_depth_buffer && m_last_depth_z < 1.0f)
ClearDepthBuffer();
{
FlushRender();
CopyAndClearDepthBuffer();
EnsureVertexBufferSpaceForCurrentCommand();
}
if (m_sw_renderer)
{
@ -3292,12 +3357,12 @@ void GPU_HW::UpdateDisplay()
if (IsUsingMultisampling())
{
UpdateVRAMReadTexture(true, true);
SetDisplayTexture(m_vram_read_texture.get(), 0, 0, m_vram_read_texture->GetWidth(),
SetDisplayTexture(m_vram_read_texture.get(), nullptr, 0, 0, m_vram_read_texture->GetWidth(),
m_vram_read_texture->GetHeight());
}
else
{
SetDisplayTexture(m_vram_texture.get(), 0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
SetDisplayTexture(m_vram_texture.get(), nullptr, 0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
}
return;
@ -3315,6 +3380,12 @@ void GPU_HW::UpdateDisplay()
const u32 line_skip = BoolToUInt32(interlaced && m_GPUSTAT.vertical_resolution);
bool drew_anything = false;
// Don't bother grabbing depth if postfx doesn't need it.
GPUTexture* depth_source = (!m_GPUSTAT.display_area_color_depth_24 && m_pgxp_depth_buffer &&
PostProcessing::InternalChain.NeedsDepthBuffer()) ?
(m_depth_was_copied ? m_vram_depth_copy_texture.get() : m_vram_depth_texture.get()) :
nullptr;
if (IsDisplayDisabled())
{
ClearDisplayTexture();
@ -3325,8 +3396,8 @@ void GPU_HW::UpdateDisplay()
(scaled_vram_offset_y + scaled_display_height) <= m_vram_texture->GetHeight() &&
!PostProcessing::InternalChain.IsActive())
{
SetDisplayTexture(m_vram_texture.get(), scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width,
read_height);
SetDisplayTexture(m_vram_texture.get(), depth_source, scaled_vram_offset_x, scaled_vram_offset_y,
scaled_display_width, read_height);
// Fast path if no copies are needed.
if (interlaced)
@ -3353,14 +3424,39 @@ void GPU_HW::UpdateDisplay()
}
}
m_vram_texture->MakeReadyForSampling();
g_gpu_device->InvalidateRenderTarget(m_vram_extract_texture.get());
g_gpu_device->SetRenderTarget(m_vram_extract_texture.get());
g_gpu_device->SetPipeline(m_vram_extract_pipeline[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)].get());
g_gpu_device->SetTextureSampler(0, m_vram_texture.get(), g_gpu_device->GetNearestSampler());
if (depth_source &&
((m_vram_extract_depth_texture && m_vram_extract_depth_texture->GetWidth() == scaled_display_width &&
m_vram_extract_depth_texture->GetHeight() == scaled_display_height) ||
!g_gpu_device->ResizeTexture(&m_vram_extract_depth_texture, scaled_display_width, scaled_display_height,
GPUTexture::Type::RenderTarget, VRAM_DS_EXTRACT_FORMAT)))
{
depth_source->MakeReadyForSampling();
g_gpu_device->InvalidateRenderTarget(m_vram_extract_depth_texture.get());
GPUTexture* targets[] = {m_vram_extract_texture.get(), m_vram_extract_depth_texture.get()};
g_gpu_device->SetRenderTargets(targets, static_cast<u32>(std::size(targets)), nullptr);
g_gpu_device->SetPipeline(m_vram_extract_pipeline[2].get());
g_gpu_device->SetTextureSampler(0, m_vram_texture.get(), g_gpu_device->GetNearestSampler());
g_gpu_device->SetTextureSampler(1, depth_source, g_gpu_device->GetNearestSampler());
}
else
{
g_gpu_device->SetRenderTarget(m_vram_extract_texture.get());
g_gpu_device->SetPipeline(m_vram_extract_pipeline[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)].get());
g_gpu_device->SetTextureSampler(0, m_vram_texture.get(), g_gpu_device->GetNearestSampler());
}
const u32 reinterpret_start_x = m_crtc_state.regs.X * resolution_scale;
const u32 skip_x = (m_crtc_state.display_vram_left - m_crtc_state.regs.X) * resolution_scale;
GL_INS_FMT("Convert 16bpp to 24bpp, skip_x = {}, line_skip = {}", skip_x, line_skip);
GL_INS_FMT("VRAM extract, depth = {}, 24bpp = {}, skip_x = {}, line_skip = {}", depth_source ? "yes" : "no",
m_GPUSTAT.display_area_color_depth_24.GetValue(), skip_x, line_skip);
GL_INS_FMT("Source: {},{} => {},{} ({}x{})", reinterpret_start_x, scaled_vram_offset_y,
reinterpret_start_x + scaled_display_width, scaled_vram_offset_y + read_height, scaled_display_width,
read_height);
const u32 uniforms[4] = {reinterpret_start_x, scaled_vram_offset_y, skip_x, line_skip};
g_gpu_device->PushUniformBuffer(uniforms, sizeof(uniforms));
@ -3369,9 +3465,17 @@ void GPU_HW::UpdateDisplay()
g_gpu_device->Draw(3, 0);
m_vram_extract_texture->MakeReadyForSampling();
if (depth_source)
{
// Thanks DX11...
m_vram_extract_depth_texture->MakeReadyForSampling();
g_gpu_device->SetTextureSampler(1, nullptr, nullptr);
}
drew_anything = true;
SetDisplayTexture(m_vram_extract_texture.get(), 0, 0, scaled_display_width, read_height);
SetDisplayTexture(m_vram_extract_texture.get(), depth_source ? m_vram_extract_depth_texture.get() : nullptr, 0, 0,
scaled_display_width, read_height);
if (g_settings.gpu_24bit_chroma_smoothing)
{
if (ApplyChromaSmoothing())
@ -3425,6 +3529,7 @@ void GPU_HW::UpdateDownsamplingLevels()
void GPU_HW::OnBufferSwapped()
{
GL_INS("OnBufferSwapped()");
m_depth_was_copied = false;
}
void GPU_HW::DownsampleFramebuffer()
@ -3556,7 +3661,7 @@ void GPU_HW::DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top
RestoreDeviceContext();
SetDisplayTexture(m_downsample_texture.get(), 0, 0, width, height);
SetDisplayTexture(m_downsample_texture.get(), m_display_depth_buffer, 0, 0, width, height);
}
void GPU_HW::DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height)
@ -3594,7 +3699,7 @@ void GPU_HW::DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 to
RestoreDeviceContext();
SetDisplayTexture(m_downsample_texture.get(), 0, 0, ds_width, ds_height);
SetDisplayTexture(m_downsample_texture.get(), m_display_depth_buffer, 0, 0, ds_width, ds_height);
}
void GPU_HW::DrawRendererStats()

View File

@ -156,6 +156,7 @@ private:
void SetClampedDrawingArea();
void UpdateVRAMReadTexture(bool drawn, bool written);
void UpdateDepthBufferFromMaskBit();
void CopyAndClearDepthBuffer();
void ClearDepthBuffer();
void SetScissor();
void SetVRAMRenderTarget();
@ -229,6 +230,7 @@ private:
std::unique_ptr<GPUTexture> m_vram_texture;
std::unique_ptr<GPUTexture> m_vram_depth_texture;
std::unique_ptr<GPUTexture> m_vram_depth_copy_texture;
std::unique_ptr<GPUTexture> m_vram_read_texture;
std::unique_ptr<GPUTexture> m_vram_readback_texture;
std::unique_ptr<GPUDownloadTexture> m_vram_readback_download_texture;
@ -269,6 +271,7 @@ private:
bool m_allow_shader_blend : 1 = false;
u8 m_texpage_dirty = 0;
bool m_depth_was_copied = false;
BatchConfig m_batch;
@ -295,8 +298,10 @@ private:
std::unique_ptr<GPUPipeline> m_vram_update_depth_pipeline;
std::unique_ptr<GPUPipeline> m_vram_write_replacement_pipeline;
std::array<std::unique_ptr<GPUPipeline>, 2> m_vram_extract_pipeline; // [24bit]
std::array<std::unique_ptr<GPUPipeline>, 3> m_vram_extract_pipeline; // [24bit, 2=depth]
std::unique_ptr<GPUTexture> m_vram_extract_texture;
std::unique_ptr<GPUTexture> m_vram_extract_depth_texture;
std::unique_ptr<GPUPipeline> m_copy_depth_pipeline;
std::unique_ptr<GPUTexture> m_downsample_texture;
std::unique_ptr<GPUPipeline> m_downsample_first_pass_pipeline;

View File

@ -1031,16 +1031,19 @@ float3 ApplyDebanding(float2 frag_coord)
return ss.str();
}
std::string GPU_HW_ShaderGen::GenerateVRAMExtractFragmentShader(bool depth_24bit)
std::string GPU_HW_ShaderGen::GenerateVRAMExtractFragmentShader(bool color_24bit, bool depth_buffer)
{
std::stringstream ss;
WriteHeader(ss);
DefineMacro(ss, "DEPTH_24BIT", depth_24bit);
DefineMacro(ss, "COLOR_24BIT", color_24bit);
DefineMacro(ss, "DEPTH_BUFFER", depth_buffer);
DefineMacro(ss, "MULTISAMPLED", UsingMSAA());
WriteCommonFunctions(ss);
DeclareUniformBuffer(ss, {"uint2 u_vram_offset", "uint u_skip_x", "uint u_line_skip"}, true);
DeclareTexture(ss, "samp0", 0, UsingMSAA());
if (depth_buffer)
DeclareTexture(ss, "samp1", 1, UsingMSAA());
ss << R"(
float4 LoadVRAM(int2 coords)
@ -1056,6 +1059,22 @@ float4 LoadVRAM(int2 coords)
#endif
}
#if DEPTH_BUFFER
float LoadDepth(int2 coords)
{
// Need to duplicate because different types in different languages...
#if MULTISAMPLING
float value = LOAD_TEXTURE_MS(samp1, coords, 0u).r;
FOR_UNROLL (uint sample_index = 1u; sample_index < MULTISAMPLES; sample_index++)
value += LOAD_TEXTURE_MS(samp1, coords, sample_index).r;
value /= float(MULTISAMPLES);
return value;
#else
return LOAD_TEXTURE(samp1, coords, 0).r;
#endif
}
#endif
float3 SampleVRAM24(uint2 icoords)
{
// load adjacent 16-bit texels
@ -1075,15 +1094,20 @@ float3 SampleVRAM24(uint2 icoords)
}
)";
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1);
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, depth_buffer ? 2 : 1);
ss << R"(
{
uint2 icoords = uint2(uint(v_pos.x) + u_skip_x, uint(v_pos.y) << u_line_skip);
int2 wrapped_coords = int2((icoords + u_vram_offset) % VRAM_SIZE);
#if DEPTH_24BIT
#if COLOR_24BIT
o_col0 = float4(SampleVRAM24(icoords), 1.0);
#else
o_col0 = float4(LoadVRAM(int2((icoords + u_vram_offset) % VRAM_SIZE)).rgb, 1.0);
o_col0 = float4(LoadVRAM(wrapped_coords).rgb, 1.0);
#endif
#if DEPTH_BUFFER
o_col1 = float4(LoadDepth(wrapped_coords), 0.0, 0.0, 0.0);
#endif
}
)";

View File

@ -25,7 +25,7 @@ public:
std::string GenerateVRAMCopyFragmentShader();
std::string GenerateVRAMFillFragmentShader(bool wrapped, bool interlaced);
std::string GenerateVRAMUpdateDepthFragmentShader();
std::string GenerateVRAMExtractFragmentShader(bool depth_24bit);
std::string GenerateVRAMExtractFragmentShader(bool color_24bit, bool depth_buffer);
std::string GenerateAdaptiveDownsampleVertexShader();
std::string GenerateAdaptiveDownsampleMipFragmentShader(bool first_pass);

View File

@ -486,7 +486,7 @@ void GPU_SW::UpdateDisplay()
const u32 line_skip = m_GPUSTAT.vertical_resolution;
if (CopyOut(vram_offset_x, vram_offset_y, skip_x, read_width, read_height, line_skip, is_24bit))
{
SetDisplayTexture(m_upload_texture.get(), 0, 0, read_width, read_height);
SetDisplayTexture(m_upload_texture.get(), nullptr, 0, 0, read_width, read_height);
if (is_24bit && g_settings.gpu_24bit_chroma_smoothing)
{
if (ApplyChromaSmoothing())
@ -502,7 +502,7 @@ void GPU_SW::UpdateDisplay()
{
if (CopyOut(vram_offset_x, vram_offset_y, skip_x, read_width, read_height, 0, is_24bit))
{
SetDisplayTexture(m_upload_texture.get(), 0, 0, read_width, read_height);
SetDisplayTexture(m_upload_texture.get(), nullptr, 0, 0, read_width, read_height);
if (is_24bit && g_settings.gpu_24bit_chroma_smoothing)
ApplyChromaSmoothing();
}
@ -511,7 +511,7 @@ void GPU_SW::UpdateDisplay()
else
{
if (CopyOut(0, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 0, false))
SetDisplayTexture(m_upload_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT);
SetDisplayTexture(m_upload_texture.get(), nullptr, 0, 0, VRAM_WIDTH, VRAM_HEIGHT);
}
}