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