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/macros.h"
     40 #include "main/glformats.h"
     41 #include "program/prog_instruction.h"
     42 #include "st_context.h"
     43 #include "st_atom.h"
     44 #include "st_cb_bitmap.h"
     45 #include "st_cb_clear.h"
     46 #include "st_cb_fbo.h"
     47 #include "st_draw.h"
     48 #include "st_format.h"
     49 #include "st_program.h"
     50 
     51 #include "pipe/p_context.h"
     52 #include "pipe/p_shader_tokens.h"
     53 #include "pipe/p_state.h"
     54 #include "pipe/p_defines.h"
     55 #include "util/u_format.h"
     56 #include "util/u_framebuffer.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    const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
    184    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
    185    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
    186    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
    187    unsigned num_layers =
    188       util_framebuffer_get_num_layers(&st->state.framebuffer);
    189 
    190    /*
    191    printf("%s %s%s%s %f,%f %f,%f\n", __func__,
    192 	  color ? "color, " : "",
    193 	  depth ? "depth, " : "",
    194 	  stencil ? "stencil" : "",
    195 	  x0, y0,
    196 	  x1, y1);
    197    */
    198 
    199    cso_save_state(cso, (CSO_BIT_BLEND |
    200                         CSO_BIT_STENCIL_REF |
    201                         CSO_BIT_DEPTH_STENCIL_ALPHA |
    202                         CSO_BIT_RASTERIZER |
    203                         CSO_BIT_SAMPLE_MASK |
    204                         CSO_BIT_MIN_SAMPLES |
    205                         CSO_BIT_VIEWPORT |
    206                         CSO_BIT_STREAM_OUTPUTS |
    207                         CSO_BIT_VERTEX_ELEMENTS |
    208                         CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
    209                         CSO_BIT_PAUSE_QUERIES |
    210                         CSO_BITS_ALL_SHADERS));
    211 
    212    /* blend state: RGBA masking */
    213    {
    214       struct pipe_blend_state blend;
    215       memset(&blend, 0, sizeof(blend));
    216       if (clear_buffers & PIPE_CLEAR_COLOR) {
    217          int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
    218                            ctx->DrawBuffer->_NumColorDrawBuffers : 1;
    219          int i;
    220 
    221          blend.independent_blend_enable = num_buffers > 1;
    222 
    223          for (i = 0; i < num_buffers; i++) {
    224             if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
    225                continue;
    226 
    227             if (ctx->Color.ColorMask[i][0])
    228                blend.rt[i].colormask |= PIPE_MASK_R;
    229             if (ctx->Color.ColorMask[i][1])
    230                blend.rt[i].colormask |= PIPE_MASK_G;
    231             if (ctx->Color.ColorMask[i][2])
    232                blend.rt[i].colormask |= PIPE_MASK_B;
    233             if (ctx->Color.ColorMask[i][3])
    234                blend.rt[i].colormask |= PIPE_MASK_A;
    235          }
    236 
    237          if (ctx->Color.DitherFlag)
    238             blend.dither = 1;
    239       }
    240       cso_set_blend(cso, &blend);
    241    }
    242 
    243    /* depth_stencil state: always pass/set to ref value */
    244    {
    245       struct pipe_depth_stencil_alpha_state depth_stencil;
    246       memset(&depth_stencil, 0, sizeof(depth_stencil));
    247       if (clear_buffers & PIPE_CLEAR_DEPTH) {
    248          depth_stencil.depth.enabled = 1;
    249          depth_stencil.depth.writemask = 1;
    250          depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
    251       }
    252 
    253       if (clear_buffers & PIPE_CLEAR_STENCIL) {
    254          struct pipe_stencil_ref stencil_ref;
    255          memset(&stencil_ref, 0, sizeof(stencil_ref));
    256          depth_stencil.stencil[0].enabled = 1;
    257          depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
    258          depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
    259          depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
    260          depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
    261          depth_stencil.stencil[0].valuemask = 0xff;
    262          depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
    263          stencil_ref.ref_value[0] = ctx->Stencil.Clear;
    264          cso_set_stencil_ref(cso, &stencil_ref);
    265       }
    266 
    267       cso_set_depth_stencil_alpha(cso, &depth_stencil);
    268    }
    269 
    270    cso_set_vertex_elements(cso, 2, st->util_velems);
    271    cso_set_stream_outputs(cso, 0, NULL, NULL);
    272    cso_set_sample_mask(cso, ~0);
    273    cso_set_min_samples(cso, 1);
    274    cso_set_rasterizer(cso, &st->clear.raster);
    275 
    276    /* viewport state: viewport matching window dims */
    277    cso_set_viewport_dims(st->cso_context, fb_width, fb_height,
    278                          st_fb_orientation(fb) == Y_0_TOP);
    279 
    280    set_fragment_shader(st);
    281    cso_set_tessctrl_shader_handle(cso, NULL);
    282    cso_set_tesseval_shader_handle(cso, NULL);
    283 
    284    if (num_layers > 1)
    285       set_vertex_shader_layered(st);
    286    else
    287       set_vertex_shader(st);
    288 
    289    /* draw quad matching scissor rect.
    290     *
    291     * Note: if we're only clearing depth/stencil we still setup vertices
    292     * with color, but they'll be ignored.
    293     *
    294     * We can't translate the clear color to the colorbuffer format,
    295     * because different colorbuffers may have different formats.
    296     */
    297    if (!st_draw_quad(st, x0, y0, x1, y1,
    298                      ctx->Depth.Clear * 2.0f - 1.0f,
    299                      0.0f, 0.0f, 0.0f, 0.0f,
    300                      (const float *) &ctx->Color.ClearColor.f,
    301                      num_layers)) {
    302       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear");
    303    }
    304 
    305    /* Restore pipe state */
    306    cso_restore_state(cso);
    307 }
    308 
    309 
    310 /**
    311  * Return if the scissor must be enabled during the clear.
    312  */
    313 static inline GLboolean
    314 is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
    315 {
    316    const struct gl_scissor_rect *scissor = &ctx->Scissor.ScissorArray[0];
    317 
    318    return (ctx->Scissor.EnableFlags & 1) &&
    319           (scissor->X > 0 ||
    320            scissor->Y > 0 ||
    321            scissor->X + scissor->Width < (int)rb->Width ||
    322            scissor->Y + scissor->Height < (int)rb->Height);
    323 }
    324 
    325 /**
    326  * Return if window rectangles must be enabled during the clear.
    327  */
    328 static inline bool
    329 is_window_rectangle_enabled(struct gl_context *ctx)
    330 {
    331    if (ctx->DrawBuffer == ctx->WinSysDrawBuffer)
    332       return false;
    333    return ctx->Scissor.NumWindowRects > 0 ||
    334       ctx->Scissor.WindowRectMode == GL_INCLUSIVE_EXT;
    335 }
    336 
    337 
    338 /**
    339  * Return if all of the color channels are masked.
    340  */
    341 static inline GLboolean
    342 is_color_disabled(struct gl_context *ctx, int i)
    343 {
    344    return !ctx->Color.ColorMask[i][0] &&
    345           !ctx->Color.ColorMask[i][1] &&
    346           !ctx->Color.ColorMask[i][2] &&
    347           !ctx->Color.ColorMask[i][3];
    348 }
    349 
    350 
    351 /**
    352  * Return if any of the color channels are masked.
    353  */
    354 static inline GLboolean
    355 is_color_masked(struct gl_context *ctx, int i)
    356 {
    357    return !ctx->Color.ColorMask[i][0] ||
    358           !ctx->Color.ColorMask[i][1] ||
    359           !ctx->Color.ColorMask[i][2] ||
    360           !ctx->Color.ColorMask[i][3];
    361 }
    362 
    363 
    364 /**
    365  * Return if all of the stencil bits are masked.
    366  */
    367 static inline GLboolean
    368 is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
    369 {
    370    const GLuint stencilMax = 0xff;
    371 
    372    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
    373    return (ctx->Stencil.WriteMask[0] & stencilMax) == 0;
    374 }
    375 
    376 
    377 /**
    378  * Return if any of the stencil bits are masked.
    379  */
    380 static inline GLboolean
    381 is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb)
    382 {
    383    const GLuint stencilMax = 0xff;
    384 
    385    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
    386    return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
    387 }
    388 
    389 
    390 /**
    391  * Called via ctx->Driver.Clear()
    392  */
    393 static void
    394 st_Clear(struct gl_context *ctx, GLbitfield mask)
    395 {
    396    struct st_context *st = st_context(ctx);
    397    struct gl_renderbuffer *depthRb
    398       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
    399    struct gl_renderbuffer *stencilRb
    400       = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
    401    GLbitfield quad_buffers = 0x0;
    402    GLbitfield clear_buffers = 0x0;
    403    GLuint i;
    404 
    405    st_flush_bitmap_cache(st);
    406    st_invalidate_readpix_cache(st);
    407 
    408    /* This makes sure the pipe has the latest scissor, etc values */
    409    st_validate_state( st, ST_PIPELINE_RENDER );
    410 
    411    if (mask & BUFFER_BITS_COLOR) {
    412       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
    413          GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
    414 
    415          if (b >= 0 && mask & (1 << b)) {
    416             struct gl_renderbuffer *rb
    417                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
    418             struct st_renderbuffer *strb = st_renderbuffer(rb);
    419             int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0;
    420 
    421             if (!strb || !strb->surface)
    422                continue;
    423 
    424             if (is_color_disabled(ctx, colormask_index))
    425                continue;
    426 
    427             if (is_scissor_enabled(ctx, rb) ||
    428                 is_window_rectangle_enabled(ctx) ||
    429                 is_color_masked(ctx, colormask_index))
    430                quad_buffers |= PIPE_CLEAR_COLOR0 << i;
    431             else
    432                clear_buffers |= PIPE_CLEAR_COLOR0 << i;
    433          }
    434       }
    435    }
    436 
    437    if (mask & BUFFER_BIT_DEPTH) {
    438       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
    439 
    440       if (strb->surface && ctx->Depth.Mask) {
    441          if (is_scissor_enabled(ctx, depthRb) ||
    442              is_window_rectangle_enabled(ctx))
    443             quad_buffers |= PIPE_CLEAR_DEPTH;
    444          else
    445             clear_buffers |= PIPE_CLEAR_DEPTH;
    446       }
    447    }
    448    if (mask & BUFFER_BIT_STENCIL) {
    449       struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
    450 
    451       if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
    452          if (is_scissor_enabled(ctx, stencilRb) ||
    453              is_window_rectangle_enabled(ctx) ||
    454              is_stencil_masked(ctx, stencilRb))
    455             quad_buffers |= PIPE_CLEAR_STENCIL;
    456          else
    457             clear_buffers |= PIPE_CLEAR_STENCIL;
    458       }
    459    }
    460 
    461    /* Always clear depth and stencil together.
    462     * This can only happen when the stencil writemask is not a full mask.
    463     */
    464    if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL &&
    465        clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
    466       quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL;
    467       clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
    468    }
    469 
    470    /* Only use quad-based clearing for the renderbuffers which cannot
    471     * use pipe->clear. We want to always use pipe->clear for the other
    472     * renderbuffers, because it's likely to be faster.
    473     */
    474    if (quad_buffers) {
    475       clear_with_quad(ctx, quad_buffers);
    476    }
    477    if (clear_buffers) {
    478       /* We can't translate the clear color to the colorbuffer format,
    479        * because different colorbuffers may have different formats.
    480        */
    481       st->pipe->clear(st->pipe, clear_buffers,
    482                       (union pipe_color_union*)&ctx->Color.ClearColor,
    483                       ctx->Depth.Clear, ctx->Stencil.Clear);
    484    }
    485    if (mask & BUFFER_BIT_ACCUM)
    486       _mesa_clear_accum_buffer(ctx);
    487 }
    488 
    489 
    490 void
    491 st_init_clear_functions(struct dd_function_table *functions)
    492 {
    493    functions->Clear = st_Clear;
    494 }
    495