mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-10-11 22:49:55 +00:00
rsx/gl: Implement support for framebuffer-less rendering
This commit is contained in:
@@ -192,6 +192,11 @@ void GLGSRender::on_init_thread()
|
||||
backend_config.supports_hw_instanced_rendering = false;
|
||||
}
|
||||
|
||||
if (gl_caps.ARB_framebuffer_no_attachments_supported)
|
||||
{
|
||||
backend_config.supports_framebufferless_rendering = true;
|
||||
}
|
||||
|
||||
if (!gl_caps.ARB_bindless_texture_supported)
|
||||
{
|
||||
switch (shadermode)
|
||||
|
||||
@@ -158,6 +158,8 @@ OPENGL_PROC(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC, NamedFramebufferDrawBuffers);
|
||||
OPENGL_PROC(PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC, FramebufferDrawBuffersEXT);
|
||||
OPENGL_PROC(PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC, NamedFramebufferReadBuffer);
|
||||
OPENGL_PROC(PFNGLFRAMEBUFFERREADBUFFEREXTPROC, FramebufferReadBufferEXT);
|
||||
OPENGL_PROC(PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC, NamedFramebufferParameteri);
|
||||
OPENGL_PROC(PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC, NamedFramebufferParameteriEXT);
|
||||
|
||||
OPENGL_PROC(PFNGLENABLEIPROC, Enablei);
|
||||
OPENGL_PROC(PFNGLDISABLEIPROC, Disablei);
|
||||
|
||||
@@ -268,6 +268,18 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /*
|
||||
|
||||
ensure(m_draw_fbo);
|
||||
|
||||
if (!depth_stencil_target &&
|
||||
std::all_of(color_targets.begin(), color_targets.end(), FN(x == GL_NONE)))
|
||||
{
|
||||
// Framebufferless rendering. Raster dimensions must be supplied explicitly and match what real surfaces would have used.
|
||||
const auto [raster_width, raster_height] = rsx::apply_resolution_scale<true>(
|
||||
resolution_scaling_config, m_framebuffer_layout.width, m_framebuffer_layout.height);
|
||||
|
||||
const GLint raster_samples = (g_cfg.video.antialiasing_level == msaa_level::_auto) ? samples : 1;
|
||||
m_draw_fbo->set_default_extents({ raster_width, raster_height });
|
||||
m_draw_fbo->set_default_samples(raster_samples);
|
||||
}
|
||||
|
||||
switch (rsx::method_registers.surface_color_target())
|
||||
{
|
||||
case rsx::surface_target::none: break;
|
||||
|
||||
@@ -96,6 +96,8 @@ namespace gl
|
||||
|
||||
CHECK_EXTENSION_SUPPORT(ARB_shader_storage_buffer_object);
|
||||
|
||||
CHECK_EXTENSION_SUPPORT(ARB_framebuffer_no_attachments);
|
||||
|
||||
#undef CHECK_EXTENSION_SUPPORT
|
||||
|
||||
// Set GLSL version
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace gl
|
||||
bool ARB_shader_texture_image_samples_supported = false;
|
||||
bool EXT_texture_compression_s3tc_supported = false;
|
||||
bool ARB_shader_storage_buffer_object_supported = false;
|
||||
bool ARB_framebuffer_no_attachments_supported = false;
|
||||
|
||||
bool vendor_INTEL = false; // has broken GLSL compiler
|
||||
bool vendor_AMD = false; // has broken ARB_multidraw
|
||||
|
||||
@@ -255,6 +255,18 @@ namespace gl
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void fbo::set_default_extents(const size2i& extents) const
|
||||
{
|
||||
DSA_CALL2(NamedFramebufferParameteri, m_id, GL_FRAMEBUFFER_DEFAULT_WIDTH, extents.width);
|
||||
DSA_CALL2(NamedFramebufferParameteri, m_id, GL_FRAMEBUFFER_DEFAULT_HEIGHT, extents.height);
|
||||
}
|
||||
|
||||
void fbo::set_default_samples(GLint samples) const
|
||||
{
|
||||
DSA_CALL2(NamedFramebufferParameteri, m_id, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples > 1 ? samples : 0);
|
||||
DSA_CALL2(NamedFramebufferParameteri, m_id, GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS, GL_TRUE);
|
||||
}
|
||||
|
||||
bool fbo::matches(const std::array<GLuint, 4>& color_targets, GLuint depth_stencil_target) const
|
||||
{
|
||||
for (u32 index = 0; index < 4; ++index)
|
||||
|
||||
@@ -257,6 +257,9 @@ namespace gl
|
||||
void set_extents(const size2i& extents);
|
||||
size2i get_extents() const;
|
||||
|
||||
void set_default_extents(const size2i& extents) const;
|
||||
void set_default_samples(GLint samples) const;
|
||||
|
||||
bool matches(const std::array<GLuint, 4>& color_targets, GLuint depth_stencil_target) const;
|
||||
bool references_any(const std::vector<GLuint>& resources) const;
|
||||
|
||||
|
||||
@@ -1773,10 +1773,19 @@ namespace rsx
|
||||
m_graphics_state.set(rsx::rtt_config_valid);
|
||||
}
|
||||
|
||||
if (!m_graphics_state.test(rsx::rtt_config_valid) && !layout.zeta_address)
|
||||
const bool framebufferless = !m_graphics_state.test(rsx::rtt_config_valid) && !layout.zeta_address;
|
||||
if (framebufferless)
|
||||
{
|
||||
rsx_log.warning("Framebuffer setup failed. Draw calls may have been lost");
|
||||
return;
|
||||
// No attachments. The hardware still rasterizes in this case and side effects such as ZPASS counters are still updated.
|
||||
if (context != rsx::framebuffer_creation_context::context_draw ||
|
||||
!backend_config.supports_framebufferless_rendering)
|
||||
{
|
||||
rsx_log.warning("Framebuffer setup failed. Draw calls may have been lost");
|
||||
return;
|
||||
}
|
||||
|
||||
// Context must be draw now...
|
||||
// TODO: Also disable rendering if ZPASS stat counting is not enabled (side-effect)
|
||||
}
|
||||
|
||||
// At least one attachment exists
|
||||
@@ -1852,7 +1861,8 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
if (!really_changed)
|
||||
// Framebufferless setups have no surface info to compare against. Always rebuild.
|
||||
if (!really_changed && !framebufferless)
|
||||
{
|
||||
if (layout.zeta_address == m_depth_surface_info.address &&
|
||||
layout.depth_format == m_depth_surface_info.depth_format &&
|
||||
|
||||
+16
-15
@@ -79,21 +79,22 @@ namespace rsx
|
||||
|
||||
struct backend_configuration
|
||||
{
|
||||
bool supports_multidraw; // Draw call batching
|
||||
bool supports_hw_a2c; // Alpha to coverage
|
||||
bool supports_hw_a2c_1spp; // Alpha to coverage at 1 sample per pixel
|
||||
bool supports_hw_renormalization; // Should be true on NV hardware which matches PS3 texture renormalization behaviour
|
||||
bool supports_hw_msaa; // MSAA support
|
||||
bool supports_hw_a2one; // Alpha to one
|
||||
bool supports_hw_conditional_render; // Conditional render
|
||||
bool supports_hw_instanced_rendering; // Instanced draws
|
||||
bool supports_passthrough_dma; // DMA passthrough
|
||||
bool supports_asynchronous_compute; // Async compute
|
||||
bool supports_host_gpu_labels; // Advanced host synchronization
|
||||
bool supports_normalized_barycentrics; // Basically all GPUs except NVIDIA have properly normalized barycentrics
|
||||
bool supports_last_provoking_vertex; // Flat shading using RSX's last-vertex convention
|
||||
bool supports_extended_depth_range; // Depth values above 1 can be stored and tested. Float depth targets are emulated otherwise.
|
||||
bool supports_programmable_blending; // Can handle programmable blending requests
|
||||
bool supports_multidraw; // Draw call batching
|
||||
bool supports_hw_a2c; // Alpha to coverage
|
||||
bool supports_hw_a2c_1spp; // Alpha to coverage at 1 sample per pixel
|
||||
bool supports_hw_renormalization; // Should be true on NV hardware which matches PS3 texture renormalization behaviour
|
||||
bool supports_hw_msaa; // MSAA support
|
||||
bool supports_hw_a2one; // Alpha to one
|
||||
bool supports_hw_conditional_render; // Conditional render
|
||||
bool supports_hw_instanced_rendering; // Instanced draws
|
||||
bool supports_passthrough_dma; // DMA passthrough
|
||||
bool supports_asynchronous_compute; // Async compute
|
||||
bool supports_host_gpu_labels; // Advanced host synchronization
|
||||
bool supports_normalized_barycentrics; // Basically all GPUs except NVIDIA have properly normalized barycentrics
|
||||
bool supports_last_provoking_vertex; // Flat shading using RSX's last-vertex convention
|
||||
bool supports_programmable_blending; // Can handle programmable blending requests
|
||||
bool supports_extended_depth_range; // Depth values above 1 can be stored and tested. Float depth targets are emulated otherwise.
|
||||
bool supports_framebufferless_rendering; // Can rasterize without any attachments bound (e.g for occlusion queries)
|
||||
};
|
||||
|
||||
struct desync_fifo_cmd_info
|
||||
|
||||
Reference in New Issue
Block a user