Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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 <keith@tungstengraphics.com>
  32.   *   Brian Paul
  33.   *   Michel Dänzer
  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_clear.h"
  45. #include "st_cb_fbo.h"
  46. #include "st_format.h"
  47. #include "st_program.h"
  48.  
  49. #include "pipe/p_context.h"
  50. #include "pipe/p_shader_tokens.h"
  51. #include "pipe/p_state.h"
  52. #include "pipe/p_defines.h"
  53. #include "util/u_format.h"
  54. #include "util/u_inlines.h"
  55. #include "util/u_simple_shaders.h"
  56. #include "util/u_draw_quad.h"
  57. #include "util/u_upload_mgr.h"
  58.  
  59. #include "cso_cache/cso_context.h"
  60.  
  61.  
  62. /**
  63.  * Do per-context initialization for glClear.
  64.  */
  65. void
  66. st_init_clear(struct st_context *st)
  67. {
  68.    memset(&st->clear, 0, sizeof(st->clear));
  69.  
  70.    st->clear.raster.half_pixel_center = 1;
  71.    st->clear.raster.bottom_edge_rule = 1;
  72.    st->clear.raster.depth_clip = 1;
  73. }
  74.  
  75.  
  76. /**
  77.  * Free per-context state for glClear.
  78.  */
  79. void
  80. st_destroy_clear(struct st_context *st)
  81. {
  82.    if (st->clear.fs) {
  83.       cso_delete_fragment_shader(st->cso_context, st->clear.fs);
  84.       st->clear.fs = NULL;
  85.    }
  86.    if (st->clear.vs) {
  87.       cso_delete_vertex_shader(st->cso_context, st->clear.vs);
  88.       st->clear.vs = NULL;
  89.    }
  90. }
  91.  
  92.  
  93. /**
  94.  * Helper function to set the fragment shaders.
  95.  */
  96. static INLINE void
  97. set_fragment_shader(struct st_context *st)
  98. {
  99.    if (!st->clear.fs)
  100.       st->clear.fs =
  101.          util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_GENERIC,
  102.                                                TGSI_INTERPOLATE_CONSTANT,
  103.                                                TRUE);
  104.  
  105.    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
  106. }
  107.  
  108.  
  109. /**
  110.  * Helper function to set the vertex shader.
  111.  */
  112. static INLINE void
  113. set_vertex_shader(struct st_context *st)
  114. {
  115.    /* vertex shader - still required to provide the linkage between
  116.     * fragment shader input semantics and vertex_element/buffers.
  117.     */
  118.    if (!st->clear.vs)
  119.    {
  120.       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  121.                                       TGSI_SEMANTIC_GENERIC };
  122.       const uint semantic_indexes[] = { 0, 0 };
  123.       st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
  124.                                                          semantic_names,
  125.                                                          semantic_indexes);
  126.    }
  127.  
  128.    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
  129. }
  130.  
  131.  
  132. /**
  133.  * Draw a screen-aligned quadrilateral.
  134.  * Coords are clip coords with y=0=bottom.
  135.  */
  136. static void
  137. draw_quad(struct st_context *st,
  138.           float x0, float y0, float x1, float y1, GLfloat z,
  139.           const union pipe_color_union *color)
  140. {
  141.    struct pipe_context *pipe = st->pipe;
  142.    struct pipe_resource *vbuf = NULL;
  143.    GLuint i, offset;
  144.    float (*vertices)[2][4];  /**< vertex pos + color */
  145.  
  146.    if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]),
  147.                       &offset, &vbuf, (void **) &vertices) != PIPE_OK) {
  148.       return;
  149.    }
  150.  
  151.    /* positions */
  152.    vertices[0][0][0] = x0;
  153.    vertices[0][0][1] = y0;
  154.  
  155.    vertices[1][0][0] = x1;
  156.    vertices[1][0][1] = y0;
  157.  
  158.    vertices[2][0][0] = x1;
  159.    vertices[2][0][1] = y1;
  160.  
  161.    vertices[3][0][0] = x0;
  162.    vertices[3][0][1] = y1;
  163.  
  164.    /* same for all verts: */
  165.    for (i = 0; i < 4; i++) {
  166.       vertices[i][0][2] = z;
  167.       vertices[i][0][3] = 1.0;
  168.       vertices[i][1][0] = color->f[0];
  169.       vertices[i][1][1] = color->f[1];
  170.       vertices[i][1][2] = color->f[2];
  171.       vertices[i][1][3] = color->f[3];
  172.    }
  173.  
  174.    u_upload_unmap(st->uploader);
  175.  
  176.    /* draw */
  177.    util_draw_vertex_buffer(pipe,
  178.                            st->cso_context,
  179.                            vbuf,
  180.                            cso_get_aux_vertex_buffer_slot(st->cso_context),
  181.                            offset,
  182.                            PIPE_PRIM_TRIANGLE_FAN,
  183.                            4,  /* verts */
  184.                            2); /* attribs/vert */
  185.  
  186.    pipe_resource_reference(&vbuf, NULL);
  187. }
  188.  
  189.  
  190.  
  191. /**
  192.  * Do glClear by drawing a quadrilateral.
  193.  * The vertices of the quad will be computed from the
  194.  * ctx->DrawBuffer->_X/Ymin/max fields.
  195.  */
  196. static void
  197. clear_with_quad(struct gl_context *ctx,
  198.                 GLboolean color, GLboolean depth, GLboolean stencil)
  199. {
  200.    struct st_context *st = st_context(ctx);
  201.    const struct gl_framebuffer *fb = ctx->DrawBuffer;
  202.    const GLfloat fb_width = (GLfloat) fb->Width;
  203.    const GLfloat fb_height = (GLfloat) fb->Height;
  204.    const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
  205.    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
  206.    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
  207.    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
  208.    union pipe_color_union clearColor;
  209.  
  210.    /*
  211.    printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
  212.           color ? "color, " : "",
  213.           depth ? "depth, " : "",
  214.           stencil ? "stencil" : "",
  215.           x0, y0,
  216.           x1, y1);
  217.    */
  218.  
  219.    cso_save_blend(st->cso_context);
  220.    cso_save_stencil_ref(st->cso_context);
  221.    cso_save_depth_stencil_alpha(st->cso_context);
  222.    cso_save_rasterizer(st->cso_context);
  223.    cso_save_sample_mask(st->cso_context);
  224.    cso_save_viewport(st->cso_context);
  225.    cso_save_fragment_shader(st->cso_context);
  226.    cso_save_stream_outputs(st->cso_context);
  227.    cso_save_vertex_shader(st->cso_context);
  228.    cso_save_geometry_shader(st->cso_context);
  229.    cso_save_vertex_elements(st->cso_context);
  230.    cso_save_aux_vertex_buffer_slot(st->cso_context);
  231.  
  232.    /* blend state: RGBA masking */
  233.    {
  234.       struct pipe_blend_state blend;
  235.       memset(&blend, 0, sizeof(blend));
  236.       if (color) {
  237.          int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
  238.                            ctx->DrawBuffer->_NumColorDrawBuffers : 1;
  239.          int i;
  240.  
  241.          blend.independent_blend_enable = num_buffers > 1;
  242.  
  243.          for (i = 0; i < num_buffers; i++) {
  244.             if (ctx->Color.ColorMask[i][0])
  245.                blend.rt[i].colormask |= PIPE_MASK_R;
  246.             if (ctx->Color.ColorMask[i][1])
  247.                blend.rt[i].colormask |= PIPE_MASK_G;
  248.             if (ctx->Color.ColorMask[i][2])
  249.                blend.rt[i].colormask |= PIPE_MASK_B;
  250.             if (ctx->Color.ColorMask[i][3])
  251.                blend.rt[i].colormask |= PIPE_MASK_A;
  252.          }
  253.  
  254.          if (st->ctx->Color.DitherFlag)
  255.             blend.dither = 1;
  256.       }
  257.       cso_set_blend(st->cso_context, &blend);
  258.    }
  259.  
  260.    /* depth_stencil state: always pass/set to ref value */
  261.    {
  262.       struct pipe_depth_stencil_alpha_state depth_stencil;
  263.       memset(&depth_stencil, 0, sizeof(depth_stencil));
  264.       if (depth) {
  265.          depth_stencil.depth.enabled = 1;
  266.          depth_stencil.depth.writemask = 1;
  267.          depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
  268.       }
  269.  
  270.       if (stencil) {
  271.          struct pipe_stencil_ref stencil_ref;
  272.          memset(&stencil_ref, 0, sizeof(stencil_ref));
  273.          depth_stencil.stencil[0].enabled = 1;
  274.          depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
  275.          depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
  276.          depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
  277.          depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
  278.          depth_stencil.stencil[0].valuemask = 0xff;
  279.          depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
  280.          stencil_ref.ref_value[0] = ctx->Stencil.Clear;
  281.          cso_set_stencil_ref(st->cso_context, &stencil_ref);
  282.       }
  283.  
  284.       cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
  285.    }
  286.  
  287.    cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
  288.    cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
  289.    cso_set_sample_mask(st->cso_context, ~0);
  290.    cso_set_rasterizer(st->cso_context, &st->clear.raster);
  291.  
  292.    /* viewport state: viewport matching window dims */
  293.    {
  294.       const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
  295.       struct pipe_viewport_state vp;
  296.       vp.scale[0] = 0.5f * fb_width;
  297.       vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
  298.       vp.scale[2] = 1.0f;
  299.       vp.scale[3] = 1.0f;
  300.       vp.translate[0] = 0.5f * fb_width;
  301.       vp.translate[1] = 0.5f * fb_height;
  302.       vp.translate[2] = 0.0f;
  303.       vp.translate[3] = 0.0f;
  304.       cso_set_viewport(st->cso_context, &vp);
  305.    }
  306.  
  307.    set_fragment_shader(st);
  308.    set_vertex_shader(st);
  309.    cso_set_geometry_shader_handle(st->cso_context, NULL);
  310.  
  311.    if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
  312.       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
  313.       GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat);
  314.  
  315.       st_translate_color(&ctx->Color.ClearColor,
  316.                          &clearColor,
  317.                          ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
  318.                          is_integer);
  319.    }
  320.  
  321.    /* draw quad matching scissor rect */
  322.    draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, &clearColor);
  323.  
  324.    /* Restore pipe state */
  325.    cso_restore_blend(st->cso_context);
  326.    cso_restore_stencil_ref(st->cso_context);
  327.    cso_restore_depth_stencil_alpha(st->cso_context);
  328.    cso_restore_rasterizer(st->cso_context);
  329.    cso_restore_sample_mask(st->cso_context);
  330.    cso_restore_viewport(st->cso_context);
  331.    cso_restore_fragment_shader(st->cso_context);
  332.    cso_restore_vertex_shader(st->cso_context);
  333.    cso_restore_geometry_shader(st->cso_context);
  334.    cso_restore_vertex_elements(st->cso_context);
  335.    cso_restore_aux_vertex_buffer_slot(st->cso_context);
  336.    cso_restore_stream_outputs(st->cso_context);
  337. }
  338.  
  339.  
  340. /**
  341.  * Return if the scissor must be enabled during the clear.
  342.  */
  343. static INLINE GLboolean
  344. is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
  345. {
  346.    return ctx->Scissor.Enabled &&
  347.           (ctx->Scissor.X > 0 ||
  348.            ctx->Scissor.Y > 0 ||
  349.            (unsigned) ctx->Scissor.Width < rb->Width ||
  350.            (unsigned) ctx->Scissor.Height < rb->Height);
  351. }
  352.  
  353.  
  354. /**
  355.  * Return if any of the color channels are masked.
  356.  */
  357. static INLINE GLboolean
  358. is_color_masked(struct gl_context *ctx, int i)
  359. {
  360.    return !ctx->Color.ColorMask[i][0] ||
  361.           !ctx->Color.ColorMask[i][1] ||
  362.           !ctx->Color.ColorMask[i][2] ||
  363.           !ctx->Color.ColorMask[i][3];
  364. }
  365.  
  366.  
  367. /**
  368.  * Return if any of the stencil bits are masked.
  369.  */
  370. static INLINE GLboolean
  371. is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb)
  372. {
  373.    const GLuint stencilMax = 0xff;
  374.  
  375.    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
  376.    return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
  377. }
  378.  
  379.  
  380. /**
  381.  * Called via ctx->Driver.Clear()
  382.  */
  383. static void
  384. st_Clear(struct gl_context *ctx, GLbitfield mask)
  385. {
  386.    struct st_context *st = st_context(ctx);
  387.    struct gl_renderbuffer *depthRb
  388.       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  389.    struct gl_renderbuffer *stencilRb
  390.       = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
  391.    GLbitfield quad_buffers = 0x0;
  392.    GLbitfield clear_buffers = 0x0;
  393.    GLuint i;
  394.  
  395.    /* This makes sure the pipe has the latest scissor, etc values */
  396.    st_validate_state( st );
  397.  
  398.    if (mask & BUFFER_BITS_COLOR) {
  399.       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
  400.          GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
  401.  
  402.          if (mask & (1 << b)) {
  403.             struct gl_renderbuffer *rb
  404.                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
  405.             struct st_renderbuffer *strb = st_renderbuffer(rb);
  406.             int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0;
  407.  
  408.             if (!strb || !strb->surface)
  409.                continue;
  410.  
  411.             if (is_scissor_enabled(ctx, rb) ||
  412.                 is_color_masked(ctx, colormask_index))
  413.                quad_buffers |= PIPE_CLEAR_COLOR;
  414.             else
  415.                clear_buffers |= PIPE_CLEAR_COLOR;
  416.          }
  417.       }
  418.    }
  419.  
  420.    if (mask & BUFFER_BIT_DEPTH) {
  421.       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
  422.  
  423.       if (strb->surface) {
  424.          if (is_scissor_enabled(ctx, depthRb))
  425.             quad_buffers |= PIPE_CLEAR_DEPTH;
  426.          else
  427.             clear_buffers |= PIPE_CLEAR_DEPTH;
  428.       }
  429.    }
  430.    if (mask & BUFFER_BIT_STENCIL) {
  431.       struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
  432.  
  433.       if (strb->surface) {
  434.          if (is_scissor_enabled(ctx, stencilRb) ||
  435.              is_stencil_masked(ctx, stencilRb))
  436.             quad_buffers |= PIPE_CLEAR_STENCIL;
  437.          else
  438.             clear_buffers |= PIPE_CLEAR_STENCIL;
  439.       }
  440.    }
  441.  
  442.    /*
  443.     * If we're going to use clear_with_quad() for any reason, use it for
  444.     * everything possible.
  445.     */
  446.    if (quad_buffers) {
  447.       quad_buffers |= clear_buffers;
  448.       clear_with_quad(ctx,
  449.                       quad_buffers & PIPE_CLEAR_COLOR,
  450.                       quad_buffers & PIPE_CLEAR_DEPTH,
  451.                       quad_buffers & PIPE_CLEAR_STENCIL);
  452.    } else if (clear_buffers) {
  453.       union pipe_color_union clearColor;
  454.  
  455.       if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
  456.          struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
  457.          GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat);
  458.  
  459.          st_translate_color(&ctx->Color.ClearColor,
  460.                             &clearColor,
  461.                             ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
  462.                             is_integer);
  463.       }
  464.  
  465.       st->pipe->clear(st->pipe, clear_buffers, &clearColor,
  466.                       ctx->Depth.Clear, ctx->Stencil.Clear);
  467.    }
  468.    if (mask & BUFFER_BIT_ACCUM)
  469.       _mesa_clear_accum_buffer(ctx);
  470. }
  471.  
  472.  
  473. void
  474. st_init_clear_functions(struct dd_function_table *functions)
  475. {
  476.    functions->Clear = st_Clear;
  477. }
  478.