i915_state_dynamic.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 #include "i915_batch.h"
00029 #include "i915_state_inlines.h"
00030 #include "i915_context.h"
00031 #include "i915_reg.h"
00032 #include "i915_state.h"
00033 #include "util/u_math.h"
00034 #include "util/u_memory.h"
00035 #include "util/u_pack_color.h"
00036 
00037 #define FILE_DEBUG_FLAG DEBUG_STATE
00038 
00039 /* State that we have chosen to store in the DYNAMIC segment of the
00040  * i915 indirect state mechanism.  
00041  *
00042  * Can't cache these in the way we do the static state, as there is no
00043  * start/size in the command packet, instead an 'end' value that gets
00044  * incremented.
00045  *
00046  * Additionally, there seems to be a requirement to re-issue the full
00047  * (active) state every time a 4kb boundary is crossed.
00048  */
00049 
00050 static INLINE void set_dynamic_indirect( struct i915_context *i915,
00051                                          unsigned offset,
00052                                          const unsigned *src,
00053                                          unsigned dwords )
00054 {
00055    unsigned i;
00056 
00057    for (i = 0; i < dwords; i++)
00058       i915->current.dynamic[offset + i] = src[i];
00059 
00060    i915->hardware_dirty |= I915_HW_DYNAMIC;
00061 }
00062 
00063 
00064 /***********************************************************************
00065  * Modes4: stencil masks and logicop 
00066  */
00067 static void upload_MODES4( struct i915_context *i915 )
00068 {
00069    unsigned modes4 = 0;
00070 
00071    /* I915_NEW_STENCIL */
00072    modes4 |= i915->depth_stencil->stencil_modes4;
00073    /* I915_NEW_BLEND */
00074    modes4 |= i915->blend->modes4;
00075 
00076    /* Always, so that we know when state is in-active: 
00077     */
00078    set_dynamic_indirect( i915, 
00079                          I915_DYNAMIC_MODES4,
00080                          &modes4,
00081                          1 );
00082 }
00083 
00084 const struct i915_tracked_state i915_upload_MODES4 = {
00085    I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL,
00086    upload_MODES4
00087 };
00088 
00089 
00090 
00091 
00092 /***********************************************************************
00093  */
00094 
00095 static void upload_BFO( struct i915_context *i915 )
00096 {
00097    set_dynamic_indirect( i915,
00098                          I915_DYNAMIC_BFO_0,
00099                          &(i915->depth_stencil->bfo[0]),
00100                          2 );
00101 }
00102 
00103 const struct i915_tracked_state i915_upload_BFO = {
00104    I915_NEW_DEPTH_STENCIL,
00105    upload_BFO
00106 };
00107 
00108 
00109 /***********************************************************************
00110  */
00111 
00112 
00113 static void upload_BLENDCOLOR( struct i915_context *i915 )
00114 {
00115    unsigned bc[2];
00116 
00117    memset( bc, 0, sizeof(bc) );
00118 
00119    /* I915_NEW_BLEND {_COLOR} 
00120     */
00121    {
00122       const float *color = i915->blend_color.color;
00123 
00124       bc[0] = _3DSTATE_CONST_BLEND_COLOR_CMD;
00125       bc[1] = pack_ui32_float4( color[0],
00126                                 color[1],
00127                                 color[2], 
00128                                 color[3] );
00129    }
00130 
00131    set_dynamic_indirect( i915, 
00132                          I915_DYNAMIC_BC_0,
00133                          bc,
00134                          2 );
00135 }
00136 
00137 const struct i915_tracked_state i915_upload_BLENDCOLOR = {
00138    I915_NEW_BLEND,
00139    upload_BLENDCOLOR
00140 };
00141 
00142 /***********************************************************************
00143  */
00144 
00145 
00146 static void upload_IAB( struct i915_context *i915 )
00147 {
00148    unsigned iab = i915->blend->iab;
00149 
00150 
00151    set_dynamic_indirect( i915,
00152                          I915_DYNAMIC_IAB,
00153                          &iab,
00154                          1 );
00155 }
00156 
00157 const struct i915_tracked_state i915_upload_IAB = {
00158    I915_NEW_BLEND,
00159    upload_IAB
00160 };
00161 
00162 
00163 /***********************************************************************
00164  */
00165 
00166 
00167 
00168 static void upload_DEPTHSCALE( struct i915_context *i915 )
00169 {
00170    set_dynamic_indirect( i915,
00171                          I915_DYNAMIC_DEPTHSCALE_0,
00172                          &(i915->rasterizer->ds[0].u),
00173                          2 );
00174 }
00175 
00176 const struct i915_tracked_state i915_upload_DEPTHSCALE = {
00177    I915_NEW_RASTERIZER,
00178    upload_DEPTHSCALE
00179 };
00180 
00181 
00182 
00183 /***********************************************************************
00184  * Polygon stipple
00185  *
00186  * The i915 supports a 4x4 stipple natively, GL wants 32x32.
00187  * Fortunately stipple is usually a repeating pattern.
00188  *
00189  * XXX: does stipple pattern need to be adjusted according to
00190  * the window position?
00191  *
00192  * XXX: possibly need workaround for conform paths test. 
00193  */
00194 
00195 static void upload_STIPPLE( struct i915_context *i915 )
00196 {
00197    unsigned st[2];
00198 
00199    st[0] = _3DSTATE_STIPPLE;
00200    st[1] = 0;
00201 
00202    /* I915_NEW_RASTERIZER
00203     */
00204    st[1] |= i915->rasterizer->st;
00205 
00206 
00207    /* I915_NEW_STIPPLE
00208     */
00209    {
00210       const ubyte *mask = (const ubyte *)i915->poly_stipple.stipple;
00211       ubyte p[4];
00212 
00213       p[0] = mask[12] & 0xf;
00214       p[1] = mask[8] & 0xf;
00215       p[2] = mask[4] & 0xf;
00216       p[3] = mask[0] & 0xf;
00217 
00218       /* Not sure what to do about fallbacks, so for now just dont:
00219        */
00220       st[1] |= ((p[0] << 0) |
00221                 (p[1] << 4) |
00222                 (p[2] << 8) | 
00223                 (p[3] << 12));
00224    }
00225 
00226 
00227    set_dynamic_indirect( i915, 
00228                          I915_DYNAMIC_STP_0,
00229                          &st[0],
00230                          2 );
00231 }
00232 
00233 
00234 const struct i915_tracked_state i915_upload_STIPPLE = {
00235    I915_NEW_RASTERIZER | I915_NEW_STIPPLE,
00236    upload_STIPPLE
00237 };
00238 
00239 
00240 
00241 /***********************************************************************
00242  * Scissor.
00243  */
00244 static void upload_SCISSOR_ENABLE( struct i915_context *i915 )
00245 {
00246    set_dynamic_indirect( i915,
00247                          I915_DYNAMIC_SC_ENA_0,
00248                          &(i915->rasterizer->sc[0]),
00249                          1 );
00250 }
00251 
00252 const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = {
00253    I915_NEW_RASTERIZER,
00254    upload_SCISSOR_ENABLE
00255 };
00256 
00257 
00258 
00259 static void upload_SCISSOR_RECT( struct i915_context *i915 )
00260 {
00261    unsigned x1 = i915->scissor.minx;
00262    unsigned y1 = i915->scissor.miny;
00263    unsigned x2 = i915->scissor.maxx;
00264    unsigned y2 = i915->scissor.maxy;
00265    unsigned sc[3];
00266  
00267    sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD;
00268    sc[1] = (y1 << 16) | (x1 & 0xffff);
00269    sc[2] = (y2 << 16) | (x2 & 0xffff);
00270 
00271    set_dynamic_indirect( i915, 
00272                          I915_DYNAMIC_SC_RECT_0,
00273                          &sc[0],
00274                          3 );
00275 }
00276 
00277 
00278 const struct i915_tracked_state i915_upload_SCISSOR_RECT = {
00279    I915_NEW_SCISSOR,
00280    upload_SCISSOR_RECT
00281 };
00282 
00283 
00284 
00285 
00286 
00287 
00288 static const struct i915_tracked_state *atoms[] = {
00289    &i915_upload_MODES4,
00290    &i915_upload_BFO,
00291    &i915_upload_BLENDCOLOR,
00292    &i915_upload_IAB,
00293    &i915_upload_DEPTHSCALE,
00294    &i915_upload_STIPPLE,
00295    &i915_upload_SCISSOR_ENABLE,
00296    &i915_upload_SCISSOR_RECT
00297 };
00298 
00299 /* These will be dynamic indirect state commands, but for now just end
00300  * up on the batch buffer with everything else.
00301  */
00302 void i915_update_dynamic( struct i915_context *i915 )
00303 {
00304    int i;
00305 
00306    for (i = 0; i < Elements(atoms); i++)
00307       if (i915->dirty & atoms[i]->dirty)
00308          atoms[i]->update( i915 );
00309 }
00310 

Generated on Tue Sep 29 06:25:16 2009 for Gallium3D by  doxygen 1.5.4