brw_context.c revision 67e9ae856355be532455c1cf1211d59b3a4c5992
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 "intel_fbo.h"
45#include "intel_mipmap_tree.h"
46#include "intel_regions.h"
47#include "intel_span.h"
48#include "intel_tex.h"
49#include "intel_tex_obj.h"
50
51#include "tnl/t_pipeline.h"
52#include "glsl/ralloc.h"
53
54/***************************************
55 * Mesa's Driver Functions
56 ***************************************/
57
58static void brwInitDriverFunctions(struct intel_screen *screen,
59				   struct dd_function_table *functions)
60{
61   intelInitDriverFunctions( functions );
62
63   brwInitFragProgFuncs( functions );
64   brw_init_queryobj_functions(functions);
65
66   functions->BeginTransformFeedback = brw_begin_transform_feedback;
67
68   if (screen->gen >= 7)
69      functions->EndTransformFeedback = gen7_end_transform_feedback;
70   else
71      functions->EndTransformFeedback = brw_end_transform_feedback;
72}
73
74bool
75brwCreateContext(int api,
76	         const struct gl_config *mesaVis,
77		 __DRIcontext *driContextPriv,
78                 unsigned major_version,
79                 unsigned minor_version,
80                 unsigned *error,
81	         void *sharedContextPrivate)
82{
83   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
84   struct intel_screen *screen = sPriv->driverPrivate;
85   struct dd_function_table functions;
86   unsigned i;
87
88   /* Filter against the requested API and version.
89    */
90   switch (api) {
91   case API_OPENGL: {
92#ifdef TEXTURE_FLOAT_ENABLED
93      const unsigned max_version =
94         (screen->gen == 6 ||
95          (screen->gen == 7 && screen->kernel_has_gen7_sol_reset))
96         ? 30 : 21;
97#else
98      const unsigned max_version = 21;
99#endif
100      const unsigned req_version = major_version * 10 + minor_version;
101
102      if (req_version > max_version) {
103         *error = __DRI_CTX_ERROR_BAD_VERSION;
104         return false;
105      }
106      break;
107   }
108   case API_OPENGLES:
109   case API_OPENGLES2:
110      break;
111   default:
112      *error = __DRI_CTX_ERROR_BAD_API;
113      return false;
114   }
115
116   struct brw_context *brw = rzalloc(NULL, struct brw_context);
117   if (!brw) {
118      printf("%s: failed to alloc context\n", __FUNCTION__);
119      *error = __DRI_CTX_ERROR_NO_MEMORY;
120      return false;
121   }
122
123   brwInitDriverFunctions(screen, &functions);
124
125   struct intel_context *intel = &brw->intel;
126   struct gl_context *ctx = &intel->ctx;
127
128   if (!intelInitContext( intel, api, mesaVis, driContextPriv,
129			  sharedContextPrivate, &functions )) {
130      printf("%s: failed to init intel context\n", __FUNCTION__);
131      FREE(brw);
132      *error = __DRI_CTX_ERROR_NO_MEMORY;
133      return false;
134   }
135
136   brwInitVtbl( brw );
137
138   brw_init_surface_formats(brw);
139
140   /* Initialize swrast, tnl driver tables: */
141   intelInitSpanFuncs(ctx);
142
143   TNLcontext *tnl = TNL_CONTEXT(ctx);
144   if (tnl)
145      tnl->Driver.RunPipeline = _tnl_run_pipeline;
146
147   ctx->Const.MaxDualSourceDrawBuffers = 1;
148   ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
149   ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
150   ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
151   ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
152                                     ctx->Const.MaxTextureImageUnits);
153   ctx->Const.MaxVertexTextureImageUnits = BRW_MAX_TEX_UNIT;
154   ctx->Const.MaxCombinedTextureImageUnits =
155      ctx->Const.MaxVertexTextureImageUnits +
156      ctx->Const.MaxTextureImageUnits;
157
158   ctx->Const.MaxTextureLevels = 14; /* 8192 */
159   if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
160	   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
161   ctx->Const.Max3DTextureLevels = 9;
162   ctx->Const.MaxCubeTextureLevels = 12;
163
164   if (intel->gen >= 7)
165      ctx->Const.MaxArrayTextureLayers = 2048;
166   else
167      ctx->Const.MaxArrayTextureLayers = 512;
168
169   ctx->Const.MaxTextureRectSize = (1<<12);
170
171   ctx->Const.MaxTextureMaxAnisotropy = 16.0;
172
173   /* Hardware only supports a limited number of transform feedback buffers.
174    * So we need to override the Mesa default (which is based only on software
175    * limits).
176    */
177   ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;
178
179   /* On Gen6, in the worst case, we use up one binding table entry per
180    * transform feedback component (see comments above the definition of
181    * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
182    * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
183    * BRW_MAX_SOL_BINDINGS.
184    *
185    * In "separate components" mode, we need to divide this value by
186    * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
187    * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
188    */
189   ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
190   ctx->Const.MaxTransformFeedbackSeparateComponents =
191      BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
192
193   if (intel->gen == 6)
194      ctx->Const.MaxSamples = 4;
195   else if (intel->gen >= 7)
196      ctx->Const.MaxSamples = 8;
197
198   /* if conformance mode is set, swrast can handle any size AA point */
199   ctx->Const.MaxPointSizeAA = 255.0;
200
201   /* We want the GLSL compiler to emit code that uses condition codes */
202   for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) {
203      ctx->ShaderCompilerOptions[i].MaxIfDepth = intel->gen < 6 ? 16 : UINT_MAX;
204      ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
205      ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = true;
206      ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
207      ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
208      ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
209      ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;
210
211      ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
212	 (i == MESA_SHADER_FRAGMENT);
213      ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
214	 (i == MESA_SHADER_FRAGMENT);
215      ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
216   }
217
218   ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
219   ctx->Const.VertexProgram.MaxAluInstructions = 0;
220   ctx->Const.VertexProgram.MaxTexInstructions = 0;
221   ctx->Const.VertexProgram.MaxTexIndirections = 0;
222   ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
223   ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
224   ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
225   ctx->Const.VertexProgram.MaxNativeAttribs = 16;
226   ctx->Const.VertexProgram.MaxNativeTemps = 256;
227   ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
228   ctx->Const.VertexProgram.MaxNativeParameters = 1024;
229   ctx->Const.VertexProgram.MaxEnvParams =
230      MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
231	   ctx->Const.VertexProgram.MaxEnvParams);
232
233   ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024);
234   ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024);
235   ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024);
236   ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024);
237   ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
238   ctx->Const.FragmentProgram.MaxNativeTemps = 256;
239   ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
240   ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
241   ctx->Const.FragmentProgram.MaxEnvParams =
242      MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
243	   ctx->Const.FragmentProgram.MaxEnvParams);
244
245   /* Fragment shaders use real, 32-bit twos-complement integers for all
246    * integer types.
247    */
248   ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
249   ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
250   ctx->Const.FragmentProgram.LowInt.Precision = 0;
251   ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.MediumInt
252      = ctx->Const.FragmentProgram.LowInt;
253
254   /* Gen6 converts quads to polygon in beginning of 3D pipeline,
255      but we're not sure how it's actually done for vertex order,
256      that affect provoking vertex decision. Always use last vertex
257      convention for quad primitive which works as expected for now. */
258   if (intel->gen >= 6)
259       ctx->Const.QuadsFollowProvokingVertexConvention = false;
260
261   ctx->Const.QueryCounterBits.Timestamp = 36;
262
263   if (intel->is_g4x || intel->gen >= 5) {
264      brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS;
265      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
266      brw->has_surface_tile_offset = true;
267      if (intel->gen < 6)
268	  brw->has_compr4 = true;
269      brw->has_aa_line_parameters = true;
270      brw->has_pln = true;
271  } else {
272      brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS;
273      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965;
274   }
275
276   /* WM maximum threads is number of EUs times number of threads per EU. */
277   if (intel->gen >= 7) {
278      if (intel->gt == 1) {
279	 brw->max_wm_threads = 48;
280	 brw->max_vs_threads = 36;
281	 brw->max_gs_threads = 36;
282	 brw->urb.size = 128;
283	 brw->urb.max_vs_entries = 512;
284	 brw->urb.max_gs_entries = 192;
285      } else if (intel->gt == 2) {
286	 brw->max_wm_threads = 172;
287	 brw->max_vs_threads = 128;
288	 brw->max_gs_threads = 128;
289	 brw->urb.size = 256;
290	 brw->urb.max_vs_entries = 704;
291	 brw->urb.max_gs_entries = 320;
292      } else {
293	 assert(!"Unknown gen7 device.");
294      }
295   } else if (intel->gen == 6) {
296      if (intel->gt == 2) {
297	 brw->max_wm_threads = 80;
298	 brw->max_vs_threads = 60;
299	 brw->max_gs_threads = 60;
300	 brw->urb.size = 64;            /* volume 5c.5 section 5.1 */
301	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
302	 brw->urb.max_gs_entries = 256;
303      } else {
304	 brw->max_wm_threads = 40;
305	 brw->max_vs_threads = 24;
306	 brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */
307	 brw->urb.size = 32;            /* volume 5c.5 section 5.1 */
308	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
309	 brw->urb.max_gs_entries = 256;
310      }
311      brw->urb.gen6_gs_previously_active = false;
312   } else if (intel->gen == 5) {
313      brw->urb.size = 1024;
314      brw->max_vs_threads = 72;
315      brw->max_gs_threads = 32;
316      brw->max_wm_threads = 12 * 6;
317   } else if (intel->is_g4x) {
318      brw->urb.size = 384;
319      brw->max_vs_threads = 32;
320      brw->max_gs_threads = 2;
321      brw->max_wm_threads = 10 * 5;
322   } else if (intel->gen < 6) {
323      brw->urb.size = 256;
324      brw->max_vs_threads = 16;
325      brw->max_gs_threads = 2;
326      brw->max_wm_threads = 8 * 4;
327      brw->has_negative_rhw_bug = true;
328   }
329
330   if (intel->gen <= 7) {
331      brw->needs_unlit_centroid_workaround = true;
332   }
333
334   brw->prim_restart.in_progress = false;
335   brw->prim_restart.enable_cut_index = false;
336   intel->hw_ctx = drm_intel_gem_context_create(intel->bufmgr);
337
338   brw_init_state( brw );
339
340   brw->curbe.last_buf = calloc(1, 4096);
341   brw->curbe.next_buf = calloc(1, 4096);
342
343   brw->state.dirty.mesa = ~0;
344   brw->state.dirty.brw = ~0;
345
346   brw->emit_state_always = 0;
347
348   intel->batch.need_workaround_flush = true;
349
350   ctx->VertexProgram._MaintainTnlProgram = true;
351   ctx->FragmentProgram._MaintainTexEnvProgram = true;
352
353   brw_draw_init( brw );
354
355   brw->precompile = driQueryOptionb(&intel->optionCache, "shader_precompile");
356
357   ctx->Const.NativeIntegers = true;
358   ctx->Const.UniformBooleanTrue = 1;
359
360   ctx->Const.ForceGLSLExtensionsWarn = driQueryOptionb(&intel->optionCache, "force_glsl_extensions_warn");
361
362   return true;
363}
364
365