*
**************************************************************************/
+#include <errno.h>
#include "main/glheader.h"
#include "main/context.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
+#include "main/hash.h"
+#include "main/fbobject.h"
+#include "main/mfeatures.h"
#include "utils.h"
-#include "vblank.h"
#include "xmlpool.h"
-#include "intel_batchbuffer.h"
-#include "intel_buffers.h"
-#include "intel_bufmgr.h"
-#include "intel_chipset.h"
-#include "intel_extensions.h"
-#include "intel_fbo.h"
-#include "intel_regions.h"
-#include "intel_swapbuffers.h"
-#include "intel_screen.h"
-#include "intel_span.h"
-#include "intel_tex.h"
-
-#include "i915_drm.h"
-#include "i830_dri.h"
-
-#define DRI_CONF_TEXTURE_TILING(def) \
- DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \
- DRI_CONF_DESC(en, "Enable texture tiling") \
- DRI_CONF_OPT_END \
-
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_DESC_END
DRI_CONF_OPT_END
-#ifdef I915
- DRI_CONF_TEXTURE_TILING(false)
-#else
- DRI_CONF_TEXTURE_TILING(true)
-#endif
+ DRI_CONF_OPT_BEGIN(texture_tiling, bool, true)
+ DRI_CONF_DESC(en, "Enable texture tiling")
+ DRI_CONF_OPT_END
DRI_CONF_OPT_BEGIN(early_z, bool, false)
DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
DRI_CONF_OPT_END
- DRI_CONF_OPT_BEGIN(fragment_shader, bool, false)
+ DRI_CONF_OPT_BEGIN(fragment_shader, bool, true)
DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.")
DRI_CONF_OPT_END
const GLuint __driNConfigOptions = 11;
+#include "intel_batchbuffer.h"
+#include "intel_buffers.h"
+#include "intel_bufmgr.h"
+#include "intel_chipset.h"
+#include "intel_fbo.h"
+#include "intel_screen.h"
+#include "intel_tex.h"
+#include "intel_regions.h"
+
+#include "i915_drm.h"
+
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
#endif /*USE_NEW_INTERFACE */
-/**
- * Map all the memory regions described by the screen.
- * \return GL_TRUE if success, GL_FALSE if error.
- */
-GLboolean
-intelMapScreenRegions(__DRIscreen * sPriv)
+static const __DRItexBufferExtension intelTexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ intelSetTexBuffer,
+ intelSetTexBuffer2,
+};
+
+static void
+intelDRI2Flush(__DRIdrawable *drawable)
{
- intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
-
- if (0)
- _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle);
- if (intelScreen->tex.size != 0) {
- if (drmMap(sPriv->fd,
- intelScreen->tex.handle,
- intelScreen->tex.size,
- (drmAddress *) & intelScreen->tex.map) != 0) {
- intelUnmapScreenRegions(intelScreen);
- return GL_FALSE;
- }
- }
+ GET_CURRENT_CONTEXT(ctx);
+ struct intel_context *intel = intel_context(ctx);
- return GL_TRUE;
-}
+ if (intel->gen < 4)
+ INTEL_FIREVERTICES(intel);
-void
-intelUnmapScreenRegions(intelScreenPrivate * intelScreen)
-{
- if (intelScreen->tex.map) {
- drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
- intelScreen->tex.map = NULL;
- }
+ intel->need_throttle = GL_TRUE;
+
+ if (intel->batch.used)
+ intel_batchbuffer_flush(intel);
}
+static const struct __DRI2flushExtensionRec intelFlushExtension = {
+ { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+ intelDRI2Flush,
+ dri2InvalidateDrawable,
+};
-static void
-intelPrintDRIInfo(intelScreenPrivate * intelScreen,
- __DRIscreen * sPriv, I830DRIPtr gDRIPriv)
+static __DRIimage *
+intel_create_image_from_name(__DRIscreen *screen,
+ int width, int height, int format,
+ int name, int pitch, void *loaderPrivate)
{
- fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
- intelScreen->front.size, intelScreen->front.offset,
- intelScreen->pitch);
- fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n",
- intelScreen->back.size, intelScreen->back.offset,
- intelScreen->pitch);
- fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n",
- intelScreen->depth.size, intelScreen->depth.offset,
- intelScreen->pitch);
- fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n",
- intelScreen->tex.size, intelScreen->tex.offset);
- fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
+ struct intel_screen *intelScreen = screen->private;
+ __DRIimage *image;
+ int cpp;
+
+ image = CALLOC(sizeof *image);
+ if (image == NULL)
+ return NULL;
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ image->format = MESA_FORMAT_RGB565;
+ image->internal_format = GL_RGB;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ case __DRI_IMAGE_FORMAT_XRGB8888:
+ image->format = MESA_FORMAT_XRGB8888;
+ image->internal_format = GL_RGB;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ case __DRI_IMAGE_FORMAT_ARGB8888:
+ image->format = MESA_FORMAT_ARGB8888;
+ image->internal_format = GL_RGBA;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ free(image);
+ return NULL;
+ }
+
+ image->data = loaderPrivate;
+ cpp = _mesa_get_format_bytes(image->format);
+
+ image->region = intel_region_alloc_for_handle(intelScreen,
+ cpp, width, height,
+ pitch, name, "image");
+ if (image->region == NULL) {
+ FREE(image);
+ return NULL;
+ }
+
+ return image;
}
+static __DRIimage *
+intel_create_image_from_renderbuffer(__DRIcontext *context,
+ int renderbuffer, void *loaderPrivate)
+{
+ __DRIimage *image;
+ struct intel_context *intel = context->driverPrivate;
+ struct gl_renderbuffer *rb;
+ struct intel_renderbuffer *irb;
+
+ rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
+ if (!rb) {
+ _mesa_error(&intel->ctx,
+ GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
+ return NULL;
+ }
+
+ irb = intel_renderbuffer(rb);
+ image = CALLOC(sizeof *image);
+ if (image == NULL)
+ return NULL;
+
+ image->internal_format = rb->InternalFormat;
+ image->format = rb->Format;
+ image->data_type = rb->DataType;
+ image->data = loaderPrivate;
+ intel_region_reference(&image->region, irb->region);
+
+ return image;
+}
static void
-intelPrintSAREA(const drm_i915_sarea_t * sarea)
+intel_destroy_image(__DRIimage *image)
{
- fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width,
- sarea->height);
- fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
- fprintf(stderr,
- "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n",
- sarea->front_offset, sarea->front_size,
- (unsigned) sarea->front_handle, sarea->front_tiled);
- fprintf(stderr,
- "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n",
- sarea->back_offset, sarea->back_size,
- (unsigned) sarea->back_handle, sarea->back_tiled);
- fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n",
- sarea->depth_offset, sarea->depth_size,
- (unsigned) sarea->depth_handle, sarea->depth_tiled);
- fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
- sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle);
+ intel_region_release(&image->region);
+ FREE(image);
}
-
-/**
- * A number of the screen parameters are obtained/computed from
- * information in the SAREA. This function updates those parameters.
- */
-static void
-intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
- drm_i915_sarea_t * sarea)
+static __DRIimage *
+intel_create_image(__DRIscreen *screen,
+ int width, int height, int format,
+ unsigned int use,
+ void *loaderPrivate)
{
- intelScreen->width = sarea->width;
- intelScreen->height = sarea->height;
- intelScreen->pitch = sarea->pitch;
-
- intelScreen->front.offset = sarea->front_offset;
- intelScreen->front.handle = sarea->front_handle;
- intelScreen->front.size = sarea->front_size;
- intelScreen->front.tiled = sarea->front_tiled;
-
- intelScreen->back.offset = sarea->back_offset;
- intelScreen->back.handle = sarea->back_handle;
- intelScreen->back.size = sarea->back_size;
- intelScreen->back.tiled = sarea->back_tiled;
-
- intelScreen->depth.offset = sarea->depth_offset;
- intelScreen->depth.handle = sarea->depth_handle;
- intelScreen->depth.size = sarea->depth_size;
- intelScreen->depth.tiled = sarea->depth_tiled;
-
- if (intelScreen->driScrnPriv->ddx_version.minor >= 9) {
- intelScreen->front.bo_handle = sarea->front_bo_handle;
- intelScreen->back.bo_handle = sarea->back_bo_handle;
- intelScreen->depth.bo_handle = sarea->depth_bo_handle;
- } else {
- intelScreen->front.bo_handle = -1;
- intelScreen->back.bo_handle = -1;
- intelScreen->depth.bo_handle = -1;
+ __DRIimage *image;
+ struct intel_screen *intelScreen = screen->private;
+ uint32_t tiling;
+ int cpp;
+
+ tiling = I915_TILING_X;
+ if (use & __DRI_IMAGE_USE_CURSOR) {
+ if (width != 64 || height != 64)
+ return NULL;
+ tiling = I915_TILING_NONE;
}
- intelScreen->tex.offset = sarea->tex_offset;
- intelScreen->logTextureGranularity = sarea->log_tex_granularity;
- intelScreen->tex.handle = sarea->tex_handle;
- intelScreen->tex.size = sarea->tex_size;
+ image = CALLOC(sizeof *image);
+ if (image == NULL)
+ return NULL;
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ image->format = MESA_FORMAT_RGB565;
+ image->internal_format = GL_RGB;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ case __DRI_IMAGE_FORMAT_XRGB8888:
+ image->format = MESA_FORMAT_XRGB8888;
+ image->internal_format = GL_RGB;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ case __DRI_IMAGE_FORMAT_ARGB8888:
+ image->format = MESA_FORMAT_ARGB8888;
+ image->internal_format = GL_RGBA;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ free(image);
+ return NULL;
+ }
- if (0)
- intelPrintSAREA(sarea);
+ image->data = loaderPrivate;
+ cpp = _mesa_get_format_bytes(image->format);
+
+ image->region =
+ intel_region_alloc(intelScreen, tiling,
+ cpp, width, height, GL_TRUE);
+ if (image->region == NULL) {
+ FREE(image);
+ return NULL;
+ }
+
+ return image;
}
-static const __DRItexOffsetExtension intelTexOffsetExtension = {
- { __DRI_TEX_OFFSET },
- intelSetTexOffset,
-};
+static GLboolean
+intel_query_image(__DRIimage *image, int attrib, int *value)
+{
+ switch (attrib) {
+ case __DRI_IMAGE_ATTRIB_STRIDE:
+ *value = image->region->pitch * image->region->cpp;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_HANDLE:
+ *value = image->region->buffer->handle;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_NAME:
+ return intel_region_flink(image->region, (uint32_t *) value);
+ default:
+ return GL_FALSE;
+ }
+}
-static const __DRItexBufferExtension intelTexBufferExtension = {
- { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
- intelSetTexBuffer,
- intelSetTexBuffer2,
+static __DRIimage *
+intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
+{
+ __DRIimage *image;
+
+ image = CALLOC(sizeof *image);
+ if (image == NULL)
+ return NULL;
+
+ image->region = NULL;
+ intel_region_reference(&image->region, orig_image->region);
+ if (image->region == NULL) {
+ FREE(image);
+ return NULL;
+ }
+
+ image->internal_format = orig_image->internal_format;
+ image->format = orig_image->format;
+ image->data_type = orig_image->data_type;
+ image->data = loaderPrivate;
+
+ return image;
+}
+
+static struct __DRIimageExtensionRec intelImageExtension = {
+ { __DRI_IMAGE, __DRI_IMAGE_VERSION },
+ intel_create_image_from_name,
+ intel_create_image_from_renderbuffer,
+ intel_destroy_image,
+ intel_create_image,
+ intel_query_image,
+ intel_dup_image
};
static const __DRIextension *intelScreenExtensions[] = {
&driReadDrawableExtension,
- &driSwapControlExtension.base,
- &driFrameTrackingExtension.base,
- &driMediaStreamCounterExtension.base,
- &intelTexOffsetExtension.base,
&intelTexBufferExtension.base,
+ &intelFlushExtension.base,
+ &intelImageExtension.base,
+ &dri2ConfigQueryExtension.base,
NULL
};
ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
if (ret) {
- _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
+ if (ret != -EINVAL)
+ _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
return GL_FALSE;
}
return GL_TRUE;
}
-static GLboolean intelInitDriver(__DRIscreen *sPriv)
+static GLboolean
+intel_get_boolean(__DRIscreen *psp, int param)
{
- intelScreenPrivate *intelScreen;
- I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
- drm_i915_sarea_t *sarea;
-
- if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
- fprintf(stderr,
- "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
- return GL_FALSE;
- }
-
- /* Allocate the private area */
- intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate));
- if (!intelScreen) {
- fprintf(stderr, "\nERROR! Allocating private area failed\n");
- return GL_FALSE;
- }
- /* parse information in __driConfigOptions */
- driParseOptionInfo(&intelScreen->optionCache,
- __driConfigOptions, __driNConfigOptions);
-
- intelScreen->driScrnPriv = sPriv;
- sPriv->private = (void *) intelScreen;
- sarea = (drm_i915_sarea_t *)
- (((GLubyte *) sPriv->pSAREA) + gDRIPriv->sarea_priv_offset);
- intelScreen->sarea = sarea;
-
- intelScreen->deviceID = gDRIPriv->deviceID;
-
- intelUpdateScreenFromSAREA(intelScreen, sarea);
-
- if (!intelMapScreenRegions(sPriv)) {
- fprintf(stderr, "\nERROR! mapping regions\n");
- _mesa_free(intelScreen);
- sPriv->private = NULL;
- return GL_FALSE;
- }
-
- if (0)
- intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
-
- intelScreen->drmMinor = sPriv->drm_version.minor;
-
- /* Determine if IRQs are active? */
- if (!intel_get_param(sPriv, I915_PARAM_IRQ_ACTIVE,
- &intelScreen->irq_active))
- return GL_FALSE;
-
- sPriv->extensions = intelScreenExtensions;
-
- return GL_TRUE;
+ int value = 0;
+ return intel_get_param(psp, param, &value) && value;
}
+static void
+nop_callback(GLuint key, void *data, void *userData)
+{
+}
static void
intelDestroyScreen(__DRIscreen * sPriv)
{
- intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
+ struct intel_screen *intelScreen = sPriv->private;
dri_bufmgr_destroy(intelScreen->bufmgr);
- intelUnmapScreenRegions(intelScreen);
driDestroyOptionInfo(&intelScreen->optionCache);
+ /* Some regions may still have references to them at this point, so
+ * flush the hash table to prevent _mesa_DeleteHashTable() from
+ * complaining about the hash not being empty; */
+ _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
+ _mesa_DeleteHashTable(intelScreen->named_regions);
+
FREE(intelScreen);
sPriv->private = NULL;
}
static GLboolean
intelCreateBuffer(__DRIscreen * driScrnPriv,
__DRIdrawable * driDrawPriv,
- const __GLcontextModes * mesaVis, GLboolean isPixmap)
+ const struct gl_config * mesaVis, GLboolean isPixmap)
{
+ struct intel_renderbuffer *rb;
+ struct intel_screen *screen = (struct intel_screen*) driScrnPriv->private;
+
if (isPixmap) {
return GL_FALSE; /* not implemented */
}
else {
- GLboolean swStencil = (mesaVis->stencilBits > 0 &&
- mesaVis->depthBits != 24);
gl_format rgbFormat;
- struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer);
+ struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
- if (!intel_fb)
+ if (!fb)
return GL_FALSE;
- _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis);
+ _mesa_initialize_window_framebuffer(fb, mesaVis);
if (mesaVis->redBits == 5)
rgbFormat = MESA_FORMAT_RGB565;
rgbFormat = MESA_FORMAT_ARGB8888;
/* setup the hardware-based renderbuffers */
- intel_fb->color_rb[0] = intel_create_renderbuffer(rgbFormat);
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
- &intel_fb->color_rb[0]->Base);
+ rb = intel_create_renderbuffer(rgbFormat);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base);
if (mesaVis->doubleBufferMode) {
- intel_fb->color_rb[1] = intel_create_renderbuffer(rgbFormat);
-
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
- &intel_fb->color_rb[1]->Base);
-
+ rb = intel_create_renderbuffer(rgbFormat);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base);
}
+ /*
+ * Assert here that the gl_config has an expected depth/stencil bit
+ * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
+ * which constructs the advertised configs.)
+ */
if (mesaVis->depthBits == 24) {
- if (mesaVis->stencilBits == 8) {
- /* combined depth/stencil buffer */
- struct intel_renderbuffer *depthStencilRb
- = intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
- /* note: bind RB to two attachment points */
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
- &depthStencilRb->Base);
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL,
- &depthStencilRb->Base);
+ assert(mesaVis->stencilBits == 8);
+
+ if (screen->hw_has_separate_stencil
+ && screen->dri2_has_hiz != INTEL_DRI2_HAS_HIZ_FALSE) {
+ /*
+ * Request a separate stencil buffer even if we do not yet know if
+ * the screen supports it. (See comments for
+ * enum intel_dri2_has_hiz).
+ */
+ rb = intel_create_renderbuffer(MESA_FORMAT_X8_Z24);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base);
+ rb = intel_create_renderbuffer(MESA_FORMAT_S8);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base);
} else {
- struct intel_renderbuffer *depthRb
- = intel_create_renderbuffer(MESA_FORMAT_X8_Z24);
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
- &depthRb->Base);
+ /*
+ * Use combined depth/stencil. Note that the renderbuffer is
+ * attached to two attachment points.
+ */
+ rb = intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base);
}
}
else if (mesaVis->depthBits == 16) {
+ assert(mesaVis->stencilBits == 0);
/* just 16-bit depth buffer, no hw stencil */
struct intel_renderbuffer *depthRb
= intel_create_renderbuffer(MESA_FORMAT_Z16);
- _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+ else {
+ assert(mesaVis->depthBits == 0);
+ assert(mesaVis->stencilBits == 0);
}
/* now add any/all software-based renderbuffers we may need */
- _mesa_add_soft_renderbuffers(&intel_fb->Base,
+ _mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* never sw color */
GL_FALSE, /* never sw depth */
- swStencil, mesaVis->accumRedBits > 0,
+ GL_FALSE, /* never sw stencil */
+ mesaVis->accumRedBits > 0,
GL_FALSE, /* never sw alpha */
GL_FALSE /* never sw aux */ );
- driDrawPriv->driverPrivate = (void *) intel_fb;
+ driDrawPriv->driverPrivate = fb;
return GL_TRUE;
}
static void
intelDestroyBuffer(__DRIdrawable * driDrawPriv)
{
- struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate;
- struct intel_renderbuffer *depth_rb;
- struct intel_renderbuffer *stencil_rb;
-
- if (intel_fb) {
- if (intel_fb->color_rb[0]) {
- intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL);
- }
-
- if (intel_fb->color_rb[1]) {
- intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL);
- }
-
- depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
- if (depth_rb) {
- intel_renderbuffer_set_region(depth_rb, NULL);
- }
-
- stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
- if (stencil_rb) {
- intel_renderbuffer_set_region(stencil_rb, NULL);
- }
- }
-
- _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
-}
-
-
-/**
- * Get information about previous buffer swaps.
- */
-static int
-intelGetSwapInfo(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
-{
- struct intel_framebuffer *intel_fb;
-
- if ((dPriv == NULL) || (dPriv->driverPrivate == NULL)
- || (sInfo == NULL)) {
- return -1;
- }
-
- intel_fb = dPriv->driverPrivate;
- sInfo->swap_count = intel_fb->swap_count;
- sInfo->swap_ust = intel_fb->swap_ust;
- sInfo->swap_missed_count = intel_fb->swap_missed_count;
-
- sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
- ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust)
- : 0.0;
-
- return 0;
+ struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
+
+ _mesa_reference_framebuffer(&fb, NULL);
}
-
/* There are probably better ways to do this, such as an
* init-designated function to register chipids and createcontext
* functions.
*/
-extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis,
+extern GLboolean i830CreateContext(const struct gl_config * mesaVis,
__DRIcontext * driContextPriv,
void *sharedContextPrivate);
-extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis,
+extern GLboolean i915CreateContext(int api,
+ const struct gl_config * mesaVis,
__DRIcontext * driContextPriv,
void *sharedContextPrivate);
-extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis,
+extern GLboolean brwCreateContext(int api,
+ const struct gl_config * mesaVis,
__DRIcontext * driContextPriv,
void *sharedContextPrivate);
static GLboolean
-intelCreateContext(const __GLcontextModes * mesaVis,
+intelCreateContext(gl_api api,
+ const struct gl_config * mesaVis,
__DRIcontext * driContextPriv,
void *sharedContextPrivate)
{
__DRIscreen *sPriv = driContextPriv->driScreenPriv;
- intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
+ struct intel_screen *intelScreen = sPriv->private;
#ifdef I915
if (IS_9XX(intelScreen->deviceID)) {
if (!IS_965(intelScreen->deviceID)) {
- return i915CreateContext(mesaVis, driContextPriv,
+ return i915CreateContext(api, mesaVis, driContextPriv,
sharedContextPrivate);
}
} else {
}
#else
if (IS_965(intelScreen->deviceID))
- return brwCreateContext(mesaVis, driContextPriv, sharedContextPrivate);
+ return brwCreateContext(api, mesaVis,
+ driContextPriv, sharedContextPrivate);
#endif
- fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
+ fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
return GL_FALSE;
}
static GLboolean
-intel_init_bufmgr(intelScreenPrivate *intelScreen)
+intel_init_bufmgr(struct intel_screen *intelScreen)
{
- int gem_kernel = 0;
- struct drm_i915_getparam gp;
__DRIscreen *spriv = intelScreen->driScrnPriv;
int num_fences = 0;
- intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
-
- gp.param = I915_PARAM_HAS_GEM;
- gp.value = &gem_kernel;
-
- (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
-
- /* If we've got a new enough DDX that's initializing GEM and giving us
- * object handles for the shared buffers, use that.
- */
- if (!intelScreen->driScrnPriv->dri2.enabled &&
- intelScreen->driScrnPriv->ddx_version.minor < 9) {
- fprintf(stderr, "[%s:%u] Error initializing GEM.\n",
- __func__, __LINE__);
- return GL_FALSE;
- }
+ intelScreen->no_hw = (getenv("INTEL_NO_HW") != NULL ||
+ getenv("INTEL_DEVID_OVERRIDE") != NULL);
intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
- /* Otherwise, use the classic buffer manager. */
if (intelScreen->bufmgr == NULL) {
fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
__func__, __LINE__);
return GL_FALSE;
}
- if (intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences))
- intelScreen->kernel_exec_fencing = !!num_fences;
- else
- intelScreen->kernel_exec_fencing = GL_FALSE;
+ if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
+ num_fences == 0) {
+ fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
+ return GL_FALSE;
+ }
+
+ drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
+
+ intelScreen->named_regions = _mesa_NewHashTable();
+
+ intelScreen->relaxed_relocations = 0;
+ intelScreen->relaxed_relocations |=
+ intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
return GL_TRUE;
}
-struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
+/**
+ * Override intel_screen.hw_has_hiz with environment variable INTEL_HIZ.
+ *
+ * Valid values for INTEL_HIZ are "0" and "1". If an invalid valid value is
+ * encountered, a warning is emitted and INTEL_HIZ is ignored.
+ */
+static void
+intel_override_hiz(struct intel_screen *intel)
{
- /*
- * This should probably change to have the screen allocate a dummy
- * context at screen creation. For now just use the current context.
- */
-
- GET_CURRENT_CONTEXT(ctx);
- if (ctx == NULL) {
- _mesa_problem(NULL, "No current context in intelScreenContext\n");
- return NULL;
- }
- return intel_context(ctx);
+ const char *s = getenv("INTEL_HIZ");
+ if (!s) {
+ return;
+ } else if (!strncmp("0", s, 2)) {
+ intel->hw_has_hiz = false;
+ } else if (!strncmp("1", s, 2)) {
+ intel->hw_has_hiz = true;
+ } else {
+ fprintf(stderr,
+ "warning: env variable INTEL_HIZ=\"%s\" has invalid value "
+ "and is ignored", s);
+ }
+}
+
+/**
+ * Override intel_screen.hw_has_separate_stencil with environment variable
+ * INTEL_SEPARATE_STENCIL.
+ *
+ * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
+ * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
+ * is ignored.
+ */
+static void
+intel_override_separate_stencil(struct intel_screen *screen)
+{
+ const char *s = getenv("INTEL_SEPARATE_STENCIL");
+ if (!s) {
+ return;
+ } else if (!strncmp("0", s, 2)) {
+ screen->hw_has_separate_stencil = false;
+ } else if (!strncmp("1", s, 2)) {
+ screen->hw_has_separate_stencil = true;
+ } else {
+ fprintf(stderr,
+ "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
+ "invalid value and is ignored", s);
+ }
}
/**
* This is the driver specific part of the createNewScreen entry point.
* Called when using DRI2.
*
- * \return the __GLcontextModes supported by this driver
+ * \return the struct gl_config supported by this driver
*/
static const
__DRIconfig **intelInitScreen2(__DRIscreen *psp)
{
- intelScreenPrivate *intelScreen;
+ struct intel_screen *intelScreen;
GLenum fb_format[3];
GLenum fb_type[3];
- /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
- * support pageflipping at all.
- */
+ unsigned int api_mask;
+ char *devid_override;
+
static const GLenum back_buffer_modes[] = {
- GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
};
uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
int color;
__DRIconfig **configs = NULL;
/* Allocate the private area */
- intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate));
+ intelScreen = CALLOC(sizeof *intelScreen);
if (!intelScreen) {
fprintf(stderr, "\nERROR! Allocating private area failed\n");
return GL_FALSE;
intelScreen->driScrnPriv = psp;
psp->private = (void *) intelScreen;
- intelScreen->drmMinor = psp->drm_version.minor;
-
/* Determine chipset ID */
if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
&intelScreen->deviceID))
return GL_FALSE;
+ /* Allow an override of the device ID for the purpose of making the
+ * driver produce dumps for debugging of new chipset enablement.
+ * This implies INTEL_NO_HW, to avoid programming your actual GPU
+ * incorrectly.
+ */
+ devid_override = getenv("INTEL_DEVID_OVERRIDE");
+ if (devid_override) {
+ intelScreen->deviceID = strtod(devid_override, NULL);
+ }
+
+ if (IS_GEN7(intelScreen->deviceID)) {
+ intelScreen->gen = 7;
+ } else if (IS_GEN6(intelScreen->deviceID)) {
+ intelScreen->gen = 6;
+ } else if (IS_GEN5(intelScreen->deviceID)) {
+ intelScreen->gen = 5;
+ } else if (IS_965(intelScreen->deviceID)) {
+ intelScreen->gen = 4;
+ } else if (IS_9XX(intelScreen->deviceID)) {
+ intelScreen->gen = 3;
+ } else {
+ intelScreen->gen = 2;
+ }
+
+ /*
+ * FIXME: The hiz and separate stencil fields need updating once the
+ * FIXME: features are completely implemented for a given chipset.
+ */
+ intelScreen->hw_has_separate_stencil = intelScreen->gen >= 7;
+ intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
+ intelScreen->hw_has_hiz = false;
+ intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_UNKNOWN;
+
+ intel_override_hiz(intelScreen);
+ intel_override_separate_stencil(intelScreen);
+
+ api_mask = (1 << __DRI_API_OPENGL);
+#if FEATURE_ES1
+ api_mask |= (1 << __DRI_API_GLES);
+#endif
+#if FEATURE_ES2
+ api_mask |= (1 << __DRI_API_GLES2);
+#endif
+
+ if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
+ psp->api_mask = api_mask;
+
if (!intel_init_bufmgr(intelScreen))
return GL_FALSE;
- intelScreen->irq_active = 1;
psp->extensions = intelScreenExtensions;
- depth_bits[0] = 0;
- stencil_bits[0] = 0;
- depth_bits[1] = 16;
- stencil_bits[1] = 0;
- depth_bits[2] = 24;
- stencil_bits[2] = 0;
- depth_bits[3] = 24;
- stencil_bits[3] = 8;
-
msaa_samples_array[0] = 0;
fb_format[0] = GL_RGB;
depth_bits[0] = 0;
stencil_bits[0] = 0;
+ /* Generate a rich set of useful configs that do not include an
+ * accumulation buffer.
+ */
for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
__DRIconfig **new_configs;
int depth_factor;
- /* With DRI2 right now, GetBuffers always returns a depth/stencil buffer
- * with the same cpp as the drawable. So we can't support depth cpp !=
- * color cpp currently.
+ /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
+ * buffer that has a diffferent number of bits per pixel than the color
+ * buffer. This isn't yet supported here.
*/
if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
depth_bits[1] = 16;
stencil_bits[1] = 0;
-
- depth_factor = 2;
} else {
depth_bits[1] = 24;
- stencil_bits[1] = 0;
- depth_bits[2] = 24;
- stencil_bits[2] = 8;
-
- depth_factor = 3;
+ stencil_bits[1] = 8;
}
+
+ depth_factor = 2;
+
new_configs = driCreateConfigs(fb_format[color], fb_type[color],
depth_bits,
stencil_bits,
back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_samples_array,
- ARRAY_SIZE(msaa_samples_array));
+ ARRAY_SIZE(msaa_samples_array),
+ GL_FALSE);
+ if (configs == NULL)
+ configs = new_configs;
+ else
+ configs = driConcatConfigs(configs, new_configs);
+ }
+
+ /* Generate the minimum possible set of configs that include an
+ * accumulation buffer.
+ */
+ for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
+ __DRIconfig **new_configs;
+
+ if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
+ depth_bits[0] = 16;
+ stencil_bits[0] = 0;
+ } else {
+ depth_bits[0] = 24;
+ stencil_bits[0] = 8;
+ }
+
+ new_configs = driCreateConfigs(fb_format[color], fb_type[color],
+ depth_bits, stencil_bits, 1,
+ back_buffer_modes + 1, 1,
+ msaa_samples_array, 1,
+ GL_TRUE);
if (configs == NULL)
configs = new_configs;
else
return (const __DRIconfig **)configs;
}
+struct intel_buffer {
+ __DRIbuffer base;
+ struct intel_region *region;
+};
+
+static __DRIbuffer *
+intelAllocateBuffer(__DRIscreen *screen,
+ unsigned attachment, unsigned format,
+ int width, int height)
+{
+ struct intel_buffer *intelBuffer;
+ struct intel_screen *intelScreen = screen->private;
+ uint32_t tiling;
+
+ intelBuffer = CALLOC(sizeof *intelBuffer);
+ if (intelBuffer == NULL)
+ return NULL;
+
+ if ((attachment == __DRI_BUFFER_DEPTH ||
+ attachment == __DRI_BUFFER_STENCIL ||
+ attachment == __DRI_BUFFER_DEPTH_STENCIL) &&
+ intelScreen->gen >= 4)
+ tiling = I915_TILING_Y;
+ else
+ tiling = I915_TILING_X;
+
+ intelBuffer->region = intel_region_alloc(intelScreen, tiling,
+ format / 8, width, height, GL_TRUE);
+
+ if (intelBuffer->region == NULL) {
+ FREE(intelBuffer);
+ return NULL;
+ }
+
+ intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
+
+ intelBuffer->base.attachment = attachment;
+ intelBuffer->base.cpp = intelBuffer->region->cpp;
+ intelBuffer->base.pitch =
+ intelBuffer->region->pitch * intelBuffer->region->cpp;
+
+ return &intelBuffer->base;
+}
+
+static void
+intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
+{
+ struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
+
+ intel_region_release(&intelBuffer->region);
+ free(intelBuffer);
+}
+
+
const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = intelDestroyScreen,
.CreateContext = intelCreateContext,
.DestroyContext = intelDestroyContext,
.CreateBuffer = intelCreateBuffer,
.DestroyBuffer = intelDestroyBuffer,
- .SwapBuffers = intelSwapBuffers,
.MakeCurrent = intelMakeCurrent,
.UnbindContext = intelUnbindContext,
- .GetSwapInfo = intelGetSwapInfo,
- .GetDrawableMSC = driDrawableGetMSC32,
- .WaitForMSC = driWaitForMSC32,
-
.InitScreen2 = intelInitScreen2,
+ .AllocateBuffer = intelAllocateBuffer,
+ .ReleaseBuffer = intelReleaseBuffer
};
/* This is the table of extensions that the loader will dlsym() for. */