X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_clear.c;h=eb9ba0557d3ac5816be7795fbb0fc7f523995fa2;hb=0203136e69bfa711edd69a4f69c4539cd877b5cb;hp=36510720a4c1f37d196cc19052bd702d10bf8d6e;hpb=ab9d1011f5549502a4b960c2067cde69856a2719;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 36510720a4c..eb9ba0557d3 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -34,6 +34,7 @@ */ #include "main/glheader.h" +#include "main/formats.h" #include "main/macros.h" #include "shader/prog_instruction.h" #include "st_context.h" @@ -41,37 +42,35 @@ #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 */ { @@ -85,6 +84,9 @@ st_init_clear(struct st_context *st) } +/** + * Free per-context state for glClear. + */ void st_destroy_clear(struct st_context *st) { @@ -97,7 +99,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; } } @@ -105,9 +107,7 @@ 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, @@ -131,12 +131,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)); } @@ -164,10 +165,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); + st_no_flush_pipe_buffer_write_nooverlap(st, 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,18 +195,13 @@ 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; - } + 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__, @@ -216,28 +213,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; } @@ -255,33 +256,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(ctx, 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); } @@ -296,36 +323,44 @@ 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) { - const GLuint stencilMax = (1 << rb->StencilBits) - 1; + const GLuint stencilMax = 0xff; GLboolean maskStencil = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; + assert(rb->Format == MESA_FORMAT_S8 || + rb->Format == MESA_FORMAT_Z24_S8 || + rb->Format == MESA_FORMAT_S8_Z24); + 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 (maskStencil) - return TRUE; + return GL_TRUE; - return FALSE; + return GL_FALSE; } @@ -336,20 +371,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; } @@ -360,41 +394,48 @@ 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 GLuint stencilMax = (1 << rb->StencilBits) - 1; + 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; + assert(rb->Format == MESA_FORMAT_S8 || + rb->Format == MESA_FORMAT_Z24_S8 || + 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; } @@ -402,10 +443,9 @@ 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); @@ -414,8 +454,8 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) = 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,7 +540,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; }