ngl: Determine intermediate formats

Look at the framebuffer and the rendernode to
determine what format to use for intermediate
textures.

Our preference here is to use fp16, if we have it
and it makes sense for the framebuffer we're given.
This commit is contained in:
Matthias Clasen 2021-10-01 08:48:43 -04:00
parent 9174814686
commit 985d2d221c

View File

@ -162,6 +162,11 @@ struct _GskNglRenderJob
/* If we should be rendering red zones over fallback nodes */
guint debug_fallback : 1;
/* Format we want to use for intermediate textures, determined by
* looking at the format of the framebuffer we are rendering on.
*/
int target_format;
};
typedef struct _GskNglRenderOffscreen
@ -198,6 +203,16 @@ static gboolean gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob
const GskRenderNode *node,
GskNglRenderOffscreen *offscreen);
static inline int
get_target_format (GskNglRenderJob *job,
const GskRenderNode *node)
{
if (gsk_render_node_prefers_high_depth (node))
return job->target_format;
return GL_RGBA8;
}
static inline void
init_full_texture_region (GskNglRenderOffscreen *offscreen)
{
@ -1258,7 +1273,7 @@ blur_offscreen (GskNglRenderJob *job,
if (!gsk_ngl_driver_create_render_target (job->driver,
MAX (texture_to_blur_width, 1),
MAX (texture_to_blur_height, 1),
GL_RGBA8,
job->target_format,
GL_NEAREST, GL_NEAREST,
&pass1))
return 0;
@ -1269,7 +1284,7 @@ blur_offscreen (GskNglRenderJob *job,
if (!gsk_ngl_driver_create_render_target (job->driver,
texture_to_blur_width,
texture_to_blur_height,
GL_RGBA8,
job->target_format,
GL_NEAREST, GL_NEAREST,
&pass2))
return gsk_ngl_driver_release_render_target (job->driver, pass1, FALSE);
@ -2181,7 +2196,7 @@ gsk_ngl_render_job_visit_blurred_inset_shadow_node (GskNglRenderJob *job,
if (!gsk_ngl_driver_create_render_target (job->driver,
texture_width, texture_height,
GL_RGBA8,
get_target_format (job, node),
GL_NEAREST, GL_NEAREST,
&render_target))
g_assert_not_reached ();
@ -2452,7 +2467,7 @@ gsk_ngl_render_job_visit_blurred_outset_shadow_node (GskNglRenderJob *job,
gsk_ngl_driver_create_render_target (job->driver,
texture_width, texture_height,
GL_RGBA8,
get_target_format (job, node),
GL_NEAREST, GL_NEAREST,
&render_target);
@ -3860,7 +3875,7 @@ gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob *job,
if (!gsk_ngl_driver_create_render_target (job->driver,
scaled_width, scaled_height,
GL_RGBA8,
get_target_format (job, node),
filter, filter,
&render_target))
g_assert_not_reached ();
@ -3959,7 +3974,7 @@ gsk_ngl_render_job_render_flipped (GskNglRenderJob *job,
if (!gsk_ngl_command_queue_create_render_target (job->command_queue,
MAX (1, job->viewport.size.width),
MAX (1, job->viewport.size.height),
GL_RGBA8,
job->target_format,
GL_NEAREST, GL_NEAREST,
&framebuffer_id, &texture_id))
return;
@ -4050,6 +4065,22 @@ gsk_ngl_render_job_set_debug_fallback (GskNglRenderJob *job,
job->debug_fallback = !!debug_fallback;
}
static int
get_framebuffer_format (guint framebuffer)
{
int size;
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size);
if (size >= 32)
return GL_RGBA32F;
else if (size >= 16)
return GL_RGBA16F;
else
return GL_RGBA8;
}
GskNglRenderJob *
gsk_ngl_render_job_new (GskNglDriver *driver,
const graphene_rect_t *viewport,
@ -4076,6 +4107,7 @@ gsk_ngl_render_job_new (GskNglDriver *driver,
job->scale_x = scale_factor;
job->scale_y = scale_factor;
job->viewport = *viewport;
job->target_format = get_framebuffer_format (framebuffer);
gsk_ngl_render_job_set_alpha (job, 1.0f);
gsk_ngl_render_job_set_projection_from_rect (job, viewport, NULL);