X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_clear.c;h=887e58bd9b6840b538a40feb048550e21cf28351;hb=84732a982c3eeaca2e2809532c8422dc5f7045c1;hp=36510720a4c1f37d196cc19052bd702d10bf8d6e;hpb=57e3eb1b178e861dee7695c9a5e1c71a4333192d;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..887e58bd9b6 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -34,57 +34,49 @@ */ #include "main/glheader.h" +#include "main/accum.h" +#include "main/formats.h" #include "main/macros.h" -#include "shader/prog_instruction.h" +#include "main/glformats.h" +#include "program/prog_instruction.h" #include "st_context.h" #include "st_atom.h" -#include "st_cb_accum.h" #include "st_cb_clear.h" #include "st_cb_fbo.h" -#include "st_draw.h" +#include "st_format.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_shader_tokens.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_framebuffer.h" +#include "util/u_inlines.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" +#include "util/u_upload_mgr.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; - - /* rasterizer state: bypass vertex shader, clipping and viewport */ - st->clear.raster.bypass_vs_clip_and_viewport = 1; - - /* fragment shader state: color pass-through program */ - st->clear.fs = - util_make_fragment_passthrough_shader(pipe); + memset(&st->clear, 0, sizeof(st->clear)); - /* vertex shader state: color/position pass-through */ - { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_COLOR }; - const uint semantic_indexes[] = { 0, 0 }; - st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2, - semantic_names, - semantic_indexes); - } + st->clear.raster.half_pixel_center = 1; + st->clear.raster.bottom_edge_rule = 1; + st->clear.raster.depth_clip = 1; } +/** + * Free per-context state for glClear. + */ void st_destroy_clear(struct st_context *st) { @@ -96,89 +88,121 @@ st_destroy_clear(struct st_context *st) cso_delete_vertex_shader(st->cso_context, st->clear.vs); st->clear.vs = NULL; } - if (st->clear.vbuf) { - pipe_buffer_reference(&st->clear.vbuf, NULL); - st->clear.vbuf = NULL; +} + + +/** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct st_context *st) +{ + if (!st->clear.fs) + st->clear.fs = + util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_GENERIC, + TGSI_INTERPOLATE_CONSTANT, + TRUE); + + cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct st_context *st) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!st->clear.vs) + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); +} + + +static void +set_vertex_shader_layered(struct st_context *st) +{ + struct pipe_context *pipe = st->pipe; + + if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) || + !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) { + assert(!"Got layered clear, but the VS layer output is unsupported"); + set_vertex_shader(st); + return; + } + + if (!st->clear.vs_layered) { + st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe); } + + cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered); } /** * 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]) + unsigned num_instances, + const union pipe_color_union *color) { - 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 - * no_flush) updates to buffers where we know there is no conflict - * with previous data. Currently using max_slots > 1 will cause - * synchronous rendering if the driver flushes its command buffers - * between one bitmap and the next. Our flush hook below isn't - * sufficient to catch this as the driver doesn't tell us when it - * flushes its own command buffers. Until this gets fixed, pay the - * price of allocating a new buffer for each bitmap cache-flush to - * avoid synchronous rendering. - */ - const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */ + struct cso_context *cso = st->cso_context; + struct pipe_vertex_buffer vb = {0}; GLuint i; + float (*vertices)[2][4]; /**< vertex pos + color */ - if (st->clear.vbuf_slot >= max_slots) { - pipe_buffer_reference(&st->clear.vbuf, NULL); - st->clear.vbuf_slot = 0; - } + vb.stride = 8 * sizeof(float); - if (!st->clear.vbuf) { - st->clear.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, - max_slots * sizeof(st->clear.vertices)); + if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), + &vb.buffer_offset, &vb.buffer, + (void **) &vertices) != PIPE_OK) { + return; } /* positions */ - st->clear.vertices[0][0][0] = x0; - st->clear.vertices[0][0][1] = y0; + vertices[0][0][0] = x0; + vertices[0][0][1] = y0; - st->clear.vertices[1][0][0] = x1; - st->clear.vertices[1][0][1] = y0; + vertices[1][0][0] = x1; + vertices[1][0][1] = y0; - st->clear.vertices[2][0][0] = x1; - st->clear.vertices[2][0][1] = y1; + vertices[2][0][0] = x1; + vertices[2][0][1] = y1; - st->clear.vertices[3][0][0] = x0; - st->clear.vertices[3][0][1] = y1; + vertices[3][0][0] = x0; + vertices[3][0][1] = y1; /* same for all verts: */ for (i = 0; i < 4; i++) { - st->clear.vertices[i][0][2] = z; - st->clear.vertices[i][0][3] = 1.0; - st->clear.vertices[i][1][0] = color[0]; - st->clear.vertices[i][1][1] = color[1]; - st->clear.vertices[i][1][2] = color[2]; - st->clear.vertices[i][1][3] = color[3]; + vertices[i][0][2] = z; + vertices[i][0][3] = 1.0; + vertices[i][1][0] = color->f[0]; + vertices[i][1][1] = color->f[1]; + vertices[i][1][2] = color->f[2]; + vertices[i][1][3] = color->f[3]; } - /* 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); + u_upload_unmap(st->uploader); /* draw */ - util_draw_vertex_buffer(pipe, - st->clear.vbuf, - st->clear.vbuf_slot * sizeof(st->clear.vertices), - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 2); /* attribs/vert */ - - /* Increment slot */ - st->clear.vbuf_slot++; + 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); } @@ -189,22 +213,18 @@ draw_quad(GLcontext *ctx, * ctx->DrawBuffer->_X/Ymin/max fields. */ static void -clear_with_quad(GLcontext *ctx, - GLboolean color, GLboolean depth, GLboolean stencil) +clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) { - 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; + unsigned num_layers = + util_framebuffer_get_num_layers(&st->state.framebuffer); /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, @@ -216,28 +236,43 @@ 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_sample_mask(st->cso_context); + cso_save_viewport(st->cso_context); cso_save_fragment_shader(st->cso_context); + cso_save_stream_outputs(st->cso_context); cso_save_vertex_shader(st->cso_context); + cso_save_geometry_shader(st->cso_context); + cso_save_vertex_elements(st->cso_context); + cso_save_aux_vertex_buffer_slot(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; - 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 (clear_buffers & PIPE_CLEAR_COLOR) { + int num_buffers = ctx->Extensions.EXT_draw_buffers2 ? + ctx->DrawBuffer->_NumColorDrawBuffers : 1; + int i; + + blend.independent_blend_enable = num_buffers > 1; + + for (i = 0; i < num_buffers; i++) { + if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i))) + continue; + + if (ctx->Color.ColorMask[i][0]) + blend.rt[i].colormask |= PIPE_MASK_R; + if (ctx->Color.ColorMask[i][1]) + blend.rt[i].colormask |= PIPE_MASK_G; + if (ctx->Color.ColorMask[i][2]) + blend.rt[i].colormask |= PIPE_MASK_B; + if (ctx->Color.ColorMask[i][3]) + blend.rt[i].colormask |= PIPE_MASK_A; + } + if (st->ctx->Color.DitherFlag) blend.dither = 1; } @@ -248,174 +283,147 @@ clear_with_quad(GLcontext *ctx, { struct pipe_depth_stencil_alpha_state depth_stencil; memset(&depth_stencil, 0, sizeof(depth_stencil)); - if (depth) { + if (clear_buffers & PIPE_CLEAR_DEPTH) { depth_stencil.depth.enabled = 1; depth_stencil.depth.writemask = 1; depth_stencil.depth.func = PIPE_FUNC_ALWAYS; } - if (stencil) { + if (clear_buffers & PIPE_CLEAR_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_stream_outputs(st->cso_context, 0, NULL, 0); + cso_set_sample_mask(st->cso_context, ~0); cso_set_rasterizer(st->cso_context, &st->clear.raster); - cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); - cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); + /* 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); + } + + set_fragment_shader(st); + cso_set_geometry_shader_handle(st->cso_context, NULL); + + if (num_layers > 1) + set_vertex_shader_layered(st); + else + set_vertex_shader(st); + + /* We can't translate the clear color to the colorbuffer format, + * because different colorbuffers may have different formats. + */ - /* 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 matching scissor rect */ + draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers, + (union pipe_color_union*)&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_sample_mask(st->cso_context); + cso_restore_viewport(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); + cso_restore_geometry_shader(st->cso_context); + cso_restore_vertex_elements(st->cso_context); + cso_restore_aux_vertex_buffer_slot(st->cso_context); + cso_restore_stream_outputs(st->cso_context); } /** - * Determine if we need to clear the depth buffer by drawing a quad. + * Return if the scissor must be enabled during the clear. */ static INLINE GLboolean -check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) +is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb) { - if (ctx->Scissor.Enabled && - (ctx->Scissor.X != 0 || - ctx->Scissor.Y != 0 || - ctx->Scissor.Width < rb->Width || - ctx->Scissor.Height < rb->Height)) - return TRUE; - - if (!ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3]) - return TRUE; - - return FALSE; + return ctx->Scissor.Enabled && + (ctx->Scissor.X > 0 || + ctx->Scissor.Y > 0 || + (unsigned) ctx->Scissor.Width < rb->Width || + (unsigned) ctx->Scissor.Height < rb->Height); } +/** + * Return if all of the color channels are masked. + */ static INLINE GLboolean -check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) +is_color_disabled(struct gl_context *ctx, int i) { - const GLuint stencilMax = (1 << rb->StencilBits) - 1; - GLboolean maskStencil - = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; - - if (ctx->Scissor.Enabled && - (ctx->Scissor.X != 0 || - ctx->Scissor.Y != 0 || - ctx->Scissor.Width < rb->Width || - ctx->Scissor.Height < rb->Height)) - return TRUE; - - if (maskStencil) - return TRUE; - - return FALSE; + return !ctx->Color.ColorMask[i][0] && + !ctx->Color.ColorMask[i][1] && + !ctx->Color.ColorMask[i][2] && + !ctx->Color.ColorMask[i][3]; } /** - * Determine if we need to clear the depth buffer by drawing a quad. + * Return if any of the color channels are masked. */ static INLINE GLboolean -check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) +is_color_masked(struct gl_context *ctx, int i) { - const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = pf_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; - - if (isDS && - ctx->DrawBuffer->Visual.stencilBits > 0) - return TRUE; - - return FALSE; + return !ctx->Color.ColorMask[i][0] || + !ctx->Color.ColorMask[i][1] || + !ctx->Color.ColorMask[i][2] || + !ctx->Color.ColorMask[i][3]; } /** - * Determine if we need to clear the stencil buffer by drawing a quad. + * Return if any of the stencil bits are masked. */ static INLINE GLboolean -check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) +is_stencil_masked(struct gl_context *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 maskStencil - = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; - - if (maskStencil) - return 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; - - /* 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; - - return FALSE; -} + const GLuint stencilMax = 0xff; - - -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); - st->clear.vbuf_slot = 0; + assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0); + return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; } - /** * 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(struct gl_context *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 */ @@ -428,55 +436,43 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) if (mask & (1 << b)) { struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; - struct st_renderbuffer *strb; - - assert(rb); + struct st_renderbuffer *strb = st_renderbuffer(rb); + int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0; - strb = st_renderbuffer(rb); + if (!strb || !strb->surface) + continue; - if (!strb->surface) + if (is_color_disabled(ctx, colormask_index)) continue; - if (check_clear_color_with_quad( ctx, rb )) - quad_buffers |= PIPE_CLEAR_COLOR; + if (is_scissor_enabled(ctx, rb) || + is_color_masked(ctx, colormask_index)) + quad_buffers |= PIPE_CLEAR_COLOR0 << i; else - clear_buffers |= PIPE_CLEAR_COLOR; + clear_buffers |= PIPE_CLEAR_COLOR0 << i; } } } - if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) { - /* clearing combined depth + stencil */ + if (mask & BUFFER_BIT_DEPTH) { struct st_renderbuffer *strb = st_renderbuffer(depthRb); if (strb->surface) { - if (check_clear_depth_stencil_with_quad(ctx, depthRb)) - quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + if (is_scissor_enabled(ctx, depthRb)) + quad_buffers |= PIPE_CLEAR_DEPTH; else - clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + clear_buffers |= PIPE_CLEAR_DEPTH; } } - else { - /* separate depth/stencil clears */ - if (mask & BUFFER_BIT_DEPTH) { - struct st_renderbuffer *strb = st_renderbuffer(depthRb); - - if (strb->surface) { - if (check_clear_depth_with_quad(ctx, depthRb)) - quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; - else - clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; - } - } - if (mask & BUFFER_BIT_STENCIL) { - struct st_renderbuffer *strb = st_renderbuffer(stencilRb); + if (mask & BUFFER_BIT_STENCIL) { + struct st_renderbuffer *strb = st_renderbuffer(stencilRb); - if (strb->surface) { - if (check_clear_stencil_with_quad(ctx, stencilRb)) - quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; - else - clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; - } + if (strb->surface) { + if (is_scissor_enabled(ctx, stencilRb) || + is_stencil_masked(ctx, stencilRb)) + quad_buffers |= PIPE_CLEAR_STENCIL; + else + clear_buffers |= PIPE_CLEAR_STENCIL; } } @@ -486,21 +482,22 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) */ if (quad_buffers) { quad_buffers |= clear_buffers; - clear_with_quad(ctx, - quad_buffers & PIPE_CLEAR_COLOR, - 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); - + clear_with_quad(ctx, quad_buffers); + } else if (clear_buffers) { + /* We can't translate the clear color to the colorbuffer format, + * because different colorbuffers may have different formats. + */ + st->pipe->clear(st->pipe, clear_buffers, + (union pipe_color_union*)&ctx->Color.ClearColor, + ctx->Depth.Clear, ctx->Stencil.Clear); + } if (mask & BUFFER_BIT_ACCUM) - st_clear_accum_buffer(ctx, - ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); + _mesa_clear_accum_buffer(ctx); } -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; }