From c5c73c1b605611faf0f06df9b5d08d8984388238 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 21 Jan 2008 17:07:33 -0500 Subject: [PATCH] Hook up i915 driver to new DRI2 infrastructure. --- src/mesa/drivers/dri/i915/intel_context.c | 75 +++++---- src/mesa/drivers/dri/intel/intel_blit.c | 4 +- src/mesa/drivers/dri/intel/intel_buffers.c | 3 +- src/mesa/drivers/dri/intel/intel_regions.c | 48 +++++- src/mesa/drivers/dri/intel/intel_regions.h | 5 + src/mesa/drivers/dri/intel/intel_screen.c | 187 +++++++++++++++++++++ 6 files changed, 277 insertions(+), 45 deletions(-) diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index b2d9c9c5918..3b6a1d5ef95 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -417,7 +417,7 @@ intelInitContext(struct intel_context *intel, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + intel->driHwLock = sPriv->lock; intel->width = intelScreen->width; intel->height = intelScreen->height; @@ -523,7 +523,8 @@ intelInitContext(struct intel_context *intel, if (intel->ttm) driInitExtensions(ctx, ttm_extensions, GL_FALSE); - intel_recreate_static_regions(intel); + if (!sPriv->dri2.enabled) + intel_recreate_static_regions(intel); intel->batch = intel_batchbuffer_alloc(intel); intel->last_swap_fence = NULL; @@ -633,7 +634,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, /* XXX FBO temporary fix-ups! */ /* if the renderbuffers don't have regions, init them from the context */ - { + if (!driContextPriv->driScreenPriv->dri2.enabled) { struct intel_renderbuffer *irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); struct intel_renderbuffer *irbStencil @@ -709,6 +710,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags) __DRIdrawablePrivate *dPriv = intel->driDrawable; __DRIscreenPrivate *sPriv = intel->driScreen; drmI830Sarea *sarea = intel->sarea; + int drawable_changed = 0; drmGetLock(intel->driFd, intel->hHWContext, flags); @@ -720,8 +722,12 @@ intelContendedLock(struct intel_context *intel, GLuint flags) * NOTE: This releases and regains the hw lock, so all state * checking must be done *after* this call: */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + if (dPriv) { + if (sPriv->dri2.enabled) + drawable_changed = __driParseEvents(sPriv, dPriv); + else + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + } /* If the last consumer of the texture memory wasn't us, notify the fake * bufmgr and record the new owner. We should have the memory shared @@ -735,42 +741,47 @@ intelContendedLock(struct intel_context *intel, GLuint flags) intel_decode_context_reset(); } - if (sarea->width != intel->width || - sarea->height != intel->height) { - int numClipRects = intel->numClipRects; + if (!sPriv->dri2.enabled) { + if (sarea->width != intel->width || + sarea->height != intel->height) { + int numClipRects = intel->numClipRects; - /* - * FIXME: Really only need to do this when drawing to a - * common back- or front buffer. - */ + /* + * FIXME: Really only need to do this when drawing to a + * common back- or front buffer. + */ - /* - * This will essentially drop the outstanding batchbuffer on the floor. - */ - intel->numClipRects = 0; + /* + * This will essentially drop the outstanding batchbuffer on the floor. + */ + intel->numClipRects = 0; - if (intel->Fallback) - _swrast_flush(&intel->ctx); + if (intel->Fallback) + _swrast_flush(&intel->ctx); - INTEL_FIREVERTICES(intel); + INTEL_FIREVERTICES(intel); - if (intel->batch->map != intel->batch->ptr) - intel_batchbuffer_flush(intel->batch); + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); - intel->numClipRects = numClipRects; + intel->numClipRects = numClipRects; - /* force window update */ - intel->lastStamp = 0; + /* force window update */ + intel->lastStamp = 0; - intel->width = sarea->width; - intel->height = sarea->height; - } + intel->width = sarea->width; + intel->height = sarea->height; + } - /* Drawable changed? - */ - if (dPriv && intel->lastStamp != dPriv->lastStamp) { - intelWindowMoved(intel); - intel->lastStamp = dPriv->lastStamp; + /* Drawable changed? + */ + if (dPriv && intel->lastStamp != dPriv->lastStamp) { + intelWindowMoved(intel); + intel->lastStamp = dPriv->lastStamp; + } + } else if (drawable_changed) { + intelWindowMoved(intel); + intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); } } diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index f7968db92f6..f4358bb3ddf 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -132,9 +132,7 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, } if (box.x1 >= box.x2 || - box.y1 >= box.y2 || - box.x2 > intelScreen->width || - box.y2 > intelScreen->height) + box.y1 >= box.y2) continue; assert(box.x1 < box.x2); diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index a77e498b863..d6665081ff9 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -302,7 +302,8 @@ intelWindowMoved(struct intel_context *intel) } } - if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { + if (!intel->intelScreen->driScrnPriv->dri2.enabled && + intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { volatile drmI830Sarea *sarea = intel->sarea; drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index dcf32d9f84f..8bc548913f4 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -76,27 +76,57 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region) } } -struct intel_region * -intel_region_alloc(struct intel_context *intel, - GLuint cpp, GLuint pitch, GLuint height) +static struct intel_region * +intel_region_alloc_internal(struct intel_context *intel, + GLuint cpp, GLuint pitch, GLuint height, + GLuint tiled, dri_bo *buffer) { - struct intel_region *region = calloc(sizeof(*region), 1); + struct intel_region *region; DBG("%s\n", __FUNCTION__); + if (buffer == NULL) + return NULL; + + region = calloc(sizeof(*region), 1); region->cpp = cpp; region->pitch = pitch; region->height = height; /* needed? */ region->refcount = 1; + region->tiled = tiled; + region->buffer = buffer; - region->buffer = dri_bo_alloc(intel->bufmgr, "region", - pitch * cpp * height, 64, - DRM_BO_FLAG_MEM_LOCAL | - DRM_BO_FLAG_CACHED | - DRM_BO_FLAG_CACHED_MAPPED); return region; } +struct intel_region * +intel_region_alloc(struct intel_context *intel, + GLuint cpp, GLuint pitch, GLuint height) +{ + dri_bo *buffer; + + buffer = dri_bo_alloc(intel->bufmgr, "region", + pitch * cpp * height, 64, + DRM_BO_FLAG_MEM_LOCAL | + DRM_BO_FLAG_CACHED | + DRM_BO_FLAG_CACHED_MAPPED); + + return intel_region_alloc_internal(intel, cpp, pitch, height, 0, buffer); +} + +struct intel_region * +intel_region_alloc_for_handle(struct intel_context *intel, + GLuint cpp, GLuint pitch, GLuint height, + GLuint tiled, GLuint handle) +{ + dri_bo *buffer; + + buffer = intel_ttm_bo_create_from_handle(intel->bufmgr, "region", handle); + + return intel_region_alloc_internal(intel, + cpp, pitch, height, tiled, buffer); +} + void intel_region_reference(struct intel_region **dst, struct intel_region *src) { diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index 0d1dabe9ca7..229f79aeba7 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -66,6 +66,11 @@ struct intel_region *intel_region_alloc(struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height); +struct intel_region * +intel_region_alloc_for_handle(struct intel_context *intel, + GLuint cpp, GLuint pitch, GLuint height, + GLuint tiled, unsigned int handle); + void intel_region_reference(struct intel_region **dst, struct intel_region *src); diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 84c77d39919..7e0c52005de 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -49,6 +49,7 @@ #include "i830_dri.h" #include "intel_regions.h" #include "intel_batchbuffer.h" +#include "intel_bufmgr_ttm.h" PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -287,6 +288,111 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelPrintSAREA(sarea); } +static void +intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, + __DRIDrawableConfigEvent *event) +{ + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_region *region; + struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; + struct intel_context *intel = dPriv->driContextPriv->driverPrivate; + int cpp = intel->ctx.Visual.rgbBits / 8; + GLuint pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; + + rb = intel_fb->color_rb[1]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + rb = intel_fb->color_rb[2]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (depth_rb || stencil_rb) + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + if (depth_rb) + intel_renderbuffer_set_region(depth_rb, region); + if (stencil_rb) + intel_renderbuffer_set_region(stencil_rb, region); + + /* FIXME: Tell the X server about the regions we just allocated and + * attached. */ +} + +#define BUFFER_FLAG_TILED 0x0100 + +static void +intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, + __DRIBufferAttachEvent *ba) +{ + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_renderbuffer *rb; + struct intel_region *region; + struct intel_context *intel = dPriv->driContextPriv->driverPrivate; + GLuint tiled; + + switch (ba->buffer.attachment) { + case DRI_DRAWABLE_BUFFER_FRONT_LEFT: + rb = intel_fb->color_rb[0]; + break; + + case DRI_DRAWABLE_BUFFER_BACK_LEFT: + rb = intel_fb->color_rb[0]; + break; + + case DRI_DRAWABLE_BUFFER_DEPTH: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + break; + + case DRI_DRAWABLE_BUFFER_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + break; + + case DRI_DRAWABLE_BUFFER_ACCUM: + default: + fprintf(stderr, "unhandled buffer attach event, attacment type %d\n", + ba->buffer.attachment); + return; + } + +#if 0 + /* FIXME: Add this so we can filter out when the X server sends us + * attachment events for the buffers we just allocated. Need to + * get the BO handle for a render buffer. */ + if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle) + return; +#endif + + tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0; + region = intel_region_alloc_for_handle(intel, ba->buffer.cpp, + ba->buffer.pitch / ba->buffer.cpp, + dPriv->h, tiled, + ba->buffer.handle); + + intel_renderbuffer_set_region(rb, region); +} + +static void +intelUpdateBuffer(__DRIdrawablePrivate *dPriv, unsigned int *event) +{ + switch (DRI2_EVENT_TYPE(*event)) { + case DRI2_EVENT_DRAWABLE_CONFIG: + /* flush all current regions, allocate new ones, except front buffer */ + intelHandleDrawableConfig(dPriv, (__DRIDrawableConfigEvent *) event); + break; + + case DRI2_EVENT_BUFFER_ATTACH: + /* attach buffer if different from what we have */ + intelHandleBufferAttach(dPriv, (__DRIBufferAttachEvent *) event); + break; + } +} + static const __DRItexOffsetExtension intelTexOffsetExtension = { { __DRI_TEX_OFFSET }, intelSetTexOffset, @@ -569,6 +675,7 @@ static const struct __DriverAPIRec intelAPI = { #ifdef I915 .setTexOffset = intelSetTexOffset, #endif + .UpdateBuffer = intelUpdateBuffer, }; @@ -723,3 +830,83 @@ struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) return intel_context(ctx); } +/** + * This is the driver specific part of the createNewScreen entry point. + * + * \return the __GLcontextModes supported by this driver + */ +PUBLIC __GLcontextModes *__dri2DriverInitScreen(__DRIscreenPrivate *psp) +{ + static const __DRIversion ddx_expected = { 1, 9, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 5, 0 }; + intelScreenPrivate *intelScreen; + __GLcontextModes *modes, *m; + + psp->DriverAPI = intelAPI; + + if (!driCheckDriDdxDrmVersions2("i915", + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { + fprintf(stderr, "bad version voodoo\n"); + return NULL; + } + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + driInitExtensions(NULL, ttm_extensions, 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 = 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; + + /* Determine if IRQs are active? */ + if (!intel_get_param(psp, I830_PARAM_IRQ_ACTIVE, + &intelScreen->irq_active)) + return GL_FALSE; + + /* Determine if batchbuffers are allowed */ + if (!intel_get_param(psp, I830_PARAM_ALLOW_BATCHBUFFER, + &intelScreen->allow_batchbuffer)) + return GL_FALSE; + + if (!intelScreen->allow_batchbuffer) { + fprintf(stderr, "batch buffer not allowed\n"); + return GL_FALSE; + } + + psp->extensions = intelExtensions; + + modes = intelFillInModes(16, 16, 0, 1); + for (m = modes; m->next != NULL; m = m->next) + ; + m->next = intelFillInModes(32, 24, 8, 1); + + return modes; +} -- 2.30.2