From d7d4fe90c42d85ecbbedeca8b77043b750e18212 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 16 Feb 2016 10:22:32 -0700 Subject: [PATCH] st/mesa: consolidate quad drawing code The glClear, glBitmap and glDrawPixels code now use a new st_draw_quad() helper function. Reviewed-by: Jose Fonseca --- src/mesa/state_tracker/st_cb_bitmap.c | 66 +----------- src/mesa/state_tracker/st_cb_clear.c | 91 +++------------- src/mesa/state_tracker/st_cb_drawpixels.c | 120 ++++------------------ src/mesa/state_tracker/st_draw.c | 90 ++++++++++++++++ src/mesa/state_tracker/st_draw.h | 7 ++ 5 files changed, 136 insertions(+), 238 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index a85c34068ec..0db2514f451 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -41,6 +41,7 @@ #include "st_context.h" #include "st_atom.h" #include "st_atom_constbuf.h" +#include "st_draw.h" #include "st_program.h" #include "st_cb_bitmap.h" #include "st_texture.h" @@ -50,7 +51,6 @@ #include "pipe/p_shader_tokens.h" #include "util/u_inlines.h" #include "util/u_simple_shaders.h" -#include "util/u_upload_mgr.h" #include "program/prog_instruction.h" #include "cso_cache/cso_context.h" @@ -322,7 +322,6 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; - struct pipe_vertex_buffer vb = {0}; const float fb_width = (float) st->state.framebuffer.width; const float fb_height = (float) st->state.framebuffer.height; const float x0 = (float) x; @@ -335,7 +334,6 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, const float clip_y0 = y0 / fb_height * 2.0f - 1.0f; const float clip_x1 = x1 / fb_width * 2.0f - 1.0f; const float clip_y1 = y1 / fb_height * 2.0f - 1.0f; - struct st_util_vertex *verts; /* limit checks */ { @@ -359,71 +357,13 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, tBot = (float) height; } - vb.stride = sizeof(struct st_util_vertex); - - u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4, - &vb.buffer_offset, &vb.buffer, (void **) &verts); - if (!vb.buffer) { + if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z, + sLeft, tBot, sRight, tTop, color, 0)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBitmap"); - restore_render_state(ctx); - return; } - /* Positions are in clip coords since we need to do clipping in case - * the bitmap quad goes beyond the window bounds. - */ - verts[0].x = clip_x0; - verts[0].y = clip_y0; - verts[0].z = z; - verts[0].r = color[0]; - verts[0].g = color[1]; - verts[0].b = color[2]; - verts[0].a = color[3]; - verts[0].s = sLeft; - verts[0].t = tTop; - - verts[1].x = clip_x1; - verts[1].y = clip_y0; - verts[1].z = z; - verts[1].r = color[0]; - verts[1].g = color[1]; - verts[1].b = color[2]; - verts[1].a = color[3]; - verts[1].s = sRight; - verts[1].t = tTop; - - verts[2].x = clip_x1; - verts[2].y = clip_y1; - verts[2].z = z; - verts[2].r = color[0]; - verts[2].g = color[1]; - verts[2].b = color[2]; - verts[2].a = color[3]; - verts[2].s = sRight; - verts[2].t = tBot; - - verts[3].x = clip_x0; - verts[3].y = clip_y1; - verts[3].z = z; - verts[3].r = color[0]; - verts[3].g = color[1]; - verts[3].b = color[2]; - verts[3].a = color[3]; - verts[3].s = sLeft; - verts[3].t = tBot; - - u_upload_unmap(st->uploader); - - cso_set_vertex_buffers(st->cso_context, - cso_get_aux_vertex_buffer_slot(st->cso_context), - 1, &vb); - - cso_draw_arrays(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4); - restore_render_state(ctx); - pipe_resource_reference(&vb.buffer, NULL); - /* We uploaded modified constants, need to invalidate them. */ st->dirty.mesa |= _NEW_PROGRAM_CONSTANTS; } diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 5c632c0b146..9fc22e68f4b 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -44,6 +44,7 @@ #include "st_cb_bitmap.h" #include "st_cb_clear.h" #include "st_cb_fbo.h" +#include "st_draw.h" #include "st_format.h" #include "st_program.h" @@ -55,7 +56,6 @@ #include "util/u_framebuffer.h" #include "util/u_inlines.h" #include "util/u_simple_shaders.h" -#include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" @@ -167,77 +167,6 @@ set_vertex_shader_layered(struct st_context *st) } -/** - * Draw a screen-aligned quadrilateral. - * Coords are clip coords with y=0=bottom. - */ -static void -draw_quad(struct st_context *st, - float x0, float y0, float x1, float y1, GLfloat z, - unsigned num_instances, - const union pipe_color_union *color) -{ - struct cso_context *cso = st->cso_context; - struct pipe_vertex_buffer vb = {0}; - struct st_util_vertex *verts; - - vb.stride = sizeof(struct st_util_vertex); - - u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4, - &vb.buffer_offset, &vb.buffer, (void **) &verts); - if (!vb.buffer) { - return; - } - - /* Convert Z from [0,1] to [-1,1] range */ - z = z * 2.0f - 1.0f; - - /* Note: if we're only clearing depth/stencil we still setup vertices - * with color, but they'll be ignored. - */ - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[0].r = color->f[0]; - verts[0].g = color->f[1]; - verts[0].b = color->f[2]; - verts[0].a = color->f[3]; - - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[1].r = color->f[0]; - verts[1].g = color->f[1]; - verts[1].b = color->f[2]; - verts[1].a = color->f[3]; - - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[2].r = color->f[0]; - verts[2].g = color->f[1]; - verts[2].b = color->f[2]; - verts[2].a = color->f[3]; - - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - verts[3].r = color->f[0]; - verts[3].g = color->f[1]; - verts[3].b = color->f[2]; - verts[3].a = color->f[3]; - - u_upload_unmap(st->uploader); - - /* draw */ - cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb); - cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4, - 0, num_instances); - pipe_resource_reference(&vb.buffer, NULL); -} - - - /** * Do glClear by drawing a quadrilateral. * The vertices of the quad will be computed from the @@ -368,13 +297,21 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) else set_vertex_shader(st); - /* We can't translate the clear color to the colorbuffer format, + /* draw quad matching scissor rect. + * + * Note: if we're only clearing depth/stencil we still setup vertices + * with color, but they'll be ignored. + * + * We can't translate the clear color to the colorbuffer format, * because different colorbuffers may have different formats. */ - - /* draw quad matching scissor rect */ - draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers, - (union pipe_color_union*)&ctx->Color.ClearColor); + if (!st_draw_quad(st, x0, y0, x1, y1, + ctx->Depth.Clear * 2.0f - 1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + (const float *) &ctx->Color.ClearColor.f, + num_layers)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear"); + } /* Restore pipe state */ cso_restore_blend(st->cso_context); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 565a10bc1b2..acaf926f093 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -56,6 +56,7 @@ #include "st_cb_fbo.h" #include "st_context.h" #include "st_debug.h" +#include "st_draw.h" #include "st_format.h" #include "st_program.h" #include "st_texture.h" @@ -67,7 +68,6 @@ #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_tile.h" -#include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" @@ -440,100 +440,6 @@ make_texture(struct st_context *st, } -/** - * Draw quad with texcoords and optional color. - * Coords are gallium window coords with y=0=top. - * \param color may be null - * \param invertTex if true, flip texcoords vertically - */ -static void -draw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z, - GLfloat x1, GLfloat y1, const GLfloat *color, - GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord) -{ - struct st_context *st = st_context(ctx); - struct pipe_vertex_buffer vb = {0}; - struct st_util_vertex *verts; - - vb.stride = sizeof(struct st_util_vertex); - - u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4, - &vb.buffer_offset, &vb.buffer, (void **) &verts); - if (!vb.buffer) { - return; - } - - /* setup vertex data */ - { - const struct gl_framebuffer *fb = st->ctx->DrawBuffer; - const GLfloat fb_width = (GLfloat) fb->Width; - const GLfloat fb_height = (GLfloat) fb->Height; - const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f; - const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f; - const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f; - const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f; - const GLfloat sLeft = 0.0f, sRight = maxXcoord; - const GLfloat tTop = invertTex ? maxYcoord : 0.0f; - const GLfloat tBot = invertTex ? 0.0f : maxYcoord; - - /* upper-left */ - verts[0].x = clip_x0; - verts[0].y = clip_y0; - verts[0].z = z; - verts[0].r = color[0]; - verts[0].g = color[1]; - verts[0].b = color[2]; - verts[0].a = color[3]; - verts[0].s = sLeft; - verts[0].t = tTop; - - /* upper-right */ - verts[1].x = clip_x1; - verts[1].y = clip_y0; - verts[1].z = z; - verts[1].r = color[0]; - verts[1].g = color[1]; - verts[1].b = color[2]; - verts[1].a = color[3]; - verts[1].s = sRight; - verts[1].t = tTop; - - /* lower-right */ - verts[2].x = clip_x1; - verts[2].y = clip_y1; - verts[2].z = z; - verts[2].r = color[0]; - verts[2].g = color[1]; - verts[2].b = color[2]; - verts[2].a = color[3]; - verts[2].s = sRight; - verts[2].t = tBot; - - /* lower-left */ - verts[3].x = clip_x0; - verts[3].y = clip_y1; - verts[3].z = z; - verts[3].r = color[0]; - verts[3].g = color[1]; - verts[3].b = color[2]; - verts[3].a = color[3]; - verts[3].s = sLeft; - verts[3].t = tBot; - } - - u_upload_unmap(st->uploader); - - cso_set_vertex_buffers(st->cso_context, - cso_get_aux_vertex_buffer_slot(st->cso_context), - 1, &vb); - - cso_draw_arrays(st->cso_context, PIPE_PRIM_QUADS, 0, 4); - - pipe_resource_reference(&vb.buffer, NULL); -} - - - static void draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, @@ -723,9 +629,27 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */ z = z * 2.0f - 1.0f; - draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, - normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width, - normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height); + { + const struct gl_framebuffer *fb = ctx->DrawBuffer; + const float fb_width = (float) fb->Width; + const float fb_height = (float) fb->Height; + const float clip_x0 = x0 / fb_width * 2.0f - 1.0f; + const float clip_y0 = y0 / fb_height * 2.0f - 1.0f; + const float clip_x1 = x1 / fb_width * 2.0f - 1.0f; + const float clip_y1 = y1 / fb_height * 2.0f - 1.0f; + const float maxXcoord = normalized ? + ((float) width / sv[0]->texture->width0) : (float) width; + const float maxYcoord = normalized + ? ((float) height / sv[0]->texture->height0) : (float) height; + const float sLeft = 0.0f, sRight = maxXcoord; + const float tTop = invertTex ? maxYcoord : 0.0f; + const float tBot = invertTex ? 0.0f : maxYcoord; + + if (!st_draw_quad(ctx->st, clip_x0, clip_y0, clip_x1, clip_y1, z, + sLeft, tBot, sRight, tTop, color, 0)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); + } + } /* restore state */ cso_restore_rasterizer(cso); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 1cc9e9615e3..2de6620602d 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -398,3 +398,93 @@ st_destroy_draw(struct st_context *st) { draw_destroy(st->draw); } + + +/** + * Draw a quad with given position, texcoords and color. + */ +bool +st_draw_quad(struct st_context *st, + float x0, float y0, float x1, float y1, float z, + float s0, float t0, float s1, float t1, + const float *color, + unsigned num_instances) +{ + struct pipe_vertex_buffer vb = {0}; + struct st_util_vertex *verts; + + vb.stride = sizeof(struct st_util_vertex); + + u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4, + &vb.buffer_offset, &vb.buffer, (void **) &verts); + if (!vb.buffer) { + return false; + } + + /* lower-left */ + verts[0].x = x0; + verts[0].y = y1; + verts[0].z = z; + verts[0].r = color[0]; + verts[0].g = color[1]; + verts[0].b = color[2]; + verts[0].a = color[3]; + verts[0].s = s0; + verts[0].t = t0; + + /* lower-right */ + verts[1].x = x1; + verts[1].y = y1; + verts[1].z = z; + verts[1].r = color[0]; + verts[1].g = color[1]; + verts[1].b = color[2]; + verts[1].a = color[3]; + verts[1].s = s1; + verts[1].t = t0; + + /* upper-right */ + verts[2].x = x1; + verts[2].y = y0; + verts[2].z = z; + verts[2].r = color[0]; + verts[2].g = color[1]; + verts[2].b = color[2]; + verts[2].a = color[3]; + verts[2].s = s1; + verts[2].t = t1; + + /* upper-left */ + verts[3].x = x0; + verts[3].y = y0; + verts[3].z = z; + verts[3].r = color[0]; + verts[3].g = color[1]; + verts[3].b = color[2]; + verts[3].a = color[3]; + verts[3].s = s0; + verts[3].t = t1; + + u_upload_unmap(st->uploader); + + /* At the time of writing, cso_get_aux_vertex_buffer_slot() always returns + * zero. If that ever changes we need to audit the calls to that function + * and make sure the slot number is used consistently everywhere. + */ + assert(cso_get_aux_vertex_buffer_slot(st->cso_context) == 0); + + cso_set_vertex_buffers(st->cso_context, + cso_get_aux_vertex_buffer_slot(st->cso_context), + 1, &vb); + + if (num_instances > 1) { + cso_draw_arrays_instanced(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4, + 0, num_instances); + } else { + cso_draw_arrays(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4); + } + + pipe_resource_reference(&vb.buffer, NULL); + + return true; +} diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h index a973c8a4a5d..d85c3b7facd 100644 --- a/src/mesa/state_tracker/st_draw.h +++ b/src/mesa/state_tracker/st_draw.h @@ -85,4 +85,11 @@ pointer_to_offset(const void *ptr) } +bool +st_draw_quad(struct st_context *st, + float x0, float y0, float x1, float y1, float z, + float s0, float t0, float s1, float t1, + const float *color, + unsigned num_instances); + #endif -- 2.30.2