19f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*
29f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Copyright (C) Intel Corp.  2006.  All Rights Reserved.
39f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
49f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt develop this 3D driver.
59f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
69f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Permission is hereby granted, free of charge, to any person obtaining
79f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt a copy of this software and associated documentation files (the
89f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "Software"), to deal in the Software without restriction, including
99f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt without limitation the rights to use, copy, modify, merge, publish,
109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt distribute, sublicense, and/or sell copies of the Software, and to
119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt permit persons to whom the Software is furnished to do so, subject to
129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt the following conditions:
139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt The above copyright notice and this permission notice (including the
159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt next paragraph) shall be included in all copies or substantial
169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt portions of the Software.
179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt **********************************************************************/
279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /*
289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  * Authors:
299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  *   Keith Whitwell <keith@tungstengraphics.com>
309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  */
319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
344433b0302d0aa9dc61002e8bb4fd1b752b0be338Brian Paul#include "main/mtypes.h"
354433b0302d0aa9dc61002e8bb4fd1b752b0be338Brian Paul#include "main/macros.h"
364433b0302d0aa9dc61002e8bb4fd1b752b0be338Brian Paul#include "main/fbobject.h"
379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_context.h"
389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_state.h"
399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_defines.h"
4039fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry#include "brw_sf.h"
419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
42f75843a517bd188639e6866db2a7b04de3524e16Dave Airliestatic void upload_sf_vp(struct brw_context *brw)
439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
4488022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt   struct intel_context *intel = &brw->intel;
45855f56ca13c1003396a81da1a110357d624a2101Eric Anholt   struct gl_context *ctx = &intel->ctx;
462c9e515d8607fb91f08c500a841cdf7f32bda346Eric Anholt   const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
4788022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt   struct brw_sf_viewport *sfv;
48bea6b5fe5aa3138cec8d057766ae48da4aa57deeEric Anholt   GLfloat y_scale, y_bias;
494433b0302d0aa9dc61002e8bb4fd1b752b0be338Brian Paul   const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
503b946cde45f214be08edfbb716034d407a13c6b4Brian Paul   const GLfloat *v = ctx->Viewport._WindowMap.m;
519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
52d375df220fae47f38944c4832bcbd5f5d568884cEric Anholt   sfv = brw_state_batch(brw, AUB_TRACE_SF_VP_STATE,
53d375df220fae47f38944c4832bcbd5f5d568884cEric Anholt			 sizeof(*sfv), 32, &brw->sf.vp_offset);
54aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   memset(sfv, 0, sizeof(*sfv));
559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
56ba367f68ccacf255f78ac0c8dd066e64bbb1e5c2Brian Paul   if (render_to_fbo) {
57a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul      y_scale = 1.0;
58a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul      y_bias = 0;
59a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul   }
60a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul   else {
61bea6b5fe5aa3138cec8d057766ae48da4aa57deeEric Anholt      y_scale = -1.0;
62bea6b5fe5aa3138cec8d057766ae48da4aa57deeEric Anholt      y_bias = ctx->DrawBuffer->Height;
63bea6b5fe5aa3138cec8d057766ae48da4aa57deeEric Anholt   }
64bea6b5fe5aa3138cec8d057766ae48da4aa57deeEric Anholt
6514321fcfde9e30d0b9f15aab3c9a057271ae6295Eric Anholt   /* _NEW_VIEWPORT */
6614321fcfde9e30d0b9f15aab3c9a057271ae6295Eric Anholt
67aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sfv->viewport.m00 = v[MAT_SX];
68aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sfv->viewport.m11 = v[MAT_SY] * y_scale;
69aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sfv->viewport.m22 = v[MAT_SZ] * depth_scale;
70aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sfv->viewport.m30 = v[MAT_TX];
71aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sfv->viewport.m31 = v[MAT_TY] * y_scale + y_bias;
72aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sfv->viewport.m32 = v[MAT_TZ] * depth_scale;
739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
743a521d84ecc646fcc65fa3fe7c5f1fdbdebe8bc2Eric Anholt   /* _NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT
753a521d84ecc646fcc65fa3fe7c5f1fdbdebe8bc2Eric Anholt    * for DrawBuffer->_[XY]{min,max}
763a521d84ecc646fcc65fa3fe7c5f1fdbdebe8bc2Eric Anholt    */
779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7841f4d82ba8e2497d9fe27f55cb1b8707862fed46Eric Anholt   /* The scissor only needs to handle the intersection of drawable
7941f4d82ba8e2497d9fe27f55cb1b8707862fed46Eric Anholt    * and scissor rect, since there are no longer cliprects for shared
8041f4d82ba8e2497d9fe27f55cb1b8707862fed46Eric Anholt    * buffers with DRI2.
81447facfcd6d807128ebf6ba3efc894180b447494Eric Anholt    *
82447facfcd6d807128ebf6ba3efc894180b447494Eric Anholt    * Note that the hardware's coordinates are inclusive, while Mesa's min is
83447facfcd6d807128ebf6ba3efc894180b447494Eric Anholt    * inclusive but max is exclusive.
84447facfcd6d807128ebf6ba3efc894180b447494Eric Anholt    */
8564516430be1cbe4904613903887a8178f4b4fc60Eric Anholt
8664516430be1cbe4904613903887a8178f4b4fc60Eric Anholt   if (ctx->DrawBuffer->_Xmin == ctx->DrawBuffer->_Xmax ||
8764516430be1cbe4904613903887a8178f4b4fc60Eric Anholt       ctx->DrawBuffer->_Ymin == ctx->DrawBuffer->_Ymax) {
8864516430be1cbe4904613903887a8178f4b4fc60Eric Anholt      /* If the scissor was out of bounds and got clamped to 0
8964516430be1cbe4904613903887a8178f4b4fc60Eric Anholt       * width/height at the bounds, the subtraction of 1 from
9064516430be1cbe4904613903887a8178f4b4fc60Eric Anholt       * maximums could produce a negative number and thus not clip
9164516430be1cbe4904613903887a8178f4b4fc60Eric Anholt       * anything.  Instead, just provide a min > max scissor inside
9264516430be1cbe4904613903887a8178f4b4fc60Eric Anholt       * the bounds, which produces the expected no rendering.
9364516430be1cbe4904613903887a8178f4b4fc60Eric Anholt       */
94aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.xmin = 1;
95aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.xmax = 0;
96aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.ymin = 1;
97aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.ymax = 0;
9864516430be1cbe4904613903887a8178f4b4fc60Eric Anholt   } else if (render_to_fbo) {
993b23a8e07d59ff6ee766e7d3eb384137279a5250Brian Paul      /* texmemory: Y=0=bottom */
100aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.xmin = ctx->DrawBuffer->_Xmin;
101aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
102aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.ymin = ctx->DrawBuffer->_Ymin;
103aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.ymax = ctx->DrawBuffer->_Ymax - 1;
1043b23a8e07d59ff6ee766e7d3eb384137279a5250Brian Paul   }
1053b23a8e07d59ff6ee766e7d3eb384137279a5250Brian Paul   else {
1063b23a8e07d59ff6ee766e7d3eb384137279a5250Brian Paul      /* memory: Y=0=top */
107aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.xmin = ctx->DrawBuffer->_Xmin;
108aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
109aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.ymin = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax;
110aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sfv->scissor.ymax = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin - 1;
1113b23a8e07d59ff6ee766e7d3eb384137279a5250Brian Paul   }
1129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11388022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt   brw->state.dirty.cache |= CACHE_NEW_SF_VP;
1149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtconst struct brw_tracked_state brw_sf_vp = {
1179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   .dirty = {
1189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      .mesa  = (_NEW_VIEWPORT |
1193a521d84ecc646fcc65fa3fe7c5f1fdbdebe8bc2Eric Anholt		_NEW_SCISSOR |
1203a521d84ecc646fcc65fa3fe7c5f1fdbdebe8bc2Eric Anholt		_NEW_BUFFERS),
12188022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt      .brw   = BRW_NEW_BATCH,
1229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      .cache = 0
1239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   },
124c4aaf85285fc9484e95e9cda89db9cc6923259f4Eric Anholt   .emit = upload_sf_vp
1259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
1269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
12739fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry/**
12839fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry * Compute the offset within the URB (expressed in 256-bit register
12939fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry * increments) that should be used to read the VUE in th efragment shader.
13039fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry */
13139fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berryint
13239fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berrybrw_sf_compute_urb_entry_read_offset(struct intel_context *intel)
13339fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry{
13439fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry   if (intel->gen == 5)
13539fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry      return 3;
13639fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry   else
13739fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry      return 1;
13839fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry}
13939fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry
140b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholtstatic void upload_sf_unit( struct brw_context *brw )
1419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1421c96e85c9d6b8c636b0636f3320d1057ab5357b3Eric Anholt   struct intel_context *intel = &brw->intel;
143b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   struct gl_context *ctx = &intel->ctx;
144b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   struct brw_sf_unit_state *sf;
145b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   drm_intel_bo *bo = intel->batch.bo;
1462995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao   int chipset_max_threads;
1474433b0302d0aa9dc61002e8bb4fd1b752b0be338Brian Paul   bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
148b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt
149d375df220fae47f38944c4832bcbd5f5d568884cEric Anholt   sf = brw_state_batch(brw, AUB_TRACE_SF_STATE,
150d375df220fae47f38944c4832bcbd5f5d568884cEric Anholt			sizeof(*sf), 64, &brw->sf.state_offset);
1519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
152aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   memset(sf, 0, sizeof(*sf));
1539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
154c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_SF_PROG */
155b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
156c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt   sf->thread0.kernel_start_pointer =
157c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt      brw_program_reloc(brw,
158c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt			brw->sf.state_offset +
159c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt			offsetof(struct brw_sf_unit_state, thread0),
160c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt			brw->sf.prog_offset +
161c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt			(sf->thread0.grf_reg_count << 1)) >> 6;
16277e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt
163aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
164aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt
165aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->thread3.dispatch_grf_start_reg = 3;
1662995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao
16739fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry   sf->thread3.urb_entry_read_offset =
16839fc725b0c81db8d76cb490488cd95de5c4d7a79Paul Berry      brw_sf_compute_urb_entry_read_offset(intel);
1692995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao
170b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   /* CACHE_NEW_SF_PROG */
171b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length;
1729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
173b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   /* BRW_NEW_URB_FENCE */
174b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->thread4.nr_urb_entries = brw->urb.nr_sf_entries;
175b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->thread4.urb_entry_allocation_size = brw->urb.sfsize - 1;
1762995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao
1771c96e85c9d6b8c636b0636f3320d1057ab5357b3Eric Anholt   /* Each SF thread produces 1 PUE, and there can be up to 24 (Pre-Ironlake) or
1781c96e85c9d6b8c636b0636f3320d1057ab5357b3Eric Anholt    * 48 (Ironlake) threads.
1792995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao    */
180cdcef6cbf4dd80047819e9098e34a3b98bd502a4Zhenyu Wang   if (intel->gen == 5)
1812995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao      chipset_max_threads = 48;
1822995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao   else
1832995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao      chipset_max_threads = 24;
1842995bf0d68f1b28ba68b81e9dc79e3ab52bc2795Xiang, Haihao
185b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   /* BRW_NEW_URB_FENCE */
186b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->thread4.max_threads = MIN2(chipset_max_threads,
187b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt				  brw->urb.nr_sf_entries) - 1;
1889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
189bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt   if (unlikely(INTEL_DEBUG & DEBUG_STATS))
190aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->thread4.stats_enable = 1;
1919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* CACHE_NEW_SF_VP */
1938d2047ca7e8a533e1853a2ba51cd1bd6e52ae4a3Eric Anholt   sf->sf5.sf_viewport_state_offset = (intel->batch.bo->offset +
19488022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt				       brw->sf.vp_offset) >> 5; /* reloc */
19577e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt
196aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->sf5.viewport_transform = 1;
19777e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt
1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_SCISSOR */
199b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   if (ctx->Scissor.Enabled)
200aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.scissor = 1;
2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_POLYGON */
203b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   if (ctx->Polygon.FrontFace == GL_CCW)
204aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf5.front_winding = BRW_FRONTWINDING_CCW;
2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
206aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf5.front_winding = BRW_FRONTWINDING_CW;
2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
208b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   /* _NEW_BUFFERS
209b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt    * The viewport is inverted for rendering to a FBO, and that inverts
210a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul    * polygon front/back orientation.
211a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul    */
212b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->sf5.front_winding ^= render_to_fbo;
213a61a1a8181f05e07de1c0bccad109f4ad529a298Brian Paul
214b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   /* _NEW_POLYGON */
215b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   switch (ctx->Polygon.CullFlag ? ctx->Polygon.CullFaceMode : GL_NONE) {
21677e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt   case GL_FRONT:
217aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.cull_mode = BRW_CULLMODE_FRONT;
21877e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt      break;
21977e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt   case GL_BACK:
220aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.cull_mode = BRW_CULLMODE_BACK;
22177e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt      break;
22277e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt   case GL_FRONT_AND_BACK:
223aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.cull_mode = BRW_CULLMODE_BOTH;
22477e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt      break;
22577e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt   case GL_NONE:
226aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.cull_mode = BRW_CULLMODE_NONE;
22777e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt      break;
22877e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt   default:
22977e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt      assert(0);
23077e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt      break;
23177e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt   }
2329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_LINE */
234af2aa8e9cf88a9ee3ec338eddc9a47bf2f142cb7Brian   /* XXX use ctx->Const.Min/MaxLineWidth here */
235b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->sf6.line_width = CLAMP(ctx->Line.Width, 1.0, 5.0) * (1<<1);
2369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
237aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->sf6.line_endcap_aa_region_width = 1;
238b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   if (ctx->Line.SmoothFlag)
239aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.aa_enable = 1;
240aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   else if (sf->sf6.line_width <= 0x2)
241aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt       sf->sf6.line_width = 0;
2429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
24399174e7630676307f618c252755a20ba61ad9158Eric Anholt   /* _NEW_BUFFERS */
244b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   if (!render_to_fbo) {
245cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison      /* Rendering to an OpenGL window */
246aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;
247cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison   }
248cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison   else {
249cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison      /* If rendering to an FBO, the pixel coordinate system is
250cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * inverted with respect to the normal OpenGL coordinate
251cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * system, so BRW_RASTRULE_LOWER_RIGHT is correct.
252cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * But this value is listed as "Reserved, but not seen as useful"
253cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * in Intel documentation (page 212, "Point Rasterization Rule",
254cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * section 7.4 "SF Pipeline State Summary", of document
255cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * "Intel® 965 Express Chipset Family and Intel® G35 Express
256cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * Chipset Graphics Controller Programmer's Reference Manual,
257cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * Volume 2: 3D/Media", Revision 1.0b as of January 2008,
258cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * available at
259cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       *     http://intellinuxgraphics.org/documentation.html
260cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * at the time of this writing).
261cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       *
262cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * It does work on at least some devices, if not all;
263cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * if devices that don't support it can be identified,
264cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * the likely failure case is that points are rasterized
265cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * incorrectly, which is no worse than occurs without
266cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       * the value, so we're using it here.
267cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison       */
268aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf6.point_rast_rule = BRW_RASTRULE_LOWER_RIGHT;
269cc8afbd3862fedfe42e51c3774960d1c7078ec53Robert Ellison   }
270af2aa8e9cf88a9ee3ec338eddc9a47bf2f142cb7Brian   /* XXX clamp max depends on AA vs. non-AA */
271505453a04e8ba5e394c34401bd9ec320ffce2423Zou Nan hai
27299174e7630676307f618c252755a20ba61ad9158Eric Anholt   /* _NEW_POINT */
273b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->sf7.sprite_point = ctx->Point.PointSprite;
274b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->sf7.point_size = CLAMP(rint(CLAMP(ctx->Point.Size,
275b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt					 ctx->Point.MinSize,
276b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt					 ctx->Point.MaxSize)), 1, 255) * (1<<3);
27762ca17101c8282732d5c05e7891c3380a0701e4fKenneth Graunke   /* _NEW_PROGRAM | _NEW_POINT */
278b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   sf->sf7.use_point_size_state = !(ctx->VertexProgram.PointSizeEnabled ||
279b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt				    ctx->Point._Attenuated);
280aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->sf7.aa_line_distance_mode = 0;
28177e6cf8c1758c6b3091adf95ead96fbe9a996a17Eric Anholt
2829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
283b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt    * _NEW_LIGHT
2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
285b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) {
286aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf7.trifan_pv = 2;
287aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf7.linestrip_pv = 1;
288aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf7.tristrip_pv = 2;
289de80eeea0eebf00ee678b1a0fbd5fe67b00a8636Eric Anholt   } else {
290aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf7.trifan_pv = 1;
291aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf7.linestrip_pv = 0;
292aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt      sf->sf7.tristrip_pv = 0;
293de80eeea0eebf00ee678b1a0fbd5fe67b00a8636Eric Anholt   }
294aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->sf7.line_last_pixel_enable = 0;
2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Set bias for OpenGL rasterization rules:
2979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
298aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->sf6.dest_org_vbias = 0x8;
299aaf188e3bbe29826f0fea8944243a416946e7343Eric Anholt   sf->sf6.dest_org_hbias = 0x8;
3009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
30112c6973c6e32e5ee29242cb037830c1ca081f479Eric Anholt   /* STATE_PREFETCH command description describes this state as being
30212c6973c6e32e5ee29242cb037830c1ca081f479Eric Anholt    * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain.
30312c6973c6e32e5ee29242cb037830c1ca081f479Eric Anholt    */
3048abffada70fcd62e3c2dcbcdc6d00d258805326bEric Anholt
3058abffada70fcd62e3c2dcbcdc6d00d258805326bEric Anholt   /* Emit SF viewport relocation */
306b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset +
307b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt				offsetof(struct brw_sf_unit_state, sf5)),
30888022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt			   intel->batch.bo, (brw->sf.vp_offset |
30988022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt					     sf->sf5.front_winding |
31088022278f71ed3ea9613a7fa72a03367f75443d3Eric Anholt					     (sf->sf5.viewport_transform << 1)),
311df3c1a563f3d76b07ab82c7b230b0030452f36ffEric Anholt			   I915_GEM_DOMAIN_INSTRUCTION, 0);
3128abffada70fcd62e3c2dcbcdc6d00d258805326bEric Anholt
313b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt   brw->state.dirty.cache |= CACHE_NEW_SF_UNIT;
3149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtconst struct brw_tracked_state brw_sf_unit = {
3179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   .dirty = {
3189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      .mesa  = (_NEW_POLYGON |
31962ca17101c8282732d5c05e7891c3380a0701e4fKenneth Graunke		_NEW_PROGRAM |
320de80eeea0eebf00ee678b1a0fbd5fe67b00a8636Eric Anholt		_NEW_LIGHT |
3219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_LINE |
3229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_POINT |
32399174e7630676307f618c252755a20ba61ad9158Eric Anholt		_NEW_SCISSOR |
32499174e7630676307f618c252755a20ba61ad9158Eric Anholt		_NEW_BUFFERS),
325b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt      .brw   = (BRW_NEW_BATCH |
326c173541d9769d41a85cc899bc49699a3587df4bfEric Anholt		BRW_NEW_PROGRAM_CACHE |
327b1be5bd205d3efcaf4012d2c9a12831da57fc7fbEric Anholt		BRW_NEW_URB_FENCE),
3289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      .cache = (CACHE_NEW_SF_VP |
3299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		CACHE_NEW_SF_PROG)
3309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   },
331c4aaf85285fc9484e95e9cda89db9cc6923259f4Eric Anholt   .emit = upload_sf_unit,
3329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
333