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 
brwInitDriverFunctions(struct intel_screen * screen,struct dd_function_table * functions)58 static 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 
74 bool
brwCreateContext(int api,const struct gl_config * mesaVis,__DRIcontext * driContextPriv,unsigned major_version,unsigned minor_version,uint32_t flags,unsigned * error,void * sharedContextPrivate)75 brwCreateContext(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