X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fintel_screen.c;h=a3d252d030ddb613ef886f2bdfe0b2712d6a06ee;hb=ed65e6ef49e17e9cae93a8f98e2968346de2bc6e;hp=896a12534e6adc7b1e0458a153db57a7a3b2beb0;hpb=8a59f2f26fb7bb036ad524cdec668716664d2a82;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 896a12534e6..a3d252d030d 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -1,5 +1,4 @@ -/************************************************************************** - * +/* * Copyright 2003 VMware, Inc. * All Rights Reserved. * @@ -7,7 +6,7 @@ * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to + * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * @@ -17,18 +16,16 @@ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ + */ #include #include #include -#include "main/glheader.h" #include "main/context.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" @@ -39,6 +36,7 @@ #include "swrast/s_renderbuffer.h" #include "util/ralloc.h" #include "brw_shader.h" +#include "compiler/nir/nir.h" #include "utils.h" #include "xmlpool.h" @@ -67,6 +65,8 @@ DRI_CONF_BEGIN DRI_CONF_SECTION_QUALITY DRI_CONF_FORCE_S3TC_ENABLE("false") + DRI_CONF_PRECISE_TRIG("false") + DRI_CONF_OPT_BEGIN(clamp_max_samples, int, -1) DRI_CONF_DESC(en, "Clamp the value of GL_MAX_SAMPLES to the " "given integer. If negative, then do not clamp.") @@ -81,12 +81,17 @@ DRI_CONF_BEGIN DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false") DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false") DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false") + DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION("false") DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER("false") DRI_CONF_OPT_BEGIN_B(shader_precompile, "true") DRI_CONF_DESC(en, "Perform code generation at shader link time.") DRI_CONF_OPT_END DRI_CONF_SECTION_END + + DRI_CONF_SECTION_MISCELLANEOUS + DRI_CONF_GLSL_ZERO_INIT("false") + DRI_CONF_SECTION_END DRI_CONF_END }; @@ -121,7 +126,7 @@ aub_dump_bmp(struct gl_context *ctx) { struct gl_framebuffer *fb = ctx->DrawBuffer; - for (int i = 0; i < fb->_NumColorDrawBuffers; i++) { + for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) { struct intel_renderbuffer *irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); @@ -228,6 +233,12 @@ static struct intel_image_format intel_image_formats[] = { { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1, { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } }, + { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_COMPONENTS_R, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, } }, + + { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_COMPONENTS_RG, 1, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, } }, + { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 }, @@ -253,6 +264,31 @@ static struct intel_image_format intel_image_formats[] = { { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, + { __DRI_IMAGE_FOURCC_YVU410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YVU411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YVU420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YVU422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, + + { __DRI_IMAGE_FOURCC_YVU444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, + { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } }, + { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2, { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } }, @@ -390,7 +426,7 @@ intel_create_image_from_name(__DRIscreen *screen, return NULL; } - return image; + return image; } static __DRIimage * @@ -525,7 +561,6 @@ intel_create_image(__DRIscreen *screen, if (image == NULL) return NULL; - cpp = _mesa_get_format_bytes(image->format); image->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr, "image", width, height, cpp, &tiling, @@ -568,13 +603,9 @@ intel_query_image(__DRIimage *image, int attrib, int *value) *value = image->planar_format->components; return true; case __DRI_IMAGE_ATTRIB_FD: - if (drm_intel_bo_gem_export_to_prime(image->bo, value) == 0) - return true; - return false; + return !drm_intel_bo_gem_export_to_prime(image->bo, value); case __DRI_IMAGE_ATTRIB_FOURCC: - if (intel_lookup_fourcc(image->dri_format, value)) - return true; - return false; + return intel_lookup_fourcc(image->dri_format, value); case __DRI_IMAGE_ATTRIB_NUM_PLANES: *value = 1; return true; @@ -672,9 +703,14 @@ intel_create_image_from_fds(__DRIscreen *screen, __DRIimage *image; int i, index; - if (fds == NULL || num_fds != 1) + if (fds == NULL || num_fds < 1) return NULL; + /* We only support all planes from the same bo */ + for (i = 0; i < num_fds; i++) + if (fds[0] != fds[i]) + return NULL; + f = intel_image_format_lookup(fourcc); if (f == NULL) return NULL; @@ -687,22 +723,28 @@ intel_create_image_from_fds(__DRIscreen *screen, if (image == NULL) return NULL; - image->bo = drm_intel_bo_gem_create_from_prime(intelScreen->bufmgr, - fds[0], - height * strides[0]); - if (image->bo == NULL) { - free(image); - return NULL; - } image->width = width; image->height = height; image->pitch = strides[0]; image->planar_format = f; + int size = 0; for (i = 0; i < f->nplanes; i++) { index = f->planes[i].buffer_index; image->offsets[index] = offsets[index]; image->strides[index] = strides[index]; + + const int plane_height = height >> f->planes[i].height_shift; + const int end = offsets[index] + plane_height * strides[index]; + if (size < end) + size = end; + } + + image->bo = drm_intel_bo_gem_create_from_prime(intelScreen->bufmgr, + fds[0], size); + if (image->bo == NULL) { + free(image); + return NULL; } if (f->nplanes == 1) { @@ -728,8 +770,7 @@ intel_create_image_from_dma_bufs(__DRIscreen *screen, __DRIimage *image; struct intel_image_format *f = intel_image_format_lookup(fourcc); - /* For now only packed formats that have native sampling are supported. */ - if (!f || f->nplanes != 1) { + if (!f) { *error = __DRI_IMAGE_ERROR_BAD_MATCH; return NULL; } @@ -887,7 +928,7 @@ brw_query_renderer_string(__DRIscreen *psp, int param, const char **value) value[0] = brw_vendor_string; return 0; case __DRI2_RENDERER_DEVICE_ID: - value[0] = brw_get_renderer_string(intelScreen->deviceID); + value[0] = brw_get_renderer_string(intelScreen); return 0; default: break; @@ -928,31 +969,41 @@ static const __DRIextension *intelRobustScreenExtensions[] = { NULL }; -static bool -intel_get_param(__DRIscreen *psp, int param, int *value) +static int +intel_get_param(struct intel_screen *screen, int param, int *value) { - int ret; + int ret = 0; struct drm_i915_getparam gp; memset(&gp, 0, sizeof(gp)); gp.param = param; gp.value = value; - ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); - if (ret) { + if (drmIoctl(screen->driScrnPriv->fd, DRM_IOCTL_I915_GETPARAM, &gp) == -1) { + ret = -errno; if (ret != -EINVAL) - _mesa_warning(NULL, "drm_i915_getparam: %d", ret); - return false; + _mesa_warning(NULL, "drm_i915_getparam: %d", ret); } - return true; + return ret; } static bool -intel_get_boolean(__DRIscreen *psp, int param) +intel_get_boolean(struct intel_screen *screen, int param) { int value = 0; - return intel_get_param(psp, param, &value) && value; + return (intel_get_param(screen, param, &value) == 0) && value; +} + +static int +intel_get_integer(struct intel_screen *screen, int param) +{ + int value = -1; + + if (intel_get_param(screen, param, &value) == 0) + return value; + + return -1; } static void @@ -996,14 +1047,18 @@ intelCreateBuffer(__DRIscreen * driScrnPriv, fb->Visual.samples = num_samples; } - if (mesaVis->redBits == 5) - rgbFormat = MESA_FORMAT_B5G6R5_UNORM; - else if (mesaVis->sRGBCapable) - rgbFormat = MESA_FORMAT_B8G8R8A8_SRGB; - else if (mesaVis->alphaBits == 0) - rgbFormat = MESA_FORMAT_B8G8R8X8_UNORM; - else { - rgbFormat = MESA_FORMAT_B8G8R8A8_SRGB; + if (mesaVis->redBits == 5) { + rgbFormat = mesaVis->redMask == 0x1f ? MESA_FORMAT_R5G6B5_UNORM + : MESA_FORMAT_B5G6R5_UNORM; + } else if (mesaVis->sRGBCapable) { + rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8A8_SRGB + : MESA_FORMAT_B8G8R8A8_SRGB; + } else if (mesaVis->alphaBits == 0) { + rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8X8_UNORM + : MESA_FORMAT_B8G8R8X8_UNORM; + } else { + rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8A8_SRGB + : MESA_FORMAT_B8G8R8A8_SRGB; fb->Visual.sRGBCapable = true; } @@ -1074,6 +1129,41 @@ intelDestroyBuffer(__DRIdrawable * driDrawPriv) _mesa_reference_framebuffer(&fb, NULL); } +static void +intel_detect_sseu(struct intel_screen *intelScreen) +{ + assert(intelScreen->devinfo->gen >= 8); + int ret; + + intelScreen->subslice_total = -1; + intelScreen->eu_total = -1; + + ret = intel_get_param(intelScreen, I915_PARAM_SUBSLICE_TOTAL, + &intelScreen->subslice_total); + if (ret < 0 && ret != -EINVAL) + goto err_out; + + ret = intel_get_param(intelScreen, + I915_PARAM_EU_TOTAL, &intelScreen->eu_total); + if (ret < 0 && ret != -EINVAL) + goto err_out; + + /* Without this information, we cannot get the right Braswell brandstrings, + * and we have to use conservative numbers for GPGPU on many platforms, but + * otherwise, things will just work. + */ + if (intelScreen->subslice_total < 1 || intelScreen->eu_total < 1) + _mesa_warning(NULL, + "Kernel 4.1 required to properly query GPU properties.\n"); + + return; + +err_out: + intelScreen->subslice_total = -1; + intelScreen->eu_total = -1; + _mesa_warning(NULL, "Failed to query GPU properties (%s).\n", strerror(-ret)); +} + static bool intel_init_bufmgr(struct intel_screen *intelScreen) { @@ -1090,7 +1180,7 @@ intel_init_bufmgr(struct intel_screen *intelScreen) drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr); - if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) { + if (!intel_get_boolean(intelScreen, I915_PARAM_HAS_RELAXED_DELTA)) { fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__); return false; } @@ -1122,6 +1212,50 @@ intel_detect_swizzling(struct intel_screen *screen) return true; } +static int +intel_detect_timestamp(struct intel_screen *screen) +{ + uint64_t dummy = 0, last = 0; + int upper, lower, loops; + + /* On 64bit systems, some old kernels trigger a hw bug resulting in the + * TIMESTAMP register being shifted and the low 32bits always zero. + * + * More recent kernels offer an interface to read the full 36bits + * everywhere. + */ + if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP | 1, &dummy) == 0) + return 3; + + /* Determine if we have a 32bit or 64bit kernel by inspecting the + * upper 32bits for a rapidly changing timestamp. + */ + if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP, &last)) + return 0; + + upper = lower = 0; + for (loops = 0; loops < 10; loops++) { + /* The TIMESTAMP should change every 80ns, so several round trips + * through the kernel should be enough to advance it. + */ + if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP, &dummy)) + return 0; + + upper += (dummy >> 32) != (last >> 32); + if (upper > 1) /* beware 32bit counter overflow */ + return 2; /* upper dword holds the low 32bits of the timestamp */ + + lower += (dummy & 0xffffffff) != (last & 0xffffffff); + if (lower > 1) + return 1; /* timestamp is unshifted */ + + last = dummy; + } + + /* No advancement? No timestamp! */ + return 0; +} + /** * Return array of MSAA modes supported by the hardware. The array is * zero-terminated and sorted in decreasing order. @@ -1129,12 +1263,15 @@ intel_detect_swizzling(struct intel_screen *screen) const int* intel_supported_msaa_modes(const struct intel_screen *screen) { + static const int gen9_modes[] = {16, 8, 4, 2, 0, -1}; static const int gen8_modes[] = {8, 4, 2, 0, -1}; static const int gen7_modes[] = {8, 4, 0, -1}; static const int gen6_modes[] = {4, 0, -1}; static const int gen4_modes[] = {0, -1}; - if (screen->devinfo->gen >= 8) { + if (screen->devinfo->gen >= 9) { + return gen9_modes; + } else if (screen->devinfo->gen >= 8) { return gen8_modes; } else if (screen->devinfo->gen >= 7) { return gen7_modes; @@ -1163,12 +1300,12 @@ intel_screen_make_configs(__DRIscreen *dri_screen) static const uint8_t multisample_samples[2] = {4, 8}; struct intel_screen *screen = dri_screen->driverPrivate; - const struct brw_device_info *devinfo = screen->devinfo; + const struct gen_device_info *devinfo = screen->devinfo; uint8_t depth_bits[4], stencil_bits[4]; __DRIconfig **configs = NULL; /* Generate singlesample configs without accumulation buffer. */ - for (int i = 0; i < ARRAY_SIZE(formats); i++) { + for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) { __DRIconfig **new_configs; int num_depth_stencil_bits = 2; @@ -1198,14 +1335,14 @@ intel_screen_make_configs(__DRIscreen *dri_screen) num_depth_stencil_bits, back_buffer_modes, 2, singlesample_samples, 1, - false); + false, false); configs = driConcatConfigs(configs, new_configs); } /* Generate the minimum possible set of configs that include an * accumulation buffer. */ - for (int i = 0; i < ARRAY_SIZE(formats); i++) { + for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) { __DRIconfig **new_configs; if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) { @@ -1220,7 +1357,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen) depth_bits, stencil_bits, 1, back_buffer_modes, 1, singlesample_samples, 1, - true); + true, false); configs = driConcatConfigs(configs, new_configs); } @@ -1237,7 +1374,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen) * supported. Singlebuffer configs are not supported because no one wants * them. */ - for (int i = 0; i < ARRAY_SIZE(formats); i++) { + for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) { if (devinfo->gen < 6) break; @@ -1268,7 +1405,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen) back_buffer_modes, 1, multisample_samples, num_msaa_modes, - false); + false, false); configs = driConcatConfigs(configs, new_configs); } @@ -1289,7 +1426,17 @@ set_max_gl_versions(struct intel_screen *screen) switch (screen->devinfo->gen) { case 9: case 8: + psp->max_gl_core_version = 44; + psp->max_gl_compat_version = 30; + psp->max_gl_es1_version = 11; + psp->max_gl_es2_version = 31; + break; case 7: + psp->max_gl_core_version = 33; + psp->max_gl_compat_version = 30; + psp->max_gl_es1_version = 11; + psp->max_gl_es2_version = screen->devinfo->is_haswell ? 31 : 30; + break; case 6: psp->max_gl_core_version = 33; psp->max_gl_compat_version = 30; @@ -1308,12 +1455,16 @@ set_max_gl_versions(struct intel_screen *screen) } } -/* drop when libdrm 2.4.61 is released */ -#ifndef I915_PARAM_REVISION -#define I915_PARAM_REVISION 32 -#endif - -static int +/** + * Return the revision (generally the revid field of the PCI header) of the + * graphics device. + * + * XXX: This function is useful to keep around even if it is not currently in + * use. It is necessary for new platforms and revision specific workarounds or + * features. Please don't remove it so that we know it at least continues to + * build. + */ +static __attribute__((__unused__)) int brw_get_revision(int fd) { struct drm_i915_getparam gp; @@ -1331,6 +1482,51 @@ brw_get_revision(int fd) return revision; } +/* Drop when RS headers get pulled to libdrm */ +#ifndef I915_PARAM_HAS_RESOURCE_STREAMER +#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#endif + +static void +shader_debug_log_mesa(void *data, const char *fmt, ...) +{ + struct brw_context *brw = (struct brw_context *)data; + va_list args; + + va_start(args, fmt); + GLuint msg_id = 0; + _mesa_gl_vdebug(&brw->ctx, &msg_id, + MESA_DEBUG_SOURCE_SHADER_COMPILER, + MESA_DEBUG_TYPE_OTHER, + MESA_DEBUG_SEVERITY_NOTIFICATION, fmt, args); + va_end(args); +} + +static void +shader_perf_log_mesa(void *data, const char *fmt, ...) +{ + struct brw_context *brw = (struct brw_context *)data; + + va_list args; + va_start(args, fmt); + + if (unlikely(INTEL_DEBUG & DEBUG_PERF)) { + va_list args_copy; + va_copy(args_copy, args); + vfprintf(stderr, fmt, args_copy); + va_end(args_copy); + } + + if (brw->perf_debug) { + GLuint msg_id = 0; + _mesa_gl_vdebug(&brw->ctx, &msg_id, + MESA_DEBUG_SOURCE_SHADER_COMPILER, + MESA_DEBUG_TYPE_PERFORMANCE, + MESA_DEBUG_SEVERITY_MEDIUM, fmt, args); + } + va_end(args); +} + /** * This is the driver specific part of the createNewScreen entry point. * Called when using DRI2. @@ -1367,14 +1563,70 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) return false; intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr); - intelScreen->devinfo = brw_get_device_info(intelScreen->deviceID, - brw_get_revision(psp->fd)); + intelScreen->devinfo = gen_get_device_info(intelScreen->deviceID); if (!intelScreen->devinfo) return false; - intelScreen->hw_must_use_separate_stencil = intelScreen->devinfo->gen >= 7; + brw_process_intel_debug_variable(); + + if (INTEL_DEBUG & DEBUG_BUFMGR) + dri_bufmgr_set_debug(intelScreen->bufmgr, true); + + if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && intelScreen->devinfo->gen < 7) { + fprintf(stderr, + "shader_time debugging requires gen7 (Ivybridge) or better.\n"); + INTEL_DEBUG &= ~DEBUG_SHADER_TIME; + } + + if (INTEL_DEBUG & DEBUG_AUB) + drm_intel_bufmgr_gem_set_aub_dump(intelScreen->bufmgr, true); + +#ifndef I915_PARAM_MMAP_GTT_VERSION +#define I915_PARAM_MMAP_GTT_VERSION 40 /* XXX delete me with new libdrm */ +#endif + if (intel_get_integer(intelScreen, I915_PARAM_MMAP_GTT_VERSION) >= 1) { + /* Theorectically unlimited! At least for individual objects... + * + * Currently the entire (global) address space for all GTT maps is + * limited to 64bits. That is all objects on the system that are + * setup for GTT mmapping must fit within 64bits. An attempt to use + * one that exceeds the limit with fail in drm_intel_bo_map_gtt(). + * + * Long before we hit that limit, we will be practically limited by + * that any single object must fit in physical memory (RAM). The upper + * limit on the CPU's address space is currently 48bits (Skylake), of + * which only 39bits can be physical memory. (The GPU itself also has + * a 48bit addressable virtual space.) We can fit over 32 million + * objects of the current maximum allocable size before running out + * of mmap space. + */ + intelScreen->max_gtt_map_object_size = UINT64_MAX; + } else { + /* Estimate the size of the mappable aperture into the GTT. There's an + * ioctl to get the whole GTT size, but not one to get the mappable subset. + * It turns out it's basically always 256MB, though some ancient hardware + * was smaller. + */ + uint32_t gtt_size = 256 * 1024 * 1024; + + /* We don't want to map two objects such that a memcpy between them would + * just fault one mapping in and then the other over and over forever. So + * we would need to divide the GTT size by 2. Additionally, some GTT is + * taken up by things like the framebuffer and the ringbuffer and such, so + * be more conservative. + */ + intelScreen->max_gtt_map_object_size = gtt_size / 4; + } intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen); + intelScreen->hw_has_timestamp = intel_detect_timestamp(intelScreen); + + /* GENs prior to 8 do not support EU/Subslice info */ + if (intelScreen->devinfo->gen >= 8) { + intel_detect_sseu(intelScreen); + } else if (intelScreen->devinfo->gen == 7) { + intelScreen->subslice_total = 1 << (intelScreen->devinfo->gt - 1); + } const char *force_msaa = getenv("INTEL_FORCE_MSAA"); if (force_msaa) { @@ -1407,18 +1659,32 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) (ret != -1 || errno != EINVAL); } - struct drm_i915_getparam getparam; - getparam.param = I915_PARAM_CMD_PARSER_VERSION; - getparam.value = &intelScreen->cmd_parser_version; - const int ret = drmIoctl(psp->fd, DRM_IOCTL_I915_GETPARAM, &getparam); - if (ret == -1) + if (intel_get_param(intelScreen, I915_PARAM_CMD_PARSER_VERSION, + &intelScreen->cmd_parser_version) < 0) { intelScreen->cmd_parser_version = 0; + } + + /* Haswell requires command parser version 6 in order to write to the + * MI_MATH GPR registers, and version 7 in order to use + * MI_LOAD_REGISTER_REG (which all users of MI_MATH use). + */ + intelScreen->has_mi_math_and_lrr = intelScreen->devinfo->gen >= 8 || + (intelScreen->devinfo->is_haswell && + intelScreen->cmd_parser_version >= 7); psp->extensions = !intelScreen->has_context_reset_notification ? intelScreenExtensions : intelRobustScreenExtensions; intelScreen->compiler = brw_compiler_create(intelScreen, intelScreen->devinfo); + intelScreen->compiler->shader_debug_log = shader_debug_log_mesa; + intelScreen->compiler->shader_perf_log = shader_perf_log_mesa; + intelScreen->program_id = 1; + + if (intelScreen->devinfo->has_resource_streamer) { + intelScreen->has_resource_streamer = + intel_get_boolean(intelScreen, I915_PARAM_HAS_RESOURCE_STREAMER); + } return (const __DRIconfig**) intel_screen_make_configs(psp); }