1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org develop this 3D driver.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Permission is hereby granted, free of charge, to any person obtaining
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org distribute, sublicense, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next paragraph) shall be included in all copies or substantial
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org portions of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **********************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  * Authors:
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  *   Keith Whitwell <keith@tungstengraphics.com>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  */
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/fbobject.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "brw_context.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "brw_state.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "brw_defines.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "brw_sf.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void upload_sf_vp(struct brw_context *brw)
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &brw->intel;
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_context *ctx = &intel->ctx;
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_sf_viewport *sfv;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat y_scale, y_bias;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat *v = ctx->Viewport._WindowMap.m;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv = brw_state_batch(brw, AUB_TRACE_SF_VP_STATE,
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 sizeof(*sfv), 32, &brw->sf.vp_offset);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(sfv, 0, sizeof(*sfv));
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (render_to_fbo) {
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y_scale = 1.0;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y_bias = 0;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y_scale = -1.0;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y_bias = ctx->DrawBuffer->Height;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_VIEWPORT */
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv->viewport.m00 = v[MAT_SX];
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv->viewport.m11 = v[MAT_SY] * y_scale;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv->viewport.m22 = v[MAT_SZ] * depth_scale;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv->viewport.m30 = v[MAT_TX];
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv->viewport.m31 = v[MAT_TY] * y_scale + y_bias;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sfv->viewport.m32 = v[MAT_TZ] * depth_scale;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * for DrawBuffer->_[XY]{min,max}
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The scissor only needs to handle the intersection of drawable
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and scissor rect, since there are no longer cliprects for shared
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * buffers with DRI2.
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Note that the hardware's coordinates are inclusive, while Mesa's min is
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * inclusive but max is exclusive.
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->DrawBuffer->_Xmin == ctx->DrawBuffer->_Xmax ||
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ctx->DrawBuffer->_Ymin == ctx->DrawBuffer->_Ymax) {
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the scissor was out of bounds and got clamped to 0
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * width/height at the bounds, the subtraction of 1 from
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * maximums could produce a negative number and thus not clip
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * anything.  Instead, just provide a min > max scissor inside
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the bounds, which produces the expected no rendering.
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.xmin = 1;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.xmax = 0;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.ymin = 1;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.ymax = 0;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (render_to_fbo) {
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* texmemory: Y=0=bottom */
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.xmin = ctx->DrawBuffer->_Xmin;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.ymin = ctx->DrawBuffer->_Ymin;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.ymax = ctx->DrawBuffer->_Ymax - 1;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* memory: Y=0=top */
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.xmin = ctx->DrawBuffer->_Xmin;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.ymin = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sfv->scissor.ymax = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin - 1;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw->state.dirty.cache |= CACHE_NEW_SF_VP;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct brw_tracked_state brw_sf_vp = {
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .dirty = {
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .mesa  = (_NEW_VIEWPORT |
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_SCISSOR |
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_BUFFERS),
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .brw   = BRW_NEW_BATCH,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .cache = 0
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   },
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .emit = upload_sf_vp
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute the offset within the URB (expressed in 256-bit register
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * increments) that should be used to read the VUE in th efragment shader.
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbrw_sf_compute_urb_entry_read_offset(struct intel_context *intel)
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen == 5)
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 3;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void upload_sf_unit( struct brw_context *brw )
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &brw->intel;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_context *ctx = &intel->ctx;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_sf_unit_state *sf;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_intel_bo *bo = intel->batch.bo;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int chipset_max_threads;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf = brw_state_batch(brw, AUB_TRACE_SF_STATE,
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			sizeof(*sf), 64, &brw->sf.state_offset);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(sf, 0, sizeof(*sf));
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_SF_PROG */
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread0.kernel_start_pointer =
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_program_reloc(brw,
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			brw->sf.state_offset +
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			offsetof(struct brw_sf_unit_state, thread0),
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			brw->sf.prog_offset +
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			(sf->thread0.grf_reg_count << 1)) >> 6;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread3.dispatch_grf_start_reg = 3;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread3.urb_entry_read_offset =
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_sf_compute_urb_entry_read_offset(intel);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* CACHE_NEW_SF_PROG */
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* BRW_NEW_URB_FENCE */
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread4.nr_urb_entries = brw->urb.nr_sf_entries;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread4.urb_entry_allocation_size = brw->urb.sfsize - 1;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Each SF thread produces 1 PUE, and there can be up to 24 (Pre-Ironlake) or
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * 48 (Ironlake) threads.
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen == 5)
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      chipset_max_threads = 48;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      chipset_max_threads = 24;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* BRW_NEW_URB_FENCE */
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->thread4.max_threads = MIN2(chipset_max_threads,
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  brw->urb.nr_sf_entries) - 1;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (unlikely(INTEL_DEBUG & DEBUG_STATS))
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->thread4.stats_enable = 1;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* CACHE_NEW_SF_VP */
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf5.sf_viewport_state_offset = (intel->batch.bo->offset +
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       brw->sf.vp_offset) >> 5; /* reloc */
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf5.viewport_transform = 1;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_SCISSOR */
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Scissor.Enabled)
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.scissor = 1;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_POLYGON */
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Polygon.FrontFace == GL_CCW)
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf5.front_winding = BRW_FRONTWINDING_CCW;
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf5.front_winding = BRW_FRONTWINDING_CW;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_BUFFERS
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The viewport is inverted for rendering to a FBO, and that inverts
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * polygon front/back orientation.
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf5.front_winding ^= render_to_fbo;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_POLYGON */
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ctx->Polygon.CullFlag ? ctx->Polygon.CullFaceMode : GL_NONE) {
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_FRONT:
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.cull_mode = BRW_CULLMODE_FRONT;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BACK:
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.cull_mode = BRW_CULLMODE_BACK;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_FRONT_AND_BACK:
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.cull_mode = BRW_CULLMODE_BOTH;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NONE:
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.cull_mode = BRW_CULLMODE_NONE;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_LINE */
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX use ctx->Const.Min/MaxLineWidth here */
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf6.line_width = CLAMP(ctx->Line.Width, 1.0, 5.0) * (1<<1);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf6.line_endcap_aa_region_width = 1;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Line.SmoothFlag)
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.aa_enable = 1;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (sf->sf6.line_width <= 0x2)
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       sf->sf6.line_width = 0;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_BUFFERS */
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!render_to_fbo) {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Rendering to an OpenGL window */
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If rendering to an FBO, the pixel coordinate system is
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * inverted with respect to the normal OpenGL coordinate
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * system, so BRW_RASTRULE_LOWER_RIGHT is correct.
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * But this value is listed as "Reserved, but not seen as useful"
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * in Intel documentation (page 212, "Point Rasterization Rule",
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * section 7.4 "SF Pipeline State Summary", of document
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * "Intel® 965 Express Chipset Family and Intel® G35 Express
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Chipset Graphics Controller Programmer's Reference Manual,
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Volume 2: 3D/Media", Revision 1.0b as of January 2008,
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * available at
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     http://intellinuxgraphics.org/documentation.html
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * at the time of this writing).
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * It does work on at least some devices, if not all;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * if devices that don't support it can be identified,
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the likely failure case is that points are rasterized
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * incorrectly, which is no worse than occurs without
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the value, so we're using it here.
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf6.point_rast_rule = BRW_RASTRULE_LOWER_RIGHT;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX clamp max depends on AA vs. non-AA */
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_POINT */
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf7.sprite_point = ctx->Point.PointSprite;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf7.point_size = CLAMP(rint(CLAMP(ctx->Point.Size,
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ctx->Point.MinSize,
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 ctx->Point.MaxSize)), 1, 255) * (1<<3);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* _NEW_PROGRAM | _NEW_POINT */
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf7.use_point_size_state = !(ctx->VertexProgram.PointSizeEnabled ||
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    ctx->Point._Attenuated);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf7.aa_line_distance_mode = 0;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * _NEW_LIGHT
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) {
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf7.trifan_pv = 2;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf7.linestrip_pv = 1;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf7.tristrip_pv = 2;
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf7.trifan_pv = 1;
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf7.linestrip_pv = 0;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sf->sf7.tristrip_pv = 0;
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf7.line_last_pixel_enable = 0;
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Set bias for OpenGL rasterization rules:
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf6.dest_org_vbias = 0x8;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sf->sf6.dest_org_hbias = 0x8;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* STATE_PREFETCH command description describes this state as being
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain.
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit SF viewport relocation */
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset +
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				offsetof(struct brw_sf_unit_state, sf5)),
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   intel->batch.bo, (brw->sf.vp_offset |
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     sf->sf5.front_winding |
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     (sf->sf5.viewport_transform << 1)),
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   I915_GEM_DOMAIN_INSTRUCTION, 0);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw->state.dirty.cache |= CACHE_NEW_SF_UNIT;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct brw_tracked_state brw_sf_unit = {
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .dirty = {
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .mesa  = (_NEW_POLYGON |
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_PROGRAM |
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_LIGHT |
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_LINE |
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_POINT |
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_SCISSOR |
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_NEW_BUFFERS),
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .brw   = (BRW_NEW_BATCH |
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BRW_NEW_PROGRAM_CACHE |
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BRW_NEW_URB_FENCE),
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .cache = (CACHE_NEW_SF_VP |
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		CACHE_NEW_SF_PROG)
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   },
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .emit = upload_sf_unit,
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
333