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