diff options
Diffstat (limited to 'src/mesa/drivers')
49 files changed, 1239 insertions, 700 deletions
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 8f67798a08..9d94ca3b39 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -231,7 +231,7 @@ alloc_block(dri_bo *bo) dri_bo_fake *bo_fake = (dri_bo_fake *)bo; dri_bufmgr_fake *bufmgr_fake= (dri_bufmgr_fake *)bo->bufmgr; struct block *block = (struct block *)calloc(sizeof *block, 1); - unsigned int align_log2 = ffs(bo_fake->alignment); + unsigned int align_log2 = _mesa_ffs(bo_fake->alignment); GLuint sz; if (!block) @@ -660,10 +660,12 @@ dri_fake_bo_unreference(dri_bo *bo) for (i = 0; i < bo_fake->nr_relocs; i++) dri_bo_unreference(bo_fake->relocs[i].target_buf); - free(bo_fake->relocs); + DBG("drm_bo_unreference: free buf %d %s\n", bo_fake->id, bo_fake->name); + + free(bo_fake->relocs); free(bo); - DBG("drm_bo_unreference: free %s\n", bo_fake->name); + return; } } @@ -924,6 +926,8 @@ dri_fake_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta, dri_bo_fake *reloc_fake = (dri_bo_fake *)reloc_buf; int i; + assert(reloc_buf); + assert(target_buf); if (reloc_fake->relocs == NULL) { reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) * MAX_RELOCS); diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 89c1a099d9..1f5d65265c 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -49,6 +49,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen, const __GLcontextModes *modes, __DRIdrawable *pdraw, drm_drawable_t hwDrawable, + unsigned int head, int renderType, const int *attrs); static void driDestroyDrawable(__DRIdrawable *drawable); @@ -192,8 +193,8 @@ static GLboolean driBindContext(__DRIcontext * ctx, */ if (psp->dri2.enabled) { - __driParseEvents(psp, pdp); - __driParseEvents(psp, prp); + __driParseEvents(pcp, pdp); + __driParseEvents(pcp, prp); } else { if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); @@ -285,17 +286,14 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) } int -__driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp) +__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp) { - __DRIDrawableConfigEvent *dc; - __DRIBufferAttachEvent *ba; + __DRIscreenPrivate *psp = pcp->driScreenPriv; + __DRIDrawableConfigEvent *dc, *last_dc; + __DRIBufferAttachEvent *ba, *last_ba; unsigned int tail, mask, *p, end, total, size, changed; unsigned char *data; size_t rect_size; - __DRIcontextPrivate *pcp = pdp->driContextPriv; - - if (pcp == NULL) - return 0; /* Check for wraparound. */ if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) { @@ -303,18 +301,20 @@ __driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp) * server overwrote it and we have to reset our tail * pointer. */ DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext); - (*psp->dri2.core->reemitDrawableInfo)(pdp->pdraw); + (*psp->dri2.core->reemitDrawableInfo)(pdp->pdraw, &pdp->dri2.tail); DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext); } total = psp->dri2.buffer->head - pdp->dri2.tail; mask = psp->dri2.buffer->size - 1; - tail = pdp->dri2.tail; end = psp->dri2.buffer->head; data = psp->dri2.buffer->data; + changed = 0; + last_dc = NULL; + last_ba = NULL; - while (tail != end) { + for (tail = pdp->dri2.tail; tail != end; tail += size) { p = (unsigned int *) (data + (tail & mask)); size = DRI2_EVENT_SIZE(*p); if (size > total || (tail & mask) + size > psp->dri2.buffer->size) { @@ -326,50 +326,92 @@ __driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp) switch (DRI2_EVENT_TYPE(*p)) { case DRI2_EVENT_DRAWABLE_CONFIG: dc = (__DRIDrawableConfigEvent *) p; - - if (dc->drawable != pdp->hHWDrawable) - break; - - if (pdp->w != dc->width || pdp->h != dc->height) - changed = 1; - - pdp->x = dc->x; - pdp->y = dc->y; - pdp->w = dc->width; - pdp->h = dc->height; - - pdp->backX = 0; - pdp->backY = 0; - pdp->numBackClipRects = 1; - pdp->pBackClipRects[0].x1 = 0; - pdp->pBackClipRects[0].y1 = 0; - pdp->pBackClipRects[0].x2 = pdp->w; - pdp->pBackClipRects[0].y2 = pdp->h; - - pdp->numClipRects = dc->num_rects; - _mesa_free(pdp->pClipRects); - rect_size = dc->num_rects * sizeof dc->rects[0]; - pdp->pClipRects = _mesa_malloc(rect_size); - memcpy(pdp->pClipRects, dc->rects, rect_size); - - if (changed) - (*psp->DriverAPI.UpdateBuffer)(pdp, p); + if (dc->drawable == pdp->hHWDrawable) + last_dc = dc; break; case DRI2_EVENT_BUFFER_ATTACH: ba = (__DRIBufferAttachEvent *) p; + if (ba->drawable == pdp->hHWDrawable && + ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT) + last_ba = ba; + break; + } + } + + if (last_dc) { + if (pdp->w != last_dc->width || pdp->h != last_dc->height) + changed = 1; + + pdp->x = last_dc->x; + pdp->y = last_dc->y; + pdp->w = last_dc->width; + pdp->h = last_dc->height; + + pdp->backX = 0; + pdp->backY = 0; + pdp->numBackClipRects = 1; + pdp->pBackClipRects[0].x1 = 0; + pdp->pBackClipRects[0].y1 = 0; + pdp->pBackClipRects[0].x2 = pdp->w; + pdp->pBackClipRects[0].y2 = pdp->h; + + pdp->numClipRects = last_dc->num_rects; + _mesa_free(pdp->pClipRects); + rect_size = last_dc->num_rects * sizeof last_dc->rects[0]; + pdp->pClipRects = _mesa_malloc(rect_size); + memcpy(pdp->pClipRects, last_dc->rects, rect_size); + + if (changed) + (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); + } - if (ba->drawable != pdp->hHWDrawable) - break; + /* Front buffer attachments are special, they typically mean that + * we're rendering to a redirected window (or a child window of a + * redirected window) and that it got resized. Resizing the root + * window on randr events is a special case of this. Other causes + * may be a window transitioning between redirected and + * non-redirected, or a window getting reparented between parents + * with different window pixmaps (eg two redirected windows). + * These events are special in that the X server allocates the + * buffer and that the buffer may be shared by other child + * windows. When our window share the window pixmap with its + * parent, drawable config events doesn't affect the front buffer. + * We only care about the last such event in the buffer; in fact, + * older events will refer to invalid buffer objects.*/ + if (last_ba) + (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba); + + /* Like for buffer attachments, we only care about the most recent + * drawable config. */ + if (last_dc) + (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); + + /* If there was a drawable config event in the buffer and it + * changed the size of the window, all buffer auxillary buffer + * attachments prior to that are invalid (as opposed to the front + * buffer case discussed above). In that case we can start + * looking for buffer attachment after the last drawable config + * event. If there is no drawable config event in this batch of + * events, we have to assume that the last batch might have had + * one and process all buffer attach events.*/ + if (last_dc && changed) + tail = (unsigned char *) last_dc - data; + else + tail = pdp->dri2.tail; - (*psp->DriverAPI.UpdateBuffer)(pdp, p); - break; + for ( ; tail != end; tail += size) { + ba = (__DRIBufferAttachEvent *) (data + (tail & mask)); + size = DRI2_EVENT_SIZE(ba->event_header); - default: - break; - } + if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH) + continue; + if (ba->drawable != pdp->hHWDrawable) + continue; + if (last_ba == ba) + continue; - tail += size; + (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba); } pdp->dri2.tail = tail; @@ -508,13 +550,13 @@ static void *driCreateNewDrawable(__DRIscreen *screen, const __GLcontextModes *modes, __DRIdrawable *pdraw, drm_drawable_t hwDrawable, + unsigned int head, int renderType, const int *attrs) { __DRIscreenPrivate *psp; __DRIdrawablePrivate *pdp; - pdraw->private = NULL; /* Since pbuffers are not yet supported, no drawable attributes are @@ -568,7 +610,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen, pdp->swapBuffers = psp->DriverAPI.SwapBuffers; if (psp->dri2.enabled) { - pdp->dri2.tail = 0; + pdp->dri2.tail = head; pdp->pBackClipRects = _mesa_malloc(sizeof *pdp->pBackClipRects); } diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index e6659811d7..59c64e4adf 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -209,8 +209,14 @@ struct __DriverAPIRec { int64_t *count); /* DRI2 Entry points */ - void (*UpdateBuffer)(__DRIdrawablePrivate *dPriv, - unsigned int *event); + void (*HandleDrawableConfig)(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIDrawableConfigEvent *event); + + void (*HandleBufferAttach)(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIBufferAttachEvent *ba); + }; @@ -559,7 +565,7 @@ extern void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp); extern int -__driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp); +__driParseEvents(__DRIcontextPrivate *psp, __DRIdrawablePrivate *pdp); extern float driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 9bc868b043..d1b07c5a2f 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -609,11 +609,12 @@ i830_state_draw_region(struct intel_context *intel, static void i830_set_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) + struct intel_region *color_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct i830_context *i830 = i830_context(&intel->ctx); - i830_state_draw_region(intel, &i830->state, color_region, depth_region); + i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region); } #if 0 @@ -665,6 +666,11 @@ i830_assert_not_dirty( struct intel_context *intel ) assert(!get_dirty(state)); } +static void +i830_note_unlock( struct intel_context *intel ) +{ + /* nothing */ +} void i830InitVtbl(struct i830_context *i830) @@ -680,4 +686,5 @@ i830InitVtbl(struct i830_context *i830) i830->intel.vtbl.render_start = i830_render_start; i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; + i830->intel.vtbl.note_unlock = i830_note_unlock; } diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c index dfd02112ba..b5085f49d4 100644 --- a/src/mesa/drivers/dri/i915/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -25,8 +25,8 @@ * **************************************************************************/ -/* Code to layout images in a mipmap tree for i915 and i945 - * respectively. +/** @file i915_tex_layout.c + * Code to layout images in a mipmap tree for i830M-GM915 and G945 and beyond. */ #include "intel_mipmap_tree.h" @@ -36,141 +36,206 @@ #define FILE_DEBUG_FLAG DEBUG_TEXTURE -static GLint initial_offsets[6][2] = { {0, 0}, -{0, 2}, -{1, 0}, -{1, 2}, -{1, 1}, -{1, 3} +static GLint initial_offsets[6][2] = { + [FACE_POS_X] = {0, 0}, + [FACE_POS_Y] = {1, 0}, + [FACE_POS_Z] = {1, 1}, + [FACE_NEG_X] = {0, 2}, + [FACE_NEG_Y] = {1, 2}, + [FACE_NEG_Z] = {1, 3}, }; -static GLint step_offsets[6][2] = { {0, 2}, -{0, 2}, -{-1, 2}, -{-1, 2}, -{-1, 1}, -{-1, 1} +static GLint step_offsets[6][2] = { + [FACE_POS_X] = {0, 2}, + [FACE_POS_Y] = {-1, 2}, + [FACE_POS_Z] = {-1, 1}, + [FACE_NEG_X] = {0, 2}, + [FACE_NEG_Y] = {-1, 2}, + [FACE_NEG_Z] = {-1, 1}, }; -GLboolean -i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +/** + * Cube texture map layout for i830M-GM915. + * + * Hardware layout looks like: + * + * +-------+-------+ + * | | | + * | | | + * | | | + * | +x | +y | + * | | | + * | | | + * | | | + * | | | + * +---+---+-------+ + * | | | | + * | +x| +y| | + * | | | | + * | | | | + * +-+-+---+ +z | + * | | | | | + * +-+-+ +z| | + * | | | | + * +-+-+---+-------+ + * | | | + * | | | + * | | | + * | -x | -y | + * | | | + * | | | + * | | | + * | | | + * +---+---+-------+ + * | | | | + * | -x| -y| | + * | | | | + * | | | | + * +-+-+---+ -z | + * | | | | | + * +-+-+ -z| | + * | | | | + * +-+---+-------+ + * + */ +static void +i915_miptree_layout_cube(struct intel_context *intel, + struct intel_mipmap_tree * mt) { + const GLuint dim = mt->width0; + GLuint face; + GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; GLint level; - switch (mt->target) { - case GL_TEXTURE_CUBE_MAP:{ - const GLuint dim = mt->width0; - GLuint face; - GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* double pitch for cube layouts */ - mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2); - mt->total_height = dim * 4; - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_level_info(mt, level, 6, - 0, 0, - /*OLD: mt->pitch, mt->total_height,*/ - lvlWidth, lvlHeight, - 1); - lvlWidth /= 2; - lvlHeight /= 2; - } - - for (face = 0; face < 6; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_image_offset(mt, level, face, x, y); - - if (d == 0) - _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", - face, level, mt->first_level, mt->last_level); - - d >>= 1; - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - } - } - break; - } - case GL_TEXTURE_3D:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; - GLuint stack_height = 0; - - /* Calculate the size of a single slice. - */ - mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); - - /* XXX: hardware expects/requires 9 levels at minimum. - */ - for (level = mt->first_level; level <= MAX2(8, mt->last_level); - level++) { - intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, - width, height, depth); - - - stack_height += MAX2(2, height); - - width = minify(width); - height = minify(height); - depth = minify(depth); - } - - /* Fixup depth image_offsets: - */ - depth = mt->depth0; - for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint i; - for (i = 0; i < depth; i++) - intel_miptree_set_image_offset(mt, level, i, - 0, i * stack_height); - - depth = minify(depth); - } - - - /* Multiply slice size by texture depth for total size. It's - * remarkable how wasteful of memory the i915 texture layouts - * are. They are largely fixed in the i945. - */ - mt->total_height = stack_height * mt->depth0; - break; + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* double pitch for cube layouts */ + mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2); + mt->total_height = dim * 4; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + /*OLD: mt->pitch, mt->total_height,*/ + lvlWidth, lvlHeight, + 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + if (d == 0) + _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", + face, level, mt->first_level, mt->last_level); + + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; } + } +} - default:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint img_height; +static void +i915_miptree_layout_3d(struct intel_context *intel, + struct intel_mipmap_tree * mt) +{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint stack_height = 0; + GLint level; - mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); - mt->total_height = 0; + /* Calculate the size of a single slice. */ + mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_level_info(mt, level, 1, - 0, mt->total_height, - width, height, 1); + /* XXX: hardware expects/requires 9 levels at minimum. */ + for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) { + intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, + width, height, depth); - if (mt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = (MAX2(2, height) + 1) & ~1; + stack_height += MAX2(2, height); - mt->total_height += img_height; + width = minify(width); + height = minify(height); + depth = minify(depth); + } - width = minify(width); - height = minify(height); - } - break; + /* Fixup depth image_offsets: */ + depth = mt->depth0; + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint i; + for (i = 0; i < depth; i++) { + intel_miptree_set_image_offset(mt, level, i, + 0, i * stack_height); } + + depth = minify(depth); + } + + /* Multiply slice size by texture depth for total size. It's + * remarkable how wasteful of memory the i915 texture layouts + * are. They are largely fixed in the i945. + */ + mt->total_height = stack_height * mt->depth0; +} + +static void +i915_miptree_layout_2d(struct intel_context *intel, + struct intel_mipmap_tree * mt) +{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint img_height; + GLint level; + + mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); + mt->total_height = 0; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 1, + 0, mt->total_height, + width, height, 1); + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = (MAX2(2, height) + 1) & ~1; + + mt->total_height += img_height; + + width = minify(width); + height = minify(height); + } +} + +GLboolean +i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +{ + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP: + i915_miptree_layout_cube(intel, mt); + break; + case GL_TEXTURE_3D: + i915_miptree_layout_3d(intel, mt); + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE_ARB: + i915_miptree_layout_2d(intel, mt); + break; + default: + _mesa_problem(NULL, "Unexpected tex target in i915_miptree_layout()"); + break; } + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, mt->pitch, mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); @@ -179,160 +244,229 @@ i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) } -GLboolean -i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +/** + * Cube texture map layout for GM945 and later. + * + * The hardware layout looks like the 830-915 layout, except for the small + * sizes. A zoomed in view of the layout for 945 is: + * + * +-------+-------+ + * | 8x8 | 8x8 | + * | | | + * | | | + * | +x | +y | + * | | | + * | | | + * | | | + * | | | + * +---+---+-------+ + * |4x4| | 8x8 | + * | +x| | | + * | | | | + * | | | | + * +---+ | +z | + * |4x4| | | + * | +y| | | + * | | | | + * +---+ +-------+ + * + * ... + * + * +-------+-------+ + * | 8x8 | 8x8 | + * | | | + * | | | + * | -x | -y | + * | | | + * | | | + * | | | + * | | | + * +---+---+-------+ + * |4x4| | 8x8 | + * | -x| | | + * | | | | + * | | | | + * +---+ | -z | + * |4x4| | | + * | -y| | | + * | | | | + * +---+ +---+---+---+---+---+---+---+---+---+ + * |4x4| |4x4| |2x2| |2x2| |2x2| |2x2| + * | +z| | -z| | +x| | +y| | +z| | -x| ... + * | | | | | | | | | | | | + * +---+ +---+ +---+ +---+ +---+ +---+ + * + * The bottom row continues with the remaining 2x2 then the 1x1 mip contents + * in order, with each of them aligned to a 4x4 block boundary. Thus, for + * 32x32 cube maps and smaller, the bottom row layout is going to dictate the + * pitch of the tree. For a tree with 4x4 images, the pitch is at least + * 14 * 8 = 112 texels, for 2x2 it is at least 12 * 8 texels, and for 1x1 + * it is 6 * 8 texels. + */ + +static void +i945_miptree_layout_cube(struct intel_context *intel, + struct intel_mipmap_tree * mt) { + const GLuint dim = mt->width0; + GLuint face; + GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; GLint level; - switch (mt->target) { - case GL_TEXTURE_CUBE_MAP:{ - const GLuint dim = mt->width0; - GLuint face; - GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) - mt->pitch = intel_miptree_pitch_align (intel, mt, dim); - else - mt->pitch = 14 * 8; - - mt->total_height = dim * 4 + 4; - - /* Set all the levels to effectively occupy the whole rectangular region. - */ - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_level_info(mt, level, 6, - 0, 0, - lvlWidth, lvlHeight, 1); - lvlWidth /= 2; - lvlHeight /= 2; + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2); + else + mt->pitch = intel_miptree_pitch_align (intel, mt, 14 * 8); + + if (dim >= 4) + mt->total_height = dim * 4 + 4; + else + mt->total_height = 4; + + /* Set all the levels to effectively occupy the whole rectangular region. */ + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + lvlWidth, lvlHeight, 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + if (dim == 4 && face >= 4) { + y = mt->total_height - 4; + x = (face - 4) * 8; + } else if (dim < 4 && (face > 0 || mt->first_level > 0)) { + y = mt->total_height - 4; + x = face * 8; + } + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case FACE_POS_X: + case FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case FACE_POS_Y: + case FACE_NEG_Y: + y += 12; + x -= 8; + break; + case FACE_POS_Z: + case FACE_NEG_Z: + y = mt->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = mt->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; } + } + } +} + +static void +i945_miptree_layout_3d(struct intel_context *intel, + struct intel_mipmap_tree * mt) +{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint pack_x_pitch, pack_x_nr; + GLuint pack_y_pitch; + GLuint level; + + mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); + mt->total_height = 0; + + pack_y_pitch = MAX2(mt->height0, 2); + pack_x_pitch = mt->pitch; + pack_x_nr = 1; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLint x = 0; + GLint y = 0; + GLint q, j; + + intel_miptree_set_level_info(mt, level, depth, + 0, mt->total_height, + width, height, depth); + + for (q = 0; q < depth;) { + for (j = 0; j < pack_x_nr && q < depth; j++, q++) { + intel_miptree_set_image_offset(mt, level, q, x, y); + x += pack_x_pitch; + } + + x = 0; + y += pack_y_pitch; + } + mt->total_height += y; - for (face = 0; face < 6; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - if (dim == 4 && face >= 4) { - y = mt->total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4 && (face > 0 || mt->first_level > 0)) { - y = mt->total_height - 4; - x = face * 8; - } - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_image_offset(mt, level, face, x, y); - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case FACE_POS_X: - case FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case FACE_POS_Y: - case FACE_NEG_Y: - y += 12; - x -= 8; - break; - case FACE_POS_Z: - case FACE_NEG_Z: - y = mt->total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = mt->total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - break; + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); } - case GL_TEXTURE_3D:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; - GLuint pack_x_pitch, pack_x_nr; - GLuint pack_y_pitch; - GLuint level; - - mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); - mt->total_height = 0; - - pack_y_pitch = MAX2(mt->height0, 2); - pack_x_pitch = mt->pitch; - pack_x_nr = 1; - - for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6; - GLint x = 0; - GLint y = 0; - GLint q, j; - - intel_miptree_set_level_info(mt, level, nr_images, - 0, mt->total_height, - width, height, depth); - - for (q = 0; q < nr_images;) { - for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - intel_miptree_set_image_offset(mt, level, q, x, y); - x += pack_x_pitch; - } - - x = 0; - y += pack_y_pitch; - } - - - mt->total_height += y; - - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - } - - width = minify(width); - height = minify(height); - depth = minify(depth); - } - break; + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; } + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + +GLboolean +i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +{ + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP: + i945_miptree_layout_cube(intel, mt); + break; + case GL_TEXTURE_3D: + i945_miptree_layout_3d(intel, mt); + break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE_ARB: - i945_miptree_layout_2d(intel, mt); - break; + i945_miptree_layout_2d(intel, mt); + break; default: _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); + break; } DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 1c45fd5dcd..e489d25ae8 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -38,7 +38,7 @@ static GLuint -translate_texture_format(GLuint mesa_format) +translate_texture_format(GLuint mesa_format, GLenum DepthMode) { switch (mesa_format) { case MESA_FORMAT_L8: @@ -65,7 +65,7 @@ translate_texture_format(GLuint mesa_format) case MESA_FORMAT_RGBA_FXT1: return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); case MESA_FORMAT_Z16: - return (MAPSURF_16BIT | MT_16BIT_L16); + return (MAPSURF_16BIT | (DepthMode==GL_ALPHA?MT_16BIT_A16:MT_16BIT_L16)); case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGB_DXT1: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); @@ -74,7 +74,7 @@ translate_texture_format(GLuint mesa_format) case MESA_FORMAT_RGBA_DXT5: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); case MESA_FORMAT_Z24_S8: - return (MAPSURF_32BIT | MT_32BIT_xL824); + return (MAPSURF_32BIT | MT_32BIT_xI824); default: fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); abort(); @@ -166,7 +166,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) 0, intelObj-> firstLevel); - format = translate_texture_format(firstImage->TexFormat->MesaFormat); + format = translate_texture_format(firstImage->TexFormat->MesaFormat, + tObj->DepthMode); pitch = intelObj->mt->pitch * intelObj->mt->cpp; } @@ -248,8 +249,13 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) (SS2_SHADOW_ENABLE | intel_translate_shadow_compare_func(tObj->CompareFunc)); - minFilt = FILTER_4X4_FLAT; - magFilt = FILTER_4X4_FLAT; + if (tObj->Target == GL_TEXTURE_1D) { + minFilt = FILTER_NEAREST; + magFilt = FILTER_NEAREST; + } else { + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } } state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index c856a8627d..94d70be441 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -532,11 +532,12 @@ i915_state_draw_region(struct intel_context *intel, static void i915_set_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) + struct intel_region *color_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->state, color_region, depth_region); + i915_state_draw_region(intel, &i915->state, color_regions[0], depth_region); } @@ -571,6 +572,12 @@ i915_assert_not_dirty( struct intel_context *intel ) assert(!dirty); } +static void +i915_note_unlock( struct intel_context *intel ) +{ + /* nothing */ +} + void i915InitVtbl(struct i915_context *i915) @@ -586,4 +593,5 @@ i915InitVtbl(struct i915_context *i915) i915->intel.vtbl.update_texture_state = i915UpdateTextureState; i915->intel.vtbl.flush_cmd = i915_flush_cmd; i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; + i915->intel.vtbl.note_unlock = i915_note_unlock; } diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index 29f0b51ba6..bbb4e0f3cd 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -311,10 +311,18 @@ intel_wpos_triangle(struct intel_context *intel, { GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; + GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); + GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset); + GLfloat *v2_wpos = (GLfloat *)((char *)v2 + offset); + + __memcpy(v0_wpos, v0, size); + __memcpy(v1_wpos, v1, size); + __memcpy(v2_wpos, v2, size); + + v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; + v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h; + v2_wpos[1] = -v2_wpos[1] + intel->driDrawable->h; - __memcpy(((char *) v0) + offset, v0, size); - __memcpy(((char *) v1) + offset, v1, size); - __memcpy(((char *) v2) + offset, v2, size); intel_draw_triangle(intel, v0, v1, v2); } @@ -326,9 +334,14 @@ intel_wpos_line(struct intel_context *intel, { GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; + GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); + GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset); + + __memcpy(v0_wpos, v0, size); + __memcpy(v1_wpos, v1, size); - __memcpy(((char *) v0) + offset, v0, size); - __memcpy(((char *) v1) + offset, v1, size); + v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; + v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h; intel_draw_line(intel, v0, v1); } @@ -339,8 +352,10 @@ intel_wpos_point(struct intel_context *intel, intelVertexPtr v0) { GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; + GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); - __memcpy(((char *) v0) + offset, v0, size); + __memcpy(v0_wpos, v0, size); + v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; intel_draw_point(intel, v0); } diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 24b0288f88..ce34da165c 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -168,12 +168,10 @@ static void upload_clip_prog( struct brw_context *brw ) offset_front = 0; break; case GL_LINE: - key.do_unfilled = 1; fill_front = CLIP_LINE; offset_front = brw->attribs.Polygon->OffsetLine; break; case GL_POINT: - key.do_unfilled = 1; fill_front = CLIP_POINT; offset_front = brw->attribs.Polygon->OffsetPoint; break; @@ -188,26 +186,23 @@ static void upload_clip_prog( struct brw_context *brw ) offset_back = 0; break; case GL_LINE: - key.do_unfilled = 1; fill_back = CLIP_LINE; offset_back = brw->attribs.Polygon->OffsetLine; break; case GL_POINT: - key.do_unfilled = 1; fill_back = CLIP_POINT; offset_back = brw->attribs.Polygon->OffsetPoint; break; } } - if (brw->attribs.Polygon->BackMode != GL_FILL || - brw->attribs.Polygon->FrontMode != GL_FILL) - key.do_unfilled = 1; + if (brw->attribs.Polygon->BackMode != GL_FILL || + brw->attribs.Polygon->FrontMode != GL_FILL) { + key.do_unfilled = 1; - /* Most cases the fixed function units will handle. Cases where - * one or more polygon faces are unfilled will require help: - */ - if (key.do_unfilled) { + /* Most cases the fixed function units will handle. Cases where + * one or more polygon faces are unfilled will require help: + */ key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; if (offset_back || offset_front) { diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c index 918e000187..57ebf388f5 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c +++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c @@ -220,8 +220,8 @@ static void apply_one_offset( struct brw_clip_compile *c, struct brw_indirect vert ) { struct brw_compile *p = &c->func; - struct brw_reg pos = deref_4f(vert, c->offset[VERT_RESULT_HPOS]); - struct brw_reg z = get_element(pos, 2); + struct brw_reg z = deref_1f(vert, c->header_position_offset + + 2 * type_sz(BRW_REGISTER_TYPE_F)); brw_ADD(p, z, z, vec1(c->reg.offset)); } diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 49e739b0ad..56021fa209 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -146,12 +146,12 @@ struct brw_context; struct brw_state_flags { /** State update flags signalled by mesa internals */ GLuint mesa; - /** State update flags signalled by brw_state_cache.c searches */ - GLuint cache; /** * State update flags signalled as the result of brw_tracked_state updates */ GLuint brw; + /** State update flags signalled by brw_state_cache.c searches */ + GLuint cache; }; struct brw_vertex_program { @@ -240,7 +240,7 @@ struct brw_vs_ouput_sizes { #define BRW_MAX_TEX_UNIT 8 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + MAX_DRAW_BUFFERS enum brw_cache_id { BRW_CC_VP, @@ -425,8 +425,8 @@ struct brw_context struct brw_tracked_state **atoms; GLuint nr_atoms; - - struct intel_region *draw_region; + GLuint nr_draw_regions; + struct intel_region *draw_regions[MAX_DRAW_BUFFERS]; struct intel_region *depth_region; } state; @@ -461,6 +461,7 @@ struct brw_context struct gl_buffer_object *vbo; struct intel_region *saved_draw_region; + GLuint saved_nr_draw_regions; struct intel_region *saved_depth_region; GLuint restore_draw_buffers[MAX_DRAW_BUFFERS]; diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 58aeeb4228..ce0df0357b 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -57,16 +57,6 @@ static GLboolean do_check_fallback(struct brw_context *brw) return GL_TRUE; } - /* _NEW_BUFFERS - */ - /* We can only handle a single draw buffer at the moment, and only as the - * first color buffer. - */ - if (fb->_NumColorDrawBuffers > 1) { - DBG("FALLBACK: multiple color draw buffers\n"); - return GL_TRUE; - } - /* _NEW_RENDERMODE * * XXX: need to save/restore RenderMode in metaops state, or diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index dd62be34f4..252a8996e2 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -362,17 +362,20 @@ static void meta_draw_region( struct intel_context *intel, struct brw_context *brw = brw_context(&intel->ctx); if (!brw->metaops.saved_draw_region) { - brw->metaops.saved_draw_region = brw->state.draw_region; + brw->metaops.saved_draw_region = brw->state.draw_regions[0]; + brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions; brw->metaops.saved_depth_region = brw->state.depth_region; } - brw->state.draw_region = draw_region; + brw->state.draw_regions[0] = draw_region; + brw->state.nr_draw_regions = 1; brw->state.depth_region = depth_region; if (intel->frame_buffer_texobj != NULL) brw_FrameBufferTexDestroy(brw); - brw_FrameBufferTexInit(brw, draw_region); + if (draw_region) + brw_FrameBufferTexInit(brw, draw_region); brw->state.dirty.mesa |= _NEW_BUFFERS; } @@ -508,7 +511,8 @@ static void install_meta_state( struct intel_context *intel ) /* This works without adjusting refcounts. Fix later? */ - brw->metaops.saved_draw_region = brw->state.draw_region; + brw->metaops.saved_draw_region = brw->state.draw_regions[0]; + brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions; brw->metaops.saved_depth_region = brw->state.depth_region; brw->metaops.active = 1; @@ -531,7 +535,8 @@ static void leave_meta_state( struct intel_context *intel ) ctx->FragmentProgram.Current = brw->metaops.restore_fp; - brw->state.draw_region = brw->metaops.saved_draw_region; + brw->state.draw_regions[0] = brw->metaops.saved_draw_region; + brw->state.nr_draw_regions = brw->metaops.saved_nr_draw_regions; brw->state.depth_region = brw->metaops.saved_depth_region; brw->metaops.saved_draw_region = NULL; brw->metaops.saved_depth_region = NULL; diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 8e8fea48e9..f717b6f6c3 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -124,6 +124,9 @@ static void brwProgramStringNotify( GLcontext *ctx, struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program; if (p == vp) brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; + if (p->program.IsPositionInvariant) { + _mesa_insert_mvp_code(ctx, &p->program); + } p->id = brw->program_id++; p->param_state = p->program.Base.Parameters->StateFlags; diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 2b6087d691..398048429b 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -224,11 +224,11 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, sf.sf6.line_width = 0; /* _NEW_POINT */ - sf.sf6.point_rast_rule = 1; /* opengl conventions */ + sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT; /* opengl conventions */ /* XXX clamp max depends on AA vs. non-AA */ sf.sf7.sprite_point = key->point_sprite; - sf.sf7.point_size = CLAMP(key->point_size, 1.0, 255.0) * (1<<3); + sf.sf7.point_size = CLAMP(nearbyint(key->point_size), 1, 255) * (1<<3); sf.sf7.use_point_size_state = !key->point_attenuated; sf.sf7.aa_line_distance_mode = 0; diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 7b5eff4f2d..d617650fad 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -85,7 +85,7 @@ static GLuint hash_key( const void *key, GLuint key_size, } /* Include the BO pointers as key data as well */ - ikey = (void *)reloc_bufs; + ikey = (GLuint *)reloc_bufs; key_size = nr_reloc_bufs * sizeof(dri_bo *); for (i = 0; i < key_size/4; i++) { hash ^= ikey[i]; @@ -102,6 +102,9 @@ static void update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, dri_bo *bo) { + if (bo == cache->last_bo[cache_id]) + return; /* no change */ + dri_bo_unreference(cache->last_bo[cache_id]); cache->last_bo[cache_id] = bo; dri_bo_reference(cache->last_bo[cache_id]); @@ -255,7 +258,7 @@ brw_upload_cache( struct brw_cache *cache, if (INTEL_DEBUG & DEBUG_STATE) _mesa_printf("upload %s: %d bytes to cache id %d\n", cache->name[cache_id], - data_size); + data_size, cache_id); /* Copy data to the buffer */ dri_bo_subdata(bo, 0, data_size, data); @@ -282,6 +285,7 @@ brw_cache_data_sz(struct brw_cache *cache, item = search_cache(cache, cache_id, hash, data, data_size, reloc_bufs, nr_reloc_bufs); if (item) { + update_cache_last(cache, cache_id, item->bo); dri_bo_reference(item->bo); return item->bo; } diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index ef14b8e89f..258c6260fb 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -77,6 +77,7 @@ void brw_FrameBufferTexDestroy( struct brw_context *brw ) if (brw->intel.frame_buffer_texobj != NULL) brw->intel.ctx.Driver.DeleteTexture( &brw->intel.ctx, brw->intel.frame_buffer_texobj ); + brw->intel.frame_buffer_texobj = NULL; } /** diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index cdbbe7b699..31e96a250a 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -70,18 +70,21 @@ static void brw_destroy_context( struct intel_context *intel ) /* called from intelDrawBuffer() */ static void brw_set_draw_region( struct intel_context *intel, - struct intel_region *draw_region, - struct intel_region *depth_region) + struct intel_region *draw_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct brw_context *brw = brw_context(&intel->ctx); - + int i; if (brw->state.depth_region != depth_region) brw->state.dirty.brw |= BRW_NEW_DEPTH_BUFFER; - - intel_region_release(&brw->state.draw_region); + for (i = 0; i < brw->state.nr_draw_regions; i++) + intel_region_release(&brw->state.draw_regions[i]); intel_region_release(&brw->state.depth_region); - intel_region_reference(&brw->state.draw_region, draw_region); + for (i = 0; i < num_regions; i++) + intel_region_reference(&brw->state.draw_regions[i], draw_regions[i]); intel_region_reference(&brw->state.depth_region, depth_region); + brw->state.nr_draw_regions = num_regions; } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 342e7f8496..abdc92bf01 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -29,7 +29,7 @@ * Keith Whitwell <keith@tungstengraphics.com> */ - +#include "main/texformat.h" #include "brw_context.h" #include "brw_util.h" #include "brw_wm.h" @@ -139,6 +139,7 @@ static void do_wm_prog( struct brw_context *brw, c->fp = fp; c->env_param = brw->intel.ctx.FragmentProgram.Parameters; + brw_init_compile(brw, &c->func); if (brw_wm_is_glsl(&c->fp->program)) { brw_wm_glsl_emit(brw, c); } else { @@ -160,10 +161,6 @@ static void do_wm_prog( struct brw_context *brw, */ c->grf_limit = BRW_WM_MAX_GRF/2; - /* This is where we start emitting gen4 code: - */ - brw_init_compile(brw, &c->func); - brw_wm_pass2(c); c->prog_data.total_grf = c->max_wm_grf; @@ -288,8 +285,12 @@ static void brw_wm_populate_key( struct brw_context *brw, key->shadowtex_mask |= 1<<i; } - if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) + if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) { key->yuvtex_mask |= 1<<i; + if (t->Image[0][t->BaseLevel]->TexFormat->MesaFormat == + MESA_FORMAT_YCBCR) + key->yuvtex_swap_mask |= 1<< i; + } } } diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 645286d470..297617ee2d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -69,7 +69,8 @@ struct brw_wm_prog_key { GLuint runtime_check_aads_emit:1; GLuint yuvtex_mask:8; - GLuint pad1:24; + GLuint yuvtex_swap_mask:8; /* UV swaped */ + GLuint pad1:16; GLuint program_string_id:32; GLuint origin_x, origin_y; @@ -142,6 +143,8 @@ struct brw_wm_instruction { GLuint writemask:4; GLuint tex_unit:4; /* texture unit for TEX, TXD, TXP instructions */ GLuint tex_idx:3; /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */ + GLuint eot:1; /* End of thread indicator for FB_WRITE*/ + GLuint target:10; /* target binding table index for FB_WRITE*/ }; @@ -196,6 +199,7 @@ struct brw_wm_compile { GLuint nr_fp_insns; GLuint fp_temp; GLuint fp_interp_emitted; + GLuint fp_fragcolor_emitted; GLuint fp_deriv_emitted; struct prog_src_register pixel_xy; diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index df51f73dd8..a02f70a50c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -137,7 +137,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c, brw_ADD(p, dst[0], retype(arg0[0], BRW_REGISTER_TYPE_W), - brw_imm_d(- c->key.origin_x)); + brw_imm_d(0 - c->key.origin_x)); } if (mask & WRITEMASK_Y) { @@ -145,7 +145,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c, brw_ADD(p, dst[1], negate(retype(arg0[1], BRW_REGISTER_TYPE_W)), - brw_imm_d(c->key.origin_y + c->key.drawable_height)); + brw_imm_d(c->key.origin_y + c->key.drawable_height - 1)); } } @@ -223,6 +223,10 @@ static void emit_pinterp( struct brw_compile *p, if (mask & (1<<i)) { brw_LINE(p, brw_null_reg(), interp[i], deltas[0]); brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]); + } + } + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { brw_MUL(p, dst[i], dst[i], w[3]); } } @@ -500,6 +504,9 @@ static void emit_dp3( struct brw_compile *p, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { + if (!(mask & WRITEMASK_XYZW)) + return; /* Do not emit dead code*/ + assert((mask & WRITEMASK_XYZW) == WRITEMASK_X); brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); @@ -517,6 +524,9 @@ static void emit_dp4( struct brw_compile *p, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { + if (!(mask & WRITEMASK_XYZW)) + return; /* Do not emit dead code*/ + assert((mask & WRITEMASK_XYZW) == WRITEMASK_X); brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); @@ -535,6 +545,9 @@ static void emit_dph( struct brw_compile *p, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { + if (!(mask & WRITEMASK_XYZW)) + return; /* Do not emit dead code*/ + assert((mask & WRITEMASK_XYZW) == WRITEMASK_X); brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); @@ -578,6 +591,9 @@ static void emit_math1( struct brw_compile *p, GLuint mask, const struct brw_reg *arg0 ) { + if (!(mask & WRITEMASK_XYZW)) + return; /* Do not emit dead code*/ + //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X || // function == BRW_MATH_FUNCTION_SINCOS); @@ -602,6 +618,9 @@ static void emit_math2( struct brw_compile *p, const struct brw_reg *arg0, const struct brw_reg *arg1) { + if (!(mask & WRITEMASK_XYZW)) + return; /* Do not emit dead code*/ + assert((mask & WRITEMASK_XYZW) == WRITEMASK_X); brw_push_insn_state(p); @@ -696,7 +715,7 @@ static void emit_tex( struct brw_wm_compile *c, retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW), 1, retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW), - inst->tex_unit + 1, /* surface */ + inst->tex_unit + MAX_DRAW_BUFFERS, /* surface */ inst->tex_unit, /* sampler */ inst->writemask, (shadow ? @@ -749,7 +768,7 @@ static void emit_txb( struct brw_wm_compile *c, retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW), 1, retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW), - inst->tex_unit + 1, /* surface */ + inst->tex_unit + MAX_DRAW_BUFFERS, /* surface */ inst->tex_unit, /* sampler */ inst->writemask, BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, @@ -822,7 +841,9 @@ static void emit_kil( struct brw_wm_compile *c, static void fire_fb_write( struct brw_wm_compile *c, GLuint base_reg, - GLuint nr ) + GLuint nr, + GLuint target, + GLuint eot ) { struct brw_compile *p = &c->func; @@ -845,10 +866,10 @@ static void fire_fb_write( struct brw_wm_compile *c, retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW), base_reg, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), - 0, /* render surface always 0 */ + target, nr, 0, - 1); + eot); } static void emit_aa( struct brw_wm_compile *c, @@ -873,7 +894,9 @@ static void emit_aa( struct brw_wm_compile *c, static void emit_fb_write( struct brw_wm_compile *c, struct brw_reg *arg0, struct brw_reg *arg1, - struct brw_reg *arg2) + struct brw_reg *arg2, + GLuint target, + GLuint eot) { struct brw_compile *p = &c->func; GLuint nr = 2; @@ -946,7 +969,7 @@ static void emit_fb_write( struct brw_wm_compile *c, if (c->key.aa_dest_stencil_reg) emit_aa(c, arg1, 2); - fire_fb_write(c, 0, nr); + fire_fb_write(c, 0, nr, target, eot); } else { struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); @@ -963,14 +986,14 @@ static void emit_fb_write( struct brw_wm_compile *c, jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { emit_aa(c, arg1, 2); - fire_fb_write(c, 0, nr); + fire_fb_write(c, 0, nr, target, eot); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); /* ELSE: Shuffle up one register to fill in the hole left for AA: */ - fire_fb_write(c, 1, nr-1); + fire_fb_write(c, 1, nr-1, target, eot); } } @@ -1138,7 +1161,7 @@ void brw_wm_emit( struct brw_wm_compile *c ) break; case WM_FB_WRITE: - emit_fb_write(c, args[0], args[1], args[2]); + emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot); break; /* Straightforward arithmetic: diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 55527373bc..7e80724130 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -144,7 +144,7 @@ static struct prog_dst_register dst_undef( void ) static struct prog_dst_register get_temp( struct brw_wm_compile *c ) { - int bit = ffs( ~c->fp_temp ); + int bit = _mesa_ffs( ~c->fp_temp ); if (!bit) { _mesa_printf("%s: out of temporaries\n", __FILE__); @@ -158,7 +158,7 @@ static struct prog_dst_register get_temp( struct brw_wm_compile *c ) static void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp ) { - c->fp_temp &= ~1<<(temp.Index + 1 - FIRST_INTERNAL_TEMP); + c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP)); } @@ -494,17 +494,20 @@ static void precalc_dst( struct brw_wm_compile *c, if (dst.WriteMask & WRITEMASK_XZ) { + struct prog_instruction *swz; GLuint z = GET_SWZ(src0.Swizzle, Z); /* dst.xz = swz src0.1zzz */ - emit_op(c, - OPCODE_SWZ, - dst_mask(dst, WRITEMASK_XZ), - inst->SaturateMode, 0, 0, - src_swizzle(src0, SWIZZLE_ONE, z, z, z), - src_undef(), - src_undef()); + swz = emit_op(c, + OPCODE_SWZ, + dst_mask(dst, WRITEMASK_XZ), + inst->SaturateMode, 0, 0, + src_swizzle(src0, SWIZZLE_ONE, z, z, z), + src_undef(), + src_undef()); + /* Avoid letting negation flag of src0 affect our 1 constant. */ + swz->SrcReg[0].NegateBase &= ~NEGATE_X; } if (dst.WriteMask & WRITEMASK_W) { /* dst.w = mov src1.w @@ -527,15 +530,19 @@ static void precalc_lit( struct brw_wm_compile *c, struct prog_dst_register dst = inst->DstReg; if (dst.WriteMask & WRITEMASK_XW) { + struct prog_instruction *swz; + /* dst.xw = swz src0.1111 */ - emit_op(c, - OPCODE_SWZ, - dst_mask(dst, WRITEMASK_XW), - 0, 0, 0, - src_swizzle1(src0, SWIZZLE_ONE), - src_undef(), - src_undef()); + swz = emit_op(c, + OPCODE_SWZ, + dst_mask(dst, WRITEMASK_XW), + 0, 0, 0, + src_swizzle1(src0, SWIZZLE_ONE), + src_undef(), + src_undef()); + /* Avoid letting the negation flag of src0 affect our 1 constant. */ + swz->SrcReg[0].NegateBase = 0; } @@ -649,17 +656,21 @@ static void precalc_tex( struct brw_wm_compile *c, src_undef()); } else { + GLboolean swap_uv = c->key.yuvtex_swap_mask & (1<<inst->TexSrcUnit); + /* CONST C0 = { -.5, -.0625, -.5, 1.164 } CONST C1 = { 1.596, -0.813, 2.018, -.391 } UYV = TEX ... UYV.xyz = ADD UYV, C0 UYV.y = MUL UYV.y, C0.w - RGB.xyz = MAD UYV.xxz, C1, UYV.y + if (UV swaped) + RGB.xyz = MAD UYV.zzx, C1, UYV.y + else + RGB.xyz = MAD UYV.xxz, C1, UYV.y RGB.y = MAD UYV.z, C1.w, RGB.y */ struct prog_dst_register dst = inst->DstReg; - struct prog_src_register src0 = inst->SrcReg[0]; struct prog_dst_register tmp = get_temp(c); struct prog_src_register tmpsrc = src_reg_from_dst(tmp); struct prog_src_register C0 = search_or_add_const4f( c, -.5, -.0625, -.5, 1.164 ); @@ -673,7 +684,7 @@ static void precalc_tex( struct brw_wm_compile *c, inst->SaturateMode, inst->TexSrcUnit, inst->TexSrcTarget, - src0, + coord, src_undef(), src_undef()); @@ -689,6 +700,7 @@ static void precalc_tex( struct brw_wm_compile *c, /* YUV.y = MUL YUV.y, C0.w */ + emit_op(c, OPCODE_MUL, dst_mask(tmp, WRITEMASK_Y), @@ -697,13 +709,18 @@ static void precalc_tex( struct brw_wm_compile *c, src_swizzle1(C0, W), src_undef()); - /* RGB.xyz = MAD YUV.xxz, C1, YUV.y + /* + * if (UV swaped) + * RGB.xyz = MAD YUV.zzx, C1, YUV.y + * else + * RGB.xyz = MAD YUV.xxz, C1, YUV.y */ + emit_op(c, OPCODE_MAD, dst_mask(dst, WRITEMASK_XYZ), 0, 0, 0, - src_swizzle(tmpsrc, X,X,Z,Z), + swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z), C1, src_swizzle1(tmpsrc, Y)); @@ -851,14 +868,34 @@ static void emit_fb_write( struct brw_wm_compile *c ) struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH); struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR); + GLuint i; - emit_op(c, - WM_FB_WRITE, - dst_mask(dst_undef(),0), - 0, 0, 0, - outcolor, - payload_r0_depth, - outdepth); + struct prog_instruction *inst, *last_inst; + struct brw_context *brw = c->func.brw; + + /* inst->Sampler is not used by backend, + use it for fb write target and eot */ + + if (brw->state.nr_draw_regions > 1) { + for (i = 0 ; i < brw->state.nr_draw_regions; i++) { + outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i); + last_inst = inst = emit_op(c, + WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0, + outcolor, payload_r0_depth, outdepth); + inst->Sampler = (i<<1); + if (c->fp_fragcolor_emitted) { + outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); + last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0), + 0, 0, 0, outcolor, payload_r0_depth, outdepth); + inst->Sampler = (i<<1); + } + } + last_inst->Sampler |= 1; //eot + }else { + inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0), + 0, 0, 0, outcolor, payload_r0_depth, outdepth); + inst->Sampler = 1|(0<<1); + } } @@ -884,7 +921,15 @@ static void validate_src_regs( struct brw_wm_compile *c, } } - +static void validate_dst_regs( struct brw_wm_compile *c, + const struct prog_instruction *inst ) +{ + if (inst->DstReg.File == PROGRAM_OUTPUT) { + GLuint idx = inst->DstReg.Index; + if (idx == FRAG_RESULT_COLR) + c->fp_fragcolor_emitted = 1; + } +} static void print_insns( const struct prog_instruction *insn, GLuint nr ) @@ -929,12 +974,16 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; + validate_src_regs(c, inst); + validate_dst_regs(c, inst); + } + for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { + const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; struct prog_instruction *out; /* Check for INPUT values, emit INTERP instructions where * necessary: */ - validate_src_regs(c, inst); switch (inst->Opcode) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index fd237ee028..b2ffc82ed2 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -274,10 +274,11 @@ static void emit_delta_xy(struct brw_wm_compile *c, static void fire_fb_write( struct brw_wm_compile *c, GLuint base_reg, - GLuint nr ) + GLuint nr, + GLuint target, + GLuint eot) { struct brw_compile *p = &c->func; - /* Pass through control information: */ /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */ @@ -294,10 +295,10 @@ static void fire_fb_write( struct brw_wm_compile *c, retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW), base_reg, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), - 0, /* render surface always 0 */ + target, nr, 0, - 1); + eot); } static void emit_fb_write(struct brw_wm_compile *c, @@ -306,7 +307,8 @@ static void emit_fb_write(struct brw_wm_compile *c, struct brw_compile *p = &c->func; int nr = 2; int channel; - struct brw_reg src0;//, src1, src2, dst; + GLuint target, eot; + struct brw_reg src0; /* Reserve a space for AA - may not be needed: */ @@ -337,8 +339,9 @@ static void emit_fb_write(struct brw_wm_compile *c, nr += 2; } - - fire_fb_write(c, 0, nr); + target = inst->Sampler >> 1; + eot = inst->Sampler & 1; + fire_fb_write(c, 0, nr, target, eot); } static void emit_pixel_w( struct brw_wm_compile *c, @@ -983,7 +986,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c, brw_ADD(p, dst[1], negate(retype(src0[1], BRW_REGISTER_TYPE_W)), - brw_imm_d(c->key.origin_y + c->key.drawable_height)); + brw_imm_d(c->key.origin_y + c->key.drawable_height - 1)); } } @@ -1026,7 +1029,7 @@ static void emit_txb(struct brw_wm_compile *c, retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), 1, retype(payload_reg, BRW_REGISTER_TYPE_UW), - inst->TexSrcUnit + 1, /* surface */ + inst->TexSrcUnit + MAX_DRAW_BUFFERS, /* surface */ inst->TexSrcUnit, /* sampler */ inst->DstReg.WriteMask, BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, @@ -1088,7 +1091,7 @@ static void emit_tex(struct brw_wm_compile *c, retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), 1, retype(payload_reg, BRW_REGISTER_TYPE_UW), - inst->TexSrcUnit + 1, /* surface */ + inst->TexSrcUnit + MAX_DRAW_BUFFERS, /* surface */ inst->TexSrcUnit, /* sampler */ inst->DstReg.WriteMask, BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, @@ -1125,7 +1128,6 @@ static void post_wm_emit( struct brw_wm_compile *c ) } static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) - { #define MAX_IFSN 32 #define MAX_LOOP_DEPTH 32 @@ -1135,7 +1137,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) struct brw_compile *p = &c->func; struct brw_indirect stack_index = brw_indirect(0, 0); - brw_init_compile(brw, &c->func); c->reg_index = 0; prealloc_reg(c); brw_set_compression_control(p, BRW_COMPRESSION_NONE); diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c index 1bfae5a069..205a7160d3 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c @@ -348,6 +348,8 @@ static struct brw_wm_instruction *translate_insn( struct brw_wm_compile *c, out->saturate = (inst->SaturateMode != SATURATE_OFF); out->tex_unit = inst->TexSrcUnit; out->tex_idx = inst->TexSrcTarget; + out->eot = inst->Sampler & 1; + out->target = inst->Sampler>>1; /* Args: */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c index 26c044d400..f6f3a38e9e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c @@ -150,6 +150,7 @@ void brw_wm_pass1( struct brw_wm_compile *c ) case OPCODE_FLR: case OPCODE_FRC: case OPCODE_MOV: + case OPCODE_SWZ: read0 = writemask; break; @@ -257,7 +258,6 @@ void brw_wm_pass1( struct brw_wm_compile *c ) read0 = WRITEMASK_XYW; break; - case OPCODE_SWZ: case OPCODE_DST: case OPCODE_TXP: default: diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f2ae210c38..c5c944f781 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -133,6 +133,9 @@ static GLuint translate_tex_format( GLuint mesa_format ) case MESA_FORMAT_SRGB_DXT1: return BRW_SURFACEFORMAT_BC1_UNORM_SRGB; + case MESA_FORMAT_Z24_S8: + return BRW_SURFACEFORMAT_I24X8_UNORM; + default: assert(0); return 0; @@ -226,13 +229,13 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) key.depth = firstImage->Depth; key.tiled = intelObj->mt->region->tiled; - dri_bo_unreference(brw->wm.surf_bo[unit + 1]); - brw->wm.surf_bo[unit + 1] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, + dri_bo_unreference(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]); + brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, &key, sizeof(key), &key.bo, 1, NULL); - if (brw->wm.surf_bo[unit + 1] == NULL) - brw->wm.surf_bo[unit + 1] = brw_create_texture_surface(brw, &key); + if (brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] == NULL) + brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_create_texture_surface(brw, &key); } /** @@ -242,7 +245,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) */ static void brw_update_region_surface(struct brw_context *brw, struct intel_region *region, - unsigned int unit) + unsigned int unit, GLboolean cached) { dri_bo *region_bo = NULL; @@ -276,17 +279,19 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region, key.height = 1; key.cpp = 4; } - memcpy(key.color_mask, brw->attribs.Color->ColorMask, sizeof(key.color_mask)); key.color_blend = (!brw->attribs.Color->_LogicOpEnabled && brw->attribs.Color->BlendEnabled); dri_bo_unreference(brw->wm.surf_bo[unit]); - brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, - &key, sizeof(key), - ®ion_bo, 1, - NULL); + brw->wm.surf_bo[unit] = NULL; + if (cached) + brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, + &key, sizeof(key), + ®ion_bo, 1, + NULL); + if (brw->wm.surf_bo[unit] == NULL) { struct brw_surface_state surf; @@ -312,11 +317,10 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region, /* Key size will never match key size for textures, so we're safe. */ brw->wm.surf_bo[unit] = brw_upload_cache(&brw->cache, BRW_SS_SURFACE, - &key, sizeof(key), + &key, sizeof(key), ®ion_bo, 1, &surf, sizeof(surf), NULL, NULL); - if (region_bo != NULL) { dri_emit_reloc(brw->wm.surf_bo[unit], DRM_BO_FLAG_MEM_TT | @@ -345,7 +349,7 @@ brw_wm_get_binding_table(struct brw_context *brw) NULL); if (bind_bo == NULL) { - GLuint data_size = brw->wm.nr_surfaces * 4; + GLuint data_size = brw->wm.nr_surfaces * sizeof(GLuint); uint32_t *data = malloc(data_size); int i; @@ -369,7 +373,7 @@ brw_wm_get_binding_table(struct brw_context *brw) DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, - i * 4, + i * sizeof(GLuint), brw->wm.surf_bo[i]); } } @@ -385,9 +389,14 @@ static void upload_wm_surfaces(struct brw_context *brw ) GLcontext *ctx = &brw->intel.ctx; struct intel_context *intel = &brw->intel; GLuint i; + if (brw->state.nr_draw_regions > 1) { + for (i = 0; i < brw->state.nr_draw_regions; i++) + brw_update_region_surface(brw, brw->state.draw_regions[i], i, + GL_FALSE); + }else + brw_update_region_surface(brw, brw->state.draw_regions[0], 0, GL_TRUE); - brw_update_region_surface(brw, brw->state.draw_region, 0); - brw->wm.nr_surfaces = 1; + brw->wm.nr_surfaces = MAX_DRAW_BUFFERS; for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i]; @@ -396,16 +405,16 @@ static void upload_wm_surfaces(struct brw_context *brw ) if(texUnit->_ReallyEnabled && texUnit->_Current == intel->frame_buffer_texobj) { - dri_bo_unreference(brw->wm.surf_bo[i+1]); - brw->wm.surf_bo[i+1] = brw->wm.surf_bo[0]; - dri_bo_reference(brw->wm.surf_bo[i+1]); - brw->wm.nr_surfaces = i+2; + dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]); + brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = brw->wm.surf_bo[0]; + dri_bo_reference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]); + brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1; } else if (texUnit->_ReallyEnabled) { brw_update_texture_surface(ctx, i); - brw->wm.nr_surfaces = i+2; + brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1; } else { - dri_bo_unreference(brw->wm.surf_bo[i+1]); - brw->wm.surf_bo[i+1] = NULL; + dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]); + brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = NULL; } } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 5199f833e2..2a25f079e9 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -300,6 +300,7 @@ intelWindowMoved(struct intel_context *intel) default: intelSetFrontClipRects(intel); } + } if (!intel->intelScreen->driScrnPriv->dri2.enabled && @@ -894,7 +895,7 @@ void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) { struct intel_context *intel = intel_context(ctx); - struct intel_region *colorRegion, *depthRegion = NULL; + struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL; struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; int front = 0; /* drawing to front color buffer? */ @@ -933,14 +934,24 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* * How many color buffers are we drawing into? */ - if (fb->_NumColorDrawBuffers != 1) { - /* writing to 0 or 2 or 4 color buffers */ - /*_mesa_debug(ctx, "Software rendering\n");*/ + if (fb->_NumColorDrawBuffers == 0) { + /* writing to 0 */ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); - colorRegion = NULL; + colorRegions[0] = NULL; if (fb->Name != 0) intelSetRenderbufferClipRects(intel); + } else if (fb->_NumColorDrawBuffers > 1) { + int i; + struct intel_renderbuffer *irb; + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + + if (fb->Name != 0) + intelSetRenderbufferClipRects(intel); + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); + colorRegions[i] = (irb && irb->region) ? irb->region : NULL; + } } else { /* draw to exactly one color buffer */ @@ -958,11 +969,11 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* drawing to window system buffer */ if (front) { intelSetFrontClipRects(intel); - colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); } else { intelSetBackClipRects(intel); - colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + colorRegions[0]= intel_get_rb_region(fb, BUFFER_BACK_LEFT); } } else { @@ -970,7 +981,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) struct intel_renderbuffer *irb; intelSetRenderbufferClipRects(intel); irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); - colorRegion = (irb && irb->region) ? irb->region : NULL; + colorRegions[0] = (irb && irb->region) ? irb->region : NULL; } } @@ -982,7 +993,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) else ctx->NewState |= _NEW_POLYGON; - if (!colorRegion) { + if (!colorRegions[0]) { FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); } else { @@ -1055,7 +1066,8 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) ctx->NewState |= _NEW_DEPTH; } - intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); + intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, + fb->_NumColorDrawBuffers); /* update viewport since it depends on window size */ if (ctx->Driver.Viewport) { diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c index fb65e66555..f164b48963 100644 --- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c @@ -72,6 +72,28 @@ struct intel_validate_entry { struct drm_i915_op_arg bo_arg; }; +struct dri_ttm_bo_bucket_entry { + drmBO drm_bo; + struct dri_ttm_bo_bucket_entry *next; +}; + +struct dri_ttm_bo_bucket { + struct dri_ttm_bo_bucket_entry *head; + struct dri_ttm_bo_bucket_entry **tail; + /** + * Limit on the number of entries in this bucket. + * + * 0 means that this caching at this bucket size is disabled. + * -1 means that there is no limit to caching at this size. + */ + int max_entries; + int num_entries; +}; + +/* Arbitrarily chosen, 16 means that the maximum size we'll cache for reuse + * is 1 << 16 pages, or 256MB. + */ +#define INTEL_TTM_BO_BUCKETS 16 typedef struct _dri_bufmgr_ttm { dri_bufmgr bufmgr; @@ -84,6 +106,9 @@ typedef struct _dri_bufmgr_ttm { struct intel_validate_entry *validate_array; int validate_array_size; int validate_count; + + /** Array of lists of cached drmBOs of power-of-two sizes */ + struct dri_ttm_bo_bucket cache_bucket[INTEL_TTM_BO_BUCKETS]; } dri_bufmgr_ttm; /** @@ -137,6 +162,41 @@ typedef struct _dri_fence_ttm drmFence drm_fence; } dri_fence_ttm; +static int +logbase2(int n) +{ + GLint i = 1; + GLint log2 = 0; + + while (n > i) { + i *= 2; + log2++; + } + + return log2; +} + +static struct dri_ttm_bo_bucket * +dri_ttm_bo_bucket_for_size(dri_bufmgr_ttm *bufmgr_ttm, unsigned long size) +{ + int i; + + /* We only do buckets in power of two increments */ + if ((size & (size - 1)) != 0) + return NULL; + + /* We should only see sizes rounded to pages. */ + assert((size % 4096) == 0); + + /* We always allocate in units of pages */ + i = ffs(size / 4096) - 1; + if (i >= INTEL_TTM_BO_BUCKETS) + return NULL; + + return &bufmgr_ttm->cache_bucket[i]; +} + + static void dri_ttm_dump_validation_list(dri_bufmgr_ttm *bufmgr_ttm) { int i, j; @@ -294,8 +354,8 @@ intel_setup_reloc_list(dri_bo *bo) dri_bo_ttm *bo_ttm = (dri_bo_ttm *)bo; dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bo->bufmgr; - bo_ttm->relocs = malloc(sizeof(struct dri_ttm_reloc) * - bufmgr_ttm->max_relocs); + bo_ttm->relocs = calloc(bufmgr_ttm->max_relocs, + sizeof(struct dri_ttm_reloc)); bo_ttm->reloc_buf_data = calloc(1, RELOC_BUF_SIZE(bufmgr_ttm->max_relocs)); /* Initialize the relocation list with the header: @@ -338,6 +398,9 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, int ret; uint64_t flags; unsigned int hint; + unsigned long alloc_size; + struct dri_ttm_bo_bucket *bucket; + GLboolean alloc_from_cache = GL_FALSE; ttm_buf = calloc(1, sizeof(*ttm_buf)); if (!ttm_buf) @@ -352,13 +415,48 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, /* No hints we want to use. */ hint = 0; - ret = drmBOCreate(bufmgr_ttm->fd, size, alignment / pageSize, - NULL, flags, hint, &ttm_buf->drm_bo); - if (ret != 0) { - free(ttm_buf); - return NULL; + /* Round the allocated size up to a power of two number of pages. */ + alloc_size = 1 << logbase2(size); + if (alloc_size < pageSize) + alloc_size = pageSize; + bucket = dri_ttm_bo_bucket_for_size(bufmgr_ttm, alloc_size); + + /* If we don't have caching at this size, don't actually round the + * allocation up. + */ + if (bucket == NULL || bucket->max_entries == 0) + alloc_size = size; + + /* Get a buffer out of the cache if available */ + if (bucket != NULL && bucket->num_entries > 0) { + struct dri_ttm_bo_bucket_entry *entry = bucket->head; + int busy; + + /* Check if the buffer is still in flight. If not, reuse it. */ + ret = drmBOBusy(bufmgr_ttm->fd, &entry->drm_bo, &busy); + alloc_from_cache = (ret == 0 && busy == 0); + + if (alloc_from_cache) { + bucket->head = entry->next; + if (entry->next == NULL) + bucket->tail = &bucket->head; + bucket->num_entries--; + + ttm_buf->drm_bo = entry->drm_bo; + free(entry); + } } - ttm_buf->bo.size = ttm_buf->drm_bo.size; + + if (!alloc_from_cache) { + ret = drmBOCreate(bufmgr_ttm->fd, alloc_size, alignment / pageSize, + NULL, flags, hint, &ttm_buf->drm_bo); + if (ret != 0) { + free(ttm_buf); + return NULL; + } + } + + ttm_buf->bo.size = size; ttm_buf->bo.offset = ttm_buf->drm_bo.offset; ttm_buf->bo.virtual = NULL; ttm_buf->bo.bufmgr = bufmgr; @@ -450,6 +548,7 @@ dri_ttm_bo_unreference(dri_bo *buf) return; if (--ttm_buf->refcount == 0) { + struct dri_ttm_bo_bucket *bucket; int ret; assert(ttm_buf->map_count == 0); @@ -476,11 +575,32 @@ dri_ttm_bo_unreference(dri_bo *buf) } } - ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo); - if (ret != 0) { - fprintf(stderr, "drmBOUnreference failed (%s): %s\n", - ttm_buf->name, strerror(-ret)); + bucket = dri_ttm_bo_bucket_for_size(bufmgr_ttm, ttm_buf->drm_bo.size); + /* Put the buffer into our internal cache for reuse if we can. */ + if (!ttm_buf->shared && + bucket != NULL && + (bucket->max_entries == -1 || + (bucket->max_entries > 0 && + bucket->num_entries < bucket->max_entries))) + { + struct dri_ttm_bo_bucket_entry *entry; + + entry = calloc(1, sizeof(*entry)); + entry->drm_bo = ttm_buf->drm_bo; + + entry->next = NULL; + *bucket->tail = entry; + bucket->tail = &entry->next; + bucket->num_entries++; + } else { + /* Decrement the kernel refcount for the buffer. */ + ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + if (ret != 0) { + fprintf(stderr, "drmBOUnreference failed (%s): %s\n", + ttm_buf->name, strerror(-ret)); + } } + DBG("bo_unreference final: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); free(buf); @@ -657,9 +777,34 @@ static void dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr) { dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; + int i; free(bufmgr_ttm->validate_array); + /* Free any cached buffer objects we were going to reuse */ + for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++) { + struct dri_ttm_bo_bucket *bucket = &bufmgr_ttm->cache_bucket[i]; + struct dri_ttm_bo_bucket_entry *entry; + + while ((entry = bucket->head) != NULL) { + int ret; + + bucket->head = entry->next; + if (entry->next == NULL) + bucket->tail = &bucket->head; + bucket->num_entries--; + + /* Decrement the kernel refcount for the buffer. */ + ret = drmBOUnreference(bufmgr_ttm->fd, &entry->drm_bo); + if (ret != 0) { + fprintf(stderr, "drmBOUnreference failed: %s\n", + strerror(-ret)); + } + + free(entry); + } + } + free(bufmgr); } @@ -877,6 +1022,24 @@ dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence) } /** + * Enables unlimited caching of buffer objects for reuse. + * + * This is potentially very memory expensive, as the cache at each bucket + * size is only bounded by how many buffers of that size we've managed to have + * in flight at once. + */ +void +intel_ttm_enable_bo_reuse(dri_bufmgr *bufmgr) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; + int i; + + for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++) { + bufmgr_ttm->cache_bucket[i].max_entries = -1; + } +} + +/** * Initializes the TTM buffer manager, which uses the kernel to allocate, map, * and manage map buffer objections. * @@ -890,6 +1053,7 @@ intel_bufmgr_ttm_init(int fd, unsigned int fence_type, unsigned int fence_type_flush, int batch_size) { dri_bufmgr_ttm *bufmgr_ttm; + int i; bufmgr_ttm = calloc(1, sizeof(*bufmgr_ttm)); bufmgr_ttm->fd = fd; @@ -919,6 +1083,10 @@ intel_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit; bufmgr_ttm->bufmgr.debug = GL_FALSE; + /* Initialize the linked lists for BO reuse cache. */ + for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++) + bufmgr_ttm->cache_bucket[i].tail = &bufmgr_ttm->cache_bucket[i].head; + return &bufmgr_ttm->bufmgr; } diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h index 0738839cef..d267a168cd 100644 --- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h +++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h @@ -14,4 +14,7 @@ dri_fence *intel_ttm_fence_create_from_arg(dri_bufmgr *bufmgr, const char *name, dri_bufmgr *intel_bufmgr_ttm_init(int fd, unsigned int fence_type, unsigned int fence_type_flush, int batch_size); +void +intel_ttm_enable_bo_reuse(dri_bufmgr *bufmgr); + #endif diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index d3f0681807..e2388dbb09 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -205,7 +205,6 @@ static const struct dri_extension card_extensions[] = { {"GL_ARB_texture_rectangle", NULL}, {"GL_NV_texture_rectangle", NULL}, {"GL_EXT_texture_rectangle", NULL}, - {"GL_ARB_point_sprite", NULL}, {"GL_ARB_point_parameters", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, @@ -231,7 +230,6 @@ static const struct dri_extension card_extensions[] = { {"GL_EXT_texture_env_dot3", NULL}, {"GL_EXT_texture_filter_anisotropic", NULL}, {"GL_EXT_texture_lod_bias", NULL}, - {"GL_EXT_texture_sRGB", NULL}, {"GL_3DFX_texture_compression_FXT1", NULL}, {"GL_APPLE_client_storage", NULL}, {"GL_MESA_pack_invert", NULL}, @@ -248,6 +246,7 @@ static const struct dri_extension brw_extensions[] = { { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + { "GL_ARB_point_sprite", NULL}, { "GL_ARB_fragment_shader", NULL }, { "GL_ARB_draw_buffers", NULL }, { "GL_ARB_depth_texture", NULL }, @@ -257,6 +256,7 @@ static const struct dri_extension brw_extensions[] = { /* ARB extn won't work if not enabled */ { "GL_SGIX_depth_texture", NULL }, { "GL_ARB_texture_env_crossbar", NULL }, + { "GL_EXT_texture_sRGB", NULL}, { NULL, NULL } }; @@ -456,6 +456,7 @@ intel_init_bufmgr(struct intel_context *intel) ttm_supported = GL_FALSE; if (!ttm_disable && ttm_supported) { + int bo_reuse_mode; intel->bufmgr = intel_bufmgr_ttm_init(intel->driFd, DRM_FENCE_TYPE_EXE, DRM_FENCE_TYPE_EXE | @@ -463,6 +464,15 @@ intel_init_bufmgr(struct intel_context *intel) BATCH_SZ); if (intel->bufmgr != NULL) intel->ttm = GL_TRUE; + + bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse"); + switch (bo_reuse_mode) { + case DRI_CONF_BO_REUSE_DISABLED: + break; + case DRI_CONF_BO_REUSE_ALL: + intel_ttm_enable_bo_reuse(intel->bufmgr); + break; + } } /* Otherwise, use the classic buffer manager. */ if (intel->bufmgr == NULL) { @@ -548,6 +558,9 @@ intelInitContext(struct intel_context *intel, intel->width = intelScreen->width; intel->height = intelScreen->height; + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, + IS_965(intelScreen->deviceID) ? "i965" : "i915"); if (intelScreen->deviceID == PCI_CHIP_I865_G) intel->maxBatchSize = 4096; else @@ -556,10 +569,6 @@ intelInitContext(struct intel_context *intel, if (!intel_init_bufmgr(intel)) return GL_FALSE; - driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, - IS_965(intelScreen->deviceID) ? "i965" : "i915"); - ctx->Const.MaxTextureMaxAnisotropy = 2.0; /* This doesn't yet catch all non-conformant rendering, but it's a @@ -855,7 +864,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags) */ if (dPriv) { if (sPriv->dri2.enabled) - drawable_changed = __driParseEvents(sPriv, dPriv); + drawable_changed = __driParseEvents(dPriv->driContextPriv, dPriv); else DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); } @@ -984,6 +993,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) */ void UNLOCK_HARDWARE( struct intel_context *intel ) { + intel->vtbl.note_unlock( intel ); intel->locked = 0; DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 6c97955b14..1348b0adcf 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -94,8 +94,9 @@ struct intel_context void (*render_start) (struct intel_context * intel); void (*render_prevalidate) (struct intel_context * intel); void (*set_draw_region) (struct intel_context * intel, - struct intel_region * draw_region, - struct intel_region * depth_region); + struct intel_region * draw_regions[], + struct intel_region * depth_region, + GLuint num_regions); GLuint (*flush_cmd) (void); void (*emit_flush) (struct intel_context *intel, GLuint unused); @@ -476,6 +477,11 @@ extern void intelInitStateFuncs(struct dd_function_table *functions); #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f +enum { + DRI_CONF_BO_REUSE_DISABLED, + DRI_CONF_BO_REUSE_ALL +}; + extern int intel_translate_shadow_compare_func(GLenum func); extern int intel_translate_compare_func(GLenum func); extern int intel_translate_stencil_op(GLenum op); diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 94d499f001..b3f6610546 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -517,28 +517,10 @@ intel_framebuffer_renderbuffer(GLcontext * ctx, intel_draw_buffer(ctx, fb); } - -/** - * When glFramebufferTexture[123]D is called this function sets up the - * gl_renderbuffer wrapper around the texture image. - * This will have the region info needed for hardware rendering. - */ -static struct intel_renderbuffer * -intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +static GLboolean +intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, + struct gl_texture_image *texImage) { - const GLuint name = ~0; /* not significant, but distinct for debugging */ - struct intel_renderbuffer *irb; - - /* make an intel_renderbuffer to wrap the texture image */ - irb = CALLOC_STRUCT(intel_renderbuffer); - if (!irb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); - return NULL; - } - - _mesa_init_renderbuffer(&irb->Base, name); - irb->Base.ClassID = INTEL_RB_CLASS; - if (texImage->TexFormat == &_mesa_texformat_argb8888) { irb->Base._ActualFormat = GL_RGBA8; irb->Base._BaseFormat = GL_RGBA; @@ -553,12 +535,15 @@ intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; DBG("Render to DEPTH16 texture OK\n"); + } else if (texImage->TexFormat == &_mesa_texformat_z24_s8) { + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + DBG("Render to DEPTH_STENCIL texture OK\n"); } else { DBG("Render to texture BAD FORMAT %d\n", texImage->TexFormat->MesaFormat); - _mesa_free(irb); - return NULL; + return GL_FALSE; } irb->Base.InternalFormat = irb->Base._ActualFormat; @@ -577,6 +562,35 @@ intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) irb->RenderToTexture = GL_TRUE; + return GL_TRUE; +} + +/** + * When glFramebufferTexture[123]D is called this function sets up the + * gl_renderbuffer wrapper around the texture image. + * This will have the region info needed for hardware rendering. + */ +static struct intel_renderbuffer * +intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +{ + const GLuint name = ~0; /* not significant, but distinct for debugging */ + struct intel_renderbuffer *irb; + + /* make an intel_renderbuffer to wrap the texture image */ + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + if (!intel_update_wrapper(ctx, irb, texImage)) { + _mesa_free(irb); + return NULL; + } + return irb; } @@ -613,6 +627,10 @@ intel_render_texture(GLcontext * ctx, _mesa_render_texture(ctx, fb, att); return; } + } if (!intel_update_wrapper(ctx, irb, newImage)) { + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + _mesa_render_texture(ctx, fb, att); + return; } DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 48dcf07131..55503f45ae 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -110,10 +110,12 @@ intel_miptree_create(struct intel_context *intel, mt = intel_miptree_create_internal(intel, target, internal_format, first_level, last_level, width0, height0, depth0, cpp, compress_byte); - if (!mt) + /* + * pitch == 0 indicates the null texture + */ + if (!mt || !mt->pitch) return NULL; - assert (mt->pitch); mt->region = intel_region_alloc(intel, mt->cpp, mt->pitch, mt->total_height); @@ -180,7 +182,10 @@ int intel_miptree_pitch_align (struct intel_context *intel, struct intel_mipmap_tree *mt, int pitch) { +#ifdef I915 GLcontext *ctx = &intel->ctx; +#endif + if (!mt->compressed) { int pitch_align; @@ -321,7 +326,7 @@ intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, assert(img < mt->level[level].nr_images); - mt->level[level].image_offset[img] = (x + y * mt->pitch); + mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp; DBG("%s level %d img %d pos %d,%d image_offset %x\n", __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); @@ -352,7 +357,7 @@ intel_miptree_image_offset(struct intel_mipmap_tree *mt, { if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) return (mt->level[level].level_offset + - mt->level[level].image_offset[face] * mt->cpp); + mt->level[level].image_offset[face]); else return mt->level[level].level_offset; } @@ -363,6 +368,8 @@ intel_miptree_image_offset(struct intel_mipmap_tree *mt, * Map a teximage in a mipmap tree. * \param row_stride returns row stride in bytes * \param image_stride returns image stride in bytes (for 3D textures). + * \param image_offsets pointer to array of pixel offsets from the returned + * pointer to each depth image * \return address of mapping */ GLubyte * @@ -377,12 +384,16 @@ intel_miptree_image_map(struct intel_context * intel, if (row_stride) *row_stride = mt->pitch * mt->cpp; - if (image_offsets) { - if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) - memset(image_offsets, 0, mt->level[level].depth * sizeof(GLuint)); - else - memcpy(image_offsets, mt->level[level].image_offset, - mt->level[level].depth * sizeof(GLuint)); + if (mt->target == GL_TEXTURE_3D) { + int i; + + for (i = 0; i < mt->level[level].depth; i++) + image_offsets[i] = mt->level[level].image_offset[i] / mt->cpp; + } else { + assert(mt->level[level].depth == 1); + assert(mt->target == GL_TEXTURE_CUBE_MAP || + mt->level[level].image_offset[0] == 0); + image_offsets[0] = 0; } return (intel_region_map(intel, mt->region) + diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 3c1a6ffa2a..c9537dbb9a 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -62,18 +62,29 @@ */ struct intel_mipmap_level { + /** + * Byte offset to the base of this level. + * + * This is used for mipmap levels of 1D/2D/3D textures. However, CUBE + * layouts spread images around the whole tree, so the level offset is + * always zero in that case. + */ GLuint level_offset; GLuint width; GLuint height; + /** Depth of the mipmap at this level: 1 for 1D/2D/CUBE, n for 3D. */ GLuint depth; + /** Number of images at this level: 1 for 1D/2D, 6 for CUBE, depth for 3D */ GLuint nr_images; - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats + /** + * Byte offset from level_offset to the image for each cube face or depth + * level. + * + * Pretty much have to accept that hardware formats * are going to be so diverse that there is no unified way to * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - * NOTE level_offset is a byte offset, but the image_offsets are _pixel_ offsets!!! + * so have to store them as a lookup table. */ GLuint *image_offset; }; diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 77b6c53cb3..4cb68655f2 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -166,11 +166,8 @@ do_blit_bitmap( GLcontext *ctx, struct intel_context *intel = intel_context(ctx); struct intel_region *dst = intel_drawbuf_region(intel); GLfloat tmpColor[4]; - - union { - GLuint ui; - GLubyte ub[4]; - } color; + GLubyte ubcolor[4]; + GLuint color8888, color565; if (!dst) return GL_FALSE; @@ -187,10 +184,13 @@ do_blit_bitmap( GLcontext *ctx, ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor); } - UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], tmpColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], tmpColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], tmpColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], tmpColor[3]); + UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]); + UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]); + UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]); + UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]); + + color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]); + color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]); /* Does zoom apply to bitmaps? */ @@ -289,7 +289,7 @@ do_blit_bitmap( GLcontext *ctx, dst->cpp, (GLubyte *)stipple, sz, - color.ui, + (dst->cpp == 2) ? color565 : color8888, dst->pitch, dst->buffer, 0, diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 8b8eeb77aa..3d46073daa 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -56,6 +56,15 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_SECTION_PERFORMANCE DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + /* Options correspond to DRI_CONF_BO_REUSE_DISABLED, + * DRI_CONF_BO_REUSE_ALL + */ + DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 0, "0:1") + DRI_CONF_DESC_BEGIN(en, "Buffer object reuse") + DRI_CONF_ENUM(0, "Disable buffer object reuse") + DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects") + DRI_CONF_DESC_END + DRI_CONF_OPT_END DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY DRI_CONF_FORCE_S3TC_ENABLE(false) @@ -66,7 +75,7 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_SECTION_END DRI_CONF_END; -const GLuint __driNConfigOptions = 5; +const GLuint __driNConfigOptions = 6; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; @@ -284,14 +293,17 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, static void intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, __DRIDrawableConfigEvent *event) { struct intel_framebuffer *intel_fb = dPriv->driverPrivate; struct intel_region *region = NULL; 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; + struct intel_context *intel = pcp->driverPrivate; + int cpp, pitch; + + cpp = intel->ctx.Visual.rgbBits / 8; + pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; rb = intel_fb->color_rb[1]; if (rb) { @@ -322,12 +334,13 @@ intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, static void intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, __DRIBufferAttachEvent *ba) { struct intel_framebuffer *intel_fb = dPriv->driverPrivate; struct intel_renderbuffer *rb; struct intel_region *region; - struct intel_context *intel = dPriv->driContextPriv->driverPrivate; + struct intel_context *intel = pcp->driverPrivate; GLuint tiled; switch (ba->buffer.attachment) { @@ -371,22 +384,6 @@ intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, 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, @@ -671,7 +668,9 @@ static const struct __DriverAPIRec intelAPI = { .WaitForSBC = NULL, .SwapBuffersMSC = NULL, .CopySubBuffer = intelCopySubBuffer, - .UpdateBuffer = intelUpdateBuffer, + + .HandleDrawableConfig = intelHandleDrawableConfig, + .HandleBufferAttach = intelHandleBufferAttach, }; diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index c110df478f..329af0d1b0 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -1,5 +1,6 @@ #include "swrast/swrast.h" #include "texobj.h" +#include "teximage.h" #include "mipmap.h" #include "intel_context.h" #include "intel_mipmap_tree.h" @@ -71,7 +72,7 @@ intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) } if (texImage->Data) { - free(texImage->Data); + _mesa_free_texmemory(texImage->Data); texImage->Data = NULL; } } diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index 34995f4ebf..3a87137cc9 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -138,8 +138,7 @@ void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); void intelSetTexBuffer(__DRIcontext *pDRICtx, - GLint target, unsigned long handle, - GLint cpp, GLuint pitch, GLuint height); + GLint target, __DRIdrawable *pDraw); GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index df08ee1a3b..dd8fbeaa91 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -23,6 +23,7 @@ #include "intel_tex.h" #include "intel_ioctl.h" #include "intel_blit.h" +#include "intel_fbo.h" #define FILE_DEBUG_FLAG DEBUG_TEXTURE @@ -359,7 +360,8 @@ intelTexImage(GLcontext * ctx, assert(!texImage->Data); } else if (texImage->Data) { - _mesa_align_free(texImage->Data); + _mesa_free_texmemory(texImage->Data); + texImage->Data = NULL; } /* If this is the only texture image in the tree, could call @@ -455,8 +457,6 @@ intelTexImage(GLcontext * ctx, format, type, pixels, unpack, "glTexImage"); } - if (!pixels) - return; LOCK_HARDWARE(intel); @@ -482,7 +482,7 @@ intelTexImage(GLcontext * ctx, sizeInBytes = depth * dstRowStride * postConvHeight; } - texImage->Data = malloc(sizeInBytes); + texImage->Data = _mesa_alloc_texmemory(sizeInBytes); } DBG("Upload image %dx%dx%d row_len %d " @@ -493,27 +493,29 @@ intelTexImage(GLcontext * ctx, * the blitter to copy. Or, use the hardware to do the format * conversion and copy: */ - if (compressed) { - if (intelImage->mt) { - struct intel_region *dst = intelImage->mt->region; - _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, - 0, 0, - intelImage->mt->level[level].width, - intelImage->mt->level[level].height/4, - pixels, - srcRowStride, - 0, 0); - } else - memcpy(texImage->Data, pixels, imageSize); - } else if (!texImage->TexFormat->StoreImage(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, unpack)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + if (pixels) { + if (compressed) { + if (intelImage->mt) { + struct intel_region *dst = intelImage->mt->region; + _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, + 0, 0, + intelImage->mt->level[level].width, + intelImage->mt->level[level].height/4, + pixels, + srcRowStride, + 0, 0); + } else + memcpy(texImage->Data, pixels, imageSize); + } else if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, unpack)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } } /* GL_SGIS_generate_mipmap */ @@ -694,26 +696,20 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, } void -intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, - unsigned long handle, GLint cpp, GLuint pitch, GLuint height) +intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *pDraw) { __DRIcontextPrivate *driContext = pDRICtx->private; + __DRIdrawablePrivate *dPriv = pDraw->private; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; struct intel_context *intel = driContext->driverPrivate; struct intel_texture_object *intelObj; struct intel_texture_image *intelImage; struct intel_mipmap_tree *mt; - struct intel_region *region; + struct intel_renderbuffer *rb; struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; - int level = 0; - - /* FIXME: type, format, internalFormat */ - int type = GL_BGRA; - int format = GL_UNSIGNED_BYTE; - int internalFormat = (cpp == 3 ? 3 : 4); - cpp = 4; - pitch /= 4; + int level = 0, type, format, internalFormat; texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit]; texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); @@ -722,12 +718,16 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, if (!intelObj) return; - region = intel_region_alloc_for_handle(intel, cpp, pitch, height, - 0, handle); + __driParseEvents(driContext, dPriv); + + rb = intel_fb->color_rb[0]; + type = GL_BGRA; + format = GL_UNSIGNED_BYTE; + internalFormat = (rb->region->cpp == 3 ? 3 : 4); mt = intel_miptree_create_for_region(intel, target, internalFormat, - 0, 0, region, 1, 0); + 0, 0, rb->region, 1, 0); if (mt == NULL) return; @@ -739,7 +739,7 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, intelObj->mt = mt; texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); _mesa_init_teximage_fields(&intel->ctx, target, texImage, - pitch, height, 1, + rb->region->pitch, rb->region->height, 1, 0, internalFormat); intelImage = intel_texture_image(texImage); @@ -748,7 +748,7 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat, type, format); _mesa_set_fetch_functions(texImage, 2); - texImage->RowStride = pitch; + texImage->RowStride = rb->region->pitch; intel_miptree_reference(&intelImage->mt, intelObj->mt); if (!intel_miptree_match_image(intelObj->mt, &intelImage->base, diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index bd27b86bf3..688e3870df 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -50,8 +50,8 @@ intelTexSubimage(GLcontext * ctx, { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intelImage = intel_texture_image(texImage); - GLuint dstRowStride; - + GLuint dstRowStride = 0; + DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, xoffset, yoffset, width, height); @@ -76,6 +76,16 @@ intelTexSubimage(GLcontext * ctx, intelImage->level, &dstRowStride, texImage->ImageOffsets); + else { + if (texImage->IsCompressed) { + dstRowStride = + _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); + assert(dims != 3); + } + else { + dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; + } + } assert(dstRowStride); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 9fe8e86870..53d00e17a1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -214,7 +214,7 @@ static const struct __DriverAPIRec nouveauAPI = { static __GLcontextModes * -nouveauFillInModes( __DRIscreenPRiv *psp, +nouveauFillInModes( __DRIscreenPrivate *psp, unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer ) { @@ -304,7 +304,7 @@ __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) " git://anongit.freedesktop.org/git/nouveau/mesa\n"); #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 -#error nouveau_drm.h version doesn't match expected version +#error nouveau_drm.h version does not match expected version #endif if (!driCheckDriDdxDrmVersions2("nouveau", diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 1abc92ec49..3497738eac 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -377,7 +377,7 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8); ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_0, 1); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1); ALLOC_STATE(sc_hyperz, always, 3, 0); r300->hw.sc_hyperz.cmd[0] = cmdpacket0(R300_SC_HYPERZ, 2); ALLOC_STATE(sc_screendoor, always, 2, 0); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 993aa51990..780d9aa5d2 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -331,14 +331,14 @@ struct r300_state_atom { #define R300_RI_CMDSIZE 9 #define R300_RR_CMD_0 0 /* rr is variable size (at least 1) */ -#define R300_RR_ROUTE_0 1 -#define R300_RR_ROUTE_1 2 -#define R300_RR_ROUTE_2 3 -#define R300_RR_ROUTE_3 4 -#define R300_RR_ROUTE_4 5 -#define R300_RR_ROUTE_5 6 -#define R300_RR_ROUTE_6 7 -#define R300_RR_ROUTE_7 8 +#define R300_RR_INST_0 1 +#define R300_RR_INST_1 2 +#define R300_RR_INST_2 3 +#define R300_RR_INST_3 4 +#define R300_RR_INST_4 5 +#define R300_RR_INST_5 6 +#define R300_RR_INST_6 7 +#define R300_RR_INST_7 8 #define R300_RR_CMDSIZE 9 #define R300_FP_CMD_0 0 diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index a135376398..deb62b2762 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -210,22 +210,18 @@ static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb, static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, int *inputs, GLint * tab, GLuint nr) { - GLuint i, dw; - + GLushort i, w; + uint16_t * dst16 = (uint16_t *) dst; + /* type, inputs, stop bit, size */ - for (i = 0; i + 1 < nr; i += 2) { - dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1); - dw |= (R300_INPUT_ROUTE_FLOAT | (inputs[tab[i + 1]] << 8) | (attribptr[tab[i + 1]]->size - 1)) << 16; - if (i + 2 == nr) { - dw |= (R300_VAP_INPUT_ROUTE_END << 16); + for (i = 0; i < nr; i++) { + /* make sure input is valid, would lockup the gpu */ + assert(inputs[tab[i]] != -1); + w = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1); + if (i + 1 == nr) { + w |= R300_VAP_INPUT_ROUTE_END; } - dst[i >> 1] = dw; - } - - if (nr & 1) { - dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[nr - 1]] << 8) | (attribptr[tab[nr - 1]]->size - 1); - dw |= R300_VAP_INPUT_ROUTE_END; - dst[nr >> 1] = dw; + dst16[i] = w; } return (nr + 1) >> 1; @@ -242,14 +238,10 @@ static GLuint r300VAPInputRoute1Swizzle(int swizzle[4]) GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) { GLuint i; + uint16_t * dst16 = (uint16_t *) dst; - for (i = 0; i + 1 < nr; i += 2) { - dst[i >> 1] = r300VAPInputRoute1Swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE; - dst[i >> 1] |= (r300VAPInputRoute1Swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE) << 16; - } - - if (nr & 1) { - dst[nr >> 1] = r300VAPInputRoute1Swizzle(swizzle[nr - 1]) | R300_INPUT_ROUTE_ENABLE; + for (i = 0; i < nr; i++) { + dst16[i] = r300VAPInputRoute1Swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE; } return (nr + 1) >> 1; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 3501ba2d09..1b405889c3 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -284,8 +284,8 @@ static void r300EmitClearState(GLcontext * ctx) e32(0x0); R300_STATECHANGE(r300, rr); - reg_start(R300_RS_ROUTE_0, 0); - e32(R300_RS_ROUTE_0_COLOR); + reg_start(R300_RS_INST_0, 0); + e32(R300_RS_INST_COL_CN_WRITE); R300_STATECHANGE(r300, fp); reg_start(R300_PFS_CNTL_0, 2); diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 0614c8b2e0..2200cec6ab 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1175,50 +1175,30 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R500_RS_INST_COL_CN_WRITE (1 << 16)
#define R500_RS_INST_COL_CN_WRITE_FBUFFER (2 << 16)
#define R500_RS_INST_COL_CN_WRITE_BACKFACE (3 << 16)
-#define R500_RS_INST_COL_COL_ADDR_SHIFT 18
+#define R500_RS_INST_COL_ADDR_SHIFT 18
#define R500_RS_INST_TEX_ADJ (1 << 25)
#define R500_RS_INST_W_CN (1 << 26)
/* These DWORDs control how vertex data is routed into fragment program * registers, after interpolators. */ -#define R300_RS_ROUTE_0 0x4330 -#define R300_RS_ROUTE_1 0x4334 -#define R300_RS_ROUTE_2 0x4338 -#define R300_RS_ROUTE_3 0x433C /* GUESS */ -#define R300_RS_ROUTE_4 0x4340 /* GUESS */ -#define R300_RS_ROUTE_5 0x4344 /* GUESS */ -#define R300_RS_ROUTE_6 0x4348 /* GUESS */ -#define R300_RS_ROUTE_7 0x434C /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_0 0 -# define R300_RS_ROUTE_SOURCE_INTERP_1 1 -# define R300_RS_ROUTE_SOURCE_INTERP_2 2 -# define R300_RS_ROUTE_SOURCE_INTERP_3 3 -# define R300_RS_ROUTE_SOURCE_INTERP_4 4 -# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ -# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ -# define R300_RS_ROUTE_DEST_SHIFT 6 -# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ - -/* Special handling for color: When the fragment program uses color, - * the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the - * color register index. - * - * Apperently you may set the R300_RS_ROUTE_0_COLOR bit, but not provide any - * R300_RS_ROUTE_0_COLOR_DEST value; this setup is used for clearing the state. - * See r300_ioctl.c:r300EmitClearState. I'm not sure if this setup is strictly - * correct or not. - Oliver. - */ -# define R300_RS_ROUTE_0_COLOR (1 << 14) -# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17 -# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ -/* As above, but for secondary color */ -# define R300_RS_ROUTE_1_COLOR1 (1 << 14) -# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 -# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17) -# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11) +#define R300_RS_INST_0 0x4330 +#define R300_RS_INST_1 0x4334 +#define R300_RS_INST_2 0x4338 +#define R300_RS_INST_3 0x433C /* GUESS */ +#define R300_RS_INST_4 0x4340 /* GUESS */ +#define R300_RS_INST_5 0x4344 /* GUESS */ +#define R300_RS_INST_6 0x4348 /* GUESS */ +#define R300_RS_INST_7 0x434C /* GUESS */ +# define R300_RS_INST_TEX_ID(x) ((x) << 0) +# define R300_RS_INST_TEX_CN_WRITE (1 << 3) +# define R300_RS_INST_TEX_ADDR_SHIFT 6 +# define R300_RS_INST_COL_ID(x) ((x) << 11) +# define R300_RS_INST_COL_CN_WRITE (1 << 14) +# define R300_RS_INST_COL_ADDR_SHIFT 17 +# define R300_RS_INST_TEX_ADJ (1 << 22) +# define R300_RS_COL_BIAS_UNUSED_SHIFT 23 + /* END: Rasterization / Interpolators - many guesses */ /* Hierarchical Z Enable */ @@ -1890,7 +1870,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Fog: Green Component of Fog Color */ #define FG_FOG_COLOR_G 0x4bcc /* Fog: Blue Component of Fog Color */ -#define FG_FOG_COLOR_B 0x4db0 +#define FG_FOG_COLOR_B 0x4bd0 # define FG_FOG_COLOR_MASK 0x000001ff /* Fog: Constant Factor for Fog Blending */ @@ -2262,6 +2242,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define ZB_STENCILREFMASK 0x4f08 # define ZB_STENCILREFMASK_STENCILREF_SHIFT 0 +# define ZB_STENCILREFMASK_STENCIL_MASK 0xff # define ZB_STENCILREFMASK_STENCILREF_MASK 0x000000ff # define ZB_STENCILREFMASK_STENCILMASK_SHIFT 8 # define ZB_STENCILREFMASK_STENCILMASK_MASK 0x0000ff00 @@ -2290,8 +2271,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) # define ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) # define ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) -# define ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 1) -# define ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 1) +# define ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) +# define ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) #define R300_ZB_BW_CNTL 0x4f1c # define R300_HIZ_DISABLE (0 << 0) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c4de022d84..e11b5afc30 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -932,8 +932,8 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, R300_RB3D_ZS1_BACK_FUNC_SHIFT)); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= - ~((ZB_STENCILREFMASK_STENCILREF_MASK << ZB_STENCILREFMASK_STENCILREF_SHIFT) | - (ZB_STENCILREFMASK_STENCILMASK_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT)); + ~((ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILREF_SHIFT) | + (ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT)); flag = translate_func(ctx->Stencil.Function[0]); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= @@ -953,11 +953,12 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) R300_STATECHANGE(rmesa, zs); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= - ~(ZB_STENCILREFMASK_STENCILMASK_MASK << + ~(ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= (ctx->Stencil. - WriteMask[0] & 0xff) << ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT; + WriteMask[0] & ZB_STENCILREFMASK_STENCIL_MASK) << + ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT; } static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, @@ -1004,11 +1005,10 @@ static void r300ClearStencil(GLcontext * ctx, GLint s) r300ContextPtr rmesa = R300_CONTEXT(ctx); rmesa->state.stencil.clear = - ((GLuint) (ctx->Stencil.Clear & 0xff) | - (ZB_STENCILREFMASK_STENCILMASK_MASK << - ZB_STENCILREFMASK_STENCILMASK_SHIFT) | ((ctx->Stencil. - WriteMask[0] & 0xff) << - ZB_STENCILREFMASK_STENCILMASK_SHIFT)); + ((GLuint) (ctx->Stencil.Clear & ZB_STENCILREFMASK_STENCIL_MASK) | + (ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT) | + ((ctx->Stencil.WriteMask[0] & ZB_STENCILREFMASK_STENCIL_MASK) << + ZB_STENCILREFMASK_STENCILMASK_SHIFT)); } /* ============================================================= @@ -1522,7 +1522,7 @@ static void r300SetupRSUnit(GLcontext * ctx) fp_reg = in_texcoords = col_interp_nr = high_rr = 0; - r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0; + r300->hw.rr.cmd[R300_RR_INST_1] = 0; if (InputsRead & FRAG_BIT_WPOS) { for (i = 0; i < ctx->Const.MaxTextureUnits; i++) @@ -1542,11 +1542,11 @@ static void r300SetupRSUnit(GLcontext * ctx) r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0 | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | (in_texcoords << R300_RS_INTERP_SRC_SHIFT) | interp_magic[i]; - r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0; + r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0; if (InputsRead & (FRAG_BIT_TEX0 << i)) { //assert(r300->state.texture.tc_count != 0); - r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] |= R300_RS_ROUTE_ENABLE | i /* source INTERP */ - | (fp_reg << R300_RS_ROUTE_DEST_SHIFT); + r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R300_RS_INST_TEX_CN_WRITE | i /* source INTERP */ + | (fp_reg << R300_RS_INST_TEX_ADDR_SHIFT); high_rr = fp_reg; /* Passing invalid data here can lock the GPU. */ @@ -1565,7 +1565,7 @@ static void r300SetupRSUnit(GLcontext * ctx) if (InputsRead & FRAG_BIT_COL0) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) { - r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT); + r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT); InputsRead &= ~FRAG_BIT_COL0; col_interp_nr++; } else { @@ -1575,7 +1575,7 @@ static void r300SetupRSUnit(GLcontext * ctx) if (InputsRead & FRAG_BIT_COL1) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) { - r300->hw.rr.cmd[R300_RR_ROUTE_1] |= R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 | (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT); + r300->hw.rr.cmd[R300_RR_INST_1] |= R300_RS_INST_COL_ID(1) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT); InputsRead &= ~FRAG_BIT_COL1; if (high_rr < 1) high_rr = 1; @@ -1587,7 +1587,7 @@ static void r300SetupRSUnit(GLcontext * ctx) /* Need at least one. This might still lock as the values are undefined... */ if (in_texcoords == 0 && col_interp_nr == 0) { - r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT); + r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT); col_interp_nr++; } @@ -1596,7 +1596,7 @@ static void r300SetupRSUnit(GLcontext * ctx) | R300_HIRES_EN; assert(high_rr >= 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_0, high_rr + 1); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1); r300->hw.rc.cmd[2] = 0xC0 | high_rr; if (InputsRead) diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h index 4dece95a98..6ad441bdd0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_chipset.h +++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h @@ -149,6 +149,7 @@ #define PCI_CHIP_RS350_7834 0x7834 #define PCI_CHIP_RS350_7835 0x7835 #define PCI_CHIP_RS690_791E 0x791E +#define PCI_CHIP_RS690_791F 0x791F enum { CHIP_FAMILY_R100, diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 93b239ae9f..d6caa2ac89 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -557,7 +557,11 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->chip_family = CHIP_FAMILY_RS300; break; + /* 9500 with 1 pipe verified by: Reid Linnemann <lreid@cs.okstate.edu> */ case PCI_CHIP_R300_AD: + screen->chip_family = CHIP_FAMILY_RV350; + screen->chip_flags = RADEON_CHIPSET_TCL; + break; case PCI_CHIP_R300_AE: case PCI_CHIP_R300_AF: case PCI_CHIP_R300_AG: |