gpu: Add a flip_y argument to shader execution

Because GL flips its shit sometimes (ie when it's the framebuffer),
pass the height of the target as the flip variable, so commands
that need to operate on the pixels can flip the y axis around this value.
This commit is contained in:
Benjamin Otte 2023-08-29 08:34:55 +02:00
parent 57ab670991
commit 73ac2d0a1c
13 changed files with 52 additions and 20 deletions

View File

@ -95,7 +95,7 @@ gsk_gl_frame_submit (GskGpuFrame *frame,
while (op)
{
op = gsk_gpu_op_gl_command (op, frame);
op = gsk_gpu_op_gl_command (op, frame, 0);
}
}

View File

@ -207,6 +207,12 @@ gsk_gl_image_bind_framebuffer (GskGLImage *self)
gsk_gl_image_bind_framebuffer_target (self, GL_FRAMEBUFFER);
}
gboolean
gsk_gl_image_is_flipped (GskGLImage *self)
{
return self->texture_id == 0;
}
GLint
gsk_gl_image_get_gl_internal_format (GskGLImage *self)
{

View File

@ -24,6 +24,7 @@ void gsk_gl_image_bind_framebuffer (GskGLIm
void gsk_gl_image_bind_framebuffer_target (GskGLImage *self,
GLenum target);
gboolean gsk_gl_image_is_flipped (GskGLImage *self);
GLint gsk_gl_image_get_gl_internal_format (GskGLImage *self);
GLenum gsk_gl_image_get_gl_format (GskGLImage *self);
GLenum gsk_gl_image_get_gl_type (GskGLImage *self);

View File

@ -147,7 +147,8 @@ gsk_gpu_blit_op_vk_command (GskGpuOp *op,
static GskGpuOp *
gsk_gpu_blit_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
GskGpuBlitOp *self = (GskGpuBlitOp *) op;
GLenum filter;
@ -175,9 +176,11 @@ gsk_gpu_blit_op_gl_command (GskGpuOp *op,
self->src_rect.x + self->src_rect.width,
self->src_rect.y + self->src_rect.height,
self->dest_rect.x,
self->dest_rect.y,
flip_y ? flip_y - self->dest_rect.y - self->dest_rect.height
: self->dest_rect.y,
self->dest_rect.x + self->dest_rect.width,
self->dest_rect.y + self->dest_rect.height,
flip_y ? flip_y - self->dest_rect.y
: self->dest_rect.y + self->dest_rect.height,
GL_COLOR_BUFFER_BIT,
filter);
glEnable (GL_SCISSOR_TEST);

View File

@ -181,7 +181,8 @@ gsk_gl_texture_data_free (gpointer user_data)
static GskGpuOp *
gsk_gpu_download_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
GskGpuDownloadOp *self = (GskGpuDownloadOp *) op;
GdkGLTextureBuilder *builder;

View File

@ -56,7 +56,8 @@ gsk_gpu_globals_op_vk_command (GskGpuOp *op,
static GskGpuOp *
gsk_gpu_globals_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
GskGpuGlobalsOp *self = (GskGpuGlobalsOp *) op;

View File

@ -45,8 +45,9 @@ gsk_gpu_op_vk_command (GskGpuOp *op,
GskGpuOp *
gsk_gpu_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
return op->op_class->gl_command (op, frame);
return op->op_class->gl_command (op, frame, flip_y);
}

View File

@ -44,7 +44,8 @@ struct _GskGpuOpClass
VkCommandBuffer command_buffer);
#endif
GskGpuOp * (* gl_command) (GskGpuOp *op,
GskGpuFrame *frame);
GskGpuFrame *frame,
gsize flip_y);
};
/* ensures alignment of ops to multipes of 16 bytes - and that makes graphene happy */
@ -67,7 +68,8 @@ GskGpuOp * gsk_gpu_op_vk_command (GskGpuO
VkCommandBuffer command_buffer);
#endif
GskGpuOp * gsk_gpu_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame);
GskGpuFrame *frame,
gsize flip_y);
G_END_DECLS

View File

@ -155,12 +155,19 @@ gsk_gpu_render_pass_op_vk_command (GskGpuOp *op,
static GskGpuOp *
gsk_gpu_render_pass_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
GskGpuRenderPassOp *self = (GskGpuRenderPassOp *) op;
gsize target_flip_y;
gsk_gl_image_bind_framebuffer (GSK_GL_IMAGE (self->target));
if (gsk_gl_image_is_flipped (GSK_GL_IMAGE (self->target)))
target_flip_y = gsk_gpu_image_get_height (self->target);
else
target_flip_y = 0;
glViewport (0, 0,
gsk_gpu_image_get_width (self->target),
gsk_gpu_image_get_height (self->target));
@ -171,10 +178,10 @@ gsk_gpu_render_pass_op_gl_command (GskGpuOp *op,
op = op->next;
while (op->op_class->stage != GSK_GPU_STAGE_END_PASS)
{
op = gsk_gpu_op_gl_command (op, frame);
op = gsk_gpu_op_gl_command (op, frame, target_flip_y);
}
op = gsk_gpu_op_gl_command (op, frame);
op = gsk_gpu_op_gl_command (op, frame, target_flip_y);
return op;
}
@ -244,7 +251,8 @@ gsk_gpu_render_pass_end_op_vk_command (GskGpuOp *op,
static GskGpuOp *
gsk_gpu_render_pass_end_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
/* nothing to do here */

View File

@ -56,11 +56,15 @@ gsk_gpu_scissor_op_vk_command (GskGpuOp *op,
static GskGpuOp *
gsk_gpu_scissor_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
GskGpuScissorOp *self = (GskGpuScissorOp *) op;
glScissor (self->rect.x, self->rect.y, self->rect.width, self->rect.height);
if (flip_y)
glScissor (self->rect.x, flip_y - self->rect.y - self->rect.height, self->rect.width, self->rect.height);
else
glScissor (self->rect.x, self->rect.y, self->rect.width, self->rect.height);
return op->next;
}

View File

@ -75,6 +75,7 @@ gsk_gpu_shader_op_vk_command (GskGpuOp *op,
GskGpuOp *
gsk_gpu_shader_op_gl_command_n (GskGpuOp *op,
GskGpuFrame *frame,
gsize flip_y,
gsize instance_scale)
{
GskGpuShaderOp *self = (GskGpuShaderOp *) op;
@ -108,9 +109,10 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op,
GskGpuOp *
gsk_gpu_shader_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
return gsk_gpu_shader_op_gl_command_n (op, frame, 1);
return gsk_gpu_shader_op_gl_command_n (op, frame, flip_y, 1);
}
GskGpuShaderOp *

View File

@ -59,9 +59,11 @@ GskGpuOp * gsk_gpu_shader_op_vk_command (GskGpuO
#endif
GskGpuOp * gsk_gpu_shader_op_gl_command_n (GskGpuOp *op,
GskGpuFrame *frame,
gsize flip_y,
gsize instance_scale);
GskGpuOp * gsk_gpu_shader_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame);
GskGpuFrame *frame,
gsize flip_y);
G_END_DECLS

View File

@ -294,7 +294,8 @@ gsk_gpu_upload_cairo_op_vk_command (GskGpuOp *op,
static GskGpuOp *
gsk_gpu_upload_cairo_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
GskGpuFrame *frame,
gsize flip_y)
{
GskGpuUploadCairoOp *self = (GskGpuUploadCairoOp *) op;