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