brw_misc_state.c revision ddb10c3e603ee03e1287a992d23a5507779b7ffd
1/*
2 Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28  * Authors:
29  *   Keith Whitwell <keith@tungstengraphics.com>
30  */
31
32
33
34#include "intel_batchbuffer.h"
35#include "intel_regions.h"
36
37#include "brw_context.h"
38#include "brw_state.h"
39#include "brw_defines.h"
40
41
42
43
44
45/***********************************************************************
46 * Blend color
47 */
48
49static void upload_blend_constant_color(struct brw_context *brw)
50{
51   GLcontext *ctx = &brw->intel.ctx;
52   struct brw_blend_constant_color bcc;
53
54   memset(&bcc, 0, sizeof(bcc));
55   bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
56   bcc.header.length = sizeof(bcc)/4-2;
57   bcc.blend_constant_color[0] = ctx->Color.BlendColor[0];
58   bcc.blend_constant_color[1] = ctx->Color.BlendColor[1];
59   bcc.blend_constant_color[2] = ctx->Color.BlendColor[2];
60   bcc.blend_constant_color[3] = ctx->Color.BlendColor[3];
61
62   BRW_CACHED_BATCH_STRUCT(brw, &bcc);
63}
64
65
66const struct brw_tracked_state brw_blend_constant_color = {
67   .dirty = {
68      .mesa = _NEW_COLOR,
69      .brw = BRW_NEW_CONTEXT,
70      .cache = 0
71   },
72   .emit = upload_blend_constant_color
73};
74
75/* Constant single cliprect for framebuffer object or DRI2 drawing */
76static void upload_drawing_rect(struct brw_context *brw)
77{
78   struct intel_context *intel = &brw->intel;
79   GLcontext *ctx = &intel->ctx;
80
81   BEGIN_BATCH(4);
82   OUT_BATCH(_3DSTATE_DRAWRECT_INFO_I965);
83   OUT_BATCH(0); /* xmin, ymin */
84   OUT_BATCH(((ctx->DrawBuffer->Width - 1) & 0xffff) |
85	    ((ctx->DrawBuffer->Height - 1) << 16));
86   OUT_BATCH(0);
87   ADVANCE_BATCH();
88}
89
90const struct brw_tracked_state brw_drawing_rect = {
91   .dirty = {
92      .mesa = _NEW_BUFFERS,
93      .brw = BRW_NEW_CONTEXT,
94      .cache = 0
95   },
96   .emit = upload_drawing_rect
97};
98
99static void prepare_binding_table_pointers(struct brw_context *brw)
100{
101   brw_add_validated_bo(brw, brw->vs.bind_bo);
102   brw_add_validated_bo(brw, brw->wm.bind_bo);
103}
104
105/**
106 * Upload the binding table pointers, which point each stage's array of surface
107 * state pointers.
108 *
109 * The binding table pointers are relative to the surface state base address,
110 * which is 0.
111 */
112static void upload_binding_table_pointers(struct brw_context *brw)
113{
114   struct intel_context *intel = &brw->intel;
115
116   BEGIN_BATCH(6);
117   OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2));
118   if (brw->vs.bind_bo != NULL)
119      OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */
120   else
121      OUT_BATCH(0);
122   OUT_BATCH(0); /* gs */
123   OUT_BATCH(0); /* clip */
124   OUT_BATCH(0); /* sf */
125   OUT_RELOC(brw->wm.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* wm/ps */
126   ADVANCE_BATCH();
127}
128
129const struct brw_tracked_state brw_binding_table_pointers = {
130   .dirty = {
131      .mesa = 0,
132      .brw = BRW_NEW_BATCH,
133      .cache = CACHE_NEW_SURF_BIND,
134   },
135   .prepare = prepare_binding_table_pointers,
136   .emit = upload_binding_table_pointers,
137};
138
139/**
140 * Upload the binding table pointers, which point each stage's array of surface
141 * state pointers.
142 *
143 * The binding table pointers are relative to the surface state base address,
144 * which is 0.
145 */
146static void upload_gen6_binding_table_pointers(struct brw_context *brw)
147{
148   struct intel_context *intel = &brw->intel;
149
150   BEGIN_BATCH(4);
151   OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 |
152	     GEN6_BINDING_TABLE_MODIFY_VS |
153	     GEN6_BINDING_TABLE_MODIFY_GS |
154	     GEN6_BINDING_TABLE_MODIFY_PS |
155	     (4 - 2));
156   if (brw->vs.bind_bo != NULL)
157      OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */
158   else
159      OUT_BATCH(0);
160   OUT_BATCH(0); /* gs */
161   OUT_RELOC(brw->wm.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* wm/ps */
162   ADVANCE_BATCH();
163}
164
165const struct brw_tracked_state gen6_binding_table_pointers = {
166   .dirty = {
167      .mesa = 0,
168      .brw = BRW_NEW_BATCH,
169      .cache = CACHE_NEW_SURF_BIND,
170   },
171   .prepare = prepare_binding_table_pointers,
172   .emit = upload_gen6_binding_table_pointers,
173};
174
175/**
176 * Upload pointers to the per-stage state.
177 *
178 * The state pointers in this packet are all relative to the general state
179 * base address set by CMD_STATE_BASE_ADDRESS, which is 0.
180 */
181static void upload_pipelined_state_pointers(struct brw_context *brw )
182{
183   struct intel_context *intel = &brw->intel;
184
185   if (intel->gen == 5) {
186      /* Need to flush before changing clip max threads for errata. */
187      BEGIN_BATCH(1);
188      OUT_BATCH(MI_FLUSH);
189      ADVANCE_BATCH();
190   }
191
192   BEGIN_BATCH(7);
193   OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2));
194   OUT_RELOC(brw->vs.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
195   if (brw->gs.prog_active)
196      OUT_RELOC(brw->gs.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
197   else
198      OUT_BATCH(0);
199   OUT_RELOC(brw->clip.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
200   OUT_RELOC(brw->sf.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
201   OUT_RELOC(brw->wm.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
202   OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
203   ADVANCE_BATCH();
204
205   brw->state.dirty.brw |= BRW_NEW_PSP;
206}
207
208
209static void prepare_psp_urb_cbs(struct brw_context *brw)
210{
211   brw_add_validated_bo(brw, brw->vs.state_bo);
212   brw_add_validated_bo(brw, brw->gs.state_bo);
213   brw_add_validated_bo(brw, brw->clip.state_bo);
214   brw_add_validated_bo(brw, brw->sf.state_bo);
215   brw_add_validated_bo(brw, brw->wm.state_bo);
216   brw_add_validated_bo(brw, brw->cc.state_bo);
217}
218
219static void upload_psp_urb_cbs(struct brw_context *brw )
220{
221   upload_pipelined_state_pointers(brw);
222   brw_upload_urb_fence(brw);
223   brw_upload_cs_urb_state(brw);
224}
225
226const struct brw_tracked_state brw_psp_urb_cbs = {
227   .dirty = {
228      .mesa = 0,
229      .brw = BRW_NEW_URB_FENCE | BRW_NEW_BATCH,
230      .cache = (CACHE_NEW_VS_UNIT |
231		CACHE_NEW_GS_UNIT |
232		CACHE_NEW_GS_PROG |
233		CACHE_NEW_CLIP_UNIT |
234		CACHE_NEW_SF_UNIT |
235		CACHE_NEW_WM_UNIT |
236		CACHE_NEW_CC_UNIT)
237   },
238   .prepare = prepare_psp_urb_cbs,
239   .emit = upload_psp_urb_cbs,
240};
241
242static void prepare_depthbuffer(struct brw_context *brw)
243{
244   struct intel_region *region = brw->state.depth_region;
245
246   if (region != NULL)
247      brw_add_validated_bo(brw, region->buffer);
248}
249
250static void emit_depthbuffer(struct brw_context *brw)
251{
252   struct intel_context *intel = &brw->intel;
253   struct intel_region *region = brw->state.depth_region;
254   unsigned int len;
255
256   if (intel->gen >= 6)
257      len = 7;
258   else if (intel->is_g4x || intel->gen == 5)
259      len = 6;
260   else
261      len = 5;
262
263   if (region == NULL) {
264      BEGIN_BATCH(len);
265      OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
266      OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
267		(BRW_SURFACE_NULL << 29));
268      OUT_BATCH(0);
269      OUT_BATCH(0);
270      OUT_BATCH(0);
271
272      if (intel->is_g4x || intel->gen >= 5)
273         OUT_BATCH(0);
274
275      if (intel->gen >= 6)
276	 OUT_BATCH(0);
277
278      ADVANCE_BATCH();
279   } else {
280      unsigned int format;
281
282      switch (region->cpp) {
283      case 2:
284	 format = BRW_DEPTHFORMAT_D16_UNORM;
285	 break;
286      case 4:
287	 if (intel->depth_buffer_is_float)
288	    format = BRW_DEPTHFORMAT_D32_FLOAT;
289	 else
290	    format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
291	 break;
292      default:
293	 assert(0);
294	 return;
295      }
296
297      assert(region->tiling != I915_TILING_X);
298      if (IS_GEN6(intel->intelScreen->deviceID))
299	 assert(region->tiling != I915_TILING_NONE);
300
301      BEGIN_BATCH(len);
302      OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
303      OUT_BATCH(((region->pitch * region->cpp) - 1) |
304		(format << 18) |
305		(BRW_TILEWALK_YMAJOR << 26) |
306		((region->tiling != I915_TILING_NONE) << 27) |
307		(BRW_SURFACE_2D << 29));
308      OUT_RELOC(region->buffer,
309		I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
310		0);
311      OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
312		((region->pitch - 1) << 6) |
313		((region->height - 1) << 19));
314      OUT_BATCH(0);
315
316      if (intel->is_g4x || intel->gen >= 5)
317         OUT_BATCH(0);
318
319      if (intel->gen >= 6)
320	 OUT_BATCH(0);
321
322      ADVANCE_BATCH();
323   }
324
325   /* Initialize it for safety. */
326   if (intel->gen >= 6) {
327      BEGIN_BATCH(2);
328      OUT_BATCH(CMD_3D_CLEAR_PARAMS << 16 | (2 - 2));
329      OUT_BATCH(0);
330      ADVANCE_BATCH();
331   }
332}
333
334const struct brw_tracked_state brw_depthbuffer = {
335   .dirty = {
336      .mesa = 0,
337      .brw = BRW_NEW_DEPTH_BUFFER | BRW_NEW_BATCH,
338      .cache = 0,
339   },
340   .prepare = prepare_depthbuffer,
341   .emit = emit_depthbuffer,
342};
343
344
345
346/***********************************************************************
347 * Polygon stipple packet
348 */
349
350static void upload_polygon_stipple(struct brw_context *brw)
351{
352   GLcontext *ctx = &brw->intel.ctx;
353   struct brw_polygon_stipple bps;
354   GLuint i;
355
356   memset(&bps, 0, sizeof(bps));
357   bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
358   bps.header.length = sizeof(bps)/4-2;
359
360   /* Polygon stipple is provided in OpenGL order, i.e. bottom
361    * row first.  If we're rendering to a window (i.e. the
362    * default frame buffer object, 0), then we need to invert
363    * it to match our pixel layout.  But if we're rendering
364    * to a FBO (i.e. any named frame buffer object), we *don't*
365    * need to invert - we already match the layout.
366    */
367   if (ctx->DrawBuffer->Name == 0) {
368      for (i = 0; i < 32; i++)
369         bps.stipple[i] = ctx->PolygonStipple[31 - i]; /* invert */
370   }
371   else {
372      for (i = 0; i < 32; i++)
373         bps.stipple[i] = ctx->PolygonStipple[i]; /* don't invert */
374   }
375
376   BRW_CACHED_BATCH_STRUCT(brw, &bps);
377}
378
379const struct brw_tracked_state brw_polygon_stipple = {
380   .dirty = {
381      .mesa = _NEW_POLYGONSTIPPLE,
382      .brw = BRW_NEW_CONTEXT,
383      .cache = 0
384   },
385   .emit = upload_polygon_stipple
386};
387
388
389/***********************************************************************
390 * Polygon stipple offset packet
391 */
392
393static void upload_polygon_stipple_offset(struct brw_context *brw)
394{
395   GLcontext *ctx = &brw->intel.ctx;
396   struct brw_polygon_stipple_offset bpso;
397
398   memset(&bpso, 0, sizeof(bpso));
399   bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
400   bpso.header.length = sizeof(bpso)/4-2;
401
402   /* If we're drawing to a system window (ctx->DrawBuffer->Name == 0),
403    * we have to invert the Y axis in order to match the OpenGL
404    * pixel coordinate system, and our offset must be matched
405    * to the window position.  If we're drawing to a FBO
406    * (ctx->DrawBuffer->Name != 0), then our native pixel coordinate
407    * system works just fine, and there's no window system to
408    * worry about.
409    */
410   if (brw->intel.ctx.DrawBuffer->Name == 0) {
411      bpso.bits0.x_offset = 0;
412      bpso.bits0.y_offset = (32 - (ctx->DrawBuffer->Height & 31)) & 31;
413   }
414   else {
415      bpso.bits0.y_offset = 0;
416      bpso.bits0.x_offset = 0;
417   }
418
419   BRW_CACHED_BATCH_STRUCT(brw, &bpso);
420}
421
422#define _NEW_WINDOW_POS 0x40000000
423
424const struct brw_tracked_state brw_polygon_stipple_offset = {
425   .dirty = {
426      .mesa = _NEW_WINDOW_POS,
427      .brw = BRW_NEW_CONTEXT,
428      .cache = 0
429   },
430   .emit = upload_polygon_stipple_offset
431};
432
433/**********************************************************************
434 * AA Line parameters
435 */
436static void upload_aa_line_parameters(struct brw_context *brw)
437{
438   struct brw_aa_line_parameters balp;
439
440   if (!brw->has_aa_line_parameters)
441      return;
442
443   /* use legacy aa line coverage computation */
444   memset(&balp, 0, sizeof(balp));
445   balp.header.opcode = CMD_AA_LINE_PARAMETERS;
446   balp.header.length = sizeof(balp) / 4 - 2;
447
448   BRW_CACHED_BATCH_STRUCT(brw, &balp);
449}
450
451const struct brw_tracked_state brw_aa_line_parameters = {
452   .dirty = {
453      .mesa = 0,
454      .brw = BRW_NEW_CONTEXT,
455      .cache = 0
456   },
457   .emit = upload_aa_line_parameters
458};
459
460/***********************************************************************
461 * Line stipple packet
462 */
463
464static void upload_line_stipple(struct brw_context *brw)
465{
466   GLcontext *ctx = &brw->intel.ctx;
467   struct brw_line_stipple bls;
468   GLfloat tmp;
469   GLint tmpi;
470
471   memset(&bls, 0, sizeof(bls));
472   bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
473   bls.header.length = sizeof(bls)/4 - 2;
474
475   bls.bits0.pattern = ctx->Line.StipplePattern;
476   bls.bits1.repeat_count = ctx->Line.StippleFactor;
477
478   tmp = 1.0 / (GLfloat) ctx->Line.StippleFactor;
479   tmpi = tmp * (1<<13);
480
481
482   bls.bits1.inverse_repeat_count = tmpi;
483
484   BRW_CACHED_BATCH_STRUCT(brw, &bls);
485}
486
487const struct brw_tracked_state brw_line_stipple = {
488   .dirty = {
489      .mesa = _NEW_LINE,
490      .brw = BRW_NEW_CONTEXT,
491      .cache = 0
492   },
493   .emit = upload_line_stipple
494};
495
496
497/***********************************************************************
498 * Misc invarient state packets
499 */
500
501static void upload_invarient_state( struct brw_context *brw )
502{
503   struct intel_context *intel = &brw->intel;
504
505   {
506      /* 0x61040000  Pipeline Select */
507      /*     PipelineSelect            : 0 */
508      struct brw_pipeline_select ps;
509
510      memset(&ps, 0, sizeof(ps));
511      ps.header.opcode = brw->CMD_PIPELINE_SELECT;
512      ps.header.pipeline_select = 0;
513      BRW_BATCH_STRUCT(brw, &ps);
514   }
515
516   if (intel->gen < 6) {
517      struct brw_global_depth_offset_clamp gdo;
518      memset(&gdo, 0, sizeof(gdo));
519
520      /* Disable depth offset clamping.
521       */
522      gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
523      gdo.header.length = sizeof(gdo)/4 - 2;
524      gdo.depth_offset_clamp = 0.0;
525
526      BRW_BATCH_STRUCT(brw, &gdo);
527   }
528
529   if (intel->gen >= 6) {
530      int i;
531
532      intel_batchbuffer_emit_mi_flush(intel->batch);
533
534      BEGIN_BATCH(3);
535      OUT_BATCH(CMD_3D_MULTISAMPLE << 16 | (3 - 2));
536      OUT_BATCH(MS_PIXEL_LOCATION_CENTER |
537		MS_NUMSAMPLES_1);
538      OUT_BATCH(0); /* positions for 4/8-sample */
539      ADVANCE_BATCH();
540
541      BEGIN_BATCH(2);
542      OUT_BATCH(CMD_3D_SAMPLE_MASK << 16 | (2 - 2));
543      OUT_BATCH(1);
544      ADVANCE_BATCH();
545
546      for (i = 0; i < 4; i++) {
547	 BEGIN_BATCH(4);
548	 OUT_BATCH(CMD_GS_SVB_INDEX << 16 | (4 - 2));
549	 OUT_BATCH(i << SVB_INDEX_SHIFT);
550	 OUT_BATCH(0);
551	 OUT_BATCH(0xffffffff);
552	 ADVANCE_BATCH();
553      }
554   }
555
556   /* 0x61020000  State Instruction Pointer */
557   {
558      struct brw_system_instruction_pointer sip;
559      memset(&sip, 0, sizeof(sip));
560
561      sip.header.opcode = CMD_STATE_INSN_POINTER;
562      sip.header.length = 0;
563      sip.bits0.pad = 0;
564      sip.bits0.system_instruction_pointer = 0;
565      BRW_BATCH_STRUCT(brw, &sip);
566   }
567
568
569   {
570      struct brw_vf_statistics vfs;
571      memset(&vfs, 0, sizeof(vfs));
572
573      vfs.opcode = brw->CMD_VF_STATISTICS;
574      if (INTEL_DEBUG & DEBUG_STATS)
575	 vfs.statistics_enable = 1;
576
577      BRW_BATCH_STRUCT(brw, &vfs);
578   }
579}
580
581const struct brw_tracked_state brw_invarient_state = {
582   .dirty = {
583      .mesa = 0,
584      .brw = BRW_NEW_CONTEXT,
585      .cache = 0
586   },
587   .emit = upload_invarient_state
588};
589
590/**
591 * Define the base addresses which some state is referenced from.
592 *
593 * This allows us to avoid having to emit relocations in many places for
594 * cached state, and instead emit pointers inside of large, mostly-static
595 * state pools.  This comes at the expense of memory, and more expensive cache
596 * misses.
597 */
598static void upload_state_base_address( struct brw_context *brw )
599{
600   struct intel_context *intel = &brw->intel;
601
602   /* Output the structure (brw_state_base_address) directly to the
603    * batchbuffer, so we can emit relocations inline.
604    */
605   if (intel->gen >= 6) {
606       BEGIN_BATCH(10);
607       OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2));
608       OUT_BATCH(1); /* General state base address */
609       OUT_BATCH(1); /* Surface state base address */
610       OUT_BATCH(1); /* Dynamic state base address */
611       OUT_BATCH(1); /* Indirect object base address */
612       OUT_BATCH(1); /* Instruction base address */
613       OUT_BATCH(1); /* General state upper bound */
614       OUT_BATCH(1); /* Dynamic state upper bound */
615       OUT_BATCH(1); /* Indirect object upper bound */
616       OUT_BATCH(1); /* Instruction access upper bound */
617       ADVANCE_BATCH();
618   } else if (intel->gen == 5) {
619       BEGIN_BATCH(8);
620       OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
621       OUT_BATCH(1); /* General state base address */
622       OUT_BATCH(1); /* Surface state base address */
623       OUT_BATCH(1); /* Indirect object base address */
624       OUT_BATCH(1); /* Instruction base address */
625       OUT_BATCH(1); /* General state upper bound */
626       OUT_BATCH(1); /* Indirect object upper bound */
627       OUT_BATCH(1); /* Instruction access upper bound */
628       ADVANCE_BATCH();
629   } else {
630       BEGIN_BATCH(6);
631       OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
632       OUT_BATCH(1); /* General state base address */
633       OUT_BATCH(1); /* Surface state base address */
634       OUT_BATCH(1); /* Indirect object base address */
635       OUT_BATCH(1); /* General state upper bound */
636       OUT_BATCH(1); /* Indirect object upper bound */
637       ADVANCE_BATCH();
638   }
639}
640
641const struct brw_tracked_state brw_state_base_address = {
642   .dirty = {
643      .mesa = 0,
644      .brw = BRW_NEW_CONTEXT,
645      .cache = 0,
646   },
647   .emit = upload_state_base_address
648};
649