summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_misc_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_misc_state.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c529
1 files changed, 529 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
new file mode 100644
index 0000000000..49a8a6e4a8
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -0,0 +1,529 @@
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+
+#include "intel_batchbuffer.h"
+#include "intel_regions.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+
+
+
+
+
+/***********************************************************************
+ * Blend color
+ */
+
+static void upload_blend_constant_color(struct brw_context *brw)
+{
+ struct brw_blend_constant_color bcc;
+
+ memset(&bcc, 0, sizeof(bcc));
+ bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
+ bcc.header.length = sizeof(bcc)/4-2;
+ bcc.blend_constant_color[0] = brw->attribs.Color->BlendColor[0];
+ bcc.blend_constant_color[1] = brw->attribs.Color->BlendColor[1];
+ bcc.blend_constant_color[2] = brw->attribs.Color->BlendColor[2];
+ bcc.blend_constant_color[3] = brw->attribs.Color->BlendColor[3];
+
+ BRW_CACHED_BATCH_STRUCT(brw, &bcc);
+}
+
+
+const struct brw_tracked_state brw_blend_constant_color = {
+ .dirty = {
+ .mesa = _NEW_COLOR,
+ .brw = 0,
+ .cache = 0
+ },
+ .update = upload_blend_constant_color
+};
+
+/***********************************************************************
+ * Drawing rectangle -- Need for AUB file only.
+ */
+
+static void upload_drawing_rect(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ struct brw_drawrect bdr;
+ int x1, y1;
+ int x2, y2;
+
+ if (!brw->intel.aub_file)
+ return;
+
+ /* Basically calculate a single cliprect for the whole window.
+ * Don't bother iterating over cliprects at the moment.
+ */
+
+ x1 = dPriv->x;
+ y1 = dPriv->y;
+ x2 = dPriv->x + dPriv->w;
+ y2 = dPriv->y + dPriv->h;
+
+ if (x1 < 0) x1 = 0;
+ if (y1 < 0) y1 = 0;
+ if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
+ if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
+
+ memset(&bdr, 0, sizeof(bdr));
+ bdr.header.opcode = CMD_DRAW_RECT;
+ bdr.header.length = sizeof(bdr)/4 - 2;
+ bdr.xmin = x1;
+ bdr.ymin = y1;
+ bdr.xmax = x2;
+ bdr.ymax = y2;
+ bdr.xorg = dPriv->x;
+ bdr.yorg = dPriv->y;
+
+ BRW_CACHED_BATCH_STRUCT(brw, &bdr);
+}
+
+const struct brw_tracked_state brw_drawing_rect = {
+ .dirty = {
+ .mesa = _NEW_WINDOW_POS,
+ .brw = 0,
+ .cache = 0
+ },
+ .update = upload_drawing_rect
+};
+
+/***********************************************************************
+ * Binding table pointers
+ */
+
+static void upload_binding_table_pointers(struct brw_context *brw)
+{
+ struct brw_binding_table_pointers btp;
+ memset(&btp, 0, sizeof(btp));
+
+ /* The binding table has been emitted to the SS pool already, so we
+ * know what its offset is. When the batch buffer is fired, the
+ * binding table and surface structs will get fixed up to point to
+ * where the textures actually landed, but that won't change the
+ * value of the offsets here:
+ */
+ btp.header.opcode = CMD_BINDING_TABLE_PTRS;
+ btp.header.length = sizeof(btp)/4 - 2;
+ btp.vs = 0;
+ btp.gs = 0;
+ btp.clp = 0;
+ btp.sf = 0;
+ btp.wm = brw->wm.bind_ss_offset;
+
+ BRW_CACHED_BATCH_STRUCT(brw, &btp);
+}
+
+const struct brw_tracked_state brw_binding_table_pointers = {
+ .dirty = {
+ .mesa = 0,
+ .brw = 0,
+ .cache = CACHE_NEW_SURF_BIND
+ },
+ .update = upload_binding_table_pointers
+};
+
+
+/***********************************************************************
+ * Pipelined state pointers. This is the key state packet from which
+ * the hardware chases pointers to all the uploaded state in VRAM.
+ */
+
+static void upload_pipelined_state_pointers(struct brw_context *brw )
+{
+ struct brw_pipelined_state_pointers psp;
+ memset(&psp, 0, sizeof(psp));
+
+ psp.header.opcode = CMD_PIPELINED_STATE_POINTERS;
+ psp.header.length = sizeof(psp)/4 - 2;
+
+ psp.vs.offset = brw->vs.state_gs_offset >> 5;
+ psp.sf.offset = brw->sf.state_gs_offset >> 5;
+ psp.wm.offset = brw->wm.state_gs_offset >> 5;
+ psp.cc.offset = brw->cc.state_gs_offset >> 5;
+
+ /* GS gets turned on and off regularly. Need to re-emit URB fence
+ * after this occurs.
+ */
+ if (brw->gs.prog_active) {
+ psp.gs.offset = brw->gs.state_gs_offset >> 5;
+ psp.gs.enable = 1;
+ }
+
+ if (!brw->metaops.active) {
+ psp.clp.offset = brw->clip.state_gs_offset >> 5;
+ psp.clp.enable = 1;
+ }
+
+
+ if (BRW_CACHED_BATCH_STRUCT(brw, &psp))
+ brw->state.dirty.brw |= BRW_NEW_PSP;
+}
+
+const struct brw_tracked_state brw_pipelined_state_pointers = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_METAOPS,
+ .cache = (CACHE_NEW_VS_UNIT |
+ CACHE_NEW_GS_UNIT |
+ CACHE_NEW_GS_PROG |
+ CACHE_NEW_CLIP_UNIT |
+ CACHE_NEW_SF_UNIT |
+ CACHE_NEW_WM_UNIT |
+ CACHE_NEW_CC_UNIT)
+ },
+ .update = upload_pipelined_state_pointers
+};
+
+static void upload_psp_urb_cbs(struct brw_context *brw )
+{
+ upload_pipelined_state_pointers(brw);
+ brw_upload_urb_fence(brw);
+ brw_upload_constant_buffer_state(brw);
+}
+
+
+const struct brw_tracked_state brw_psp_urb_cbs = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_URB_FENCE | BRW_NEW_METAOPS,
+ .cache = (CACHE_NEW_VS_UNIT |
+ CACHE_NEW_GS_UNIT |
+ CACHE_NEW_GS_PROG |
+ CACHE_NEW_CLIP_UNIT |
+ CACHE_NEW_SF_UNIT |
+ CACHE_NEW_WM_UNIT |
+ CACHE_NEW_CC_UNIT)
+ },
+ .update = upload_psp_urb_cbs
+};
+
+
+
+
+/***********************************************************************
+ * Depthbuffer - currently constant, but rotation would change that.
+ */
+
+static void upload_depthbuffer(struct brw_context *brw)
+{
+ /* 0x79050003 Depth Buffer */
+ struct intel_context *intel = &brw->intel;
+ struct intel_region *region = brw->state.depth_region;
+ struct brw_depthbuffer bd;
+ memset(&bd, 0, sizeof(bd));
+
+ bd.header.bits.opcode = CMD_DEPTH_BUFFER;
+ bd.header.bits.length = sizeof(bd)/4-2;
+ bd.dword1.bits.pitch = (region->pitch * region->cpp) - 1;
+
+ switch (region->cpp) {
+ case 2:
+ bd.dword1.bits.format = BRW_DEPTHFORMAT_D16_UNORM;
+ break;
+ case 4:
+ if (intel->depth_buffer_is_float)
+ bd.dword1.bits.format = BRW_DEPTHFORMAT_D32_FLOAT;
+ else
+ bd.dword1.bits.format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ bd.dword1.bits.depth_offset_disable = 0; /* coordinate offset */
+
+ /* The depthbuffer can only use YMAJOR tiling... This is a bit of
+ * a shame as it clashes with the 2d blitter which only supports
+ * XMAJOR tiling...
+ */
+ bd.dword1.bits.tile_walk = BRW_TILEWALK_YMAJOR;
+ bd.dword1.bits.tiled_surface = intel->depth_region->tiled;
+ bd.dword1.bits.surface_type = BRW_SURFACE_2D;
+
+ bd.dword2_base_addr = bmBufferOffset(intel, region->buffer);
+
+ bd.dword3.bits.mipmap_layout = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ bd.dword3.bits.lod = 0;
+ bd.dword3.bits.width = region->pitch - 1; /* XXX: width ? */
+ bd.dword3.bits.height = region->height - 1;
+
+ bd.dword4.bits.min_array_element = 0;
+ bd.dword4.bits.depth = 0;
+
+ BRW_CACHED_BATCH_STRUCT(brw, &bd);
+}
+
+const struct brw_tracked_state brw_depthbuffer = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT | BRW_NEW_FENCE,
+ .cache = 0
+ },
+ .update = upload_depthbuffer
+};
+
+
+
+/***********************************************************************
+ * Polygon stipple packet
+ */
+
+static void upload_polygon_stipple(struct brw_context *brw)
+{
+ struct brw_polygon_stipple bps;
+ GLuint i;
+
+ memset(&bps, 0, sizeof(bps));
+ bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
+ bps.header.length = sizeof(bps)/4-2;
+
+ for (i = 0; i < 32; i++)
+ bps.stipple[i] = brw->attribs.PolygonStipple[31 - i]; /* invert */
+
+ BRW_CACHED_BATCH_STRUCT(brw, &bps);
+}
+
+const struct brw_tracked_state brw_polygon_stipple = {
+ .dirty = {
+ .mesa = _NEW_POLYGONSTIPPLE,
+ .brw = 0,
+ .cache = 0
+ },
+ .update = upload_polygon_stipple
+};
+
+
+/***********************************************************************
+ * Polygon stipple offset packet
+ */
+
+static void upload_polygon_stipple_offset(struct brw_context *brw)
+{
+ __DRIdrawablePrivate *dPriv = brw->intel.driDrawable;
+ struct brw_polygon_stipple_offset bpso;
+
+ memset(&bpso, 0, sizeof(bpso));
+ bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
+ bpso.header.length = sizeof(bpso)/4-2;
+
+ bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31;
+ bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31;
+
+ BRW_CACHED_BATCH_STRUCT(brw, &bpso);
+}
+
+const struct brw_tracked_state brw_polygon_stipple_offset = {
+ .dirty = {
+ .mesa = _NEW_WINDOW_POS,
+ .brw = 0,
+ .cache = 0
+ },
+ .update = upload_polygon_stipple_offset
+};
+
+/***********************************************************************
+ * Line stipple packet
+ */
+
+static void upload_line_stipple(struct brw_context *brw)
+{
+ struct brw_line_stipple bls;
+ GLfloat tmp;
+ GLint tmpi;
+
+ memset(&bls, 0, sizeof(bls));
+ bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
+ bls.header.length = sizeof(bls)/4 - 2;
+
+ bls.bits0.pattern = brw->attribs.Line->StipplePattern;
+ bls.bits1.repeat_count = brw->attribs.Line->StippleFactor;
+
+ tmp = 1.0 / (GLfloat) brw->attribs.Line->StippleFactor;
+ tmpi = tmp * (1<<13);
+
+
+ bls.bits1.inverse_repeat_count = tmpi;
+
+ BRW_CACHED_BATCH_STRUCT(brw, &bls);
+}
+
+const struct brw_tracked_state brw_line_stipple = {
+ .dirty = {
+ .mesa = _NEW_LINE,
+ .brw = 0,
+ .cache = 0
+ },
+ .update = upload_line_stipple
+};
+
+
+
+/***********************************************************************
+ * Misc constant state packets
+ */
+
+static void upload_pipe_control(struct brw_context *brw)
+{
+ struct brw_pipe_control pc;
+
+ return;
+
+ memset(&pc, 0, sizeof(pc));
+
+ pc.header.opcode = CMD_PIPE_CONTROL;
+ pc.header.length = sizeof(pc)/4 - 2;
+ pc.header.post_sync_operation = PIPE_CONTROL_NOWRITE;
+
+ pc.header.instruction_state_cache_flush_enable = 1;
+
+ pc.bits1.dest_addr_type = PIPE_CONTROL_GTTWRITE_GLOBAL;
+
+ BRW_BATCH_STRUCT(brw, &pc);
+}
+
+const struct brw_tracked_state brw_pipe_control = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT,
+ .cache = 0
+ },
+ .update = upload_pipe_control
+};
+
+
+/***********************************************************************
+ * Misc invarient state packets
+ */
+
+static void upload_invarient_state( struct brw_context *brw )
+{
+ {
+ /* 0x61040000 Pipeline Select */
+ /* PipelineSelect : 0 */
+ struct brw_pipeline_select ps;
+
+ memset(&ps, 0, sizeof(ps));
+ ps.header.opcode = CMD_PIPELINE_SELECT;
+ ps.header.pipeline_select = 0;
+ BRW_BATCH_STRUCT(brw, &ps);
+ }
+
+ {
+ struct brw_global_depth_offset_clamp gdo;
+ memset(&gdo, 0, sizeof(gdo));
+
+ /* Disable depth offset clamping.
+ */
+ gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
+ gdo.header.length = sizeof(gdo)/4 - 2;
+ gdo.depth_offset_clamp = 0.0;
+
+ BRW_BATCH_STRUCT(brw, &gdo);
+ }
+
+
+ /* 0x61020000 State Instruction Pointer */
+ {
+ struct brw_system_instruction_pointer sip;
+ memset(&sip, 0, sizeof(sip));
+
+ sip.header.opcode = CMD_STATE_INSN_POINTER;
+ sip.header.length = 0;
+ sip.bits0.pad = 0;
+ sip.bits0.system_instruction_pointer = 0;
+ BRW_BATCH_STRUCT(brw, &sip);
+ }
+
+
+ {
+ struct brw_vf_statistics vfs;
+ memset(&vfs, 0, sizeof(vfs));
+
+ vfs.opcode = CMD_VF_STATISTICS;
+ if (INTEL_DEBUG & DEBUG_STATS)
+ vfs.statistics_enable = 1;
+
+ BRW_BATCH_STRUCT(brw, &vfs);
+ }
+}
+
+const struct brw_tracked_state brw_invarient_state = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT,
+ .cache = 0
+ },
+ .update = upload_invarient_state
+};
+
+
+/* State pool addresses:
+ */
+static void upload_state_base_address( struct brw_context *brw )
+{
+ struct intel_context *intel = &brw->intel;
+ struct brw_state_base_address sba;
+
+ memset(&sba, 0, sizeof(sba));
+
+ sba.header.opcode = CMD_STATE_BASE_ADDRESS;
+ sba.header.length = 0x4;
+
+ sba.bits0.general_state_address = bmBufferOffset(intel, brw->pool[BRW_GS_POOL].buffer) >> 5;
+ sba.bits0.modify_enable = 1;
+
+ sba.bits1.surface_state_address = bmBufferOffset(intel, brw->pool[BRW_SS_POOL].buffer) >> 5;
+ sba.bits1.modify_enable = 1;
+
+ sba.bits2.modify_enable = 1;
+ sba.bits3.modify_enable = 1;
+ sba.bits4.modify_enable = 1;
+
+ BRW_CACHED_BATCH_STRUCT(brw, &sba);
+}
+
+
+const struct brw_tracked_state brw_state_base_address = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_CONTEXT | BRW_NEW_FENCE,
+ .cache = 0
+ },
+ .update = upload_state_base_address
+};