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