brw_context.c revision d60692601388b5448fb0ed4eb894103293b2f074
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   TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
144
145   ctx->Const.MaxDualSourceDrawBuffers = 1;
146   ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
147   ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
148   ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
149   ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
150                                     ctx->Const.MaxTextureImageUnits);
151   ctx->Const.MaxVertexTextureImageUnits = BRW_MAX_TEX_UNIT;
152   ctx->Const.MaxCombinedTextureImageUnits =
153      ctx->Const.MaxVertexTextureImageUnits +
154      ctx->Const.MaxTextureImageUnits;
155
156   ctx->Const.MaxTextureLevels = 14; /* 8192 */
157   if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
158	   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
159   ctx->Const.Max3DTextureLevels = 9;
160   ctx->Const.MaxCubeTextureLevels = 12;
161
162   if (intel->gen >= 7)
163      ctx->Const.MaxArrayTextureLayers = 2048;
164   else
165      ctx->Const.MaxArrayTextureLayers = 512;
166
167   ctx->Const.MaxTextureRectSize = (1<<12);
168
169   ctx->Const.MaxTextureMaxAnisotropy = 16.0;
170
171   /* Hardware only supports a limited number of transform feedback buffers.
172    * So we need to override the Mesa default (which is based only on software
173    * limits).
174    */
175   ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;
176
177   /* On Gen6, in the worst case, we use up one binding table entry per
178    * transform feedback component (see comments above the definition of
179    * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
180    * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
181    * BRW_MAX_SOL_BINDINGS.
182    *
183    * In "separate components" mode, we need to divide this value by
184    * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
185    * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
186    */
187   ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
188   ctx->Const.MaxTransformFeedbackSeparateComponents =
189      BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
190
191   if (intel->gen == 6)
192      ctx->Const.MaxSamples = 4;
193   else if (intel->gen >= 7)
194      ctx->Const.MaxSamples = 8;
195
196   /* if conformance mode is set, swrast can handle any size AA point */
197   ctx->Const.MaxPointSizeAA = 255.0;
198
199   /* We want the GLSL compiler to emit code that uses condition codes */
200   for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) {
201      ctx->ShaderCompilerOptions[i].MaxIfDepth = intel->gen < 6 ? 16 : UINT_MAX;
202      ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
203      ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = true;
204      ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
205      ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
206      ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
207      ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;
208
209      ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
210	 (i == MESA_SHADER_FRAGMENT);
211      ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
212	 (i == MESA_SHADER_FRAGMENT);
213      ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
214   }
215
216   ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
217   ctx->Const.VertexProgram.MaxAluInstructions = 0;
218   ctx->Const.VertexProgram.MaxTexInstructions = 0;
219   ctx->Const.VertexProgram.MaxTexIndirections = 0;
220   ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
221   ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
222   ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
223   ctx->Const.VertexProgram.MaxNativeAttribs = 16;
224   ctx->Const.VertexProgram.MaxNativeTemps = 256;
225   ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
226   ctx->Const.VertexProgram.MaxNativeParameters = 1024;
227   ctx->Const.VertexProgram.MaxEnvParams =
228      MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
229	   ctx->Const.VertexProgram.MaxEnvParams);
230
231   ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024);
232   ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024);
233   ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024);
234   ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024);
235   ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
236   ctx->Const.FragmentProgram.MaxNativeTemps = 256;
237   ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
238   ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
239   ctx->Const.FragmentProgram.MaxEnvParams =
240      MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
241	   ctx->Const.FragmentProgram.MaxEnvParams);
242
243   /* Fragment shaders use real, 32-bit twos-complement integers for all
244    * integer types.
245    */
246   ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
247   ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
248   ctx->Const.FragmentProgram.LowInt.Precision = 0;
249   ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.MediumInt
250      = ctx->Const.FragmentProgram.LowInt;
251
252   /* Gen6 converts quads to polygon in beginning of 3D pipeline,
253      but we're not sure how it's actually done for vertex order,
254      that affect provoking vertex decision. Always use last vertex
255      convention for quad primitive which works as expected for now. */
256   if (intel->gen >= 6)
257       ctx->Const.QuadsFollowProvokingVertexConvention = false;
258
259   if (intel->is_g4x || intel->gen >= 5) {
260      brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS;
261      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
262      brw->has_surface_tile_offset = true;
263      if (intel->gen < 6)
264	  brw->has_compr4 = true;
265      brw->has_aa_line_parameters = true;
266      brw->has_pln = true;
267  } else {
268      brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS;
269      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965;
270   }
271
272   /* WM maximum threads is number of EUs times number of threads per EU. */
273   if (intel->gen >= 7) {
274      if (intel->gt == 1) {
275	 brw->max_wm_threads = 48;
276	 brw->max_vs_threads = 36;
277	 brw->max_gs_threads = 36;
278	 brw->urb.size = 128;
279	 brw->urb.max_vs_entries = 512;
280	 brw->urb.max_gs_entries = 192;
281      } else if (intel->gt == 2) {
282	 brw->max_wm_threads = 172;
283	 brw->max_vs_threads = 128;
284	 brw->max_gs_threads = 128;
285	 brw->urb.size = 256;
286	 brw->urb.max_vs_entries = 704;
287	 brw->urb.max_gs_entries = 320;
288      } else {
289	 assert(!"Unknown gen7 device.");
290      }
291   } else if (intel->gen == 6) {
292      if (intel->gt == 2) {
293	 brw->max_wm_threads = 80;
294	 brw->max_vs_threads = 60;
295	 brw->max_gs_threads = 60;
296	 brw->urb.size = 64;            /* volume 5c.5 section 5.1 */
297	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
298	 brw->urb.max_gs_entries = 256;
299      } else {
300	 brw->max_wm_threads = 40;
301	 brw->max_vs_threads = 24;
302	 brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */
303	 brw->urb.size = 32;            /* volume 5c.5 section 5.1 */
304	 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */
305	 brw->urb.max_gs_entries = 256;
306      }
307      brw->urb.gen6_gs_previously_active = false;
308   } else if (intel->gen == 5) {
309      brw->urb.size = 1024;
310      brw->max_vs_threads = 72;
311      brw->max_gs_threads = 32;
312      brw->max_wm_threads = 12 * 6;
313   } else if (intel->is_g4x) {
314      brw->urb.size = 384;
315      brw->max_vs_threads = 32;
316      brw->max_gs_threads = 2;
317      brw->max_wm_threads = 10 * 5;
318   } else if (intel->gen < 6) {
319      brw->urb.size = 256;
320      brw->max_vs_threads = 16;
321      brw->max_gs_threads = 2;
322      brw->max_wm_threads = 8 * 4;
323      brw->has_negative_rhw_bug = true;
324   }
325
326   if (intel->gen <= 7) {
327      brw->needs_unlit_centroid_workaround = true;
328   }
329
330   brw->prim_restart.in_progress = false;
331   brw->prim_restart.enable_cut_index = false;
332   intel->hw_ctx = drm_intel_gem_context_create(intel->bufmgr);
333
334   brw_init_state( brw );
335
336   brw->curbe.last_buf = calloc(1, 4096);
337   brw->curbe.next_buf = calloc(1, 4096);
338
339   brw->state.dirty.mesa = ~0;
340   brw->state.dirty.brw = ~0;
341
342   brw->emit_state_always = 0;
343
344   intel->batch.need_workaround_flush = true;
345
346   ctx->VertexProgram._MaintainTnlProgram = true;
347   ctx->FragmentProgram._MaintainTexEnvProgram = true;
348
349   brw_draw_init( brw );
350
351   brw->precompile = driQueryOptionb(&intel->optionCache, "shader_precompile");
352
353   ctx->Const.NativeIntegers = true;
354   ctx->Const.UniformBooleanTrue = 1;
355
356   ctx->Const.ForceGLSLExtensionsWarn = driQueryOptionb(&intel->optionCache, "force_glsl_extensions_warn");
357
358   return true;
359}
360
361