i915_state_emit.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 
00029 #include "i915_reg.h"
00030 #include "i915_context.h"
00031 #include "i915_winsys.h"
00032 #include "i915_batch.h"
00033 #include "i915_reg.h"
00034 
00035 #include "pipe/p_context.h"
00036 #include "pipe/p_defines.h"
00037 
00038 static unsigned translate_format( enum pipe_format format )
00039 {
00040    switch (format) {
00041    case PIPE_FORMAT_A8R8G8B8_UNORM:
00042       return COLOR_BUF_ARGB8888;
00043    case PIPE_FORMAT_R5G6B5_UNORM:
00044       return COLOR_BUF_RGB565;
00045    default:
00046       assert(0);
00047       return 0;
00048    }
00049 }
00050 
00051 static unsigned translate_depth_format( enum pipe_format zformat )
00052 {
00053    switch (zformat) {
00054    case PIPE_FORMAT_S8Z24_UNORM:
00055       return DEPTH_FRMT_24_FIXED_8_OTHER;
00056    case PIPE_FORMAT_Z16_UNORM:
00057       return DEPTH_FRMT_16_FIXED;
00058    default:
00059       assert(0);
00060       return 0;
00061    }
00062 }
00063 
00064 
00068 static boolean
00069 framebuffer_size(const struct pipe_framebuffer_state *fb,
00070                  uint *width, uint *height)
00071 {
00072    if (fb->cbufs[0]) {
00073       *width = fb->cbufs[0]->width;
00074       *height = fb->cbufs[0]->height;
00075       return TRUE;
00076    }
00077    else if (fb->zsbuf) {
00078       *width = fb->zsbuf->width;
00079       *height = fb->zsbuf->height;
00080       return TRUE;
00081    }
00082    else {
00083       *width = *height = 0;
00084       return FALSE;
00085    }
00086 }
00087 
00088 
00089 /* Push the state into the sarea and/or texture memory.
00090  */
00091 void
00092 i915_emit_hardware_state(struct i915_context *i915 )
00093 {
00094    /* XXX: there must be an easier way */
00095    const unsigned dwords = ( 14 + 
00096                              7 + 
00097                              I915_MAX_DYNAMIC + 
00098                              8 + 
00099                              2 + I915_TEX_UNITS*3 + 
00100                              2 + I915_TEX_UNITS*3 +
00101                              2 + I915_MAX_CONSTANT*4 + 
00102 #if 0
00103                              i915->current.program_len + 
00104 #else
00105                              i915->fs->program_len + 
00106 #endif
00107                              6 
00108                            ) * 3/2; /* plus 50% margin */
00109    const unsigned relocs = ( I915_TEX_UNITS +
00110                              3
00111                            ) * 3/2; /* plus 50% margin */
00112 
00113 #if 0
00114    debug_printf("i915_emit_hardware_state: %d dwords, %d relocs\n", dwords, relocs);
00115 #endif
00116    
00117    if(!BEGIN_BATCH(dwords, relocs)) {
00118       FLUSH_BATCH(NULL);
00119       assert(BEGIN_BATCH(dwords, relocs));
00120    }
00121 
00122    /* 14 dwords, 0 relocs */
00123    if (i915->hardware_dirty & I915_HW_INVARIENT)
00124    {
00125       OUT_BATCH(_3DSTATE_AA_CMD |
00126                 AA_LINE_ECAAR_WIDTH_ENABLE |
00127                 AA_LINE_ECAAR_WIDTH_1_0 |
00128                 AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
00129 
00130       OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
00131       OUT_BATCH(0);
00132 
00133       OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
00134       OUT_BATCH(0);
00135       
00136       OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
00137       OUT_BATCH(0);
00138 
00139       OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
00140                 CSB_TCB(0, 0) |
00141                 CSB_TCB(1, 1) |
00142                 CSB_TCB(2, 2) |
00143                 CSB_TCB(3, 3) |
00144                 CSB_TCB(4, 4) | 
00145                 CSB_TCB(5, 5) | 
00146                 CSB_TCB(6, 6) | 
00147                 CSB_TCB(7, 7));
00148 
00149       OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
00150                 ENABLE_POINT_RASTER_RULE |
00151                 OGL_POINT_RASTER_RULE |
00152                 ENABLE_LINE_STRIP_PROVOKE_VRTX |
00153                 ENABLE_TRI_FAN_PROVOKE_VRTX |
00154                 LINE_STRIP_PROVOKE_VRTX(1) |
00155                 TRI_FAN_PROVOKE_VRTX(2) | 
00156                 ENABLE_TEXKILL_3D_4D | 
00157                 TEXKILL_4D);
00158 
00159       /* Need to initialize this to zero.
00160        */
00161       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0));
00162       OUT_BATCH(0);
00163 
00164       OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
00165 
00166       /* disable indirect state for now
00167        */
00168       OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);
00169       OUT_BATCH(0);
00170    }
00171    
00172    /* 7 dwords, 1 relocs */
00173    if (i915->hardware_dirty & I915_HW_IMMEDIATE)
00174    {
00175       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 
00176                 I1_LOAD_S(0) |
00177                 I1_LOAD_S(1) |
00178                 I1_LOAD_S(2) |
00179                 I1_LOAD_S(4) |
00180                 I1_LOAD_S(5) |
00181                 I1_LOAD_S(6) | 
00182                 (5));
00183       
00184       if(i915->vbo)
00185          OUT_RELOC(i915->vbo,
00186                    I915_BUFFER_ACCESS_READ,
00187                    i915->current.immediate[I915_IMMEDIATE_S0]);
00188       else
00189          /* FIXME: we should not do this */
00190          OUT_BATCH(0);
00191       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]);
00192       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]);
00193       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]);
00194       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S5]);
00195       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S6]);
00196    } 
00197    
00198    /* I915_MAX_DYNAMIC dwords, 0 relocs */
00199    if (i915->hardware_dirty & I915_HW_DYNAMIC) 
00200    {
00201       int i;
00202       for (i = 0; i < I915_MAX_DYNAMIC; i++) {
00203          OUT_BATCH(i915->current.dynamic[i]);
00204       }
00205    }
00206    
00207    /* 8 dwords, 2 relocs */
00208    if (i915->hardware_dirty & I915_HW_STATIC)
00209    {
00210       struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
00211       struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
00212 
00213       if (cbuf_surface) {
00214          unsigned cpitch = cbuf_surface->stride;
00215          unsigned ctile = BUF_3D_USE_FENCE;
00216          if (cbuf_surface->texture &&
00217                ((struct i915_texture*)(cbuf_surface->texture))->tiled) {
00218             ctile = BUF_3D_TILED_SURFACE;
00219          }
00220 
00221          OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
00222 
00223          OUT_BATCH(BUF_3D_ID_COLOR_BACK | 
00224                    BUF_3D_PITCH(cpitch) |  /* pitch in bytes */
00225                    ctile);
00226 
00227          OUT_RELOC(cbuf_surface->buffer,
00228                    I915_BUFFER_ACCESS_WRITE,
00229                    cbuf_surface->offset);
00230       }
00231 
00232       /* What happens if no zbuf??
00233        */
00234       if (depth_surface) {
00235          unsigned zpitch = depth_surface->stride;
00236          unsigned ztile = BUF_3D_USE_FENCE;
00237          if (depth_surface->texture &&
00238                ((struct i915_texture*)(depth_surface->texture))->tiled) {
00239             ztile = BUF_3D_TILED_SURFACE;
00240          }
00241 
00242          OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
00243 
00244          OUT_BATCH(BUF_3D_ID_DEPTH |
00245                    BUF_3D_PITCH(zpitch) |  /* pitch in bytes */
00246                    ztile);
00247 
00248          OUT_RELOC(depth_surface->buffer,
00249                    I915_BUFFER_ACCESS_WRITE,
00250                    depth_surface->offset);
00251       }
00252    
00253       {
00254          unsigned cformat, zformat = 0;
00255       
00256          if (cbuf_surface)
00257             cformat = cbuf_surface->format;
00258          else
00259             cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */
00260          cformat = translate_format(cformat);
00261 
00262          if (depth_surface) 
00263             zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
00264 
00265          OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
00266          OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
00267                    DSTORG_VERT_BIAS(0x8) | /* .5 */
00268                    LOD_PRECLAMP_OGL |
00269                    TEX_DEFAULT_COLOR_OGL |
00270                    cformat |
00271                    zformat );
00272       }
00273    }
00274 
00275 #if 01
00276       /* texture images */
00277       /* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */
00278       if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER))
00279       {
00280          const uint nr = i915->current.sampler_enable_nr;
00281          if (nr) {
00282             const uint enabled = i915->current.sampler_enable_flags;
00283             uint unit;
00284             uint count = 0;
00285             OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
00286             OUT_BATCH(enabled);
00287             for (unit = 0; unit < I915_TEX_UNITS; unit++) {
00288                if (enabled & (1 << unit)) {
00289                   struct pipe_buffer *buf =
00290                      i915->texture[unit]->buffer;
00291                   uint offset = 0;
00292                   assert(buf);
00293 
00294                   count++;
00295 
00296                   OUT_RELOC(buf,
00297                             I915_BUFFER_ACCESS_READ,
00298                             offset);
00299                   OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
00300                   OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
00301                }
00302             }
00303             assert(count == nr);
00304          }
00305       }
00306 #endif
00307 
00308 #if 01
00309    /* samplers */
00310    /* 2 + I915_TEX_UNITS*3 dwords, 0 relocs */
00311    if (i915->hardware_dirty & I915_HW_SAMPLER) 
00312    {
00313       if (i915->current.sampler_enable_nr) {
00314          int i;
00315          
00316          OUT_BATCH( _3DSTATE_SAMPLER_STATE | 
00317                     (3 * i915->current.sampler_enable_nr) );
00318 
00319          OUT_BATCH( i915->current.sampler_enable_flags );
00320 
00321          for (i = 0; i < I915_TEX_UNITS; i++) {
00322             if (i915->current.sampler_enable_flags & (1<<i)) {
00323                OUT_BATCH( i915->current.sampler[i][0] );
00324                OUT_BATCH( i915->current.sampler[i][1] );
00325                OUT_BATCH( i915->current.sampler[i][2] );
00326             }
00327          }
00328       }
00329    }
00330 #endif
00331 
00332    /* constants */
00333    /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */
00334    if (i915->hardware_dirty & I915_HW_PROGRAM)
00335    {
00336       /* Collate the user-defined constants with the fragment shader's
00337        * immediates according to the constant_flags[] array.
00338        */
00339       const uint nr = i915->fs->num_constants;
00340       if (nr) {
00341          uint i;
00342 
00343          OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) );
00344          OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) );
00345 
00346          for (i = 0; i < nr; i++) {
00347             const uint *c;
00348             if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) {
00349                /* grab user-defined constant */
00350                c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i];
00351             }
00352             else {
00353                /* emit program constant */
00354                c = (uint *) i915->fs->constants[i];
00355             }
00356 #if 0 /* debug */
00357             {
00358                float *f = (float *) c;
00359                printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3],
00360                       (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER
00361                        ? "user" : "immediate"));
00362             }
00363 #endif
00364             OUT_BATCH(*c++);
00365             OUT_BATCH(*c++);
00366             OUT_BATCH(*c++);
00367             OUT_BATCH(*c++);
00368          }
00369       }
00370    }
00371 
00372    /* Fragment program */
00373    /* i915->current.program_len dwords, 0 relocs */
00374    if (i915->hardware_dirty & I915_HW_PROGRAM)
00375    {
00376       uint i;
00377       /* we should always have, at least, a pass-through program */
00378       assert(i915->fs->program_len > 0);
00379       for (i = 0; i < i915->fs->program_len; i++) {
00380          OUT_BATCH(i915->fs->program[i]);
00381       }
00382    }
00383 
00384    /* drawing surface size */
00385    /* 6 dwords, 0 relocs */
00386    {
00387       uint w, h;
00388       boolean k = framebuffer_size(&i915->framebuffer, &w, &h);
00389       (void)k;
00390       assert(k);
00391 
00392       OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
00393       OUT_BATCH(0);
00394       OUT_BATCH(0);
00395       OUT_BATCH(((w - 1) & 0xffff) | ((h - 1) << 16));
00396       OUT_BATCH(0);
00397       OUT_BATCH(0);
00398    }
00399 
00400 
00401    i915->hardware_dirty = 0;
00402 }

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