blob: 78766524e3c985e777ab69e2e11ba284a2799e6f [file] [log] [blame]
Ian Romanickaa1a5c02015-08-19 19:24:45 -07001/*
José Fonseca87712852014-01-17 16:27:50 +00002 * Copyright 2003 VMware, Inc.
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00003 * All Rights Reserved.
Kenneth Graunkea7bdd4c2013-11-25 15:46:34 -08004 *
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00005 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
Ian Romanick284dcad2015-08-19 16:36:35 -07009 * distribute, sublicense, and/or sell copies of the Software, and to
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000010 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
Kenneth Graunkea7bdd4c2013-11-25 15:46:34 -080012 *
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000013 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
Kenneth Graunkea7bdd4c2013-11-25 15:46:34 -080016 *
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Ian Romanick284dcad2015-08-19 16:36:35 -070019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
José Fonseca87712852014-01-17 16:27:50 +000020 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000021 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Ian Romanickaa1a5c02015-08-19 19:24:45 -070024 */
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000025
Eric Anholtf6ca4a32011-03-09 12:54:14 -080026#include <errno.h>
Quentin Glidic7cb87642012-10-09 15:15:47 +020027#include <time.h>
Ian Romanick1e4ce082013-02-14 16:50:28 -080028#include <unistd.h>
Brian Paulecadb512008-09-18 15:17:05 -060029#include "main/context.h"
30#include "main/framebuffer.h"
Brian Paulecadb512008-09-18 15:17:05 -060031#include "main/renderbuffer.h"
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +020032#include "main/texobj.h"
Kristian Høgsberg2d995882010-02-11 17:18:01 -050033#include "main/hash.h"
Kristian Høgsbergd7322c92010-02-26 14:49:31 -050034#include "main/fbobject.h"
Brian Paul14aff232012-01-02 15:20:04 -070035#include "main/version.h"
Brian Pauld0dc75c2011-12-05 20:40:48 -070036#include "swrast/s_renderbuffer.h"
Kenneth Graunke1e0da622014-02-24 23:39:14 -080037#include "util/ralloc.h"
Jason Ekstrandae3870d2015-04-16 12:01:09 -070038#include "brw_shader.h"
Emil Velikova39a8fb2016-01-18 12:54:03 +020039#include "compiler/nir/nir.h"
Brian Paul6c244b02009-01-26 12:38:46 -070040
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000041#include "utils.h"
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000042#include "xmlpool.h"
43
Eric Anholt68689232013-09-27 15:25:40 -070044static const __DRIconfigOptionsExtension brw_config_options = {
45 .base = { __DRI_CONFIG_OPTIONS, 1 },
46 .xml =
47DRI_CONF_BEGIN
Eric Anholta0e453a2008-01-17 14:23:04 -080048 DRI_CONF_SECTION_PERFORMANCE
Jesse Barnese9bf3e42008-07-31 11:50:37 -070049 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
Eric Anholtfe91c052008-03-05 14:14:54 -080050 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
51 * DRI_CONF_BO_REUSE_ALL
52 */
Dave Airlief75843a2008-08-24 17:59:10 +100053 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
Eric Anholtfe91c052008-03-05 14:14:54 -080054 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
55 DRI_CONF_ENUM(0, "Disable buffer object reuse")
56 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
57 DRI_CONF_DESC_END
58 DRI_CONF_OPT_END
Eric Anholt1ba96652009-06-03 16:40:20 +000059
Eric Anholtea6cf2b2013-01-02 17:02:58 -080060 DRI_CONF_OPT_BEGIN_B(hiz, "true")
Eric Anholtd09fce52012-03-06 11:05:20 -080061 DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
62 DRI_CONF_OPT_END
Eric Anholta0e453a2008-01-17 14:23:04 -080063 DRI_CONF_SECTION_END
Chad Versace2f896622013-11-03 13:14:50 -080064
Eric Anholta0e453a2008-01-17 14:23:04 -080065 DRI_CONF_SECTION_QUALITY
Eric Anholtea6cf2b2013-01-02 17:02:58 -080066 DRI_CONF_FORCE_S3TC_ENABLE("false")
Chad Versace2f896622013-11-03 13:14:50 -080067
Gurchetan Singhd9546b02016-05-11 13:32:09 -070068 DRI_CONF_PRECISE_TRIG("false")
69
Chad Versace2f896622013-11-03 13:14:50 -080070 DRI_CONF_OPT_BEGIN(clamp_max_samples, int, -1)
71 DRI_CONF_DESC(en, "Clamp the value of GL_MAX_SAMPLES to the "
72 "given integer. If negative, then do not clamp.")
73 DRI_CONF_OPT_END
Eric Anholta0e453a2008-01-17 14:23:04 -080074 DRI_CONF_SECTION_END
Chad Versace2f896622013-11-03 13:14:50 -080075
Eric Anholta0e453a2008-01-17 14:23:04 -080076 DRI_CONF_SECTION_DEBUG
Eric Anholtea6cf2b2013-01-02 17:02:58 -080077 DRI_CONF_NO_RAST("false")
78 DRI_CONF_ALWAYS_FLUSH_BATCH("false")
79 DRI_CONF_ALWAYS_FLUSH_CACHE("false")
80 DRI_CONF_DISABLE_THROTTLING("false")
81 DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
82 DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
83 DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
Kenneth Graunkeb3340cd2016-01-20 17:33:14 -080084 DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION("false")
Kenneth Graunke31f1cbc2014-08-08 01:03:15 -070085 DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER("false")
Eric Anholt81aa5d72009-07-29 13:07:49 -070086
Eric Anholtea6cf2b2013-01-02 17:02:58 -080087 DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
Eric Anholtc6abde22011-11-23 10:01:39 -080088 DRI_CONF_DESC(en, "Perform code generation at shader link time.")
89 DRI_CONF_OPT_END
Eric Anholta0e453a2008-01-17 14:23:04 -080090 DRI_CONF_SECTION_END
Rob Clarkf78a6b12016-06-24 14:28:51 -040091
92 DRI_CONF_SECTION_MISCELLANEOUS
93 DRI_CONF_GLSL_ZERO_INIT("false")
94 DRI_CONF_SECTION_END
Eric Anholt68689232013-09-27 15:25:40 -070095DRI_CONF_END
96};
Eric Anholta0e453a2008-01-17 14:23:04 -080097
Eric Anholtdf9f8912010-12-13 11:02:15 -080098#include "intel_batchbuffer.h"
99#include "intel_buffers.h"
100#include "intel_bufmgr.h"
Eric Anholtdf9f8912010-12-13 11:02:15 -0800101#include "intel_fbo.h"
Chad Versaceda2816a2011-11-16 14:04:25 -0800102#include "intel_mipmap_tree.h"
Eric Anholtdf9f8912010-12-13 11:02:15 -0800103#include "intel_screen.h"
104#include "intel_tex.h"
Eric Anholt55667472014-04-29 15:30:15 -0700105#include "intel_image.h"
Eric Anholtdf9f8912010-12-13 11:02:15 -0800106
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200107#include "brw_context.h"
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200108
Eric Anholtdf9f8912010-12-13 11:02:15 -0800109#include "i915_drm.h"
110
Eric Anholt006c1a32012-08-07 10:05:38 -0700111/**
112 * For debugging purposes, this returns a time in seconds.
113 */
114double
115get_time(void)
116{
117 struct timespec tp;
118
119 clock_gettime(CLOCK_MONOTONIC, &tp);
120
121 return tp.tv_sec + tp.tv_nsec / 1000000000.0;
122}
123
Kenneth Graunke252d3112012-03-29 23:37:09 -0700124void
125aub_dump_bmp(struct gl_context *ctx)
126{
127 struct gl_framebuffer *fb = ctx->DrawBuffer;
128
Rhys Kidd65fe7c62015-08-06 16:34:00 +1000129 for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
Kenneth Graunke252d3112012-03-29 23:37:09 -0700130 struct intel_renderbuffer *irb =
131 intel_renderbuffer(fb->_ColorDrawBuffers[i]);
132
133 if (irb && irb->mt) {
134 enum aub_dump_bmp_format format;
135
136 switch (irb->Base.Base.Format) {
Mark Muelleref145ba2014-01-20 14:21:43 -0800137 case MESA_FORMAT_B8G8R8A8_UNORM:
138 case MESA_FORMAT_B8G8R8X8_UNORM:
Kenneth Graunke252d3112012-03-29 23:37:09 -0700139 format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
140 break;
141 default:
142 continue;
143 }
144
Eric Anholte16c5c92014-04-25 13:29:41 -0700145 drm_intel_gem_bo_aub_dump_bmp(irb->mt->bo,
Kenneth Graunke252d3112012-03-29 23:37:09 -0700146 irb->draw_x,
147 irb->draw_y,
148 irb->Base.Base.Width,
149 irb->Base.Base.Height,
150 format,
Eric Anholte16c5c92014-04-25 13:29:41 -0700151 irb->mt->pitch,
Kenneth Graunke252d3112012-03-29 23:37:09 -0700152 0);
153 }
154 }
155}
156
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500157static const __DRItexBufferExtension intelTexBufferExtension = {
Emil Velikov38f20f72014-02-12 17:47:53 +0000158 .base = { __DRI_TEX_BUFFER, 3 },
Chad Versacec9f51262012-11-19 11:43:51 -0800159
160 .setTexBuffer = intelSetTexBuffer,
161 .setTexBuffer2 = intelSetTexBuffer2,
162 .releaseTexBuffer = NULL,
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500163};
164
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500165static void
Eric Anholt313f2bc2012-12-28 11:44:08 -0800166intel_dri2_flush_with_flags(__DRIcontext *cPriv,
167 __DRIdrawable *dPriv,
168 unsigned flags,
169 enum __DRI2throttleReason reason)
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500170{
Eric Anholt313f2bc2012-12-28 11:44:08 -0800171 struct brw_context *brw = cPriv->driverPrivate;
172
173 if (!brw)
Anuj Phogatce1c9492012-01-17 13:21:52 -0800174 return;
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500175
Eric Anholt313f2bc2012-12-28 11:44:08 -0800176 struct gl_context *ctx = &brw->ctx;
Kristian Høgsberge67c3382010-05-18 21:50:44 -0400177
Eric Anholt313f2bc2012-12-28 11:44:08 -0800178 FLUSH_VERTICES(ctx, 0);
179
180 if (flags & __DRI2_FLUSH_DRAWABLE)
181 intel_resolve_for_dri2_flush(brw, dPriv);
182
Chris Wilson8b9bd192015-02-26 11:25:18 +0000183 if (reason == __DRI2_THROTTLE_SWAPBUFFER)
184 brw->need_swap_throttle = true;
185 if (reason == __DRI2_THROTTLE_FLUSHFRONT)
186 brw->need_flush_throttle = true;
Eric Anholt313f2bc2012-12-28 11:44:08 -0800187
188 intel_batchbuffer_flush(brw);
Eric Anholt0247d892012-03-06 15:31:42 -0800189
190 if (INTEL_DEBUG & DEBUG_AUB) {
Kenneth Graunke252d3112012-03-29 23:37:09 -0700191 aub_dump_bmp(ctx);
Eric Anholt0247d892012-03-06 15:31:42 -0800192 }
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500193}
194
Eric Anholt313f2bc2012-12-28 11:44:08 -0800195/**
196 * Provides compatibility with loaders that only support the older (version
197 * 1-3) flush interface.
198 *
199 * That includes libGL up to Mesa 9.0, and the X Server at least up to 1.13.
200 */
201static void
202intel_dri2_flush(__DRIdrawable *drawable)
203{
204 intel_dri2_flush_with_flags(drawable->driContextPriv, drawable,
205 __DRI2_FLUSH_DRAWABLE,
206 __DRI2_THROTTLE_SWAPBUFFER);
207}
Chad Versacec9f51262012-11-19 11:43:51 -0800208
Eric Anholt313f2bc2012-12-28 11:44:08 -0800209static const struct __DRI2flushExtensionRec intelFlushExtension = {
210 .base = { __DRI2_FLUSH, 4 },
211
212 .flush = intel_dri2_flush,
Chad Versacec9f51262012-11-19 11:43:51 -0800213 .invalidate = dri2InvalidateDrawable,
Eric Anholt313f2bc2012-12-28 11:44:08 -0800214 .flush_with_flags = intel_dri2_flush_with_flags,
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500215};
216
Eric Anholt9ba6f472012-09-21 10:36:22 +0200217static struct intel_image_format intel_image_formats[] = {
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200218 { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
219 { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
220
Gwenole Beauchesnee1c50ab2014-09-09 10:56:24 +0200221 { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
222 { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } },
223
Keith Packardaea47572013-11-21 20:08:35 -0800224 { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
225 { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } },
226
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200227 { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
228 { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
229
Gwenole Beauchesnee1c50ab2014-09-09 10:56:24 +0200230 { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
231 { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 }, } },
232
Singh, Satyeshware2620c12013-10-16 01:11:02 +0000233 { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1,
234 { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } },
235
Chad Versace56f1f472015-06-23 15:48:40 -0700236 { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_COMPONENTS_R, 1,
237 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, } },
238
239 { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_COMPONENTS_RG, 1,
240 { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, } },
241
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200242 { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
243 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
244 { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
245 { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
246
247 { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
248 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
249 { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
250 { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
251
252 { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
253 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
254 { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
255 { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
256
257 { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
258 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
259 { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
260 { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
261
262 { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
263 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
264 { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
265 { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
266
Kristian Høgsberg Kristensen2bb935b2016-04-27 15:00:54 -0700267 { __DRI_IMAGE_FOURCC_YVU410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
268 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
269 { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
270 { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
271
272 { __DRI_IMAGE_FOURCC_YVU411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
273 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
274 { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
275 { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
276
277 { __DRI_IMAGE_FOURCC_YVU420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
278 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
279 { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
280 { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
281
282 { __DRI_IMAGE_FOURCC_YVU422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
283 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
284 { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
285 { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
286
287 { __DRI_IMAGE_FOURCC_YVU444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
288 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
289 { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
290 { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
291
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200292 { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
293 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
294 { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
295
296 { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
297 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
298 { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
299
300 /* For YUYV buffers, we set up two overlapping DRI images and treat
301 * them as planar buffers in the compositors. Plane 0 is GR88 and
302 * samples YU or YV pairs and places Y into the R component, while
303 * plane 1 is ARGB and samples YUYV clusters and places pairs and
304 * places U into the G component and V into A. This lets the
305 * texture sampler interpolate the Y components correctly when
306 * sampling from plane 0, and interpolate U and V correctly when
307 * sampling from plane 1. */
308 { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
309 { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
310 { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
311};
312
Eric Anholte3a9ca42014-04-25 12:14:34 -0700313static void
314intel_image_warn_if_unaligned(__DRIimage *image, const char *func)
315{
316 uint32_t tiling, swizzle;
317 drm_intel_bo_get_tiling(image->bo, &tiling, &swizzle);
318
319 if (tiling != I915_TILING_NONE && (image->offset & 0xfff)) {
320 _mesa_warning(NULL, "%s: offset 0x%08x not on tile boundary",
321 func, image->offset);
322 }
323}
324
Topi Pohjolainen904587a2012-12-28 12:22:54 +0200325static struct intel_image_format *
326intel_image_format_lookup(int fourcc)
327{
328 struct intel_image_format *f = NULL;
329
330 for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
331 if (intel_image_formats[i].fourcc == fourcc) {
332 f = &intel_image_formats[i];
333 break;
334 }
335 }
336
337 return f;
338}
339
Dave Airlie8f7338f2014-03-03 13:57:16 +1000340static boolean intel_lookup_fourcc(int dri_format, int *fourcc)
341{
342 for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
343 if (intel_image_formats[i].planes[0].dri_format == dri_format) {
344 *fourcc = intel_image_formats[i].fourcc;
345 return true;
346 }
347 }
348 return false;
349}
350
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500351static __DRIimage *
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400352intel_allocate_image(int dri_format, void *loaderPrivate)
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500353{
354 __DRIimage *image;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500355
Brian Paul4fdac652012-09-01 07:47:24 -0600356 image = calloc(1, sizeof *image);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500357 if (image == NULL)
358 return NULL;
359
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400360 image->dri_format = dri_format;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400361 image->offset = 0;
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300362
Keith Packard1f085ba2013-11-04 17:33:34 -0800363 image->format = driImageFormatToGLFormat(dri_format);
Ander Conselvan de Oliveira5ba6be22013-11-12 14:47:08 +0200364 if (dri_format != __DRI_IMAGE_FORMAT_NONE &&
365 image->format == MESA_FORMAT_NONE) {
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500366 free(image);
367 return NULL;
368 }
369
Kristian Høgsberg454fc072012-07-05 00:07:15 -0400370 image->internal_format = _mesa_get_format_base_format(image->format);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500371 image->data = loaderPrivate;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500372
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400373 return image;
374}
375
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200376/**
Eric Anholte3a9ca42014-04-25 12:14:34 -0700377 * Sets up a DRIImage structure to point to a slice out of a miptree.
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200378 */
379static void
Kenneth Graunkeca437572013-07-02 23:17:14 -0700380intel_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image,
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200381 struct intel_mipmap_tree *mt, GLuint level,
382 GLuint zoffset)
383{
Kenneth Graunkeca437572013-07-02 23:17:14 -0700384 intel_miptree_make_shareable(brw, mt);
Paul Berryef9142d2013-05-21 14:21:44 -0700385
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200386 intel_miptree_check_level_layer(mt, level, zoffset);
387
Kenneth Graunkeb18871c2014-02-22 23:47:30 -0800388 image->width = minify(mt->physical_width0, level - mt->first_level);
389 image->height = minify(mt->physical_height0, level - mt->first_level);
Eric Anholte16c5c92014-04-25 13:29:41 -0700390 image->pitch = mt->pitch;
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200391
Eric Anholt6db640d2014-04-25 11:26:27 -0700392 image->offset = intel_miptree_get_tile_offsets(mt, level, zoffset,
393 &image->tile_x,
394 &image->tile_y);
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200395
Eric Anholte3a9ca42014-04-25 12:14:34 -0700396 drm_intel_bo_unreference(image->bo);
Eric Anholte16c5c92014-04-25 13:29:41 -0700397 image->bo = mt->bo;
398 drm_intel_bo_reference(mt->bo);
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200399}
400
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400401static __DRIimage *
402intel_create_image_from_name(__DRIscreen *screen,
403 int width, int height, int format,
404 int name, int pitch, void *loaderPrivate)
405{
406 struct intel_screen *intelScreen = screen->driverPrivate;
407 __DRIimage *image;
408 int cpp;
409
410 image = intel_allocate_image(format, loaderPrivate);
Anuj Phogat484b89a2013-04-16 10:34:43 -0700411 if (image == NULL)
412 return NULL;
413
Kristian Høgsberg636646a2012-07-16 10:54:30 -0400414 if (image->format == MESA_FORMAT_NONE)
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200415 cpp = 1;
Kristian Høgsberg636646a2012-07-16 10:54:30 -0400416 else
417 cpp = _mesa_get_format_bytes(image->format);
Eric Anholte3a9ca42014-04-25 12:14:34 -0700418
419 image->width = width;
420 image->height = height;
421 image->pitch = pitch * cpp;
422 image->bo = drm_intel_bo_gem_create_from_name(intelScreen->bufmgr, "image",
423 name);
424 if (!image->bo) {
Brian Paulfe72a062012-09-01 07:47:24 -0600425 free(image);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500426 return NULL;
427 }
428
Iago Toral Quiroga2bba2152015-11-24 12:49:55 +0100429 return image;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500430}
431
432static __DRIimage *
433intel_create_image_from_renderbuffer(__DRIcontext *context,
434 int renderbuffer, void *loaderPrivate)
435{
436 __DRIimage *image;
Kenneth Graunkeca437572013-07-02 23:17:14 -0700437 struct brw_context *brw = context->driverPrivate;
Kenneth Graunke8c9a54e2013-07-06 00:46:38 -0700438 struct gl_context *ctx = &brw->ctx;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500439 struct gl_renderbuffer *rb;
440 struct intel_renderbuffer *irb;
441
Kenneth Graunkeca437572013-07-02 23:17:14 -0700442 rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500443 if (!rb) {
Kenneth Graunkeca437572013-07-02 23:17:14 -0700444 _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500445 return NULL;
446 }
447
448 irb = intel_renderbuffer(rb);
Kenneth Graunkeca437572013-07-02 23:17:14 -0700449 intel_miptree_make_shareable(brw, irb->mt);
Brian Paul4fdac652012-09-01 07:47:24 -0600450 image = calloc(1, sizeof *image);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500451 if (image == NULL)
452 return NULL;
453
454 image->internal_format = rb->InternalFormat;
455 image->format = rb->Format;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400456 image->offset = 0;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500457 image->data = loaderPrivate;
Eric Anholte3a9ca42014-04-25 12:14:34 -0700458 drm_intel_bo_unreference(image->bo);
Eric Anholte16c5c92014-04-25 13:29:41 -0700459 image->bo = irb->mt->bo;
460 drm_intel_bo_reference(irb->mt->bo);
461 image->width = rb->Width;
462 image->height = rb->Height;
463 image->pitch = irb->mt->pitch;
Keith Packard1f085ba2013-11-04 17:33:34 -0800464 image->dri_format = driGLFormatToImageFormat(image->format);
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200465 image->has_depthstencil = irb->mt->stencil_mt? true : false;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500466
Eric Anholtc810e672013-05-10 12:36:43 -0700467 rb->NeedsFinishRenderTexture = true;
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200468 return image;
469}
470
471static __DRIimage *
472intel_create_image_from_texture(__DRIcontext *context, int target,
473 unsigned texture, int zoffset,
474 int level,
475 unsigned *error,
476 void *loaderPrivate)
477{
478 __DRIimage *image;
Kenneth Graunkeca437572013-07-02 23:17:14 -0700479 struct brw_context *brw = context->driverPrivate;
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200480 struct gl_texture_object *obj;
481 struct intel_texture_object *iobj;
482 GLuint face = 0;
483
Kenneth Graunke8c9a54e2013-07-06 00:46:38 -0700484 obj = _mesa_lookup_texture(&brw->ctx, texture);
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200485 if (!obj || obj->Target != target) {
486 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
487 return NULL;
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300488 }
489
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200490 if (target == GL_TEXTURE_CUBE_MAP)
491 face = zoffset;
492
Kenneth Graunke8c9a54e2013-07-06 00:46:38 -0700493 _mesa_test_texobj_completeness(&brw->ctx, obj);
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200494 iobj = intel_texture_object(obj);
495 if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
496 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
497 return NULL;
498 }
499
500 if (level < obj->BaseLevel || level > obj->_MaxLevel) {
501 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
502 return NULL;
503 }
504
505 if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
506 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
507 return NULL;
508 }
509 image = calloc(1, sizeof *image);
510 if (image == NULL) {
511 *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
512 return NULL;
513 }
514
515 image->internal_format = obj->Image[face][level]->InternalFormat;
516 image->format = obj->Image[face][level]->TexFormat;
517 image->data = loaderPrivate;
Kenneth Graunkeca437572013-07-02 23:17:14 -0700518 intel_setup_image_from_mipmap_tree(brw, image, iobj->mt, level, zoffset);
Keith Packard1f085ba2013-11-04 17:33:34 -0800519 image->dri_format = driGLFormatToImageFormat(image->format);
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200520 image->has_depthstencil = iobj->mt->stencil_mt? true : false;
521 if (image->dri_format == MESA_FORMAT_NONE) {
522 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
523 free(image);
524 return NULL;
525 }
526
527 *error = __DRI_IMAGE_ERROR_SUCCESS;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500528 return image;
529}
530
531static void
532intel_destroy_image(__DRIimage *image)
533{
Eric Anholte3a9ca42014-04-25 12:14:34 -0700534 drm_intel_bo_unreference(image->bo);
535 free(image);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500536}
537
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400538static __DRIimage *
539intel_create_image(__DRIscreen *screen,
540 int width, int height, int format,
541 unsigned int use,
542 void *loaderPrivate)
543{
544 __DRIimage *image;
George Sapountzis875a7572011-11-03 13:04:57 +0200545 struct intel_screen *intelScreen = screen->driverPrivate;
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400546 uint32_t tiling;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400547 int cpp;
Eric Anholte3a9ca42014-04-25 12:14:34 -0700548 unsigned long pitch;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400549
Daniel Stonee54b2e92016-05-02 15:34:40 +0100550 tiling = I915_TILING_X;
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400551 if (use & __DRI_IMAGE_USE_CURSOR) {
552 if (width != 64 || height != 64)
553 return NULL;
554 tiling = I915_TILING_NONE;
555 }
556
Axel Davye8f91952013-08-15 12:47:58 +0200557 if (use & __DRI_IMAGE_USE_LINEAR)
558 tiling = I915_TILING_NONE;
559
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400560 image = intel_allocate_image(format, loaderPrivate);
Anuj Phogat484b89a2013-04-16 10:34:43 -0700561 if (image == NULL)
562 return NULL;
563
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400564 cpp = _mesa_get_format_bytes(image->format);
Eric Anholte3a9ca42014-04-25 12:14:34 -0700565 image->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr, "image",
566 width, height, cpp, &tiling,
567 &pitch, 0);
568 if (image->bo == NULL) {
Brian Paulfe72a062012-09-01 07:47:24 -0600569 free(image);
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400570 return NULL;
571 }
Eric Anholte3a9ca42014-04-25 12:14:34 -0700572 image->width = width;
573 image->height = height;
574 image->pitch = pitch;
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200575
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400576 return image;
577}
578
579static GLboolean
580intel_query_image(__DRIimage *image, int attrib, int *value)
581{
582 switch (attrib) {
583 case __DRI_IMAGE_ATTRIB_STRIDE:
Eric Anholte3a9ca42014-04-25 12:14:34 -0700584 *value = image->pitch;
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700585 return true;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400586 case __DRI_IMAGE_ATTRIB_HANDLE:
Eric Anholte3a9ca42014-04-25 12:14:34 -0700587 *value = image->bo->handle;
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700588 return true;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400589 case __DRI_IMAGE_ATTRIB_NAME:
Eric Anholte3a9ca42014-04-25 12:14:34 -0700590 return !drm_intel_bo_flink(image->bo, (uint32_t *) value);
Jesse Barnes8de5c352012-02-21 12:53:09 -0800591 case __DRI_IMAGE_ATTRIB_FORMAT:
Ander Conselvan de Oliveirafc7d2242012-04-26 16:21:19 +0300592 *value = image->dri_format;
593 return true;
Kristian Høgsberg44f066b2012-07-13 11:19:24 -0400594 case __DRI_IMAGE_ATTRIB_WIDTH:
Eric Anholte3a9ca42014-04-25 12:14:34 -0700595 *value = image->width;
Kristian Høgsberg44f066b2012-07-13 11:19:24 -0400596 return true;
597 case __DRI_IMAGE_ATTRIB_HEIGHT:
Eric Anholte3a9ca42014-04-25 12:14:34 -0700598 *value = image->height;
Kristian Høgsberg44f066b2012-07-13 11:19:24 -0400599 return true;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200600 case __DRI_IMAGE_ATTRIB_COMPONENTS:
601 if (image->planar_format == NULL)
602 return false;
603 *value = image->planar_format->components;
604 return true;
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500605 case __DRI_IMAGE_ATTRIB_FD:
Eric Engestrom25327432016-08-15 15:51:20 +0100606 return !drm_intel_bo_gem_export_to_prime(image->bo, value);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000607 case __DRI_IMAGE_ATTRIB_FOURCC:
Eric Engestrom25327432016-08-15 15:51:20 +0100608 return intel_lookup_fourcc(image->dri_format, value);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000609 case __DRI_IMAGE_ATTRIB_NUM_PLANES:
610 *value = 1;
611 return true;
612
Kristian Høgsberg44f066b2012-07-13 11:19:24 -0400613 default:
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700614 return false;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400615 }
616}
617
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100618static __DRIimage *
619intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
620{
621 __DRIimage *image;
622
Brian Paul4fdac652012-09-01 07:47:24 -0600623 image = calloc(1, sizeof *image);
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100624 if (image == NULL)
625 return NULL;
626
Eric Anholte3a9ca42014-04-25 12:14:34 -0700627 drm_intel_bo_reference(orig_image->bo);
628 image->bo = orig_image->bo;
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100629 image->internal_format = orig_image->internal_format;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200630 image->planar_format = orig_image->planar_format;
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300631 image->dri_format = orig_image->dri_format;
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100632 image->format = orig_image->format;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400633 image->offset = orig_image->offset;
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200634 image->width = orig_image->width;
635 image->height = orig_image->height;
Eric Anholte3a9ca42014-04-25 12:14:34 -0700636 image->pitch = orig_image->pitch;
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200637 image->tile_x = orig_image->tile_x;
638 image->tile_y = orig_image->tile_y;
639 image->has_depthstencil = orig_image->has_depthstencil;
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100640 image->data = loaderPrivate;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200641
642 memcpy(image->strides, orig_image->strides, sizeof(image->strides));
643 memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
644
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100645 return image;
646}
647
Kristian Høgsberg221c6782012-01-18 15:32:35 -0500648static GLboolean
649intel_validate_usage(__DRIimage *image, unsigned int use)
650{
651 if (use & __DRI_IMAGE_USE_CURSOR) {
Eric Anholte3a9ca42014-04-25 12:14:34 -0700652 if (image->width != 64 || image->height != 64)
Kristian Høgsberg221c6782012-01-18 15:32:35 -0500653 return GL_FALSE;
654 }
655
656 return GL_TRUE;
657}
658
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400659static __DRIimage *
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200660intel_create_image_from_names(__DRIscreen *screen,
661 int width, int height, int fourcc,
662 int *names, int num_names,
663 int *strides, int *offsets,
664 void *loaderPrivate)
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400665{
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200666 struct intel_image_format *f = NULL;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400667 __DRIimage *image;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200668 int i, index;
669
670 if (screen == NULL || names == NULL || num_names != 1)
671 return NULL;
672
Topi Pohjolainen904587a2012-12-28 12:22:54 +0200673 f = intel_image_format_lookup(fourcc);
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200674 if (f == NULL)
675 return NULL;
676
677 image = intel_create_image_from_name(screen, width, height,
678 __DRI_IMAGE_FORMAT_NONE,
679 names[0], strides[0],
680 loaderPrivate);
681
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500682 if (image == NULL)
683 return NULL;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200684
685 image->planar_format = f;
686 for (i = 0; i < f->nplanes; i++) {
687 index = f->planes[i].buffer_index;
688 image->offsets[index] = offsets[index];
689 image->strides[index] = strides[index];
690 }
691
692 return image;
693}
694
695static __DRIimage *
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500696intel_create_image_from_fds(__DRIscreen *screen,
697 int width, int height, int fourcc,
698 int *fds, int num_fds, int *strides, int *offsets,
699 void *loaderPrivate)
700{
701 struct intel_screen *intelScreen = screen->driverPrivate;
Topi Pohjolainen904587a2012-12-28 12:22:54 +0200702 struct intel_image_format *f;
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500703 __DRIimage *image;
704 int i, index;
705
Kristian Høgsberg Kristensen1be11142016-05-01 21:25:35 -0700706 if (fds == NULL || num_fds < 1)
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500707 return NULL;
708
Kristian Høgsberg Kristensen1be11142016-05-01 21:25:35 -0700709 /* We only support all planes from the same bo */
710 for (i = 0; i < num_fds; i++)
711 if (fds[0] != fds[i])
712 return NULL;
713
Topi Pohjolainen904587a2012-12-28 12:22:54 +0200714 f = intel_image_format_lookup(fourcc);
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500715 if (f == NULL)
716 return NULL;
717
Topi Pohjolainene8568a02013-04-25 14:33:09 +0300718 if (f->nplanes == 1)
719 image = intel_allocate_image(f->planes[0].dri_format, loaderPrivate);
720 else
721 image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
722
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500723 if (image == NULL)
724 return NULL;
725
Eric Anholte3a9ca42014-04-25 12:14:34 -0700726 image->width = width;
727 image->height = height;
728 image->pitch = strides[0];
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500729
730 image->planar_format = f;
Kristian Høgsberg Kristensen1be11142016-05-01 21:25:35 -0700731 int size = 0;
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500732 for (i = 0; i < f->nplanes; i++) {
733 index = f->planes[i].buffer_index;
734 image->offsets[index] = offsets[index];
735 image->strides[index] = strides[index];
Kristian Høgsberg Kristensen1be11142016-05-01 21:25:35 -0700736
Kristian Høgsberg Kristensen89bb4be2016-05-25 09:30:26 -0700737 const int plane_height = height >> f->planes[i].height_shift;
738 const int end = offsets[index] + plane_height * strides[index];
Kristian Høgsberg Kristensen1be11142016-05-01 21:25:35 -0700739 if (size < end)
740 size = end;
741 }
742
743 image->bo = drm_intel_bo_gem_create_from_prime(intelScreen->bufmgr,
744 fds[0], size);
745 if (image->bo == NULL) {
746 free(image);
747 return NULL;
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500748 }
749
Gwenole Beauchesne3bd65dc2014-03-10 16:55:21 +0100750 if (f->nplanes == 1) {
751 image->offset = image->offsets[0];
Marius Predut28d9e902015-04-07 22:05:28 +0300752 intel_image_warn_if_unaligned(image, __func__);
Gwenole Beauchesne3bd65dc2014-03-10 16:55:21 +0100753 }
754
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500755 return image;
756}
757
Topi Pohjolainen674dedc2013-03-26 15:14:20 +0200758static __DRIimage *
759intel_create_image_from_dma_bufs(__DRIscreen *screen,
760 int width, int height, int fourcc,
761 int *fds, int num_fds,
762 int *strides, int *offsets,
763 enum __DRIYUVColorSpace yuv_color_space,
764 enum __DRISampleRange sample_range,
765 enum __DRIChromaSiting horizontal_siting,
766 enum __DRIChromaSiting vertical_siting,
767 unsigned *error,
768 void *loaderPrivate)
769{
770 __DRIimage *image;
771 struct intel_image_format *f = intel_image_format_lookup(fourcc);
772
Kristian Høgsberg Kristensen1be11142016-05-01 21:25:35 -0700773 if (!f) {
Topi Pohjolainen674dedc2013-03-26 15:14:20 +0200774 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
775 return NULL;
776 }
777
778 image = intel_create_image_from_fds(screen, width, height, fourcc, fds,
779 num_fds, strides, offsets,
780 loaderPrivate);
781
782 /*
783 * Invalid parameters and any inconsistencies between are assumed to be
784 * checked by the caller. Therefore besides unsupported formats one can fail
785 * only in allocation.
786 */
787 if (!image) {
788 *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
789 return NULL;
790 }
791
Topi Pohjolainen3a52cd32013-06-18 13:47:43 +0300792 image->dma_buf_imported = true;
Topi Pohjolainen674dedc2013-03-26 15:14:20 +0200793 image->yuv_color_space = yuv_color_space;
794 image->sample_range = sample_range;
795 image->horizontal_siting = horizontal_siting;
796 image->vertical_siting = vertical_siting;
797
798 *error = __DRI_IMAGE_ERROR_SUCCESS;
799 return image;
800}
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500801
802static __DRIimage *
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200803intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
804{
Eric Anholt60894ed2013-01-10 15:11:28 -0800805 int width, height, offset, stride, dri_format, index;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200806 struct intel_image_format *f;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200807 __DRIimage *image;
808
809 if (parent == NULL || parent->planar_format == NULL)
810 return NULL;
811
812 f = parent->planar_format;
813
814 if (plane >= f->nplanes)
815 return NULL;
816
Eric Anholte3a9ca42014-04-25 12:14:34 -0700817 width = parent->width >> f->planes[plane].width_shift;
818 height = parent->height >> f->planes[plane].height_shift;
Jakob Bornecrantz6a7dea92012-08-31 19:48:26 +0200819 dri_format = f->planes[plane].dri_format;
820 index = f->planes[plane].buffer_index;
821 offset = parent->offsets[index];
822 stride = parent->strides[index];
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400823
824 image = intel_allocate_image(dri_format, loaderPrivate);
Anuj Phogat484b89a2013-04-16 10:34:43 -0700825 if (image == NULL)
826 return NULL;
827
Eric Anholte3a9ca42014-04-25 12:14:34 -0700828 if (offset + height * stride > parent->bo->size) {
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400829 _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
Brian Paulfe72a062012-09-01 07:47:24 -0600830 free(image);
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400831 return NULL;
832 }
833
Eric Anholte3a9ca42014-04-25 12:14:34 -0700834 image->bo = parent->bo;
835 drm_intel_bo_reference(parent->bo);
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400836
Eric Anholte3a9ca42014-04-25 12:14:34 -0700837 image->width = width;
838 image->height = height;
839 image->pitch = stride;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400840 image->offset = offset;
841
Marius Predut28d9e902015-04-07 22:05:28 +0300842 intel_image_warn_if_unaligned(image, __func__);
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400843
844 return image;
845}
846
Emil Velikov38f20f72014-02-12 17:47:53 +0000847static const __DRIimageExtension intelImageExtension = {
Dave Airlie8f7338f2014-03-03 13:57:16 +1000848 .base = { __DRI_IMAGE, 11 },
Chad Versacec9f51262012-11-19 11:43:51 -0800849
850 .createImageFromName = intel_create_image_from_name,
851 .createImageFromRenderbuffer = intel_create_image_from_renderbuffer,
852 .destroyImage = intel_destroy_image,
853 .createImage = intel_create_image,
854 .queryImage = intel_query_image,
855 .dupImage = intel_dup_image,
856 .validateUsage = intel_validate_usage,
857 .createImageFromNames = intel_create_image_from_names,
Abdiel Janulgue6c7e95c2012-11-28 13:30:18 +0200858 .fromPlanar = intel_from_planar,
Kristian Høgsberg2356e282013-02-02 08:38:07 -0500859 .createImageFromTexture = intel_create_image_from_texture,
Topi Pohjolainen674dedc2013-03-26 15:14:20 +0200860 .createImageFromFds = intel_create_image_from_fds,
Dave Airlie8f7338f2014-03-03 13:57:16 +1000861 .createImageFromDmaBufs = intel_create_image_from_dma_bufs,
862 .blitImage = NULL,
863 .getCapabilities = NULL
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500864};
865
Ian Romanick1e4ce082013-02-14 16:50:28 -0800866static int
Ian Romanicka15a19f2013-11-11 11:08:26 -0800867brw_query_renderer_integer(__DRIscreen *psp, int param, unsigned int *value)
Ian Romanick1e4ce082013-02-14 16:50:28 -0800868{
869 const struct intel_screen *const intelScreen =
870 (struct intel_screen *) psp->driverPrivate;
871
872 switch (param) {
873 case __DRI2_RENDERER_VENDOR_ID:
874 value[0] = 0x8086;
875 return 0;
876 case __DRI2_RENDERER_DEVICE_ID:
877 value[0] = intelScreen->deviceID;
878 return 0;
879 case __DRI2_RENDERER_ACCELERATED:
880 value[0] = 1;
881 return 0;
882 case __DRI2_RENDERER_VIDEO_MEMORY: {
883 /* Once a batch uses more than 75% of the maximum mappable size, we
884 * assume that there's some fragmentation, and we start doing extra
885 * flushing, etc. That's the big cliff apps will care about.
Ian Romanick1e4ce082013-02-14 16:50:28 -0800886 */
Ian Romanickcb6182b2013-11-11 10:57:55 -0800887 size_t aper_size;
888 size_t mappable_size;
889
890 drm_intel_get_aperture_sizes(psp->fd, &mappable_size, &aper_size);
891
892 const unsigned gpu_mappable_megabytes =
893 (aper_size / (1024 * 1024)) * 3 / 4;
Ian Romanick1e4ce082013-02-14 16:50:28 -0800894
895 const long system_memory_pages = sysconf(_SC_PHYS_PAGES);
896 const long system_page_size = sysconf(_SC_PAGE_SIZE);
897
898 if (system_memory_pages <= 0 || system_page_size <= 0)
899 return -1;
900
901 const uint64_t system_memory_bytes = (uint64_t) system_memory_pages
902 * (uint64_t) system_page_size;
903
904 const unsigned system_memory_megabytes =
Emil Velikovfc259562014-02-22 03:04:02 +0000905 (unsigned) (system_memory_bytes / (1024 * 1024));
Ian Romanick1e4ce082013-02-14 16:50:28 -0800906
907 value[0] = MIN2(system_memory_megabytes, gpu_mappable_megabytes);
908 return 0;
909 }
910 case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
911 value[0] = 1;
912 return 0;
Ian Romanick1e4ce082013-02-14 16:50:28 -0800913 default:
914 return driQueryRendererIntegerCommon(psp, param, value);
915 }
916
917 return -1;
918}
919
920static int
921brw_query_renderer_string(__DRIscreen *psp, int param, const char **value)
922{
923 const struct intel_screen *intelScreen =
924 (struct intel_screen *) psp->driverPrivate;
925
926 switch (param) {
927 case __DRI2_RENDERER_VENDOR_ID:
928 value[0] = brw_vendor_string;
929 return 0;
930 case __DRI2_RENDERER_DEVICE_ID:
Ben Widawskyd1ab5442016-02-08 12:42:29 -0800931 value[0] = brw_get_renderer_string(intelScreen);
Ian Romanick1e4ce082013-02-14 16:50:28 -0800932 return 0;
933 default:
934 break;
935 }
936
937 return -1;
938}
939
Emil Velikov38f20f72014-02-12 17:47:53 +0000940static const __DRI2rendererQueryExtension intelRendererQueryExtension = {
Ian Romanick1e4ce082013-02-14 16:50:28 -0800941 .base = { __DRI2_RENDERER_QUERY, 1 },
942
943 .queryInteger = brw_query_renderer_integer,
944 .queryString = brw_query_renderer_string
945};
946
Emil Velikov38f20f72014-02-12 17:47:53 +0000947static const __DRIrobustnessExtension dri2Robustness = {
948 .base = { __DRI2_ROBUSTNESS, 1 }
Ian Romanick1f712bd2012-09-11 11:08:44 +0300949};
950
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400951static const __DRIextension *intelScreenExtensions[] = {
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500952 &intelTexBufferExtension.base,
Chad Versacec6362842015-05-05 19:05:32 -0700953 &intelFenceExtension.base,
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500954 &intelFlushExtension.base,
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500955 &intelImageExtension.base,
Ian Romanick1e4ce082013-02-14 16:50:28 -0800956 &intelRendererQueryExtension.base,
Jesse Barnes234286c2010-04-22 12:47:41 -0700957 &dri2ConfigQueryExtension.base,
Ian Romanick9b1c6862013-11-19 17:01:23 -0800958 NULL
959};
960
961static const __DRIextension *intelRobustScreenExtensions[] = {
962 &intelTexBufferExtension.base,
Chad Versacec6362842015-05-05 19:05:32 -0700963 &intelFenceExtension.base,
Ian Romanick9b1c6862013-11-19 17:01:23 -0800964 &intelFlushExtension.base,
965 &intelImageExtension.base,
966 &intelRendererQueryExtension.base,
967 &dri2ConfigQueryExtension.base,
Ian Romanick1f712bd2012-09-11 11:08:44 +0300968 &dri2Robustness.base,
Kristian Høgsbergac3e8382007-05-15 15:17:30 -0400969 NULL
970};
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000971
Ben Widawskya8975a92016-04-11 09:49:41 -0700972static int
Chad Versace844e0bd2016-06-27 11:29:27 -0700973intel_get_param(struct intel_screen *screen, int param, int *value)
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500974{
Chad Versaced3a147b2016-06-27 11:33:36 -0700975 int ret = 0;
Alan Hourihane1c718c02008-02-22 00:18:54 +0000976 struct drm_i915_getparam gp;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500977
Eric Anholtf33d1002012-02-16 11:30:49 -0800978 memset(&gp, 0, sizeof(gp));
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500979 gp.param = param;
980 gp.value = value;
981
Chad Versaced3a147b2016-06-27 11:33:36 -0700982 if (drmIoctl(screen->driScrnPriv->fd, DRM_IOCTL_I915_GETPARAM, &gp) == -1) {
983 ret = -errno;
984 if (ret != -EINVAL)
985 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
986 }
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500987
Ben Widawskya8975a92016-04-11 09:49:41 -0700988 return ret;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500989}
Kristian Høgsbergac3e8382007-05-15 15:17:30 -0400990
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700991static bool
Chad Versace844e0bd2016-06-27 11:29:27 -0700992intel_get_boolean(struct intel_screen *screen, int param)
Chris Wilson900a5c92011-03-01 14:46:50 +0000993{
994 int value = 0;
Chad Versace844e0bd2016-06-27 11:29:27 -0700995 return (intel_get_param(screen, param, &value) == 0) && value;
Chris Wilson900a5c92011-03-01 14:46:50 +0000996}
997
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000998static void
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500999intelDestroyScreen(__DRIscreen * sPriv)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001000{
George Sapountzis875a7572011-11-03 13:04:57 +02001001 struct intel_screen *intelScreen = sPriv->driverPrivate;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001002
Eric Anholt904f31a2008-09-16 17:01:06 -07001003 dri_bufmgr_destroy(intelScreen->bufmgr);
Eric Anholt6d66f232009-07-02 13:30:20 -07001004 driDestroyOptionInfo(&intelScreen->optionCache);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001005
Kenneth Graunkeb3e4b762014-03-17 13:57:14 -07001006 ralloc_free(intelScreen);
George Sapountzis875a7572011-11-03 13:04:57 +02001007 sPriv->driverPrivate = NULL;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001008}
1009
1010
1011/**
1012 * This is called when we need to set up GL rendering to a new X window.
1013 */
1014static GLboolean
Kristian Høgsbergd61f0732010-01-01 17:09:12 -05001015intelCreateBuffer(__DRIscreen * driScrnPriv,
1016 __DRIdrawable * driDrawPriv,
Kristian Høgsbergd3491e72010-10-12 11:58:47 -04001017 const struct gl_config * mesaVis, GLboolean isPixmap)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001018{
Kristian Høgsbergd2821282010-01-01 23:21:16 -05001019 struct intel_renderbuffer *rb;
George Sapountzis875a7572011-11-03 13:04:57 +02001020 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
Mark Mueller71fe9432014-01-04 14:11:43 -08001021 mesa_format rgbFormat;
Chad Versacee2f23762012-07-11 15:10:49 -07001022 unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -07001023 struct gl_framebuffer *fb;
Kristian Høgsbergd2821282010-01-01 23:21:16 -05001024
Chad Versace2b4fbc42012-07-09 16:51:23 -07001025 if (isPixmap)
1026 return false;
1027
1028 fb = CALLOC_STRUCT(gl_framebuffer);
1029 if (!fb)
1030 return false;
1031
1032 _mesa_initialize_window_framebuffer(fb, mesaVis);
1033
Eric Anholt41033502014-03-21 16:36:22 -07001034 if (screen->winsys_msaa_samples_override != -1) {
1035 num_samples = screen->winsys_msaa_samples_override;
1036 fb->Visual.samples = num_samples;
1037 }
1038
Haixia Shi35ade362016-04-07 11:05:09 -07001039 if (mesaVis->redBits == 5) {
1040 rgbFormat = mesaVis->redMask == 0x1f ? MESA_FORMAT_R5G6B5_UNORM
1041 : MESA_FORMAT_B5G6R5_UNORM;
1042 } else if (mesaVis->sRGBCapable) {
1043 rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8A8_SRGB
1044 : MESA_FORMAT_B8G8R8A8_SRGB;
1045 } else if (mesaVis->alphaBits == 0) {
1046 rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8X8_UNORM
1047 : MESA_FORMAT_B8G8R8X8_UNORM;
1048 } else {
1049 rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8A8_SRGB
1050 : MESA_FORMAT_B8G8R8A8_SRGB;
Eric Anholt6fddd372013-06-20 16:10:43 -07001051 fb->Visual.sRGBCapable = true;
Eric Anholte15c21a2013-02-15 07:41:42 -08001052 }
Chad Versace2b4fbc42012-07-09 16:51:23 -07001053
1054 /* setup the hardware-based renderbuffers */
Chad Versacee2f23762012-07-11 15:10:49 -07001055 rb = intel_create_renderbuffer(rgbFormat, num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -07001056 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
1057
1058 if (mesaVis->doubleBufferMode) {
Chad Versacee2f23762012-07-11 15:10:49 -07001059 rb = intel_create_renderbuffer(rgbFormat, num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -07001060 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
1061 }
1062
1063 /*
1064 * Assert here that the gl_config has an expected depth/stencil bit
1065 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
1066 * which constructs the advertised configs.)
1067 */
1068 if (mesaVis->depthBits == 24) {
1069 assert(mesaVis->stencilBits == 8);
1070
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001071 if (screen->devinfo->has_hiz_and_separate_stencil) {
Kenneth Graunkea487ef82014-02-07 21:53:18 -08001072 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT,
Chad Versacee2f23762012-07-11 15:10:49 -07001073 num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -07001074 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
Mark Mueller50a01d22014-01-20 19:08:54 -08001075 rb = intel_create_private_renderbuffer(MESA_FORMAT_S_UINT8,
Chad Versacee2f23762012-07-11 15:10:49 -07001076 num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -07001077 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
1078 } else {
1079 /*
1080 * Use combined depth/stencil. Note that the renderbuffer is
1081 * attached to two attachment points.
1082 */
Kenneth Graunkea487ef82014-02-07 21:53:18 -08001083 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT,
Chad Versacee2f23762012-07-11 15:10:49 -07001084 num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -07001085 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
1086 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
1087 }
1088 }
1089 else if (mesaVis->depthBits == 16) {
1090 assert(mesaVis->stencilBits == 0);
Mark Mueller50a01d22014-01-20 19:08:54 -08001091 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z_UNORM16,
Chad Versacee2f23762012-07-11 15:10:49 -07001092 num_samples);
Chad Versace8c94f6b2012-07-09 17:01:29 -07001093 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001094 }
1095 else {
Chad Versace2b4fbc42012-07-09 16:51:23 -07001096 assert(mesaVis->depthBits == 0);
1097 assert(mesaVis->stencilBits == 0);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001098 }
Chad Versace2b4fbc42012-07-09 16:51:23 -07001099
1100 /* now add any/all software-based renderbuffers we may need */
1101 _swrast_add_soft_renderbuffers(fb,
1102 false, /* never sw color */
1103 false, /* never sw depth */
1104 false, /* never sw stencil */
1105 mesaVis->accumRedBits > 0,
1106 false, /* never sw alpha */
1107 false /* never sw aux */ );
1108 driDrawPriv->driverPrivate = fb;
1109
1110 return true;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001111}
1112
1113static void
Kristian Høgsbergd61f0732010-01-01 17:09:12 -05001114intelDestroyBuffer(__DRIdrawable * driDrawPriv)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001115{
Kristian Høgsbergd2821282010-01-01 23:21:16 -05001116 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
Kenneth Graunkea7bdd4c2013-11-25 15:46:34 -08001117
Kristian Høgsbergd2821282010-01-01 23:21:16 -05001118 _mesa_reference_framebuffer(&fb, NULL);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001119}
1120
Ben Widawsky4213b002016-04-07 10:53:12 -07001121static void
1122intel_detect_sseu(struct intel_screen *intelScreen)
1123{
Ben Widawskycc01b632016-04-07 10:53:13 -07001124 assert(intelScreen->devinfo->gen >= 8);
1125 int ret;
1126
Ben Widawsky4213b002016-04-07 10:53:12 -07001127 intelScreen->subslice_total = -1;
1128 intelScreen->eu_total = -1;
1129
Chad Versace844e0bd2016-06-27 11:29:27 -07001130 ret = intel_get_param(intelScreen, I915_PARAM_SUBSLICE_TOTAL,
Ben Widawskycc01b632016-04-07 10:53:13 -07001131 &intelScreen->subslice_total);
Ben Widawskya8975a92016-04-11 09:49:41 -07001132 if (ret < 0 && ret != -EINVAL)
Ben Widawskycc01b632016-04-07 10:53:13 -07001133 goto err_out;
1134
Chad Versace844e0bd2016-06-27 11:29:27 -07001135 ret = intel_get_param(intelScreen,
Ben Widawskycc01b632016-04-07 10:53:13 -07001136 I915_PARAM_EU_TOTAL, &intelScreen->eu_total);
Ben Widawskya8975a92016-04-11 09:49:41 -07001137 if (ret < 0 && ret != -EINVAL)
Ben Widawskycc01b632016-04-07 10:53:13 -07001138 goto err_out;
Ben Widawsky4213b002016-04-07 10:53:12 -07001139
1140 /* Without this information, we cannot get the right Braswell brandstrings,
1141 * and we have to use conservative numbers for GPGPU on many platforms, but
1142 * otherwise, things will just work.
1143 */
Ben Widawskye5295b52016-04-07 10:53:14 -07001144 if (intelScreen->subslice_total < 1 || intelScreen->eu_total < 1)
Ben Widawsky4213b002016-04-07 10:53:12 -07001145 _mesa_warning(NULL,
1146 "Kernel 4.1 required to properly query GPU properties.\n");
Ben Widawskycc01b632016-04-07 10:53:13 -07001147
1148 return;
1149
1150err_out:
1151 intelScreen->subslice_total = -1;
1152 intelScreen->eu_total = -1;
Mark Janesa2d28dd2016-05-19 13:42:16 -07001153 _mesa_warning(NULL, "Failed to query GPU properties (%s).\n", strerror(-ret));
Ben Widawsky4213b002016-04-07 10:53:12 -07001154}
1155
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -07001156static bool
Kristian Høgsberg5777dee2010-02-11 16:44:21 -05001157intel_init_bufmgr(struct intel_screen *intelScreen)
Eric Anholt7e0bbdc2008-09-04 22:16:31 +01001158{
Kristian Høgsbergd61f0732010-01-01 17:09:12 -05001159 __DRIscreen *spriv = intelScreen->driScrnPriv;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +01001160
Eric Anholt2222aa02012-03-09 16:27:35 -08001161 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +01001162
Eric Anholt827ba442009-11-18 18:15:25 +01001163 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
Eric Anholt7e0bbdc2008-09-04 22:16:31 +01001164 if (intelScreen->bufmgr == NULL) {
Eric Anholt827ba442009-11-18 18:15:25 +01001165 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
1166 __func__, __LINE__);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -07001167 return false;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +01001168 }
1169
Eric Anholt06d14722010-03-02 18:04:40 -08001170 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
1171
Chad Versace844e0bd2016-06-27 11:29:27 -07001172 if (!intel_get_boolean(intelScreen, I915_PARAM_HAS_RELAXED_DELTA)) {
Kenneth Graunke394edb52013-04-05 23:59:52 -07001173 fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
1174 return false;
1175 }
Chris Wilson900a5c92011-03-01 14:46:50 +00001176
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -07001177 return true;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +01001178}
1179
Daniel Vetterf172eae2012-03-02 21:38:44 +01001180static bool
1181intel_detect_swizzling(struct intel_screen *screen)
1182{
1183 drm_intel_bo *buffer;
1184 unsigned long flags = 0;
1185 unsigned long aligned_pitch;
Daniel Stonee54b2e92016-05-02 15:34:40 +01001186 uint32_t tiling = I915_TILING_X;
Daniel Vetterf172eae2012-03-02 21:38:44 +01001187 uint32_t swizzle_mode = 0;
1188
1189 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
1190 64, 64, 4,
1191 &tiling, &aligned_pitch, flags);
1192 if (buffer == NULL)
1193 return false;
1194
1195 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
1196 drm_intel_bo_unreference(buffer);
1197
1198 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
1199 return false;
1200 else
1201 return true;
1202}
1203
Chris Wilson013d7312015-07-21 11:12:57 +01001204static int
Chris Wilsonc8d3eba2015-04-29 13:32:38 +01001205intel_detect_timestamp(struct intel_screen *screen)
1206{
Chris Wilson013d7312015-07-21 11:12:57 +01001207 uint64_t dummy = 0, last = 0;
1208 int upper, lower, loops;
Chris Wilsonc8d3eba2015-04-29 13:32:38 +01001209
Chris Wilson013d7312015-07-21 11:12:57 +01001210 /* On 64bit systems, some old kernels trigger a hw bug resulting in the
1211 * TIMESTAMP register being shifted and the low 32bits always zero.
1212 *
1213 * More recent kernels offer an interface to read the full 36bits
1214 * everywhere.
Chris Wilsonc8d3eba2015-04-29 13:32:38 +01001215 */
Chris Wilson013d7312015-07-21 11:12:57 +01001216 if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP | 1, &dummy) == 0)
1217 return 3;
Chris Wilsonc8d3eba2015-04-29 13:32:38 +01001218
Chris Wilson013d7312015-07-21 11:12:57 +01001219 /* Determine if we have a 32bit or 64bit kernel by inspecting the
1220 * upper 32bits for a rapidly changing timestamp.
1221 */
1222 if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP, &last))
1223 return 0;
1224
1225 upper = lower = 0;
1226 for (loops = 0; loops < 10; loops++) {
1227 /* The TIMESTAMP should change every 80ns, so several round trips
1228 * through the kernel should be enough to advance it.
1229 */
1230 if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP, &dummy))
1231 return 0;
1232
1233 upper += (dummy >> 32) != (last >> 32);
1234 if (upper > 1) /* beware 32bit counter overflow */
1235 return 2; /* upper dword holds the low 32bits of the timestamp */
1236
1237 lower += (dummy & 0xffffffff) != (last & 0xffffffff);
1238 if (lower > 1)
1239 return 1; /* timestamp is unshifted */
1240
1241 last = dummy;
1242 }
1243
1244 /* No advancement? No timestamp! */
1245 return 0;
Chris Wilsonc8d3eba2015-04-29 13:32:38 +01001246}
1247
Chad Versace95ebabb2013-11-06 19:40:25 -08001248/**
1249 * Return array of MSAA modes supported by the hardware. The array is
1250 * zero-terminated and sorted in decreasing order.
1251 */
1252const int*
1253intel_supported_msaa_modes(const struct intel_screen *screen)
1254{
Neil Roberts6c5f3712015-09-07 18:23:14 +01001255 static const int gen9_modes[] = {16, 8, 4, 2, 0, -1};
Kenneth Graunke57405602014-02-10 11:42:47 -08001256 static const int gen8_modes[] = {8, 4, 2, 0, -1};
Chad Versace95ebabb2013-11-06 19:40:25 -08001257 static const int gen7_modes[] = {8, 4, 0, -1};
1258 static const int gen6_modes[] = {4, 0, -1};
1259 static const int gen4_modes[] = {0, -1};
1260
Neil Roberts6c5f3712015-09-07 18:23:14 +01001261 if (screen->devinfo->gen >= 9) {
1262 return gen9_modes;
1263 } else if (screen->devinfo->gen >= 8) {
Kenneth Graunke57405602014-02-10 11:42:47 -08001264 return gen8_modes;
1265 } else if (screen->devinfo->gen >= 7) {
Chad Versace95ebabb2013-11-06 19:40:25 -08001266 return gen7_modes;
1267 } else if (screen->devinfo->gen == 6) {
1268 return gen6_modes;
1269 } else {
1270 return gen4_modes;
1271 }
1272}
1273
Chad Versaceb2d428c2012-07-12 14:17:22 -07001274static __DRIconfig**
1275intel_screen_make_configs(__DRIscreen *dri_screen)
1276{
Mark Mueller71fe9432014-01-04 14:11:43 -08001277 static const mesa_format formats[] = {
Mark Muellereeed49f2014-01-26 15:12:56 -08001278 MESA_FORMAT_B5G6R5_UNORM,
Boyan Ding28090b32015-03-25 19:36:54 +08001279 MESA_FORMAT_B8G8R8A8_UNORM,
1280 MESA_FORMAT_B8G8R8X8_UNORM
Ian Romanick1f6e10f2012-07-12 13:52:06 -07001281 };
1282
Chad Versace7dc0be82012-08-09 09:06:42 -07001283 /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
Chad Versaceb2d428c2012-07-12 14:17:22 -07001284 static const GLenum back_buffer_modes[] = {
Chad Versace7dc0be82012-08-09 09:06:42 -07001285 GLX_SWAP_UNDEFINED_OML, GLX_NONE,
Chad Versaceb2d428c2012-07-12 14:17:22 -07001286 };
1287
Chad Versace8b5d68d2012-08-02 14:51:47 -07001288 static const uint8_t singlesample_samples[1] = {0};
Chad Versacee943e5c2012-08-02 17:13:17 -07001289 static const uint8_t multisample_samples[2] = {4, 8};
Chad Versace8b5d68d2012-08-02 14:51:47 -07001290
Chad Versacee943e5c2012-08-02 17:13:17 -07001291 struct intel_screen *screen = dri_screen->driverPrivate;
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001292 const struct brw_device_info *devinfo = screen->devinfo;
Chad Versace8b5d68d2012-08-02 14:51:47 -07001293 uint8_t depth_bits[4], stencil_bits[4];
Chad Versaceb2d428c2012-07-12 14:17:22 -07001294 __DRIconfig **configs = NULL;
1295
Chad Versacee943e5c2012-08-02 17:13:17 -07001296 /* Generate singlesample configs without accumulation buffer. */
Rhys Kiddf4ef8d02015-08-06 16:34:03 +10001297 for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
Chad Versaceb2d428c2012-07-12 14:17:22 -07001298 __DRIconfig **new_configs;
Tapani Pällie4e3b072012-10-29 11:56:28 -07001299 int num_depth_stencil_bits = 2;
Chad Versaceb2d428c2012-07-12 14:17:22 -07001300
1301 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
1302 * buffer that has a different number of bits per pixel than the color
Tapani Pällie4e3b072012-10-29 11:56:28 -07001303 * buffer, gen >= 6 supports this.
Chad Versaceb2d428c2012-07-12 14:17:22 -07001304 */
Chad Versace8b5d68d2012-08-02 14:51:47 -07001305 depth_bits[0] = 0;
1306 stencil_bits[0] = 0;
1307
Mark Muellereeed49f2014-01-26 15:12:56 -08001308 if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
Chad Versaceb2d428c2012-07-12 14:17:22 -07001309 depth_bits[1] = 16;
1310 stencil_bits[1] = 0;
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001311 if (devinfo->gen >= 6) {
Tapani Pällie4e3b072012-10-29 11:56:28 -07001312 depth_bits[2] = 24;
1313 stencil_bits[2] = 8;
1314 num_depth_stencil_bits = 3;
1315 }
Chad Versaceb2d428c2012-07-12 14:17:22 -07001316 } else {
1317 depth_bits[1] = 24;
1318 stencil_bits[1] = 8;
1319 }
1320
Ian Romanick1f6e10f2012-07-12 13:52:06 -07001321 new_configs = driCreateConfigs(formats[i],
Chad Versaceb2d428c2012-07-12 14:17:22 -07001322 depth_bits,
1323 stencil_bits,
Chad Versace8b5d68d2012-08-02 14:51:47 -07001324 num_depth_stencil_bits,
Chad Versace7dc0be82012-08-09 09:06:42 -07001325 back_buffer_modes, 2,
Chad Versace8b5d68d2012-08-02 14:51:47 -07001326 singlesample_samples, 1,
Ilia Mirkin52839002016-08-20 16:10:20 -04001327 false, false);
Chad Versacea4bf68c2012-08-01 21:23:47 -07001328 configs = driConcatConfigs(configs, new_configs);
Chad Versaceb2d428c2012-07-12 14:17:22 -07001329 }
1330
1331 /* Generate the minimum possible set of configs that include an
1332 * accumulation buffer.
1333 */
Rhys Kiddf4ef8d02015-08-06 16:34:03 +10001334 for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
Chad Versaceb2d428c2012-07-12 14:17:22 -07001335 __DRIconfig **new_configs;
1336
Mark Muellereeed49f2014-01-26 15:12:56 -08001337 if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
Chad Versaceb2d428c2012-07-12 14:17:22 -07001338 depth_bits[0] = 16;
1339 stencil_bits[0] = 0;
1340 } else {
1341 depth_bits[0] = 24;
1342 stencil_bits[0] = 8;
1343 }
1344
Ian Romanick1f6e10f2012-07-12 13:52:06 -07001345 new_configs = driCreateConfigs(formats[i],
Chad Versaceb2d428c2012-07-12 14:17:22 -07001346 depth_bits, stencil_bits, 1,
Chad Versace7dc0be82012-08-09 09:06:42 -07001347 back_buffer_modes, 1,
Chad Versace8b5d68d2012-08-02 14:51:47 -07001348 singlesample_samples, 1,
Ilia Mirkin52839002016-08-20 16:10:20 -04001349 true, false);
Chad Versacea4bf68c2012-08-01 21:23:47 -07001350 configs = driConcatConfigs(configs, new_configs);
Chad Versaceb2d428c2012-07-12 14:17:22 -07001351 }
1352
Chad Versacee943e5c2012-08-02 17:13:17 -07001353 /* Generate multisample configs.
1354 *
1355 * This loop breaks early, and hence is a no-op, on gen < 6.
1356 *
1357 * Multisample configs must follow the singlesample configs in order to
1358 * work around an X server bug present in 1.12. The X server chooses to
1359 * associate the first listed RGBA888-Z24S8 config, regardless of its
1360 * sample count, with the 32-bit depth visual used for compositing.
1361 *
1362 * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
1363 * supported. Singlebuffer configs are not supported because no one wants
Chad Versace7dc0be82012-08-09 09:06:42 -07001364 * them.
Chad Versacee943e5c2012-08-02 17:13:17 -07001365 */
Rhys Kiddf4ef8d02015-08-06 16:34:03 +10001366 for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001367 if (devinfo->gen < 6)
Chad Versacee943e5c2012-08-02 17:13:17 -07001368 break;
1369
1370 __DRIconfig **new_configs;
1371 const int num_depth_stencil_bits = 2;
Eric Anholt3aaeb3e2012-08-07 11:33:10 -07001372 int num_msaa_modes = 0;
Chad Versacee943e5c2012-08-02 17:13:17 -07001373
1374 depth_bits[0] = 0;
1375 stencil_bits[0] = 0;
1376
Mark Muellereeed49f2014-01-26 15:12:56 -08001377 if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
Chad Versacee943e5c2012-08-02 17:13:17 -07001378 depth_bits[1] = 16;
1379 stencil_bits[1] = 0;
1380 } else {
1381 depth_bits[1] = 24;
1382 stencil_bits[1] = 8;
1383 }
1384
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001385 if (devinfo->gen >= 7)
Chad Versacee943e5c2012-08-02 17:13:17 -07001386 num_msaa_modes = 2;
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001387 else if (devinfo->gen == 6)
Chad Versacee943e5c2012-08-02 17:13:17 -07001388 num_msaa_modes = 1;
1389
Ian Romanick1f6e10f2012-07-12 13:52:06 -07001390 new_configs = driCreateConfigs(formats[i],
Chad Versacee943e5c2012-08-02 17:13:17 -07001391 depth_bits,
1392 stencil_bits,
1393 num_depth_stencil_bits,
Chad Versace7dc0be82012-08-09 09:06:42 -07001394 back_buffer_modes, 1,
Chad Versacee943e5c2012-08-02 17:13:17 -07001395 multisample_samples,
1396 num_msaa_modes,
Ilia Mirkin52839002016-08-20 16:10:20 -04001397 false, false);
Chad Versacee943e5c2012-08-02 17:13:17 -07001398 configs = driConcatConfigs(configs, new_configs);
1399 }
1400
Chad Versaceb2d428c2012-07-12 14:17:22 -07001401 if (configs == NULL) {
1402 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
1403 __LINE__);
1404 return NULL;
1405 }
1406
1407 return configs;
1408}
1409
Chad Versace4945086f32012-11-21 15:08:27 -08001410static void
1411set_max_gl_versions(struct intel_screen *screen)
1412{
Eric Anholt083f66f2013-09-26 12:01:56 -07001413 __DRIscreen *psp = screen->driScrnPriv;
Jordan Justenfde59a22013-02-21 16:59:33 -08001414
Kenneth Graunkeafe05e72013-07-04 12:35:22 -07001415 switch (screen->devinfo->gen) {
Jordan Justene8137282014-04-20 17:31:30 -07001416 case 9:
Kenneth Graunke232140a2013-11-01 11:45:47 -07001417 case 8:
Timothy Arcerib463b1d2016-07-21 11:53:14 +10001418 psp->max_gl_core_version = 44;
Jordan Justene97b2072015-12-15 15:53:20 -08001419 psp->max_gl_compat_version = 30;
1420 psp->max_gl_es1_version = 11;
1421 psp->max_gl_es2_version = 31;
1422 break;
Chad Versace4945086f32012-11-21 15:08:27 -08001423 case 7:
Chad Versace4945086f32012-11-21 15:08:27 -08001424 case 6:
Chris Forbesc4ed6c72014-09-20 10:39:37 +12001425 psp->max_gl_core_version = 33;
Eric Anholt083f66f2013-09-26 12:01:56 -07001426 psp->max_gl_compat_version = 30;
1427 psp->max_gl_es1_version = 11;
1428 psp->max_gl_es2_version = 30;
Chad Versace4945086f32012-11-21 15:08:27 -08001429 break;
1430 case 5:
1431 case 4:
Eric Anholt083f66f2013-09-26 12:01:56 -07001432 psp->max_gl_core_version = 0;
1433 psp->max_gl_compat_version = 21;
1434 psp->max_gl_es1_version = 11;
1435 psp->max_gl_es2_version = 20;
Chad Versace4945086f32012-11-21 15:08:27 -08001436 break;
Chad Versace4945086f32012-11-21 15:08:27 -08001437 default:
Matt Turner3d826722014-06-29 14:54:01 -07001438 unreachable("unrecognized intel_screen::gen");
Chad Versace4945086f32012-11-21 15:08:27 -08001439 }
Chad Versace4945086f32012-11-21 15:08:27 -08001440}
1441
Ben Widawsky9ecfc6b2015-10-23 14:38:39 -07001442/**
1443 * Return the revision (generally the revid field of the PCI header) of the
1444 * graphics device.
1445 *
1446 * XXX: This function is useful to keep around even if it is not currently in
1447 * use. It is necessary for new platforms and revision specific workarounds or
1448 * features. Please don't remove it so that we know it at least continues to
1449 * build.
1450 */
1451static __attribute__((__unused__)) int
Jason Ekstrand38dc2dd2015-04-16 17:52:03 -07001452brw_get_revision(int fd)
1453{
1454 struct drm_i915_getparam gp;
1455 int revision;
1456 int ret;
1457
1458 memset(&gp, 0, sizeof(gp));
1459 gp.param = I915_PARAM_REVISION;
1460 gp.value = &revision;
1461
1462 ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
1463 if (ret)
1464 revision = -1;
1465
1466 return revision;
1467}
1468
Abdiel Janulgue090529a2013-07-02 11:48:22 -04001469/* Drop when RS headers get pulled to libdrm */
1470#ifndef I915_PARAM_HAS_RESOURCE_STREAMER
1471#define I915_PARAM_HAS_RESOURCE_STREAMER 36
1472#endif
1473
Jason Ekstrand870ff6c2016-05-25 18:19:50 -07001474static void
1475shader_debug_log_mesa(void *data, const char *fmt, ...)
1476{
1477 struct brw_context *brw = (struct brw_context *)data;
1478 va_list args;
1479
1480 va_start(args, fmt);
1481 GLuint msg_id = 0;
1482 _mesa_gl_vdebug(&brw->ctx, &msg_id,
1483 MESA_DEBUG_SOURCE_SHADER_COMPILER,
1484 MESA_DEBUG_TYPE_OTHER,
1485 MESA_DEBUG_SEVERITY_NOTIFICATION, fmt, args);
1486 va_end(args);
1487}
1488
1489static void
1490shader_perf_log_mesa(void *data, const char *fmt, ...)
1491{
1492 struct brw_context *brw = (struct brw_context *)data;
1493
1494 va_list args;
1495 va_start(args, fmt);
1496
1497 if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
1498 va_list args_copy;
1499 va_copy(args_copy, args);
1500 vfprintf(stderr, fmt, args_copy);
1501 va_end(args_copy);
1502 }
1503
1504 if (brw->perf_debug) {
1505 GLuint msg_id = 0;
1506 _mesa_gl_vdebug(&brw->ctx, &msg_id,
1507 MESA_DEBUG_SOURCE_SHADER_COMPILER,
1508 MESA_DEBUG_TYPE_PERFORMANCE,
1509 MESA_DEBUG_SEVERITY_MEDIUM, fmt, args);
1510 }
1511 va_end(args);
1512}
1513
Chad Versace6b2bf272011-05-26 15:24:48 -07001514/**
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001515 * This is the driver specific part of the createNewScreen entry point.
Brian Paul8d976ae2008-06-11 19:33:14 -06001516 * Called when using DRI2.
1517 *
Kristian Høgsbergd3491e72010-10-12 11:58:47 -04001518 * \return the struct gl_config supported by this driver
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001519 */
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001520static const
Kristian Høgsbergd61f0732010-01-01 17:09:12 -05001521__DRIconfig **intelInitScreen2(__DRIscreen *psp)
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001522{
Kristian Høgsberg5777dee2010-02-11 16:44:21 -05001523 struct intel_screen *intelScreen;
Kristian Høgsberg7c50d292010-01-08 12:35:47 -05001524
Keith Packard44244202013-11-04 18:09:51 -08001525 if (psp->image.loader) {
1526 } else if (psp->dri2.loader->base.version <= 2 ||
Eric Anholt1b4374d2012-07-04 10:52:34 -07001527 psp->dri2.loader->getBuffersWithFormat == NULL) {
1528 fprintf(stderr,
1529 "\nERROR! DRI2 loader with getBuffersWithFormat() "
1530 "support required\n");
1531 return false;
1532 }
1533
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001534 /* Allocate the private area */
Kenneth Graunkeb3e4b762014-03-17 13:57:14 -07001535 intelScreen = rzalloc(NULL, struct intel_screen);
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001536 if (!intelScreen) {
1537 fprintf(stderr, "\nERROR! Allocating private area failed\n");
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -07001538 return false;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001539 }
1540 /* parse information in __driConfigOptions */
Eric Anholt68689232013-09-27 15:25:40 -07001541 driParseOptionInfo(&intelScreen->optionCache, brw_config_options.xml);
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001542
1543 intelScreen->driScrnPriv = psp;
George Sapountzis875a7572011-11-03 13:04:57 +02001544 psp->driverPrivate = (void *) intelScreen;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001545
Eric Anholt2222aa02012-03-09 16:27:35 -08001546 if (!intel_init_bufmgr(intelScreen))
1547 return false;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001548
Eric Anholt2222aa02012-03-09 16:27:35 -08001549 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
Ben Widawsky9ecfc6b2015-10-23 14:38:39 -07001550 intelScreen->devinfo = brw_get_device_info(intelScreen->deviceID);
Kenneth Graunkeeaf33582014-02-10 01:54:23 -08001551 if (!intelScreen->devinfo)
1552 return false;
Eric Anholt4ac2f092010-12-02 18:25:45 -08001553
Kristian Høgsberg Kristensen99ca2252015-10-06 16:19:04 -07001554 brw_process_intel_debug_variable();
1555
1556 if (INTEL_DEBUG & DEBUG_BUFMGR)
1557 dri_bufmgr_set_debug(intelScreen->bufmgr, true);
1558
1559 if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && intelScreen->devinfo->gen < 7) {
1560 fprintf(stderr,
1561 "shader_time debugging requires gen7 (Ivybridge) or better.\n");
1562 INTEL_DEBUG &= ~DEBUG_SHADER_TIME;
1563 }
1564
1565 if (INTEL_DEBUG & DEBUG_AUB)
1566 drm_intel_bufmgr_gem_set_aub_dump(intelScreen->bufmgr, true);
Jason Ekstrand1bc3b622015-04-16 17:39:13 -07001567
Daniel Vetterf172eae2012-03-02 21:38:44 +01001568 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
Chris Wilsonc8d3eba2015-04-29 13:32:38 +01001569 intelScreen->hw_has_timestamp = intel_detect_timestamp(intelScreen);
Daniel Vetterf172eae2012-03-02 21:38:44 +01001570
Ben Widawskycc01b632016-04-07 10:53:13 -07001571 /* GENs prior to 8 do not support EU/Subslice info */
Kenneth Graunke9cd8f952016-06-08 23:36:16 -07001572 if (intelScreen->devinfo->gen >= 8) {
Ben Widawskycc01b632016-04-07 10:53:13 -07001573 intel_detect_sseu(intelScreen);
Kenneth Graunke9cd8f952016-06-08 23:36:16 -07001574 } else if (intelScreen->devinfo->gen == 7) {
1575 intelScreen->subslice_total = 1 << (intelScreen->devinfo->gt - 1);
1576 }
Ben Widawskycc01b632016-04-07 10:53:13 -07001577
Eric Anholt41033502014-03-21 16:36:22 -07001578 const char *force_msaa = getenv("INTEL_FORCE_MSAA");
1579 if (force_msaa) {
1580 intelScreen->winsys_msaa_samples_override =
1581 intel_quantize_num_samples(intelScreen, atoi(force_msaa));
1582 printf("Forcing winsys sample count to %d\n",
1583 intelScreen->winsys_msaa_samples_override);
1584 } else {
1585 intelScreen->winsys_msaa_samples_override = -1;
1586 }
1587
Chad Versace4945086f32012-11-21 15:08:27 -08001588 set_max_gl_versions(intelScreen);
1589
Ian Romanick9b1c6862013-11-19 17:01:23 -08001590 /* Notification of GPU resets requires hardware contexts and a kernel new
1591 * enough to support DRM_IOCTL_I915_GET_RESET_STATS. If the ioctl is
1592 * supported, calling it with a context of 0 will either generate EPERM or
1593 * no error. If the ioctl is not supported, it always generate EINVAL.
1594 * Use this to determine whether to advertise the __DRI2_ROBUSTNESS
1595 * extension to the loader.
Kenneth Graunke0380ec42014-03-12 01:43:40 -07001596 *
1597 * Don't even try on pre-Gen6, since we don't attempt to use contexts there.
Ian Romanick9b1c6862013-11-19 17:01:23 -08001598 */
Kenneth Graunke0380ec42014-03-12 01:43:40 -07001599 if (intelScreen->devinfo->gen >= 6) {
1600 struct drm_i915_reset_stats stats;
1601 memset(&stats, 0, sizeof(stats));
Ian Romanick9b1c6862013-11-19 17:01:23 -08001602
Kenneth Graunke0380ec42014-03-12 01:43:40 -07001603 const int ret = drmIoctl(psp->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats);
Ian Romanick9b1c6862013-11-19 17:01:23 -08001604
Kenneth Graunke0380ec42014-03-12 01:43:40 -07001605 intelScreen->has_context_reset_notification =
1606 (ret != -1 || errno != EINVAL);
1607 }
Ian Romanick53a65e52013-11-26 16:27:57 -08001608
Chad Versacea2ae8882016-06-27 11:50:17 -07001609 if (intel_get_param(intelScreen, I915_PARAM_CMD_PARSER_VERSION,
1610 &intelScreen->cmd_parser_version) < 0) {
Neil Roberts8a59f2f2014-11-07 18:20:17 +00001611 intelScreen->cmd_parser_version = 0;
Chad Versacea2ae8882016-06-27 11:50:17 -07001612 }
Neil Roberts8a59f2f2014-11-07 18:20:17 +00001613
Kenneth Graunke4c71c8a2016-05-05 01:57:30 -07001614 /* Haswell requires command parser version 6 in order to write to the
1615 * MI_MATH GPR registers, and version 7 in order to use
1616 * MI_LOAD_REGISTER_REG (which all users of MI_MATH use).
1617 */
1618 intelScreen->has_mi_math_and_lrr = intelScreen->devinfo->gen >= 8 ||
1619 (intelScreen->devinfo->is_haswell &&
1620 intelScreen->cmd_parser_version >= 7);
1621
Ian Romanick53a65e52013-11-26 16:27:57 -08001622 psp->extensions = !intelScreen->has_context_reset_notification
Ian Romanick9b1c6862013-11-19 17:01:23 -08001623 ? intelScreenExtensions : intelRobustScreenExtensions;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001624
Jason Ekstrandae3870d2015-04-16 12:01:09 -07001625 intelScreen->compiler = brw_compiler_create(intelScreen,
1626 intelScreen->devinfo);
Jason Ekstrand870ff6c2016-05-25 18:19:50 -07001627 intelScreen->compiler->shader_debug_log = shader_debug_log_mesa;
1628 intelScreen->compiler->shader_perf_log = shader_perf_log_mesa;
Kenneth Graunke4ec3f0f2015-12-18 03:18:11 -08001629 intelScreen->program_id = 1;
Kenneth Graunke7a0fd3c2014-03-17 13:53:44 -07001630
Abdiel Janulgue090529a2013-07-02 11:48:22 -04001631 if (intelScreen->devinfo->has_resource_streamer) {
Chad Versacea2ae8882016-06-27 11:50:17 -07001632 intelScreen->has_resource_streamer =
1633 intel_get_boolean(intelScreen, I915_PARAM_HAS_RESOURCE_STREAMER);
Abdiel Janulgue090529a2013-07-02 11:48:22 -04001634 }
1635
Chad Versaceb2d428c2012-07-12 14:17:22 -07001636 return (const __DRIconfig**) intel_screen_make_configs(psp);
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001637}
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001638
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001639struct intel_buffer {
1640 __DRIbuffer base;
Eric Anholt3278f962014-04-25 13:44:41 -07001641 drm_intel_bo *bo;
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001642};
1643
1644static __DRIbuffer *
1645intelAllocateBuffer(__DRIscreen *screen,
1646 unsigned attachment, unsigned format,
1647 int width, int height)
1648{
1649 struct intel_buffer *intelBuffer;
George Sapountzis875a7572011-11-03 13:04:57 +02001650 struct intel_screen *intelScreen = screen->driverPrivate;
Chad Versace79653c12011-11-15 07:08:49 -08001651
Chad Versace83fa0842012-07-09 15:51:06 -07001652 assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1653 attachment == __DRI_BUFFER_BACK_LEFT);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001654
Brian Paul4fdac652012-09-01 07:47:24 -06001655 intelBuffer = calloc(1, sizeof *intelBuffer);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001656 if (intelBuffer == NULL)
1657 return NULL;
1658
Chad Versace83fa0842012-07-09 15:51:06 -07001659 /* The front and back buffers are color buffers, which are X tiled. */
Daniel Stonee54b2e92016-05-02 15:34:40 +01001660 uint32_t tiling = I915_TILING_X;
Eric Anholt3278f962014-04-25 13:44:41 -07001661 unsigned long pitch;
1662 int cpp = format / 8;
1663 intelBuffer->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr,
1664 "intelAllocateBuffer",
1665 width,
1666 height,
1667 cpp,
1668 &tiling, &pitch,
1669 BO_ALLOC_FOR_RENDER);
Kenneth Graunkea7bdd4c2013-11-25 15:46:34 -08001670
Eric Anholt3278f962014-04-25 13:44:41 -07001671 if (intelBuffer->bo == NULL) {
Brian Paulfe72a062012-09-01 07:47:24 -06001672 free(intelBuffer);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001673 return NULL;
1674 }
Kenneth Graunkea7bdd4c2013-11-25 15:46:34 -08001675
Eric Anholt3278f962014-04-25 13:44:41 -07001676 drm_intel_bo_flink(intelBuffer->bo, &intelBuffer->base.name);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001677
1678 intelBuffer->base.attachment = attachment;
Eric Anholt3278f962014-04-25 13:44:41 -07001679 intelBuffer->base.cpp = cpp;
1680 intelBuffer->base.pitch = pitch;
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001681
1682 return &intelBuffer->base;
1683}
1684
1685static void
1686intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1687{
1688 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1689
Eric Anholt3278f962014-04-25 13:44:41 -07001690 drm_intel_bo_unreference(intelBuffer->bo);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001691 free(intelBuffer);
1692}
1693
Eric Anholt1925a9a2013-06-26 13:04:51 -07001694static const struct __DriverAPIRec brw_driver_api = {
George Sapountzis7192c372011-11-03 12:46:08 +02001695 .InitScreen = intelInitScreen2,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001696 .DestroyScreen = intelDestroyScreen,
Eric Anholtee8983b2013-09-26 17:08:28 -07001697 .CreateContext = brwCreateContext,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001698 .DestroyContext = intelDestroyContext,
1699 .CreateBuffer = intelCreateBuffer,
1700 .DestroyBuffer = intelDestroyBuffer,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001701 .MakeCurrent = intelMakeCurrent,
1702 .UnbindContext = intelUnbindContext,
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001703 .AllocateBuffer = intelAllocateBuffer,
1704 .ReleaseBuffer = intelReleaseBuffer
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001705};
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -05001706
Eric Anholt1925a9a2013-06-26 13:04:51 -07001707static const struct __DRIDriverVtableExtensionRec brw_vtable = {
1708 .base = { __DRI_DRIVER_VTABLE, 1 },
1709 .vtable = &brw_driver_api,
1710};
1711
1712static const __DRIextension *brw_driver_extensions[] = {
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -05001713 &driCoreExtension.base,
Keith Packard44244202013-11-04 18:09:51 -08001714 &driImageDriverExtension.base,
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -05001715 &driDRI2Extension.base,
Eric Anholt1925a9a2013-06-26 13:04:51 -07001716 &brw_vtable.base,
Eric Anholt68689232013-09-27 15:25:40 -07001717 &brw_config_options.base,
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -05001718 NULL
1719};
Eric Anholt1925a9a2013-06-26 13:04:51 -07001720
1721PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
1722{
1723 globalDriverAPI = &brw_driver_api;
1724
1725 return brw_driver_extensions;
1726}