Home | History | Annotate | Download | only in i915
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27  /*
     28   * Authors:
     29   *   Keith Whitwell <keith (at) tungstengraphics.com>
     30   */
     31 
     32 #include "i915_state_inlines.h"
     33 #include "i915_context.h"
     34 #include "i915_state.h"
     35 #include "i915_reg.h"
     36 #include "util/u_memory.h"
     37 
     38 
     39 /* Convinience function to check immediate state.
     40  */
     41 
     42 static INLINE void set_immediate(struct i915_context *i915,
     43                                  unsigned offset,
     44                                  const unsigned state)
     45 {
     46    if (i915->current.immediate[offset] == state)
     47       return;
     48 
     49    i915->current.immediate[offset] = state;
     50    i915->immediate_dirty |= 1 << offset;
     51    i915->hardware_dirty |= I915_HW_IMMEDIATE;
     52 }
     53 
     54 
     55 
     56 /***********************************************************************
     57  * S0,S1: Vertex buffer state.
     58  */
     59 static void upload_S0S1(struct i915_context *i915)
     60 {
     61    unsigned LIS0, LIS1;
     62 
     63    /* I915_NEW_VBO
     64     */
     65    LIS0 = i915->vbo_offset;
     66 
     67    /* Need to force this */
     68    if (i915->dirty & I915_NEW_VBO) {
     69       i915->immediate_dirty |= 1 << I915_IMMEDIATE_S0;
     70       i915->hardware_dirty |= I915_HW_IMMEDIATE;
     71    }
     72 
     73    /* I915_NEW_VERTEX_SIZE
     74     */
     75    {
     76       unsigned vertex_size = i915->current.vertex_info.size;
     77 
     78       LIS1 = ((vertex_size << 24) |
     79               (vertex_size << 16));
     80    }
     81 
     82    set_immediate(i915, I915_IMMEDIATE_S0, LIS0);
     83    set_immediate(i915, I915_IMMEDIATE_S1, LIS1);
     84 }
     85 
     86 const struct i915_tracked_state i915_upload_S0S1 = {
     87    "imm S0 S1",
     88    upload_S0S1,
     89    I915_NEW_VBO | I915_NEW_VERTEX_FORMAT
     90 };
     91 
     92 
     93 
     94 /***********************************************************************
     95  * S4: Vertex format, rasterization state
     96  */
     97 static void upload_S2S4(struct i915_context *i915)
     98 {
     99    unsigned LIS2, LIS4;
    100 
    101    /* I915_NEW_VERTEX_FORMAT
    102     */
    103    {
    104       LIS2 = i915->current.vertex_info.hwfmt[1];
    105       LIS4 = i915->current.vertex_info.hwfmt[0];
    106       assert(LIS4); /* should never be zero? */
    107    }
    108 
    109    LIS4 |= i915->rasterizer->LIS4;
    110 
    111    set_immediate(i915, I915_IMMEDIATE_S2, LIS2);
    112    set_immediate(i915, I915_IMMEDIATE_S4, LIS4);
    113 }
    114 
    115 const struct i915_tracked_state i915_upload_S2S4 = {
    116    "imm S2 S4",
    117    upload_S2S4,
    118    I915_NEW_RASTERIZER | I915_NEW_VERTEX_FORMAT
    119 };
    120 
    121 
    122 
    123 /***********************************************************************
    124  */
    125 static void upload_S5(struct i915_context *i915)
    126 {
    127    unsigned LIS5 = 0;
    128 
    129    /* I915_NEW_DEPTH_STENCIL
    130     */
    131    LIS5 |= i915->depth_stencil->stencil_LIS5;
    132    /* hope it's safe to set stencil ref value even if stencil test is disabled? */
    133    LIS5 |= i915->stencil_ref.ref_value[0] << S5_STENCIL_REF_SHIFT;
    134 
    135    /* I915_NEW_BLEND
    136     */
    137    LIS5 |= i915->blend->LIS5;
    138 
    139 #if 0
    140    /* I915_NEW_RASTERIZER
    141     */
    142    if (i915->rasterizer->LIS7) {
    143       LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE;
    144    }
    145 #endif
    146 
    147    set_immediate(i915, I915_IMMEDIATE_S5, LIS5);
    148 }
    149 
    150 const struct i915_tracked_state i915_upload_S5 = {
    151    "imm S5",
    152    upload_S5,
    153    I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_RASTERIZER
    154 };
    155 
    156 
    157 
    158 /***********************************************************************
    159  */
    160 static void upload_S6(struct i915_context *i915)
    161 {
    162    unsigned LIS6 = (2 << S6_TRISTRIP_PV_SHIFT);
    163 
    164    /* I915_NEW_FRAMEBUFFER
    165     */
    166    if (i915->framebuffer.cbufs[0])
    167       LIS6 |= S6_COLOR_WRITE_ENABLE;
    168 
    169    /* I915_NEW_BLEND
    170     */
    171    LIS6 |= i915->blend->LIS6;
    172 
    173    /* I915_NEW_DEPTH
    174     */
    175    LIS6 |= i915->depth_stencil->depth_LIS6;
    176 
    177    set_immediate(i915, I915_IMMEDIATE_S6, LIS6);
    178 }
    179 
    180 const struct i915_tracked_state i915_upload_S6 = {
    181    "imm S6",
    182    upload_S6,
    183    I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_FRAMEBUFFER
    184 };
    185 
    186 
    187 
    188 /***********************************************************************
    189  */
    190 static void upload_S7(struct i915_context *i915)
    191 {
    192 #if 0
    193    unsigned LIS7;
    194 
    195    /* I915_NEW_RASTERIZER
    196     */
    197    LIS7 = i915->rasterizer->LIS7;
    198 
    199    set_immediate(i915, I915_IMMEDIATE_S7, LIS7);
    200 #endif
    201 }
    202 
    203 const struct i915_tracked_state i915_upload_S7 = {
    204    "imm S7",
    205    upload_S7,
    206    I915_NEW_RASTERIZER
    207 };
    208 
    209 
    210 
    211 /***********************************************************************
    212  */
    213 static const struct i915_tracked_state *atoms[] = {
    214    &i915_upload_S0S1,
    215    &i915_upload_S2S4,
    216    &i915_upload_S5,
    217    &i915_upload_S6,
    218    &i915_upload_S7
    219 };
    220 
    221 static void update_immediate(struct i915_context *i915)
    222 {
    223    int i;
    224 
    225    for (i = 0; i < Elements(atoms); i++)
    226       if (i915->dirty & atoms[i]->dirty)
    227          atoms[i]->update(i915);
    228 }
    229 
    230 struct i915_tracked_state i915_hw_immediate = {
    231    "immediate",
    232    update_immediate,
    233    ~0 /* all state atoms, becuase we do internal checking */
    234 };
    235