i965: Only enable __DRI2_ROBUSTNESS if kernel support is available
[mesa.git] / src / mesa / drivers / dri / i965 / brw_context.c
1 /*
2 Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
3 Copyright (C) Intel Corp. 2006. All Rights Reserved.
4 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
5 develop this 3D driver.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **********************************************************************/
28 /*
29 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33
34 #include "main/api_exec.h"
35 #include "main/context.h"
36 #include "main/fbobject.h"
37 #include "main/imports.h"
38 #include "main/macros.h"
39 #include "main/points.h"
40 #include "main/version.h"
41 #include "main/vtxfmt.h"
42
43 #include "vbo/vbo_context.h"
44
45 #include "drivers/common/driverfuncs.h"
46 #include "drivers/common/meta.h"
47 #include "utils.h"
48
49 #include "brw_context.h"
50 #include "brw_defines.h"
51 #include "brw_draw.h"
52 #include "brw_state.h"
53
54 #include "intel_batchbuffer.h"
55 #include "intel_buffer_objects.h"
56 #include "intel_buffers.h"
57 #include "intel_fbo.h"
58 #include "intel_mipmap_tree.h"
59 #include "intel_pixel.h"
60 #include "intel_regions.h"
61 #include "intel_tex.h"
62 #include "intel_tex_obj.h"
63
64 #include "swrast_setup/swrast_setup.h"
65 #include "tnl/tnl.h"
66 #include "tnl/t_pipeline.h"
67 #include "glsl/ralloc.h"
68
69 /***************************************
70 * Mesa's Driver Functions
71 ***************************************/
72
73 static size_t
74 brw_query_samples_for_format(struct gl_context *ctx, GLenum target,
75 GLenum internalFormat, int samples[16])
76 {
77 struct brw_context *brw = brw_context(ctx);
78
79 (void) target;
80
81 switch (brw->gen) {
82 case 7:
83 samples[0] = 8;
84 samples[1] = 4;
85 return 2;
86
87 case 6:
88 samples[0] = 4;
89 return 1;
90
91 default:
92 samples[0] = 1;
93 return 1;
94 }
95 }
96
97 const char *const brw_vendor_string = "Intel Open Source Technology Center";
98
99 const char *
100 brw_get_renderer_string(unsigned deviceID)
101 {
102 const char *chipset;
103 static char buffer[128];
104
105 switch (deviceID) {
106 #undef CHIPSET
107 #define CHIPSET(id, symbol, str) case id: chipset = str; break;
108 #include "pci_ids/i965_pci_ids.h"
109 default:
110 chipset = "Unknown Intel Chipset";
111 break;
112 }
113
114 (void) driGetRendererString(buffer, chipset, 0);
115 return buffer;
116 }
117
118 static const GLubyte *
119 intelGetString(struct gl_context * ctx, GLenum name)
120 {
121 const struct brw_context *const brw = brw_context(ctx);
122
123 switch (name) {
124 case GL_VENDOR:
125 return (GLubyte *) brw_vendor_string;
126
127 case GL_RENDERER:
128 return
129 (GLubyte *) brw_get_renderer_string(brw->intelScreen->deviceID);
130
131 default:
132 return NULL;
133 }
134 }
135
136 static void
137 intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
138 {
139 struct brw_context *brw = brw_context(ctx);
140 __DRIcontext *driContext = brw->driContext;
141
142 (void) x;
143 (void) y;
144 (void) w;
145 (void) h;
146
147 if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
148 dri2InvalidateDrawable(driContext->driDrawablePriv);
149 dri2InvalidateDrawable(driContext->driReadablePriv);
150 }
151 }
152
153 static void
154 intelInvalidateState(struct gl_context * ctx, GLuint new_state)
155 {
156 struct brw_context *brw = brw_context(ctx);
157
158 if (ctx->swrast_context)
159 _swrast_InvalidateState(ctx, new_state);
160 _vbo_InvalidateState(ctx, new_state);
161
162 brw->NewGLState |= new_state;
163 }
164
165 #define flushFront(screen) ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer)
166
167 static void
168 intel_flush_front(struct gl_context *ctx)
169 {
170 struct brw_context *brw = brw_context(ctx);
171 __DRIcontext *driContext = brw->driContext;
172 __DRIdrawable *driDrawable = driContext->driDrawablePriv;
173 __DRIscreen *const screen = brw->intelScreen->driScrnPriv;
174
175 if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
176 if (flushFront(screen) && driDrawable &&
177 driDrawable->loaderPrivate) {
178
179 /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
180 *
181 * This potentially resolves both front and back buffer. It
182 * is unnecessary to resolve the back, but harms nothing except
183 * performance. And no one cares about front-buffer render
184 * performance.
185 */
186 intel_resolve_for_dri2_flush(brw, driDrawable);
187 intel_batchbuffer_flush(brw);
188
189 flushFront(screen)(driDrawable, driDrawable->loaderPrivate);
190
191 /* We set the dirty bit in intel_prepare_render() if we're
192 * front buffer rendering once we get there.
193 */
194 brw->front_buffer_dirty = false;
195 }
196 }
197 }
198
199 static void
200 intel_glFlush(struct gl_context *ctx)
201 {
202 struct brw_context *brw = brw_context(ctx);
203
204 intel_batchbuffer_flush(brw);
205 intel_flush_front(ctx);
206 if (brw->is_front_buffer_rendering)
207 brw->need_throttle = true;
208 }
209
210 void
211 intelFinish(struct gl_context * ctx)
212 {
213 struct brw_context *brw = brw_context(ctx);
214
215 intel_glFlush(ctx);
216
217 if (brw->batch.last_bo)
218 drm_intel_bo_wait_rendering(brw->batch.last_bo);
219 }
220
221 static void
222 brw_init_driver_functions(struct brw_context *brw,
223 struct dd_function_table *functions)
224 {
225 _mesa_init_driver_functions(functions);
226
227 /* GLX uses DRI2 invalidate events to handle window resizing.
228 * Unfortunately, EGL does not - libEGL is written in XCB (not Xlib),
229 * which doesn't provide a mechanism for snooping the event queues.
230 *
231 * So EGL still relies on viewport hacks to handle window resizing.
232 * This should go away with DRI3000.
233 */
234 if (!brw->driContext->driScreenPriv->dri2.useInvalidate)
235 functions->Viewport = intel_viewport;
236
237 functions->Flush = intel_glFlush;
238 functions->Finish = intelFinish;
239 functions->GetString = intelGetString;
240 functions->UpdateState = intelInvalidateState;
241
242 intelInitTextureFuncs(functions);
243 intelInitTextureImageFuncs(functions);
244 intelInitTextureSubImageFuncs(functions);
245 intelInitTextureCopyImageFuncs(functions);
246 intelInitClearFuncs(functions);
247 intelInitBufferFuncs(functions);
248 intelInitPixelFuncs(functions);
249 intelInitBufferObjectFuncs(functions);
250 intel_init_syncobj_functions(functions);
251 brw_init_object_purgeable_functions(functions);
252
253 brwInitFragProgFuncs( functions );
254 brw_init_common_queryobj_functions(functions);
255 if (brw->gen >= 6)
256 gen6_init_queryobj_functions(functions);
257 else
258 gen4_init_queryobj_functions(functions);
259
260 functions->QuerySamplesForFormat = brw_query_samples_for_format;
261
262 functions->NewTransformFeedback = brw_new_transform_feedback;
263 functions->DeleteTransformFeedback = brw_delete_transform_feedback;
264 functions->GetTransformFeedbackVertexCount =
265 brw_get_transform_feedback_vertex_count;
266 if (brw->gen >= 7) {
267 functions->BeginTransformFeedback = gen7_begin_transform_feedback;
268 functions->EndTransformFeedback = gen7_end_transform_feedback;
269 functions->PauseTransformFeedback = gen7_pause_transform_feedback;
270 functions->ResumeTransformFeedback = gen7_resume_transform_feedback;
271 } else {
272 functions->BeginTransformFeedback = brw_begin_transform_feedback;
273 functions->EndTransformFeedback = brw_end_transform_feedback;
274 }
275
276 if (brw->gen >= 6)
277 functions->GetSamplePosition = gen6_get_sample_position;
278 }
279
280 static void
281 brw_initialize_context_constants(struct brw_context *brw)
282 {
283 struct gl_context *ctx = &brw->ctx;
284
285 ctx->Const.QueryCounterBits.Timestamp = 36;
286
287 ctx->Const.StripTextureBorder = true;
288
289 ctx->Const.MaxDualSourceDrawBuffers = 1;
290 ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
291 ctx->Const.FragmentProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
292 ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
293 ctx->Const.MaxTextureUnits =
294 MIN2(ctx->Const.MaxTextureCoordUnits,
295 ctx->Const.FragmentProgram.MaxTextureImageUnits);
296 ctx->Const.VertexProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
297 if (brw->gen >= 7)
298 ctx->Const.GeometryProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
299 else
300 ctx->Const.GeometryProgram.MaxTextureImageUnits = 0;
301 ctx->Const.MaxCombinedTextureImageUnits =
302 ctx->Const.VertexProgram.MaxTextureImageUnits +
303 ctx->Const.FragmentProgram.MaxTextureImageUnits +
304 ctx->Const.GeometryProgram.MaxTextureImageUnits;
305
306 ctx->Const.MaxTextureLevels = 14; /* 8192 */
307 if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
308 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
309 ctx->Const.Max3DTextureLevels = 9;
310 ctx->Const.MaxCubeTextureLevels = 12;
311
312 if (brw->gen >= 7)
313 ctx->Const.MaxArrayTextureLayers = 2048;
314 else
315 ctx->Const.MaxArrayTextureLayers = 512;
316
317 ctx->Const.MaxTextureRectSize = 1 << 12;
318
319 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
320
321 ctx->Const.MaxRenderbufferSize = 8192;
322
323 /* Hardware only supports a limited number of transform feedback buffers.
324 * So we need to override the Mesa default (which is based only on software
325 * limits).
326 */
327 ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;
328
329 /* On Gen6, in the worst case, we use up one binding table entry per
330 * transform feedback component (see comments above the definition of
331 * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
332 * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
333 * BRW_MAX_SOL_BINDINGS.
334 *
335 * In "separate components" mode, we need to divide this value by
336 * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
337 * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
338 */
339 ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
340 ctx->Const.MaxTransformFeedbackSeparateComponents =
341 BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
342
343 ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;
344
345 int max_samples;
346 const int *msaa_modes = intel_supported_msaa_modes(brw->intelScreen);
347 const int clamp_max_samples =
348 driQueryOptioni(&brw->optionCache, "clamp_max_samples");
349
350 if (clamp_max_samples < 0) {
351 max_samples = msaa_modes[0];
352 } else {
353 /* Select the largest supported MSAA mode that does not exceed
354 * clamp_max_samples.
355 */
356 max_samples = 0;
357 for (int i = 0; msaa_modes[i] != 0; ++i) {
358 if (msaa_modes[i] <= clamp_max_samples) {
359 max_samples = msaa_modes[i];
360 break;
361 }
362 }
363 }
364
365 ctx->Const.MaxSamples = max_samples;
366 ctx->Const.MaxColorTextureSamples = max_samples;
367 ctx->Const.MaxDepthTextureSamples = max_samples;
368 ctx->Const.MaxIntegerSamples = max_samples;
369
370 if (brw->gen >= 7)
371 ctx->Const.MaxProgramTextureGatherComponents = 4;
372
373 ctx->Const.MinLineWidth = 1.0;
374 ctx->Const.MinLineWidthAA = 1.0;
375 ctx->Const.MaxLineWidth = 5.0;
376 ctx->Const.MaxLineWidthAA = 5.0;
377 ctx->Const.LineWidthGranularity = 0.5;
378
379 ctx->Const.MinPointSize = 1.0;
380 ctx->Const.MinPointSizeAA = 1.0;
381 ctx->Const.MaxPointSize = 255.0;
382 ctx->Const.MaxPointSizeAA = 255.0;
383 ctx->Const.PointSizeGranularity = 1.0;
384
385 if (brw->gen >= 5 || brw->is_g4x)
386 ctx->Const.MaxClipPlanes = 8;
387
388 ctx->Const.VertexProgram.MaxNativeInstructions = 16 * 1024;
389 ctx->Const.VertexProgram.MaxAluInstructions = 0;
390 ctx->Const.VertexProgram.MaxTexInstructions = 0;
391 ctx->Const.VertexProgram.MaxTexIndirections = 0;
392 ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
393 ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
394 ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
395 ctx->Const.VertexProgram.MaxNativeAttribs = 16;
396 ctx->Const.VertexProgram.MaxNativeTemps = 256;
397 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
398 ctx->Const.VertexProgram.MaxNativeParameters = 1024;
399 ctx->Const.VertexProgram.MaxEnvParams =
400 MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
401 ctx->Const.VertexProgram.MaxEnvParams);
402
403 ctx->Const.FragmentProgram.MaxNativeInstructions = 1024;
404 ctx->Const.FragmentProgram.MaxNativeAluInstructions = 1024;
405 ctx->Const.FragmentProgram.MaxNativeTexInstructions = 1024;
406 ctx->Const.FragmentProgram.MaxNativeTexIndirections = 1024;
407 ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
408 ctx->Const.FragmentProgram.MaxNativeTemps = 256;
409 ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
410 ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
411 ctx->Const.FragmentProgram.MaxEnvParams =
412 MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
413 ctx->Const.FragmentProgram.MaxEnvParams);
414
415 /* Fragment shaders use real, 32-bit twos-complement integers for all
416 * integer types.
417 */
418 ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
419 ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
420 ctx->Const.FragmentProgram.LowInt.Precision = 0;
421 ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.LowInt;
422 ctx->Const.FragmentProgram.MediumInt = ctx->Const.FragmentProgram.LowInt;
423
424 if (brw->gen >= 7) {
425 ctx->Const.FragmentProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
426 ctx->Const.VertexProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
427 ctx->Const.GeometryProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
428 ctx->Const.FragmentProgram.MaxAtomicBuffers = BRW_MAX_ABO;
429 ctx->Const.VertexProgram.MaxAtomicBuffers = BRW_MAX_ABO;
430 ctx->Const.GeometryProgram.MaxAtomicBuffers = BRW_MAX_ABO;
431 ctx->Const.MaxCombinedAtomicBuffers = 3 * BRW_MAX_ABO;
432 }
433
434 /* Gen6 converts quads to polygon in beginning of 3D pipeline,
435 * but we're not sure how it's actually done for vertex order,
436 * that affect provoking vertex decision. Always use last vertex
437 * convention for quad primitive which works as expected for now.
438 */
439 if (brw->gen >= 6)
440 ctx->Const.QuadsFollowProvokingVertexConvention = false;
441
442 ctx->Const.NativeIntegers = true;
443 ctx->Const.UniformBooleanTrue = 1;
444
445 /* From the gen4 PRM, volume 4 page 127:
446 *
447 * "For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
448 * the base address of the first element of the surface, computed in
449 * software by adding the surface base address to the byte offset of
450 * the element in the buffer."
451 *
452 * However, unaligned accesses are slower, so enforce buffer alignment.
453 */
454 ctx->Const.UniformBufferOffsetAlignment = 16;
455 ctx->Const.TextureBufferOffsetAlignment = 16;
456
457 if (brw->gen >= 6) {
458 ctx->Const.MaxVarying = 32;
459 ctx->Const.VertexProgram.MaxOutputComponents = 128;
460 ctx->Const.GeometryProgram.MaxInputComponents = 64;
461 ctx->Const.GeometryProgram.MaxOutputComponents = 128;
462 ctx->Const.FragmentProgram.MaxInputComponents = 128;
463 }
464
465 /* We want the GLSL compiler to emit code that uses condition codes */
466 for (int i = 0; i < MESA_SHADER_TYPES; i++) {
467 ctx->ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
468 ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
469 ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
470 ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
471 ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
472 ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;
473
474 ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
475 (i == MESA_SHADER_FRAGMENT);
476 ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
477 (i == MESA_SHADER_FRAGMENT);
478 ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
479 }
480
481 ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].PreferDP4 = true;
482 }
483
484 /**
485 * Process driconf (drirc) options, setting appropriate context flags.
486 *
487 * intelInitExtensions still pokes at optionCache directly, in order to
488 * avoid advertising various extensions. No flags are set, so it makes
489 * sense to continue doing that there.
490 */
491 static void
492 brw_process_driconf_options(struct brw_context *brw)
493 {
494 struct gl_context *ctx = &brw->ctx;
495
496 driOptionCache *options = &brw->optionCache;
497 driParseConfigFiles(options, &brw->intelScreen->optionCache,
498 brw->driContext->driScreenPriv->myNum, "i965");
499
500 int bo_reuse_mode = driQueryOptioni(options, "bo_reuse");
501 switch (bo_reuse_mode) {
502 case DRI_CONF_BO_REUSE_DISABLED:
503 break;
504 case DRI_CONF_BO_REUSE_ALL:
505 intel_bufmgr_gem_enable_reuse(brw->bufmgr);
506 break;
507 }
508
509 if (!driQueryOptionb(options, "hiz")) {
510 brw->has_hiz = false;
511 /* On gen6, you can only do separate stencil with HIZ. */
512 if (brw->gen == 6)
513 brw->has_separate_stencil = false;
514 }
515
516 if (driQueryOptionb(options, "always_flush_batch")) {
517 fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
518 brw->always_flush_batch = true;
519 }
520
521 if (driQueryOptionb(options, "always_flush_cache")) {
522 fprintf(stderr, "flushing GPU caches before/after each draw call\n");
523 brw->always_flush_cache = true;
524 }
525
526 if (driQueryOptionb(options, "disable_throttling")) {
527 fprintf(stderr, "disabling flush throttling\n");
528 brw->disable_throttling = true;
529 }
530
531 brw->disable_derivative_optimization =
532 driQueryOptionb(&brw->optionCache, "disable_derivative_optimization");
533
534 brw->precompile = driQueryOptionb(&brw->optionCache, "shader_precompile");
535
536 ctx->Const.ForceGLSLExtensionsWarn =
537 driQueryOptionb(options, "force_glsl_extensions_warn");
538
539 ctx->Const.DisableGLSLLineContinuations =
540 driQueryOptionb(options, "disable_glsl_line_continuations");
541 }
542
543 GLboolean
544 brwCreateContext(gl_api api,
545 const struct gl_config *mesaVis,
546 __DRIcontext *driContextPriv,
547 unsigned major_version,
548 unsigned minor_version,
549 uint32_t flags,
550 bool notify_reset,
551 unsigned *dri_ctx_error,
552 void *sharedContextPrivate)
553 {
554 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
555 struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
556 struct intel_screen *screen = sPriv->driverPrivate;
557 const struct brw_device_info *devinfo = screen->devinfo;
558 struct dd_function_table functions;
559 struct gl_config visual;
560
561 if (flags & ~(__DRI_CTX_FLAG_DEBUG
562 | __DRI_CTX_FLAG_FORWARD_COMPATIBLE
563 | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)) {
564 *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
565 return false;
566 }
567
568 struct brw_context *brw = rzalloc(NULL, struct brw_context);
569 if (!brw) {
570 printf("%s: failed to alloc context\n", __FUNCTION__);
571 *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
572 return false;
573 }
574
575 driContextPriv->driverPrivate = brw;
576 brw->driContext = driContextPriv;
577 brw->intelScreen = screen;
578 brw->bufmgr = screen->bufmgr;
579
580 brw->gen = devinfo->gen;
581 brw->gt = devinfo->gt;
582 brw->is_g4x = devinfo->is_g4x;
583 brw->is_baytrail = devinfo->is_baytrail;
584 brw->is_haswell = devinfo->is_haswell;
585 brw->has_llc = devinfo->has_llc;
586 brw->has_hiz = devinfo->has_hiz_and_separate_stencil && brw->gen < 8;
587 brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil;
588 brw->has_pln = devinfo->has_pln;
589 brw->has_compr4 = devinfo->has_compr4;
590 brw->has_surface_tile_offset = devinfo->has_surface_tile_offset;
591 brw->has_negative_rhw_bug = devinfo->has_negative_rhw_bug;
592 brw->needs_unlit_centroid_workaround =
593 devinfo->needs_unlit_centroid_workaround;
594
595 brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil;
596 brw->has_swizzling = screen->hw_has_swizzling;
597
598 if (brw->gen >= 7) {
599 gen7_init_vtable_surface_functions(brw);
600 gen7_init_vtable_sampler_functions(brw);
601 brw->vtbl.emit_depth_stencil_hiz = gen7_emit_depth_stencil_hiz;
602 } else {
603 gen4_init_vtable_surface_functions(brw);
604 gen4_init_vtable_sampler_functions(brw);
605 brw->vtbl.emit_depth_stencil_hiz = brw_emit_depth_stencil_hiz;
606 }
607
608 brw_init_driver_functions(brw, &functions);
609
610 if (notify_reset)
611 functions.GetGraphicsResetStatus = brw_get_graphics_reset_status;
612
613 struct gl_context *ctx = &brw->ctx;
614
615 if (mesaVis == NULL) {
616 memset(&visual, 0, sizeof visual);
617 mesaVis = &visual;
618 }
619
620 if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) {
621 *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
622 printf("%s: failed to init mesa context\n", __FUNCTION__);
623 intelDestroyContext(driContextPriv);
624 return false;
625 }
626
627 /* Initialize the software rasterizer and helper modules.
628 *
629 * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
630 * software fallbacks (which we have to support on legacy GL to do weird
631 * glDrawPixels(), glBitmap(), and other functions).
632 */
633 if (api != API_OPENGL_CORE && api != API_OPENGLES2) {
634 _swrast_CreateContext(ctx);
635 }
636
637 _vbo_CreateContext(ctx);
638 if (ctx->swrast_context) {
639 _tnl_CreateContext(ctx);
640 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
641 _swsetup_CreateContext(ctx);
642
643 /* Configure swrast to match hardware characteristics: */
644 _swrast_allow_pixel_fog(ctx, false);
645 _swrast_allow_vertex_fog(ctx, true);
646 }
647
648 _mesa_meta_init(ctx);
649
650 brw_process_driconf_options(brw);
651 brw_process_intel_debug_variable(brw);
652 brw_initialize_context_constants(brw);
653
654 ctx->Const.ResetStrategy = notify_reset
655 ? GL_LOSE_CONTEXT_ON_RESET_ARB : GL_NO_RESET_NOTIFICATION_ARB;
656
657 /* Reinitialize the context point state. It depends on ctx->Const values. */
658 _mesa_init_point(ctx);
659
660 intel_batchbuffer_init(brw);
661
662 brw_init_state(brw);
663
664 intelInitExtensions(ctx);
665
666 intel_fbo_init(brw);
667
668 if (brw->gen >= 6) {
669 /* Create a new hardware context. Using a hardware context means that
670 * our GPU state will be saved/restored on context switch, allowing us
671 * to assume that the GPU is in the same state we left it in.
672 *
673 * This is required for transform feedback buffer offsets, query objects,
674 * and also allows us to reduce how much state we have to emit.
675 */
676 brw->hw_ctx = drm_intel_gem_context_create(brw->bufmgr);
677
678 if (!brw->hw_ctx) {
679 fprintf(stderr, "Gen6+ requires Kernel 3.6 or later.\n");
680 intelDestroyContext(driContextPriv);
681 return false;
682 }
683 }
684
685 brw_init_surface_formats(brw);
686
687 if (brw->is_g4x || brw->gen >= 5) {
688 brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS;
689 brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
690 } else {
691 brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS;
692 brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965;
693 }
694
695 brw->max_vs_threads = devinfo->max_vs_threads;
696 brw->max_gs_threads = devinfo->max_gs_threads;
697 brw->max_wm_threads = devinfo->max_wm_threads;
698 brw->urb.size = devinfo->urb.size;
699 brw->urb.min_vs_entries = devinfo->urb.min_vs_entries;
700 brw->urb.max_vs_entries = devinfo->urb.max_vs_entries;
701 brw->urb.max_gs_entries = devinfo->urb.max_gs_entries;
702
703 /* Estimate the size of the mappable aperture into the GTT. There's an
704 * ioctl to get the whole GTT size, but not one to get the mappable subset.
705 * It turns out it's basically always 256MB, though some ancient hardware
706 * was smaller.
707 */
708 uint32_t gtt_size = 256 * 1024 * 1024;
709
710 /* We don't want to map two objects such that a memcpy between them would
711 * just fault one mapping in and then the other over and over forever. So
712 * we would need to divide the GTT size by 2. Additionally, some GTT is
713 * taken up by things like the framebuffer and the ringbuffer and such, so
714 * be more conservative.
715 */
716 brw->max_gtt_map_object_size = gtt_size / 4;
717
718 if (brw->gen == 6)
719 brw->urb.gen6_gs_previously_active = false;
720
721 brw->prim_restart.in_progress = false;
722 brw->prim_restart.enable_cut_index = false;
723 brw->gs.enabled = false;
724
725 if (brw->gen < 6) {
726 brw->curbe.last_buf = calloc(1, 4096);
727 brw->curbe.next_buf = calloc(1, 4096);
728 }
729
730 ctx->VertexProgram._MaintainTnlProgram = true;
731 ctx->FragmentProgram._MaintainTexEnvProgram = true;
732
733 brw_draw_init( brw );
734
735 if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) {
736 /* Turn on some extra GL_ARB_debug_output generation. */
737 brw->perf_debug = true;
738 }
739
740 if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0)
741 ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
742
743 brw_fs_alloc_reg_sets(brw);
744 brw_vec4_alloc_reg_set(brw);
745
746 if (INTEL_DEBUG & DEBUG_SHADER_TIME)
747 brw_init_shader_time(brw);
748
749 _mesa_compute_version(ctx);
750
751 _mesa_initialize_dispatch_tables(ctx);
752 _mesa_initialize_vbo_vtxfmt(ctx);
753
754 if (ctx->Extensions.AMD_performance_monitor) {
755 brw_init_performance_monitors(brw);
756 }
757
758 return true;
759 }
760
761 void
762 intelDestroyContext(__DRIcontext * driContextPriv)
763 {
764 struct brw_context *brw =
765 (struct brw_context *) driContextPriv->driverPrivate;
766 struct gl_context *ctx = &brw->ctx;
767
768 assert(brw); /* should never be null */
769 if (!brw)
770 return;
771
772 /* Dump a final BMP in case the application doesn't call SwapBuffers */
773 if (INTEL_DEBUG & DEBUG_AUB) {
774 intel_batchbuffer_flush(brw);
775 aub_dump_bmp(&brw->ctx);
776 }
777
778 _mesa_meta_free(&brw->ctx);
779
780 if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
781 /* Force a report. */
782 brw->shader_time.report_time = 0;
783
784 brw_collect_and_report_shader_time(brw);
785 brw_destroy_shader_time(brw);
786 }
787
788 brw_destroy_state(brw);
789 brw_draw_destroy(brw);
790
791 drm_intel_bo_unreference(brw->curbe.curbe_bo);
792 drm_intel_bo_unreference(brw->vs.base.const_bo);
793 drm_intel_bo_unreference(brw->wm.base.const_bo);
794
795 free(brw->curbe.last_buf);
796 free(brw->curbe.next_buf);
797
798 drm_intel_gem_context_destroy(brw->hw_ctx);
799
800 if (ctx->swrast_context) {
801 _swsetup_DestroyContext(&brw->ctx);
802 _tnl_DestroyContext(&brw->ctx);
803 }
804 _vbo_DestroyContext(&brw->ctx);
805
806 if (ctx->swrast_context)
807 _swrast_DestroyContext(&brw->ctx);
808
809 intel_batchbuffer_free(brw);
810
811 drm_intel_bo_unreference(brw->first_post_swapbuffers_batch);
812 brw->first_post_swapbuffers_batch = NULL;
813
814 driDestroyOptionCache(&brw->optionCache);
815
816 /* free the Mesa context */
817 _mesa_free_context_data(&brw->ctx);
818
819 ralloc_free(brw);
820 driContextPriv->driverPrivate = NULL;
821 }
822
823 GLboolean
824 intelUnbindContext(__DRIcontext * driContextPriv)
825 {
826 /* Unset current context and dispath table */
827 _mesa_make_current(NULL, NULL, NULL);
828
829 return true;
830 }
831
832 /**
833 * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior
834 * on window system framebuffers.
835 *
836 * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if
837 * your renderbuffer can do sRGB encode, and you can flip a switch that does
838 * sRGB encode if the renderbuffer can handle it. You can ask specifically
839 * for a visual where you're guaranteed to be capable, but it turns out that
840 * everyone just makes all their ARGB8888 visuals capable and doesn't offer
841 * incapable ones, becuase there's no difference between the two in resources
842 * used. Applications thus get built that accidentally rely on the default
843 * visual choice being sRGB, so we make ours sRGB capable. Everything sounds
844 * great...
845 *
846 * But for GLES2/3, they decided that it was silly to not turn on sRGB encode
847 * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent.
848 * So they removed the enable knob and made it "if the renderbuffer is sRGB
849 * capable, do sRGB encode". Then, for your window system renderbuffers, you
850 * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals
851 * and get no sRGB encode (assuming that both kinds of visual are available).
852 * Thus our choice to support sRGB by default on our visuals for desktop would
853 * result in broken rendering of GLES apps that aren't expecting sRGB encode.
854 *
855 * Unfortunately, renderbuffer setup happens before a context is created. So
856 * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3
857 * context (without an sRGB visual, though we don't have sRGB visuals exposed
858 * yet), we go turn that back off before anyone finds out.
859 */
860 static void
861 intel_gles3_srgb_workaround(struct brw_context *brw,
862 struct gl_framebuffer *fb)
863 {
864 struct gl_context *ctx = &brw->ctx;
865
866 if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable)
867 return;
868
869 /* Some day when we support the sRGB capable bit on visuals available for
870 * GLES, we'll need to respect that and not disable things here.
871 */
872 fb->Visual.sRGBCapable = false;
873 for (int i = 0; i < BUFFER_COUNT; i++) {
874 if (fb->Attachment[i].Renderbuffer &&
875 fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) {
876 fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888;
877 }
878 }
879 }
880
881 GLboolean
882 intelMakeCurrent(__DRIcontext * driContextPriv,
883 __DRIdrawable * driDrawPriv,
884 __DRIdrawable * driReadPriv)
885 {
886 struct brw_context *brw;
887 GET_CURRENT_CONTEXT(curCtx);
888
889 if (driContextPriv)
890 brw = (struct brw_context *) driContextPriv->driverPrivate;
891 else
892 brw = NULL;
893
894 /* According to the glXMakeCurrent() man page: "Pending commands to
895 * the previous context, if any, are flushed before it is released."
896 * But only flush if we're actually changing contexts.
897 */
898 if (brw_context(curCtx) && brw_context(curCtx) != brw) {
899 _mesa_flush(curCtx);
900 }
901
902 if (driContextPriv) {
903 struct gl_context *ctx = &brw->ctx;
904 struct gl_framebuffer *fb, *readFb;
905
906 if (driDrawPriv == NULL && driReadPriv == NULL) {
907 fb = _mesa_get_incomplete_framebuffer();
908 readFb = _mesa_get_incomplete_framebuffer();
909 } else {
910 fb = driDrawPriv->driverPrivate;
911 readFb = driReadPriv->driverPrivate;
912 driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
913 driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
914 }
915
916 /* The sRGB workaround changes the renderbuffer's format. We must change
917 * the format before the renderbuffer's miptree get's allocated, otherwise
918 * the formats of the renderbuffer and its miptree will differ.
919 */
920 intel_gles3_srgb_workaround(brw, fb);
921 intel_gles3_srgb_workaround(brw, readFb);
922
923 intel_prepare_render(brw);
924 _mesa_make_current(ctx, fb, readFb);
925 } else {
926 _mesa_make_current(NULL, NULL, NULL);
927 }
928
929 return true;
930 }
931
932 void
933 intel_resolve_for_dri2_flush(struct brw_context *brw,
934 __DRIdrawable *drawable)
935 {
936 if (brw->gen < 6) {
937 /* MSAA and fast color clear are not supported, so don't waste time
938 * checking whether a resolve is needed.
939 */
940 return;
941 }
942
943 struct gl_framebuffer *fb = drawable->driverPrivate;
944 struct intel_renderbuffer *rb;
945
946 /* Usually, only the back buffer will need to be downsampled. However,
947 * the front buffer will also need it if the user has rendered into it.
948 */
949 static const gl_buffer_index buffers[2] = {
950 BUFFER_BACK_LEFT,
951 BUFFER_FRONT_LEFT,
952 };
953
954 for (int i = 0; i < 2; ++i) {
955 rb = intel_get_renderbuffer(fb, buffers[i]);
956 if (rb == NULL || rb->mt == NULL)
957 continue;
958 if (rb->mt->num_samples <= 1)
959 intel_miptree_resolve_color(brw, rb->mt);
960 else
961 intel_miptree_downsample(brw, rb->mt);
962 }
963 }
964
965 static unsigned
966 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
967 {
968 return _mesa_get_format_bytes(intel_rb_format(rb)) * 8;
969 }
970
971 static void
972 intel_query_dri2_buffers(struct brw_context *brw,
973 __DRIdrawable *drawable,
974 __DRIbuffer **buffers,
975 int *count);
976
977 static void
978 intel_process_dri2_buffer(struct brw_context *brw,
979 __DRIdrawable *drawable,
980 __DRIbuffer *buffer,
981 struct intel_renderbuffer *rb,
982 const char *buffer_name);
983
984 static void
985 intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable);
986
987 static void
988 intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable)
989 {
990 struct gl_framebuffer *fb = drawable->driverPrivate;
991 struct intel_renderbuffer *rb;
992 __DRIbuffer *buffers = NULL;
993 int i, count;
994 const char *region_name;
995
996 /* Set this up front, so that in case our buffers get invalidated
997 * while we're getting new buffers, we don't clobber the stamp and
998 * thus ignore the invalidate. */
999 drawable->lastStamp = drawable->dri2.stamp;
1000
1001 if (unlikely(INTEL_DEBUG & DEBUG_DRI))
1002 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
1003
1004 intel_query_dri2_buffers(brw, drawable, &buffers, &count);
1005
1006 if (buffers == NULL)
1007 return;
1008
1009 for (i = 0; i < count; i++) {
1010 switch (buffers[i].attachment) {
1011 case __DRI_BUFFER_FRONT_LEFT:
1012 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1013 region_name = "dri2 front buffer";
1014 break;
1015
1016 case __DRI_BUFFER_FAKE_FRONT_LEFT:
1017 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1018 region_name = "dri2 fake front buffer";
1019 break;
1020
1021 case __DRI_BUFFER_BACK_LEFT:
1022 rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1023 region_name = "dri2 back buffer";
1024 break;
1025
1026 case __DRI_BUFFER_DEPTH:
1027 case __DRI_BUFFER_HIZ:
1028 case __DRI_BUFFER_DEPTH_STENCIL:
1029 case __DRI_BUFFER_STENCIL:
1030 case __DRI_BUFFER_ACCUM:
1031 default:
1032 fprintf(stderr,
1033 "unhandled buffer attach event, attachment type %d\n",
1034 buffers[i].attachment);
1035 return;
1036 }
1037
1038 intel_process_dri2_buffer(brw, drawable, &buffers[i], rb, region_name);
1039 }
1040
1041 }
1042
1043 void
1044 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
1045 {
1046 struct brw_context *brw = context->driverPrivate;
1047 __DRIscreen *screen = brw->intelScreen->driScrnPriv;
1048
1049 /* Set this up front, so that in case our buffers get invalidated
1050 * while we're getting new buffers, we don't clobber the stamp and
1051 * thus ignore the invalidate. */
1052 drawable->lastStamp = drawable->dri2.stamp;
1053
1054 if (unlikely(INTEL_DEBUG & DEBUG_DRI))
1055 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
1056
1057 if (screen->image.loader)
1058 intel_update_image_buffers(brw, drawable);
1059 else
1060 intel_update_dri2_buffers(brw, drawable);
1061
1062 driUpdateFramebufferSize(&brw->ctx, drawable);
1063 }
1064
1065 /**
1066 * intel_prepare_render should be called anywhere that curent read/drawbuffer
1067 * state is required.
1068 */
1069 void
1070 intel_prepare_render(struct brw_context *brw)
1071 {
1072 __DRIcontext *driContext = brw->driContext;
1073 __DRIdrawable *drawable;
1074
1075 drawable = driContext->driDrawablePriv;
1076 if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
1077 if (drawable->lastStamp != drawable->dri2.stamp)
1078 intel_update_renderbuffers(driContext, drawable);
1079 driContext->dri2.draw_stamp = drawable->dri2.stamp;
1080 }
1081
1082 drawable = driContext->driReadablePriv;
1083 if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) {
1084 if (drawable->lastStamp != drawable->dri2.stamp)
1085 intel_update_renderbuffers(driContext, drawable);
1086 driContext->dri2.read_stamp = drawable->dri2.stamp;
1087 }
1088
1089 /* If we're currently rendering to the front buffer, the rendering
1090 * that will happen next will probably dirty the front buffer. So
1091 * mark it as dirty here.
1092 */
1093 if (brw->is_front_buffer_rendering)
1094 brw->front_buffer_dirty = true;
1095
1096 /* Wait for the swapbuffers before the one we just emitted, so we
1097 * don't get too many swaps outstanding for apps that are GPU-heavy
1098 * but not CPU-heavy.
1099 *
1100 * We're using intelDRI2Flush (called from the loader before
1101 * swapbuffer) and glFlush (for front buffer rendering) as the
1102 * indicator that a frame is done and then throttle when we get
1103 * here as we prepare to render the next frame. At this point for
1104 * round trips for swap/copy and getting new buffers are done and
1105 * we'll spend less time waiting on the GPU.
1106 *
1107 * Unfortunately, we don't have a handle to the batch containing
1108 * the swap, and getting our hands on that doesn't seem worth it,
1109 * so we just us the first batch we emitted after the last swap.
1110 */
1111 if (brw->need_throttle && brw->first_post_swapbuffers_batch) {
1112 if (!brw->disable_throttling)
1113 drm_intel_bo_wait_rendering(brw->first_post_swapbuffers_batch);
1114 drm_intel_bo_unreference(brw->first_post_swapbuffers_batch);
1115 brw->first_post_swapbuffers_batch = NULL;
1116 brw->need_throttle = false;
1117 }
1118 }
1119
1120 /**
1121 * \brief Query DRI2 to obtain a DRIdrawable's buffers.
1122 *
1123 * To determine which DRI buffers to request, examine the renderbuffers
1124 * attached to the drawable's framebuffer. Then request the buffers with
1125 * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
1126 *
1127 * This is called from intel_update_renderbuffers().
1128 *
1129 * \param drawable Drawable whose buffers are queried.
1130 * \param buffers [out] List of buffers returned by DRI2 query.
1131 * \param buffer_count [out] Number of buffers returned.
1132 *
1133 * \see intel_update_renderbuffers()
1134 * \see DRI2GetBuffers()
1135 * \see DRI2GetBuffersWithFormat()
1136 */
1137 static void
1138 intel_query_dri2_buffers(struct brw_context *brw,
1139 __DRIdrawable *drawable,
1140 __DRIbuffer **buffers,
1141 int *buffer_count)
1142 {
1143 __DRIscreen *screen = brw->intelScreen->driScrnPriv;
1144 struct gl_framebuffer *fb = drawable->driverPrivate;
1145 int i = 0;
1146 unsigned attachments[8];
1147
1148 struct intel_renderbuffer *front_rb;
1149 struct intel_renderbuffer *back_rb;
1150
1151 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1152 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1153
1154 memset(attachments, 0, sizeof(attachments));
1155 if ((brw->is_front_buffer_rendering ||
1156 brw->is_front_buffer_reading ||
1157 !back_rb) && front_rb) {
1158 /* If a fake front buffer is in use, then querying for
1159 * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
1160 * the real front buffer to the fake front buffer. So before doing the
1161 * query, we need to make sure all the pending drawing has landed in the
1162 * real front buffer.
1163 */
1164 intel_batchbuffer_flush(brw);
1165 intel_flush_front(&brw->ctx);
1166
1167 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
1168 attachments[i++] = intel_bits_per_pixel(front_rb);
1169 } else if (front_rb && brw->front_buffer_dirty) {
1170 /* We have pending front buffer rendering, but we aren't querying for a
1171 * front buffer. If the front buffer we have is a fake front buffer,
1172 * the X server is going to throw it away when it processes the query.
1173 * So before doing the query, make sure all the pending drawing has
1174 * landed in the real front buffer.
1175 */
1176 intel_batchbuffer_flush(brw);
1177 intel_flush_front(&brw->ctx);
1178 }
1179
1180 if (back_rb) {
1181 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
1182 attachments[i++] = intel_bits_per_pixel(back_rb);
1183 }
1184
1185 assert(i <= ARRAY_SIZE(attachments));
1186
1187 *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
1188 &drawable->w,
1189 &drawable->h,
1190 attachments, i / 2,
1191 buffer_count,
1192 drawable->loaderPrivate);
1193 }
1194
1195 /**
1196 * \brief Assign a DRI buffer's DRM region to a renderbuffer.
1197 *
1198 * This is called from intel_update_renderbuffers().
1199 *
1200 * \par Note:
1201 * DRI buffers whose attachment point is DRI2BufferStencil or
1202 * DRI2BufferDepthStencil are handled as special cases.
1203 *
1204 * \param buffer_name is a human readable name, such as "dri2 front buffer",
1205 * that is passed to intel_region_alloc_for_handle().
1206 *
1207 * \see intel_update_renderbuffers()
1208 * \see intel_region_alloc_for_handle()
1209 */
1210 static void
1211 intel_process_dri2_buffer(struct brw_context *brw,
1212 __DRIdrawable *drawable,
1213 __DRIbuffer *buffer,
1214 struct intel_renderbuffer *rb,
1215 const char *buffer_name)
1216 {
1217 struct intel_region *region = NULL;
1218
1219 if (!rb)
1220 return;
1221
1222 unsigned num_samples = rb->Base.Base.NumSamples;
1223
1224 /* We try to avoid closing and reopening the same BO name, because the first
1225 * use of a mapping of the buffer involves a bunch of page faulting which is
1226 * moderately expensive.
1227 */
1228 if (num_samples == 0) {
1229 if (rb->mt &&
1230 rb->mt->region &&
1231 rb->mt->region->name == buffer->name)
1232 return;
1233 } else {
1234 if (rb->mt &&
1235 rb->mt->singlesample_mt &&
1236 rb->mt->singlesample_mt->region &&
1237 rb->mt->singlesample_mt->region->name == buffer->name)
1238 return;
1239 }
1240
1241 if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
1242 fprintf(stderr,
1243 "attaching buffer %d, at %d, cpp %d, pitch %d\n",
1244 buffer->name, buffer->attachment,
1245 buffer->cpp, buffer->pitch);
1246 }
1247
1248 intel_miptree_release(&rb->mt);
1249 region = intel_region_alloc_for_handle(brw->intelScreen,
1250 buffer->cpp,
1251 drawable->w,
1252 drawable->h,
1253 buffer->pitch,
1254 buffer->name,
1255 buffer_name);
1256 if (!region)
1257 return;
1258
1259 rb->mt = intel_miptree_create_for_dri2_buffer(brw,
1260 buffer->attachment,
1261 intel_rb_format(rb),
1262 num_samples,
1263 region);
1264 intel_region_release(&region);
1265 }
1266
1267 /**
1268 * \brief Query DRI image loader to obtain a DRIdrawable's buffers.
1269 *
1270 * To determine which DRI buffers to request, examine the renderbuffers
1271 * attached to the drawable's framebuffer. Then request the buffers from
1272 * the image loader
1273 *
1274 * This is called from intel_update_renderbuffers().
1275 *
1276 * \param drawable Drawable whose buffers are queried.
1277 * \param buffers [out] List of buffers returned by DRI2 query.
1278 * \param buffer_count [out] Number of buffers returned.
1279 *
1280 * \see intel_update_renderbuffers()
1281 */
1282
1283 static void
1284 intel_update_image_buffer(struct brw_context *intel,
1285 __DRIdrawable *drawable,
1286 struct intel_renderbuffer *rb,
1287 __DRIimage *buffer,
1288 enum __DRIimageBufferMask buffer_type)
1289 {
1290 struct intel_region *region = buffer->region;
1291
1292 if (!rb || !region)
1293 return;
1294
1295 unsigned num_samples = rb->Base.Base.NumSamples;
1296
1297 if (rb->mt &&
1298 rb->mt->region &&
1299 rb->mt->region == region)
1300 return;
1301
1302 intel_miptree_release(&rb->mt);
1303 rb->mt = intel_miptree_create_for_image_buffer(intel,
1304 buffer_type,
1305 intel_rb_format(rb),
1306 num_samples,
1307 region);
1308 }
1309
1310 static void
1311 intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
1312 {
1313 struct gl_framebuffer *fb = drawable->driverPrivate;
1314 __DRIscreen *screen = brw->intelScreen->driScrnPriv;
1315 struct intel_renderbuffer *front_rb;
1316 struct intel_renderbuffer *back_rb;
1317 struct __DRIimageList images;
1318 unsigned int format;
1319 uint32_t buffer_mask = 0;
1320
1321 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1322 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1323
1324 if (back_rb)
1325 format = intel_rb_format(back_rb);
1326 else if (front_rb)
1327 format = intel_rb_format(front_rb);
1328 else
1329 return;
1330
1331 if ((brw->is_front_buffer_rendering || brw->is_front_buffer_reading || !back_rb) && front_rb)
1332 buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
1333
1334 if (back_rb)
1335 buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
1336
1337 (*screen->image.loader->getBuffers) (drawable,
1338 driGLFormatToImageFormat(format),
1339 &drawable->dri2.stamp,
1340 drawable->loaderPrivate,
1341 buffer_mask,
1342 &images);
1343
1344 if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
1345 drawable->w = images.front->width;
1346 drawable->h = images.front->height;
1347 intel_update_image_buffer(brw,
1348 drawable,
1349 front_rb,
1350 images.front,
1351 __DRI_IMAGE_BUFFER_FRONT);
1352 }
1353 if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
1354 drawable->w = images.back->width;
1355 drawable->h = images.back->height;
1356 intel_update_image_buffer(brw,
1357 drawable,
1358 back_rb,
1359 images.back,
1360 __DRI_IMAGE_BUFFER_BACK);
1361 }
1362 }