brw_misc_state.c

Go to the documentation of this file.
00001 /*
00002  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
00003  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
00004  develop this 3D driver.
00005 
00006  Permission is hereby granted, free of charge, to any person obtaining
00007  a 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, sublicense, 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
00016  portions of the Software.
00017 
00018  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00021  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
00022  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025 
00026  **********************************************************************/
00027  /*
00028   * Authors:
00029   *   Keith Whitwell <keith@tungstengraphics.com>
00030   */
00031 
00032 #include "brw_batch.h"
00033 #include "brw_context.h"
00034 #include "brw_state.h"
00035 #include "brw_defines.h"
00036 
00037 
00038 
00039 
00040 
00041 /***********************************************************************
00042  * Blend color
00043  */
00044 
00045 static void upload_blend_constant_color(struct brw_context *brw)
00046 {
00047    struct brw_blend_constant_color bcc;
00048 
00049    memset(&bcc, 0, sizeof(bcc));
00050    bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
00051    bcc.header.length = sizeof(bcc)/4-2;
00052    bcc.blend_constant_color[0] = brw->attribs.BlendColor.color[0];
00053    bcc.blend_constant_color[1] = brw->attribs.BlendColor.color[1];
00054    bcc.blend_constant_color[2] = brw->attribs.BlendColor.color[2];
00055    bcc.blend_constant_color[3] = brw->attribs.BlendColor.color[3];
00056 
00057    BRW_CACHED_BATCH_STRUCT(brw, &bcc);
00058 }
00059 
00060 
00061 const struct brw_tracked_state brw_blend_constant_color = {
00062    .dirty = {
00063       .brw = BRW_NEW_BLEND,
00064       .cache = 0
00065    },
00066    .update = upload_blend_constant_color
00067 };
00068 
00069 
00070 /***********************************************************************
00071  * Drawing rectangle 
00072  */
00073 static void upload_drawing_rect(struct brw_context *brw)
00074 {
00075    struct brw_drawrect bdr;
00076 
00077    memset(&bdr, 0, sizeof(bdr));
00078    bdr.header.opcode = CMD_DRAW_RECT;
00079    bdr.header.length = sizeof(bdr)/4 - 2;
00080    bdr.xmin = 0;
00081    bdr.ymin = 0;
00082    bdr.xmax = brw->attribs.FrameBuffer.cbufs[0]->width;
00083    bdr.ymax = brw->attribs.FrameBuffer.cbufs[0]->height;
00084    bdr.xorg = 0;
00085    bdr.yorg = 0;
00086 
00087    /* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted
00088     * uncached in brw_draw.c:
00089     */
00090    BRW_BATCH_STRUCT(brw, &bdr);
00091 }
00092 
00093 const struct brw_tracked_state brw_drawing_rect = {
00094    .dirty = {
00095       .brw = BRW_NEW_SCENE,
00096       .cache = 0
00097    },
00098    .update = upload_drawing_rect
00099 };
00100 
00108 static void upload_binding_table_pointers(struct brw_context *brw)
00109 {
00110    struct brw_binding_table_pointers btp;
00111    memset(&btp, 0, sizeof(btp));
00112 
00113    btp.header.opcode = CMD_BINDING_TABLE_PTRS;
00114    btp.header.length = sizeof(btp)/4 - 2;
00115    btp.vs = 0;
00116    btp.gs = 0;
00117    btp.clp = 0;
00118    btp.sf = 0;
00119    btp.wm = brw->wm.bind_ss_offset;
00120 
00121    BRW_CACHED_BATCH_STRUCT(brw, &btp);
00122 }
00123 
00124 const struct brw_tracked_state brw_binding_table_pointers = {
00125    .dirty = {
00126       .brw = 0,
00127       .cache = CACHE_NEW_SURF_BIND
00128    },
00129    .update = upload_binding_table_pointers,
00130 };
00131 
00132 
00139 static void upload_pipelined_state_pointers(struct brw_context *brw )
00140 {
00141    struct brw_pipelined_state_pointers psp;
00142    memset(&psp, 0, sizeof(psp));
00143 
00144    psp.header.opcode = CMD_PIPELINED_STATE_POINTERS;
00145    psp.header.length = sizeof(psp)/4 - 2;
00146 
00147    psp.vs.offset = brw->vs.state_gs_offset >> 5;
00148    psp.sf.offset = brw->sf.state_gs_offset >> 5;
00149    psp.wm.offset = brw->wm.state_gs_offset >> 5;
00150    psp.cc.offset = brw->cc.state_gs_offset >> 5;
00151 
00152    /* GS gets turned on and off regularly.  Need to re-emit URB fence
00153     * after this occurs.
00154     */
00155    if (brw->gs.prog_active) {
00156       psp.gs.offset = brw->gs.state_gs_offset >> 5;
00157       psp.gs.enable = 1;
00158    }
00159 
00160    if (0) {
00161       psp.clp.offset = brw->clip.state_gs_offset >> 5;
00162       psp.clp.enable = 1;
00163    }
00164 
00165 
00166    if (BRW_CACHED_BATCH_STRUCT(brw, &psp))
00167       brw->state.dirty.brw |= BRW_NEW_PSP;
00168 }
00169 
00170 const struct brw_tracked_state brw_pipelined_state_pointers = {
00171    .dirty = {
00172       .brw = 0,
00173       .cache = (CACHE_NEW_VS_UNIT |
00174                 CACHE_NEW_GS_UNIT |
00175                 CACHE_NEW_GS_PROG |
00176                 CACHE_NEW_CLIP_UNIT |
00177                 CACHE_NEW_SF_UNIT |
00178                 CACHE_NEW_WM_UNIT |
00179                 CACHE_NEW_CC_UNIT)
00180    },
00181    .update = upload_pipelined_state_pointers
00182 };
00183 
00184 static void upload_psp_urb_cbs(struct brw_context *brw )
00185 {
00186    upload_pipelined_state_pointers(brw);
00187    brw_upload_urb_fence(brw);
00188    brw_upload_constant_buffer_state(brw);
00189 }
00190 
00191 
00192 const struct brw_tracked_state brw_psp_urb_cbs = {
00193    .dirty = {
00194       .brw = BRW_NEW_URB_FENCE,
00195       .cache = (CACHE_NEW_VS_UNIT |
00196                 CACHE_NEW_GS_UNIT |
00197                 CACHE_NEW_GS_PROG |
00198                 CACHE_NEW_CLIP_UNIT |
00199                 CACHE_NEW_SF_UNIT |
00200                 CACHE_NEW_WM_UNIT |
00201                 CACHE_NEW_CC_UNIT)
00202    },
00203    .update = upload_psp_urb_cbs
00204 };
00205 
00212 static void upload_depthbuffer(struct brw_context *brw)
00213 {
00214    struct pipe_surface *depth_surface = brw->attribs.FrameBuffer.zsbuf;
00215 
00216    BEGIN_BATCH(5, INTEL_BATCH_NO_CLIPRECTS);
00217    OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (5 - 2));
00218    if (depth_surface == NULL) {
00219       OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
00220                 (BRW_SURFACE_NULL << 29));
00221       OUT_BATCH(0);
00222       OUT_BATCH(0);
00223       OUT_BATCH(0);
00224    } else {
00225       unsigned int format;
00226 
00227       assert(depth_surface->block.width == 1);
00228       assert(depth_surface->block.height == 1);
00229       switch (depth_surface->block.size) {
00230       case 2:
00231          format = BRW_DEPTHFORMAT_D16_UNORM;
00232          break;
00233       case 4:
00234          if (depth_surface->format == PIPE_FORMAT_Z32_FLOAT)
00235             format = BRW_DEPTHFORMAT_D32_FLOAT;
00236          else
00237             format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
00238          break;
00239       default:
00240          assert(0);
00241          return;
00242       }
00243 
00244       OUT_BATCH((depth_surface->stride - 1) |
00245                 (format << 18) |
00246                 (BRW_TILEWALK_YMAJOR << 26) |
00247 //              (depth_surface->region->tiled << 27) |
00248                 (BRW_SURFACE_2D << 29));
00249       OUT_RELOC(depth_surface->buffer,
00250                 PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE, 0);
00251       OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
00252                 ((depth_surface->stride/depth_surface->block.size - 1) << 6) |
00253                 ((depth_surface->height - 1) << 19));
00254       OUT_BATCH(0);
00255    }
00256    ADVANCE_BATCH();
00257 }
00258 
00259 const struct brw_tracked_state brw_depthbuffer = {
00260    .dirty = {
00261       .brw = BRW_NEW_SCENE,
00262       .cache = 0
00263    },
00264    .update = upload_depthbuffer,
00265 };
00266 
00267 
00268 
00269 
00270 /***********************************************************************
00271  * Polygon stipple packet
00272  */
00273 
00274 static void upload_polygon_stipple(struct brw_context *brw)
00275 {
00276    struct brw_polygon_stipple bps;
00277    unsigned i;
00278 
00279    memset(&bps, 0, sizeof(bps));
00280    bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
00281    bps.header.length = sizeof(bps)/4-2;
00282 
00283    /* XXX: state tracker should send *all* state down initially!
00284     */
00285    if (brw->attribs.PolygonStipple)
00286       for (i = 0; i < 32; i++)
00287          bps.stipple[i] = brw->attribs.PolygonStipple->stipple[31 - i]; /* invert */
00288 
00289    BRW_CACHED_BATCH_STRUCT(brw, &bps);
00290 }
00291 
00292 const struct brw_tracked_state brw_polygon_stipple = {
00293    .dirty = {
00294       .brw = BRW_NEW_STIPPLE,
00295       .cache = 0
00296    },
00297    .update = upload_polygon_stipple
00298 };
00299 
00300 
00301 /***********************************************************************
00302  * Line stipple packet
00303  */
00304 
00305 static void upload_line_stipple(struct brw_context *brw)
00306 {
00307    struct brw_line_stipple bls;
00308    float tmp;
00309    int tmpi;
00310 
00311    memset(&bls, 0, sizeof(bls));
00312    bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
00313    bls.header.length = sizeof(bls)/4 - 2;
00314 
00315    bls.bits0.pattern = brw->attribs.Raster->line_stipple_pattern;
00316    bls.bits1.repeat_count = brw->attribs.Raster->line_stipple_factor;
00317 
00318    tmp = 1.0 / (float) brw->attribs.Raster->line_stipple_factor;
00319    tmpi = tmp * (1<<13);
00320 
00321 
00322    bls.bits1.inverse_repeat_count = tmpi;
00323 
00324    BRW_CACHED_BATCH_STRUCT(brw, &bls);
00325 }
00326 
00327 const struct brw_tracked_state brw_line_stipple = {
00328    .dirty = {
00329       .brw = BRW_NEW_STIPPLE,
00330       .cache = 0
00331    },
00332    .update = upload_line_stipple
00333 };
00334 
00335 
00336 /***********************************************************************
00337  * Misc constant state packets
00338  */
00339 
00340 static void upload_pipe_control(struct brw_context *brw)
00341 {
00342    struct brw_pipe_control pc;
00343 
00344    return;
00345 
00346    memset(&pc, 0, sizeof(pc));
00347 
00348    pc.header.opcode = CMD_PIPE_CONTROL;
00349    pc.header.length = sizeof(pc)/4 - 2;
00350    pc.header.post_sync_operation = PIPE_CONTROL_NOWRITE;
00351 
00352    pc.header.instruction_state_cache_flush_enable = 1;
00353 
00354    pc.bits1.dest_addr_type = PIPE_CONTROL_GTTWRITE_GLOBAL;
00355 
00356    BRW_BATCH_STRUCT(brw, &pc);
00357 }
00358 
00359 const struct brw_tracked_state brw_pipe_control = {
00360    .dirty = {
00361       .brw = BRW_NEW_SCENE,
00362       .cache = 0
00363    },
00364    .update = upload_pipe_control
00365 };
00366 
00367 
00368 /***********************************************************************
00369  * Misc invarient state packets
00370  */
00371 
00372 static void upload_invarient_state( struct brw_context *brw )
00373 {
00374    {
00375       struct brw_mi_flush flush;
00376 
00377       memset(&flush, 0, sizeof(flush));      
00378       flush.opcode = CMD_MI_FLUSH;
00379       flush.flags = BRW_FLUSH_STATE_CACHE | BRW_FLUSH_READ_CACHE;
00380       BRW_BATCH_STRUCT(brw, &flush);
00381    }
00382 
00383    {
00384       /* 0x61040000  Pipeline Select */
00385       /*     PipelineSelect            : 0 */
00386       struct brw_pipeline_select ps;
00387 
00388       memset(&ps, 0, sizeof(ps));
00389       ps.header.opcode = CMD_PIPELINE_SELECT;
00390       ps.header.pipeline_select = 0;
00391       BRW_BATCH_STRUCT(brw, &ps);
00392    }
00393 
00394    {
00395       struct brw_global_depth_offset_clamp gdo;
00396       memset(&gdo, 0, sizeof(gdo));
00397 
00398       /* Disable depth offset clamping.
00399        */
00400       gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
00401       gdo.header.length = sizeof(gdo)/4 - 2;
00402       gdo.depth_offset_clamp = 0.0;
00403 
00404       BRW_BATCH_STRUCT(brw, &gdo);
00405    }
00406 
00407 
00408    /* 0x61020000  State Instruction Pointer */
00409    {
00410       struct brw_system_instruction_pointer sip;
00411       memset(&sip, 0, sizeof(sip));
00412 
00413       sip.header.opcode = CMD_STATE_INSN_POINTER;
00414       sip.header.length = 0;
00415       sip.bits0.pad = 0;
00416       sip.bits0.system_instruction_pointer = 0;
00417       BRW_BATCH_STRUCT(brw, &sip);
00418    }
00419 
00420 
00421    {
00422       struct brw_vf_statistics vfs;
00423       memset(&vfs, 0, sizeof(vfs));
00424 
00425       vfs.opcode = CMD_VF_STATISTICS;
00426       if (BRW_DEBUG & DEBUG_STATS)
00427          vfs.statistics_enable = 1;
00428 
00429       BRW_BATCH_STRUCT(brw, &vfs);
00430    }
00431 
00432    
00433    {
00434       struct brw_polygon_stipple_offset bpso;
00435       
00436       memset(&bpso, 0, sizeof(bpso));
00437       bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
00438       bpso.header.length = sizeof(bpso)/4-2;      
00439       bpso.bits0.x_offset = 0;
00440       bpso.bits0.y_offset = 0;
00441 
00442       BRW_BATCH_STRUCT(brw, &bpso);
00443    }
00444 }
00445 
00446 const struct brw_tracked_state brw_invarient_state = {
00447    .dirty = {
00448       .brw = BRW_NEW_SCENE,
00449       .cache = 0
00450    },
00451    .update = upload_invarient_state
00452 };
00453 
00462 static void upload_state_base_address( struct brw_context *brw )
00463 {
00464    /* Output the structure (brw_state_base_address) directly to the
00465     * batchbuffer, so we can emit relocations inline.
00466     */
00467    BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
00468    OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
00469    OUT_RELOC(brw->pool[BRW_GS_POOL].buffer,
00470              PIPE_BUFFER_USAGE_GPU_READ,
00471              1); /* General state base address */
00472    OUT_RELOC(brw->pool[BRW_SS_POOL].buffer,
00473              PIPE_BUFFER_USAGE_GPU_READ,
00474              1); /* Surface state base address */
00475    OUT_BATCH(1); /* Indirect object base address */
00476    OUT_BATCH(1); /* General state upper bound */
00477    OUT_BATCH(1); /* Indirect object upper bound */
00478    ADVANCE_BATCH();
00479 }
00480 
00481 
00482 const struct brw_tracked_state brw_state_base_address = {
00483    .dirty = {
00484       .brw = BRW_NEW_SCENE,
00485       .cache = 0
00486    },
00487    .update = upload_state_base_address
00488 };

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