-/**************************************************************************
- *
+/*
* Copyright 2003 VMware, Inc.
* All Rights Reserved.
*
* 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:
*
*
* 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 <errno.h>
#include <time.h>
#include <unistd.h>
-#include "main/glheader.h"
#include "main/context.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
#include "main/version.h"
#include "swrast/s_renderbuffer.h"
#include "util/ralloc.h"
+#include "brw_shader.h"
+#include "compiler/nir/nir.h"
#include "utils.h"
#include "xmlpool.h"
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")
{
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]);
{ __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 },
return NULL;
}
- return image;
+ return image;
}
static __DRIimage *
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,
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;
static const __DRIextension *intelScreenExtensions[] = {
&intelTexBufferExtension.base,
+ &intelFenceExtension.base,
&intelFlushExtension.base,
&intelImageExtension.base,
&intelRendererQueryExtension.base,
static const __DRIextension *intelRobustScreenExtensions[] = {
&intelTexBufferExtension.base,
+ &intelFenceExtension.base,
&intelFlushExtension.base,
&intelImageExtension.base,
&intelRendererQueryExtension.base,
NULL
};
-static bool
+static int
intel_get_param(__DRIscreen *psp, int param, int *value)
{
int ret;
gp.value = value;
ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
- if (ret) {
- if (ret != -EINVAL)
+ if (ret < 0 && ret != -EINVAL)
_mesa_warning(NULL, "drm_i915_getparam: %d", ret);
- return false;
- }
- return true;
+ return ret;
}
static bool
intel_get_boolean(__DRIscreen *psp, int param)
{
int value = 0;
- return intel_get_param(psp, param, &value) && value;
+ return (intel_get_param(psp, param, &value) == 0) && value;
}
static void
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;
}
_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->driScrnPriv, I915_PARAM_SUBSLICE_TOTAL,
+ &intelScreen->subslice_total);
+ if (ret < 0 && ret != -EINVAL)
+ goto err_out;
+
+ ret = intel_get_param(intelScreen->driScrnPriv,
+ 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)
{
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.
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;
{
static const mesa_format formats[] = {
MESA_FORMAT_B5G6R5_UNORM,
- MESA_FORMAT_B8G8R8A8_UNORM
+ MESA_FORMAT_B8G8R8A8_UNORM,
+ MESA_FORMAT_B8G8R8X8_UNORM
};
/* GLX_SWAP_COPY_OML is not supported due to page flipping. */
__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;
/* 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) {
* 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;
switch (screen->devinfo->gen) {
case 9:
case 8:
+ psp->max_gl_core_version = 42;
+ psp->max_gl_compat_version = 30;
+ psp->max_gl_es1_version = 11;
+ psp->max_gl_es2_version = 31;
+ break;
case 7:
case 6:
psp->max_gl_core_version = 33;
}
}
+/**
+ * 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;
+ int revision;
+ int ret;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = I915_PARAM_REVISION;
+ gp.value = &revision;
+
+ ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
+ if (ret)
+ revision = -1;
+
+ return revision;
+}
+
+/* Drop when RS headers get pulled to libdrm */
+#ifndef I915_PARAM_HAS_RESOURCE_STREAMER
+#define I915_PARAM_HAS_RESOURCE_STREAMER 36
+#endif
+
/**
* This is the driver specific part of the createNewScreen entry point.
* Called when using DRI2.
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);
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);
const char *force_msaa = getenv("INTEL_FORCE_MSAA");
if (force_msaa) {
(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)
+ 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;
- brw_fs_alloc_reg_sets(intelScreen);
- brw_vec4_alloc_reg_set(intelScreen);
+ intelScreen->compiler = brw_compiler_create(intelScreen,
+ intelScreen->devinfo);
+ intelScreen->program_id = 1;
+
+ if (intelScreen->devinfo->has_resource_streamer) {
+ int val = -1;
+ getparam.param = I915_PARAM_HAS_RESOURCE_STREAMER;
+ getparam.value = &val;
+
+ drmIoctl(psp->fd, DRM_IOCTL_I915_GETPARAM, &getparam);
+ intelScreen->has_resource_streamer = val > 0;
+ }
return (const __DRIconfig**) intel_screen_make_configs(psp);
}