brw_context.c revision 642247883fb9e6dce9bad724f7f6503321e0ef6f
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#include "main/imports.h"
34#include "main/macros.h"
35#include "main/simple_list.h"
36
37#include "vbo/vbo_context.h"
38
39#include "brw_context.h"
40#include "brw_defines.h"
41#include "brw_draw.h"
42#include "brw_state.h"
43
44#include "gen6_hiz.h"
45
46#include "intel_fbo.h"
47#include "intel_mipmap_tree.h"
48#include "intel_regions.h"
49#include "intel_span.h"
50#include "intel_tex.h"
51#include "intel_tex_obj.h"
52
53#include "tnl/t_pipeline.h"
54#include "glsl/ralloc.h"
55
56/***************************************
57 * Mesa's Driver Functions
58 ***************************************/
59
60/**
61 * \brief Prepare for entry into glBegin/glEnd block.
62 *
63 * Resolve buffers before entering a glBegin/glEnd block. This is
64 * necessary to prevent recursive calls to FLUSH_VERTICES.
65 *
66 * This resolves the depth buffer of each enabled depth texture and the HiZ
67 * buffer of the attached depth renderbuffer.
68 *
69 * Details
70 * -------
71 * When vertices are queued during a glBegin/glEnd block, those vertices must
72 * be drawn before any rendering state changes. To ensure this, Mesa calls
73 * FLUSH_VERTICES as a prehook to such state changes. Therefore,
74 * FLUSH_VERTICES itself cannot change rendering state without falling into a
75 * recursive trap.
76 *
77 * This precludes meta-ops, namely buffer resolves, from occurring while any
78 * vertices are queued. To prevent that situation, we resolve some buffers on
79 * entering a glBegin/glEnd
80 *
81 * \see brwCleanupExecEnd()
82 */
83static void brwPrepareExecBegin(struct gl_context *ctx)
84{
85   struct brw_context *brw = brw_context(ctx);
86   struct intel_context *intel = &brw->intel;
87   struct intel_renderbuffer *draw_irb;
88   struct intel_texture_object *tex_obj;
89
90   if (!intel->has_hiz) {
91      /* The context uses no feature that requires buffer resolves. */
92      return;
93   }
94
95   /* Resolve each enabled texture. */
96   for (int i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
97      if (!ctx->Texture.Unit[i]._ReallyEnabled)
98	 continue;
99      tex_obj = intel_texture_object(ctx->Texture.Unit[i]._Current);
100      if (!tex_obj || !tex_obj->mt)
101	 continue;
102      intel_miptree_all_slices_resolve_depth(intel, tex_obj->mt);
103   }
104
105   /* Resolve the attached depth buffer. */
106   draw_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH);
107   if (draw_irb) {
108      intel_renderbuffer_resolve_hiz(intel, draw_irb);
109   }
110}
111
112static void brwInitDriverFunctions(struct intel_screen *screen,
113				   struct dd_function_table *functions)
114{
115   intelInitDriverFunctions( functions );
116
117   brwInitFragProgFuncs( functions );
118   brw_init_queryobj_functions(functions);
119
120   functions->PrepareExecBegin = brwPrepareExecBegin;
121   functions->BeginTransformFeedback = brw_begin_transform_feedback;
122
123   if (screen->gen >= 7)
124      functions->EndTransformFeedback = gen7_end_transform_feedback;
125   else
126      functions->EndTransformFeedback = brw_end_transform_feedback;
127}
128
129bool
130brwCreateContext(int api,
131	         const struct gl_config *mesaVis,
132		 __DRIcontext *driContextPriv,
133	         void *sharedContextPrivate)
134{
135   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
136   struct intel_screen *screen = sPriv->driverPrivate;
137   struct dd_function_table functions;
138   struct brw_context *brw = rzalloc(NULL, struct brw_context);
139   struct intel_context *intel = &brw->intel;
140   struct gl_context *ctx = &intel->ctx;
141   unsigned i;
142
143   if (!brw) {
144      printf("%s: failed to alloc context\n", __FUNCTION__);
145      return false;
146   }
147
148   brwInitDriverFunctions(screen, &functions);
149
150   if (!intelInitContext( intel, api, mesaVis, driContextPriv,
151			  sharedContextPrivate, &functions )) {
152      printf("%s: failed to init intel context\n", __FUNCTION__);
153      FREE(brw);
154      return false;
155   }
156
157   brwInitVtbl( brw );
158
159   brw_init_surface_formats(brw);
160
161   /* Initialize swrast, tnl driver tables: */
162   intelInitSpanFuncs(ctx);
163
164   TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
165
166   ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
167   ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
168   ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
169   ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
170                                     ctx->Const.MaxTextureImageUnits);
171   ctx->Const.MaxVertexTextureImageUnits = BRW_MAX_TEX_UNIT;
172   ctx->Const.MaxCombinedTextureImageUnits =
173      ctx->Const.MaxVertexTextureImageUnits +
174      ctx->Const.MaxTextureImageUnits;
175
176   ctx->Const.MaxTextureLevels = 14; /* 8192 */
177   if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
178	   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
179   ctx->Const.Max3DTextureLevels = 9;
180   ctx->Const.MaxCubeTextureLevels = 12;
181
182   if (intel->gen >= 7)
183      ctx->Const.MaxArrayTextureLayers = 2048;
184   else
185      ctx->Const.MaxArrayTextureLayers = 512;
186
187   ctx->Const.MaxTextureRectSize = (1<<12);
188
189   ctx->Const.MaxTextureMaxAnisotropy = 16.0;
190
191   /* Hardware only supports a limited number of transform feedback buffers.
192    * So we need to override the Mesa default (which is based only on software
193    * limits).
194    */
195   ctx->Const.MaxTransformFeedbackSeparateAttribs = BRW_MAX_SOL_BUFFERS;
196
197   /* On Gen6, in the worst case, we use up one binding table entry per
198    * transform feedback component (see comments above the definition of
199    * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
200    * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
201    * BRW_MAX_SOL_BINDINGS.
202    *
203    * In "separate components" mode, we need to divide this value by
204    * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
205    * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
206    */
207   ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
208   ctx->Const.MaxTransformFeedbackSeparateComponents =
209      BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
210
211   /* Claim to support 4 multisamples, even though we don't.  This is a
212    * requirement for GL 3.0 that we missed until the last minute.  Go ahead and
213    * claim the limit, so that usage of the 4 multisample-based API that is
214    * guaranteed in 3.0 succeeds, even though we only rasterize a single sample.
215    */
216   if (intel->gen >= 6)
217      ctx->Const.MaxSamples = 4;
218
219   /* if conformance mode is set, swrast can handle any size AA point */
220   ctx->Const.MaxPointSizeAA = 255.0;
221
222   /* We want the GLSL compiler to emit code that uses condition codes */
223   for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) {
224      ctx->ShaderCompilerOptions[i].MaxIfDepth = intel->gen < 6 ? 16 : UINT_MAX;
225      ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
226      ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = true;
227      ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
228      ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
229      ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
230      ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;
231
232      ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
233	 (i == MESA_SHADER_FRAGMENT);
234      ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
235	 (i == MESA_SHADER_FRAGMENT);
236      ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
237   }
238
239   ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
240   ctx->Const.VertexProgram.MaxAluInstructions = 0;
241   ctx->Const.VertexProgram.MaxTexInstructions = 0;
242   ctx->Const.VertexProgram.MaxTexIndirections = 0;
243   ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
244   ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
245   ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
246   ctx->Const.VertexProgram.MaxNativeAttribs = 16;
247   ctx->Const.VertexProgram.MaxNativeTemps = 256;
248   ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
249   ctx->Const.VertexProgram.MaxNativeParameters = 1024;
250   ctx->Const.VertexProgram.MaxEnvParams =
251      MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
252	   ctx->Const.VertexProgram.MaxEnvParams);
253
254   ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024);
255   ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024);
256   ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024);
257   ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024);
258   ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
259   ctx->Const.FragmentProgram.MaxNativeTemps = 256;
260   ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
261   ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
262   ctx->Const.FragmentProgram.MaxEnvParams =
263      MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
264	   ctx->Const.FragmentProgram.MaxEnvParams);
265
266   /* Fragment shaders use real, 32-bit twos-complement integers for all
267    * integer types.
268    */
269   ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
270   ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
271   ctx->Const.FragmentProgram.LowInt.Precision = 0;
272   ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.MediumInt
273      = ctx->Const.FragmentProgram.LowInt;
274
275   /* Gen6 converts quads to polygon in beginning of 3D pipeline,
276      but we're not sure how it's actually done for vertex order,
277      that affect provoking vertex decision. Always use last vertex
278      convention for quad primitive which works as expected for now. */
279   if (intel->gen >= 6)
280       ctx->Const.QuadsFollowProvokingVertexConvention = false;
281
282   if (intel->is_g4x || intel->gen >= 5) {
283      brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS;
284      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
285      brw->has_surface_tile_offset = true;
286      if (intel->gen < 6)
287	  brw->has_compr4 = true;
288      brw->has_aa_line_parameters = true;
289      brw->has_pln = true;
290  } else {
291      brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS;
292      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965;
293   }
294
295   /* WM maximum threads is number of EUs times number of threads per EU. */
296   if (intel->gen >= 7) {
297      if (intel->gt == 1) {
298	 brw->max_wm_threads = 86;
299	 brw->max_vs_threads = 36;
300	 brw->max_gs_threads = 36;
301	 brw->urb.size = 128;
302	 brw->urb.max_vs_entries = 512;
303	 brw->urb.max_gs_entries = 192;
304      } else if (intel->gt == 2) {
305	 brw->max_wm_threads = 86;
306	 brw->max_vs_threads = 128;
307	 brw->max_gs_threads = 128;
308	 brw->urb.size = 256;
309	 brw->urb.max_vs_entries = 704;
310	 brw->urb.max_gs_entries = 320;
311      } else {
312	 assert(!"Unknown gen7 device.");
313      }
314   } else if (intel->gen == 6) {
315      if (intel->gt == 2) {
316	 /* This could possibly be 80, but is supposed to require
317	  * disabling of WIZ hashing (bit 6 of GT_MODE, 0x20d0) and a
318	  * GPU reset to change.
319	  */
320	 brw->max_wm_threads = 40;
321	 brw->max_vs_threads = 60;
322	 brw->max_gs_threads = 60;
323	 brw->urb.size = 64;            /* volume 5c.5 section 5.1 */
324	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
325	 brw->urb.max_gs_entries = 256;
326      } else {
327	 brw->max_wm_threads = 40;
328	 brw->max_vs_threads = 24;
329	 brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */
330	 brw->urb.size = 32;            /* volume 5c.5 section 5.1 */
331	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
332	 brw->urb.max_gs_entries = 256;
333      }
334      brw->urb.gen6_gs_previously_active = false;
335   } else if (intel->gen == 5) {
336      brw->urb.size = 1024;
337      brw->max_vs_threads = 72;
338      brw->max_gs_threads = 32;
339      brw->max_wm_threads = 12 * 6;
340   } else if (intel->is_g4x) {
341      brw->urb.size = 384;
342      brw->max_vs_threads = 32;
343      brw->max_gs_threads = 2;
344      brw->max_wm_threads = 10 * 5;
345   } else if (intel->gen < 6) {
346      brw->urb.size = 256;
347      brw->max_vs_threads = 16;
348      brw->max_gs_threads = 2;
349      brw->max_wm_threads = 8 * 4;
350      brw->has_negative_rhw_bug = true;
351   }
352
353   brw_init_state( brw );
354
355   brw->curbe.last_buf = calloc(1, 4096);
356   brw->curbe.next_buf = calloc(1, 4096);
357
358   brw->state.dirty.mesa = ~0;
359   brw->state.dirty.brw = ~0;
360
361   brw->emit_state_always = 0;
362
363   intel->batch.need_workaround_flush = true;
364
365   ctx->VertexProgram._MaintainTnlProgram = true;
366   ctx->FragmentProgram._MaintainTexEnvProgram = true;
367
368   brw_draw_init( brw );
369
370   brw->precompile = driQueryOptionb(&intel->optionCache, "shader_precompile");
371
372   ctx->Const.NativeIntegers = true;
373   ctx->Const.UniformBooleanTrue = 1;
374
375   ctx->Const.ForceGLSLExtensionsWarn = driQueryOptionb(&intel->optionCache, "force_glsl_extensions_warn");
376
377   return true;
378}
379
380