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