summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/Makefile30
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr_fake.c10
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c142
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h12
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c13
-rw-r--r--src/mesa/drivers/dri/i915/i915_tex_layout.c654
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c18
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c14
-rw-r--r--src/mesa/drivers/dri/i915/intel_tris.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c17
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_unfilled.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h11
-rw-r--r--src/mesa/drivers/dri/i965/brw_fallback.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_metaops.c15
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vtbl.c15
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c13
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c47
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c109
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c25
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass0.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c55
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffers.c32
-rw-r--r--src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c192
-rw-r--r--src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c24
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h10
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c64
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c31
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h19
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_bitmap.c20
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c43
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c82
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c14
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.c4
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h16
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.c34
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c4
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h63
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c34
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_chipset.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c4
-rw-r--r--src/mesa/glapi/glX_proto_send.py2
-rw-r--r--src/mesa/main/attrib.c4
-rw-r--r--src/mesa/main/bufferobj.c141
-rw-r--r--src/mesa/main/bufferobj.h33
-rw-r--r--src/mesa/main/context.c6
-rw-r--r--src/mesa/main/dlist.c26
-rw-r--r--src/mesa/main/drawpix.c65
-rw-r--r--src/mesa/main/fbobject.c2
-rw-r--r--src/mesa/main/get.c60
-rw-r--r--src/mesa/main/get_gen.py5
-rw-r--r--src/mesa/main/glheader.h2
-rw-r--r--src/mesa/main/imports.c19
-rw-r--r--src/mesa/main/imports.h6
-rw-r--r--src/mesa/main/texenvprogram.c2
-rw-r--r--src/mesa/main/teximage.c3
-rw-r--r--src/mesa/main/varray.c3
-rw-r--r--src/mesa/shader/arbprogparse.c232
-rw-r--r--src/mesa/shader/arbprogram.syn4
-rw-r--r--src/mesa/shader/arbprogram_syn.h2
-rw-r--r--src/mesa/shader/prog_print.c18
-rw-r--r--src/mesa/shader/prog_statevars.c4
-rw-r--r--src/mesa/shader/program.c2
-rw-r--r--src/mesa/shader/shader_api.c6
-rw-r--r--src/mesa/shader/slang/slang_emit.c16
-rw-r--r--src/mesa/swrast/s_bitmap.c32
-rw-r--r--src/mesa/swrast/s_buffers.c7
-rw-r--r--src/mesa/swrast/s_drawpix.c31
-rw-r--r--src/mesa/swrast/s_readpix.c32
-rw-r--r--src/mesa/swrast/s_span.c6
-rw-r--r--src/mesa/tnl/t_vertex_sse.c4
-rw-r--r--src/mesa/x86/rtasm/x86sse.c247
-rw-r--r--src/mesa/x86/rtasm/x86sse.h63
82 files changed, 1955 insertions, 1099 deletions
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index d0c78b71ee..695a416094 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -132,15 +132,6 @@ $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECT
######################################################################
-# libGL pkg-config file
-pcedit = sed \
- -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
- -e 's,@LIB_DIR@,$(LIB_DIR),' \
- -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),'
-gl.pc: gl.pc.in
- $(pcedit) $< > $@
-
-######################################################################
# Generic stuff
depend: $(ALL_SOURCES)
@@ -159,25 +150,40 @@ subdirs:
(cd x86-64 ; $(MAKE)) ; \
fi
+pcedit = sed \
+ -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+ -e 's,@LIB_DIR@,$(LIB_DIR),' \
+ -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),'
+
+gl.pc: gl.pc.in
+ $(pcedit) $< > $@
-install: default gl.pc
+install-libgl: gl.pc
$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL
@if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
+ $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* \
+ $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
fi
$(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
+
+install-osmesa:
@if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
+ $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* \
+ $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
fi
+
+install-drivers:
@for target in $(DRIVER_DIRS); do \
case "$$target" in \
dri) cd drivers/dri ; $(MAKE) install ;; \
esac; \
done
+install: default install-libgl install-osmesa install-drivers
+
## NOT INSTALLED YET:
## $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES
## $(INSTALL) -m 644 include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES
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),
- &region_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),
+ &region_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),
&region_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:
diff --git a/src/mesa/glapi/glX_proto_send.py b/src/mesa/glapi/glX_proto_send.py
index 6207b00a94..b00b8a1ba6 100644
--- a/src/mesa/glapi/glX_proto_send.py
+++ b/src/mesa/glapi/glX_proto_send.py
@@ -373,7 +373,7 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
print '{'
print ' __GLXcontext * const gc = __glXGetCurrentContext();'
print ''
- print ' if (gc->isDirect) {'
+ print ' if (gc->driContext) {'
print ' %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string())
print ' } else {'
footer = '}\n}\n'
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 66e6aadc0f..c3c1f927fd 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -47,10 +47,10 @@
#include "stencil.h"
#include "texobj.h"
#include "texstate.h"
+#include "varray.h"
#include "mtypes.h"
#include "math/m_xform.h"
-
/**
* Special struct for saving/restoring texture state (GL_TEXTURE_BIT)
*/
@@ -1401,7 +1401,7 @@ _mesa_PopClientAttrib(void)
ctx->Array.ActiveTexture = data->ActiveTexture;
if (data->LockCount != 0)
_mesa_LockArraysEXT(data->LockFirst, data->LockCount);
- else
+ else if (ctx->Array.LockCount)
_mesa_UnlockArraysEXT();
_mesa_BindVertexArrayAPPLE( data->ArrayObj->Name );
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 9ad2dccc12..eb418610a7 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.1
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -565,6 +565,143 @@ _mesa_validate_pbo_access(GLuint dimensions,
/**
+ * If the source of glBitmap data is a PBO, check that we won't read out
+ * of buffer bounds, then map the buffer.
+ * If not sourcing from a PBO, just return the bitmap pointer.
+ * This is a helper function for (some) drivers.
+ * Return NULL if error.
+ * If non-null return, must call _mesa_unmap_bitmap_pbo() when done.
+ */
+const GLubyte *
+_mesa_map_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap)
+{
+ const GLubyte *buf;
+
+ if (unpack->BufferObj->Name) {
+ /* unpack from PBO */
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ unpack->BufferObj);
+ if (!buf)
+ return NULL;
+
+ buf = ADD_POINTERS(buf, bitmap);
+ }
+ else {
+ /* unpack from normal memory */
+ buf = bitmap;
+ }
+
+ return buf;
+}
+
+
+/**
+ * Counterpart to _mesa_map_bitmap_pbo()
+ * This is a helper function for (some) drivers.
+ */
+void
+_mesa_unmap_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack)
+{
+ if (unpack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+ }
+}
+
+
+/**
+ * \sa _mesa_map_bitmap_pbo
+ */
+const GLvoid *
+_mesa_map_drawpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ const GLvoid *buf;
+
+ if (unpack->BufferObj->Name) {
+ /* unpack from PBO */
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ unpack->BufferObj);
+ if (!buf)
+ return NULL;
+
+ buf = ADD_POINTERS(buf, pixels);
+ }
+ else {
+ /* unpack from normal memory */
+ buf = pixels;
+ }
+
+ return buf;
+}
+
+
+/**
+ * \sa _mesa_unmap_bitmap_pbo
+ */
+void
+_mesa_unmap_drapix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack)
+{
+ if (unpack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+ }
+}
+
+
+/**
+ * If PBO is bound, map the buffer, return dest pointer in mapped buffer.
+ * Call _mesa_unmap_readpix_pbo() when finished
+ * \return NULL if error
+ */
+void *
+_mesa_map_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack,
+ GLvoid *dest)
+{
+ void *buf;
+
+ if (pack->BufferObj->Name) {
+ /* pack into PBO */
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ pack->BufferObj);
+ if (!buf)
+ return NULL;
+
+ buf = ADD_POINTERS(buf, dest);
+ }
+ else {
+ /* pack to normal memory */
+ buf = dest;
+ }
+
+ return buf;
+}
+
+
+/**
+ * Counterpart to _mesa_map_readpix_pbo()
+ */
+void
+_mesa_unmap_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack)
+{
+ if (pack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj);
+ }
+}
+
+
+
+/**
* Return the gl_buffer_object for the given ID.
* Always return NULL for ID 0.
*/
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index 1d2715da84..8baa59d617 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 7.1
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -89,6 +89,35 @@ _mesa_validate_pbo_access(GLuint dimensions,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid *ptr);
+extern const GLubyte *
+_mesa_map_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap);
+
+extern void
+_mesa_unmap_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack);
+
+extern const GLvoid *
+_mesa_map_drawpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels);
+
+extern void
+_mesa_unmap_drapix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack);
+
+
+extern void *
+_mesa_map_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack,
+ GLvoid *dest);
+
+extern void
+_mesa_unmap_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack);
+
+
extern void
_mesa_unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj );
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 69c361f63e..62d592767d 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -706,10 +706,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
- _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
@@ -777,7 +777,7 @@ _mesa_init_current(GLcontext *ctx)
}
/* redo special cases: */
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index a421d04957..8d10d8a750 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -5578,6 +5578,27 @@ save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)
}
+/* GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */
+
+static void GLAPIENTRY
+exec_BindAttribLocationARB(GLuint program, GLuint index, const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_BindAttribLocationARB(ctx->Exec, (program, index, name));
+}
+
+static GLint GLAPIENTRY
+exec_GetAttribLocationARB(GLuint program, const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_GetAttribLocationARB(ctx->Exec, (program, name));
+}
+/* XXX more shader functions needed here */
+
+
+
#if FEATURE_EXT_framebuffer_blit
static void GLAPIENTRY
save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -8111,6 +8132,11 @@ _mesa_init_dlist_table(struct _glapi_table *table)
SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
#endif
+ /* ARB 30/31/32. GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */
+ SET_BindAttribLocationARB(table, exec_BindAttribLocationARB);
+ SET_GetAttribLocationARB(table, exec_GetAttribLocationARB);
+ /* XXX additional functions need to be implemented here! */
+
/* 299. GL_EXT_blend_equation_separate */
SET_BlendEquationSeparateEXT(table, save_BlendEquationSeparateEXT);
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index c82abccc41..4f28766674 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,6 +24,7 @@
#include "glheader.h"
#include "imports.h"
+#include "bufferobj.h"
#include "context.h"
#include "drawpix.h"
#include "feedback.h"
@@ -105,8 +106,7 @@ error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
}
break;
case GL_DEPTH_COMPONENT:
- if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ if (!drawing && !_mesa_source_buffer_exists(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no depth buffer)", readDraw);
return GL_TRUE;
@@ -183,6 +183,23 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
/* Round, to satisfy conformance tests (matches SGI's OpenGL) */
GLint x = IROUND(ctx->Current.RasterPos[0]);
GLint y = IROUND(ctx->Current.RasterPos[1]);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack from PBO */
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(invalid PBO access)");
+ return;
+ }
+ if (ctx->Unpack.BufferObj->Pointer) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(PBO is mapped)");
+ return;
+ }
+ }
+
ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
&ctx->Unpack, pixels);
}
@@ -301,6 +318,21 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
+ if (ctx->Pack.BufferObj->Name) {
+ if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(invalid PBO access)");
+ return;
+ }
+
+ if (ctx->Pack.BufferObj->Pointer) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
+ return;
+ }
+ }
+
ctx->Driver.ReadPixels(ctx, x, y, width, height,
format, type, &ctx->Pack, pixels);
}
@@ -341,12 +373,27 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
}
if (ctx->RenderMode == GL_RENDER) {
- if (bitmap) {
- /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
- GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
- GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
- ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
+ /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
+ GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
+ GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack from PBO */
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
+ GL_COLOR_INDEX, GL_BITMAP,
+ (GLvoid *) bitmap)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBitmap(invalid PBO access)");
+ return;
+ }
+ if (ctx->Unpack.BufferObj->Pointer) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
+ return;
+ }
}
+
+ ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
}
#if _HAVE_FULL_GL
else if (ctx->RenderMode == GL_FEEDBACK) {
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 671f80c7a4..9b60c73294 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -303,7 +303,7 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
- att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
/* OK */
}
else {
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index eb81ee4a52..9d8f2002c9 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -870,6 +870,14 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
case GL_TEXTURE_3D:
params[0] = _mesa_IsEnabled(GL_TEXTURE_3D);
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetBooleanv");
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT);
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetBooleanv");
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT);
+ break;
case GL_TEXTURE_BINDING_1D:
params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name);
break;
@@ -879,6 +887,14 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
case GL_TEXTURE_BINDING_3D:
params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name);
break;
+ case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1DArray->Name);
+ break;
+ case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2DArray->Name);
+ break;
case GL_TEXTURE_ENV_COLOR:
{
const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor;
@@ -1864,6 +1880,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(ctx->Const.MaxRenderbufferSize);
break;
+ case GL_READ_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_blit, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->ReadBuffer->Name);
+ break;
case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
CHECK_EXT1(ARB_fragment_shader, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(ctx->Const.FragmentProgram.MaxUniformComponents);
@@ -2701,6 +2721,14 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
case GL_TEXTURE_3D:
params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_3D));
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT));
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT));
+ break;
case GL_TEXTURE_BINDING_1D:
params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name);
break;
@@ -2710,6 +2738,14 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
case GL_TEXTURE_BINDING_3D:
params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name);
break;
+ case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1DArray->Name);
+ break;
+ case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2DArray->Name);
+ break;
case GL_TEXTURE_ENV_COLOR:
{
const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor;
@@ -3695,6 +3731,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
CHECK_EXT1(EXT_framebuffer_object, "GetFloatv");
params[0] = (GLfloat)(ctx->Const.MaxRenderbufferSize);
break;
+ case GL_READ_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_blit, "GetFloatv");
+ params[0] = (GLfloat)(ctx->ReadBuffer->Name);
+ break;
case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
CHECK_EXT1(ARB_fragment_shader, "GetFloatv");
params[0] = (GLfloat)(ctx->Const.FragmentProgram.MaxUniformComponents);
@@ -4532,6 +4572,14 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
case GL_TEXTURE_3D:
params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_3D));
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT));
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT));
+ break;
case GL_TEXTURE_BINDING_1D:
params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name;
break;
@@ -4541,6 +4589,14 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
case GL_TEXTURE_BINDING_3D:
params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name;
break;
+ case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetIntegerv");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1DArray->Name;
+ break;
+ case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetIntegerv");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2DArray->Name;
+ break;
case GL_TEXTURE_ENV_COLOR:
{
const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor;
@@ -5526,6 +5582,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv");
params[0] = ctx->Const.MaxRenderbufferSize;
break;
+ case GL_READ_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_blit, "GetIntegerv");
+ params[0] = ctx->ReadBuffer->Name;
+ break;
case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
CHECK_EXT1(ARB_fragment_shader, "GetIntegerv");
params[0] = ctx->Const.FragmentProgram.MaxUniformComponents;
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 9055433281..819a7cc5d7 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -983,6 +983,11 @@ StateVars = [
["ctx->Const.MaxRenderbufferSize"], "",
["EXT_framebuffer_object"] ),
+ # GL_EXT_framebuffer_blit
+ # NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT
+ ( "GL_READ_FRAMEBUFFER_BINDING_EXT", GLint, ["ctx->ReadBuffer->Name"], "",
+ ["EXT_framebuffer_blit"] ),
+
# GL_ARB_fragment_shader
( "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", GLint,
["ctx->Const.FragmentProgram.MaxUniformComponents"], "",
diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h
index 2d2da49fe5..bab962ad5e 100644
--- a/src/mesa/main/glheader.h
+++ b/src/mesa/main/glheader.h
@@ -237,7 +237,7 @@
#endif
-#if (!defined(__GNUC__) || __GNUC__ < 3) && !defined(__IBMC__)
+#if (!defined(__GNUC__) || __GNUC__ < 3) && (!defined(__IBMC__) || __IBMC__ < 900)
# define __builtin_expect(x, y) x
#endif
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 3ae56c8b0b..1aebb25163 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -104,6 +104,8 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment)
(void) posix_memalign(& mem, alignment, bytes);
return mem;
+#elif defined(_WIN32) && defined(_MSC_VER)
+ return _aligned_malloc(bytes, alignment);
#else
uintptr_t ptr, buf;
@@ -144,6 +146,15 @@ _mesa_align_calloc(size_t bytes, unsigned long alignment)
}
return mem;
+#elif defined(_WIN32) && defined(_MSC_VER)
+ void *mem;
+
+ mem = _aligned_malloc(bytes, alignment);
+ if (mem != NULL) {
+ (void) memset(mem, 0, bytes);
+ }
+
+ return mem;
#else
uintptr_t ptr, buf;
@@ -180,6 +191,8 @@ _mesa_align_free(void *ptr)
{
#if defined(HAVE_POSIX_MEMALIGN)
free(ptr);
+#elif defined(_WIN32) && defined(_MSC_VER)
+ _aligned_free(ptr);
#else
void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
void *realAddr = *cubbyHole;
@@ -194,6 +207,10 @@ void *
_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
unsigned long alignment)
{
+#if defined(_WIN32) && defined(_MSC_VER)
+ (void) oldSize;
+ return _aligned_realloc(oldBuffer, newSize, alignment);
+#else
const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
void *newBuf = _mesa_align_malloc(newSize, alignment);
if (newBuf && oldBuffer && copySize > 0) {
@@ -202,6 +219,7 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
if (oldBuffer)
_mesa_align_free(oldBuffer);
return newBuf;
+#endif
}
@@ -560,6 +578,7 @@ _mesa_ffs(int i)
bit++;
i >>= 1;
}
+ bit++;
}
return bit;
#else
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index ebdfc452a7..b0234a2b85 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -159,7 +159,7 @@ typedef union { GLfloat f; GLint i; } fi_type;
***/
#if defined(__i386__) || defined(__386__) || defined(__sparc__) || \
defined(__s390x__) || defined(__powerpc__) || \
- defined(__amd64__) || \
+ defined(__amd64__) || defined(__x86_64__) || \
defined(ia64) || defined(__ia64__) || \
defined(__hppa__) || defined(hpux) || \
defined(__mips) || defined(_MIPS_ARCH) || \
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index b1c00a36ac..fb68bf0720 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -1272,7 +1272,7 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx )
}
else {
/* _Current pointer has been updated in update_program */
- // ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ /* ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; */
}
/* Tell the driver about the change. Could define a new target for
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 7241cf61be..adf3d37597 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2306,9 +2306,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
return;
}
- if (!pixels)
- return;
-
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 11720e4073..f41ee73c88 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -443,7 +443,7 @@ void GLAPIENTRY
_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr)
{
- const GLboolean normalized = GL_FALSE;
+ GLboolean normalized = GL_FALSE;
GLsizei elementSize;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -471,6 +471,7 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
/* check for valid 'type' and compute StrideB right away */
switch (type) {
case GL_UNSIGNED_BYTE:
+ normalized = GL_TRUE;
elementSize = size * sizeof(GLubyte);
break;
case GL_SHORT:
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 10fa196586..74004e9b13 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -2,7 +2,7 @@
* Mesa 3-D graphics library
* Version: 7.1
*
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -1616,8 +1616,6 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst,
if (err) {
program_error(ctx, Program->Position, "Bad attribute binding");
- } else {
- Program->Base.InputsRead |= (1 << *inputReg);
}
return err;
@@ -1862,12 +1860,14 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
break;
case PARAM_CONSTANT:
+ /* parsing something like {1.0, 2.0, 3.0, 4.0} */
parse_constant (inst, const_values, Program, use);
idx = _mesa_add_named_constant(Program->Base.Parameters,
(char *) param_var->name,
const_values, 4);
if (param_var->param_binding_begin == ~0U)
param_var->param_binding_begin = idx;
+ param_var->param_binding_type = PROGRAM_CONSTANT;
param_var->param_binding_length++;
Program->Base.NumParameters++;
break;
@@ -2574,26 +2574,32 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
return 1;
}
+ /* Add attributes to InputsRead only if they are used the program.
+ * This avoids the handling of unused ATTRIB declarations in the drivers. */
+ if (*File == PROGRAM_INPUT)
+ Program->Base.InputsRead |= (1 << *Index);
+
return 0;
}
+
/**
- * Parse fragment program vector source register.
+ * Parse vertex/fragment program vector source register.
*/
static GLuint
-parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *program,
- struct prog_src_register *reg)
+parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst,
+ struct var_cache **vc_head,
+ struct arb_program *program,
+ struct prog_src_register *reg)
{
enum register_file file;
GLint index;
- GLboolean negate;
+ GLubyte negateMask;
GLubyte swizzle[4];
GLboolean isRelOffset;
/* Grab the sign */
- negate = (parse_sign (inst) == -1) ? 0xf : 0x0;
+ negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
/* And the src reg */
if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
@@ -2604,66 +2610,66 @@ parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,
reg->File = file;
reg->Index = index;
- reg->NegateBase = negate;
reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
+ reg->NegateBase = negateMask;
+ reg->RelAddr = isRelOffset;
return 0;
}
/**
- * Parse fragment program destination register.
- * \return 1 if error, 0 if no error.
+ * Parse vertex/fragment program scalar source register.
*/
-static GLuint
-parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- struct prog_dst_register *reg )
+static GLuint
+parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst,
+ struct var_cache **vc_head,
+ struct arb_program *program,
+ struct prog_src_register *reg)
{
- GLint mask;
- GLuint idx;
enum register_file file;
+ GLint index;
+ GLubyte negateMask;
+ GLubyte swizzle[4];
+ GLboolean isRelOffset;
+
+ /* Grab the sign */
+ negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
- if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask))
+ /* And the src reg */
+ if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
return 1;
+ /* finally, the swizzle */
+ parse_swizzle_mask(inst, swizzle, 1);
+
reg->File = file;
- reg->Index = idx;
- reg->WriteMask = mask;
+ reg->Index = index;
+ reg->Swizzle = (swizzle[0] << 0);
+ reg->NegateBase = negateMask;
+ reg->RelAddr = isRelOffset;
return 0;
}
/**
- * Parse fragment program scalar src register.
+ * Parse vertex/fragment program destination register.
* \return 1 if error, 0 if no error.
*/
-static GLuint
-parse_fp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program,
- struct prog_src_register *reg )
+static GLuint
+parse_dst_reg(GLcontext * ctx, const GLubyte ** inst,
+ struct var_cache **vc_head, struct arb_program *program,
+ struct prog_dst_register *reg )
{
- enum register_file File;
- GLint Index;
- GLubyte Negate;
- GLubyte Swizzle[4];
- GLboolean IsRelOffset;
-
- /* Grab the sign */
- Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0;
+ GLint mask;
+ GLuint idx;
+ enum register_file file;
- /* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
+ if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask))
return 1;
- /* finally, the swizzle */
- parse_swizzle_mask(inst, Swizzle, 1);
-
- reg->File = File;
- reg->Index = Index;
- reg->NegateBase = Negate;
- reg->Swizzle = (Swizzle[0] << 0);
-
+ reg->File = file;
+ reg->Index = idx;
+ reg->WriteMask = mask;
return 0;
}
@@ -2744,10 +2750,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
break;
@@ -2797,10 +2803,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
- if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
break;
@@ -2813,11 +2819,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
return 1;
}
break;
@@ -2898,10 +2904,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
return 1;
}
break;
@@ -2927,11 +2933,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
for (a = 0; a < 3; a++) {
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
return 1;
}
break;
@@ -2944,7 +2950,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
fp->Opcode = OPCODE_SWZ;
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
{
@@ -2987,10 +2993,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
/* texImageUnit */
@@ -3062,7 +3068,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
case OP_TEX_KIL:
Program->UsesKill = 1;
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
fp->Opcode = OPCODE_KIL;
break;
@@ -3074,23 +3080,6 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
return 0;
}
-static GLuint
-parse_vp_dst_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- struct prog_dst_register *reg )
-{
- GLint mask;
- GLuint idx;
- enum register_file file;
-
- if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask))
- return 1;
-
- reg->File = file;
- reg->Index = idx;
- reg->WriteMask = mask;
- return 0;
-}
/**
* Handle the parsing out of a masked address register
@@ -3122,71 +3111,6 @@ parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst,
return 0;
}
-/**
- * Parse vertex program vector source register.
- */
-static GLuint
-parse_vp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *program,
- struct prog_src_register *reg )
-{
- enum register_file file;
- GLint index;
- GLubyte negateMask;
- GLubyte swizzle[4];
- GLboolean isRelOffset;
-
- /* Grab the sign */
- negateMask = (parse_sign (inst) == -1) ? 0xf : 0x0;
-
- /* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset))
- return 1;
-
- /* finally, the swizzle */
- parse_swizzle_mask(inst, swizzle, 4);
-
- reg->File = file;
- reg->Index = index;
- reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
- swizzle[2], swizzle[3]);
- reg->NegateBase = negateMask;
- reg->RelAddr = isRelOffset;
- return 0;
-}
-
-
-static GLuint
-parse_vp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program,
- struct prog_src_register *reg )
-{
- enum register_file File;
- GLint Index;
- GLubyte Negate;
- GLubyte Swizzle[4];
- GLboolean IsRelOffset;
-
- /* Grab the sign */
- Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0;
-
- /* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
- return 1;
-
- /* finally, the swizzle */
- parse_swizzle_mask(inst, Swizzle, 1);
-
- reg->File = File;
- reg->Index = Index;
- reg->Swizzle = (Swizzle[0] << 0);
- reg->NegateBase = Negate;
- reg->RelAddr = IsRelOffset;
- return 0;
-}
-
/**
* This is a big mother that handles getting opcodes into the instruction
@@ -3224,7 +3148,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->DstReg.File = PROGRAM_ADDRESS;
/* Get a scalar src register */
- if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
return 1;
break;
@@ -3248,10 +3172,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
- if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
return 1;
break;
@@ -3276,10 +3200,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->Opcode = OPCODE_RSQ;
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
- if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
return 1;
break;
@@ -3289,11 +3213,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->Opcode = OPCODE_POW;
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
return 1;
}
break;
@@ -3337,11 +3261,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->Opcode = OPCODE_XPD;
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
return 1;
}
break;
@@ -3353,11 +3277,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
for (a = 0; a < 3; a++) {
- if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
return 1;
}
break;
@@ -3375,7 +3299,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
enum register_file file;
GLint index;
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr))
diff --git a/src/mesa/shader/arbprogram.syn b/src/mesa/shader/arbprogram.syn
index 1746a876c3..f3aa1ad724 100644
--- a/src/mesa/shader/arbprogram.syn
+++ b/src/mesa/shader/arbprogram.syn
@@ -1942,10 +1942,10 @@ stateTexEnvProperty
fragment program
<optLegacyTexUnitNum> ::= ""
| "[" <legacyTexUnitNum> "]"
-
-NOTE: <optLegaceTexUnitNum> is not optional.
*/
optLegacyTexUnitNum
+ optLegacyTexUnitNum_1 .or .true .emit 0x00;
+optLegacyTexUnitNum_1
lbracket_ne .and legacyTexUnitNum .and rbracket;
/*
diff --git a/src/mesa/shader/arbprogram_syn.h b/src/mesa/shader/arbprogram_syn.h
index 5f3f7d6cf4..3f3ab073cf 100644
--- a/src/mesa/shader/arbprogram_syn.h
+++ b/src/mesa/shader/arbprogram_syn.h
@@ -926,6 +926,8 @@
"stateTexEnvProperty\n"
" \"color\" .emit TEX_ENV_COLOR;\n"
"optLegacyTexUnitNum\n"
+" optLegacyTexUnitNum_1 .or .true .emit 0x00;\n"
+"optLegacyTexUnitNum_1\n"
" lbracket_ne .and legacyTexUnitNum .and rbracket;\n"
"legacyTexUnitNum\n"
" integer;\n"
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index e92837f739..308cce2206 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -99,7 +99,23 @@ arb_input_attrib_string(GLint index, GLenum progType)
"vertex.texcoord[4]",
"vertex.texcoord[5]",
"vertex.texcoord[6]",
- "vertex.texcoord[7]"
+ "vertex.texcoord[7]",
+ "vertex.attrib[0]",
+ "vertex.attrib[1]",
+ "vertex.attrib[2]",
+ "vertex.attrib[3]",
+ "vertex.attrib[4]",
+ "vertex.attrib[5]",
+ "vertex.attrib[6]",
+ "vertex.attrib[7]",
+ "vertex.attrib[8]",
+ "vertex.attrib[9]",
+ "vertex.attrib[10]",
+ "vertex.attrib[11]",
+ "vertex.attrib[12]",
+ "vertex.attrib[13]",
+ "vertex.attrib[14]",
+ "vertex.attrib[15]"
};
const char *fragAttribs[] = {
"fragment.position",
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
index da0bb85f16..4ae74c1d42 100644
--- a/src/mesa/shader/prog_statevars.c
+++ b/src/mesa/shader/prog_statevars.c
@@ -181,7 +181,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
}
/* [3] = material alpha */
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
return;
case STATE_DIFFUSE:
for (i = 0; i < 3; i++) {
@@ -197,7 +197,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
}
/* [3] = material alpha */
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
return;
default:
_mesa_problem(ctx, "Invalid lightprod state in fetch_state");
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 2097c39591..d2c9183558 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -386,7 +386,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
clone->Format = prog->Format;
clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
if (!clone->Instructions) {
- _mesa_delete_program(ctx, clone);
+ ctx->Driver.DeleteProgram(ctx, clone);
return NULL;
}
_mesa_copy_instructions(clone->Instructions, prog->Instructions,
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index e9c35fce71..76da855a07 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -79,7 +79,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
/* to prevent a double-free in the next call */
shProg->VertexProgram->Base.Parameters = NULL;
}
- _mesa_delete_program(ctx, &shProg->VertexProgram->Base);
+ ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base);
shProg->VertexProgram = NULL;
}
@@ -88,7 +88,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
/* to prevent a double-free in the next call */
shProg->FragmentProgram->Base.Parameters = NULL;
}
- _mesa_delete_program(ctx, &shProg->FragmentProgram->Base);
+ ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base);
shProg->FragmentProgram = NULL;
}
@@ -246,7 +246,7 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
_mesa_free(sh->InfoLog);
for (i = 0; i < sh->NumPrograms; i++) {
assert(sh->Programs[i]);
- _mesa_delete_program(ctx, sh->Programs[i]);
+ ctx->Driver.DeleteProgram(ctx, sh->Programs[i]);
}
if (sh->Programs)
_mesa_free(sh->Programs);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 9947544a08..9c307c6275 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -677,6 +677,7 @@ static struct prog_instruction *
emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
{
struct prog_instruction *inst;
+ slang_ir_node tmpNode;
assert(n->Opcode == IR_CLAMP);
/* ch[0] = value
@@ -722,18 +723,27 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
emit(emitInfo, n->Children[1]);
emit(emitInfo, n->Children[2]);
+ /* Some GPUs don't allow reading from output registers. So if the
+ * dest for this clamp() is an output reg, we can't use that reg for
+ * the intermediate result. Use a temp register instead.
+ */
+ _mesa_bzero(&tmpNode, sizeof(tmpNode));
+ alloc_temp_storage(emitInfo, &tmpNode, n->Store->Size);
+
/* tmp = max(ch[0], ch[1]) */
inst = new_instruction(emitInfo, OPCODE_MAX);
- storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
+ storage_to_dst_reg(&inst->DstReg, tmpNode.Store, n->Writemask);
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store);
- /* tmp = min(tmp, ch[2]) */
+ /* n->dest = min(tmp, ch[2]) */
inst = new_instruction(emitInfo, OPCODE_MIN);
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
- storage_to_src_reg(&inst->SrcReg[0], n->Store);
+ storage_to_src_reg(&inst->SrcReg[0], tmpNode.Store);
storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store);
+ free_temp_storage(emitInfo->vt, &tmpNode);
+
return inst;
}
diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c
index 1e7f6c18e6..f3dda12e25 100644
--- a/src/mesa/swrast/s_bitmap.c
+++ b/src/mesa/swrast/s_bitmap.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -57,25 +57,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
ASSERT(ctx->RenderMode == GL_RENDER);
- if (unpack->BufferObj->Name) {
- /* unpack from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
- GL_COLOR_INDEX, GL_BITMAP,
- (GLvoid *) bitmap)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- unpack->BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
- return;
- }
- bitmap = ADD_POINTERS(buf, bitmap);
- }
+ bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
+ if (!bitmap)
+ return;
RENDER_START(swrast,ctx);
@@ -150,11 +134,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
RENDER_FINISH(swrast,ctx);
- if (unpack->BufferObj->Name) {
- /* done with PBO so unmap it now */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- unpack->BufferObj);
- }
+ _mesa_unmap_bitmap_pbo(ctx, unpack);
}
diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c
index b74c4ab1c8..0d1e9bac1c 100644
--- a/src/mesa/swrast/s_buffers.c
+++ b/src/mesa/swrast/s_buffers.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -331,7 +331,8 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers)
/* do software clearing here */
if (buffers) {
- if (buffers & ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
+ if ((buffers & BUFFER_BITS_COLOR)
+ && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
clear_color_buffers(ctx);
}
if (buffers & BUFFER_BIT_DEPTH) {
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 4733d10bb5..81f5caa270 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -817,7 +817,6 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
-
/**
* Execute software-based glDrawPixels.
* By time we get here, all error checking will have been done.
@@ -840,27 +839,9 @@ _swrast_DrawPixels( GLcontext *ctx,
if (swrast->NewState)
_swrast_validate_derived( ctx );
- if (unpack->BufferObj->Name) {
- /* unpack from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawPixels(invalid PBO access)");
- RENDER_FINISH(swrast, ctx);
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- unpack->BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)");
- RENDER_FINISH(swrast, ctx);
- return;
- }
- pixels = ADD_POINTERS(buf, pixels);
- }
+ pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ if (!pixels)
+ return;
switch (format) {
case GL_STENCIL_INDEX:
@@ -899,11 +880,7 @@ _swrast_DrawPixels( GLcontext *ctx,
RENDER_FINISH(swrast,ctx);
- if (unpack->BufferObj->Name) {
- /* done with PBO so unmap it now */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- unpack->BufferObj);
- }
+ _mesa_unmap_drapix_pbo(ctx, unpack);
}
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index 8df15c8704..9140d12ea0 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -574,28 +574,10 @@ _swrast_ReadPixels( GLcontext *ctx,
return;
}
- if (clippedPacking.BufferObj->Name) {
- /* pack into PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, &clippedPacking, width, height, 1,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(invalid PBO access)");
- RENDER_FINISH(swrast, ctx);
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- clippedPacking.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
- RENDER_FINISH(swrast, ctx);
- return;
- }
- pixels = ADD_POINTERS(buf, pixels);
- }
-
+ pixels = _mesa_map_readpix_pbo(ctx, &clippedPacking, pixels);
+ if (!pixels)
+ return;
+
switch (format) {
case GL_COLOR_INDEX:
read_index_pixels(ctx, x, y, width, height, type, pixels,
@@ -634,9 +616,5 @@ _swrast_ReadPixels( GLcontext *ctx,
RENDER_FINISH(swrast, ctx);
- if (clippedPacking.BufferObj->Name) {
- /* done with PBO so unmap it now */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- clippedPacking.BufferObj);
- }
+ _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
}
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index d404579279..864f77a417 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -1183,8 +1183,10 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
convert_color_type(span, GL_FLOAT, 0);
}
- if (span->primitive != GL_POINT || ctx->Point.PointSprite) {
- /* for points, we populated the arrays already */
+ if (span->primitive != GL_POINT ||
+ (span->interpMask & SPAN_RGBA) ||
+ ctx->Point.PointSprite) {
+ /* for single-pixel points, we populated the arrays already */
interpolate_active_attribs(ctx, span, ~0);
}
span->array->ChanType = GL_FLOAT;
diff --git a/src/mesa/tnl/t_vertex_sse.c b/src/mesa/tnl/t_vertex_sse.c
index 9515d9f81f..f1c98fe2d1 100644
--- a/src/mesa/tnl/t_vertex_sse.c
+++ b/src/mesa/tnl/t_vertex_sse.c
@@ -648,12 +648,12 @@ void _tnl_generate_sse_emit( GLcontext *ctx )
p.ctx = ctx;
p.inputs_safe = 0; /* for now */
- p.outputs_safe = 1; /* for now */
+ p.outputs_safe = 0; /* for now */
p.have_sse2 = cpu_has_xmm2;
p.identity = x86_make_reg(file_XMM, 6);
p.chan0 = x86_make_reg(file_XMM, 7);
- if (!x86_init_func(&p.func, MAX_SSE_CODE_SIZE)) {
+ if (!x86_init_func_size(&p.func, MAX_SSE_CODE_SIZE)) {
vtx->emit = NULL;
return;
}
diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c
index 612cd51a6e..772471c723 100644
--- a/src/mesa/x86/rtasm/x86sse.c
+++ b/src/mesa/x86/rtasm/x86sse.c
@@ -1,4 +1,4 @@
-#if defined(USE_X86_ASM) || defined(SLANG_X86)
+#if defined(__i386__) || defined(__386__)
#include "imports.h"
#include "x86sse.h"
@@ -6,54 +6,78 @@
#define DISASSEM 0
#define X86_TWOB 0x0f
-/* Emit bytes to the instruction stream:
- */
-static void emit_1b( struct x86_function *p, GLbyte b0 )
+static unsigned char *cptr( void (*label)() )
{
- *(GLbyte *)(p->csr++) = b0;
+ return (unsigned char *)(unsigned long)label;
}
-static void emit_1i( struct x86_function *p, GLint i0 )
+
+static void do_realloc( struct x86_function *p )
{
- *(GLint *)(p->csr) = i0;
- p->csr += 4;
+ if (p->size == 0) {
+ p->size = 1024;
+ p->store = _mesa_exec_malloc(p->size);
+ p->csr = p->store;
+ }
+ else {
+ unsigned used = p->csr - p->store;
+ unsigned char *tmp = p->store;
+ p->size *= 2;
+ p->store = _mesa_exec_malloc(p->size);
+ memcpy(p->store, tmp, used);
+ p->csr = p->store + used;
+ _mesa_exec_free(tmp);
+ }
}
-static void disassem( struct x86_function *p, const char *fn )
+/* Emit bytes to the instruction stream:
+ */
+static unsigned char *reserve( struct x86_function *p, int bytes )
{
-#if DISASSEM && 0
- if (fn && fn != p->fn) {
- _mesa_printf("0x%x: %s\n", p->csr, fn);
- p->fn = fn;
+ if (p->csr + bytes - p->store > p->size)
+ do_realloc(p);
+
+ {
+ unsigned char *csr = p->csr;
+ p->csr += bytes;
+ return csr;
}
-#endif
}
-static void emit_1ub_fn( struct x86_function *p, GLubyte b0, const char *fn )
+
+
+static void emit_1b( struct x86_function *p, char b0 )
{
- disassem(p, fn);
- *(p->csr++) = b0;
+ char *csr = (char *)reserve(p, 1);
+ *csr = b0;
}
-static void emit_2ub_fn( struct x86_function *p, GLubyte b0, GLubyte b1, const char *fn )
+static void emit_1i( struct x86_function *p, int i0 )
{
- disassem(p, fn);
- *(p->csr++) = b0;
- *(p->csr++) = b1;
+ int *icsr = (int *)reserve(p, sizeof(i0));
+ *icsr = i0;
}
-static void emit_3ub_fn( struct x86_function *p, GLubyte b0, GLubyte b1, GLubyte b2, const char *fn )
+static void emit_1ub( struct x86_function *p, unsigned char b0 )
{
- disassem(p, fn);
- *(p->csr++) = b0;
- *(p->csr++) = b1;
- *(p->csr++) = b2;
+ unsigned char *csr = reserve(p, 1);
+ *csr++ = b0;
}
-#define emit_1ub(p, b0) emit_1ub_fn(p, b0, __FUNCTION__)
-#define emit_2ub(p, b0, b1) emit_2ub_fn(p, b0, b1, __FUNCTION__)
-#define emit_3ub(p, b0, b1, b2) emit_3ub_fn(p, b0, b1, b2, __FUNCTION__)
+static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 )
+{
+ unsigned char *csr = reserve(p, 2);
+ *csr++ = b0;
+ *csr++ = b1;
+}
+static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 )
+{
+ unsigned char *csr = reserve(p, 3);
+ *csr++ = b0;
+ *csr++ = b1;
+ *csr++ = b2;
+}
/* Build a modRM byte + possible displacement. No treatment of SIB
@@ -63,7 +87,7 @@ static void emit_modrm( struct x86_function *p,
struct x86_reg reg,
struct x86_reg regmem )
{
- GLubyte val = 0;
+ unsigned char val = 0;
assert(reg.mod == mod_REG);
@@ -71,13 +95,13 @@ static void emit_modrm( struct x86_function *p,
val |= reg.idx << 3; /* reg field */
val |= regmem.idx; /* r/m field */
- emit_1ub_fn(p, val, 0);
+ emit_1ub(p, val);
/* Oh-oh we've stumbled into the SIB thing.
*/
if (regmem.file == file_REG32 &&
regmem.idx == reg_SP) {
- emit_1ub_fn(p, 0x24, 0); /* simplistic! */
+ emit_1ub(p, 0x24); /* simplistic! */
}
switch (regmem.mod) {
@@ -98,7 +122,7 @@ static void emit_modrm( struct x86_function *p,
static void emit_modrm_noreg( struct x86_function *p,
- GLuint op,
+ unsigned op,
struct x86_reg regmem )
{
struct x86_reg dummy = x86_make_reg(file_REG32, op);
@@ -111,21 +135,21 @@ static void emit_modrm_noreg( struct x86_function *p,
* the arguments presented.
*/
static void emit_op_modrm( struct x86_function *p,
- GLubyte op_dst_is_reg,
- GLubyte op_dst_is_mem,
+ unsigned char op_dst_is_reg,
+ unsigned char op_dst_is_mem,
struct x86_reg dst,
struct x86_reg src )
{
switch (dst.mod) {
case mod_REG:
- emit_1ub_fn(p, op_dst_is_reg, 0);
+ emit_1ub(p, op_dst_is_reg);
emit_modrm(p, dst, src);
break;
case mod_INDIRECT:
case mod_DISP32:
case mod_DISP8:
assert(src.mod == mod_REG);
- emit_1ub_fn(p, op_dst_is_mem, 0);
+ emit_1ub(p, op_dst_is_mem);
emit_modrm(p, src, dst);
break;
default:
@@ -156,7 +180,7 @@ struct x86_reg x86_make_reg( enum x86_reg_file file,
}
struct x86_reg x86_make_disp( struct x86_reg reg,
- GLint disp )
+ int disp )
{
assert(reg.file == file_REG32);
@@ -185,7 +209,7 @@ struct x86_reg x86_get_base_reg( struct x86_reg reg )
return x86_make_reg( reg.file, reg.idx );
}
-GLubyte *x86_get_label( struct x86_function *p )
+unsigned char *x86_get_label( struct x86_function *p )
{
return p->csr;
}
@@ -199,13 +223,13 @@ GLubyte *x86_get_label( struct x86_function *p )
void x86_jcc( struct x86_function *p,
enum x86_cc cc,
- GLubyte *label )
+ unsigned char *label )
{
- GLint offset = label - (x86_get_label(p) + 2);
+ int offset = label - (x86_get_label(p) + 2);
if (offset <= 127 && offset >= -128) {
emit_1ub(p, 0x70 + cc);
- emit_1b(p, (GLbyte) offset);
+ emit_1b(p, (char) offset);
}
else {
offset = label - (x86_get_label(p) + 6);
@@ -216,7 +240,7 @@ void x86_jcc( struct x86_function *p,
/* Always use a 32bit offset for forward jumps:
*/
-GLubyte *x86_jcc_forward( struct x86_function *p,
+unsigned char *x86_jcc_forward( struct x86_function *p,
enum x86_cc cc )
{
emit_2ub(p, 0x0f, 0x80 + cc);
@@ -224,14 +248,14 @@ GLubyte *x86_jcc_forward( struct x86_function *p,
return x86_get_label(p);
}
-GLubyte *x86_jmp_forward( struct x86_function *p)
+unsigned char *x86_jmp_forward( struct x86_function *p)
{
emit_1ub(p, 0xe9);
emit_1i(p, 0);
return x86_get_label(p);
}
-GLubyte *x86_call_forward( struct x86_function *p)
+unsigned char *x86_call_forward( struct x86_function *p)
{
emit_1ub(p, 0xe8);
emit_1i(p, 0);
@@ -241,28 +265,41 @@ GLubyte *x86_call_forward( struct x86_function *p)
/* Fixup offset from forward jump:
*/
void x86_fixup_fwd_jump( struct x86_function *p,
- GLubyte *fixup )
+ unsigned char *fixup )
{
*(int *)(fixup - 4) = x86_get_label(p) - fixup;
}
-void x86_jmp( struct x86_function *p, GLubyte *label)
+void x86_jmp( struct x86_function *p, unsigned char *label)
{
emit_1ub(p, 0xe9);
emit_1i(p, label - x86_get_label(p) - 4);
}
-void x86_call( struct x86_function *p, GLubyte *label)
+#if 0
+/* This doesn't work once we start reallocating & copying the
+ * generated code on buffer fills, because the call is relative to the
+ * current pc.
+ */
+void x86_call( struct x86_function *p, void (*label)())
{
emit_1ub(p, 0xe8);
- emit_1i(p, label - x86_get_label(p) - 4);
+ emit_1i(p, cptr(label) - x86_get_label(p) - 4);
+}
+#else
+void x86_call( struct x86_function *p, struct x86_reg reg)
+{
+ emit_1ub(p, 0xff);
+ emit_modrm(p, reg, reg);
}
+#endif
+
/* michal:
* Temporary. As I need immediate operands, and dont want to mess with the codegen,
* I load the immediate into general purpose register and use it.
*/
-void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, GLint imm )
+void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )
{
assert(dst.mod == mod_REG);
emit_1ub(p, 0xb8 + dst.idx);
@@ -502,6 +539,14 @@ void sse_addss( struct x86_function *p,
emit_modrm( p, dst, src );
}
+void sse_andnps( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
+ emit_2ub(p, X86_TWOB, 0x55);
+ emit_modrm( p, dst, src );
+}
+
void sse_andps( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src )
@@ -510,6 +555,13 @@ void sse_andps( struct x86_function *p,
emit_modrm( p, dst, src );
}
+void sse_rsqrtps( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
+ emit_2ub(p, X86_TWOB, 0x52);
+ emit_modrm( p, dst, src );
+}
void sse_rsqrtss( struct x86_function *p,
struct x86_reg dst,
@@ -538,6 +590,21 @@ void sse_movlhps( struct x86_function *p,
emit_modrm( p, dst, src );
}
+void sse_orps( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
+ emit_2ub(p, X86_TWOB, 0x56);
+ emit_modrm( p, dst, src );
+}
+
+void sse_xorps( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
+ emit_2ub(p, X86_TWOB, 0x57);
+ emit_modrm( p, dst, src );
+}
void sse_cvtps2pi( struct x86_function *p,
struct x86_reg dst,
@@ -559,7 +626,7 @@ void sse_cvtps2pi( struct x86_function *p,
void sse_shufps( struct x86_function *p,
struct x86_reg dest,
struct x86_reg arg0,
- GLubyte shuf)
+ unsigned char shuf)
{
emit_2ub(p, X86_TWOB, 0xC6);
emit_modrm(p, dest, arg0);
@@ -569,13 +636,21 @@ void sse_shufps( struct x86_function *p,
void sse_cmpps( struct x86_function *p,
struct x86_reg dest,
struct x86_reg arg0,
- GLubyte cc)
+ unsigned char cc)
{
emit_2ub(p, X86_TWOB, 0xC2);
emit_modrm(p, dest, arg0);
emit_1ub(p, cc);
}
+void sse_pmovmskb( struct x86_function *p,
+ struct x86_reg dest,
+ struct x86_reg src)
+{
+ emit_3ub(p, 0x66, X86_TWOB, 0xD7);
+ emit_modrm(p, dest, src);
+}
+
/***********************************************************************
* SSE2 instructions
*/
@@ -586,13 +661,21 @@ void sse_cmpps( struct x86_function *p,
void sse2_pshufd( struct x86_function *p,
struct x86_reg dest,
struct x86_reg arg0,
- GLubyte shuf)
+ unsigned char shuf)
{
emit_3ub(p, 0x66, X86_TWOB, 0x70);
emit_modrm(p, dest, arg0);
emit_1ub(p, shuf);
}
+void sse2_cvttps2dq( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
+ emit_3ub( p, 0xF3, X86_TWOB, 0x5B );
+ emit_modrm( p, dst, src );
+}
+
void sse2_cvtps2dq( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src )
@@ -625,6 +708,14 @@ void sse2_packuswb( struct x86_function *p,
emit_modrm( p, dst, src );
}
+void sse2_rcpps( struct x86_function *p,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
+ emit_2ub(p, X86_TWOB, 0x53);
+ emit_modrm( p, dst, src );
+}
+
void sse2_rcpss( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src )
@@ -712,11 +803,11 @@ void x87_fclex( struct x86_function *p )
static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg,
- GLubyte dst0ub0,
- GLubyte dst0ub1,
- GLubyte arg0ub0,
- GLubyte arg0ub1,
- GLubyte argmem_noreg)
+ unsigned char dst0ub0,
+ unsigned char dst0ub1,
+ unsigned char arg0ub0,
+ unsigned char arg0ub1,
+ unsigned char argmem_noreg)
{
assert(dst.file == file_x87);
@@ -729,7 +820,7 @@ static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86
assert(0);
}
else if (dst.idx == 0) {
- assert(arg.file = file_REG32);
+ assert(arg.file == file_REG32);
emit_1ub(p, 0xd8);
emit_modrm_noreg(p, argmem_noreg, arg);
}
@@ -1056,44 +1147,42 @@ void mmx_movq( struct x86_function *p,
* account any push/pop activity:
*/
struct x86_reg x86_fn_arg( struct x86_function *p,
- GLuint arg )
+ unsigned arg )
{
return x86_make_disp(x86_make_reg(file_REG32, reg_SP),
p->stack_offset + arg * 4); /* ??? */
}
-/**
- * Initialize an x86_function object, allocating space for up to
- * 'code_size' bytes of code.
- */
-GLboolean x86_init_func( struct x86_function *p, GLuint code_size )
+void x86_init_func( struct x86_function *p )
{
- assert(!p->store);
+ p->size = 0;
+ p->store = NULL;
+ p->csr = p->store;
+}
+
+int x86_init_func_size( struct x86_function *p, unsigned code_size )
+{
+ p->size = code_size;
p->store = _mesa_exec_malloc(code_size);
- if (p->store) {
- p->csr = p->store;
- return GL_TRUE;
- }
- else {
- p->csr = NULL;
- return GL_FALSE;
- }
+ p->csr = p->store;
+ return p->store != NULL;
}
void x86_release_func( struct x86_function *p )
{
- if (p->store)
- _mesa_exec_free(p->store);
- p->store = p->csr = NULL;
+ _mesa_exec_free(p->store);
+ p->store = NULL;
+ p->csr = NULL;
+ p->size = 0;
}
void (*x86_get_func( struct x86_function *p ))(void)
{
- if (DISASSEM)
+ if (DISASSEM && p->store)
_mesa_printf("disassemble %p %p\n", p->store, p->csr);
- return (void (*)(void))p->store;
+ return (void (*)(void)) (unsigned long) p->store;
}
#else
diff --git a/src/mesa/x86/rtasm/x86sse.h b/src/mesa/x86/rtasm/x86sse.h
index 42b09937bc..f6282f5bd4 100644
--- a/src/mesa/x86/rtasm/x86sse.h
+++ b/src/mesa/x86/rtasm/x86sse.h
@@ -2,26 +2,25 @@
#ifndef _X86SSE_H_
#define _X86SSE_H_
-#if defined(USE_X86_ASM) || defined(SLANG_X86)
-
-#include "glheader.h"
+#if defined(__i386__) || defined(__386__)
/* It is up to the caller to ensure that instructions issued are
* suitable for the host cpu. There are no checks made in this module
* for mmx/sse/sse2 support on the cpu.
*/
struct x86_reg {
- GLuint file:3;
- GLuint idx:3;
- GLuint mod:2; /* mod_REG if this is just a register */
- GLint disp:24; /* only +/- 23bits of offset - should be enough... */
+ unsigned file:3;
+ unsigned idx:3;
+ unsigned mod:2; /* mod_REG if this is just a register */
+ int disp:24; /* only +/- 23bits of offset - should be enough... */
};
struct x86_function {
- GLubyte *store;
- GLubyte *csr;
- GLuint stack_offset;
- GLint need_emms;
+ unsigned size;
+ unsigned char *store;
+ unsigned char *csr;
+ unsigned stack_offset;
+ int need_emms;
const char *fn;
};
@@ -80,7 +79,8 @@ enum sse_cc {
*/
-GLboolean x86_init_func( struct x86_function *p, GLuint code_size );
+void x86_init_func( struct x86_function *p );
+int x86_init_func_size( struct x86_function *p, unsigned code_size );
void x86_release_func( struct x86_function *p );
void (*x86_get_func( struct x86_function *p ))( void );
@@ -92,7 +92,7 @@ struct x86_reg x86_make_reg( enum x86_reg_file file,
enum x86_reg_name idx );
struct x86_reg x86_make_disp( struct x86_reg reg,
- GLint disp );
+ int disp );
struct x86_reg x86_deref( struct x86_reg reg );
@@ -101,31 +101,32 @@ struct x86_reg x86_get_base_reg( struct x86_reg reg );
/* Labels, jumps and fixup:
*/
-GLubyte *x86_get_label( struct x86_function *p );
+unsigned char *x86_get_label( struct x86_function *p );
void x86_jcc( struct x86_function *p,
enum x86_cc cc,
- GLubyte *label );
+ unsigned char *label );
-GLubyte *x86_jcc_forward( struct x86_function *p,
+unsigned char *x86_jcc_forward( struct x86_function *p,
enum x86_cc cc );
-GLubyte *x86_jmp_forward( struct x86_function *p);
+unsigned char *x86_jmp_forward( struct x86_function *p);
-GLubyte *x86_call_forward( struct x86_function *p);
+unsigned char *x86_call_forward( struct x86_function *p);
void x86_fixup_fwd_jump( struct x86_function *p,
- GLubyte *fixup );
+ unsigned char *fixup );
-void x86_jmp( struct x86_function *p, GLubyte *label );
+void x86_jmp( struct x86_function *p, unsigned char *label );
-void x86_call( struct x86_function *p, GLubyte *label );
+/* void x86_call( struct x86_function *p, void (*label)() ); */
+void x86_call( struct x86_function *p, struct x86_reg reg);
/* michal:
* Temporary. As I need immediate operands, and dont want to mess with the codegen,
* I load the immediate into general purpose register and use it.
*/
-void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, GLint imm );
+void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm );
/* Macro for sse_shufps() and sse2_pshufd():
@@ -141,19 +142,24 @@ void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg sr
void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, GLubyte shuf );
+void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0,
+ unsigned char shuf );
+void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, GLubyte cc );
+void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src,
+ unsigned char cc );
void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
@@ -166,9 +172,14 @@ void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
+void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, GLubyte shuf );
+void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0,
+ unsigned char shuf );
+void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src );
void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
@@ -239,7 +250,7 @@ void x87_fucom( struct x86_function *p, struct x86_reg arg );
* account any push/pop activity. Note - doesn't track explict
* manipulation of ESP by other instructions.
*/
-struct x86_reg x86_fn_arg( struct x86_function *p, GLuint arg );
+struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg );
#endif
#endif