i965: Don't request GLSL IR lowering of gl_VertexID
[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 "compiler/nir/nir.h"
35 #include "main/api_exec.h"
36 #include "main/context.h"
37 #include "main/fbobject.h"
38 #include "main/extensions.h"
39 #include "main/imports.h"
40 #include "main/macros.h"
41 #include "main/points.h"
42 #include "main/version.h"
43 #include "main/vtxfmt.h"
44 #include "main/texobj.h"
45 #include "main/framebuffer.h"
46 #include "main/stencil.h"
47 #include "main/state.h"
48
49 #include "vbo/vbo.h"
50
51 #include "drivers/common/driverfuncs.h"
52 #include "drivers/common/meta.h"
53 #include "utils.h"
54
55 #include "brw_context.h"
56 #include "brw_defines.h"
57 #include "brw_blorp.h"
58 #include "brw_draw.h"
59 #include "brw_state.h"
60
61 #include "intel_batchbuffer.h"
62 #include "intel_buffer_objects.h"
63 #include "intel_buffers.h"
64 #include "intel_fbo.h"
65 #include "intel_mipmap_tree.h"
66 #include "intel_pixel.h"
67 #include "intel_image.h"
68 #include "intel_tex.h"
69 #include "intel_tex_obj.h"
70
71 #include "swrast_setup/swrast_setup.h"
72 #include "tnl/tnl.h"
73 #include "tnl/t_pipeline.h"
74 #include "util/ralloc.h"
75 #include "util/debug.h"
76 #include "util/disk_cache.h"
77 #include "isl/isl.h"
78
79 #include "common/gen_defines.h"
80
81 /***************************************
82 * Mesa's Driver Functions
83 ***************************************/
84
85 const char *const brw_vendor_string = "Intel Open Source Technology Center";
86
87 static const char *
88 get_bsw_model(const struct intel_screen *screen)
89 {
90 switch (screen->eu_total) {
91 case 16:
92 return "405";
93 case 12:
94 return "400";
95 default:
96 return " ";
97 }
98 }
99
100 const char *
101 brw_get_renderer_string(const struct intel_screen *screen)
102 {
103 const char *chipset;
104 static char buffer[128];
105 char *bsw = NULL;
106
107 switch (screen->deviceID) {
108 #undef CHIPSET
109 #define CHIPSET(id, symbol, str) case id: chipset = str; break;
110 #include "pci_ids/i965_pci_ids.h"
111 default:
112 chipset = "Unknown Intel Chipset";
113 break;
114 }
115
116 /* Braswell branding is funny, so we have to fix it up here */
117 if (screen->deviceID == 0x22B1) {
118 bsw = strdup(chipset);
119 char *needle = strstr(bsw, "XXX");
120 if (needle) {
121 memcpy(needle, get_bsw_model(screen), 3);
122 chipset = bsw;
123 }
124 }
125
126 (void) driGetRendererString(buffer, chipset, 0);
127 free(bsw);
128 return buffer;
129 }
130
131 static const GLubyte *
132 intel_get_string(struct gl_context * ctx, GLenum name)
133 {
134 const struct brw_context *const brw = brw_context(ctx);
135
136 switch (name) {
137 case GL_VENDOR:
138 return (GLubyte *) brw_vendor_string;
139
140 case GL_RENDERER:
141 return
142 (GLubyte *) brw_get_renderer_string(brw->screen);
143
144 default:
145 return NULL;
146 }
147 }
148
149 static void
150 intel_viewport(struct gl_context *ctx)
151 {
152 struct brw_context *brw = brw_context(ctx);
153 __DRIcontext *driContext = brw->driContext;
154
155 if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
156 if (driContext->driDrawablePriv)
157 dri2InvalidateDrawable(driContext->driDrawablePriv);
158 if (driContext->driReadablePriv)
159 dri2InvalidateDrawable(driContext->driReadablePriv);
160 }
161 }
162
163 static void
164 intel_update_framebuffer(struct gl_context *ctx,
165 struct gl_framebuffer *fb)
166 {
167 struct brw_context *brw = brw_context(ctx);
168
169 /* Quantize the derived default number of samples
170 */
171 fb->DefaultGeometry._NumSamples =
172 intel_quantize_num_samples(brw->screen,
173 fb->DefaultGeometry.NumSamples);
174 }
175
176 static void
177 intel_update_state(struct gl_context * ctx)
178 {
179 GLuint new_state = ctx->NewState;
180 struct brw_context *brw = brw_context(ctx);
181
182 if (ctx->swrast_context)
183 _swrast_InvalidateState(ctx, new_state);
184
185 brw->NewGLState |= new_state;
186
187 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
188 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
189
190 if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) {
191 brw->stencil_enabled = _mesa_stencil_is_enabled(ctx);
192 brw->stencil_two_sided = _mesa_stencil_is_two_sided(ctx);
193 brw->stencil_write_enabled =
194 _mesa_stencil_is_write_enabled(ctx, brw->stencil_two_sided);
195 }
196
197 if (new_state & _NEW_POLYGON)
198 brw->polygon_front_bit = _mesa_polygon_get_front_bit(ctx);
199
200 if (new_state & _NEW_BUFFERS) {
201 intel_update_framebuffer(ctx, ctx->DrawBuffer);
202 if (ctx->DrawBuffer != ctx->ReadBuffer)
203 intel_update_framebuffer(ctx, ctx->ReadBuffer);
204 }
205 }
206
207 #define flushFront(screen) ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer)
208
209 static void
210 intel_flush_front(struct gl_context *ctx)
211 {
212 struct brw_context *brw = brw_context(ctx);
213 __DRIcontext *driContext = brw->driContext;
214 __DRIdrawable *driDrawable = driContext->driDrawablePriv;
215 __DRIscreen *const dri_screen = brw->screen->driScrnPriv;
216
217 if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
218 if (flushFront(dri_screen) && driDrawable &&
219 driDrawable->loaderPrivate) {
220
221 /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
222 *
223 * This potentially resolves both front and back buffer. It
224 * is unnecessary to resolve the back, but harms nothing except
225 * performance. And no one cares about front-buffer render
226 * performance.
227 */
228 intel_resolve_for_dri2_flush(brw, driDrawable);
229 intel_batchbuffer_flush(brw);
230
231 flushFront(dri_screen)(driDrawable, driDrawable->loaderPrivate);
232
233 /* We set the dirty bit in intel_prepare_render() if we're
234 * front buffer rendering once we get there.
235 */
236 brw->front_buffer_dirty = false;
237 }
238 }
239 }
240
241 static void
242 intel_glFlush(struct gl_context *ctx)
243 {
244 struct brw_context *brw = brw_context(ctx);
245
246 intel_batchbuffer_flush(brw);
247 intel_flush_front(ctx);
248
249 brw->need_flush_throttle = true;
250 }
251
252 static void
253 intel_finish(struct gl_context * ctx)
254 {
255 struct brw_context *brw = brw_context(ctx);
256
257 intel_glFlush(ctx);
258
259 if (brw->batch.last_bo)
260 brw_bo_wait_rendering(brw->batch.last_bo);
261 }
262
263 static void
264 brw_init_driver_functions(struct brw_context *brw,
265 struct dd_function_table *functions)
266 {
267 const struct gen_device_info *devinfo = &brw->screen->devinfo;
268
269 _mesa_init_driver_functions(functions);
270
271 /* GLX uses DRI2 invalidate events to handle window resizing.
272 * Unfortunately, EGL does not - libEGL is written in XCB (not Xlib),
273 * which doesn't provide a mechanism for snooping the event queues.
274 *
275 * So EGL still relies on viewport hacks to handle window resizing.
276 * This should go away with DRI3000.
277 */
278 if (!brw->driContext->driScreenPriv->dri2.useInvalidate)
279 functions->Viewport = intel_viewport;
280
281 functions->Flush = intel_glFlush;
282 functions->Finish = intel_finish;
283 functions->GetString = intel_get_string;
284 functions->UpdateState = intel_update_state;
285
286 intelInitTextureFuncs(functions);
287 intelInitTextureImageFuncs(functions);
288 intelInitTextureCopyImageFuncs(functions);
289 intelInitCopyImageFuncs(functions);
290 intelInitClearFuncs(functions);
291 intelInitBufferFuncs(functions);
292 intelInitPixelFuncs(functions);
293 intelInitBufferObjectFuncs(functions);
294 brw_init_syncobj_functions(functions);
295 brw_init_object_purgeable_functions(functions);
296
297 brwInitFragProgFuncs( functions );
298 brw_init_common_queryobj_functions(functions);
299 if (devinfo->gen >= 8 || devinfo->is_haswell)
300 hsw_init_queryobj_functions(functions);
301 else if (devinfo->gen >= 6)
302 gen6_init_queryobj_functions(functions);
303 else
304 gen4_init_queryobj_functions(functions);
305 brw_init_compute_functions(functions);
306 brw_init_conditional_render_functions(functions);
307
308 functions->GenerateMipmap = brw_generate_mipmap;
309
310 functions->QueryInternalFormat = brw_query_internal_format;
311
312 functions->NewTransformFeedback = brw_new_transform_feedback;
313 functions->DeleteTransformFeedback = brw_delete_transform_feedback;
314 if (can_do_mi_math_and_lrr(brw->screen)) {
315 functions->BeginTransformFeedback = hsw_begin_transform_feedback;
316 functions->EndTransformFeedback = hsw_end_transform_feedback;
317 functions->PauseTransformFeedback = hsw_pause_transform_feedback;
318 functions->ResumeTransformFeedback = hsw_resume_transform_feedback;
319 } else if (devinfo->gen >= 7) {
320 functions->BeginTransformFeedback = gen7_begin_transform_feedback;
321 functions->EndTransformFeedback = gen7_end_transform_feedback;
322 functions->PauseTransformFeedback = gen7_pause_transform_feedback;
323 functions->ResumeTransformFeedback = gen7_resume_transform_feedback;
324 functions->GetTransformFeedbackVertexCount =
325 brw_get_transform_feedback_vertex_count;
326 } else {
327 functions->BeginTransformFeedback = brw_begin_transform_feedback;
328 functions->EndTransformFeedback = brw_end_transform_feedback;
329 functions->PauseTransformFeedback = brw_pause_transform_feedback;
330 functions->ResumeTransformFeedback = brw_resume_transform_feedback;
331 functions->GetTransformFeedbackVertexCount =
332 brw_get_transform_feedback_vertex_count;
333 }
334
335 if (devinfo->gen >= 6)
336 functions->GetSamplePosition = gen6_get_sample_position;
337
338 /* GL_ARB_get_program_binary */
339 brw_program_binary_init(brw->screen->deviceID);
340 functions->GetProgramBinaryDriverSHA1 = brw_get_program_binary_driver_sha1;
341 functions->ProgramBinarySerializeDriverBlob = brw_program_serialize_nir;
342 functions->ProgramBinaryDeserializeDriverBlob =
343 brw_deserialize_program_binary;
344 }
345
346 static void
347 brw_initialize_context_constants(struct brw_context *brw)
348 {
349 const struct gen_device_info *devinfo = &brw->screen->devinfo;
350 struct gl_context *ctx = &brw->ctx;
351 const struct brw_compiler *compiler = brw->screen->compiler;
352
353 const bool stage_exists[MESA_SHADER_STAGES] = {
354 [MESA_SHADER_VERTEX] = true,
355 [MESA_SHADER_TESS_CTRL] = devinfo->gen >= 7,
356 [MESA_SHADER_TESS_EVAL] = devinfo->gen >= 7,
357 [MESA_SHADER_GEOMETRY] = devinfo->gen >= 6,
358 [MESA_SHADER_FRAGMENT] = true,
359 [MESA_SHADER_COMPUTE] =
360 (_mesa_is_desktop_gl(ctx) &&
361 ctx->Const.MaxComputeWorkGroupSize[0] >= 1024) ||
362 (ctx->API == API_OPENGLES2 &&
363 ctx->Const.MaxComputeWorkGroupSize[0] >= 128),
364 };
365
366 unsigned num_stages = 0;
367 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
368 if (stage_exists[i])
369 num_stages++;
370 }
371
372 unsigned max_samplers =
373 devinfo->gen >= 8 || devinfo->is_haswell ? BRW_MAX_TEX_UNIT : 16;
374
375 ctx->Const.MaxDualSourceDrawBuffers = 1;
376 ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
377 ctx->Const.MaxCombinedShaderOutputResources =
378 MAX_IMAGE_UNITS + BRW_MAX_DRAW_BUFFERS;
379
380 /* The timestamp register we can read for glGetTimestamp() is
381 * sometimes only 32 bits, before scaling to nanoseconds (depending
382 * on kernel).
383 *
384 * Once scaled to nanoseconds the timestamp would roll over at a
385 * non-power-of-two, so an application couldn't use
386 * GL_QUERY_COUNTER_BITS to handle rollover correctly. Instead, we
387 * report 36 bits and truncate at that (rolling over 5 times as
388 * often as the HW counter), and when the 32-bit counter rolls
389 * over, it happens to also be at a rollover in the reported value
390 * from near (1<<36) to 0.
391 *
392 * The low 32 bits rolls over in ~343 seconds. Our 36-bit result
393 * rolls over every ~69 seconds.
394 */
395 ctx->Const.QueryCounterBits.Timestamp = 36;
396
397 ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
398 ctx->Const.MaxImageUnits = MAX_IMAGE_UNITS;
399 if (devinfo->gen >= 7) {
400 ctx->Const.MaxRenderbufferSize = 16384;
401 ctx->Const.MaxTextureLevels = MIN2(15 /* 16384 */, MAX_TEXTURE_LEVELS);
402 ctx->Const.MaxCubeTextureLevels = 15; /* 16384 */
403 } else {
404 ctx->Const.MaxRenderbufferSize = 8192;
405 ctx->Const.MaxTextureLevels = MIN2(14 /* 8192 */, MAX_TEXTURE_LEVELS);
406 ctx->Const.MaxCubeTextureLevels = 14; /* 8192 */
407 }
408 ctx->Const.Max3DTextureLevels = 12; /* 2048 */
409 ctx->Const.MaxArrayTextureLayers = devinfo->gen >= 7 ? 2048 : 512;
410 ctx->Const.MaxTextureMbytes = 1536;
411 ctx->Const.MaxTextureRectSize = devinfo->gen >= 7 ? 16384 : 8192;
412 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
413 ctx->Const.MaxTextureLodBias = 15.0;
414 ctx->Const.StripTextureBorder = true;
415 if (devinfo->gen >= 7) {
416 ctx->Const.MaxProgramTextureGatherComponents = 4;
417 ctx->Const.MinProgramTextureGatherOffset = -32;
418 ctx->Const.MaxProgramTextureGatherOffset = 31;
419 } else if (devinfo->gen == 6) {
420 ctx->Const.MaxProgramTextureGatherComponents = 1;
421 ctx->Const.MinProgramTextureGatherOffset = -8;
422 ctx->Const.MaxProgramTextureGatherOffset = 7;
423 }
424
425 ctx->Const.MaxUniformBlockSize = 65536;
426
427 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
428 struct gl_program_constants *prog = &ctx->Const.Program[i];
429
430 if (!stage_exists[i])
431 continue;
432
433 prog->MaxTextureImageUnits = max_samplers;
434
435 prog->MaxUniformBlocks = BRW_MAX_UBO;
436 prog->MaxCombinedUniformComponents =
437 prog->MaxUniformComponents +
438 ctx->Const.MaxUniformBlockSize / 4 * prog->MaxUniformBlocks;
439
440 prog->MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
441 prog->MaxAtomicBuffers = BRW_MAX_ABO;
442 prog->MaxImageUniforms = compiler->scalar_stage[i] ? BRW_MAX_IMAGES : 0;
443 prog->MaxShaderStorageBlocks = BRW_MAX_SSBO;
444 }
445
446 ctx->Const.MaxTextureUnits =
447 MIN2(ctx->Const.MaxTextureCoordUnits,
448 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
449
450 ctx->Const.MaxUniformBufferBindings = num_stages * BRW_MAX_UBO;
451 ctx->Const.MaxCombinedUniformBlocks = num_stages * BRW_MAX_UBO;
452 ctx->Const.MaxCombinedAtomicBuffers = num_stages * BRW_MAX_ABO;
453 ctx->Const.MaxCombinedShaderStorageBlocks = num_stages * BRW_MAX_SSBO;
454 ctx->Const.MaxShaderStorageBufferBindings = num_stages * BRW_MAX_SSBO;
455 ctx->Const.MaxCombinedTextureImageUnits = num_stages * max_samplers;
456 ctx->Const.MaxCombinedImageUniforms = num_stages * BRW_MAX_IMAGES;
457
458
459 /* Hardware only supports a limited number of transform feedback buffers.
460 * So we need to override the Mesa default (which is based only on software
461 * limits).
462 */
463 ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;
464
465 /* On Gen6, in the worst case, we use up one binding table entry per
466 * transform feedback component (see comments above the definition of
467 * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
468 * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
469 * BRW_MAX_SOL_BINDINGS.
470 *
471 * In "separate components" mode, we need to divide this value by
472 * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
473 * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
474 */
475 ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
476 ctx->Const.MaxTransformFeedbackSeparateComponents =
477 BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
478
479 ctx->Const.AlwaysUseGetTransformFeedbackVertexCount =
480 !can_do_mi_math_and_lrr(brw->screen);
481
482 int max_samples;
483 const int *msaa_modes = intel_supported_msaa_modes(brw->screen);
484 const int clamp_max_samples =
485 driQueryOptioni(&brw->optionCache, "clamp_max_samples");
486
487 if (clamp_max_samples < 0) {
488 max_samples = msaa_modes[0];
489 } else {
490 /* Select the largest supported MSAA mode that does not exceed
491 * clamp_max_samples.
492 */
493 max_samples = 0;
494 for (int i = 0; msaa_modes[i] != 0; ++i) {
495 if (msaa_modes[i] <= clamp_max_samples) {
496 max_samples = msaa_modes[i];
497 break;
498 }
499 }
500 }
501
502 ctx->Const.MaxSamples = max_samples;
503 ctx->Const.MaxColorTextureSamples = max_samples;
504 ctx->Const.MaxDepthTextureSamples = max_samples;
505 ctx->Const.MaxIntegerSamples = max_samples;
506 ctx->Const.MaxImageSamples = 0;
507
508 /* gen6_set_sample_maps() sets SampleMap{2,4,8}x variables which are used
509 * to map indices of rectangular grid to sample numbers within a pixel.
510 * These variables are used by GL_EXT_framebuffer_multisample_blit_scaled
511 * extension implementation. For more details see the comment above
512 * gen6_set_sample_maps() definition.
513 */
514 gen6_set_sample_maps(ctx);
515
516 ctx->Const.MinLineWidth = 1.0;
517 ctx->Const.MinLineWidthAA = 1.0;
518 if (devinfo->gen >= 6) {
519 ctx->Const.MaxLineWidth = 7.375;
520 ctx->Const.MaxLineWidthAA = 7.375;
521 ctx->Const.LineWidthGranularity = 0.125;
522 } else {
523 ctx->Const.MaxLineWidth = 7.0;
524 ctx->Const.MaxLineWidthAA = 7.0;
525 ctx->Const.LineWidthGranularity = 0.5;
526 }
527
528 /* For non-antialiased lines, we have to round the line width to the
529 * nearest whole number. Make sure that we don't advertise a line
530 * width that, when rounded, will be beyond the actual hardware
531 * maximum.
532 */
533 assert(roundf(ctx->Const.MaxLineWidth) <= ctx->Const.MaxLineWidth);
534
535 ctx->Const.MinPointSize = 1.0;
536 ctx->Const.MinPointSizeAA = 1.0;
537 ctx->Const.MaxPointSize = 255.0;
538 ctx->Const.MaxPointSizeAA = 255.0;
539 ctx->Const.PointSizeGranularity = 1.0;
540
541 if (devinfo->gen >= 5 || devinfo->is_g4x)
542 ctx->Const.MaxClipPlanes = 8;
543
544 ctx->Const.GLSLTessLevelsAsInputs = true;
545 ctx->Const.PrimitiveRestartForPatches = true;
546
547 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeInstructions = 16 * 1024;
548 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAluInstructions = 0;
549 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexInstructions = 0;
550 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexIndirections = 0;
551 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAluInstructions = 0;
552 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexInstructions = 0;
553 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexIndirections = 0;
554 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAttribs = 16;
555 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTemps = 256;
556 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAddressRegs = 1;
557 ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters = 1024;
558 ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams =
559 MIN2(ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters,
560 ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams);
561
562 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeInstructions = 1024;
563 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAluInstructions = 1024;
564 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexInstructions = 1024;
565 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexIndirections = 1024;
566 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAttribs = 12;
567 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTemps = 256;
568 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAddressRegs = 0;
569 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters = 1024;
570 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams =
571 MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters,
572 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams);
573
574 /* Fragment shaders use real, 32-bit twos-complement integers for all
575 * integer types.
576 */
577 ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMin = 31;
578 ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMax = 30;
579 ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.Precision = 0;
580 ctx->Const.Program[MESA_SHADER_FRAGMENT].HighInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
581 ctx->Const.Program[MESA_SHADER_FRAGMENT].MediumInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
582
583 ctx->Const.Program[MESA_SHADER_VERTEX].LowInt.RangeMin = 31;
584 ctx->Const.Program[MESA_SHADER_VERTEX].LowInt.RangeMax = 30;
585 ctx->Const.Program[MESA_SHADER_VERTEX].LowInt.Precision = 0;
586 ctx->Const.Program[MESA_SHADER_VERTEX].HighInt = ctx->Const.Program[MESA_SHADER_VERTEX].LowInt;
587 ctx->Const.Program[MESA_SHADER_VERTEX].MediumInt = ctx->Const.Program[MESA_SHADER_VERTEX].LowInt;
588
589 /* Gen6 converts quads to polygon in beginning of 3D pipeline,
590 * but we're not sure how it's actually done for vertex order,
591 * that affect provoking vertex decision. Always use last vertex
592 * convention for quad primitive which works as expected for now.
593 */
594 if (devinfo->gen >= 6)
595 ctx->Const.QuadsFollowProvokingVertexConvention = false;
596
597 ctx->Const.NativeIntegers = true;
598
599 /* Regarding the CMP instruction, the Ivybridge PRM says:
600 *
601 * "For each enabled channel 0b or 1b is assigned to the appropriate flag
602 * bit and 0/all zeros or all ones (e.g, byte 0xFF, word 0xFFFF, DWord
603 * 0xFFFFFFFF) is assigned to dst."
604 *
605 * but PRMs for earlier generations say
606 *
607 * "In dword format, one GRF may store up to 8 results. When the register
608 * is used later as a vector of Booleans, as only LSB at each channel
609 * contains meaning [sic] data, software should make sure all higher bits
610 * are masked out (e.g. by 'and-ing' an [sic] 0x01 constant)."
611 *
612 * We select the representation of a true boolean uniform to be ~0, and fix
613 * the results of Gen <= 5 CMP instruction's with -(result & 1).
614 */
615 ctx->Const.UniformBooleanTrue = ~0;
616
617 /* From the gen4 PRM, volume 4 page 127:
618 *
619 * "For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
620 * the base address of the first element of the surface, computed in
621 * software by adding the surface base address to the byte offset of
622 * the element in the buffer."
623 *
624 * However, unaligned accesses are slower, so enforce buffer alignment.
625 *
626 * In order to push UBO data, 3DSTATE_CONSTANT_XS imposes an additional
627 * restriction: the start of the buffer needs to be 32B aligned.
628 */
629 ctx->Const.UniformBufferOffsetAlignment = 32;
630
631 /* ShaderStorageBufferOffsetAlignment should be a cacheline (64 bytes) so
632 * that we can safely have the CPU and GPU writing the same SSBO on
633 * non-cachecoherent systems (our Atom CPUs). With UBOs, the GPU never
634 * writes, so there's no problem. For an SSBO, the GPU and the CPU can
635 * be updating disjoint regions of the buffer simultaneously and that will
636 * break if the regions overlap the same cacheline.
637 */
638 ctx->Const.ShaderStorageBufferOffsetAlignment = 64;
639 ctx->Const.TextureBufferOffsetAlignment = 16;
640 ctx->Const.MaxTextureBufferSize = 128 * 1024 * 1024;
641
642 if (devinfo->gen >= 6) {
643 ctx->Const.MaxVarying = 32;
644 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 128;
645 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents =
646 compiler->scalar_stage[MESA_SHADER_GEOMETRY] ? 128 : 64;
647 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
648 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 128;
649 ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxInputComponents = 128;
650 ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxOutputComponents = 128;
651 ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxInputComponents = 128;
652 ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxOutputComponents = 128;
653 }
654
655 /* We want the GLSL compiler to emit code that uses condition codes */
656 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
657 ctx->Const.ShaderCompilerOptions[i] =
658 brw->screen->compiler->glsl_compiler_options[i];
659 }
660
661 if (devinfo->gen >= 7) {
662 ctx->Const.MaxViewportWidth = 32768;
663 ctx->Const.MaxViewportHeight = 32768;
664 }
665
666 /* ARB_viewport_array, OES_viewport_array */
667 if (devinfo->gen >= 6) {
668 ctx->Const.MaxViewports = GEN6_NUM_VIEWPORTS;
669 ctx->Const.ViewportSubpixelBits = 0;
670
671 /* Cast to float before negating because MaxViewportWidth is unsigned.
672 */
673 ctx->Const.ViewportBounds.Min = -(float)ctx->Const.MaxViewportWidth;
674 ctx->Const.ViewportBounds.Max = ctx->Const.MaxViewportWidth;
675 }
676
677 /* ARB_gpu_shader5 */
678 if (devinfo->gen >= 7)
679 ctx->Const.MaxVertexStreams = MIN2(4, MAX_VERTEX_STREAMS);
680
681 /* ARB_framebuffer_no_attachments */
682 ctx->Const.MaxFramebufferWidth = 16384;
683 ctx->Const.MaxFramebufferHeight = 16384;
684 ctx->Const.MaxFramebufferLayers = ctx->Const.MaxArrayTextureLayers;
685 ctx->Const.MaxFramebufferSamples = max_samples;
686
687 /* OES_primitive_bounding_box */
688 ctx->Const.NoPrimitiveBoundingBoxOutput = true;
689
690 /* TODO: We should be able to use STD430 packing by default on all hardware
691 * but some piglit tests [1] currently fail on SNB when this is enabled.
692 * The problem is the messages we're using for doing uniform pulls
693 * in the vec4 back-end on SNB is the OWORD block load instruction, which
694 * takes its offset in units of OWORDS (16 bytes). On IVB+, we use the
695 * sampler which doesn't have these restrictions.
696 *
697 * In the scalar back-end, we use the sampler for dynamic uniform loads and
698 * pull an entire cache line at a time for constant offset loads both of
699 * which support almost any alignment.
700 *
701 * [1] glsl-1.40/uniform_buffer/vs-float-array-variable-index.shader_test
702 */
703 if (devinfo->gen >= 7)
704 ctx->Const.UseSTD430AsDefaultPacking = true;
705
706 if (!(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT))
707 ctx->Const.AllowMappedBuffersDuringExecution = true;
708
709 /* GL_ARB_get_program_binary */
710 ctx->Const.NumProgramBinaryFormats = 1;
711 }
712
713 static void
714 brw_initialize_cs_context_constants(struct brw_context *brw)
715 {
716 struct gl_context *ctx = &brw->ctx;
717 const struct intel_screen *screen = brw->screen;
718 struct gen_device_info *devinfo = &brw->screen->devinfo;
719
720 /* FINISHME: Do this for all platforms that the kernel supports */
721 if (devinfo->is_cherryview &&
722 screen->subslice_total > 0 && screen->eu_total > 0) {
723 /* Logical CS threads = EUs per subslice * 7 threads per EU */
724 uint32_t max_cs_threads = screen->eu_total / screen->subslice_total * 7;
725
726 /* Fuse configurations may give more threads than expected, never less. */
727 if (max_cs_threads > devinfo->max_cs_threads)
728 devinfo->max_cs_threads = max_cs_threads;
729 }
730
731 /* Maximum number of scalar compute shader invocations that can be run in
732 * parallel in the same subslice assuming SIMD32 dispatch.
733 *
734 * We don't advertise more than 64 threads, because we are limited to 64 by
735 * our usage of thread_width_max in the gpgpu walker command. This only
736 * currently impacts Haswell, which otherwise might be able to advertise 70
737 * threads. With SIMD32 and 64 threads, Haswell still provides twice the
738 * required the number of invocation needed for ARB_compute_shader.
739 */
740 const unsigned max_threads = MIN2(64, devinfo->max_cs_threads);
741 const uint32_t max_invocations = 32 * max_threads;
742 ctx->Const.MaxComputeWorkGroupSize[0] = max_invocations;
743 ctx->Const.MaxComputeWorkGroupSize[1] = max_invocations;
744 ctx->Const.MaxComputeWorkGroupSize[2] = max_invocations;
745 ctx->Const.MaxComputeWorkGroupInvocations = max_invocations;
746 ctx->Const.MaxComputeSharedMemorySize = 64 * 1024;
747 }
748
749 /**
750 * Process driconf (drirc) options, setting appropriate context flags.
751 *
752 * intelInitExtensions still pokes at optionCache directly, in order to
753 * avoid advertising various extensions. No flags are set, so it makes
754 * sense to continue doing that there.
755 */
756 static void
757 brw_process_driconf_options(struct brw_context *brw)
758 {
759 const struct gen_device_info *devinfo = &brw->screen->devinfo;
760 struct gl_context *ctx = &brw->ctx;
761
762 driOptionCache *options = &brw->optionCache;
763 driParseConfigFiles(options, &brw->screen->optionCache,
764 brw->driContext->driScreenPriv->myNum, "i965");
765
766 int bo_reuse_mode = driQueryOptioni(options, "bo_reuse");
767 switch (bo_reuse_mode) {
768 case DRI_CONF_BO_REUSE_DISABLED:
769 break;
770 case DRI_CONF_BO_REUSE_ALL:
771 brw_bufmgr_enable_reuse(brw->bufmgr);
772 break;
773 }
774
775 if (INTEL_DEBUG & DEBUG_NO_HIZ) {
776 brw->has_hiz = false;
777 /* On gen6, you can only do separate stencil with HIZ. */
778 if (devinfo->gen == 6)
779 brw->has_separate_stencil = false;
780 }
781
782 if (driQueryOptionb(options, "mesa_no_error"))
783 ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
784
785 if (driQueryOptionb(options, "always_flush_batch")) {
786 fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
787 brw->always_flush_batch = true;
788 }
789
790 if (driQueryOptionb(options, "always_flush_cache")) {
791 fprintf(stderr, "flushing GPU caches before/after each draw call\n");
792 brw->always_flush_cache = true;
793 }
794
795 if (driQueryOptionb(options, "disable_throttling")) {
796 fprintf(stderr, "disabling flush throttling\n");
797 brw->disable_throttling = true;
798 }
799
800 brw->precompile = driQueryOptionb(&brw->optionCache, "shader_precompile");
801
802 if (driQueryOptionb(&brw->optionCache, "precise_trig"))
803 brw->screen->compiler->precise_trig = true;
804
805 ctx->Const.ForceGLSLExtensionsWarn =
806 driQueryOptionb(options, "force_glsl_extensions_warn");
807
808 ctx->Const.ForceGLSLVersion =
809 driQueryOptioni(options, "force_glsl_version");
810
811 ctx->Const.DisableGLSLLineContinuations =
812 driQueryOptionb(options, "disable_glsl_line_continuations");
813
814 ctx->Const.AllowGLSLExtensionDirectiveMidShader =
815 driQueryOptionb(options, "allow_glsl_extension_directive_midshader");
816
817 ctx->Const.AllowGLSLBuiltinVariableRedeclaration =
818 driQueryOptionb(options, "allow_glsl_builtin_variable_redeclaration");
819
820 ctx->Const.AllowHigherCompatVersion =
821 driQueryOptionb(options, "allow_higher_compat_version");
822
823 ctx->Const.ForceGLSLAbsSqrt =
824 driQueryOptionb(options, "force_glsl_abs_sqrt");
825
826 ctx->Const.GLSLZeroInit = driQueryOptionb(options, "glsl_zero_init");
827
828 brw->dual_color_blend_by_location =
829 driQueryOptionb(options, "dual_color_blend_by_location");
830
831 ctx->Const.AllowGLSLCrossStageInterpolationMismatch =
832 driQueryOptionb(options, "allow_glsl_cross_stage_interpolation_mismatch");
833
834 ctx->Const.dri_config_options_sha1 = ralloc_array(brw, unsigned char, 20);
835 driComputeOptionsSha1(&brw->screen->optionCache,
836 ctx->Const.dri_config_options_sha1);
837 }
838
839 GLboolean
840 brwCreateContext(gl_api api,
841 const struct gl_config *mesaVis,
842 __DRIcontext *driContextPriv,
843 const struct __DriverContextConfig *ctx_config,
844 unsigned *dri_ctx_error,
845 void *sharedContextPrivate)
846 {
847 struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
848 struct intel_screen *screen = driContextPriv->driScreenPriv->driverPrivate;
849 const struct gen_device_info *devinfo = &screen->devinfo;
850 struct dd_function_table functions;
851
852 /* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel
853 * provides us with context reset notifications.
854 */
855 uint32_t allowed_flags = __DRI_CTX_FLAG_DEBUG |
856 __DRI_CTX_FLAG_FORWARD_COMPATIBLE |
857 __DRI_CTX_FLAG_NO_ERROR;
858
859 if (screen->has_context_reset_notification)
860 allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
861
862 if (ctx_config->flags & ~allowed_flags) {
863 *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
864 return false;
865 }
866
867 if (ctx_config->attribute_mask &
868 ~(__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY |
869 __DRIVER_CONTEXT_ATTRIB_PRIORITY)) {
870 *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
871 return false;
872 }
873
874 bool notify_reset =
875 ((ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY) &&
876 ctx_config->reset_strategy != __DRI_CTX_RESET_NO_NOTIFICATION);
877
878 struct brw_context *brw = rzalloc(NULL, struct brw_context);
879 if (!brw) {
880 fprintf(stderr, "%s: failed to alloc context\n", __func__);
881 *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
882 return false;
883 }
884
885 driContextPriv->driverPrivate = brw;
886 brw->driContext = driContextPriv;
887 brw->screen = screen;
888 brw->bufmgr = screen->bufmgr;
889
890 brw->has_hiz = devinfo->has_hiz_and_separate_stencil;
891 brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil;
892
893 brw->has_swizzling = screen->hw_has_swizzling;
894
895 brw->isl_dev = screen->isl_dev;
896
897 brw->vs.base.stage = MESA_SHADER_VERTEX;
898 brw->tcs.base.stage = MESA_SHADER_TESS_CTRL;
899 brw->tes.base.stage = MESA_SHADER_TESS_EVAL;
900 brw->gs.base.stage = MESA_SHADER_GEOMETRY;
901 brw->wm.base.stage = MESA_SHADER_FRAGMENT;
902 brw->cs.base.stage = MESA_SHADER_COMPUTE;
903 if (devinfo->gen >= 8) {
904 brw->vtbl.emit_depth_stencil_hiz = gen8_emit_depth_stencil_hiz;
905 } else if (devinfo->gen >= 7) {
906 brw->vtbl.emit_depth_stencil_hiz = gen7_emit_depth_stencil_hiz;
907 } else if (devinfo->gen >= 6) {
908 brw->vtbl.emit_depth_stencil_hiz = gen6_emit_depth_stencil_hiz;
909 } else {
910 brw->vtbl.emit_depth_stencil_hiz = brw_emit_depth_stencil_hiz;
911 }
912
913 brw_init_driver_functions(brw, &functions);
914
915 if (notify_reset)
916 functions.GetGraphicsResetStatus = brw_get_graphics_reset_status;
917
918 struct gl_context *ctx = &brw->ctx;
919
920 if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) {
921 *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
922 fprintf(stderr, "%s: failed to init mesa context\n", __func__);
923 intelDestroyContext(driContextPriv);
924 return false;
925 }
926
927 driContextSetFlags(ctx, ctx_config->flags);
928
929 /* Initialize the software rasterizer and helper modules.
930 *
931 * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
932 * software fallbacks (which we have to support on legacy GL to do weird
933 * glDrawPixels(), glBitmap(), and other functions).
934 */
935 if (api != API_OPENGL_CORE && api != API_OPENGLES2) {
936 _swrast_CreateContext(ctx);
937 }
938
939 _vbo_CreateContext(ctx);
940 if (ctx->swrast_context) {
941 _tnl_CreateContext(ctx);
942 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
943 _swsetup_CreateContext(ctx);
944
945 /* Configure swrast to match hardware characteristics: */
946 _swrast_allow_pixel_fog(ctx, false);
947 _swrast_allow_vertex_fog(ctx, true);
948 }
949
950 _mesa_meta_init(ctx);
951
952 brw_process_driconf_options(brw);
953
954 if (INTEL_DEBUG & DEBUG_PERF)
955 brw->perf_debug = true;
956
957 brw_initialize_cs_context_constants(brw);
958 brw_initialize_context_constants(brw);
959
960 ctx->Const.ResetStrategy = notify_reset
961 ? GL_LOSE_CONTEXT_ON_RESET_ARB : GL_NO_RESET_NOTIFICATION_ARB;
962
963 /* Reinitialize the context point state. It depends on ctx->Const values. */
964 _mesa_init_point(ctx);
965
966 intel_fbo_init(brw);
967
968 intel_batchbuffer_init(brw);
969
970 if (devinfo->gen >= 6) {
971 /* Create a new hardware context. Using a hardware context means that
972 * our GPU state will be saved/restored on context switch, allowing us
973 * to assume that the GPU is in the same state we left it in.
974 *
975 * This is required for transform feedback buffer offsets, query objects,
976 * and also allows us to reduce how much state we have to emit.
977 */
978 brw->hw_ctx = brw_create_hw_context(brw->bufmgr);
979
980 if (!brw->hw_ctx) {
981 fprintf(stderr, "Failed to create hardware context.\n");
982 intelDestroyContext(driContextPriv);
983 return false;
984 }
985
986 int hw_priority = GEN_CONTEXT_MEDIUM_PRIORITY;
987 if (ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_PRIORITY) {
988 switch (ctx_config->priority) {
989 case __DRI_CTX_PRIORITY_LOW:
990 hw_priority = GEN_CONTEXT_LOW_PRIORITY;
991 break;
992 case __DRI_CTX_PRIORITY_HIGH:
993 hw_priority = GEN_CONTEXT_HIGH_PRIORITY;
994 break;
995 }
996 }
997 if (hw_priority != I915_CONTEXT_DEFAULT_PRIORITY &&
998 brw_hw_context_set_priority(brw->bufmgr, brw->hw_ctx, hw_priority)) {
999 fprintf(stderr,
1000 "Failed to set priority [%d:%d] for hardware context.\n",
1001 ctx_config->priority, hw_priority);
1002 intelDestroyContext(driContextPriv);
1003 return false;
1004 }
1005 }
1006
1007 if (brw_init_pipe_control(brw, devinfo)) {
1008 *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
1009 intelDestroyContext(driContextPriv);
1010 return false;
1011 }
1012
1013 if (devinfo->gen == 11) {
1014 fprintf(stderr,
1015 "WARNING: i965 does not fully support Gen11 yet.\n"
1016 "Instability or lower performance might occur.\n");
1017
1018 }
1019
1020 brw_upload_init(&brw->upload, brw->bufmgr, 65536);
1021
1022 brw_init_state(brw);
1023
1024 intelInitExtensions(ctx);
1025
1026 brw_init_surface_formats(brw);
1027
1028 brw_blorp_init(brw);
1029
1030 brw->urb.size = devinfo->urb.size;
1031
1032 if (devinfo->gen == 6)
1033 brw->urb.gs_present = false;
1034
1035 brw->prim_restart.in_progress = false;
1036 brw->prim_restart.enable_cut_index = false;
1037 brw->gs.enabled = false;
1038 brw->clip.viewport_count = 1;
1039
1040 brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
1041
1042 brw->max_gtt_map_object_size = screen->max_gtt_map_object_size;
1043
1044 ctx->VertexProgram._MaintainTnlProgram = true;
1045 ctx->FragmentProgram._MaintainTexEnvProgram = true;
1046
1047 brw_draw_init( brw );
1048
1049 if ((ctx_config->flags & __DRI_CTX_FLAG_DEBUG) != 0) {
1050 /* Turn on some extra GL_ARB_debug_output generation. */
1051 brw->perf_debug = true;
1052 }
1053
1054 if ((ctx_config->flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0) {
1055 ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
1056 ctx->Const.RobustAccess = GL_TRUE;
1057 }
1058
1059 if (INTEL_DEBUG & DEBUG_SHADER_TIME)
1060 brw_init_shader_time(brw);
1061
1062 _mesa_override_extensions(ctx);
1063 _mesa_compute_version(ctx);
1064
1065 _mesa_initialize_dispatch_tables(ctx);
1066 _mesa_initialize_vbo_vtxfmt(ctx);
1067
1068 if (ctx->Extensions.INTEL_performance_query)
1069 brw_init_performance_queries(brw);
1070
1071 vbo_use_buffer_objects(ctx);
1072 vbo_always_unmap_buffers(ctx);
1073
1074 brw->ctx.Cache = brw->screen->disk_cache;
1075
1076 return true;
1077 }
1078
1079 void
1080 intelDestroyContext(__DRIcontext * driContextPriv)
1081 {
1082 struct brw_context *brw =
1083 (struct brw_context *) driContextPriv->driverPrivate;
1084 struct gl_context *ctx = &brw->ctx;
1085 const struct gen_device_info *devinfo = &brw->screen->devinfo;
1086
1087 _mesa_meta_free(&brw->ctx);
1088
1089 if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
1090 /* Force a report. */
1091 brw->shader_time.report_time = 0;
1092
1093 brw_collect_and_report_shader_time(brw);
1094 brw_destroy_shader_time(brw);
1095 }
1096
1097 if (devinfo->gen >= 6)
1098 blorp_finish(&brw->blorp);
1099
1100 brw_destroy_state(brw);
1101 brw_draw_destroy(brw);
1102
1103 brw_bo_unreference(brw->curbe.curbe_bo);
1104
1105 brw_bo_unreference(brw->vs.base.scratch_bo);
1106 brw_bo_unreference(brw->tcs.base.scratch_bo);
1107 brw_bo_unreference(brw->tes.base.scratch_bo);
1108 brw_bo_unreference(brw->gs.base.scratch_bo);
1109 brw_bo_unreference(brw->wm.base.scratch_bo);
1110
1111 brw_bo_unreference(brw->vs.base.push_const_bo);
1112 brw_bo_unreference(brw->tcs.base.push_const_bo);
1113 brw_bo_unreference(brw->tes.base.push_const_bo);
1114 brw_bo_unreference(brw->gs.base.push_const_bo);
1115 brw_bo_unreference(brw->wm.base.push_const_bo);
1116
1117 brw_destroy_hw_context(brw->bufmgr, brw->hw_ctx);
1118
1119 if (ctx->swrast_context) {
1120 _swsetup_DestroyContext(&brw->ctx);
1121 _tnl_DestroyContext(&brw->ctx);
1122 }
1123 _vbo_DestroyContext(&brw->ctx);
1124
1125 if (ctx->swrast_context)
1126 _swrast_DestroyContext(&brw->ctx);
1127
1128 brw_fini_pipe_control(brw);
1129 intel_batchbuffer_free(&brw->batch);
1130
1131 brw_bo_unreference(brw->throttle_batch[1]);
1132 brw_bo_unreference(brw->throttle_batch[0]);
1133 brw->throttle_batch[1] = NULL;
1134 brw->throttle_batch[0] = NULL;
1135
1136 driDestroyOptionCache(&brw->optionCache);
1137
1138 /* free the Mesa context */
1139 _mesa_free_context_data(&brw->ctx);
1140
1141 ralloc_free(brw);
1142 driContextPriv->driverPrivate = NULL;
1143 }
1144
1145 GLboolean
1146 intelUnbindContext(__DRIcontext * driContextPriv)
1147 {
1148 /* Unset current context and dispath table */
1149 _mesa_make_current(NULL, NULL, NULL);
1150
1151 return true;
1152 }
1153
1154 /**
1155 * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior
1156 * on window system framebuffers.
1157 *
1158 * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if
1159 * your renderbuffer can do sRGB encode, and you can flip a switch that does
1160 * sRGB encode if the renderbuffer can handle it. You can ask specifically
1161 * for a visual where you're guaranteed to be capable, but it turns out that
1162 * everyone just makes all their ARGB8888 visuals capable and doesn't offer
1163 * incapable ones, because there's no difference between the two in resources
1164 * used. Applications thus get built that accidentally rely on the default
1165 * visual choice being sRGB, so we make ours sRGB capable. Everything sounds
1166 * great...
1167 *
1168 * But for GLES2/3, they decided that it was silly to not turn on sRGB encode
1169 * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent.
1170 * So they removed the enable knob and made it "if the renderbuffer is sRGB
1171 * capable, do sRGB encode". Then, for your window system renderbuffers, you
1172 * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals
1173 * and get no sRGB encode (assuming that both kinds of visual are available).
1174 * Thus our choice to support sRGB by default on our visuals for desktop would
1175 * result in broken rendering of GLES apps that aren't expecting sRGB encode.
1176 *
1177 * Unfortunately, renderbuffer setup happens before a context is created. So
1178 * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3
1179 * context (without an sRGB visual), we go turn that back off before anyone
1180 * finds out.
1181 */
1182 static void
1183 intel_gles3_srgb_workaround(struct brw_context *brw,
1184 struct gl_framebuffer *fb)
1185 {
1186 struct gl_context *ctx = &brw->ctx;
1187
1188 if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable)
1189 return;
1190
1191 for (int i = 0; i < BUFFER_COUNT; i++) {
1192 struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
1193
1194 /* Check if sRGB was specifically asked for. */
1195 struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, i);
1196 if (irb && irb->need_srgb)
1197 return;
1198
1199 if (rb)
1200 rb->Format = _mesa_get_srgb_format_linear(rb->Format);
1201 }
1202 /* Disable sRGB from framebuffers that are not compatible. */
1203 fb->Visual.sRGBCapable = false;
1204 }
1205
1206 GLboolean
1207 intelMakeCurrent(__DRIcontext * driContextPriv,
1208 __DRIdrawable * driDrawPriv,
1209 __DRIdrawable * driReadPriv)
1210 {
1211 struct brw_context *brw;
1212
1213 if (driContextPriv)
1214 brw = (struct brw_context *) driContextPriv->driverPrivate;
1215 else
1216 brw = NULL;
1217
1218 if (driContextPriv) {
1219 struct gl_context *ctx = &brw->ctx;
1220 struct gl_framebuffer *fb, *readFb;
1221
1222 if (driDrawPriv == NULL) {
1223 fb = _mesa_get_incomplete_framebuffer();
1224 } else {
1225 fb = driDrawPriv->driverPrivate;
1226 driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
1227 }
1228
1229 if (driReadPriv == NULL) {
1230 readFb = _mesa_get_incomplete_framebuffer();
1231 } else {
1232 readFb = driReadPriv->driverPrivate;
1233 driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
1234 }
1235
1236 /* The sRGB workaround changes the renderbuffer's format. We must change
1237 * the format before the renderbuffer's miptree get's allocated, otherwise
1238 * the formats of the renderbuffer and its miptree will differ.
1239 */
1240 intel_gles3_srgb_workaround(brw, fb);
1241 intel_gles3_srgb_workaround(brw, readFb);
1242
1243 /* If the context viewport hasn't been initialized, force a call out to
1244 * the loader to get buffers so we have a drawable size for the initial
1245 * viewport. */
1246 if (!brw->ctx.ViewportInitialized)
1247 intel_prepare_render(brw);
1248
1249 _mesa_make_current(ctx, fb, readFb);
1250 } else {
1251 _mesa_make_current(NULL, NULL, NULL);
1252 }
1253
1254 return true;
1255 }
1256
1257 void
1258 intel_resolve_for_dri2_flush(struct brw_context *brw,
1259 __DRIdrawable *drawable)
1260 {
1261 const struct gen_device_info *devinfo = &brw->screen->devinfo;
1262
1263 if (devinfo->gen < 6) {
1264 /* MSAA and fast color clear are not supported, so don't waste time
1265 * checking whether a resolve is needed.
1266 */
1267 return;
1268 }
1269
1270 struct gl_framebuffer *fb = drawable->driverPrivate;
1271 struct intel_renderbuffer *rb;
1272
1273 /* Usually, only the back buffer will need to be downsampled. However,
1274 * the front buffer will also need it if the user has rendered into it.
1275 */
1276 static const gl_buffer_index buffers[2] = {
1277 BUFFER_BACK_LEFT,
1278 BUFFER_FRONT_LEFT,
1279 };
1280
1281 for (int i = 0; i < 2; ++i) {
1282 rb = intel_get_renderbuffer(fb, buffers[i]);
1283 if (rb == NULL || rb->mt == NULL)
1284 continue;
1285 if (rb->mt->surf.samples == 1) {
1286 assert(rb->mt_layer == 0 && rb->mt_level == 0 &&
1287 rb->layer_count == 1);
1288 intel_miptree_prepare_external(brw, rb->mt);
1289 } else {
1290 intel_renderbuffer_downsample(brw, rb);
1291
1292 /* Call prepare_external on the single-sample miptree to do any
1293 * needed resolves prior to handing it off to the window system.
1294 * This is needed in the case that rb->singlesample_mt is Y-tiled
1295 * with CCS_E enabled but without I915_FORMAT_MOD_Y_TILED_CCS_E. In
1296 * this case, the MSAA resolve above will write compressed data into
1297 * rb->singlesample_mt.
1298 *
1299 * TODO: Some day, if we decide to care about the tiny performance
1300 * hit we're taking by doing the MSAA resolve and then a CCS resolve,
1301 * we could detect this case and just allocate the single-sampled
1302 * miptree without aux. However, that would be a lot of plumbing and
1303 * this is a rather exotic case so it's not really worth it.
1304 */
1305 intel_miptree_prepare_external(brw, rb->singlesample_mt);
1306 }
1307 }
1308 }
1309
1310 static unsigned
1311 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
1312 {
1313 return _mesa_get_format_bytes(intel_rb_format(rb)) * 8;
1314 }
1315
1316 static void
1317 intel_query_dri2_buffers(struct brw_context *brw,
1318 __DRIdrawable *drawable,
1319 __DRIbuffer **buffers,
1320 int *count);
1321
1322 static void
1323 intel_process_dri2_buffer(struct brw_context *brw,
1324 __DRIdrawable *drawable,
1325 __DRIbuffer *buffer,
1326 struct intel_renderbuffer *rb,
1327 const char *buffer_name);
1328
1329 static void
1330 intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable);
1331
1332 static void
1333 intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable)
1334 {
1335 struct gl_framebuffer *fb = drawable->driverPrivate;
1336 struct intel_renderbuffer *rb;
1337 __DRIbuffer *buffers = NULL;
1338 int count;
1339 const char *region_name;
1340
1341 /* Set this up front, so that in case our buffers get invalidated
1342 * while we're getting new buffers, we don't clobber the stamp and
1343 * thus ignore the invalidate. */
1344 drawable->lastStamp = drawable->dri2.stamp;
1345
1346 if (unlikely(INTEL_DEBUG & DEBUG_DRI))
1347 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
1348
1349 intel_query_dri2_buffers(brw, drawable, &buffers, &count);
1350
1351 if (buffers == NULL)
1352 return;
1353
1354 for (int i = 0; i < count; i++) {
1355 switch (buffers[i].attachment) {
1356 case __DRI_BUFFER_FRONT_LEFT:
1357 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1358 region_name = "dri2 front buffer";
1359 break;
1360
1361 case __DRI_BUFFER_FAKE_FRONT_LEFT:
1362 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1363 region_name = "dri2 fake front buffer";
1364 break;
1365
1366 case __DRI_BUFFER_BACK_LEFT:
1367 rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1368 region_name = "dri2 back buffer";
1369 break;
1370
1371 case __DRI_BUFFER_DEPTH:
1372 case __DRI_BUFFER_HIZ:
1373 case __DRI_BUFFER_DEPTH_STENCIL:
1374 case __DRI_BUFFER_STENCIL:
1375 case __DRI_BUFFER_ACCUM:
1376 default:
1377 fprintf(stderr,
1378 "unhandled buffer attach event, attachment type %d\n",
1379 buffers[i].attachment);
1380 return;
1381 }
1382
1383 intel_process_dri2_buffer(brw, drawable, &buffers[i], rb, region_name);
1384 }
1385
1386 }
1387
1388 void
1389 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
1390 {
1391 struct brw_context *brw = context->driverPrivate;
1392 __DRIscreen *dri_screen = brw->screen->driScrnPriv;
1393
1394 /* Set this up front, so that in case our buffers get invalidated
1395 * while we're getting new buffers, we don't clobber the stamp and
1396 * thus ignore the invalidate. */
1397 drawable->lastStamp = drawable->dri2.stamp;
1398
1399 if (unlikely(INTEL_DEBUG & DEBUG_DRI))
1400 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
1401
1402 if (dri_screen->image.loader)
1403 intel_update_image_buffers(brw, drawable);
1404 else
1405 intel_update_dri2_buffers(brw, drawable);
1406
1407 driUpdateFramebufferSize(&brw->ctx, drawable);
1408 }
1409
1410 /**
1411 * intel_prepare_render should be called anywhere that curent read/drawbuffer
1412 * state is required.
1413 */
1414 void
1415 intel_prepare_render(struct brw_context *brw)
1416 {
1417 struct gl_context *ctx = &brw->ctx;
1418 __DRIcontext *driContext = brw->driContext;
1419 __DRIdrawable *drawable;
1420
1421 drawable = driContext->driDrawablePriv;
1422 if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
1423 if (drawable->lastStamp != drawable->dri2.stamp)
1424 intel_update_renderbuffers(driContext, drawable);
1425 driContext->dri2.draw_stamp = drawable->dri2.stamp;
1426 }
1427
1428 drawable = driContext->driReadablePriv;
1429 if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) {
1430 if (drawable->lastStamp != drawable->dri2.stamp)
1431 intel_update_renderbuffers(driContext, drawable);
1432 driContext->dri2.read_stamp = drawable->dri2.stamp;
1433 }
1434
1435 /* If we're currently rendering to the front buffer, the rendering
1436 * that will happen next will probably dirty the front buffer. So
1437 * mark it as dirty here.
1438 */
1439 if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer))
1440 brw->front_buffer_dirty = true;
1441 }
1442
1443 /**
1444 * \brief Query DRI2 to obtain a DRIdrawable's buffers.
1445 *
1446 * To determine which DRI buffers to request, examine the renderbuffers
1447 * attached to the drawable's framebuffer. Then request the buffers with
1448 * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
1449 *
1450 * This is called from intel_update_renderbuffers().
1451 *
1452 * \param drawable Drawable whose buffers are queried.
1453 * \param buffers [out] List of buffers returned by DRI2 query.
1454 * \param buffer_count [out] Number of buffers returned.
1455 *
1456 * \see intel_update_renderbuffers()
1457 * \see DRI2GetBuffers()
1458 * \see DRI2GetBuffersWithFormat()
1459 */
1460 static void
1461 intel_query_dri2_buffers(struct brw_context *brw,
1462 __DRIdrawable *drawable,
1463 __DRIbuffer **buffers,
1464 int *buffer_count)
1465 {
1466 __DRIscreen *dri_screen = brw->screen->driScrnPriv;
1467 struct gl_framebuffer *fb = drawable->driverPrivate;
1468 int i = 0;
1469 unsigned attachments[8];
1470
1471 struct intel_renderbuffer *front_rb;
1472 struct intel_renderbuffer *back_rb;
1473
1474 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1475 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1476
1477 memset(attachments, 0, sizeof(attachments));
1478 if ((_mesa_is_front_buffer_drawing(fb) ||
1479 _mesa_is_front_buffer_reading(fb) ||
1480 !back_rb) && front_rb) {
1481 /* If a fake front buffer is in use, then querying for
1482 * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
1483 * the real front buffer to the fake front buffer. So before doing the
1484 * query, we need to make sure all the pending drawing has landed in the
1485 * real front buffer.
1486 */
1487 intel_batchbuffer_flush(brw);
1488 intel_flush_front(&brw->ctx);
1489
1490 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
1491 attachments[i++] = intel_bits_per_pixel(front_rb);
1492 } else if (front_rb && brw->front_buffer_dirty) {
1493 /* We have pending front buffer rendering, but we aren't querying for a
1494 * front buffer. If the front buffer we have is a fake front buffer,
1495 * the X server is going to throw it away when it processes the query.
1496 * So before doing the query, make sure all the pending drawing has
1497 * landed in the real front buffer.
1498 */
1499 intel_batchbuffer_flush(brw);
1500 intel_flush_front(&brw->ctx);
1501 }
1502
1503 if (back_rb) {
1504 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
1505 attachments[i++] = intel_bits_per_pixel(back_rb);
1506 }
1507
1508 assert(i <= ARRAY_SIZE(attachments));
1509
1510 *buffers =
1511 dri_screen->dri2.loader->getBuffersWithFormat(drawable,
1512 &drawable->w,
1513 &drawable->h,
1514 attachments, i / 2,
1515 buffer_count,
1516 drawable->loaderPrivate);
1517 }
1518
1519 /**
1520 * \brief Assign a DRI buffer's DRM region to a renderbuffer.
1521 *
1522 * This is called from intel_update_renderbuffers().
1523 *
1524 * \par Note:
1525 * DRI buffers whose attachment point is DRI2BufferStencil or
1526 * DRI2BufferDepthStencil are handled as special cases.
1527 *
1528 * \param buffer_name is a human readable name, such as "dri2 front buffer",
1529 * that is passed to brw_bo_gem_create_from_name().
1530 *
1531 * \see intel_update_renderbuffers()
1532 */
1533 static void
1534 intel_process_dri2_buffer(struct brw_context *brw,
1535 __DRIdrawable *drawable,
1536 __DRIbuffer *buffer,
1537 struct intel_renderbuffer *rb,
1538 const char *buffer_name)
1539 {
1540 struct gl_framebuffer *fb = drawable->driverPrivate;
1541 struct brw_bo *bo;
1542
1543 if (!rb)
1544 return;
1545
1546 unsigned num_samples = rb->Base.Base.NumSamples;
1547
1548 /* We try to avoid closing and reopening the same BO name, because the first
1549 * use of a mapping of the buffer involves a bunch of page faulting which is
1550 * moderately expensive.
1551 */
1552 struct intel_mipmap_tree *last_mt;
1553 if (num_samples == 0)
1554 last_mt = rb->mt;
1555 else
1556 last_mt = rb->singlesample_mt;
1557
1558 uint32_t old_name = 0;
1559 if (last_mt) {
1560 /* The bo already has a name because the miptree was created by a
1561 * previous call to intel_process_dri2_buffer(). If a bo already has a
1562 * name, then brw_bo_flink() is a low-cost getter. It does not
1563 * create a new name.
1564 */
1565 brw_bo_flink(last_mt->bo, &old_name);
1566 }
1567
1568 if (old_name == buffer->name)
1569 return;
1570
1571 if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
1572 fprintf(stderr,
1573 "attaching buffer %d, at %d, cpp %d, pitch %d\n",
1574 buffer->name, buffer->attachment,
1575 buffer->cpp, buffer->pitch);
1576 }
1577
1578 bo = brw_bo_gem_create_from_name(brw->bufmgr, buffer_name,
1579 buffer->name);
1580 if (!bo) {
1581 fprintf(stderr,
1582 "Failed to open BO for returned DRI2 buffer "
1583 "(%dx%d, %s, named %d).\n"
1584 "This is likely a bug in the X Server that will lead to a "
1585 "crash soon.\n",
1586 drawable->w, drawable->h, buffer_name, buffer->name);
1587 return;
1588 }
1589
1590 uint32_t tiling, swizzle;
1591 brw_bo_get_tiling(bo, &tiling, &swizzle);
1592
1593 struct intel_mipmap_tree *mt =
1594 intel_miptree_create_for_bo(brw,
1595 bo,
1596 intel_rb_format(rb),
1597 0,
1598 drawable->w,
1599 drawable->h,
1600 1,
1601 buffer->pitch,
1602 isl_tiling_from_i915_tiling(tiling),
1603 MIPTREE_CREATE_DEFAULT);
1604 if (!mt) {
1605 brw_bo_unreference(bo);
1606 return;
1607 }
1608
1609 /* We got this BO from X11. We cana't assume that we have coherent texture
1610 * access because X may suddenly decide to use it for scan-out which would
1611 * destroy coherency.
1612 */
1613 bo->cache_coherent = false;
1614
1615 if (!intel_update_winsys_renderbuffer_miptree(brw, rb, mt,
1616 drawable->w, drawable->h,
1617 buffer->pitch)) {
1618 brw_bo_unreference(bo);
1619 intel_miptree_release(&mt);
1620 return;
1621 }
1622
1623 if (_mesa_is_front_buffer_drawing(fb) &&
1624 (buffer->attachment == __DRI_BUFFER_FRONT_LEFT ||
1625 buffer->attachment == __DRI_BUFFER_FAKE_FRONT_LEFT) &&
1626 rb->Base.Base.NumSamples > 1) {
1627 intel_renderbuffer_upsample(brw, rb);
1628 }
1629
1630 assert(rb->mt);
1631
1632 brw_bo_unreference(bo);
1633 }
1634
1635 /**
1636 * \brief Query DRI image loader to obtain a DRIdrawable's buffers.
1637 *
1638 * To determine which DRI buffers to request, examine the renderbuffers
1639 * attached to the drawable's framebuffer. Then request the buffers from
1640 * the image loader
1641 *
1642 * This is called from intel_update_renderbuffers().
1643 *
1644 * \param drawable Drawable whose buffers are queried.
1645 * \param buffers [out] List of buffers returned by DRI2 query.
1646 * \param buffer_count [out] Number of buffers returned.
1647 *
1648 * \see intel_update_renderbuffers()
1649 */
1650
1651 static void
1652 intel_update_image_buffer(struct brw_context *intel,
1653 __DRIdrawable *drawable,
1654 struct intel_renderbuffer *rb,
1655 __DRIimage *buffer,
1656 enum __DRIimageBufferMask buffer_type)
1657 {
1658 struct gl_framebuffer *fb = drawable->driverPrivate;
1659
1660 if (!rb || !buffer->bo)
1661 return;
1662
1663 unsigned num_samples = rb->Base.Base.NumSamples;
1664
1665 /* Check and see if we're already bound to the right
1666 * buffer object
1667 */
1668 struct intel_mipmap_tree *last_mt;
1669 if (num_samples == 0)
1670 last_mt = rb->mt;
1671 else
1672 last_mt = rb->singlesample_mt;
1673
1674 if (last_mt && last_mt->bo == buffer->bo)
1675 return;
1676
1677 struct intel_mipmap_tree *mt =
1678 intel_miptree_create_for_dri_image(intel, buffer, GL_TEXTURE_2D,
1679 intel_rb_format(rb), true);
1680 if (!mt)
1681 return;
1682
1683 if (!intel_update_winsys_renderbuffer_miptree(intel, rb, mt,
1684 buffer->width, buffer->height,
1685 buffer->pitch)) {
1686 intel_miptree_release(&mt);
1687 return;
1688 }
1689
1690 if (_mesa_is_front_buffer_drawing(fb) &&
1691 buffer_type == __DRI_IMAGE_BUFFER_FRONT &&
1692 rb->Base.Base.NumSamples > 1) {
1693 intel_renderbuffer_upsample(intel, rb);
1694 }
1695 }
1696
1697 static void
1698 intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
1699 {
1700 struct gl_framebuffer *fb = drawable->driverPrivate;
1701 __DRIscreen *dri_screen = brw->screen->driScrnPriv;
1702 struct intel_renderbuffer *front_rb;
1703 struct intel_renderbuffer *back_rb;
1704 struct __DRIimageList images;
1705 mesa_format format;
1706 uint32_t buffer_mask = 0;
1707 int ret;
1708
1709 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1710 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1711
1712 if (back_rb)
1713 format = intel_rb_format(back_rb);
1714 else if (front_rb)
1715 format = intel_rb_format(front_rb);
1716 else
1717 return;
1718
1719 if (front_rb && (_mesa_is_front_buffer_drawing(fb) ||
1720 _mesa_is_front_buffer_reading(fb) || !back_rb)) {
1721 buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
1722 }
1723
1724 if (back_rb)
1725 buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
1726
1727 ret = dri_screen->image.loader->getBuffers(drawable,
1728 driGLFormatToImageFormat(format),
1729 &drawable->dri2.stamp,
1730 drawable->loaderPrivate,
1731 buffer_mask,
1732 &images);
1733 if (!ret)
1734 return;
1735
1736 if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
1737 drawable->w = images.front->width;
1738 drawable->h = images.front->height;
1739 intel_update_image_buffer(brw,
1740 drawable,
1741 front_rb,
1742 images.front,
1743 __DRI_IMAGE_BUFFER_FRONT);
1744 }
1745
1746 if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
1747 drawable->w = images.back->width;
1748 drawable->h = images.back->height;
1749 intel_update_image_buffer(brw,
1750 drawable,
1751 back_rb,
1752 images.back,
1753 __DRI_IMAGE_BUFFER_BACK);
1754 }
1755 }