Home | History | Annotate | Download | only in state_tracker
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 VMware, Inc.
      4  * All Rights Reserved.
      5  * Copyright 2009 VMware, Inc.  All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29  /*
     30   * Authors:
     31   *   Keith Whitwell <keithw (at) vmware.com>
     32   *   Brian Paul
     33   *   Michel Dnzer
     34   */
     35 
     36 #include "main/glheader.h"
     37 #include "main/accum.h"
     38 #include "main/formats.h"
     39 #include "main/framebuffer.h"
     40 #include "main/macros.h"
     41 #include "main/glformats.h"
     42 #include "program/prog_instruction.h"
     43 #include "st_context.h"
     44 #include "st_atom.h"
     45 #include "st_cb_bitmap.h"
     46 #include "st_cb_clear.h"
     47 #include "st_cb_fbo.h"
     48 #include "st_draw.h"
     49 #include "st_format.h"
     50 #include "st_program.h"
     51 
     52 #include "pipe/p_context.h"
     53 #include "pipe/p_shader_tokens.h"
     54 #include "pipe/p_state.h"
     55 #include "pipe/p_defines.h"
     56 #include "util/u_format.h"
     57 #include "util/u_inlines.h"
     58 #include "util/u_simple_shaders.h"
     59 
     60 #include "cso_cache/cso_context.h"
     61 
     62 
     63 /**
     64  * Do per-context initialization for glClear.
     65  */
     66 void
     67 st_init_clear(struct st_context *st)
     68 {
     69    memset(&st->clear, 0, sizeof(st->clear));
     70 
     71    st->clear.raster.half_pixel_center = 1;
     72    st->clear.raster.bottom_edge_rule = 1;
     73    st->clear.raster.depth_clip = 1;
     74 }
     75 
     76 
     77 /**
     78  * Free per-context state for glClear.
     79  */
     80 void
     81 st_destroy_clear(struct st_context *st)
     82 {
     83    if (st->clear.fs) {
     84       cso_delete_fragment_shader(st->cso_context, st->clear.fs);
     85       st->clear.fs = NULL;
     86    }
     87    if (st->clear.vs) {
     88       cso_delete_vertex_shader(st->cso_context, st->clear.vs);
     89       st->clear.vs = NULL;
     90    }
     91    if (st->clear.vs_layered) {
     92       cso_delete_vertex_shader(st->cso_context, st->clear.vs_layered);
     93       st->clear.vs_layered = NULL;
     94    }
     95    if (st->clear.gs_layered) {
     96       cso_delete_geometry_shader(st->cso_context, st->clear.gs_layered);
     97       st->clear.gs_layered = NULL;
     98    }
     99 }
    100 
    101 
    102 /**
    103  * Helper function to set the fragment shaders.
    104  */
    105 static inline void
    106 set_fragment_shader(struct st_context *st)
    107 {
    108    if (!st->clear.fs)
    109       st->clear.fs =
    110          util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_GENERIC,
    111                                                TGSI_INTERPOLATE_CONSTANT,
    112                                                TRUE);
    113 
    114    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
    115 }
    116 
    117 
    118 /**
    119  * Helper function to set the vertex shader.
    120  */
    121 static inline void
    122 set_vertex_shader(struct st_context *st)
    123 {
    124    /* vertex shader - still required to provide the linkage between
    125     * fragment shader input semantics and vertex_element/buffers.
    126     */
    127    if (!st->clear.vs)
    128    {
    129       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
    130                                       TGSI_SEMANTIC_GENERIC };
    131       const uint semantic_indexes[] = { 0, 0 };
    132       st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
    133                                                          semantic_names,
    134                                                          semantic_indexes,
    135                                                          FALSE);
    136    }
    137 
    138    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
    139    cso_set_geometry_shader_handle(st->cso_context, NULL);
    140 }
    141 
    142 
    143 static void
    144 set_vertex_shader_layered(struct st_context *st)
    145 {
    146    struct pipe_context *pipe = st->pipe;
    147 
    148    if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID)) {
    149       assert(!"Got layered clear, but VS instancing is unsupported");
    150       set_vertex_shader(st);
    151       return;
    152    }
    153 
    154    if (!st->clear.vs_layered) {
    155       bool vs_layer =
    156          pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT);
    157       if (vs_layer) {
    158          st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
    159       } else {
    160          st->clear.vs_layered = util_make_layered_clear_helper_vertex_shader(pipe);
    161          st->clear.gs_layered = util_make_layered_clear_geometry_shader(pipe);
    162       }
    163    }
    164 
    165    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered);
    166    cso_set_geometry_shader_handle(st->cso_context, st->clear.gs_layered);
    167 }
    168 
    169 
    170 /**
    171  * Do glClear by drawing a quadrilateral.
    172  * The vertices of the quad will be computed from the
    173  * ctx->DrawBuffer->_X/Ymin/max fields.
    174  */
    175 static void
    176 clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
    177 {
    178    struct st_context *st = st_context(ctx);
    179    struct cso_context *cso = st->cso_context;
    180    const struct gl_framebuffer *fb = ctx->DrawBuffer;
    181    const GLfloat fb_width = (GLfloat) fb->Width;
    182    const GLfloat fb_height = (GLfloat) fb->Height;
    183 
    184    _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
    185 
    186    const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
    187    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
    188    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
    189    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
    190    unsigned num_layers = st->state.fb_num_layers;
    191 
    192    /*
    193    printf("%s %s%s%s %f,%f %f,%f\n", __func__,
    194 	  color ? "color, " : "",
    195 	  depth ? "depth, " : "",
    196 	  stencil ? "stencil" : "",
    197 	  x0, y0,
    198 	  x1, y1);
    199    */
    200 
    201    cso_save_state(cso, (CSO_BIT_BLEND |
    202                         CSO_BIT_STENCIL_REF |
    203                         CSO_BIT_DEPTH_STENCIL_ALPHA |
    204                         CSO_BIT_RASTERIZER |
    205                         CSO_BIT_SAMPLE_MASK |
    206                         CSO_BIT_MIN_SAMPLES |
    207                         CSO_BIT_VIEWPORT |
    208                         CSO_BIT_STREAM_OUTPUTS |
    209                         CSO_BIT_VERTEX_ELEMENTS |
    210                         CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
    211                         CSO_BIT_PAUSE_QUERIES |
    212                         CSO_BITS_ALL_SHADERS));
    213 
    214    /* blend state: RGBA masking */
    215    {
    216       struct pipe_blend_state blend;
    217       memset(&blend, 0, sizeof(blend));
    218       if (clear_buffers & PIPE_CLEAR_COLOR) {
    219          int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
    220                            ctx->DrawBuffer->_NumColorDrawBuffers : 1;
    221          int i;
    222 
    223          blend.independent_blend_enable = num_buffers > 1;
    224 
    225          for (i = 0; i < num_buffers; i++) {
    226             if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
    227                continue;
    228 
    229             if (ctx->Color.ColorMask[i][0])
    230                blend.rt[i].colormask |= PIPE_MASK_R;
    231             if (ctx->Color.ColorMask[i][1])
    232                blend.rt[i].colormask |= PIPE_MASK_G;
    233             if (ctx->Color.ColorMask[i][2])
    234                blend.rt[i].colormask |= PIPE_MASK_B;
    235             if (ctx->Color.ColorMask[i][3])
    236                blend.rt[i].colormask |= PIPE_MASK_A;
    237          }
    238 
    239          if (ctx->Color.DitherFlag)
    240             blend.dither = 1;
    241       }
    242       cso_set_blend(cso, &blend);
    243    }
    244 
    245    /* depth_stencil state: always pass/set to ref value */
    246    {
    247       struct pipe_depth_stencil_alpha_state depth_stencil;
    248       memset(&depth_stencil, 0, sizeof(depth_stencil));
    249       if (clear_buffers & PIPE_CLEAR_DEPTH) {
    250          depth_stencil.depth.enabled = 1;
    251          depth_stencil.depth.writemask = 1;
    252          depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
    253       }
    254 
    255       if (clear_buffers & PIPE_CLEAR_STENCIL) {
    256          struct pipe_stencil_ref stencil_ref;
    257          memset(&stencil_ref, 0, sizeof(stencil_ref));
    258          depth_stencil.stencil[0].enabled = 1;
    259          depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
    260          depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
    261          depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
    262          depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
    263          depth_stencil.stencil[0].valuemask = 0xff;
    264          depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
    265          stencil_ref.ref_value[0] = ctx->Stencil.Clear;
    266          cso_set_stencil_ref(cso, &stencil_ref);
    267       }
    268 
    269       cso_set_depth_stencil_alpha(cso, &depth_stencil);
    270    }
    271 
    272    cso_set_vertex_elements(cso, 2, st->util_velems);
    273    cso_set_stream_outputs(cso, 0, NULL, NULL);
    274    cso_set_sample_mask(cso, ~0);
    275    cso_set_min_samples(cso, 1);
    276    cso_set_rasterizer(cso, &st->clear.raster);
    277 
    278    /* viewport state: viewport matching window dims */
    279    cso_set_viewport_dims(st->cso_context, fb_width, fb_height,
    280                          st_fb_orientation(fb) == Y_0_TOP);
    281 
    282    set_fragment_shader(st);
    283    cso_set_tessctrl_shader_handle(cso, NULL);
    284    cso_set_tesseval_shader_handle(cso, NULL);
    285 
    286    if (num_layers > 1)
    287       set_vertex_shader_layered(st);
    288    else
    289       set_vertex_shader(st);
    290 
    291    /* draw quad matching scissor rect.
    292     *
    293     * Note: if we're only clearing depth/stencil we still setup vertices
    294     * with color, but they'll be ignored.
    295     *
    296     * We can't translate the clear color to the colorbuffer format,
    297     * because different colorbuffers may have different formats.
    298     */
    299    if (!st_draw_quad(st, x0, y0, x1, y1,
    300                      ctx->Depth.Clear * 2.0f - 1.0f,
    301                      0.0f, 0.0f, 0.0f, 0.0f,
    302                      (const float *) &ctx->Color.ClearColor.f,
    303                      num_layers)) {
    304       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear");
    305    }
    306 
    307    /* Restore pipe state */
    308    cso_restore_state(cso);
    309 }
    310 
    311 
    312 /**
    313  * Return if the scissor must be enabled during the clear.
    314  */
    315 static inline GLboolean
    316 is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
    317 {
    318    const struct gl_scissor_rect *scissor = &ctx->Scissor.ScissorArray[0];
    319 
    320    return (ctx->Scissor.EnableFlags & 1) &&
    321           (scissor->X > 0 ||
    322            scissor->Y > 0 ||
    323            scissor->X + scissor->Width < (int)rb->Width ||
    324            scissor->Y + scissor->Height < (int)rb->Height);
    325 }
    326 
    327 /**
    328  * Return if window rectangles must be enabled during the clear.
    329  */
    330 static inline bool
    331 is_window_rectangle_enabled(struct gl_context *ctx)
    332 {
    333    if (ctx->DrawBuffer == ctx->WinSysDrawBuffer)
    334       return false;
    335    return ctx->Scissor.NumWindowRects > 0 ||
    336       ctx->Scissor.WindowRectMode == GL_INCLUSIVE_EXT;
    337 }
    338 
    339 
    340 /**
    341  * Return if all of the color channels are masked.
    342  */
    343 static inline GLboolean
    344 is_color_disabled(struct gl_context *ctx, int i)
    345 {
    346    return !ctx->Color.ColorMask[i][0] &&
    347           !ctx->Color.ColorMask[i][1] &&
    348           !ctx->Color.ColorMask[i][2] &&
    349           !ctx->Color.ColorMask[i][3];
    350 }
    351 
    352 
    353 /**
    354  * Return if any of the color channels are masked.
    355  */
    356 static inline GLboolean
    357 is_color_masked(struct gl_context *ctx, int i)
    358 {
    359    return !ctx->Color.ColorMask[i][0] ||
    360           !ctx->Color.ColorMask[i][1] ||
    361           !ctx->Color.ColorMask[i][2] ||
    362           !ctx->Color.ColorMask[i][3];
    363 }
    364 
    365 
    366 /**
    367  * Return if all of the stencil bits are masked.
    368  */
    369 static inline GLboolean
    370 is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
    371 {
    372    const GLuint stencilMax = 0xff;
    373 
    374    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
    375    return (ctx->Stencil.WriteMask[0] & stencilMax) == 0;
    376 }
    377 
    378 
    379 /**
    380  * Return if any of the stencil bits are masked.
    381  */
    382 static inline GLboolean
    383 is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb)
    384 {
    385    const GLuint stencilMax = 0xff;
    386 
    387    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
    388    return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
    389 }
    390 
    391 
    392 /**
    393  * Called via ctx->Driver.Clear()
    394  */
    395 static void
    396 st_Clear(struct gl_context *ctx, GLbitfield mask)
    397 {
    398    struct st_context *st = st_context(ctx);
    399    struct gl_renderbuffer *depthRb
    400       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
    401    struct gl_renderbuffer *stencilRb
    402       = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
    403    GLbitfield quad_buffers = 0x0;
    404    GLbitfield clear_buffers = 0x0;
    405    GLuint i;
    406 
    407    st_flush_bitmap_cache(st);
    408    st_invalidate_readpix_cache(st);
    409 
    410    /* This makes sure the pipe has the latest scissor, etc values */
    411    st_validate_state(st, ST_PIPELINE_CLEAR);
    412 
    413    if (mask & BUFFER_BITS_COLOR) {
    414       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
    415          gl_buffer_index b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
    416 
    417          if (b != BUFFER_NONE && mask & (1 << b)) {
    418             struct gl_renderbuffer *rb
    419                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
    420             struct st_renderbuffer *strb = st_renderbuffer(rb);
    421             int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0;
    422 
    423             if (!strb || !strb->surface)
    424                continue;
    425 
    426             if (is_color_disabled(ctx, colormask_index))
    427                continue;
    428 
    429             if (is_scissor_enabled(ctx, rb) ||
    430                 is_window_rectangle_enabled(ctx) ||
    431                 is_color_masked(ctx, colormask_index))
    432                quad_buffers |= PIPE_CLEAR_COLOR0 << i;
    433             else
    434                clear_buffers |= PIPE_CLEAR_COLOR0 << i;
    435          }
    436       }
    437    }
    438 
    439    if (mask & BUFFER_BIT_DEPTH) {
    440       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
    441 
    442       if (strb->surface && ctx->Depth.Mask) {
    443          if (is_scissor_enabled(ctx, depthRb) ||
    444              is_window_rectangle_enabled(ctx))
    445             quad_buffers |= PIPE_CLEAR_DEPTH;
    446          else
    447             clear_buffers |= PIPE_CLEAR_DEPTH;
    448       }
    449    }
    450    if (mask & BUFFER_BIT_STENCIL) {
    451       struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
    452 
    453       if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
    454          if (is_scissor_enabled(ctx, stencilRb) ||
    455              is_window_rectangle_enabled(ctx) ||
    456              is_stencil_masked(ctx, stencilRb))
    457             quad_buffers |= PIPE_CLEAR_STENCIL;
    458          else
    459             clear_buffers |= PIPE_CLEAR_STENCIL;
    460       }
    461    }
    462 
    463    /* Always clear depth and stencil together.
    464     * This can only happen when the stencil writemask is not a full mask.
    465     */
    466    if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL &&
    467        clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
    468       quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL;
    469       clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
    470    }
    471 
    472    /* Only use quad-based clearing for the renderbuffers which cannot
    473     * use pipe->clear. We want to always use pipe->clear for the other
    474     * renderbuffers, because it's likely to be faster.
    475     */
    476    if (quad_buffers) {
    477       clear_with_quad(ctx, quad_buffers);
    478    }
    479    if (clear_buffers) {
    480       /* We can't translate the clear color to the colorbuffer format,
    481        * because different colorbuffers may have different formats.
    482        */
    483       st->pipe->clear(st->pipe, clear_buffers,
    484                       (union pipe_color_union*)&ctx->Color.ClearColor,
    485                       ctx->Depth.Clear, ctx->Stencil.Clear);
    486    }
    487    if (mask & BUFFER_BIT_ACCUM)
    488       _mesa_clear_accum_buffer(ctx);
    489 }
    490 
    491 
    492 void
    493 st_init_clear_functions(struct dd_function_table *functions)
    494 {
    495    functions->Clear = st_Clear;
    496 }
    497