Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2012 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 "intel_batchbuffer.h"
  25.  
  26. #include "brw_context.h"
  27. #include "brw_defines.h"
  28.  
  29. /* Sample positions:
  30.  *   2 6 a e
  31.  * 2   0
  32.  * 6       1
  33.  * a 2
  34.  * e     3
  35.  */
  36. static uint32_t
  37. sample_positions_4x[] = { 0xae2ae662 };
  38. /* Sample positions are based on a solution to the "8 queens" puzzle.
  39.  * Rationale: in a solution to the 8 queens puzzle, no two queens share
  40.  * a row, column, or diagonal.  This is a desirable property for samples
  41.  * in a multisampling pattern, because it ensures that the samples are
  42.  * relatively uniformly distributed through the pixel.
  43.  *
  44.  * There are several solutions to the 8 queens puzzle (see
  45.  * http://en.wikipedia.org/wiki/Eight_queens_puzzle).  This solution was
  46.  * chosen because it has a queen close to the center; this should
  47.  * improve the accuracy of centroid interpolation, since the hardware
  48.  * implements centroid interpolation by choosing the centermost sample
  49.  * that overlaps with the primitive being drawn.
  50.  *
  51.  * Note: from the Ivy Bridge PRM, Vol2 Part1 p304 (3DSTATE_MULTISAMPLE:
  52.  * Programming Notes):
  53.  *
  54.  *     "When programming the sample offsets (for NUMSAMPLES_4 or _8 and
  55.  *     MSRASTMODE_xxx_PATTERN), the order of the samples 0 to 3 (or 7
  56.  *     for 8X) must have monotonically increasing distance from the
  57.  *     pixel center. This is required to get the correct centroid
  58.  *     computation in the device."
  59.  *
  60.  * Sample positions:
  61.  *   1 3 5 7 9 b d f
  62.  * 1     5
  63.  * 3           2
  64.  * 5               6
  65.  * 7 4
  66.  * 9       0
  67.  * b             3
  68.  * d         1
  69.  * f   7
  70.  */
  71. static uint32_t
  72. sample_positions_8x[] = { 0xdbb39d79, 0x3ff55117 };
  73.  
  74.  
  75. void
  76. gen6_get_sample_position(struct gl_context *ctx,
  77.                          struct gl_framebuffer *fb,
  78.                          GLuint index, GLfloat *result)
  79. {
  80.    switch (fb->Visual.samples) {
  81.    case 1:
  82.       result[0] = result[1] = 0.5f;
  83.       break;
  84.    case 4: {
  85.       uint8_t val = (uint8_t)(sample_positions_4x[0] >> (8*index));
  86.       result[0] = ((val >> 4) & 0xf) / 16.0f;
  87.       result[1] = (val & 0xf) / 16.0f;
  88.       break;
  89.    }
  90.    case 8: {
  91.       uint8_t val = (uint8_t)(sample_positions_8x[index>>2] >> (8*(index & 3)));
  92.       result[0] = ((val >> 4) & 0xf) / 16.0f;
  93.       result[1] = (val & 0xf) / 16.0f;
  94.       break;
  95.    }
  96.    default:
  97.       assert(!"Not implemented");
  98.    }
  99. }
  100.  
  101. /**
  102.  * 3DSTATE_MULTISAMPLE
  103.  */
  104. void
  105. gen6_emit_3dstate_multisample(struct brw_context *brw,
  106.                               unsigned num_samples)
  107. {
  108.    uint32_t number_of_multisamples = 0;
  109.    uint32_t sample_positions_3210 = 0;
  110.    uint32_t sample_positions_7654 = 0;
  111.  
  112.    switch (num_samples) {
  113.    case 0:
  114.    case 1:
  115.       number_of_multisamples = MS_NUMSAMPLES_1;
  116.       break;
  117.    case 4:
  118.       number_of_multisamples = MS_NUMSAMPLES_4;
  119.       sample_positions_3210 = sample_positions_4x[0];
  120.       break;
  121.    case 8:
  122.       number_of_multisamples = MS_NUMSAMPLES_8;
  123.       sample_positions_3210 = sample_positions_8x[0];
  124.       sample_positions_7654 = sample_positions_8x[1];
  125.       break;
  126.    default:
  127.       assert(!"Unrecognized num_samples in gen6_emit_3dstate_multisample");
  128.       break;
  129.    }
  130.  
  131.    int len = brw->gen >= 7 ? 4 : 3;
  132.    BEGIN_BATCH(len);
  133.    OUT_BATCH(_3DSTATE_MULTISAMPLE << 16 | (len - 2));
  134.    OUT_BATCH(MS_PIXEL_LOCATION_CENTER | number_of_multisamples);
  135.    OUT_BATCH(sample_positions_3210);
  136.    if (brw->gen >= 7)
  137.       OUT_BATCH(sample_positions_7654);
  138.    ADVANCE_BATCH();
  139. }
  140.  
  141.  
  142. /**
  143.  * 3DSTATE_SAMPLE_MASK
  144.  */
  145. void
  146. gen6_emit_3dstate_sample_mask(struct brw_context *brw,
  147.                               unsigned num_samples, float coverage,
  148.                               bool coverage_invert, unsigned sample_mask)
  149. {
  150.    BEGIN_BATCH(2);
  151.    OUT_BATCH(_3DSTATE_SAMPLE_MASK << 16 | (2 - 2));
  152.    if (num_samples > 1) {
  153.       int coverage_int = (int) (num_samples * coverage + 0.5);
  154.       uint32_t coverage_bits = (1 << coverage_int) - 1;
  155.       if (coverage_invert)
  156.          coverage_bits ^= (1 << num_samples) - 1;
  157.       OUT_BATCH(coverage_bits & sample_mask);
  158.    } else {
  159.       OUT_BATCH(1);
  160.    }
  161.    ADVANCE_BATCH();
  162. }
  163.  
  164.  
  165. static void upload_multisample_state(struct brw_context *brw)
  166. {
  167.    struct gl_context *ctx = &brw->ctx;
  168.    float coverage = 1.0;
  169.    float coverage_invert = false;
  170.    unsigned sample_mask = ~0u;
  171.  
  172.    /* _NEW_BUFFERS */
  173.    unsigned num_samples = ctx->DrawBuffer->Visual.samples;
  174.  
  175.    /* _NEW_MULTISAMPLE */
  176.    if (ctx->Multisample._Enabled) {
  177.       if (ctx->Multisample.SampleCoverage) {
  178.          coverage = ctx->Multisample.SampleCoverageValue;
  179.          coverage_invert = ctx->Multisample.SampleCoverageInvert;
  180.       }
  181.       if (ctx->Multisample.SampleMask) {
  182.          sample_mask = ctx->Multisample.SampleMaskValue;
  183.       }
  184.    }
  185.  
  186.    /* 3DSTATE_MULTISAMPLE is nonpipelined. */
  187.    intel_emit_post_sync_nonzero_flush(brw);
  188.  
  189.    gen6_emit_3dstate_multisample(brw, num_samples);
  190.    gen6_emit_3dstate_sample_mask(brw, num_samples, coverage,
  191.          coverage_invert, sample_mask);
  192. }
  193.  
  194.  
  195. const struct brw_tracked_state gen6_multisample_state = {
  196.    .dirty = {
  197.       .mesa = _NEW_BUFFERS |
  198.               _NEW_MULTISAMPLE,
  199.       .brw = BRW_NEW_CONTEXT,
  200.       .cache = 0
  201.    },
  202.    .emit = upload_multisample_state
  203. };
  204.