X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_clear.c;h=7e3b87351f1fbdb98dd907a8f22da0ff74cd59f6;hb=b0427bedde80e3189524651a327235bdfddbc613;hp=e83b6c92efb7ed340a99df357fefdc86190ca0dc;hpb=48302e9b309c7ce218de2e522c91bdc87e61cdbc;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index e83b6c92efb..7e3b87351f1 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -42,37 +42,33 @@ #include "st_cb_accum.h" #include "st_cb_clear.h" #include "st_cb_fbo.h" -#include "st_draw.h" #include "st_program.h" -#include "st_public.h" -#include "st_mesa_to_tgsi.h" -#include "st_inlines.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_pack_color.h" +#include "util/u_format.h" +#include "util/u_inlines.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" #include "cso_cache/cso_context.h" +/** + * Do per-context initialization for glClear. + */ void st_init_clear(struct st_context *st) { struct pipe_context *pipe = st->pipe; - memset(&st->clear.raster, 0, sizeof(st->clear.raster)); - st->clear.raster.gl_rasterization_rules = 1; + memset(&st->clear, 0, sizeof(st->clear)); - /* rasterizer state: bypass vertex shader, clipping and viewport */ - st->clear.raster.bypass_vs_clip_and_viewport = 1; + st->clear.raster.gl_rasterization_rules = 1; /* fragment shader state: color pass-through program */ - st->clear.fs = - util_make_fragment_passthrough_shader(pipe); + st->clear.fs = util_make_fragment_passthrough_shader(pipe); /* vertex shader state: color/position pass-through */ { @@ -86,6 +82,9 @@ st_init_clear(struct st_context *st) } +/** + * Free per-context state for glClear. + */ void st_destroy_clear(struct st_context *st) { @@ -98,7 +97,7 @@ st_destroy_clear(struct st_context *st) st->clear.vs = NULL; } if (st->clear.vbuf) { - pipe_buffer_reference(&st->clear.vbuf, NULL); + pipe_resource_reference(&st->clear.vbuf, NULL); st->clear.vbuf = NULL; } } @@ -106,16 +105,13 @@ st_destroy_clear(struct st_context *st) /** * Draw a screen-aligned quadrilateral. - * Coords are window coords with y=0=bottom. These will be passed - * through unmodified to the rasterizer as we have set - * rasterizer->bypass_vs_clip_and_viewport. + * Coords are clip coords with y=0=bottom. */ static void -draw_quad(GLcontext *ctx, +draw_quad(struct st_context *st, float x0, float y0, float x1, float y1, GLfloat z, const GLfloat color[4]) { - struct st_context *st = ctx->st; struct pipe_context *pipe = st->pipe; /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as @@ -132,12 +128,13 @@ draw_quad(GLcontext *ctx, GLuint i; if (st->clear.vbuf_slot >= max_slots) { - pipe_buffer_reference(&st->clear.vbuf, NULL); + pipe_resource_reference(&st->clear.vbuf, NULL); st->clear.vbuf_slot = 0; } if (!st->clear.vbuf) { - st->clear.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, + st->clear.vbuf = pipe_buffer_create(pipe->screen, + PIPE_BIND_VERTEX_BUFFER, max_slots * sizeof(st->clear.vertices)); } @@ -165,10 +162,11 @@ draw_quad(GLcontext *ctx, } /* put vertex data into vbuf */ - st_no_flush_pipe_buffer_write(st, st->clear.vbuf, - st->clear.vbuf_slot * sizeof(st->clear.vertices), - sizeof(st->clear.vertices), - st->clear.vertices); + pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf, + st->clear.vbuf_slot + * sizeof(st->clear.vertices), + sizeof(st->clear.vertices), + st->clear.vertices); /* draw */ util_draw_vertex_buffer(pipe, @@ -193,19 +191,14 @@ static void clear_with_quad(GLcontext *ctx, GLboolean color, GLboolean depth, GLboolean stencil) { - struct st_context *st = ctx->st; - const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin; - const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax; - GLfloat y0, y1; - - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - y0 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax); - y1 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin); - } - else { - y0 = (GLfloat) ctx->DrawBuffer->_Ymin; - y1 = (GLfloat) ctx->DrawBuffer->_Ymax; - } + struct st_context *st = st_context(ctx); + const struct gl_framebuffer *fb = ctx->DrawBuffer; + const GLfloat fb_width = (GLfloat) fb->Width; + const GLfloat fb_height = (GLfloat) fb->Height; + const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f; + const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f; + const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; + const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, @@ -217,28 +210,32 @@ clear_with_quad(GLcontext *ctx, */ cso_save_blend(st->cso_context); + cso_save_stencil_ref(st->cso_context); cso_save_depth_stencil_alpha(st->cso_context); cso_save_rasterizer(st->cso_context); + cso_save_viewport(st->cso_context); + cso_save_clip(st->cso_context); cso_save_fragment_shader(st->cso_context); cso_save_vertex_shader(st->cso_context); + cso_save_vertex_elements(st->cso_context); /* blend state: RGBA masking */ { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (color) { - if (ctx->Color.ColorMask[0]) - blend.colormask |= PIPE_MASK_R; - if (ctx->Color.ColorMask[1]) - blend.colormask |= PIPE_MASK_G; - if (ctx->Color.ColorMask[2]) - blend.colormask |= PIPE_MASK_B; - if (ctx->Color.ColorMask[3]) - blend.colormask |= PIPE_MASK_A; + if (ctx->Color.ColorMask[0][0]) + blend.rt[0].colormask |= PIPE_MASK_R; + if (ctx->Color.ColorMask[0][1]) + blend.rt[0].colormask |= PIPE_MASK_G; + if (ctx->Color.ColorMask[0][2]) + blend.rt[0].colormask |= PIPE_MASK_B; + if (ctx->Color.ColorMask[0][3]) + blend.rt[0].colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend.dither = 1; } @@ -256,33 +253,59 @@ clear_with_quad(GLcontext *ctx, } if (stencil) { + struct pipe_stencil_ref stencil_ref; + memset(&stencil_ref, 0, sizeof(stencil_ref)); depth_stencil.stencil[0].enabled = 1; depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS; depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; - depth_stencil.stencil[0].ref_value = ctx->Stencil.Clear; depth_stencil.stencil[0].valuemask = 0xff; depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; + stencil_ref.ref_value[0] = ctx->Stencil.Clear; + cso_set_stencil_ref(st->cso_context, &stencil_ref); } cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil); } + cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw); + cso_set_rasterizer(st->cso_context, &st->clear.raster); + /* viewport state: viewport matching window dims */ + { + const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); + struct pipe_viewport_state vp; + vp.scale[0] = 0.5f * fb_width; + vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f); + vp.scale[2] = 1.0f; + vp.scale[3] = 1.0f; + vp.translate[0] = 0.5f * fb_width; + vp.translate[1] = 0.5f * fb_height; + vp.translate[2] = 0.0f; + vp.translate[3] = 0.0f; + cso_set_viewport(st->cso_context, &vp); + } + + cso_set_clip(st->cso_context, &st->clear.clip); cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); /* draw quad matching scissor rect (XXX verify coord round-off) */ - draw_quad(ctx, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor); + draw_quad(st, x0, y0, x1, y1, + (GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor); /* Restore pipe state */ cso_restore_blend(st->cso_context); + cso_restore_stencil_ref(st->cso_context); cso_restore_depth_stencil_alpha(st->cso_context); cso_restore_rasterizer(st->cso_context); + cso_restore_viewport(st->cso_context); + cso_restore_clip(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); + cso_restore_vertex_elements(st->cso_context); } @@ -297,18 +320,22 @@ check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) ctx->Scissor.Y != 0 || ctx->Scissor.Width < rb->Width || ctx->Scissor.Height < rb->Height)) - return TRUE; + return GL_TRUE; - if (!ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3]) - return TRUE; + if (!ctx->Color.ColorMask[0][0] || + !ctx->Color.ColorMask[0][1] || + !ctx->Color.ColorMask[0][2] || + !ctx->Color.ColorMask[0][3]) + return GL_TRUE; - return FALSE; + return GL_FALSE; } +/** + * Determine if we need to clear the combiend depth/stencil buffer by + * drawing a quad. + */ static INLINE GLboolean check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { @@ -325,12 +352,12 @@ check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) ctx->Scissor.Y != 0 || ctx->Scissor.Width < rb->Width || ctx->Scissor.Height < rb->Height)) - return TRUE; + return GL_TRUE; if (maskStencil) - return TRUE; + return GL_TRUE; - return FALSE; + return GL_FALSE; } @@ -341,20 +368,19 @@ static INLINE GLboolean check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format); + const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); if (ctx->Scissor.Enabled && (ctx->Scissor.X != 0 || ctx->Scissor.Y != 0 || ctx->Scissor.Width < rb->Width || ctx->Scissor.Height < rb->Height)) - return TRUE; + return GL_TRUE; - if (isDS && - ctx->DrawBuffer->Visual.stencilBits > 0) - return TRUE; + if (isDS && ctx->DrawBuffer->Visual.stencilBits > 0) + return GL_TRUE; - return FALSE; + return GL_FALSE; } @@ -365,7 +391,7 @@ static INLINE GLboolean check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format); + const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); const GLuint stencilMax = 0xff; const GLboolean maskStencil = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; @@ -375,35 +401,38 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) rb->Format == MESA_FORMAT_S8_Z24); if (maskStencil) - return TRUE; + return GL_TRUE; if (ctx->Scissor.Enabled && (ctx->Scissor.X != 0 || ctx->Scissor.Y != 0 || ctx->Scissor.Width < rb->Width || ctx->Scissor.Height < rb->Height)) - return TRUE; + return GL_TRUE; /* This is correct, but it is necessary to look at the depth clear * value held in the surface when it comes time to issue the clear, * rather than taking depth and stencil clear values from the * current state. */ - if (isDS && - ctx->DrawBuffer->Visual.depthBits > 0) - return TRUE; + if (isDS && ctx->DrawBuffer->Visual.depthBits > 0) + return GL_TRUE; - return FALSE; + return GL_FALSE; } -void st_flush_clear( struct st_context *st ) +/** + * Called when we need to flush. + */ +void +st_flush_clear(struct st_context *st) { /* Release vertex buffer to avoid synchronous rendering if we were * to map it in the next frame. */ - pipe_buffer_reference(&st->clear.vbuf, NULL); + pipe_resource_reference(&st->clear.vbuf, NULL); st->clear.vbuf_slot = 0; } @@ -411,20 +440,19 @@ void st_flush_clear( struct st_context *st ) /** * Called via ctx->Driver.Clear() - * XXX: doesn't pick up the differences between front/back/left/right - * clears. Need to sort that out... */ -static void st_clear(GLcontext *ctx, GLbitfield mask) +static void +st_Clear(GLcontext *ctx, GLbitfield mask) { static const GLbitfield BUFFER_BITS_DS = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); - struct st_context *st = ctx->st; + struct st_context *st = st_context(ctx); struct gl_renderbuffer *depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; struct gl_renderbuffer *stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; - GLbitfield quad_buffers = 0; - GLbitfield clear_buffers = 0; + GLbitfield quad_buffers = 0x0; + GLbitfield clear_buffers = 0x0; GLuint i; /* This makes sure the pipe has the latest scissor, etc values */ @@ -500,8 +528,8 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) mask & BUFFER_BIT_DEPTH, mask & BUFFER_BIT_STENCIL); } else if (clear_buffers) - ctx->st->pipe->clear(ctx->st->pipe, clear_buffers, ctx->Color.ClearColor, - ctx->Depth.Clear, ctx->Stencil.Clear); + st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor, + ctx->Depth.Clear, ctx->Stencil.Clear); if (mask & BUFFER_BIT_ACCUM) st_clear_accum_buffer(ctx, @@ -509,7 +537,8 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) } -void st_init_clear_functions(struct dd_function_table *functions) +void +st_init_clear_functions(struct dd_function_table *functions) { - functions->Clear = st_clear; + functions->Clear = st_Clear; }