Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  */
  23.  
  24. #include "brw_context.h"
  25. #include "brw_state.h"
  26. #include "brw_defines.h"
  27. #include "intel_batchbuffer.h"
  28. #include "main/fbobject.h"
  29. #include "main/viewport.h"
  30.  
  31. static void
  32. gen8_upload_sf_clip_viewport(struct brw_context *brw)
  33. {
  34.    struct gl_context *ctx = &brw->ctx;
  35.    float y_scale, y_bias;
  36.    const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
  37.  
  38.    float *vp = brw_state_batch(brw, AUB_TRACE_SF_VP_STATE,
  39.                                16 * 4 * ctx->Const.MaxViewports,
  40.                                64, &brw->sf.vp_offset);
  41.    /* Also assign to clip.vp_offset in case something uses it. */
  42.    brw->clip.vp_offset = brw->sf.vp_offset;
  43.  
  44.    /* _NEW_BUFFERS */
  45.    if (render_to_fbo) {
  46.       y_scale = 1.0;
  47.       y_bias = 0;
  48.    } else {
  49.       y_scale = -1.0;
  50.       y_bias = ctx->DrawBuffer->Height;
  51.    }
  52.  
  53.    for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
  54.       double scale[3], translate[3];
  55.       _mesa_get_viewport_xform(ctx, i, scale, translate);
  56.  
  57.       /* _NEW_VIEWPORT: Viewport Matrix Elements */
  58.       vp[0] = scale[0];                        /* m00 */
  59.       vp[1] = scale[1] * y_scale;              /* m11 */
  60.       vp[2] = scale[2];                        /* m22 */
  61.       vp[3] = translate[0];                    /* m30 */
  62.       vp[4] = translate[1] * y_scale + y_bias; /* m31 */
  63.       vp[5] = translate[2];                    /* m32 */
  64.  
  65.       /* Reserved */
  66.       vp[6] = 0;
  67.       vp[7] = 0;
  68.  
  69.       /* According to the "Vertex X,Y Clamping and Quantization" section of the
  70.        * Strips and Fans documentation, objects must not have a screen-space
  71.        * extents of over 8192 pixels, or they may be mis-rasterized.  The
  72.        * maximum screen space coordinates of a small object may larger, but we
  73.        * have no way to enforce the object size other than through clipping.
  74.        *
  75.        * The goal is to create the maximum sized guardband (8K x 8K) with the
  76.        * viewport rectangle in the center of the guardband. This looks weird
  77.        * because the hardware wants coordinates that are scaled to the viewport
  78.        * in NDC. In other words, an 8K x 8K viewport would have [-1,1] for X and Y.
  79.        * A 4K viewport would be [-2,2], 2K := [-4,4] etc.
  80.        *
  81.        * --------------------------------
  82.        * |Guardband                     |
  83.        * |                              |
  84.        * |         ------------         |
  85.        * |         |viewport  |         |
  86.        * |         |          |         |
  87.        * |         |          |         |
  88.        * |         |__________|         |
  89.        * |                              |
  90.        * |                              |
  91.        * |______________________________|
  92.        *
  93.        */
  94.       const float maximum_guardband_extent = 8192;
  95.       float gbx = maximum_guardband_extent / ctx->ViewportArray[i].Width;
  96.       float gby = maximum_guardband_extent / ctx->ViewportArray[i].Height;
  97.  
  98.       /* _NEW_VIEWPORT: Guardband Clipping */
  99.       vp[8]  = -gbx; /* x-min */
  100.       vp[9]  =  gbx; /* x-max */
  101.       vp[10] = -gby; /* y-min */
  102.       vp[11] =  gby; /* y-max */
  103.  
  104.       /* _NEW_VIEWPORT | _NEW_BUFFERS: Screen Space Viewport
  105.        * The hardware will take the intersection of the drawing rectangle,
  106.        * scissor rectangle, and the viewport extents. We don't need to be
  107.        * smart, and can therefore just program the viewport extents.
  108.        */
  109.       float viewport_Xmax = ctx->ViewportArray[i].X + ctx->ViewportArray[i].Width;
  110.       float viewport_Ymax = ctx->ViewportArray[i].Y + ctx->ViewportArray[i].Height;
  111.       if (render_to_fbo) {
  112.          vp[12] = ctx->ViewportArray[i].X;
  113.          vp[13] = viewport_Xmax - 1;
  114.          vp[14] = ctx->ViewportArray[i].Y;
  115.          vp[15] = viewport_Ymax - 1;
  116.       } else {
  117.          vp[12] = ctx->ViewportArray[i].X;
  118.          vp[13] = viewport_Xmax - 1;
  119.          vp[14] = ctx->DrawBuffer->Height - viewport_Ymax;
  120.          vp[15] = ctx->DrawBuffer->Height - ctx->ViewportArray[i].Y - 1;
  121.       }
  122.  
  123.       vp += 16;
  124.    }
  125.  
  126.    BEGIN_BATCH(2);
  127.    OUT_BATCH(_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL << 16 | (2 - 2));
  128.    OUT_BATCH(brw->sf.vp_offset);
  129.    ADVANCE_BATCH();
  130. }
  131.  
  132. const struct brw_tracked_state gen8_sf_clip_viewport = {
  133.    .dirty = {
  134.       .mesa = _NEW_BUFFERS |
  135.               _NEW_VIEWPORT,
  136.       .brw = BRW_NEW_BATCH,
  137.    },
  138.    .emit = gen8_upload_sf_clip_viewport,
  139. };
  140.