Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2009 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.  * Authors:
  24.  *    Eric Anholt <eric@anholt.net>
  25.  *
  26.  */
  27.  
  28. #include "brw_context.h"
  29. #include "brw_state.h"
  30. #include "brw_defines.h"
  31. #include "brw_util.h"
  32. #include "brw_wm.h"
  33. #include "program/prog_parameter.h"
  34. #include "program/prog_statevars.h"
  35. #include "intel_batchbuffer.h"
  36.  
  37. static void
  38. gen6_upload_wm_push_constants(struct brw_context *brw)
  39. {
  40.    struct gl_context *ctx = &brw->ctx;
  41.    /* BRW_NEW_FRAGMENT_PROGRAM */
  42.    const struct brw_fragment_program *fp =
  43.       brw_fragment_program_const(brw->fragment_program);
  44.  
  45.    /* Updates the ParameterValues[i] pointers for all parameters of the
  46.     * basic type of PROGRAM_STATE_VAR.
  47.     */
  48.    /* XXX: Should this happen somewhere before to get our state flag set? */
  49.    _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
  50.  
  51.    /* CACHE_NEW_WM_PROG */
  52.    if (brw->wm.prog_data->nr_params != 0) {
  53.       float *constants;
  54.       unsigned int i;
  55.  
  56.       constants = brw_state_batch(brw, AUB_TRACE_WM_CONSTANTS,
  57.                                   brw->wm.prog_data->nr_params *
  58.                                   sizeof(float),
  59.                                   32, &brw->wm.push_const_offset);
  60.  
  61.       for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
  62.          constants[i] = *brw->wm.prog_data->param[i];
  63.       }
  64.  
  65.       if (0) {
  66.          printf("WM constants:\n");
  67.          for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
  68.             if ((i & 7) == 0)
  69.                printf("g%d: ", brw->wm.prog_data->first_curbe_grf + i / 8);
  70.             printf("%8f ", constants[i]);
  71.             if ((i & 7) == 7)
  72.                printf("\n");
  73.          }
  74.          if ((i & 7) != 0)
  75.             printf("\n");
  76.          printf("\n");
  77.       }
  78.    }
  79. }
  80.  
  81. const struct brw_tracked_state gen6_wm_push_constants = {
  82.    .dirty = {
  83.       .mesa  = _NEW_PROGRAM_CONSTANTS,
  84.       .brw   = (BRW_NEW_BATCH |
  85.                 BRW_NEW_FRAGMENT_PROGRAM),
  86.       .cache = CACHE_NEW_WM_PROG,
  87.    },
  88.    .emit = gen6_upload_wm_push_constants,
  89. };
  90.  
  91. static void
  92. upload_wm_state(struct brw_context *brw)
  93. {
  94.    struct gl_context *ctx = &brw->ctx;
  95.    const struct brw_fragment_program *fp =
  96.       brw_fragment_program_const(brw->fragment_program);
  97.    uint32_t dw2, dw4, dw5, dw6;
  98.  
  99.    /* _NEW_BUFFERS */
  100.    bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
  101.  
  102.     /* CACHE_NEW_WM_PROG */
  103.    if (brw->wm.prog_data->nr_params == 0) {
  104.       /* Disable the push constant buffers. */
  105.       BEGIN_BATCH(5);
  106.       OUT_BATCH(_3DSTATE_CONSTANT_PS << 16 | (5 - 2));
  107.       OUT_BATCH(0);
  108.       OUT_BATCH(0);
  109.       OUT_BATCH(0);
  110.       OUT_BATCH(0);
  111.       ADVANCE_BATCH();
  112.    } else {
  113.       BEGIN_BATCH(5);
  114.       OUT_BATCH(_3DSTATE_CONSTANT_PS << 16 |
  115.                 GEN6_CONSTANT_BUFFER_0_ENABLE |
  116.                 (5 - 2));
  117.       /* Pointer to the WM constant buffer.  Covered by the set of
  118.        * state flags from gen6_upload_wm_push_constants.
  119.        */
  120.       OUT_BATCH(brw->wm.push_const_offset +
  121.                 ALIGN(brw->wm.prog_data->nr_params,
  122.                       brw->wm.prog_data->dispatch_width) / 8 - 1);
  123.       OUT_BATCH(0);
  124.       OUT_BATCH(0);
  125.       OUT_BATCH(0);
  126.       ADVANCE_BATCH();
  127.    }
  128.  
  129.    dw2 = dw4 = dw5 = dw6 = 0;
  130.    dw4 |= GEN6_WM_STATISTICS_ENABLE;
  131.    dw5 |= GEN6_WM_LINE_AA_WIDTH_1_0;
  132.    dw5 |= GEN6_WM_LINE_END_CAP_AA_WIDTH_0_5;
  133.  
  134.    /* Use ALT floating point mode for ARB fragment programs, because they
  135.     * require 0^0 == 1.  Even though _CurrentFragmentProgram is used for
  136.     * rendering, CurrentFragmentProgram is used for this check to
  137.     * differentiate between the GLSL and non-GLSL cases.
  138.     */
  139.    if (ctx->Shader.CurrentFragmentProgram == NULL)
  140.       dw2 |= GEN6_WM_FLOATING_POINT_MODE_ALT;
  141.  
  142.    /* CACHE_NEW_SAMPLER */
  143.    dw2 |= (ALIGN(brw->sampler.count, 4) / 4) << GEN6_WM_SAMPLER_COUNT_SHIFT;
  144.    dw4 |= (brw->wm.prog_data->first_curbe_grf <<
  145.            GEN6_WM_DISPATCH_START_GRF_SHIFT_0);
  146.    dw4 |= (brw->wm.prog_data->first_curbe_grf_16 <<
  147.            GEN6_WM_DISPATCH_START_GRF_SHIFT_2);
  148.  
  149.    dw5 |= (brw->max_wm_threads - 1) << GEN6_WM_MAX_THREADS_SHIFT;
  150.  
  151.    /* CACHE_NEW_WM_PROG */
  152.    dw5 |= GEN6_WM_8_DISPATCH_ENABLE;
  153.    if (brw->wm.prog_data->prog_offset_16)
  154.       dw5 |= GEN6_WM_16_DISPATCH_ENABLE;
  155.  
  156.    /* CACHE_NEW_WM_PROG | _NEW_COLOR */
  157.    if (brw->wm.prog_data->dual_src_blend &&
  158.        (ctx->Color.BlendEnabled & 1) &&
  159.        ctx->Color.Blend[0]._UsesDualSrc) {
  160.       dw5 |= GEN6_WM_DUAL_SOURCE_BLEND_ENABLE;
  161.    }
  162.  
  163.    /* _NEW_LINE */
  164.    if (ctx->Line.StippleFlag)
  165.       dw5 |= GEN6_WM_LINE_STIPPLE_ENABLE;
  166.  
  167.    /* _NEW_POLYGON */
  168.    if (ctx->Polygon.StippleFlag)
  169.       dw5 |= GEN6_WM_POLYGON_STIPPLE_ENABLE;
  170.  
  171.    /* BRW_NEW_FRAGMENT_PROGRAM */
  172.    if (fp->program.Base.InputsRead & VARYING_BIT_POS)
  173.       dw5 |= GEN6_WM_USES_SOURCE_DEPTH | GEN6_WM_USES_SOURCE_W;
  174.    if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
  175.       dw5 |= GEN6_WM_COMPUTED_DEPTH;
  176.    /* CACHE_NEW_WM_PROG */
  177.    dw6 |= brw->wm.prog_data->barycentric_interp_modes <<
  178.       GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
  179.  
  180.    /* _NEW_COLOR, _NEW_MULTISAMPLE */
  181.    if (fp->program.UsesKill || ctx->Color.AlphaEnabled ||
  182.        ctx->Multisample.SampleAlphaToCoverage)
  183.       dw5 |= GEN6_WM_KILL_ENABLE;
  184.  
  185.    if (brw_color_buffer_write_enabled(brw) ||
  186.        dw5 & (GEN6_WM_KILL_ENABLE | GEN6_WM_COMPUTED_DEPTH)) {
  187.       dw5 |= GEN6_WM_DISPATCH_ENABLE;
  188.    }
  189.  
  190.    dw6 |= _mesa_bitcount_64(brw->fragment_program->Base.InputsRead) <<
  191.       GEN6_WM_NUM_SF_OUTPUTS_SHIFT;
  192.    if (multisampled_fbo) {
  193.       /* _NEW_MULTISAMPLE */
  194.       if (ctx->Multisample.Enabled)
  195.          dw6 |= GEN6_WM_MSRAST_ON_PATTERN;
  196.       else
  197.          dw6 |= GEN6_WM_MSRAST_OFF_PIXEL;
  198.       dw6 |= GEN6_WM_MSDISPMODE_PERPIXEL;
  199.    } else {
  200.       dw6 |= GEN6_WM_MSRAST_OFF_PIXEL;
  201.       dw6 |= GEN6_WM_MSDISPMODE_PERSAMPLE;
  202.    }
  203.  
  204.    BEGIN_BATCH(9);
  205.    OUT_BATCH(_3DSTATE_WM << 16 | (9 - 2));
  206.    OUT_BATCH(brw->wm.prog_offset);
  207.    OUT_BATCH(dw2);
  208.    if (brw->wm.prog_data->total_scratch) {
  209.       OUT_RELOC(brw->wm.scratch_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  210.                 ffs(brw->wm.prog_data->total_scratch) - 11);
  211.    } else {
  212.       OUT_BATCH(0);
  213.    }
  214.    OUT_BATCH(dw4);
  215.    OUT_BATCH(dw5);
  216.    OUT_BATCH(dw6);
  217.    OUT_BATCH(0); /* kernel 1 pointer */
  218.    /* kernel 2 pointer */
  219.    OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16);
  220.    ADVANCE_BATCH();
  221. }
  222.  
  223. const struct brw_tracked_state gen6_wm_state = {
  224.    .dirty = {
  225.       .mesa  = (_NEW_LINE |
  226.                 _NEW_COLOR |
  227.                 _NEW_BUFFERS |
  228.                 _NEW_PROGRAM_CONSTANTS |
  229.                 _NEW_POLYGON |
  230.                 _NEW_MULTISAMPLE),
  231.       .brw   = (BRW_NEW_FRAGMENT_PROGRAM |
  232.                 BRW_NEW_BATCH),
  233.       .cache = (CACHE_NEW_SAMPLER |
  234.                 CACHE_NEW_WM_PROG)
  235.    },
  236.    .emit = upload_wm_state,
  237. };
  238.