summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/Makefile.template1
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.c28
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.h40
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr_fake.c136
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr_ttm.c469
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c541
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h133
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h18
-rw-r--r--src/mesa/drivers/dri/common/vblank.c179
-rw-r--r--src/mesa/drivers/dri/common/vblank.h16
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_xmesa.c49
-rw-r--r--src/mesa/drivers/dri/i810/i810screen.c52
-rw-r--r--src/mesa/drivers/dri/i915/Makefile6
-rw-r--r--src/mesa/drivers/dri/i915/i915_debug.c37
-rw-r--r--src/mesa/drivers/dri/i915/i915_reg.h2
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchbuffer.c130
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchbuffer.h15
-rw-r--r--src/mesa/drivers/dri/i915/intel_blit.c22
-rw-r--r--src/mesa/drivers/dri/i915/intel_buffers.c62
-rw-r--r--src/mesa/drivers/dri/i915/intel_bufmgr_ttm.c833
-rw-r--r--src/mesa/drivers/dri/i915/intel_bufmgr_ttm.h17
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c18
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h5
-rw-r--r--src/mesa/drivers/dri/i915/intel_fbo.h2
-rw-r--r--src/mesa/drivers/dri/i915/intel_ioctl.c58
-rw-r--r--src/mesa/drivers/dri/i915/intel_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/i915/intel_mipmap_tree.c27
-rw-r--r--src/mesa/drivers/dri/i915/intel_regions.c5
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c130
l---------[-rw-r--r--]src/mesa/drivers/dri/i915/server/intel_dri.c1307
-rw-r--r--src/mesa/drivers/dri/i965/Makefile18
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_curbe.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h17
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c44
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_pool.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.h6
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c255
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_tnl.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c84
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h12
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c112
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c53
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c1354
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass0.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass2.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c11
-rw-r--r--src/mesa/drivers/dri/i965/bufmgr_fake.c2
-rw-r--r--src/mesa/drivers/dri/i965/intel_batchbuffer.c4
-rw-r--r--src/mesa/drivers/dri/i965/intel_batchbuffer.h6
-rw-r--r--src/mesa/drivers/dri/i965/intel_blit.c112
-rw-r--r--src/mesa/drivers/dri/i965/intel_blit.h2
-rw-r--r--src/mesa/drivers/dri/i965/intel_buffers.c46
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.c33
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.h7
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.c4
-rw-r--r--src/mesa/drivers/dri/i965/intel_pixel_bitmap.c9
-rw-r--r--src/mesa/drivers/dri/i965/intel_reg.h91
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c100
l---------src/mesa/drivers/dri/i965/server/intel_dri.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_reg.h (renamed from src/mesa/drivers/dri/i915/intel_reg.h)60
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.c21
-rw-r--r--src/mesa/drivers/dri/intel/server/i830_common.h (renamed from src/mesa/drivers/dri/i915/server/i830_common.h)0
-rw-r--r--src/mesa/drivers/dri/intel/server/i830_dri.h (renamed from src/mesa/drivers/dri/i915/server/i830_dri.h)0
-rw-r--r--src/mesa/drivers/dri/intel/server/intel.h (renamed from src/mesa/drivers/dri/i915/server/intel.h)0
-rw-r--r--src/mesa/drivers/dri/intel/server/intel_dri.c1306
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_context.c14
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_context.h2
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_ioctl.c4
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_ioctl.h2
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_screen.c95
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_screen.h2
-rw-r--r--src/mesa/drivers/dri/mga/mga_xmesa.c129
-rw-r--r--src/mesa/drivers/dri/mga/mgacontext.h5
-rw-r--r--src/mesa/drivers/dri/mga/mgadd.c2
-rw-r--r--src/mesa/drivers/dri/mga/mgaioctl.c9
-rw-r--r--src/mesa/drivers/dri/mga/mgaioctl.h2
-rw-r--r--src/mesa/drivers/dri/mga/mgastate.c5
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_card_list.h66
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.c44
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.h10
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_driver.c70
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.c97
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_state.c86
-rw-r--r--src/mesa/drivers/dri/r128/r128_context.c14
-rw-r--r--src/mesa/drivers/dri/r128/r128_context.h5
-rw-r--r--src/mesa/drivers/dri/r128/r128_ioctl.c8
-rw-r--r--src/mesa/drivers/dri/r128/r128_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/r128/r128_screen.c102
-rw-r--r--src/mesa/drivers/dri/r128/r128_screen.h2
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c24
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h5
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.c14
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.h10
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c4
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c6
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h8
-rw-r--r--src/mesa/drivers/dri/r300/r300_tex.c32
-rw-r--r--src/mesa/drivers/dri/r300/r300_tex.h2
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c76
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.c17
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.h5
-rw-r--r--src/mesa/drivers/dri/r300/radeon_ioctl.c10
-rw-r--r--src/mesa/drivers/dri/r300/radeon_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c25
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c174
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.h2
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_xmesa.c4
-rw-r--r--src/mesa/drivers/dri/savage/savage_xmesa.c94
-rw-r--r--src/mesa/drivers/dri/savage/savagetex.c4
-rw-r--r--src/mesa/drivers/dri/sis/sis_screen.c74
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_screen.c98
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.c52
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.c21
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.h4
-rw-r--r--src/mesa/drivers/dri/unichrome/via_ioctl.c13
-rw-r--r--src/mesa/drivers/dri/unichrome/via_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/unichrome/via_screen.c100
-rw-r--r--src/mesa/drivers/dri/unichrome/via_screen.h2
133 files changed, 5856 insertions, 4021 deletions
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index 3abce004c9..6ed6fc15b5 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -13,7 +13,6 @@ COMMON_SOURCES = \
COMMON_BM_SOURCES = \
../common/dri_bufmgr.c \
- ../common/dri_bufmgr_ttm.c \
../common/dri_bufmgr_fake.c
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c
index 407409bf06..83886480dd 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.c
@@ -88,18 +88,6 @@ dri_bo_unmap(dri_bo *buf)
return buf->bufmgr->bo_unmap(buf);
}
-int
-dri_bo_validate(dri_bo *buf, unsigned int flags)
-{
- return buf->bufmgr->bo_validate(buf, flags);
-}
-
-dri_fence *
-dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed)
-{
- return bufmgr->fence_validated(bufmgr, name, flushed);
-}
-
void
dri_fence_wait(dri_fence *fence)
{
@@ -150,3 +138,19 @@ dri_bufmgr_destroy(dri_bufmgr *bufmgr)
{
bufmgr->destroy(bufmgr);
}
+
+
+void dri_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset, dri_bo *relocatee)
+{
+ batch_buf->bufmgr->emit_reloc(batch_buf, flags, delta, offset, relocatee);
+}
+
+void *dri_process_relocs(dri_bo *batch_buf, GLuint *count)
+{
+ return batch_buf->bufmgr->process_relocs(batch_buf, count);
+}
+
+void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
+{
+ batch_buf->bufmgr->post_submit(batch_buf, last_fence);
+}
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h
index 3be342926f..7dbb558949 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.h
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.h
@@ -116,30 +116,6 @@ struct _dri_bufmgr {
/** Reduces the refcount on the userspace mapping of the buffer object. */
int (*bo_unmap)(dri_bo *buf);
- /**
- * Makes the buffer accessible to the graphics chip.
- *
- * The resulting offset of the buffer within the graphics aperture is then
- * available at buf->offset until the buffer is fenced.
- *
- * Flags should consist of the memory types that the buffer may be validated
- * into and the read/write/exe flags appropriate to the use of the buffer.
- */
- int (*bo_validate)(dri_bo *buf, unsigned int flags);
-
- /**
- * Associates the current set of validated buffers with a fence.
- *
- * Once fenced, the buffer manager will allow the validated buffers to be
- * evicted when the graphics device's execution has passed the fence
- * command.
- *
- * The fence object will have flags for the sum of the read/write/exe flags
- * of the validated buffers associated with it.
- */
- dri_fence * (*fence_validated)(dri_bufmgr *bufmgr, const char *name,
- GLboolean flushed);
-
/** Takes a reference on a fence object */
void (*fence_reference)(dri_fence *fence);
@@ -158,6 +134,15 @@ struct _dri_bufmgr {
* Tears down the buffer manager instance.
*/
void (*destroy)(dri_bufmgr *bufmgr);
+
+ /**
+ * Add relocation
+ */
+ void (*emit_reloc)(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset, dri_bo *relocatee);
+
+ void *(*process_relocs)(dri_bo *batch_buf, GLuint *count);
+
+ void (*post_submit)(dri_bo *batch_buf, dri_fence **fence);
};
dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size,
@@ -169,9 +154,6 @@ void dri_bo_reference(dri_bo *bo);
void dri_bo_unreference(dri_bo *bo);
int dri_bo_map(dri_bo *buf, GLboolean write_enable);
int dri_bo_unmap(dri_bo *buf);
-int dri_bo_validate(dri_bo *buf, unsigned int flags);
-dri_fence *dri_fence_validated(dri_bufmgr *bufmgr, const char *name,
- GLboolean flushed);
void dri_fence_wait(dri_fence *fence);
void dri_fence_reference(dri_fence *fence);
void dri_fence_unreference(dri_fence *fence);
@@ -195,4 +177,8 @@ void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
dri_bo *dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
unsigned int handle);
+void dri_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset, dri_bo *relocatee);
+void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count);
+void dri_post_process_relocs(dri_bo *batch_buf);
+void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence);
#endif
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c
index e0d23a3647..bda45d921c 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c
@@ -59,6 +59,16 @@
* processed through the command queue wouldn't need to care about
* fences.
*/
+#define MAX_RELOCS 4096
+
+struct fake_buffer_reloc
+{
+ dri_bo *buf;
+ GLuint offset;
+ GLuint delta; /* not needed? */
+ GLuint validate_flags;
+};
+
struct block {
struct block *next, *prev;
struct mem_block *mem; /* BM_MEM_AGP */
@@ -107,6 +117,12 @@ typedef struct _bufmgr_fake {
int (*fence_wait)(void *private, unsigned int fence_cookie);
/** Driver-supplied argument to driver callbacks */
void *driver_priv;
+
+
+ /** fake relocation list */
+ struct fake_buffer_reloc reloc[MAX_RELOCS];
+ GLuint nr_relocs;
+ GLboolean performed_rendering;
} dri_bufmgr_fake;
typedef struct _dri_bo_fake {
@@ -837,6 +853,120 @@ dri_fake_destroy(dri_bufmgr *bufmgr)
free(bufmgr);
}
+static void
+dri_fake_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset,
+ dri_bo *relocatee)
+{
+ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
+ struct fake_buffer_reloc *r = &bufmgr_fake->reloc[bufmgr_fake->nr_relocs++];
+
+ assert(bufmgr_fake->nr_relocs <= MAX_RELOCS);
+
+ dri_bo_reference(relocatee);
+
+ r->buf = relocatee;
+ r->offset = offset;
+ r->delta = delta;
+ r->validate_flags = flags;
+
+ return;
+}
+
+
+static int
+relocation_sort(const void *a_in, const void *b_in) {
+ const struct fake_buffer_reloc *a = a_in, *b = b_in;
+
+ return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
+}
+
+static void *
+dri_fake_process_relocs(dri_bo *batch_buf, GLuint *count_p)
+{
+ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
+ GLuint i;
+ GLuint *ptr;
+ GLuint count = 0;
+
+ assert(batch_buf->virtual != NULL);
+ ptr = batch_buf->virtual;
+
+ bufmgr_fake->performed_rendering = GL_FALSE;
+
+ /* Sort our relocation list in terms of referenced buffer pointer.
+ * This lets us uniquely validate the buffers with the sum of all the flags,
+ * while avoiding O(n^2) on number of relocations.
+ */
+ qsort(bufmgr_fake->reloc, bufmgr_fake->nr_relocs, sizeof(bufmgr_fake->reloc[0]),
+ relocation_sort);
+
+ /* Perform the necessary validations of buffers, and enter the relocations
+ * in the batchbuffer.
+ */
+ for (i = 0; i < bufmgr_fake->nr_relocs; i++) {
+ struct fake_buffer_reloc *r = &bufmgr_fake->reloc[i];
+
+ if (r->validate_flags & DRM_BO_FLAG_WRITE)
+ bufmgr_fake->performed_rendering = GL_TRUE;
+
+ /* If this is the first time we've seen this buffer in the relocation
+ * list, figure out our flags and validate it.
+ */
+ if (i == 0 || bufmgr_fake->reloc[i - 1].buf != r->buf) {
+ uint32_t validate_flags;
+ int j, ret;
+
+ /* Accumulate the flags we need for validating this buffer. */
+ validate_flags = r->validate_flags;
+ for (j = i + 1; j < bufmgr_fake->nr_relocs; j++) {
+ if (bufmgr_fake->reloc[j].buf != r->buf)
+ break;
+ validate_flags |= bufmgr_fake->reloc[j].validate_flags;
+ }
+
+ /* Validate. If we fail, fence to clear the unfenced list and bail
+ * out.
+ */
+ ret = dri_fake_bo_validate(r->buf, validate_flags);
+ if (ret != 0) {
+ dri_fence *fo;
+ dri_bo_unmap(batch_buf);
+ fo = dri_fake_fence_validated(batch_buf->bufmgr,
+ "batchbuffer failure fence", GL_TRUE);
+ dri_fence_unreference(fo);
+ goto done;
+ }
+ count++;
+ }
+ ptr[r->offset / 4] = r->buf->offset + r->delta;
+ dri_bo_unreference(r->buf);
+ }
+ dri_bo_unmap(batch_buf);
+
+ dri_fake_bo_validate(batch_buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
+
+ *count_p = count;
+ bufmgr_fake->nr_relocs = 0;
+ done:
+ return NULL;
+}
+
+static void
+dri_fake_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
+{
+ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
+ dri_fence *fo;
+
+ fo = dri_fake_fence_validated(batch_buf->bufmgr, "Batch fence", GL_TRUE);
+
+ if (bufmgr_fake->performed_rendering) {
+ dri_fence_unreference(*last_fence);
+ *last_fence = fo;
+ } else {
+ dri_fence_unreference(fo);
+ }
+}
+
dri_bufmgr *
dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
unsigned long size,
@@ -867,13 +997,13 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference;
bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map;
bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap;
- bufmgr_fake->bufmgr.bo_validate = dri_fake_bo_validate;
- bufmgr_fake->bufmgr.fence_validated = dri_fake_fence_validated;
bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait;
bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference;
bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference;
bufmgr_fake->bufmgr.destroy = dri_fake_destroy;
-
+ bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc;
+ bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs;
+ bufmgr_fake->bufmgr.post_submit = dri_fake_post_submit;
bufmgr_fake->fence_emit = fence_emit;
bufmgr_fake->fence_wait = fence_wait;
bufmgr_fake->driver_priv = driver_priv;
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
deleted file mode 100644
index 235398eb87..0000000000
--- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/**************************************************************************
- *
- * Copyright © 2007 Intel Corporation
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
- * 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"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
- * Eric Anholt <eric@anholt.net>
- */
-
-#include <xf86drm.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "glthread.h"
-#include "errno.h"
-#include "mtypes.h"
-#include "dri_bufmgr.h"
-#include "string.h"
-#include "imports.h"
-
-#define BUFMGR_DEBUG 0
-
-typedef struct _dri_bufmgr_ttm {
- dri_bufmgr bufmgr;
-
- int fd;
- _glthread_Mutex mutex;
- unsigned int fence_type;
- unsigned int fence_type_flush;
-} dri_bufmgr_ttm;
-
-typedef struct _dri_bo_ttm {
- dri_bo bo;
-
- int refcount; /* Protected by bufmgr->mutex */
- drmBO drm_bo;
- const char *name;
- /**
- * Note whether we are the owner of the buffer, to determine if we must
- * drmBODestroy or drmBOUnreference to unreference the buffer.
- */
- GLboolean owner;
-} dri_bo_ttm;
-
-typedef struct _dri_fence_ttm
-{
- dri_fence fence;
-
- int refcount; /* Protected by bufmgr->mutex */
- const char *name;
- drmFence drm_fence;
-} dri_fence_ttm;
-
-#if 0
-int
-driFenceSignaled(DriFenceObject * fence, unsigned type)
-{
- int signaled;
- int ret;
-
- if (fence == NULL)
- return GL_TRUE;
-
- _glthread_LOCK_MUTEX(fence->mutex);
- ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled);
- _glthread_UNLOCK_MUTEX(fence->mutex);
- BM_CKFATAL(ret);
- return signaled;
-}
-#endif
-
-static dri_bo *
-dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
- unsigned long size, unsigned int alignment,
- unsigned int location_mask)
-{
- dri_bufmgr_ttm *ttm_bufmgr;
- dri_bo_ttm *ttm_buf;
- unsigned int pageSize = getpagesize();
- int ret;
- unsigned int flags, hint;
-
- ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
-
- ttm_buf = malloc(sizeof(*ttm_buf));
- if (!ttm_buf)
- return NULL;
-
- /* The mask argument doesn't do anything for us that we want other than
- * determine which pool (TTM or local) the buffer is allocated into, so just
- * pass all of the allocation class flags.
- */
- flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_EXE;
- /* No hints we want to use. */
- hint = 0;
-
- ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize,
- NULL, drm_bo_type_dc,
- flags, hint, &ttm_buf->drm_bo);
- if (ret != 0) {
- free(ttm_buf);
- return NULL;
- }
- ttm_buf->bo.size = ttm_buf->drm_bo.size;
- ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
- ttm_buf->bo.virtual = NULL;
- ttm_buf->bo.bufmgr = bufmgr;
- ttm_buf->name = name;
- ttm_buf->refcount = 1;
- ttm_buf->owner = GL_TRUE;
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
- return &ttm_buf->bo;
-}
-
-/* Our TTM backend doesn't allow creation of static buffers, as that requires
- * privelege for the non-fake case, and the lock in the fake case where we were
- * working around the X Server not creating buffers and passing handles to us.
- */
-static dri_bo *
-dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
- unsigned long offset, unsigned long size, void *virtual,
- unsigned int location_mask)
-{
- return NULL;
-}
-
-/** Returns a dri_bo wrapping the given buffer object handle.
- *
- * This can be used when one application needs to pass a buffer object
- * to another.
- */
-dri_bo *
-dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
- unsigned int handle)
-{
- dri_bufmgr_ttm *ttm_bufmgr;
- dri_bo_ttm *ttm_buf;
- int ret;
-
- ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
-
- ttm_buf = malloc(sizeof(*ttm_buf));
- if (!ttm_buf)
- return NULL;
-
- ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
- if (ret != 0) {
- free(ttm_buf);
- return NULL;
- }
- ttm_buf->bo.size = ttm_buf->drm_bo.size;
- ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
- ttm_buf->bo.virtual = NULL;
- ttm_buf->bo.bufmgr = bufmgr;
- ttm_buf->name = name;
- ttm_buf->refcount = 1;
- ttm_buf->owner = GL_FALSE;
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo,
- ttm_buf->name);
-#endif
-
- return &ttm_buf->bo;
-}
-
-static void
-dri_ttm_bo_reference(dri_bo *buf)
-{
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
- dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
-
- _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
- ttm_buf->refcount++;
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-}
-
-static void
-dri_ttm_bo_unreference(dri_bo *buf)
-{
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
- dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
-
- if (!buf)
- return;
-
- _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
- if (--ttm_buf->refcount == 0) {
- int ret;
-
- /* XXX Having to use drmBODestroy as the opposite of drmBOCreate instead
- * of simply unreferencing is madness, and leads to behaviors we may not
- * want (making the buffer unsharable).
- */
- if (ttm_buf->owner)
- ret = drmBODestroy(bufmgr_ttm->fd, &ttm_buf->drm_bo);
- else
- ret = drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
- if (ret != 0) {
- fprintf(stderr, "drmBOUnReference failed (%s): %s\n", ttm_buf->name,
- strerror(-ret));
- }
-#if BUFMGR_DEBUG
- fprintf(stderr, "bo_unreference final: %p (%s)\n",
- &ttm_buf->bo, ttm_buf->name);
-#endif
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
- free(buf);
- return;
- }
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-}
-
-static int
-dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable)
-{
- dri_bufmgr_ttm *bufmgr_ttm;
- dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
- unsigned int flags;
-
- bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
-
- flags = DRM_BO_FLAG_READ;
- if (write_enable)
- flags |= DRM_BO_FLAG_WRITE;
-
- assert(buf->virtual == NULL);
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
- return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual);
-}
-
-static int
-dri_ttm_bo_unmap(dri_bo *buf)
-{
- dri_bufmgr_ttm *bufmgr_ttm;
- dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
-
- if (buf == NULL)
- return 0;
-
- bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
-
- assert(buf->virtual != NULL);
-
- buf->virtual = NULL;
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
- return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo);
-}
-
-static int
-dri_ttm_validate(dri_bo *buf, unsigned int flags)
-{
- dri_bufmgr_ttm *bufmgr_ttm;
- dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
- unsigned int mask;
- int err;
-
- /* XXX: Sanity-check whether we've already validated this one under
- * different flags. See drmAddValidateItem().
- */
-
- bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
-
- /* Calculate the appropriate mask to pass to the DRM. There appears to be
- * be a direct relationship to flags, so it's unnecessary to have it passed
- * in as an argument.
- */
- mask = DRM_BO_MASK_MEM;
- mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE);
-
- err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, 0, flags, mask, 0);
-
- if (err == 0) {
- /* XXX: add to fence list for sanity checking */
- } else {
- fprintf(stderr, "failed to validate buffer (%s): %s\n",
- ttm_buf->name, strerror(-err));
- }
-
- buf->offset = ttm_buf->drm_bo.offset;
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "bo_validate: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
- return err;
-}
-
-static dri_fence *
-dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name,
- GLboolean flushed)
-{
- dri_fence_ttm *fence_ttm = malloc(sizeof(*fence_ttm));
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
- int ret;
- unsigned int type;
-
- if (!fence_ttm)
- return NULL;
-
- if (flushed)
- type = bufmgr_ttm->fence_type_flush;
- else
- type = bufmgr_ttm->fence_type;
-
- fence_ttm->refcount = 1;
- fence_ttm->name = name;
- fence_ttm->fence.bufmgr = bufmgr;
- ret = drmFenceBuffers(bufmgr_ttm->fd, type, 0, &fence_ttm->drm_fence);
- if (ret) {
- fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret));
- free(fence_ttm);
- return NULL;
- }
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "fence_validated: %p (%s)\n", &fence_ttm->fence,
- fence_ttm->name);
-#endif
-
- return &fence_ttm->fence;
-}
-
-static void
-dri_ttm_fence_reference(dri_fence *fence)
-{
- dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
-
- _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
- ++fence_ttm->refcount;
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-}
-
-static void
-dri_ttm_fence_unreference(dri_fence *fence)
-{
- dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
-
- if (!fence)
- return;
-
- _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
- if (--fence_ttm->refcount == 0) {
- int ret;
-
- /* XXX Having to use drmFenceDestroy as the opposite of drmFenceBuffers
- * instead of simply unreferencing is madness, and leads to behaviors we
- * may not want (making the fence unsharable). This behavior by the DRM
- * ioctls should be fixed, and drmFenceDestroy eliminated.
- */
- ret = drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence);
- if (ret != 0) {
- fprintf(stderr, "drmFenceDestroy failed (%s): %s\n",
- fence_ttm->name, strerror(-ret));
- }
-
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
- free(fence);
- return;
- }
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-}
-
-static void
-dri_ttm_fence_wait(dri_fence *fence)
-{
- dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
- int ret;
-
- _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
- ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0);
- _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
- if (ret != 0) {
- _mesa_printf("%s:%d: Error %d waiting for fence %s.\n",
- __FILE__, __LINE__, ret, fence_ttm->name);
- abort();
- }
-
-#if BUFMGR_DEBUG
- fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence,
- fence_ttm->name);
-#endif
-}
-
-static void
-dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
-{
- dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
-
- _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
- free(bufmgr);
-}
-
-/**
- * Initializes the TTM buffer manager, which uses the kernel to allocate, map,
- * and manage map buffer objections.
- *
- * \param fd File descriptor of the opened DRM device.
- * \param fence_type Driver-specific fence type used for fences with no flush.
- * \param fence_type_flush Driver-specific fence type used for fences with a
- * flush.
- */
-dri_bufmgr *
-dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
- unsigned int fence_type_flush)
-{
- dri_bufmgr_ttm *bufmgr_ttm;
-
- bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
- bufmgr_ttm->fd = fd;
- bufmgr_ttm->fence_type = fence_type;
- bufmgr_ttm->fence_type_flush = fence_type_flush;
- _glthread_INIT_MUTEX(bufmgr_ttm->mutex);
-
- bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc;
- bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static;
- bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference;
- bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference;
- bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map;
- bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap;
- bufmgr_ttm->bufmgr.bo_validate = dri_ttm_validate;
- bufmgr_ttm->bufmgr.fence_validated = dri_ttm_fence_validated;
- bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference;
- bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference;
- bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
- bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
-
- return &bufmgr_ttm->bufmgr;
-}
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index c30e66f172..2e2e64c4d1 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -33,7 +33,7 @@
#include "drm_sarea.h"
#ifndef GLX_OML_sync_control
-typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator);
+typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
#endif
/* This pointer *must* be set by the driver's __driCreateNewScreen funciton!
@@ -47,22 +47,26 @@ static const int empty_attribute_list[1] = { None };
/**
+ * This is just a token extension used to signal that the driver
+ * supports setting a read drawable.
+ */
+const __DRIextension driReadDrawableExtension = {
+ __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
+};
+
+/**
* Cached copy of the internal API version used by libGL and the client-side
* DRI driver.
*/
static int api_ver = 0;
-/* forward declarations */
-static int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv,
- int64_t *sbc, int64_t *missedFrames,
- float *lastMissedUsage, float *usage );
-
-static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
- const __GLcontextModes *modes,
- __DRIid draw, __DRIdrawable *pdraw,
+static void *driCreateNewDrawable(__DRIscreen *screen,
+ const __GLcontextModes *modes,
+ __DRIdrawable *pdraw,
+ drm_drawable_t hwDrawable,
int renderType, const int *attrs);
-static void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate);
+static void driDestroyDrawable(__DRIdrawable *drawable);
/**
@@ -89,63 +93,6 @@ __driUtilMessage(const char *f, ...)
/*****************************************************************/
-/** \name Drawable list management */
-/*****************************************************************/
-/*@{*/
-
-static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
-{
- __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
-
- if (drmHashInsert(drawHash, pdp->draw, pdraw))
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw)
-{
- int retcode;
- __DRIdrawable *pdraw;
-
- retcode = drmHashLookup(drawHash, draw, (void *)&pdraw);
- if (retcode)
- return NULL;
-
- return pdraw;
-}
-
-
-/**
- * Find drawables in the local hash that have been destroyed on the
- * server.
- *
- * \param drawHash Hash-table containing all know drawables.
- */
-static void __driGarbageCollectDrawables(void *drawHash)
-{
- __DRIid draw;
- __DRInativeDisplay *dpy;
- __DRIdrawable *pdraw;
-
- if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) {
- do {
- __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
- dpy = pdp->driScreenPriv->display;
- if (! (*dri_interface->windowExists)(dpy, draw)) {
- /* Destroy the local drawable data, if the drawable no
- longer exists in the Xserver */
- (*pdraw->destroyDrawable)(dpy, pdraw->private);
- _mesa_free(pdraw);
- }
- } while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1);
- }
-}
-
-/*@}*/
-
-
-/*****************************************************************/
/** \name Context (un)binding functions */
/*****************************************************************/
/*@{*/
@@ -153,10 +100,7 @@ static void __driGarbageCollectDrawables(void *drawHash)
/**
* Unbind context.
*
- * \param dpy the display handle.
- * \param scrn the screen number.
- * \param draw drawable.
- * \param read Current reading drawable.
+ * \param scrn the screen.
* \param gc context.
*
* \return \c GL_TRUE on success, or \c GL_FALSE on failure.
@@ -169,13 +113,8 @@ static void __driGarbageCollectDrawables(void *drawHash)
* While casting the opaque private pointers associated with the parameters
* into their respective real types it also assures they are not \c NULL.
*/
-static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
- __DRIid draw, __DRIid read,
- __DRIcontext *ctx)
+static GLboolean driUnbindContext(__DRIcontext *ctx)
{
- __DRIscreen *pDRIScreen;
- __DRIdrawable *pdraw;
- __DRIdrawable *pread;
__DRIcontextPrivate *pcp;
__DRIscreenPrivate *psp;
__DRIdrawablePrivate *pdp;
@@ -186,39 +125,17 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
** calling driUnbindContext.
*/
- if (ctx == NULL || draw == None || read == None) {
- /* ERROR!!! */
- return GL_FALSE;
- }
-
- pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
- if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
- /* ERROR!!! */
- return GL_FALSE;
- }
+ if (ctx == NULL)
+ return GL_FALSE;
- psp = (__DRIscreenPrivate *)pDRIScreen->private;
pcp = (__DRIcontextPrivate *)ctx->private;
-
- pdraw = __driFindDrawable(psp->drawHash, draw);
- if (!pdraw) {
- /* ERROR!!! */
- return GL_FALSE;
- }
- pdp = (__DRIdrawablePrivate *)pdraw->private;
-
- pread = __driFindDrawable(psp->drawHash, read);
- if (!pread) {
- /* ERROR!!! */
- return GL_FALSE;
- }
- prp = (__DRIdrawablePrivate *)pread->private;
-
+ psp = (__DRIscreenPrivate *)pcp->driScreenPriv;
+ pdp = (__DRIdrawablePrivate *)pcp->driDrawablePriv;
+ prp = (__DRIdrawablePrivate *)pcp->driReadablePriv;
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(pcp);
-
if (pdp->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
@@ -254,72 +171,18 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
* This function takes both a read buffer and a draw buffer. This is needed
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
* function.
- *
- * \bug This function calls \c driCreateNewDrawable in two places with the
- * \c renderType hard-coded to \c GLX_WINDOW_BIT. Some checking might
- * be needed in those places when support for pbuffers and / or pixmaps
- * is added. Is it safe to assume that the drawable is a window?
*/
-static GLboolean DoBindContext(__DRInativeDisplay *dpy,
- __DRIid draw, __DRIid read,
- __DRIcontext *ctx, const __GLcontextModes * modes,
- __DRIscreenPrivate *psp)
+static GLboolean DoBindContext(__DRIcontext *ctx,
+ __DRIdrawable *pdraw,
+ __DRIdrawable *pread)
{
- __DRIdrawable *pdraw;
__DRIdrawablePrivate *pdp;
- __DRIdrawable *pread;
__DRIdrawablePrivate *prp;
__DRIcontextPrivate * const pcp = ctx->private;
+ __DRIscreenPrivate *psp = pcp->driScreenPriv;
-
- /* Find the _DRIdrawable which corresponds to the writing drawable. */
- pdraw = __driFindDrawable(psp->drawHash, draw);
- if (!pdraw) {
- /* Allocate a new drawable */
- pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
- if (!pdraw) {
- /* ERROR!!! */
- return GL_FALSE;
- }
-
- /* Create a new drawable */
- driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT,
- empty_attribute_list);
- if (!pdraw->private) {
- /* ERROR!!! */
- _mesa_free(pdraw);
- return GL_FALSE;
- }
-
- }
pdp = (__DRIdrawablePrivate *) pdraw->private;
-
- /* Find the _DRIdrawable which corresponds to the reading drawable. */
- if (read == draw) {
- /* read buffer == draw buffer */
- prp = pdp;
- }
- else {
- pread = __driFindDrawable(psp->drawHash, read);
- if (!pread) {
- /* Allocate a new drawable */
- pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
- if (!pread) {
- /* ERROR!!! */
- return GL_FALSE;
- }
-
- /* Create a new drawable */
- driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT,
- empty_attribute_list);
- if (!pread->private) {
- /* ERROR!!! */
- _mesa_free(pread);
- return GL_FALSE;
- }
- }
- prp = (__DRIdrawablePrivate *) pread->private;
- }
+ prp = (__DRIdrawablePrivate *) pread->private;
/* Bind the drawable to the context */
pcp->driDrawablePriv = pdp;
@@ -358,30 +221,19 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy,
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
* function.
*/
-static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
- __DRIid draw, __DRIid read,
- __DRIcontext * ctx)
+static GLboolean driBindContext(__DRIcontext * ctx,
+ __DRIdrawable *pdraw,
+ __DRIdrawable *pread)
{
- __DRIscreen *pDRIScreen;
-
/*
** Assume error checking is done properly in glXMakeCurrent before
** calling driBindContext.
*/
- if (ctx == NULL || draw == None || read == None) {
- /* ERROR!!! */
+ if (ctx == NULL || pdraw == None || pread == None)
return GL_FALSE;
- }
- pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
- if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
- /* ERROR!!! */
- return GL_FALSE;
- }
-
- return DoBindContext( dpy, draw, read, ctx, ctx->mode,
- (__DRIscreenPrivate *)pDRIScreen->private );
+ return DoBindContext( ctx, pdraw, pread );
}
/*@}*/
@@ -438,8 +290,7 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
- ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
+ if (! (*dri_interface->getDrawableInfo)(pdp->pdraw,
&pdp->index, &pdp->lastStamp,
&pdp->x, &pdp->y, &pdp->w, &pdp->h,
&pdp->numClipRects, &pdp->pClipRects,
@@ -473,7 +324,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
/**
* Swap buffers.
*
- * \param dpy the display handle.
* \param drawablePrivate opaque pointer to the per-drawable private info.
*
* \internal
@@ -481,9 +331,9 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
*
* Is called directly from glXSwapBuffers().
*/
-static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
+static void driSwapBuffers(__DRIdrawable *drawable)
{
- __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ __DRIdrawablePrivate *dPriv = drawable->private;
drm_clip_rect_t rect;
dPriv->swapBuffers(dPriv);
@@ -502,53 +352,33 @@ static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
* front buffer, so we report the damage there rather than to the backing
* store (if any).
*/
- (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw,
- dPriv->x, dPriv->y,
+ (*dri_interface->reportDamage)(dPriv->pdraw, dPriv->x, dPriv->y,
&rect, 1, GL_TRUE);
}
-/**
- * Called directly from a number of higher-level GLX functions.
- */
-static int driGetMSC( void *screenPrivate, int64_t *msc )
+static int driDrawableGetMSC( __DRIscreen *screen, void *drawablePrivate,
+ int64_t *msc )
{
- __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate;
+ __DRIscreenPrivate *sPriv = screen->private;
- return sPriv->DriverAPI.GetMSC( sPriv, msc );
+ return sPriv->DriverAPI.GetDrawableMSC( sPriv, drawablePrivate, msc );
}
/**
* Called directly from a number of higher-level GLX functions.
*/
-static int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc )
-{
- __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
- __DRIswapInfo sInfo;
- int status;
-
-
- status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
- *sbc = sInfo.swap_count;
-
- return status;
-}
-
-static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv,
- int64_t target_sbc,
- int64_t * msc, int64_t * sbc )
+static int driGetMSC( __DRIscreen *screen, void *drawablePrivate, int64_t *msc )
{
- __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
+ __DRIscreenPrivate *sPriv = screen->private;
- return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc,
- msc, sbc );
+ return sPriv->DriverAPI.GetMSC( sPriv, msc );
}
-static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
- int64_t target_msc,
- int64_t divisor, int64_t remainder,
- int64_t * msc, int64_t * sbc )
+static int driWaitForMSC(__DRIdrawable *drawable, int64_t target_msc,
+ int64_t divisor, int64_t remainder,
+ int64_t * msc, int64_t * sbc)
{
- __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
+ __DRIdrawablePrivate *dPriv = drawable->private;
__DRIswapInfo sInfo;
int status;
@@ -570,36 +400,56 @@ static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
return status;
}
-static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv,
- int64_t target_msc,
- int64_t divisor, int64_t remainder )
+const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
+ { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
+ driGetMSC,
+ driWaitForMSC,
+ driDrawableGetMSC,
+};
+
+static void driCopySubBuffer(__DRIdrawable *drawable,
+ int x, int y, int w, int h)
{
- __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
+ __DRIdrawablePrivate *dPriv = drawable->private;
+ dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
+}
+
+const __DRIcopySubBufferExtension driCopySubBufferExtension = {
+ { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
+ driCopySubBuffer
+};
- return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc,
- divisor,
- remainder );
+static void driSetSwapInterval(__DRIdrawable *drawable, unsigned int interval)
+{
+ __DRIdrawablePrivate *dpriv = drawable->private;
+
+ dpriv->swap_interval = interval;
}
-static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate,
- int x, int y, int w, int h)
+static unsigned int driGetSwapInterval(__DRIdrawable *drawable)
{
- __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
- dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
- (void) dpy;
+ __DRIdrawablePrivate *dpriv = drawable->private;
+
+ return dpriv->swap_interval;
}
+const __DRIswapControlExtension driSwapControlExtension = {
+ { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
+ driSetSwapInterval,
+ driGetSwapInterval
+};
+
+
/**
* This is called via __DRIscreenRec's createNewDrawable pointer.
*/
-static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
+static void *driCreateNewDrawable(__DRIscreen *screen,
const __GLcontextModes *modes,
- __DRIid draw,
__DRIdrawable *pdraw,
+ drm_drawable_t hwDrawable,
int renderType,
const int *attrs)
{
- __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
__DRIscreenPrivate *psp;
__DRIdrawablePrivate *pdp;
@@ -611,21 +461,12 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
*/
(void) attrs;
- if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
- return NULL;
- }
-
pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate));
if (!pdp) {
return NULL;
}
- if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) {
- _mesa_free(pdp);
- return NULL;
- }
-
- pdp->draw = draw;
+ pdp->hHWDrawable = hwDrawable;
pdp->pdraw = pdraw;
pdp->refcount = 0;
pdp->pStamp = NULL;
@@ -639,16 +480,15 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
pdp->numBackClipRects = 0;
pdp->pClipRects = NULL;
pdp->pBackClipRects = NULL;
- pdp->display = dpy;
- pdp->screen = modes->screen;
+ pdp->vblSeq = 0;
+ pdp->vblFlags = 0;
- psp = (__DRIscreenPrivate *)pDRIScreen->private;
+ psp = (__DRIscreenPrivate *)screen->private;
pdp->driScreenPriv = psp;
pdp->driContextPriv = &psp->dummyContextPriv;
if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes,
renderType == GLX_PIXMAP_BIT)) {
- (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw);
_mesa_free(pdp);
return NULL;
}
@@ -656,63 +496,28 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
pdraw->private = pdp;
pdraw->destroyDrawable = driDestroyDrawable;
pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */
-
- pdraw->getSBC = driGetSBC;
- pdraw->waitForSBC = driWaitForSBC;
- pdraw->waitForMSC = driWaitForMSC;
- pdraw->swapBuffersMSC = driSwapBuffersMSC;
- pdraw->frameTracking = NULL;
- pdraw->queryFrameTracking = driQueryFrameTracking;
-
- if (driCompareGLXAPIVersion (20060314) >= 0)
- pdraw->copySubBuffer = driCopySubBuffer;
+ pdp->msc_base = 0;
/* This special default value is replaced with the configured
* default value when the drawable is first bound to a direct
* rendering context.
*/
- pdraw->swap_interval = (unsigned)-1;
+ pdp->swap_interval = (unsigned)-1;
pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
- /* Add pdraw to drawable list */
- if (!__driAddDrawable(psp->drawHash, pdraw)) {
- /* ERROR!!! */
- (*pdraw->destroyDrawable)(dpy, pdp);
- _mesa_free(pdp);
- pdp = NULL;
- pdraw->private = NULL;
- }
-
return (void *) pdp;
}
-static __DRIdrawable *
-driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate)
-{
- __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
-
- /*
- ** Make sure this routine returns NULL if the drawable is not bound
- ** to a direct rendering context!
- */
- return __driFindDrawable(psp->drawHash, draw);
-}
-
static void
-driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
+driDestroyDrawable(__DRIdrawable *drawable)
{
- __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate;
+ __DRIdrawablePrivate *pdp = drawable->private;
__DRIscreenPrivate *psp;
- int scrn;
if (pdp) {
psp = pdp->driScreenPriv;
- scrn = psp->myNum;
(*psp->DriverAPI.DestroyBuffer)(pdp);
- if ((*dri_interface->windowExists)(dpy, pdp->draw))
- (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
- drmHashDelete(psp->drawHash, pdp->draw);
if (pdp->pClipRects) {
_mesa_free(pdp->pClipRects);
pdp->pClipRects = NULL;
@@ -736,8 +541,6 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
/**
* Destroy the per-context private information.
*
- * \param dpy the display handle.
- * \param scrn the screen number.
* \param contextPrivate opaque pointer to the per-drawable private info.
*
* \internal
@@ -745,14 +548,12 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
* drmDestroyContext(), and finally frees \p contextPrivate.
*/
static void
-driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
+driDestroyContext(__DRIcontext *context)
{
- __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate;
+ __DRIcontextPrivate *pcp = context->private;
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
- __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
- (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID);
_mesa_free(pcp);
}
}
@@ -765,7 +566,7 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
* \param modes Mode used to create the new context.
* \param render_type Type of rendering target. \c GLX_RGBA is the only
* type likely to ever be supported for direct-rendering.
- * \param sharedPrivate The shared context dependent methods or \c NULL if
+ * \param shared The shared context dependent methods or \c NULL if
* non-existent.
* \param pctx DRI context to receive the context dependent methods.
*
@@ -780,35 +581,23 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
*
*/
static void *
-driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
- int render_type, void *sharedPrivate, __DRIcontext *pctx)
+driCreateNewContext(__DRIscreen *screen, const __GLcontextModes *modes,
+ int render_type, __DRIcontext *shared,
+ drm_context_t hwContext, __DRIcontext *pctx)
{
- __DRIscreen *pDRIScreen;
__DRIcontextPrivate *pcp;
- __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate;
+ __DRIcontextPrivate *pshare = (shared != NULL) ? shared->private : NULL;
__DRIscreenPrivate *psp;
void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL;
- pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
- if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
- /* ERROR!!! */
- return NULL;
- }
-
- psp = (__DRIscreenPrivate *)pDRIScreen->private;
+ psp = (__DRIscreenPrivate *)screen->private;
pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate));
if (!pcp) {
return NULL;
}
- if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID,
- &pcp->contextID, &pcp->hHWContext)) {
- _mesa_free(pcp);
- return NULL;
- }
-
- pcp->display = dpy;
+ pcp->hHWContext = hwContext;
pcp->driScreenPriv = psp;
pcp->driDrawablePriv = NULL;
@@ -817,7 +606,6 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
*/
if (!psp->dummyContextPriv.driScreenPriv) {
- psp->dummyContextPriv.contextID = 0;
psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
psp->dummyContextPriv.driScreenPriv = psp;
psp->dummyContextPriv.driDrawablePriv = NULL;
@@ -830,19 +618,23 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
pctx->unbindContext = driUnbindContext;
if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) {
- (void) (*dri_interface->destroyContext)(dpy, modes->screen,
- pcp->contextID);
_mesa_free(pcp);
return NULL;
}
- __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
-
return pcp;
}
/*@}*/
+static const __DRIextension **
+driGetExtensions(__DRIscreen *screen)
+{
+ __DRIscreenPrivate *psp = screen->private;
+
+ return psp->extensions;
+}
+
/*****************************************************************/
/** \name Screen handling functions */
/*****************************************************************/
@@ -859,9 +651,9 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
* This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
* drmClose(), and finally frees \p screenPrivate.
*/
-static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate)
+static void driDestroyScreen(__DRIscreen *screen)
{
- __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
+ __DRIscreenPrivate *psp = screen->private;
if (psp) {
/* No interaction with the X-server is possible at this point. This
@@ -874,14 +666,7 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
- _mesa_free(psp->pDevPriv);
(void)drmCloseOnce(psp->fd);
- if ( psp->modes != NULL ) {
- (*dri_interface->destroyContextModes)( psp->modes );
- }
-
- assert(psp->drawHash);
- drmHashDestroy(psp->drawHash);
_mesa_free(psp);
}
@@ -889,9 +674,12 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
/**
- * Utility function used to create a new driver-private screen structure.
+ * This is the bootstrap function for the driver. libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
*
- * \param dpy Display pointer
* \param scrn Index of the screen
* \param psc DRI screen data (not driver private)
* \param modes Linked list of known display modes. This list is, at a
@@ -912,44 +700,32 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
* driver and libGL.
* \param driverAPI Driver API functions used by other routines in dri_util.c.
*
- * \note
- * There is no need to check the minimum API version in this function. Since
- * the \c __driCreateNewScreen function is versioned, it is impossible for a
- * loader that is too old to even load this driver.
+ * \note There is no need to check the minimum API version in this
+ * function. Since the name of this function is versioned, it is
+ * impossible for a loader that is too old to even load this driver.
*/
-__DRIscreenPrivate *
-__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drm_sarea_t *pSAREA,
- int fd,
- int internal_api_version,
- const struct __DriverAPIRec *driverAPI)
+PUBLIC
+void * __DRI_CREATE_NEW_SCREEN( int scrn, __DRIscreen *psc,
+ const __DRIversion * ddx_version,
+ const __DRIversion * dri_version,
+ const __DRIversion * drm_version,
+ const __DRIframebuffer * frame_buffer,
+ drmAddress pSAREA, int fd,
+ int internal_api_version,
+ const __DRIinterfaceMethods * interface,
+ __GLcontextModes ** driver_modes )
+
{
__DRIscreenPrivate *psp;
-
-
+ static const __DRIextension *emptyExtensionList[] = { NULL };
+ dri_interface = interface;
api_ver = internal_api_version;
- psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate));
- if (!psp) {
+ psp = _mesa_malloc(sizeof(*psp));
+ if (!psp)
return NULL;
- }
- /* Create the hash table */
- psp->drawHash = drmHashCreate();
- if ( psp->drawHash == NULL ) {
- _mesa_free( psp );
- return NULL;
- }
-
- psp->display = dpy;
- psp->myNum = scrn;
psp->psc = psc;
- psp->modes = modes;
/*
** NOT_DONE: This is used by the X server to detect when the client
@@ -958,18 +734,9 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
*/
psp->drawLockID = 1;
- psp->drmMajor = drm_version->major;
- psp->drmMinor = drm_version->minor;
- psp->drmPatch = drm_version->patch;
- psp->ddxMajor = ddx_version->major;
- psp->ddxMinor = ddx_version->minor;
- psp->ddxPatch = ddx_version->patch;
- psp->driMajor = dri_version->major;
- psp->driMinor = dri_version->minor;
- psp->driPatch = dri_version->patch;
-
- /* install driver's callback functions */
- memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) );
+ psp->drm_version = *drm_version;
+ psp->ddx_version = *ddx_version;
+ psp->dri_version = *dri_version;
psp->pSAREA = pSAREA;
@@ -982,7 +749,9 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
psp->pDevPriv = frame_buffer->dev_priv;
psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
+ psp->extensions = emptyExtensionList;
psp->fd = fd;
+ psp->myNum = scrn;
/*
** Do not init dummy context here; actual initialization will be
@@ -992,25 +761,19 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
psp->dummyContextPriv.driScreenPriv = NULL;
psc->destroyScreen = driDestroyScreen;
+ psc->getExtensions = driGetExtensions;
psc->createNewDrawable = driCreateNewDrawable;
- psc->getDrawable = driGetDrawable;
- psc->getMSC = driGetMSC;
psc->createNewContext = driCreateNewContext;
- if (internal_api_version >= 20070121)
- psc->setTexOffset = psp->DriverAPI.setTexOffset;
-
- if ( (psp->DriverAPI.InitDriver != NULL)
- && !(*psp->DriverAPI.InitDriver)(psp) ) {
- _mesa_free( psp );
+ *driver_modes = __driDriverInitScreen(psp);
+ if (*driver_modes == NULL) {
+ _mesa_free(psp);
return NULL;
}
-
return psp;
}
-
/**
* Compare the current GLX API version with a driver supplied required version.
*
@@ -1039,14 +802,20 @@ int driCompareGLXAPIVersion( GLint required_version )
static int
-driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
- int64_t * sbc, int64_t * missedFrames,
- float * lastMissedUsage, float * usage )
+driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
+{
+ return GLX_BAD_CONTEXT;
+}
+
+static int
+driQueryFrameTracking(__DRIdrawable *drawable,
+ int64_t * sbc, int64_t * missedFrames,
+ float * lastMissedUsage, float * usage)
{
__DRIswapInfo sInfo;
int status;
int64_t ust;
- __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv;
+ __DRIdrawablePrivate * dpriv = drawable->private;
status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
@@ -1062,6 +831,11 @@ driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
return status;
}
+const __DRIframeTrackingExtension driFrameTrackingExtension = {
+ { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
+ driFrameTracking,
+ driQueryFrameTracking
+};
/**
* Calculate amount of swap interval used between GLX buffer swaps.
@@ -1101,9 +875,8 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
float usage = 1.0;
- if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) {
- interval = (dPriv->pdraw->swap_interval != 0)
- ? dPriv->pdraw->swap_interval : 1;
+ if ( (*dri_interface->getMSCRate)(dPriv->pdraw, &n, &d) ) {
+ interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
/* We want to calculate
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 539d28d114..def0775839 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -67,6 +67,22 @@ typedef struct __DRIutilversionRec2 __DRIutilversion2;
/**
+ * Driver specific entry point. Implemented by the driver. Called
+ * from the top level createNewScreen entry point to initialize the
+ * __DRIscreenPrivate struct.
+ */
+extern __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp);
+
+/**
+ * Extensions.
+ */
+extern const __DRIextension driReadDrawableExtension;
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
+extern const __DRIswapControlExtension driSwapControlExtension;
+extern const __DRIframeTrackingExtension driFrameTrackingExtension;
+extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
+
+/**
* Used by DRI_VALIDATE_DRAWABLE_INFO
*/
#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \
@@ -109,11 +125,6 @@ do { \
* this structure.
*/
struct __DriverAPIRec {
- /**
- * Driver initialization callback
- */
- GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv);
-
/**
* Screen destruction callback
*/
@@ -195,6 +206,14 @@ struct __DriverAPIRec {
*/
void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
unsigned long long offset, GLint depth, GLuint pitch);
+
+ /**
+ * New version of GetMSC so we can pass drawable data to the low level
+ * DRM driver (e.g. pipe info).
+ */
+ int (*GetDrawableMSC) ( __DRIscreenPrivate * priv,
+ __DRIdrawablePrivate *drawablePrivate,
+ int64_t *count);
};
@@ -248,7 +267,6 @@ struct __DRIdrawablePrivateRec {
/**
* X's drawable ID associated with this private drawable.
*/
- __DRIid draw;
__DRIdrawable *pdraw;
/**
@@ -308,6 +326,32 @@ struct __DRIdrawablePrivateRec {
/*@}*/
/**
+ * \name Vertical blank tracking information
+ * Used for waiting on vertical blank events.
+ */
+ /*@{*/
+ unsigned int vblSeq;
+ unsigned int vblFlags;
+ /*@}*/
+
+ /**
+ * \name Monotonic MSC tracking
+ *
+ * Low level driver is responsible for updating msc_base and
+ * vblSeq values so that higher level code can calculate
+ * a new msc value or msc target for a WaitMSC call. The new value
+ * will be:
+ * msc = msc_base + get_vblank_count() - vblank_base;
+ *
+ * And for waiting on a value, core code will use:
+ * actual_target = target_msc - msc_base + vblank_base;
+ */
+ /*@{*/
+ int64_t vblank_base;
+ int64_t msc_base;
+ /*@}*/
+
+ /**
* Pointer to context to which this drawable is currently bound.
*/
__DRIcontextPrivate *driContextPriv;
@@ -318,20 +362,15 @@ struct __DRIdrawablePrivateRec {
__DRIscreenPrivate *driScreenPriv;
/**
- * \name Display and screen information.
- *
- * Basically just need these for when the locking code needs to call
- * \c __driUtilUpdateDrawableInfo.
+ * Called via glXSwapBuffers().
*/
- /*@{*/
- __DRInativeDisplay *display;
- int screen;
- /*@}*/
+ void (*swapBuffers)( __DRIdrawablePrivate *dPriv );
/**
- * Called via glXSwapBuffers().
+ * Controls swap interval as used by GLX_SGI_swap_control and
+ * GLX_MESA_swap_control.
*/
- void (*swapBuffers)( __DRIdrawablePrivate *dPriv );
+ unsigned int swap_interval;
};
/**
@@ -341,11 +380,6 @@ struct __DRIcontextPrivateRec {
/**
* Kernel context handle used to access the device lock.
*/
- __DRIid contextID;
-
- /**
- * Kernel context handle used to access the device lock.
- */
drm_context_t hHWContext;
/**
@@ -354,9 +388,9 @@ struct __DRIcontextPrivateRec {
void *driverPrivate;
/**
- * This context's display pointer.
+ * Pointer back to the \c __DRIcontext that contains this structure.
*/
- __DRInativeDisplay *display;
+ __DRIcontext *pctx;
/**
* Pointer to drawable currently bound to this context for drawing.
@@ -379,11 +413,6 @@ struct __DRIcontextPrivateRec {
*/
struct __DRIscreenPrivateRec {
/**
- * Display for this screen
- */
- __DRInativeDisplay *display;
-
- /**
* Current screen's number
*/
int myNum;
@@ -394,37 +423,19 @@ struct __DRIscreenPrivateRec {
struct __DriverAPIRec DriverAPI;
/**
- * \name DDX version
* DDX / 2D driver version information.
- * \todo Replace these fields with a \c __DRIversionRec.
*/
- /*@{*/
- int ddxMajor;
- int ddxMinor;
- int ddxPatch;
- /*@}*/
+ __DRIversion ddx_version;
/**
- * \name DRI version
* DRI X extension version information.
- * \todo Replace these fields with a \c __DRIversionRec.
*/
- /*@{*/
- int driMajor;
- int driMinor;
- int driPatch;
- /*@}*/
+ __DRIversion dri_version;
/**
- * \name DRM version
* DRM (kernel module) version information.
- * \todo Replace these fields with a \c __DRIversionRec.
*/
- /*@{*/
- int drmMajor;
- int drmMinor;
- int drmPatch;
- /*@}*/
+ __DRIversion drm_version;
/**
* ID used when the client sets the drawable lock.
@@ -490,11 +501,6 @@ struct __DRIscreenPrivateRec {
__DRIcontextPrivate dummyContextPriv;
/**
- * Hash table to hold the drawable information for this screen.
- */
- void *drawHash;
-
- /**
* Device-dependent private information (not stored in the SAREA).
*
* This pointer is never touched by the DRI layer.
@@ -502,21 +508,14 @@ struct __DRIscreenPrivateRec {
void *private;
/**
- * GLX visuals / FBConfigs for this screen. These are stored as a
- * linked list.
- *
- * \note
- * This field is \b only used in conjunction with the old interfaces. If
- * the new interfaces are used, this field will be set to \c NULL and will
- * not be dereferenced.
+ * Pointer back to the \c __DRIscreen that contains this structure.
*/
- __GLcontextModes *modes;
+ __DRIscreen *psc;
/**
- * Pointer back to the \c __DRIscreen that contains this structure.
+ * Extensions provided by this driver.
*/
-
- __DRIscreen *psc;
+ const __DRIextension **extensions;
};
@@ -540,8 +539,8 @@ extern void
__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp);
-extern __DRIscreenPrivate * __driUtilCreateNewScreen( __DRInativeDisplay *dpy,
- int scrn, __DRIscreen *psc, __GLcontextModes * modes,
+extern __DRIscreenPrivate * __driUtilCreateNewScreen( int scr, __DRIscreen *psc,
+ __GLcontextModes * modes,
const __DRIversion * ddx_version, const __DRIversion * dri_version,
const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
drm_sarea_t *pSAREA, int fd, int internal_api_version,
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index bf103a3931..065c5d8dae 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -1105,10 +1105,11 @@ static const char IsRenderbufferEXT_names[] =
"";
#endif
-#if defined(need_GL_VERSION_2_0)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ATI_separate_stencil)
static const char StencilOpSeparate_names[] =
"iiii\0" /* Parameter signature */
"glStencilOpSeparate\0"
+ "glStencilOpSeparateATI\0"
"";
#endif
@@ -4179,6 +4180,13 @@ static const char ActiveStencilFaceEXT_names[] =
"";
#endif
+#if defined(need_GL_ATI_separate_stencil)
+static const char StencilFuncSeparateATI_names[] =
+ "iiii\0" /* Parameter signature */
+ "glStencilFuncSeparateATI\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetShaderSourceARB_names[] =
"iipp\0" /* Parameter signature */
@@ -5182,6 +5190,14 @@ static const struct dri_extension_function GL_ATI_fragment_shader_functions[] =
};
#endif
+#if defined(need_GL_ATI_separate_stencil)
+static const struct dri_extension_function GL_ATI_separate_stencil_functions[] = {
+ { StencilOpSeparate_names, StencilOpSeparate_remap_index, -1 },
+ { StencilFuncSeparateATI_names, StencilFuncSeparateATI_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_EXT_blend_color)
static const struct dri_extension_function GL_EXT_blend_color_functions[] = {
{ BlendColor_names, -1, 336 },
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index e7ed545f13..8f8d94853e 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -35,6 +35,16 @@
#include "vblank.h"
#include "xmlpool.h"
+static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
+{
+ return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
+}
+
+static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
+{
+ return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
+}
+
/****************************************************************************/
/**
@@ -42,7 +52,7 @@
*
* Stores the 64-bit count of vertical refreshes since some (arbitrary)
* point in time in \c count. Unless the value wraps around, which it
- * may, it will never decrease.
+ * may, it will never decrease for a given drawable.
*
* \warning This function is called from \c glXGetVideoSyncSGI, which expects
* a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which
@@ -50,11 +60,14 @@
* currently always returns a \c sequence of type \c unsigned.
*
* \param priv Pointer to the DRI screen private struct.
+ * \param dPriv Pointer to the DRI drawable private struct
* \param count Storage to hold MSC counter.
* \return Zero is returned on success. A negative errno value
* is returned on failure.
*/
-int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+ __DRIdrawablePrivate * dPriv,
+ int64_t * count)
{
drmVBlank vbl;
int ret;
@@ -63,13 +76,46 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
vbl.request.type = DRM_VBLANK_RELATIVE;
vbl.request.sequence = 0;
+ if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY )
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
ret = drmWaitVBlank( priv->fd, &vbl );
- *count = (int64_t)vbl.reply.sequence;
+
+ if (dPriv) {
+ *count = vblank_to_msc(dPriv, vbl.reply.sequence);
+ } else {
+ /* Old driver (no knowledge of drawable MSC callback) */
+ *count = vbl.reply.sequence;
+ }
return ret;
}
+/**
+ * Get the current MSC refresh counter.
+ *
+ * Stores the 64-bit count of vertical refreshes since some (arbitrary)
+ * point in time in \c count. Unless the value wraps around, which it
+ * may, it will never decrease.
+ *
+ * \warning This function is called from \c glXGetVideoSyncSGI, which expects
+ * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which
+ * expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl
+ * currently always returns a \c sequence of type \c unsigned.
+ *
+ * Since this function doesn't take a drawable, it may end up getting the MSC
+ * value from a pipe not associated with the caller's context, resuling in
+ * undesired behavior.
+ *
+ * \param priv Pointer to the DRI screen private struct.
+ * \param count Storage to hold MSC counter.
+ * \return Zero is returned on success. A negative errno value
+ * is returned on failure.
+ */
+int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+{
+ return driDrawableGetMSC32(priv, NULL, count);
+}
/****************************************************************************/
/**
@@ -123,7 +169,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
*/
vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
DRM_VBLANK_ABSOLUTE;
- vbl.request.sequence = next;
+ vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0;
+ if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
/* FIXME: This doesn't seem like the right thing to return here.
@@ -131,8 +179,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
return GLX_BAD_CONTEXT;
}
+ *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
dont_wait = 0;
- if (target_msc != 0 && vbl.reply.sequence == target)
+ if (target_msc != 0 && *msc == target)
break;
/* Assuming the wait-done test fails, the next refresh to wait for
@@ -142,9 +192,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
* If this refresh has already happened, we add divisor to obtain
* the next refresh after the current one that will satisfy it.
*/
- r = (vbl.reply.sequence % (unsigned int)divisor);
- next = (vbl.reply.sequence - r + (unsigned int)remainder);
- if (next <= vbl.reply.sequence) next += (unsigned int)divisor;
+ r = (*msc % (unsigned int)divisor);
+ next = (*msc - r + (unsigned int)remainder);
+ if (next <= *msc) next += (unsigned int)divisor;
} while ( r != (unsigned int)remainder );
}
@@ -154,7 +204,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
*/
vbl.request.type = DRM_VBLANK_ABSOLUTE;
- vbl.request.sequence = target_msc;
+ vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0;
+
+ if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
/* FIXME: This doesn't seem like the right thing to return here.
@@ -163,8 +216,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
}
}
- *msc = (target_msc & 0xffffffff00000000LL);
- *msc |= vbl.reply.sequence;
+ *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
if ( *msc < target_msc ) {
*msc += 0x0000000100000000LL;
}
@@ -248,20 +301,42 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
/****************************************************************************/
/**
+ * Returns the default swap interval of the given drawable.
+ */
+
+static unsigned
+driGetDefaultVBlankInterval( const __DRIdrawablePrivate *priv )
+{
+ if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+/****************************************************************************/
+/**
* Sets the default swap interval when the drawable is first bound to a
* direct rendering context.
*/
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
- GLuint *vbl_seq )
+void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
{
- if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
+ if ( priv->swap_interval == (unsigned)-1 &&
+ !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) {
/* Get current vertical blank sequence */
- drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
- do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
-
- priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
- VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
+ drmVBlank vbl;
+
+ vbl.request.type = DRM_VBLANK_RELATIVE;
+ if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+ vbl.request.sequence = 0;
+ do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
+ priv->vblank_base = priv->vblSeq;
+
+ priv->swap_interval = driGetDefaultVBlankInterval( priv );
}
}
@@ -272,21 +347,17 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
*/
unsigned
-driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags )
+driGetVBlankInterval( const __DRIdrawablePrivate *priv )
{
- if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
+ if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) {
/* this must have been initialized when the drawable was first bound
* to a direct rendering context. */
- assert ( priv->pdraw->swap_interval != (unsigned)-1 );
+ assert ( priv->swap_interval != (unsigned)-1 );
- return priv->pdraw->swap_interval;
- }
- else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
- return 1;
- }
- else {
- return 0;
+ return priv->swap_interval;
}
+ else
+ return driGetDefaultVBlankInterval( priv );
}
@@ -296,18 +367,17 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags )
*/
void
-driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
- GLuint *vbl_seq )
+driGetCurrentVBlank( __DRIdrawablePrivate *priv )
{
drmVBlank vbl;
vbl.request.type = DRM_VBLANK_RELATIVE;
- if ( flags & VBLANK_FLAG_SECONDARY ) {
+ if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = 0;
- (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
+ (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
}
@@ -315,19 +385,15 @@ driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
/**
* Waits for the vertical blank for use with glXSwapBuffers.
*
- * \param vbl_seq Vertical blank sequence number (MSC) after the last buffer
- * swap. Updated after this wait.
- * \param flags \c VBLANK_FLAG bits that control how long to wait.
* \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later
- * than the "target" based on \c flags. The idea is that if
- * \c missed_deadline is set, then the application is not
- * achieving its desired framerate.
+ * than the "target" based on \c priv->vblFlags. The idea is
+ * that if \c missed_deadline is set, then the application is
+ * not achieving its desired framerate.
* \return Zero on success, -1 on error.
*/
int
-driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
- GLuint flags, GLboolean * missed_deadline )
+driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
{
drmVBlank vbl;
unsigned original_seq;
@@ -336,10 +402,10 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
unsigned diff;
*missed_deadline = GL_FALSE;
- if ( (flags & (VBLANK_FLAG_INTERVAL |
- VBLANK_FLAG_THROTTLE |
- VBLANK_FLAG_SYNC)) == 0 ||
- (flags & VBLANK_FLAG_NO_IRQ) != 0 ) {
+ if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL |
+ VBLANK_FLAG_THROTTLE |
+ VBLANK_FLAG_SYNC)) == 0 ||
+ (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) {
return 0;
}
@@ -350,44 +416,45 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
*
* VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at
* least one vertical blank since the last wait. Since do_wait modifies
- * vbl_seq, we have to save the original value of vbl_seq for the
+ * priv->vblSeq, we have to save the original value of priv->vblSeq for the
* VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later.
*/
- original_seq = *vbl_seq;
- interval = driGetVBlankInterval(priv, flags);
+ original_seq = priv->vblSeq;
+ interval = driGetVBlankInterval(priv);
deadline = original_seq + interval;
vbl.request.type = DRM_VBLANK_RELATIVE;
- if ( flags & VBLANK_FLAG_SECONDARY ) {
+ if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
- vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
+ vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
- if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
+ if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
- diff = *vbl_seq - deadline;
+ diff = priv->vblSeq - deadline;
/* No need to wait again if we've already reached the target */
if (diff <= (1 << 23)) {
- *missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE;
+ *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) :
+ GL_TRUE;
return 0;
}
/* Wait until the target vertical blank. */
vbl.request.type = DRM_VBLANK_ABSOLUTE;
- if ( flags & VBLANK_FLAG_SECONDARY ) {
+ if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = deadline;
- if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
+ if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
- diff = *vbl_seq - deadline;
+ diff = priv->vblSeq - deadline;
*missed_deadline = diff > 0 && diff <= (1 << 23);
return 0;
diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h
index ec83adc78d..4613c09222 100644
--- a/src/mesa/drivers/dri/common/vblank.h
+++ b/src/mesa/drivers/dri/common/vblank.h
@@ -46,17 +46,17 @@
*/
extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
+extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+ __DRIdrawablePrivate * drawablePrivate,
+ int64_t * count);
extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
-extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags,
- GLuint *vbl_seq );
-extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv,
- GLuint flags );
-extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv,
- GLuint flags, GLuint *vbl_seq );
-extern int driWaitForVBlank( const __DRIdrawablePrivate *priv,
- GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline );
+extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
+extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv );
+extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv );
+extern int driWaitForVBlank( __DRIdrawablePrivate *priv,
+ GLboolean * missed_deadline );
#undef usleep
#include <unistd.h> /* for usleep() */
diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
index 4c5323d230..173c5fa952 100644
--- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c
+++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
@@ -605,7 +605,6 @@ void ffbXMesaUpdateState(ffbContextPtr fmesa)
}
static const struct __DriverAPIRec ffbAPI = {
- .InitDriver = ffbInitDriver,
.DestroyScreen = ffbDestroyScreen,
.CreateContext = ffbCreateContext,
.DestroyContext = ffbDestroyContext,
@@ -616,6 +615,7 @@ static const struct __DriverAPIRec ffbAPI = {
.UnbindContext = ffbUnbindContext,
.GetSwapInfo = NULL,
.GetMSC = NULL,
+ .GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -704,49 +704,28 @@ ffbFillInModes( unsigned pixel_bits, unsigned depth_bits,
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 0, 1, 1 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 0, 0, 1 };
- dri_interface = interface;
-
if ( ! driCheckDriDdxDrmVersions2( "ffb",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
return NULL;
- }
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &ffbAPI);
- if ( psp != NULL ) {
- *driver_modes = ffbFillInModes( 32, 16, 0, GL_TRUE );
- }
+ psp->DriverAPI = ffbAPI;
+
+ if (!ffbInitDriver(psp))
+ return NULL;
- return (void *) psp;
+ return ffbFillInModes( 32, 16, 0, GL_TRUE );
}
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
index f8cf050d7e..1a0d3c33d7 100644
--- a/src/mesa/drivers/dri/i810/i810screen.c
+++ b/src/mesa/drivers/dri/i810/i810screen.c
@@ -403,7 +403,6 @@ i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
static const struct __DriverAPIRec i810API = {
- .InitDriver = i810InitDriver,
.DestroyScreen = i810DestroyScreen,
.CreateContext = i810CreateContext,
.DestroyContext = i810DestroyContext,
@@ -414,6 +413,7 @@ static const struct __DriverAPIRec i810API = {
.UnbindContext = i810UnbindContext,
.GetSwapInfo = NULL,
.GetMSC = NULL,
+ .GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -421,52 +421,30 @@ static const struct __DriverAPIRec i810API = {
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 2, 0 };
- dri_interface = interface;
-
if ( ! driCheckDriDdxDrmVersions2( "i810",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) ) {
return NULL;
}
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &i810API);
- if ( psp != NULL ) {
- *driver_modes = i810FillInModes( 16,
- 16, 0,
- 1);
- driInitExtensions( NULL, card_extensions, GL_TRUE );
- }
+ psp->DriverAPI = i810API;
+ driInitExtensions( NULL, card_extensions, GL_TRUE );
+
+ if (!i810InitDriver(psp))
+ return NULL;
- return (void *) psp;
+ return i810FillInModes(16, 16, 0, 1);
}
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile
index 38e4090211..ae96ddda0a 100644
--- a/src/mesa/drivers/dri/i915/Makefile
+++ b/src/mesa/drivers/dri/i915/Makefile
@@ -52,7 +52,8 @@ DRIVER_SOURCES = \
intel_state.c \
intel_tris.c \
intel_fbo.c \
- intel_depthstencil.c
+ intel_depthstencil.c \
+ intel_bufmgr_ttm.c
C_SOURCES = \
$(COMMON_SOURCES) \
@@ -61,7 +62,8 @@ C_SOURCES = \
ASM_SOURCES =
-DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \
+DRIVER_DEFINES = -I../intel -I../intel/server \
+ $(shell pkg-config libdrm --atleast-version=2.3.1 \
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
include ../Makefile.template
diff --git a/src/mesa/drivers/dri/i915/i915_debug.c b/src/mesa/drivers/dri/i915/i915_debug.c
index c0e1242a0e..8eb1c5b49e 100644
--- a/src/mesa/drivers/dri/i915/i915_debug.c
+++ b/src/mesa/drivers/dri/i915/i915_debug.c
@@ -376,20 +376,25 @@ static void BR13( struct debug_stream *stream,
}
-static void BR22( struct debug_stream *stream,
- GLuint val )
+static void BR2223( struct debug_stream *stream,
+ GLuint val22, GLuint val23 )
{
- PRINTF("\t0x%08x\n", val);
- BITS(val, 31, 16, "dest y1");
- BITS(val, 15, 0, "dest x1");
-}
+ union { GLuint val; short field[2]; } BR22, BR23;
-static void BR23( struct debug_stream *stream,
- GLuint val )
-{
- PRINTF("\t0x%08x\n", val);
- BITS(val, 31, 16, "dest y2");
- BITS(val, 15, 0, "dest x2");
+ BR22.val = val22;
+ BR23.val = val23;
+
+ PRINTF("\t0x%08x\n", val22);
+ BITS(val22, 31, 16, "dest y1");
+ BITS(val22, 15, 0, "dest x1");
+
+ PRINTF("\t0x%08x\n", val23);
+ BITS(val23, 31, 16, "dest y2");
+ BITS(val23, 15, 0, "dest x2");
+
+ /* The blit engine may produce unexpected results when these aren't met */
+ assert(BR22.field[0] < BR23.field[0]);
+ assert(BR22.field[1] < BR23.field[1]);
}
static void BR09( struct debug_stream *stream,
@@ -436,8 +441,8 @@ static GLboolean debug_copy_blit( struct debug_stream *stream,
PRINTF("\t0x%08x\n", ptr[j++]);
BR13(stream, ptr[j++]);
- BR22(stream, ptr[j++]);
- BR23(stream, ptr[j++]);
+ BR2223(stream, ptr[j], ptr[j+1]);
+ j += 2;
BR09(stream, ptr[j++]);
BR26(stream, ptr[j++]);
BR11(stream, ptr[j++]);
@@ -459,8 +464,8 @@ static GLboolean debug_color_blit( struct debug_stream *stream,
PRINTF("\t0x%08x\n", ptr[j++]);
BR13(stream, ptr[j++]);
- BR22(stream, ptr[j++]);
- BR23(stream, ptr[j++]);
+ BR2223(stream, ptr[j], ptr[j+1]);
+ j += 2;
BR09(stream, ptr[j++]);
BR16(stream, ptr[j++]);
diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h
index a9fa56e8a6..b5585e70e7 100644
--- a/src/mesa/drivers/dri/i915/i915_reg.h
+++ b/src/mesa/drivers/dri/i915/i915_reg.h
@@ -34,8 +34,6 @@
#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
-#define CMD_3D (0x3<<29)
-
#define PRIM3D_INLINE (CMD_3D | (0x1f<<24))
#define PRIM3D_TRILIST (0x0<<18)
#define PRIM3D_TRISTRIP (0x1<<18)
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
index 045ff0a5b0..74c75a3769 100644
--- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
@@ -28,7 +28,7 @@
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "intel_decode.h"
-#include "i915_debug.h"
+#include "intel_reg.h"
/* Relocations in kernel space:
* - pass dma buffer seperately
@@ -116,85 +116,23 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch)
free(batch);
}
-static int
-relocation_sort(const void *a_in, const void *b_in) {
- const struct buffer_reloc *a = a_in, *b = b_in;
-
- return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
-}
/* TODO: Push this whole function into bufmgr.
*/
static void
do_flush_locked(struct intel_batchbuffer *batch,
- GLuint used,
- GLboolean ignore_cliprects, GLboolean allow_unlock)
+ GLuint used,
+ GLboolean ignore_cliprects, GLboolean allow_unlock)
{
- GLuint *ptr;
- GLuint i;
struct intel_context *intel = batch->intel;
- dri_fence *fo;
- GLboolean performed_rendering = GL_FALSE;
-
- assert(batch->buf->virtual != NULL);
- ptr = batch->buf->virtual;
-
- /* Sort our relocation list in terms of referenced buffer pointer.
- * This lets us uniquely validate the buffers with the sum of all the flags,
- * while avoiding O(n^2) on number of relocations.
- */
- qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]),
- relocation_sort);
-
- /* Perform the necessary validations of buffers, and enter the relocations
- * in the batchbuffer.
- */
- for (i = 0; i < batch->nr_relocs; i++) {
- struct buffer_reloc *r = &batch->reloc[i];
-
- if (r->validate_flags & DRM_BO_FLAG_WRITE)
- performed_rendering = GL_TRUE;
+ void *start;
+ GLuint count;
- /* If this is the first time we've seen this buffer in the relocation
- * list, figure out our flags and validate it.
- */
- if (i == 0 || batch->reloc[i - 1].buf != r->buf) {
- uint32_t validate_flags;
- int j, ret;
+ start = dri_process_relocs(batch->buf, &count);
- /* Accumulate the flags we need for validating this buffer. */
- validate_flags = r->validate_flags;
- for (j = i + 1; j < batch->nr_relocs; j++) {
- if (batch->reloc[j].buf != r->buf)
- break;
- validate_flags |= batch->reloc[j].validate_flags;
- }
-
- /* Validate. If we fail, fence to clear the unfenced list and bail
- * out.
- */
- ret = dri_bo_validate(r->buf, validate_flags);
- if (ret != 0) {
- dri_bo_unmap(batch->buf);
- fo = dri_fence_validated(intel->intelScreen->bufmgr,
- "batchbuffer failure fence", GL_TRUE);
- dri_fence_unreference(fo);
- goto done;
- }
- }
- ptr[r->offset / 4] = r->buf->offset + r->delta;
- dri_bo_unreference(r->buf);
- }
-
- dri_bo_unmap(batch->buf);
batch->map = NULL;
batch->ptr = NULL;
-
- dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
-
- batch->list_count = 0;
- batch->nr_relocs = 0;
batch->flags = 0;
/* Throw away non-effective packets. Won't work once we have
@@ -203,26 +141,18 @@ do_flush_locked(struct intel_batchbuffer *batch,
*/
if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
- intel_batch_ioctl(batch->intel,
- batch->buf->offset,
- used, ignore_cliprects, allow_unlock);
- }
-
- /* Associate a fence with the validated buffers, and note that we included
- * a flush at the end.
- */
- fo = dri_fence_validated(intel->intelScreen->bufmgr,
- "Batch fence", GL_TRUE);
-
- if (performed_rendering) {
- dri_fence_unreference(batch->last_fence);
- batch->last_fence = fo;
- } else {
- /* If we didn't validate any buffers for writing by the card, we don't
- * need to track the fence for glFinish().
- */
- dri_fence_unreference(fo);
+ if (intel->intelScreen->ttm == GL_TRUE) {
+ intel_exec_ioctl(batch->intel,
+ used, ignore_cliprects, allow_unlock,
+ start, count, &batch->last_fence);
+ } else {
+ intel_batch_ioctl(batch->intel,
+ batch->buf->offset,
+ used, ignore_cliprects, allow_unlock);
+ }
}
+
+ dri_post_submit(batch->buf, &batch->last_fence);
if (intel->numClipRects == 0 && !ignore_cliprects) {
if (allow_unlock) {
@@ -237,16 +167,14 @@ do_flush_locked(struct intel_batchbuffer *batch,
intel->vtbl.lost_hardware(intel);
}
-done:
if (INTEL_DEBUG & DEBUG_BATCH) {
- dri_bo_map(batch->buf, GL_FALSE);
- intel_decode(ptr, used / 4, batch->buf->offset,
- intel->intelScreen->deviceID);
- dri_bo_unmap(batch->buf);
+ // dri_bo_map(batch->buf, GL_FALSE);
+ // intel_decode(ptr, used / 4, batch->buf->offset,
+ // intel->intelScreen->deviceID);
+ // dri_bo_unmap(batch->buf);
}
}
-
void
intel_batchbuffer_flush(struct intel_batchbuffer *batch)
{
@@ -280,7 +208,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
GL_FALSE);
-
+
if (!was_locked)
UNLOCK_HARDWARE(intel);
@@ -305,22 +233,12 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
dri_bo *buffer,
GLuint flags, GLuint delta)
{
- struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
-
- assert(batch->nr_relocs <= MAX_RELOCS);
-
- dri_bo_reference(buffer);
- r->buf = buffer;
- r->offset = batch->ptr - batch->map;
- r->delta = delta;
- r->validate_flags = flags;
-
+ dri_emit_reloc(batch->buf, flags, delta, batch->ptr - batch->map, buffer);
batch->ptr += 4;
+
return GL_TRUE;
}
-
-
void
intel_batchbuffer_data(struct intel_batchbuffer *batch,
const void *data, GLuint bytes, GLuint flags)
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h
index 850a91e1c9..b5c7a783a7 100644
--- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h
@@ -2,6 +2,7 @@
#define INTEL_BATCHBUFFER_H
#include "mtypes.h"
+
#include "dri_bufmgr.h"
struct intel_context;
@@ -9,19 +10,9 @@ struct intel_context;
#define BATCH_SZ 16384
#define BATCH_RESERVED 16
-#define MAX_RELOCS 4096
-
#define INTEL_BATCH_NO_CLIPRECTS 0x1
#define INTEL_BATCH_CLIPRECTS 0x2
-struct buffer_reloc
-{
- dri_bo *buf;
- GLuint offset;
- GLuint delta; /* not needed? */
- GLuint validate_flags;
-};
-
struct intel_batchbuffer
{
struct intel_context *intel;
@@ -30,13 +21,9 @@ struct intel_batchbuffer
dri_fence *last_fence;
GLuint flags;
- drmBOList list;
- GLuint list_count;
GLubyte *map;
GLubyte *ptr;
- struct buffer_reloc reloc[MAX_RELOCS];
- GLuint nr_relocs;
GLuint size;
};
diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c
index 5d97f08434..2761136f47 100644
--- a/src/mesa/drivers/dri/i915/intel_blit.c
+++ b/src/mesa/drivers/dri/i915/intel_blit.c
@@ -40,7 +40,6 @@
#include "intel_fbo.h"
#include "intel_reg.h"
#include "intel_regions.h"
-#include "vblank.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -105,8 +104,7 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
}
else {
BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
- CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ CMD = (XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB);
}
for (i = 0; i < nbox; i++, pbox++) {
@@ -184,8 +182,7 @@ intelEmitFillBlit(struct intel_context *intel,
break;
case 4:
BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25);
- CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
+ CMD = (XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB);
break;
default:
return;
@@ -273,8 +270,7 @@ intelEmitCopyBlit(struct intel_context *intel,
(((GLint) dst_pitch) & 0xffff) |
(translate_raster_op(logic_op) << 16) | (1 << 24) | (1 << 25);
CMD =
- (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ (XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB);
break;
default:
return;
@@ -405,6 +401,9 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
b = *box;
}
+ if (b.x1 >= b.x2 || b.y1 >= b.y2)
+ continue;
+
if (0)
_mesa_printf("clear %d,%d..%d,%d, mask %x\n",
b.x1, b.y1, b.x2, b.y2, mask);
@@ -443,15 +442,14 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) {
CMD = XY_COLOR_BLT_CMD;
if (clearMask & BUFFER_BIT_DEPTH)
- CMD |= XY_COLOR_BLT_WRITE_RGB;
+ CMD |= XY_BLT_WRITE_RGB;
if (clearMask & BUFFER_BIT_STENCIL)
- CMD |= XY_COLOR_BLT_WRITE_ALPHA;
+ CMD |= XY_BLT_WRITE_ALPHA;
}
else {
/* clearing RGBA */
- CMD = (XY_COLOR_BLT_CMD |
- XY_COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
+ CMD = XY_COLOR_BLT_CMD |
+ XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
}
else {
diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c
index 938bed6da7..1ae8b5feb4 100644
--- a/src/mesa/drivers/dri/i915/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915/intel_buffers.c
@@ -45,7 +45,7 @@
/* This block can be removed when libdrm >= 2.3.1 is required */
-#ifndef DRM_VBLANK_FLIP
+#ifndef DRM_IOCTL_I915_FLIP
#define DRM_VBLANK_FLIP 0x8000000
@@ -231,7 +231,7 @@ intelWindowMoved(struct intel_context *intel)
}
}
- if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
+ if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
drmI830Sarea *sarea = intel->sarea;
drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
.y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
@@ -243,7 +243,7 @@ intelWindowMoved(struct intel_context *intel)
.y2 = sarea->planeB_y + sarea->planeB_h };
GLint areaA = driIntersectArea( drw_rect, planeA_rect );
GLint areaB = driIntersectArea( drw_rect, planeB_rect );
- GLuint flags = intel_fb->vblank_flags;
+ GLuint flags = dPriv->vblFlags;
GLboolean pf_active;
GLint pf_planes;
@@ -311,19 +311,24 @@ intelWindowMoved(struct intel_context *intel)
/* Update vblank info
*/
if (areaB > areaA || (areaA == areaB && areaB > 0)) {
- flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY;
+ flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
} else {
- flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY;
+ flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
}
- if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags &&
- !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) {
+ /* Check to see if we changed pipes */
+ if (flags != dPriv->vblFlags && dPriv->vblFlags &&
+ !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+ int64_t count;
drmVBlank vbl;
int i;
+ /*
+ * Deal with page flipping
+ */
vbl.request.type = DRM_VBLANK_ABSOLUTE;
- if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+ if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
@@ -337,9 +342,19 @@ intelWindowMoved(struct intel_context *intel)
drmWaitVBlank(intel->driFd, &vbl);
}
- intel_fb->vblank_flags = flags;
- driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq);
- intel_fb->vbl_waited = intel_fb->vbl_seq;
+ /*
+ * Update msc_base from old pipe
+ */
+ driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
+ dPriv->msc_base = count;
+ /*
+ * Then get new vblank_base and vblSeq values
+ */
+ dPriv->vblFlags = flags;
+ driGetCurrentVBlank(dPriv);
+ dPriv->vblank_base = dPriv->vblSeq;
+
+ intel_fb->vbl_waited = dPriv->vblSeq;
for (i = 0; i < intel_fb->pf_num_pages; i++) {
if (intel_fb->color_rb[i])
@@ -347,7 +362,7 @@ intelWindowMoved(struct intel_context *intel)
}
}
} else {
- intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
+ dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
}
/* Update Mesa's notion of window size */
@@ -820,10 +835,10 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
*/
static GLboolean
-intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
+intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
{
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
- unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags);
+ unsigned int interval;
struct intel_context *intel =
intelScreenContext(dPriv->driScreenPriv->private);
const intelScreenPrivate *intelScreen = intel->intelScreen;
@@ -831,24 +846,26 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
drm_i915_vblank_swap_t swap;
GLboolean ret;
- if (!intel_fb->vblank_flags ||
- (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
+ if (!dPriv->vblFlags ||
+ (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) ||
intelScreen->current_rotation != 0 ||
intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
return GL_FALSE;
+ interval = driGetVBlankInterval(dPriv);
+
swap.seqtype = DRM_VBLANK_ABSOLUTE;
- if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) {
+ if (dPriv->vblFlags & VBLANK_FLAG_SYNC) {
swap.seqtype |= DRM_VBLANK_NEXTONMISS;
} else if (interval == 0) {
return GL_FALSE;
}
swap.drawable = dPriv->hHWDrawable;
- target = swap.sequence = intel_fb->vbl_seq + interval;
+ target = swap.sequence = dPriv->vblSeq + interval;
- if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+ if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
swap.seqtype |= DRM_VBLANK_SECONDARY;
}
@@ -866,14 +883,14 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
sizeof(swap))) {
- intel_fb->vbl_seq = swap.sequence;
+ dPriv->vblSeq = swap.sequence;
swap.sequence -= target;
*missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending =
intel_get_renderbuffer(&intel_fb->Base,
BUFFER_FRONT_LEFT)->vbl_pending =
- intel_fb->vbl_seq;
+ dPriv->vblSeq;
if (swap.seqtype & DRM_VBLANK_FLIP) {
intel_flip_renderbuffers(intel_fb);
@@ -918,8 +935,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
if (screen->current_rotation != 0 ||
!intelScheduleSwap(dPriv, &missed_target)) {
- driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
- &missed_target);
+ driWaitForVBlank(dPriv, &missed_target);
if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
intelCopyBuffer(dPriv, NULL);
diff --git a/src/mesa/drivers/dri/i915/intel_bufmgr_ttm.c b/src/mesa/drivers/dri/i915/intel_bufmgr_ttm.c
new file mode 100644
index 0000000000..32d9886091
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_bufmgr_ttm.c
@@ -0,0 +1,833 @@
+/**************************************************************************
+ *
+ * Copyright © 2007 Red Hat Inc.
+ * Copyright © 2007 Intel Corporation
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ * Eric Anholt <eric@anholt.net>
+ * Dave Airlie <airlied@linux.ie>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "glthread.h"
+#include "errno.h"
+#include "mtypes.h"
+#include "dri_bufmgr.h"
+#include "string.h"
+#include "imports.h"
+
+#include "i915_drm.h"
+
+#include "intel_bufmgr_ttm.h"
+
+#define BUFMGR_DEBUG 0
+
+struct intel_reloc_info
+{
+ GLuint type;
+ GLuint reloc;
+ GLuint delta; /* not needed? */
+ GLuint index;
+ drm_handle_t handle;
+};
+
+struct intel_bo_node
+{
+ drmMMListHead head;
+ drmBO *buf;
+ struct drm_i915_op_arg bo_arg;
+ unsigned long arg0;
+ unsigned long arg1;
+ void (*destroy)(void *);
+ void *priv;
+};
+
+struct intel_bo_reloc_list
+{
+ drmMMListHead head;
+ drmBO buf;
+ uint32_t *relocs;
+};
+
+struct intel_bo_reloc_node
+{
+ drmMMListHead head;
+ drm_handle_t handle;
+ uint32_t nr_reloc_types;
+ struct intel_bo_reloc_list type_list;
+};
+
+struct intel_bo_list {
+ unsigned numCurrent;
+ drmMMListHead list;
+ void (*destroy)(void *node);
+};
+
+typedef struct _dri_bufmgr_ttm {
+ dri_bufmgr bufmgr;
+
+ int fd;
+ _glthread_Mutex mutex;
+ unsigned int fence_type;
+ unsigned int fence_type_flush;
+
+ uint32_t max_relocs;
+ /** ttm relocation list */
+ struct intel_bo_list list;
+ struct intel_bo_list reloc_list;
+
+} dri_bufmgr_ttm;
+
+typedef struct _dri_bo_ttm {
+ dri_bo bo;
+
+ int refcount; /* Protected by bufmgr->mutex */
+ drmBO drm_bo;
+ const char *name;
+} dri_bo_ttm;
+
+typedef struct _dri_fence_ttm
+{
+ dri_fence fence;
+
+ int refcount; /* Protected by bufmgr->mutex */
+ const char *name;
+ drmFence drm_fence;
+} dri_fence_ttm;
+
+
+static void intel_bo_free_list(struct intel_bo_list *list)
+{
+ struct intel_bo_node *node;
+ drmMMListHead *l;
+
+ l = list->list.next;
+ while(l != &list->list) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(struct intel_bo_node, l, head);
+ list->destroy(node);
+ l = list->list.next;
+ list->numCurrent--;
+ }
+}
+
+static void generic_destroy(void *nodep)
+{
+ free(nodep);
+}
+
+static int intel_create_bo_list(int numTarget, struct intel_bo_list *list, void (*destroy)(void *))
+{
+ DRMINITLISTHEAD(&list->list);
+ list->numCurrent = 0;
+ if (destroy)
+ list->destroy = destroy;
+ else
+ list->destroy = generic_destroy;
+ return 0;
+}
+
+
+static struct drm_i915_op_arg *
+intel_setup_validate_list(int fd, struct intel_bo_list *list, struct intel_bo_list *reloc_list, GLuint *count_p)
+{
+ struct intel_bo_node *node;
+ struct intel_bo_reloc_node *rl_node;
+ drmMMListHead *l, *rl;
+ struct drm_i915_op_arg *arg, *first;
+ struct drm_bo_op_req *req;
+ uint64_t *prevNext = NULL;
+ GLuint count = 0;
+
+ first = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(struct intel_bo_node, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->d.req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
+
+ memset(arg, 0, sizeof(*arg));
+ prevNext = &arg->next;
+ req->bo_req.handle = node->buf->handle;
+ req->op = drm_bo_validate;
+ req->bo_req.flags = node->arg0;
+ req->bo_req.hint = 0;
+ req->bo_req.mask = node->arg1;
+ req->bo_req.fence_class = 0; /* Backwards compat. */
+ arg->reloc_handle = 0;
+
+ for (rl = reloc_list->list.next; rl != &reloc_list->list; rl = rl->next) {
+ rl_node = DRMLISTENTRY(struct intel_bo_reloc_node, rl, head);
+
+ if (rl_node->handle == node->buf->handle) {
+ arg->reloc_handle = rl_node->type_list.buf.handle;
+ }
+ }
+ count++;
+ }
+
+ if (!first)
+ return 0;
+
+ *count_p = count;
+ return first;
+}
+
+static void intel_free_validate_list(int fd, struct intel_bo_list *list)
+{
+ struct intel_bo_node *node;
+ drmMMListHead *l;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(struct intel_bo_node, l, head);
+
+ if (node->destroy)
+ (*node->destroy)(node->priv);
+
+ }
+}
+
+static void intel_free_reloc_list(int fd, struct intel_bo_list *reloc_list)
+{
+ struct intel_bo_reloc_node *reloc_node;
+ drmMMListHead *rl, *tmp;
+
+ for (rl = reloc_list->list.next, tmp = rl->next; rl != &reloc_list->list; rl = tmp, tmp = rl->next) {
+ reloc_node = DRMLISTENTRY(struct intel_bo_reloc_node, rl, head);
+
+ DRMLISTDEL(rl);
+
+ if (reloc_node->nr_reloc_types > 1) {
+
+ /* TODO */
+ }
+
+ drmBOUnmap(fd, &reloc_node->type_list.buf);
+ drmBOUnreference(fd, &reloc_node->type_list.buf);
+ free(reloc_node);
+ }
+}
+
+static int intel_add_validate_buffer(struct intel_bo_list *list, dri_bo *buf, unsigned flags,
+ unsigned mask, int *itemLoc, void (*destroy_cb)(void *))
+{
+ struct intel_bo_node *node, *cur;
+ drmMMListHead *l;
+ int count = 0;
+ int ret = 0;
+ drmBO *buf_bo = &((dri_bo_ttm *)buf)->drm_bo;
+ cur = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(struct intel_bo_node, l, head);
+ if (node->buf->handle == buf_bo->handle) {
+ cur = node;
+ break;
+ }
+ count++;
+ }
+
+ if (!cur) {
+ cur = drmMalloc(sizeof(*cur));
+ if (!cur) {
+ return -ENOMEM;
+ }
+ cur->buf = buf_bo;
+ cur->priv = buf;
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ cur->destroy = destroy_cb;
+ ret = 1;
+
+ DRMLISTADDTAIL(&cur->head, &list->list);
+
+ } else {
+ unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
+ unsigned memFlags = cur->arg0 & flags & memMask;
+
+ if (!memFlags) {
+ return -EINVAL;
+ }
+ if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
+ return -EINVAL;
+ }
+ cur->arg1 |= mask;
+ cur->arg0 = memFlags | ((cur->arg0 | flags) &
+ cur->arg1 & ~DRM_BO_MASK_MEM);
+ }
+ *itemLoc = count;
+ return ret;
+}
+
+
+#define RELOC_BUF_SIZE(x) ((I915_RELOC_HEADER + x * I915_RELOC0_STRIDE) * sizeof(uint32_t))
+
+static int intel_create_new_reloc_type_list(int fd, struct intel_bo_reloc_list *cur_type, int max_relocs)
+{
+ int ret;
+
+ /* should allocate a drmBO here */
+ ret = drmBOCreate(fd, RELOC_BUF_SIZE(max_relocs), 0,
+ NULL,
+ DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_CACHED,
+ 0, &cur_type->buf);
+ if (ret)
+ return ret;
+
+ ret = drmBOMap(fd, &cur_type->buf, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void **)&cur_type->relocs);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+
+static int intel_add_validate_reloc(int fd, struct intel_bo_list *reloc_list, struct intel_reloc_info *reloc_info, uint32_t max_relocs)
+{
+ struct intel_bo_reloc_node *rl_node, *cur;
+ drmMMListHead *rl, *l;
+ int ret = 0;
+ uint32_t *reloc_start;
+ int num_relocs;
+ struct intel_bo_reloc_list *cur_type;
+
+ cur = NULL;
+
+ for (rl = reloc_list->list.next; rl != &reloc_list->list; rl = rl->next) {
+ rl_node = DRMLISTENTRY(struct intel_bo_reloc_node, rl, head);
+ if (rl_node->handle == reloc_info->handle) {
+ cur = rl_node;
+ break;
+ }
+ }
+
+ if (!cur) {
+
+ cur = malloc(sizeof(*cur));
+ if (!cur)
+ return -ENOMEM;
+
+ cur->nr_reloc_types = 1;
+ cur->handle = reloc_info->handle;
+ cur_type = &cur->type_list;
+
+ DRMINITLISTHEAD(&cur->type_list.head);
+ ret = intel_create_new_reloc_type_list(fd, cur_type, max_relocs);
+ if (ret) {
+ return -1;
+ }
+ DRMLISTADDTAIL(&cur->head, &reloc_list->list);
+
+ cur_type->relocs[0] = 0 | (reloc_info->type << 16);
+ cur_type->relocs[1] = 0; // next reloc buffer handle is 0
+
+ } else {
+ int found = 0;
+ if ((cur->type_list.relocs[0] >> 16) == reloc_info->type) {
+ cur_type = &cur->type_list;
+ found = 1;
+ } else {
+ for (l = cur->type_list.head.next; l != &cur->type_list.head; l = l->next) {
+ cur_type = DRMLISTENTRY(struct intel_bo_reloc_list, l, head);
+ if (((cur_type->relocs[0] >> 16) & 0xffff) == reloc_info->type)
+ found = 1;
+ break;
+ }
+ }
+
+ /* didn't find the relocation type */
+ if (!found) {
+ cur_type = malloc(sizeof(*cur_type));
+ if (!cur_type) {
+ return -ENOMEM;
+ }
+
+ ret = intel_create_new_reloc_type_list(fd, cur_type, max_relocs);
+ DRMLISTADDTAIL(&cur_type->head, &cur->type_list.head);
+
+ cur_type->relocs[0] = (reloc_info->type << 16);
+ cur_type->relocs[1] = 0;
+
+ cur->nr_reloc_types++;
+ }
+ }
+
+ reloc_start = cur_type->relocs;
+
+ num_relocs = (reloc_start[0] & 0xffff);
+
+ reloc_start[num_relocs*I915_RELOC0_STRIDE + I915_RELOC_HEADER] = reloc_info->reloc;
+ reloc_start[num_relocs*I915_RELOC0_STRIDE + I915_RELOC_HEADER+1] = reloc_info->delta;
+ reloc_start[num_relocs*I915_RELOC0_STRIDE + I915_RELOC_HEADER+2] = reloc_info->index;
+ reloc_start[0]++;
+ if (((reloc_start[0] & 0xffff)) > (max_relocs)) {
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+
+#if 0
+int
+driFenceSignaled(DriFenceObject * fence, unsigned type)
+{
+ int signaled;
+ int ret;
+
+ if (fence == NULL)
+ return GL_TRUE;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+ ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled);
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ BM_CKFATAL(ret);
+ return signaled;
+}
+#endif
+
+static dri_bo *
+dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
+ unsigned long size, unsigned int alignment,
+ unsigned int location_mask)
+{
+ dri_bufmgr_ttm *ttm_bufmgr;
+ dri_bo_ttm *ttm_buf;
+ unsigned int pageSize = getpagesize();
+ int ret;
+ unsigned int flags, hint;
+
+ ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
+
+ ttm_buf = malloc(sizeof(*ttm_buf));
+ if (!ttm_buf)
+ return NULL;
+
+ /* The mask argument doesn't do anything for us that we want other than
+ * determine which pool (TTM or local) the buffer is allocated into, so just
+ * pass all of the allocation class flags.
+ */
+ flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_EXE;
+ /* No hints we want to use. */
+ hint = 0;
+
+ ret = drmBOCreate(ttm_bufmgr->fd, size, alignment / pageSize,
+ NULL, flags, hint, &ttm_buf->drm_bo);
+ if (ret != 0) {
+ free(ttm_buf);
+ return NULL;
+ }
+ ttm_buf->bo.size = ttm_buf->drm_bo.size;
+ ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
+ ttm_buf->bo.virtual = NULL;
+ ttm_buf->bo.bufmgr = bufmgr;
+ ttm_buf->name = name;
+ ttm_buf->refcount = 1;
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
+#endif
+
+ return &ttm_buf->bo;
+}
+
+/* Our TTM backend doesn't allow creation of static buffers, as that requires
+ * privelege for the non-fake case, and the lock in the fake case where we were
+ * working around the X Server not creating buffers and passing handles to us.
+ */
+static dri_bo *
+dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
+ unsigned long offset, unsigned long size, void *virtual,
+ unsigned int location_mask)
+{
+ return NULL;
+}
+
+/** Returns a dri_bo wrapping the given buffer object handle.
+ *
+ * This can be used when one application needs to pass a buffer object
+ * to another.
+ */
+dri_bo *
+intel_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
+ unsigned int handle)
+{
+ dri_bufmgr_ttm *ttm_bufmgr;
+ dri_bo_ttm *ttm_buf;
+ int ret;
+
+ ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
+
+ ttm_buf = malloc(sizeof(*ttm_buf));
+ if (!ttm_buf)
+ return NULL;
+
+ ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
+ if (ret != 0) {
+ free(ttm_buf);
+ return NULL;
+ }
+ ttm_buf->bo.size = ttm_buf->drm_bo.size;
+ ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
+ ttm_buf->bo.virtual = NULL;
+ ttm_buf->bo.bufmgr = bufmgr;
+ ttm_buf->name = name;
+ ttm_buf->refcount = 1;
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "bo_create_from_handle: %p %08x (%s)\n", &ttm_buf->bo, handle,
+ ttm_buf->name);
+#endif
+
+ return &ttm_buf->bo;
+}
+
+static void
+dri_ttm_bo_reference(dri_bo *buf)
+{
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
+ dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
+
+ _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
+ ttm_buf->refcount++;
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+}
+
+static void
+dri_ttm_bo_unreference(dri_bo *buf)
+{
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
+ dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
+
+ if (!buf)
+ return;
+
+ _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
+ if (--ttm_buf->refcount == 0) {
+ int ret;
+
+ ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
+ if (ret != 0) {
+ fprintf(stderr, "drmBOUnreference failed (%s): %s\n", ttm_buf->name,
+ strerror(-ret));
+ }
+#if BUFMGR_DEBUG
+ fprintf(stderr, "bo_unreference final: %p (%s)\n",
+ &ttm_buf->bo, ttm_buf->name);
+#endif
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+ free(buf);
+ return;
+ }
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+}
+
+static int
+dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable)
+{
+ dri_bufmgr_ttm *bufmgr_ttm;
+ dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
+ unsigned int flags;
+
+ bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
+
+ flags = DRM_BO_FLAG_READ;
+ if (write_enable)
+ flags |= DRM_BO_FLAG_WRITE;
+
+ assert(buf->virtual == NULL);
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
+#endif
+
+ return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual);
+}
+
+static int
+dri_ttm_bo_unmap(dri_bo *buf)
+{
+ dri_bufmgr_ttm *bufmgr_ttm;
+ dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
+
+ if (buf == NULL)
+ return 0;
+
+ bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
+
+ assert(buf->virtual != NULL);
+
+ buf->virtual = NULL;
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
+#endif
+
+ return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo);
+}
+
+/* Returns a dri_bo wrapping the given buffer object handle.
+ *
+ * This can be used when one application needs to pass a buffer object
+ * to another.
+ */
+dri_fence *
+intel_ttm_fence_create_from_arg(dri_bufmgr *bufmgr, const char *name,
+ drm_fence_arg_t *arg)
+{
+ dri_bufmgr_ttm *ttm_bufmgr;
+ dri_fence_ttm *ttm_fence;
+
+ ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
+
+ ttm_fence = malloc(sizeof(*ttm_fence));
+ if (!ttm_fence)
+ return NULL;
+
+ ttm_fence->drm_fence.handle = arg->handle;
+ ttm_fence->drm_fence.fence_class = arg->fence_class;
+ ttm_fence->drm_fence.type = arg->type;
+ ttm_fence->drm_fence.flags = arg->flags;
+ ttm_fence->drm_fence.signaled = 0;
+ ttm_fence->drm_fence.sequence = arg->sequence;
+
+ ttm_fence->fence.bufmgr = bufmgr;
+ ttm_fence->name = name;
+ ttm_fence->refcount = 1;
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "fence_create_from_handle: %p (%s)\n", &ttm_fence->fence,
+ ttm_fence->name);
+#endif
+
+ return &ttm_fence->fence;
+}
+
+
+static void
+dri_ttm_fence_reference(dri_fence *fence)
+{
+ dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
+
+ _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
+ ++fence_ttm->refcount;
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+#if BUFMGR_DEBUG
+ fprintf(stderr, "fence_reference: %p (%s)\n", &fence_ttm->fence,
+ fence_ttm->name);
+#endif
+}
+
+static void
+dri_ttm_fence_unreference(dri_fence *fence)
+{
+ dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
+
+ if (!fence)
+ return;
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "fence_unreference: %p (%s)\n", &fence_ttm->fence,
+ fence_ttm->name);
+#endif
+ _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
+ if (--fence_ttm->refcount == 0) {
+ int ret;
+
+ ret = drmFenceUnreference(bufmgr_ttm->fd, &fence_ttm->drm_fence);
+ if (ret != 0) {
+ fprintf(stderr, "drmFenceUnreference failed (%s): %s\n",
+ fence_ttm->name, strerror(-ret));
+ }
+
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+ free(fence);
+ return;
+ }
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+}
+
+static void
+dri_ttm_fence_wait(dri_fence *fence)
+{
+ dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
+ int ret;
+
+ _glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
+ ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0);
+ _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
+ if (ret != 0) {
+ _mesa_printf("%s:%d: Error %d waiting for fence %s.\n",
+ __FILE__, __LINE__, ret, fence_ttm->name);
+ abort();
+ }
+
+#if BUFMGR_DEBUG
+ fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence,
+ fence_ttm->name);
+#endif
+}
+
+static void
+dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
+{
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
+
+ intel_bo_free_list(&bufmgr_ttm->list);
+ intel_bo_free_list(&bufmgr_ttm->reloc_list);
+
+ _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
+ free(bufmgr);
+}
+
+
+static void intel_dribo_destroy_callback(void *priv)
+{
+ dri_bo *dribo = priv;
+
+ if (dribo) {
+ dri_bo_unreference(dribo);
+ }
+}
+
+static void
+dri_ttm_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset,
+ dri_bo *relocatee)
+{
+ dri_bo_ttm *ttm_buf = (dri_bo_ttm *)batch_buf;
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
+ int newItem;
+ struct intel_reloc_info reloc;
+ int mask;
+ int ret;
+
+ mask = DRM_BO_MASK_MEM;
+ mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE);
+
+ ret = intel_add_validate_buffer(&bufmgr_ttm->list, relocatee, flags, mask, &newItem, intel_dribo_destroy_callback);
+ if (ret < 0)
+ return;
+
+ if (ret == 1) {
+ dri_bo_reference(relocatee);
+ }
+
+ reloc.type = I915_RELOC_TYPE_0;
+ reloc.reloc = offset;
+ reloc.delta = delta;
+ reloc.index = newItem;
+ reloc.handle = ttm_buf->drm_bo.handle;
+
+ intel_add_validate_reloc(bufmgr_ttm->fd, &bufmgr_ttm->reloc_list, &reloc, bufmgr_ttm->max_relocs);
+ return;
+}
+
+
+static void *
+dri_ttm_process_reloc(dri_bo *batch_buf, GLuint *count)
+{
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
+ void *ptr;
+ int itemLoc;
+
+ dri_bo_unmap(batch_buf);
+
+ intel_add_validate_buffer(&bufmgr_ttm->list, batch_buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE, &itemLoc, NULL);
+
+ ptr = intel_setup_validate_list(bufmgr_ttm->fd, &bufmgr_ttm->list, &bufmgr_ttm->reloc_list, count);
+
+ return ptr;
+}
+
+static void
+dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
+{
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
+
+ intel_free_validate_list(bufmgr_ttm->fd, &bufmgr_ttm->list);
+ intel_free_reloc_list(bufmgr_ttm->fd, &bufmgr_ttm->reloc_list);
+
+ intel_bo_free_list(&bufmgr_ttm->list);
+}
+
+/**
+ * Initializes the TTM buffer manager, which uses the kernel to allocate, map,
+ * and manage map buffer objections.
+ *
+ * \param fd File descriptor of the opened DRM device.
+ * \param fence_type Driver-specific fence type used for fences with no flush.
+ * \param fence_type_flush Driver-specific fence type used for fences with a
+ * flush.
+ */
+dri_bufmgr *
+intel_bufmgr_ttm_init(int fd, unsigned int fence_type,
+ unsigned int fence_type_flush, int batch_size)
+{
+ dri_bufmgr_ttm *bufmgr_ttm;
+
+ bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
+ bufmgr_ttm->fd = fd;
+ bufmgr_ttm->fence_type = fence_type;
+ bufmgr_ttm->fence_type_flush = fence_type_flush;
+ _glthread_INIT_MUTEX(bufmgr_ttm->mutex);
+
+ /* lets go with one relocation per every four dwords - purely heuristic */
+ bufmgr_ttm->max_relocs = batch_size / sizeof(uint32_t) / 4;
+
+ intel_create_bo_list(10, &bufmgr_ttm->list, NULL);
+ intel_create_bo_list(1, &bufmgr_ttm->reloc_list, NULL);
+
+ bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc;
+ bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static;
+ bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference;
+ bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference;
+ bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map;
+ bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap;
+ bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference;
+ bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference;
+ bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
+ bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
+ bufmgr_ttm->bufmgr.emit_reloc = dri_ttm_emit_reloc;
+ bufmgr_ttm->bufmgr.process_relocs = dri_ttm_process_reloc;
+ bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;
+ return &bufmgr_ttm->bufmgr;
+}
+
diff --git a/src/mesa/drivers/dri/i915/intel_bufmgr_ttm.h b/src/mesa/drivers/dri/i915/intel_bufmgr_ttm.h
new file mode 100644
index 0000000000..0738839cef
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_bufmgr_ttm.h
@@ -0,0 +1,17 @@
+
+#ifndef INTEL_BUFMGR_TTM_H
+#define INTEL_BUFMGR_TTM_H
+
+#include "dri_bufmgr.h"
+
+extern dri_bo *intel_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
+ unsigned int handle);
+
+dri_fence *intel_ttm_fence_create_from_arg(dri_bufmgr *bufmgr, const char *name,
+ drm_fence_arg_t *arg);
+
+
+dri_bufmgr *intel_bufmgr_ttm_init(int fd, unsigned int fence_type,
+ unsigned int fence_type_flush, int batch_size);
+
+#endif
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 041a155fe7..b85b0c2939 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -613,21 +613,20 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
if (intel->ctx.DrawBuffer == &intel_fb->Base) {
if (intel->driDrawable != driDrawPriv) {
- if (driDrawPriv->pdraw->swap_interval == (unsigned)-1) {
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
int i;
- intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0)
+ driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
? driGetDefaultVBlankFlags(&intel->optionCache)
: VBLANK_FLAG_NO_IRQ;
(*dri_interface->getUST) (&intel_fb->swap_ust);
- driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags,
- &intel_fb->vbl_seq);
- intel_fb->vbl_waited = intel_fb->vbl_seq;
+ driDrawableInitVBlank(driDrawPriv);
+ intel_fb->vbl_waited = driDrawPriv->vblSeq;
for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) {
if (intel_fb->color_rb[i])
- intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq;
+ intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
}
}
intel->driDrawable = driDrawPriv;
@@ -731,6 +730,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
*/
void LOCK_HARDWARE( struct intel_context *intel )
{
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
char __ret=0;
struct intel_framebuffer *intel_fb = NULL;
struct intel_renderbuffer *intel_rb = NULL;
@@ -748,14 +748,14 @@ void LOCK_HARDWARE( struct intel_context *intel )
BUFFER_BACK_LEFT);
}
- if (intel_rb && intel_fb->vblank_flags &&
- !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
+ if (intel_rb && dPriv->vblFlags &&
+ !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) &&
(intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
drmVBlank vbl;
vbl.request.type = DRM_VBLANK_ABSOLUTE;
- if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+ if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index 1e9ccd5cdc..ce9a362944 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -292,6 +292,8 @@ extern char *__progname;
#define SUBPIXEL_X 0.125
#define SUBPIXEL_Y 0.125
+#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
+
#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
@@ -460,9 +462,6 @@ extern void intelInitStateFuncs(struct dd_function_table *functions);
#define BLENDFACT_INV_CONST_ALPHA 0x0f
#define BLENDFACT_MASK 0x0f
-#define MI_BATCH_BUFFER_END (0xA<<23)
-
-
extern int intel_translate_compare_func(GLenum func);
extern int intel_translate_stencil_op(GLenum op);
extern int intel_translate_blend_factor(GLenum factor);
diff --git a/src/mesa/drivers/dri/i915/intel_fbo.h b/src/mesa/drivers/dri/i915/intel_fbo.h
index 411d634231..f9a11d02e3 100644
--- a/src/mesa/drivers/dri/i915/intel_fbo.h
+++ b/src/mesa/drivers/dri/i915/intel_fbo.h
@@ -50,8 +50,6 @@ struct intel_framebuffer
/* VBI
*/
- GLuint vbl_seq;
- GLuint vblank_flags;
GLuint vbl_waited;
int64_t swap_ust;
diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c
index 6e76737c78..94f7e73ecf 100644
--- a/src/mesa/drivers/dri/i915/intel_ioctl.c
+++ b/src/mesa/drivers/dri/i915/intel_ioctl.c
@@ -42,6 +42,8 @@
#include "intel_regions.h"
#include "drm.h"
+#include "intel_bufmgr_ttm.h"
+
#define FILE_DEBUG_FLAG DEBUG_IOCTL
int
@@ -105,9 +107,6 @@ intel_batch_ioctl(struct intel_context *intel,
* hardware contexts which would preserve statechanges beyond a
* single buffer.
*/
-
-
-
batch.start = start_offset;
batch.used = used;
batch.cliprects = intel->pClipRects;
@@ -133,3 +132,56 @@ intel_batch_ioctl(struct intel_context *intel,
*/
intel->vtbl.lost_hardware(intel);
}
+
+void
+intel_exec_ioctl(struct intel_context *intel,
+ GLuint used,
+ GLboolean ignore_cliprects, GLboolean allow_unlock,
+ void *start, GLuint count, dri_fence **fence)
+{
+ struct drm_i915_execbuffer execbuf;
+ dri_fence *fo;
+
+ assert(intel->locked);
+ assert(used);
+
+ if (*fence) {
+ dri_fence_unreference(*fence);
+ }
+
+ memset(&execbuf, 0, sizeof(execbuf));
+
+ execbuf.num_buffers = count;
+ execbuf.batch.used = used;
+ execbuf.batch.cliprects = intel->pClipRects;
+ execbuf.batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+ execbuf.batch.DR1 = 0;
+ execbuf.batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) |
+ (((GLuint) intel->drawY) << 16));
+
+ execbuf.ops_list = (unsigned)start; // TODO
+ execbuf.fence_arg.flags = DRM_FENCE_FLAG_SHAREABLE | DRM_I915_FENCE_FLAG_FLUSHED;
+
+ if (drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, &execbuf,
+ sizeof(execbuf))) {
+ fprintf(stderr, "DRM_I830_EXECBUFFER: %d\n", -errno);
+ UNLOCK_HARDWARE(intel);
+ exit(1);
+ }
+
+
+ fo = intel_ttm_fence_create_from_arg(intel->intelScreen->bufmgr, "fence buffers",
+ &execbuf.fence_arg);
+ if (!fo) {
+ fprintf(stderr, "failed to fence handle: %08x\n", execbuf.fence_arg.handle);
+ UNLOCK_HARDWARE(intel);
+ exit(1);
+ }
+ *fence = fo;
+
+ /* FIXME: use hardware contexts to avoid 'losing' hardware after
+ * each buffer flush.
+ */
+ intel->vtbl.lost_hardware(intel);
+
+}
diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h
index 7a5b175ed1..953fee9240 100644
--- a/src/mesa/drivers/dri/i915/intel_ioctl.h
+++ b/src/mesa/drivers/dri/i915/intel_ioctl.h
@@ -37,4 +37,8 @@ void intel_batch_ioctl(struct intel_context *intel,
GLuint start_offset,
GLuint used,
GLboolean ignore_cliprects, GLboolean allow_unlock);
+void intel_exec_ioctl(struct intel_context *intel,
+ GLuint used,
+ GLboolean ignore_cliprects, GLboolean allow_unlock,
+ void *start, GLuint count, dri_fence **fence);
#endif
diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c
index 74f6b2d851..2c167a9ab7 100644
--- a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c
@@ -99,12 +99,29 @@ intel_miptree_create(struct intel_context *intel,
if (ok) {
if (!mt->compressed) {
- /* XXX: Align pitch to multiple of 64 bytes for now to allow
- * render-to-texture to work in all cases. This should probably be
- * replaced at some point by some scheme to only do this when really
- * necessary.
+ int align;
+
+ if (intel->intelScreen->ttm) {
+ /* XXX: Align pitch to multiple of 64 bytes for now to allow
+ * render-to-texture to work in all cases. This should probably be
+ * replaced at some point by some scheme to only do this when really
+ * necessary.
+ */
+ align = 63;
+ } else {
+ align = 3;
+ }
+
+ mt->pitch = (mt->pitch * cpp + align) & ~align;
+
+ /* XXX: At least the i915 seems very upset when the pitch is a multiple
+ * of 1024 and sometimes 512 bytes - performance can drop by several
+ * times. Go to the next multiple of the required alignment for now.
*/
- mt->pitch = ((mt->pitch * cpp + 63) & ~63) / cpp;
+ if (!(mt->pitch & 511))
+ mt->pitch += align + 1;
+
+ mt->pitch /= cpp;
}
mt->region = intel_region_alloc(intel->intelScreen,
diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c
index 4eac859a13..7799fdbb11 100644
--- a/src/mesa/drivers/dri/i915/intel_regions.c
+++ b/src/mesa/drivers/dri/i915/intel_regions.c
@@ -44,6 +44,7 @@
#include "intel_blit.h"
#include "intel_buffer_objects.h"
#include "dri_bufmgr.h"
+#include "intel_bufmgr_ttm.h"
#include "intel_batchbuffer.h"
#define FILE_DEBUG_FLAG DEBUG_REGION
@@ -162,7 +163,7 @@ intel_region_create_static(intelScreenPrivate *intelScreen,
if (intelScreen->ttm) {
assert(bo_handle != -1);
- region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
+ region->buffer = intel_ttm_bo_create_from_handle(intelScreen->bufmgr,
"static region",
bo_handle);
} else {
@@ -201,7 +202,7 @@ intel_region_update_static(intelScreenPrivate *intelScreen,
dri_bo_unreference(region->buffer);
if (intelScreen->ttm) {
assert(bo_handle != -1);
- region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
+ region->buffer = intel_ttm_bo_create_from_handle(intelScreen->bufmgr,
"static region",
bo_handle);
} else {
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 2721a90094..25f5efa7bc 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -50,6 +50,8 @@
#include "intel_regions.h"
#include "intel_batchbuffer.h"
+#include "intel_bufmgr_ttm.h"
+
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
@@ -65,6 +67,7 @@ PUBLIC const char __driConfigOptions[] =
#endif /*USE_NEW_INTERFACE */
extern const struct dri_extension card_extensions[];
+ extern const struct dri_extension ttm_extensions[];
/**
* Map all the memory regions described by the screen.
@@ -217,7 +220,7 @@ intel_recreate_static_regions(intelScreenPrivate *intelScreen)
/* The rotated region is only used for old DDXes that didn't handle rotation
\ * on their own.
*/
- if (intelScreen->driScrnPriv->ddxMinor < 8) {
+ if (intelScreen->driScrnPriv->ddx_version.minor < 8) {
intelScreen->rotated_region =
intel_recreate_static(intelScreen,
intelScreen->rotated_region,
@@ -377,7 +380,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
intelScreen->back.handle = sarea->back_handle;
intelScreen->back.size = sarea->back_size;
- if (intelScreen->driScrnPriv->ddxMinor >= 8) {
+ if (intelScreen->driScrnPriv->ddx_version.minor >= 8) {
intelScreen->third.offset = sarea->third_offset;
intelScreen->third.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->third.handle = sarea->third_handle;
@@ -389,7 +392,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
intelScreen->depth.handle = sarea->depth_handle;
intelScreen->depth.size = sarea->depth_size;
- if (intelScreen->driScrnPriv->ddxMinor >= 9) {
+ if (intelScreen->driScrnPriv->ddx_version.minor >= 9) {
intelScreen->front.bo_handle = sarea->front_bo_handle;
intelScreen->back.bo_handle = sarea->back_bo_handle;
intelScreen->third.bo_handle = sarea->third_bo_handle;
@@ -419,19 +422,28 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
intelPrintSAREA(sarea);
}
+static const __DRItexOffsetExtension intelTexOffsetExtension = {
+ { __DRI_TEX_OFFSET },
+ intelSetTexOffset,
+};
-static GLboolean
-intelInitDriver(__DRIscreenPrivate * sPriv)
+static const __DRIextension *intelExtensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ &intelTexOffsetExtension.base,
+ NULL
+};
+
+
+static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen;
I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
drmI830Sarea *sarea;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->
- getProcAddress("glxEnableExtension"));
- void *const psc = sPriv->psc->screenConfigs;
-
if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
fprintf(stderr,
"\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
@@ -489,7 +501,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
if (0)
intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
- intelScreen->drmMinor = sPriv->drmMinor;
+ intelScreen->drmMinor = sPriv->drm_version.minor;
/* Determine if IRQs are active? */
{
@@ -523,25 +535,21 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
}
}
- if (glx_enable_extension != NULL) {
- (*glx_enable_extension) (psc, "GLX_SGI_swap_control");
- (*glx_enable_extension) (psc, "GLX_SGI_video_sync");
- (*glx_enable_extension) (psc, "GLX_MESA_swap_control");
- (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage");
- (*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
- }
+ sPriv->extensions = intelExtensions;
/* If we've got a new enough DDX that's initializing TTM and giving us
* object handles for the shared buffers, use that.
*/
intelScreen->ttm = GL_FALSE;
if (getenv("INTEL_NO_TTM") == NULL &&
- intelScreen->driScrnPriv->ddxMinor >= 9 &&
+ intelScreen->driScrnPriv->ddx_version.minor >= 9 &&
+ intelScreen->drmMinor >= 11 &&
intelScreen->front.bo_handle != -1) {
- intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
- DRM_FENCE_TYPE_EXE,
- DRM_FENCE_TYPE_EXE |
- DRM_I915_FENCE_TYPE_RW);
+ intelScreen->bufmgr = intel_bufmgr_ttm_init(sPriv->fd,
+ DRM_FENCE_TYPE_EXE,
+ DRM_FENCE_TYPE_EXE |
+ DRM_I915_FENCE_TYPE_RW,
+ BATCH_SZ);
if (intelScreen->bufmgr != NULL)
intelScreen->ttm = GL_TRUE;
}
@@ -772,7 +780,6 @@ intelCreateContext(const __GLcontextModes * mesaVis,
static const struct __DriverAPIRec intelAPI = {
- .InitDriver = intelInitDriver,
.DestroyScreen = intelDestroyScreen,
.CreateContext = intelCreateContext,
.DestroyContext = intelDestroyContext,
@@ -783,6 +790,7 @@ static const struct __DriverAPIRec intelAPI = {
.UnbindContext = intelUnbindContext,
.GetSwapInfo = intelGetSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
@@ -877,65 +885,47 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC void *
-__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn,
- __DRIscreen * psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes)
+PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 5, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 5, 0 };
+ I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
- dri_interface = interface;
+ psp->DriverAPI = intelAPI;
if (!driCheckDriDdxDrmVersions2("i915",
- dri_version, &dri_expected,
- ddx_version, &ddx_expected,
- drm_version, &drm_expected)) {
+ &psp->dri_version, &dri_expected,
+ &psp->ddx_version, &ddx_expected,
+ &psp->drm_version, &drm_expected)) {
return NULL;
}
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &intelAPI);
-
- if (psp != NULL) {
- I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
- *driver_modes = intelFillInModes(dri_priv->cpp * 8,
- (dri_priv->cpp == 2) ? 16 : 24,
- (dri_priv->cpp == 2) ? 0 : 8, 1);
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions(NULL, card_extensions, GL_FALSE);
- }
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions(NULL, card_extensions, GL_FALSE);
+ driInitExtensions(NULL, ttm_extensions, GL_FALSE);
+
+ if (!intelInitDriver(psp))
+ return NULL;
- return (void *) psp;
+ return intelFillInModes(dri_priv->cpp * 8,
+ (dri_priv->cpp == 2) ? 16 : 24,
+ (dri_priv->cpp == 2) ? 0 : 8, 1);
}
struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
diff --git a/src/mesa/drivers/dri/i915/server/intel_dri.c b/src/mesa/drivers/dri/i915/server/intel_dri.c
index e49c4214ad..a2043afb47 100644..120000
--- a/src/mesa/drivers/dri/i915/server/intel_dri.c
+++ b/src/mesa/drivers/dri/i915/server/intel_dri.c
@@ -1,1306 +1 @@
-/**
- * \file server/intel_dri.c
- * \brief File to perform the device-specific initialization tasks typically
- * done in the X server.
- *
- * Here they are converted to run in the client (or perhaps a standalone
- * process), and to work with the frame buffer device rather than the X
- * server infrastructure.
- *
- * Copyright (C) 2006 Dave Airlie (airlied@linux.ie)
-
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sub license, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial portions
- of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR
- ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "driver.h"
-#include "drm.h"
-
-#include "intel.h"
-#include "i830_dri.h"
-
-#include "memops.h"
-#include "pciaccess.h"
-
-static size_t drm_page_size;
-static int nextTile = 0;
-#define xf86DrvMsg(...) do {} while(0)
-
-static const int pitches[] = {
- 128 * 8,
- 128 * 16,
- 128 * 32,
- 128 * 64,
- 0
-};
-
-static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea);
-
-static unsigned long
-GetBestTileAlignment(unsigned long size)
-{
- unsigned long i;
-
- for (i = KB(512); i < size; i <<= 1)
- ;
-
- if (i > MB(64))
- i = MB(64);
-
- return i;
-}
-
-static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- int i;
- unsigned char *MMIO = ctx->MMIOAddress;
-
- for (i = 0; i < 8; i++) {
- OUTREG(FENCE + i * 4, pI830->Fence[i]);
- // if (I810_DEBUG & DEBUG_VERBOSE_VGA)
- fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]);
- }
-}
-
-/* Tiled memory is good... really, really good...
- *
- * Need to make it less likely that we miss out on this - probably
- * need to move the frontbuffer away from the 'guarenteed' alignment
- * of the first memory segment, or perhaps allocate a discontigous
- * framebuffer to get more alignment 'sweet spots'.
- */
-static void
-SetFence(const DRIDriverContext *ctx, I830Rec *pI830,
- int nr, unsigned int start, unsigned int pitch,
- unsigned int size)
-{
- unsigned int val;
- unsigned int fence_mask = 0;
- unsigned int fence_pitch;
-
- if (nr < 0 || nr > 7) {
- fprintf(stderr,
- "SetFence: fence %d out of range\n",nr);
- return;
- }
-
- pI830->Fence[nr] = 0;
-
- if (IS_I9XX(pI830))
- fence_mask = ~I915G_FENCE_START_MASK;
- else
- fence_mask = ~I830_FENCE_START_MASK;
-
- if (start & fence_mask) {
- fprintf(stderr,
- "SetFence: %d: start (0x%08x) is not %s aligned\n",
- nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
- return;
- }
-
- if (start % size) {
- fprintf(stderr,
- "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n",
- nr, start, size / 1024);
- return;
- }
-
- if (pitch & 127) {
- fprintf(stderr,
- "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n",
- nr, pitch);
- return;
- }
-
- val = (start | FENCE_X_MAJOR | FENCE_VALID);
-
- if (IS_I9XX(pI830)) {
- switch (size) {
- case MB(1):
- val |= I915G_FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= I915G_FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= I915G_FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= I915G_FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= I915G_FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= I915G_FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= I915G_FENCE_SIZE_64M;
- break;
- default:
- fprintf(stderr,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
- }
- } else {
- switch (size) {
- case KB(512):
- val |= FENCE_SIZE_512K;
- break;
- case MB(1):
- val |= FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= FENCE_SIZE_64M;
- break;
- default:
- fprintf(stderr,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
- }
- }
-
- if (IS_I9XX(pI830))
- fence_pitch = pitch / 512;
- else
- fence_pitch = pitch / 128;
-
- switch (fence_pitch) {
- case 1:
- val |= FENCE_PITCH_1;
- break;
- case 2:
- val |= FENCE_PITCH_2;
- break;
- case 4:
- val |= FENCE_PITCH_4;
- break;
- case 8:
- val |= FENCE_PITCH_8;
- break;
- case 16:
- val |= FENCE_PITCH_16;
- break;
- case 32:
- val |= FENCE_PITCH_32;
- break;
- case 64:
- val |= FENCE_PITCH_64;
- break;
- default:
- fprintf(stderr,
- "SetFence: %d: illegal pitch (%d)\n", nr, pitch);
- return;
- }
-
- pI830->Fence[nr] = val;
-}
-
-static Bool
-MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem)
-{
- int pitch, ntiles, i;
-
- pitch = pMem->Pitch * ctx->cpp;
- /*
- * Simply try to break the region up into at most four pieces of size
- * equal to the alignment.
- */
- ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment;
- if (ntiles >= 4) {
- return FALSE;
- }
-
- for (i = 0; i < ntiles; i++, nextTile++) {
- SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment,
- pitch, pMem->Alignment);
- }
- return TRUE;
-}
-
-static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- int i;
-
- /* Clear out */
- for (i = 0; i < 8; i++)
- pI830->Fence[i] = 0;
-
- nextTile = 0;
-
- if (pI830->BackBuffer.Alignment >= KB(512)) {
- if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) {
- fprintf(stderr,
- "Activating tiled memory for the back buffer.\n");
- } else {
- fprintf(stderr,
- "MakeTiles failed for the back buffer.\n");
- pI830->allowPageFlip = FALSE;
- }
- }
-
- if (pI830->DepthBuffer.Alignment >= KB(512)) {
- if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) {
- fprintf(stderr,
- "Activating tiled memory for the depth buffer.\n");
- } else {
- fprintf(stderr,
- "MakeTiles failed for the depth buffer.\n");
- }
- }
-
- return;
-}
-
-static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- struct pci_device host_bridge, ig_dev;
- uint32_t gmch_ctrl;
- int memsize = 0;
- int range;
- uint32_t aper_size;
- uint32_t membase2 = 0;
-
- memset(&host_bridge, 0, sizeof(host_bridge));
- memset(&ig_dev, 0, sizeof(ig_dev));
-
- ig_dev.dev = 2;
-
- pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL);
-
- if (IS_I830(pI830) || IS_845G(pI830)) {
- if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
- aper_size = 0x80000000;
- } else {
- aper_size = 0x40000000;
- }
- } else {
- if (IS_I9XX(pI830)) {
- int ret;
- ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18);
- if (membase2 & 0x08000000)
- aper_size = 0x8000000;
- else
- aper_size = 0x10000000;
-
- fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret);
- } else
- aper_size = 0x8000000;
- }
-
- pI830->aper_size = aper_size;
-
-
- /* We need to reduce the stolen size, by the GTT and the popup.
- * The GTT varying according the the FbMapSize and the popup is 4KB */
- range = (ctx->shared.fbSize / (1024*1024)) + 4;
-
- if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
- switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
- case I855_GMCH_GMS_STOLEN_1M:
- memsize = MB(1) - KB(range);
- break;
- case I855_GMCH_GMS_STOLEN_4M:
- memsize = MB(4) - KB(range);
- break;
- case I855_GMCH_GMS_STOLEN_8M:
- memsize = MB(8) - KB(range);
- break;
- case I855_GMCH_GMS_STOLEN_16M:
- memsize = MB(16) - KB(range);
- break;
- case I855_GMCH_GMS_STOLEN_32M:
- memsize = MB(32) - KB(range);
- break;
- case I915G_GMCH_GMS_STOLEN_48M:
- if (IS_I9XX(pI830))
- memsize = MB(48) - KB(range);
- break;
- case I915G_GMCH_GMS_STOLEN_64M:
- if (IS_I9XX(pI830))
- memsize = MB(64) - KB(range);
- break;
- }
- } else {
- switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
- case I830_GMCH_GMS_STOLEN_512:
- memsize = KB(512) - KB(range);
- break;
- case I830_GMCH_GMS_STOLEN_1024:
- memsize = MB(1) - KB(range);
- break;
- case I830_GMCH_GMS_STOLEN_8192:
- memsize = MB(8) - KB(range);
- break;
- case I830_GMCH_GMS_LOCAL:
- memsize = 0;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Local memory found, but won't be used.\n");
- break;
- }
- }
- if (memsize > 0) {
- fprintf(stderr,
- "detected %d kB stolen memory.\n", memsize / 1024);
- } else {
- fprintf(stderr,
- "no video memory detected.\n");
- }
- return memsize;
-}
-
-static int AgpInit(const DRIDriverContext *ctx, I830Rec *info)
-{
- unsigned long mode = 0x4;
-
- if (drmAgpAcquire(ctx->drmFD) < 0) {
- fprintf(stderr, "[gart] AGP not available\n");
- return 0;
- }
-
- if (drmAgpEnable(ctx->drmFD, mode) < 0) {
- fprintf(stderr, "[gart] AGP not enabled\n");
- drmAgpRelease(ctx->drmFD);
- return 0;
- }
- else
- fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode);
-
- return 1;
-}
-
-/*
- * Allocate memory from the given pool. Grow the pool if needed and if
- * possible.
- */
-static unsigned long
-AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830,
- I830MemRange *result, I830MemPool *pool,
- long size, unsigned long alignment, int flags)
-{
- long needed, start, end;
-
- if (!result || !pool || !size)
- return 0;
-
- /* Calculate how much space is needed. */
- if (alignment <= GTT_PAGE_SIZE)
- needed = size;
- else {
- start = ROUND_TO(pool->Free.Start, alignment);
- end = ROUND_TO(start + size, alignment);
- needed = end - pool->Free.Start;
- }
- if (needed > pool->Free.Size) {
- return 0;
- }
-
- result->Start = ROUND_TO(pool->Free.Start, alignment);
- pool->Free.Start += needed;
- result->End = pool->Free.Start;
-
- pool->Free.Size = pool->Free.End - pool->Free.Start;
- result->Size = result->End - result->Start;
- result->Pool = pool;
- result->Alignment = alignment;
- return needed;
-}
-
-static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result)
-{
- unsigned long start, end;
- unsigned long newApStart, newApEnd;
- int ret;
- if (!result || !size)
- return 0;
-
- if (!alignment)
- alignment = 4;
-
- start = ROUND_TO(pI830->MemoryAperture.Start, alignment);
- end = ROUND_TO(start + size, alignment);
- newApStart = end;
- newApEnd = pI830->MemoryAperture.End;
-
- ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key));
-
- if (ret)
- {
- fprintf(stderr,"drmAgpAlloc failed %d\n", ret);
- return 0;
- }
- pI830->allocatedMemory += size;
- pI830->MemoryAperture.Start = newApStart;
- pI830->MemoryAperture.End = newApEnd;
- pI830->MemoryAperture.Size = newApEnd - newApStart;
- // pI830->FreeMemory -= size;
- result->Start = start;
- result->End = start + size;
- result->Size = size;
- result->Offset = start;
- result->Alignment = alignment;
- result->Pool = NULL;
-
- return size;
-}
-
-unsigned long
-I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830,
- I830MemRange *result, I830MemPool *pool, long size,
- unsigned long alignment, int flags)
-{
- unsigned long ret;
-
- if (!result)
- return 0;
-
- /* Make sure these are initialised. */
- result->Size = 0;
- result->Key = -1;
-
- if (!size) {
- return 0;
- }
-
- if (pool->Free.Size < size) {
- ret = AllocFromAGP(ctx, pI830, size, alignment, result);
- }
- else {
- ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags);
- if (ret == 0)
- ret = AllocFromAGP(ctx, pI830, size, alignment, result);
- }
- return ret;
-}
-
-static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem)
-{
- if (!mem)
- return FALSE;
-
- if (mem->Key == -1)
- return TRUE;
-
- return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset);
-}
-
-/* simple memory allocation routines needed */
-/* put ring buffer in low memory */
-/* need to allocate front, back, depth buffers aligned correctly,
- allocate ring buffer,
-*/
-
-/* */
-static Bool
-I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- unsigned long size, ret;
- unsigned long lines, lineSize, align;
-
- /* allocate ring buffer */
- memset(pI830->LpRing, 0, sizeof(I830RingBuffer));
- pI830->LpRing->mem.Key = -1;
-
- size = PRIMARY_RINGBUFFER_SIZE;
-
- ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0);
-
- if (ret != size)
- {
- fprintf(stderr,"unable to allocate ring buffer %ld\n", ret);
- return FALSE;
- }
-
- pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1;
-
-
- /* allocate front buffer */
- memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
- pI830->FrontBuffer.Key = -1;
- pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth;
-
- align = KB(512);
-
- lineSize = ctx->shared.virtualWidth * ctx->cpp;
- lines = (ctx->shared.virtualHeight + 15) / 16 * 16;
- size = lineSize * lines;
- size = ROUND_TO_PAGE(size);
-
- align = GetBestTileAlignment(size);
-
- ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0);
- if (ret < size)
- {
- fprintf(stderr,"unable to allocate front buffer %ld\n", ret);
- return FALSE;
- }
-
- memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
- pI830->BackBuffer.Key = -1;
- pI830->BackBuffer.Pitch = ctx->shared.virtualWidth;
-
- ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0);
- if (ret < size)
- {
- fprintf(stderr,"unable to allocate back buffer %ld\n", ret);
- return FALSE;
- }
-
- memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
- pI830->DepthBuffer.Key = -1;
- pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth;
-
- ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0);
- if (ret < size)
- {
- fprintf(stderr,"unable to allocate depth buffer %ld\n", ret);
- return FALSE;
- }
-
- memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
- pI830->ContextMem.Key = -1;
- size = KB(32);
-
- ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0);
- if (ret < size)
- {
- fprintf(stderr,"unable to allocate context buffer %ld\n", ret);
- return FALSE;
- }
-
-#if 0
- memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
- pI830->TexMem.Key = -1;
-
- size = 32768 * 1024;
- ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem);
- if (ret < size)
- {
- fprintf(stderr,"unable to allocate texture memory %ld\n", ret);
- return FALSE;
- }
-#endif
-
- return TRUE;
-}
-
-static Bool
-I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- if (!BindAgpRange(ctx, &pI830->LpRing->mem))
- return FALSE;
- if (!BindAgpRange(ctx, &pI830->FrontBuffer))
- return FALSE;
- if (!BindAgpRange(ctx, &pI830->BackBuffer))
- return FALSE;
- if (!BindAgpRange(ctx, &pI830->DepthBuffer))
- return FALSE;
- if (!BindAgpRange(ctx, &pI830->ContextMem))
- return FALSE;
-#if 0
- if (!BindAgpRange(ctx, &pI830->TexMem))
- return FALSE;
-#endif
- return TRUE;
-}
-
-static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
- unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
-
- fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize);
- if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) {
- fprintf(stderr,
- "DRM MM Initialization Failed\n");
- } else {
- fprintf(stderr,
- "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart);
- }
-
-}
-
-static Bool
-I830CleanupDma(const DRIDriverContext *ctx)
-{
- drmI830Init info;
-
- memset(&info, 0, sizeof(drmI830Init));
- info.func = I830_CLEANUP_DMA;
-
- if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
- &info, sizeof(drmI830Init))) {
- fprintf(stderr, "I830 Dma Cleanup Failed\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static Bool
-I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- I830RingBuffer *ring = pI830->LpRing;
- drmI830Init info;
-
- memset(&info, 0, sizeof(drmI830Init));
- info.func = I830_INIT_DMA;
-
- info.ring_start = ring->mem.Start + pI830->LinearAddr;
- info.ring_end = ring->mem.End + pI830->LinearAddr;
- info.ring_size = ring->mem.Size;
-
- info.mmio_offset = (unsigned int)ctx->MMIOStart;
-
- info.sarea_priv_offset = sizeof(drm_sarea_t);
-
- info.front_offset = pI830->FrontBuffer.Start;
- info.back_offset = pI830->BackBuffer.Start;
- info.depth_offset = pI830->DepthBuffer.Start;
- info.w = ctx->shared.virtualWidth;
- info.h = ctx->shared.virtualHeight;
- info.pitch = ctx->shared.virtualWidth;
- info.back_pitch = pI830->BackBuffer.Pitch;
- info.depth_pitch = pI830->DepthBuffer.Pitch;
- info.cpp = ctx->cpp;
-
- if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
- &info, sizeof(drmI830Init))) {
- fprintf(stderr,
- "I830 Dma Initialization Failed\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int I830CheckDRMVersion( const DRIDriverContext *ctx,
- I830Rec *pI830 )
-{
- drmVersionPtr version;
-
- version = drmGetVersion(ctx->drmFD);
-
- if (version) {
- int req_minor, req_patch;
-
- req_minor = 4;
- req_patch = 0;
-
- if (version->version_major != 1 ||
- version->version_minor < req_minor ||
- (version->version_minor == req_minor &&
- version->version_patchlevel < req_patch)) {
- /* Incompatible drm version */
- fprintf(stderr,
- "[dri] I830DRIScreenInit failed because of a version "
- "mismatch.\n"
- "[dri] i915.o kernel module version is %d.%d.%d "
- "but version 1.%d.%d or newer is needed.\n"
- "[dri] Disabling DRI.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel,
- req_minor,
- req_patch);
- drmFreeVersion(version);
- return 0;
- }
-
- pI830->drmMinor = version->version_minor;
- drmFreeVersion(version);
- }
- return 1;
-}
-
-static void
-I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- unsigned int itemp;
- unsigned char *MMIO = ctx->MMIOAddress;
-
- OUTREG(LP_RING + RING_LEN, 0);
- OUTREG(LP_RING + RING_TAIL, 0);
- OUTREG(LP_RING + RING_HEAD, 0);
-
- if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
- pI830->LpRing->mem.Start) {
- fprintf(stderr,
- "I830SetRingRegs: Ring buffer start (%lx) violates its "
- "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
- }
- /* Don't care about the old value. Reserved bits must be zero anyway. */
- itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
- OUTREG(LP_RING + RING_START, itemp);
-
- if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
- pI830->LpRing->mem.Size - 4096) {
- fprintf(stderr,
- "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
- "mask (%x)\n", pI830->LpRing->mem.Size - 4096,
- I830_RING_NR_PAGES);
- }
- /* Don't care about the old value. Reserved bits must be zero anyway. */
- itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
- itemp |= (RING_NO_REPORT | RING_VALID);
- OUTREG(LP_RING + RING_LEN, itemp);
-
- pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
- pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
- pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
- if (pI830->LpRing->space < 0)
- pI830->LpRing->space += pI830->LpRing->mem.Size;
-
- SetFenceRegs(ctx, pI830);
-
- /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky
- hacky hacky */
- OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr);
-
-}
-
-static Bool
-I830SetParam(const DRIDriverContext *ctx, int param, int value)
-{
- drmI830SetParam sp;
-
- memset(&sp, 0, sizeof(sp));
- sp.param = param;
- sp.value = value;
-
- if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) {
- fprintf(stderr, "I830 SetParam Failed\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static Bool
-I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
-{
- fprintf(stderr,
- "[drm] Mapping front buffer\n");
-
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
- sarea->front_size,
- DRM_FRAME_BUFFER, /*DRM_AGP,*/
- 0,
- &sarea->front_handle) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
- return FALSE;
- }
- ctx->shared.hFrameBuffer = sarea->front_handle;
- ctx->shared.fbSize = sarea->front_size;
- fprintf(stderr, "[drm] Front Buffer = 0x%08x\n",
- sarea->front_handle);
-
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)(sarea->back_offset),
- sarea->back_size, DRM_AGP, 0,
- &sarea->back_handle) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(back_handle) failed. Disabling DRI\n");
- return FALSE;
- }
- fprintf(stderr, "[drm] Back Buffer = 0x%08x\n",
- sarea->back_handle);
-
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)sarea->depth_offset,
- sarea->depth_size, DRM_AGP, 0,
- &sarea->depth_handle) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
- return FALSE;
- }
- fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n",
- sarea->depth_handle);
-
-#if 0
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)sarea->tex_offset,
- sarea->tex_size, DRM_AGP, 0,
- &sarea->tex_handle) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
- return FALSE;
- }
- fprintf(stderr, "[drm] textures = 0x%08x\n",
- sarea->tex_handle);
-#endif
- return TRUE;
-}
-
-
-static void
-I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
-{
-#if 1
- if (sarea->front_handle) {
- drmRmMap(ctx->drmFD, sarea->front_handle);
- sarea->front_handle = 0;
- }
-#endif
- if (sarea->back_handle) {
- drmRmMap(ctx->drmFD, sarea->back_handle);
- sarea->back_handle = 0;
- }
- if (sarea->depth_handle) {
- drmRmMap(ctx->drmFD, sarea->depth_handle);
- sarea->depth_handle = 0;
- }
- if (sarea->tex_handle) {
- drmRmMap(ctx->drmFD, sarea->tex_handle);
- sarea->tex_handle = 0;
- }
-}
-
-static Bool
-I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
-{
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)pI830->LpRing->mem.Start,
- pI830->LpRing->mem.Size, DRM_AGP, 0,
- &pI830->ring_map) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(ring_map) failed. Disabling DRI\n");
- return FALSE;
- }
- fprintf(stderr, "[drm] ring buffer = 0x%08x\n",
- pI830->ring_map);
-
- if (I830InitDma(ctx, pI830) == FALSE) {
- return FALSE;
- }
-
- /* init to zero to be safe */
-
- I830DRIMapScreenRegions(ctx, pI830, sarea);
- SetupDRIMM(ctx, pI830);
-
- if (ctx->pciDevice != PCI_CHIP_845_G &&
- ctx->pciDevice != PCI_CHIP_I830_M) {
- I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 );
- }
-
- /* Okay now initialize the dma engine */
- {
- pI830->irq = drmGetInterruptFromBusID(ctx->drmFD,
- ctx->pciBus,
- ctx->pciDevice,
- ctx->pciFunc);
-
- if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) {
- fprintf(stderr,
- "[drm] failure adding irq handler\n");
- pI830->irq = 0;
- return FALSE;
- }
- else
- fprintf(stderr,
- "[drm] dma control initialized, using IRQ %d\n",
- pI830->irq);
- }
-
- fprintf(stderr, "[dri] visual configs initialized\n");
-
- return TRUE;
-}
-
-static Bool
-I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
-{
- /* need to drmMap front and back buffers and zero them */
- drmAddress map_addr;
- int ret;
-
- ret = drmMap(ctx->drmFD,
- sarea->front_handle,
- sarea->front_size,
- &map_addr);
-
- if (ret)
- {
- fprintf(stderr, "Unable to map front buffer\n");
- return FALSE;
- }
-
- drimemsetio((char *)map_addr,
- 0,
- sarea->front_size);
- drmUnmap(map_addr, sarea->front_size);
-
-
- ret = drmMap(ctx->drmFD,
- sarea->back_handle,
- sarea->back_size,
- &map_addr);
-
- if (ret)
- {
- fprintf(stderr, "Unable to map back buffer\n");
- return FALSE;
- }
-
- drimemsetio((char *)map_addr,
- 0,
- sarea->back_size);
- drmUnmap(map_addr, sarea->back_size);
-
- return TRUE;
-}
-
-static Bool
-I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
-
-{
- I830DRIPtr pI830DRI;
- drmI830Sarea *pSAREAPriv;
- int err;
-
- drm_page_size = getpagesize();
-
- pI830->registerSize = ctx->MMIOSize;
- /* This is a hack for now. We have to have more than a 4k page here
- * because of the size of the state. However, the state should be
- * in a per-context mapping. This will be added in the Mesa 3.5 port
- * of the I830 driver.
- */
- ctx->shared.SAREASize = SAREA_MAX;
-
- /* Note that drmOpen will try to load the kernel module, if needed. */
- ctx->drmFD = drmOpen("i915", NULL );
- if (ctx->drmFD < 0) {
- fprintf(stderr, "[drm] drmOpen failed\n");
- return 0;
- }
-
- if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
- fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
- ctx->drmFD, ctx->pciBusID, strerror(-err));
- return 0;
- }
-
- if (drmAddMap( ctx->drmFD,
- 0,
- ctx->shared.SAREASize,
- DRM_SHM,
- DRM_CONTAINS_LOCK,
- &ctx->shared.hSAREA) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap failed\n");
- return 0;
- }
-
- fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n",
- ctx->shared.SAREASize, ctx->shared.hSAREA);
-
- if (drmMap( ctx->drmFD,
- ctx->shared.hSAREA,
- ctx->shared.SAREASize,
- (drmAddressPtr)(&ctx->pSAREA)) < 0)
- {
- fprintf(stderr, "[drm] drmMap failed\n");
- return 0;
-
- }
-
- memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
- fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n",
- ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
-
-
- if (drmAddMap(ctx->drmFD,
- ctx->MMIOStart,
- ctx->MMIOSize,
- DRM_REGISTERS,
- DRM_READ_ONLY,
- &pI830->registerHandle) < 0) {
- fprintf(stderr, "[drm] drmAddMap mmio failed\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] register handle = 0x%08x\n", pI830->registerHandle);
-
-
- if (!I830CheckDRMVersion(ctx, pI830)) {
- return FALSE;
- }
-
- /* Create a 'server' context so we can grab the lock for
- * initialization ioctls.
- */
- if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
- fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
- return 0;
- }
-
- DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
-
- /* Initialize the SAREA private data structure */
- pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
- memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
-
- pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830);
- pI830->StolenMemory.Start = 0;
- pI830->StolenMemory.End = pI830->StolenMemory.Size;
-
- pI830->MemoryAperture.Start = pI830->StolenMemory.End;
- pI830->MemoryAperture.End = KB(40000);
- pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start;
-
- pI830->StolenPool.Fixed = pI830->StolenMemory;
- pI830->StolenPool.Total = pI830->StolenMemory;
- pI830->StolenPool.Free = pI830->StolenPool.Total;
- pI830->FreeMemory = pI830->StolenPool.Total.Size;
-
- if (!AgpInit(ctx, pI830))
- return FALSE;
-
- if (I830AllocateMemory(ctx, pI830) == FALSE)
- {
- return FALSE;
- }
-
- if (I830BindMemory(ctx, pI830) == FALSE)
- {
- return FALSE;
- }
-
- pSAREAPriv->rotated_offset = -1;
- pSAREAPriv->rotated_size = 0;
- pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth;
-
- pSAREAPriv->front_offset = pI830->FrontBuffer.Start;
- pSAREAPriv->front_size = pI830->FrontBuffer.Size;
- pSAREAPriv->width = ctx->shared.virtualWidth;
- pSAREAPriv->height = ctx->shared.virtualHeight;
- pSAREAPriv->pitch = ctx->shared.virtualWidth;
- pSAREAPriv->virtualX = ctx->shared.virtualWidth;
- pSAREAPriv->virtualY = ctx->shared.virtualHeight;
- pSAREAPriv->back_offset = pI830->BackBuffer.Start;
- pSAREAPriv->back_size = pI830->BackBuffer.Size;
- pSAREAPriv->depth_offset = pI830->DepthBuffer.Start;
- pSAREAPriv->depth_size = pI830->DepthBuffer.Size;
-#if 0
- pSAREAPriv->tex_offset = pI830->TexMem.Start;
- pSAREAPriv->tex_size = pI830->TexMem.Size;
-#endif
- pSAREAPriv->log_tex_granularity = pI830->TexGranularity;
-
- ctx->driverClientMsg = malloc(sizeof(I830DRIRec));
- ctx->driverClientMsgSize = sizeof(I830DRIRec);
- pI830DRI = (I830DRIPtr)ctx->driverClientMsg;
- pI830DRI->deviceID = pI830->Chipset;
- pI830DRI->regsSize = I830_REG_SIZE;
- pI830DRI->width = ctx->shared.virtualWidth;
- pI830DRI->height = ctx->shared.virtualHeight;
- pI830DRI->mem = ctx->shared.fbSize;
- pI830DRI->cpp = ctx->cpp;
-
- pI830DRI->bitsPerPixel = ctx->bpp;
- pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t);
-
- err = I830DRIDoMappings(ctx, pI830, pSAREAPriv);
- if (err == FALSE)
- return FALSE;
-
- I830SetupMemoryTiling(ctx, pI830);
-
- /* Quick hack to clear the front & back buffers. Could also use
- * the clear ioctl to do this, but would need to setup hw state
- * first.
- */
- I830ClearScreen(ctx, pI830, pSAREAPriv);
-
- I830SetRingRegs(ctx, pI830);
-
- return TRUE;
-}
-
-
-/**
- * \brief Validate the fbdev mode.
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Saves some registers and returns 1.
- *
- * \sa radeonValidateMode().
- */
-static int i830ValidateMode( const DRIDriverContext *ctx )
-{
- return 1;
-}
-
-/**
- * \brief Examine mode returned by fbdev.
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Restores registers that fbdev has clobbered and returns 1.
- *
- * \sa i810ValidateMode().
- */
-static int i830PostValidateMode( const DRIDriverContext *ctx )
-{
- I830Rec *pI830 = ctx->driverPrivate;
-
- I830SetRingRegs(ctx, pI830);
- return 1;
-}
-
-
-/**
- * \brief Initialize the framebuffer device mode
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Fills in \p info with some default values and some information from \p ctx
- * and then calls I810ScreenInit() for the screen initialization.
- *
- * Before exiting clears the framebuffer memory accessing it directly.
- */
-static int i830InitFBDev( DRIDriverContext *ctx )
-{
- I830Rec *pI830 = calloc(1, sizeof(I830Rec));
- int i;
-
- {
- int dummy = ctx->shared.virtualWidth;
-
- switch (ctx->bpp / 8) {
- case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
- case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
- case 3:
- case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
- }
-
- ctx->shared.virtualWidth = dummy;
- ctx->shared.Width = ctx->shared.virtualWidth;
- }
-
-
- for (i = 0; pitches[i] != 0; i++) {
- if (pitches[i] >= ctx->shared.virtualWidth) {
- ctx->shared.virtualWidth = pitches[i];
- break;
- }
- }
-
- ctx->driverPrivate = (void *)pI830;
-
- pI830->LpRing = calloc(1, sizeof(I830RingBuffer));
- pI830->Chipset = ctx->chipset;
- pI830->LinearAddr = ctx->FBStart;
-
- if (!I830ScreenInit( ctx, pI830 ))
- return 0;
-
-
- return 1;
-}
-
-
-/**
- * \brief The screen is being closed, so clean up any state and free any
- * resources used by the DRI.
- *
- * \param ctx display handle.
- *
- * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
- * private data.
- */
-static void i830HaltFBDev( DRIDriverContext *ctx )
-{
- drmI830Sarea *pSAREAPriv;
- I830Rec *pI830 = ctx->driverPrivate;
-
- if (pI830->irq) {
- drmCtlUninstHandler(ctx->drmFD);
- pI830->irq = 0; }
-
- I830CleanupDma(ctx);
-
- pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
-
- I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv);
- drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
- drmClose(ctx->drmFD);
-
- if (ctx->driverPrivate) {
- free(ctx->driverPrivate);
- ctx->driverPrivate = 0;
- }
-}
-
-
-extern void i810NotifyFocus( int );
-
-/**
- * \brief Exported driver interface for Mini GLX.
- *
- * \sa DRIDriverRec.
- */
-const struct DRIDriverRec __driDriver = {
- i830ValidateMode,
- i830PostValidateMode,
- i830InitFBDev,
- i830HaltFBDev,
- NULL,//I830EngineShutdown,
- NULL, //I830EngineRestore,
-#ifndef _EMBEDDED
- 0,
-#else
- i810NotifyFocus,
-#endif
-};
+../intel/server/intel_dri.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 7e07bc9c1a..d7a2b46e1c 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -69,6 +69,7 @@ DRIVER_SOURCES = \
brw_wm_emit.c \
brw_wm_fp.c \
brw_wm_iz.c \
+ brw_wm_glsl.c \
brw_wm_pass0.c \
brw_wm_pass1.c \
brw_wm_pass2.c \
@@ -76,12 +77,6 @@ DRIVER_SOURCES = \
brw_wm_state.c \
brw_wm_surface_state.c
-SYMLINKS = \
- server/i830_dri.h \
- server/i830_common.h \
- server/intel_dri.c \
- server/intel.h
-
C_SOURCES = \
$(COMMON_SOURCES) \
$(MINIGLX_SOURCES) \
@@ -89,17 +84,10 @@ C_SOURCES = \
ASM_SOURCES =
-DRIVER_DEFINES = -I../intel
+DRIVER_DEFINES = -I../intel -I../intel/server
include ../Makefile.template
+symlinks:
intel_decode.o: ../intel/intel_decode.c
intel_tex_layout.o: ../intel/intel_tex_layout.c
-
-server:
- mkdir -p server
-
-$(SYMLINKS): server
- @[ -e $@ ] || ln -sf ../../i915/$@ server/
-
-symlinks: $(SYMLINKS)
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index 49b2770a51..2a65697325 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -42,7 +42,7 @@
* up polygon offset and flatshading at this point:
*/
struct brw_clip_prog_key {
- GLuint attrs:16;
+ GLuint attrs:32;
GLuint primitive:4;
GLuint nr_userclip:3;
GLuint do_flat_shading:1;
@@ -51,7 +51,7 @@ struct brw_clip_prog_key {
GLuint fill_ccw:2; /* includes cull information */
GLuint offset_cw:1;
GLuint offset_ccw:1;
- GLuint pad0:1;
+ GLuint pad0:17;
GLuint copy_bfc_cw:1;
GLuint copy_bfc_ccw:1;
diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c
index ae46d7a86e..ba2f0edf51 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_state.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_state.c
@@ -43,7 +43,8 @@ static void upload_clip_unit( struct brw_context *brw )
memset(&clip, 0, sizeof(clip));
/* CACHE_NEW_CLIP_PROG */
- clip.thread0.grf_reg_count = ((brw->clip.prog_data->total_grf-1) & ~15) / 16;
+ clip.thread0.grf_reg_count =
+ ALIGN(brw->clip.prog_data->total_grf, 16) / 16 - 1;
clip.thread0.kernel_start_pointer = brw->clip.prog_gs_offset >> 6;
clip.thread3.urb_entry_read_length = brw->clip.prog_data->urb_read_length;
clip.thread3.const_urb_entry_read_length = brw->clip.prog_data->curb_read_length;
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 0ccdd8a661..6231cba3f9 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -43,6 +43,8 @@
#include "api_noop.h"
#include "vtxfmt.h"
+#include "shader/shader_api.h"
+
/***************************************
* Mesa's Driver Functions
***************************************/
@@ -59,12 +61,37 @@ static const struct dri_extension brw_extensions[] =
{ NULL, NULL }
};
+static void brwUseProgram(GLcontext *ctx, GLuint program)
+{
+ struct brw_context *brw = brw_context(ctx);
+ struct gl_shader_program *sh_prog;
+ _mesa_use_program(ctx, program);
+ sh_prog = ctx->Shader.CurrentProgram;
+ if (sh_prog) {
+ if (sh_prog->VertexProgram) {
+ brw->attribs.VertexProgram->Current = sh_prog->VertexProgram;
+ ctx->VertexProgram.Enabled = GL_TRUE;
+ }else
+ ctx->VertexProgram.Enabled = GL_FALSE;
+
+ if (sh_prog->FragmentProgram) {
+ brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
+ ctx->FragmentProgram.Enabled = GL_TRUE;
+ } else
+ ctx->FragmentProgram.Enabled = GL_FALSE;
+ }
+}
+static void brwInitProgFuncs( struct dd_function_table *functions )
+{
+ functions->UseProgram = brwUseProgram;
+}
static void brwInitDriverFunctions( struct dd_function_table *functions )
{
intelInitDriverFunctions( functions );
brwInitTextureFuncs( functions );
brwInitFragProgFuncs( functions );
+ brwInitProgFuncs( functions );
}
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index d3c88c1dca..fa4ea42aa6 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -304,7 +304,7 @@ static void upload_constant_buffer(struct brw_context *brw)
if (!brw_pool_alloc(pool,
bufsz,
- 6,
+ 1 << 6,
&brw->curbe.gs_offset)) {
_mesa_printf("out of GS memory for curbe\n");
assert(0);
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index fc2e3035af..b7795703fd 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -290,7 +290,7 @@ static void get_space( struct brw_context *brw,
struct gl_buffer_object **vbo_return,
GLuint *offset_return )
{
- size = (size + 63) & ~63;
+ size = ALIGN(size, 64);
if (brw->vb.upload.offset + size > BRW_UPLOAD_INIT_SIZE)
wrap_buffers(brw, size);
@@ -541,7 +541,8 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
for (i = 0; i < nr_enabled; i++) {
OUT_BATCH( vbp.vb[i].vb0.dword );
- OUT_BATCH( bmBufferOffset(&brw->intel, vbp.vb[i].buffer) + vbp.vb[i].offset);
+ OUT_RELOC( vbp.vb[i].buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ vbp.vb[i].offset);
OUT_BATCH( vbp.vb[i].max_index );
OUT_BATCH( vbp.vb[i].instance_data_step_rate );
}
@@ -632,8 +633,9 @@ void brw_upload_indices( struct brw_context *brw,
BEGIN_BATCH(4, 0);
OUT_BATCH( ib.header.dword );
- OUT_BATCH( bmBufferOffset(intel, buffer) + offset );
- OUT_BATCH( bmBufferOffset(intel, buffer) + offset + ib_size );
+ OUT_RELOC( buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, offset);
+ OUT_RELOC( buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ offset + ib_size);
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 52f89d577c..5c98767c3e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -648,6 +648,11 @@ static __inline struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
}
+static __inline struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
+{
+ return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
+}
+
static __inline struct brw_reg get_addr_reg(struct brw_indirect ptr)
{
return brw_address_reg(ptr.addr_subnr);
@@ -668,7 +673,10 @@ static __inline struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offse
return ptr;
}
-
+static __inline struct brw_instruction *current_insn( struct brw_compile *p)
+{
+ return &p->store[p->nr_insn];
+}
void brw_pop_insn_state( struct brw_compile *p );
void brw_push_insn_state( struct brw_compile *p );
@@ -808,9 +816,11 @@ void brw_ENDIF(struct brw_compile *p,
struct brw_instruction *brw_DO(struct brw_compile *p,
GLuint execute_size);
-void brw_WHILE(struct brw_compile *p,
+struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *patch_insn);
+struct brw_instruction *brw_BREAK(struct brw_compile *p);
+struct brw_instruction *brw_CONT(struct brw_compile *p);
/* Forward jumps:
*/
void brw_land_fwd_jump(struct brw_compile *p,
@@ -860,5 +870,6 @@ void brw_math_invert( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg src);
-
+void brw_set_src1( struct brw_instruction *insn,
+ struct brw_reg reg );
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 9992b47d8a..95f9f02753 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -164,7 +164,7 @@ static void brw_set_src0( struct brw_instruction *insn,
}
-static void brw_set_src1( struct brw_instruction *insn,
+void brw_set_src1( struct brw_instruction *insn,
struct brw_reg reg )
{
assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
@@ -186,7 +186,7 @@ static void brw_set_src1( struct brw_instruction *insn,
* in the future:
*/
assert (reg.address_mode == BRW_ADDRESS_DIRECT);
- assert (reg.file == BRW_GENERAL_REGISTER_FILE);
+ //assert (reg.file == BRW_GENERAL_REGISTER_FILE);
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits3.da1.src1_subreg_nr = reg.subnr;
@@ -597,6 +597,34 @@ void brw_ENDIF(struct brw_compile *p,
}
}
+struct brw_instruction *brw_BREAK(struct brw_compile *p)
+{
+ struct brw_instruction *insn;
+ insn = next_insn(p, BRW_OPCODE_BREAK);
+ brw_set_dest(insn, brw_ip_reg());
+ brw_set_src0(insn, brw_ip_reg());
+ brw_set_src1(insn, brw_imm_d(0x0));
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = BRW_EXECUTE_8;
+ insn->header.mask_control = BRW_MASK_DISABLE;
+ insn->bits3.if_else.pad0 = 0;
+ return insn;
+}
+
+struct brw_instruction *brw_CONT(struct brw_compile *p)
+{
+ struct brw_instruction *insn;
+ insn = next_insn(p, BRW_OPCODE_CONTINUE);
+ brw_set_dest(insn, brw_ip_reg());
+ brw_set_src0(insn, brw_ip_reg());
+ brw_set_src1(insn, brw_imm_d(0x0));
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = BRW_EXECUTE_8;
+ insn->header.mask_control = BRW_MASK_DISABLE;
+ insn->bits3.if_else.pad0 = 0;
+ return insn;
+}
+
/* DO/WHILE loop:
*/
struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
@@ -608,13 +636,15 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
/* Override the defaults for this instruction:
*/
- brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
+ brw_set_dest(insn, brw_null_reg());
+ brw_set_src0(insn, brw_null_reg());
+ brw_set_src1(insn, brw_null_reg());
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = execute_size;
+ insn->header.predicate_control = BRW_PREDICATE_NONE;
/* insn->header.mask_control = BRW_MASK_ENABLE; */
+ insn->header.mask_control = BRW_MASK_DISABLE;
return insn;
}
@@ -622,7 +652,7 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
-void brw_WHILE(struct brw_compile *p,
+struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *do_insn)
{
struct brw_instruction *insn;
@@ -653,7 +683,9 @@ void brw_WHILE(struct brw_compile *p,
/* insn->header.mask_control = BRW_MASK_ENABLE; */
+ insn->header.mask_control = BRW_MASK_DISABLE;
p->current->header.predicate_control = BRW_PREDICATE_NONE;
+ return insn;
}
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index 29a4e80ce1..18a4537c32 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -40,11 +40,11 @@
#define MAX_GS_VERTS (4)
struct brw_gs_prog_key {
+ GLuint attrs:32;
GLuint primitive:4;
- GLuint attrs:16;
GLuint hint_gs_always:1;
GLuint need_gs_prog:1;
- GLuint pad:10;
+ GLuint pad:26;
};
struct brw_gs_compile {
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index 5826c01d4f..5db4dd4603 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -46,7 +46,8 @@ static void upload_gs_unit( struct brw_context *brw )
/* CACHE_NEW_GS_PROG */
if (brw->gs.prog_active) {
- gs.thread0.grf_reg_count = ((brw->gs.prog_data->total_grf-1) & ~15) / 16;
+ gs.thread0.grf_reg_count =
+ ALIGN(brw->gs.prog_data->total_grf, 16) / 16 - 1;
gs.thread0.kernel_start_pointer = brw->gs.prog_gs_offset >> 6;
gs.thread3.urb_entry_read_length = brw->gs.prog_data->urb_read_length;
}
diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h
index e8946511dd..385f1eea13 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.h
+++ b/src/mesa/drivers/dri/i965/brw_sf.h
@@ -45,10 +45,10 @@
#define SF_UNFILLED_TRIS 3
struct brw_sf_prog_key {
+ GLuint attrs:32;
GLuint primitive:2;
GLuint do_twoside_color:1;
GLuint do_flat_shading:1;
- GLuint attrs:16;
GLuint frontface_ccw:1;
GLuint do_point_sprite:1;
GLuint pad:10;
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index 236c6fd42a..2257916aae 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -118,7 +118,7 @@ static void upload_sf_unit( struct brw_context *brw )
memset(&sf, 0, sizeof(sf));
/* CACHE_NEW_SF_PROG */
- sf.thread0.grf_reg_count = ((brw->sf.prog_data->total_grf-1) & ~15) / 16;
+ sf.thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
sf.thread0.kernel_start_pointer = brw->sf.prog_gs_offset >> 6;
sf.thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length;
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index 98d765ac0e..0e73ff8390 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -148,7 +148,7 @@ GLuint brw_upload_cache( struct brw_cache *cache,
GLuint hash = hash_key(key, key_size);
void *tmp = _mesa_malloc(key_size + cache->aux_size);
- if (!brw_pool_alloc(cache->pool, data_size, 6, &offset)) {
+ if (!brw_pool_alloc(cache->pool, data_size, 1 << 6, &offset)) {
/* Should not be possible:
*/
_mesa_printf("brw_pool_alloc failed\n");
diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c
index 708ae857ab..eda92a2fa8 100644
--- a/src/mesa/drivers/dri/i965/brw_state_pool.c
+++ b/src/mesa/drivers/dri/i965/brw_state_pool.c
@@ -41,10 +41,9 @@ GLboolean brw_pool_alloc( struct brw_mem_pool *pool,
GLuint align,
GLuint *offset_return)
{
- GLuint align_mask = (1<<align)-1;
- GLuint fixup = ((pool->offset + align_mask) & ~align_mask) - pool->offset;
+ GLuint fixup = ALIGN(pool->offset, align) - pool->offset;
- size = (size + 3) & ~3;
+ size = ALIGN(size, 4);
if (pool->offset + fixup + size >= pool->size) {
_mesa_printf("%s failed\n", __FUNCTION__);
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 2094a1c8ad..e306c9cf10 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -37,8 +37,6 @@
#include "intel_tex_layout.h"
#include "macros.h"
-#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
-
GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt )
{
/* XXX: these vary depending on image format:
@@ -64,7 +62,7 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt )
mt->pitch = ALIGN(width, align_w);
pack_y_pitch = (height + 3) / 4;
} else {
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
+ mt->pitch = ALIGN(mt->width0 * mt->cpp, 4) / mt->cpp;
pack_y_pitch = ALIGN(mt->height0, align_h);
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index 8843f816f9..41a33ffe38 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -67,6 +67,12 @@ struct brw_vs_compile {
struct brw_reg r1;
struct brw_reg regs[PROGRAM_ADDRESS+1][128];
struct brw_reg tmp;
+ struct brw_reg stack;
+
+ struct {
+ GLboolean used_in_src;
+ struct brw_reg reg;
+ } output_regs[128];
struct brw_reg userplane[6];
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 8733b470c2..e62de186ae 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -134,6 +134,16 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
WRITEMASK_X);
reg++;
}
+
+ for (i = 0; i < 128; i++) {
+ if (c->output_regs[i].used_in_src) {
+ c->output_regs[i].reg = brw_vec8_grf(reg, 0);
+ reg++;
+ }
+ }
+
+ c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
+ reg += 2;
/* Some opcodes need an internal temporary:
@@ -213,57 +223,68 @@ static void unalias2( struct brw_vs_compile *c,
}
}
+static void emit_sop( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1,
+ GLuint cond)
+{
+ brw_push_insn_state(p);
+ brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_MOV(p, dst, brw_imm_f(1.0f));
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, brw_imm_f(0.0f));
+ brw_pop_insn_state(p);
+}
+static void emit_seq( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+}
-
+static void emit_sne( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+}
static void emit_slt( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- /* Could be done with an if/else/endif, but this method uses half
- * the instructions. Note that we are careful to reference the
- * arguments before writing the dest. That means we emit the
- * instructions in an odd order and have to play with the flag
- * values.
- */
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(1.0));
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+}
- /* Where the test succeeded, overwite with zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(0.0));
- brw_pop_insn_state(p);
+static void emit_sle( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
}
+static void emit_sgt( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+}
static void emit_sge( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(0));
-
- /* Where the test succeeded, overwite with 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(1.0));
- brw_pop_insn_state(p);
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
}
-
static void emit_max( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
@@ -592,9 +613,13 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
- case PROGRAM_STATE_VAR:
assert(c->regs[file][index].nr != 0);
return c->regs[file][index];
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_UNIFORM:
+ assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
+ return c->regs[PROGRAM_STATE_VAR][index];
case PROGRAM_ADDRESS:
assert(index == 0);
return c->regs[file][index];
@@ -668,28 +693,28 @@ static void emit_arl( struct brw_vs_compile *c,
* account.
*/
static struct brw_reg get_arg( struct brw_vs_compile *c,
- struct prog_src_register src )
+ struct prog_src_register *src )
{
struct brw_reg reg;
- if (src.File == PROGRAM_UNDEFINED)
+ if (src->File == PROGRAM_UNDEFINED)
return brw_null_reg();
- if (src.RelAddr)
- reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src.Index);
+ if (src->RelAddr)
+ reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index);
else
- reg = get_reg(c, src.File, src.Index);
+ reg = get_reg(c, src->File, src->Index);
/* Convert 3-bit swizzle to 2-bit.
*/
- reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src.Swizzle, 0),
- GET_SWZ(src.Swizzle, 1),
- GET_SWZ(src.Swizzle, 2),
- GET_SWZ(src.Swizzle, 3));
+ reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0),
+ GET_SWZ(src->Swizzle, 1),
+ GET_SWZ(src->Swizzle, 2),
+ GET_SWZ(src->Swizzle, 3));
/* Note this is ok for non-swizzle instructions:
*/
- reg.negate = src.NegateBase ? 1 : 0;
+ reg.negate = src->NegateBase ? 1 : 0;
return reg;
}
@@ -891,17 +916,50 @@ static void emit_vertex_write( struct brw_vs_compile *c)
}
-
-
+static void
+post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
+{
+ GLuint nr_insns = c->vp->program.Base.NumInstructions;
+ GLuint insn, target_insn;
+ struct prog_instruction *inst1, *inst2;
+ struct brw_instruction *brw_inst1, *brw_inst2;
+ int offset;
+ for (insn = 0; insn < nr_insns; insn++) {
+ inst1 = &c->vp->program.Base.Instructions[insn];
+ brw_inst1 = inst1->Data;
+ switch (inst1->Opcode) {
+ case OPCODE_CAL:
+ case OPCODE_BRA:
+ target_insn = inst1->BranchTarget;
+ inst2 = &c->vp->program.Base.Instructions[target_insn];
+ brw_inst2 = inst2->Data;
+ offset = brw_inst2 - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ case OPCODE_END:
+ offset = end_inst - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ default:
+ break;
+ }
+ }
+}
/* Emit the fragment program instructions here.
*/
-void brw_vs_emit( struct brw_vs_compile *c )
+void brw_vs_emit(struct brw_vs_compile *c )
{
+#define MAX_IFSN 32
struct brw_compile *p = &c->func;
GLuint nr_insns = c->vp->program.Base.NumInstructions;
- GLuint insn;
+ GLuint insn, if_insn = 0;
+ struct brw_instruction *end_inst;
+ struct brw_instruction *if_inst[MAX_IFSN];
+ struct brw_indirect stack_index = brw_indirect(0, 0);
+ GLuint index;
+ GLuint file;
if (INTEL_DEBUG & DEBUG_VS) {
_mesa_printf("\n\n\nvs-emit:\n");
@@ -912,9 +970,24 @@ void brw_vs_emit( struct brw_vs_compile *c )
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_access_mode(p, BRW_ALIGN_16);
+ /* Message registers can't be read, so copy the output into GRF register
+ if they are used in source registers */
+ for (insn = 0; insn < nr_insns; insn++) {
+ GLuint i;
+ struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
+ for (i = 0; i < 3; i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ GLuint index = src->Index;
+ GLuint file = src->File;
+ if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)
+ c->output_regs[index].used_in_src = GL_TRUE;
+ }
+ }
+
/* Static register allocation
*/
brw_vs_alloc_regs(c);
+ brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
for (insn = 0; insn < nr_insns; insn++) {
@@ -924,17 +997,29 @@ void brw_vs_emit( struct brw_vs_compile *c )
/* Get argument regs. SWZ is special and does this itself.
*/
+ inst->Data = &p->store[p->nr_insn];
if (inst->Opcode != OPCODE_SWZ)
- for (i = 0; i < 3; i++)
- args[i] = get_arg(c, inst->SrcReg[i]);
+ for (i = 0; i < 3; i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ index = src->Index;
+ file = src->File;
+ if (file == PROGRAM_OUTPUT&&c->output_regs[index].used_in_src)
+ args[i] = c->output_regs[index].reg;
+ else
+ args[i] = get_arg(c, src);
+ }
/* Get dest regs. Note that it is possible for a reg to be both
* dst and arg, given the static allocation of registers. So
* care needs to be taken emitting multi-operation instructions.
- */
- dst = get_dst(c, inst->DstReg);
+ */
+ index = inst->DstReg.Index;
+ file = inst->DstReg.File;
+ if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
+ dst = c->output_regs[index].reg;
+ else
+ dst = get_dst(c, inst->DstReg);
-
switch (inst->Opcode) {
case OPCODE_ABS:
brw_MOV(p, dst, brw_abs(args[0]));
@@ -1003,12 +1088,25 @@ void brw_vs_emit( struct brw_vs_compile *c )
case OPCODE_RSQ:
emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
break;
+
+ case OPCODE_SEQ:
+ emit_seq(p, dst, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, args[0], args[1]);
break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, args[0], args[1]);
+ break;
case OPCODE_SLT:
emit_slt(p, dst, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, args[0], args[1]);
+ break;
case OPCODE_SUB:
brw_ADD(p, dst, args[0], negate(args[1]));
break;
@@ -1021,21 +1119,60 @@ void brw_vs_emit( struct brw_vs_compile *c )
case OPCODE_XPD:
emit_xpd(p, dst, args[0], args[1]);
break;
+ case OPCODE_IF:
+ assert(if_insn < MAX_IFSN);
+ if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_ELSE:
+ if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
+ break;
+ case OPCODE_ENDIF:
+ assert(if_insn > 0);
+ brw_ENDIF(p, if_inst[--if_insn]);
+ break;
+ case OPCODE_BRA:
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ brw_set_predicate_control_flag_value(p, 0xff);
+ break;
+ case OPCODE_CAL:
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(4));
+ inst->Data = &p->store[p->nr_insn];
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
+ case OPCODE_RET:
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(-4));
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
+ brw_set_access_mode(p, BRW_ALIGN_16);
case OPCODE_END:
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
case OPCODE_PRINT:
+ case OPCODE_BGNSUB:
+ case OPCODE_ENDSUB:
break;
default:
+ _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
break;
}
+ if (inst->DstReg.File == PROGRAM_OUTPUT
+ &&inst->DstReg.Index != VERT_RESULT_HPOS
+ &&c->output_regs[inst->DstReg.Index].used_in_src)
+ brw_MOV(p, get_dst(c, inst->DstReg), dst);
+
release_tmps(c);
}
+ end_inst = &p->store[p->nr_insn];
emit_vertex_write(c);
-
+ post_vs_emit(c, end_inst);
+ for (insn = 0; insn < nr_insns; insn++)
+ c->vp->program.Base.Instructions[insn].Data = NULL;
}
-
-
-
-
-
diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c
index c225bf8f5c..f561979138 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -44,7 +44,7 @@ static void upload_vs_unit( struct brw_context *brw )
/* CACHE_NEW_VS_PROG */
vs.thread0.kernel_start_pointer = brw->vs.prog_gs_offset >> 6;
- vs.thread0.grf_reg_count = ((brw->vs.prog_data->total_grf-1) & ~15) / 16;
+ vs.thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs.thread3.urb_entry_read_length = brw->vs.prog_data->urb_read_length;
vs.thread3.const_urb_entry_read_length = brw->vs.prog_data->curb_read_length;
vs.thread3.dispatch_grf_start_reg = 1;
diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index 27210d1a37..aecdd4bc31 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
@@ -855,7 +855,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
struct ureg slt = get_temp(p);
emit_op2(p, OPCODE_DP3, spot, 0, ureg_negate(VPpli), spot_dir_norm);
- emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);
+ emit_op2(p, OPCODE_SLT, slt, 0, spot, swizzle1(spot_dir_norm,W));
emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
emit_op2(p, OPCODE_MUL, att, 0, slt, spot);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 904c00bef8..2d6249e3b5 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -66,7 +66,11 @@ GLuint brw_wm_nr_args( GLuint opcode )
case OPCODE_POW:
case OPCODE_SUB:
case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SLE:
case OPCODE_SLT:
+ case OPCODE_SEQ:
+ case OPCODE_SNE:
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
@@ -150,47 +154,49 @@ static void do_wm_prog( struct brw_context *brw,
c->fp = fp;
c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
-
- /* Augment fragment program. Add instructions for pre- and
- * post-fragment-program tasks such as interpolation and fogging.
- */
- brw_wm_pass_fp(c);
-
- /* Translate to intermediate representation. Build register usage
- * chains.
- */
- brw_wm_pass0(c);
-
- /* Dead code removal.
- */
- brw_wm_pass1(c);
-
- /* Hal optimization
- */
- brw_wm_pass_hal (c);
-
- /* Register allocation.
- */
- c->grf_limit = BRW_WM_MAX_GRF/2;
-
- /* This is where we start emitting gen4 code:
- */
- brw_init_compile(&c->func);
-
- brw_wm_pass2(c);
-
- c->prog_data.total_grf = c->max_wm_grf;
- if (c->last_scratch) {
- c->prog_data.total_scratch =
- c->last_scratch + 0x40;
+ if (brw_wm_is_glsl(&c->fp->program)) {
+ brw_wm_glsl_emit(c);
} else {
- c->prog_data.total_scratch = 0;
+ /* Augment fragment program. Add instructions for pre- and
+ * post-fragment-program tasks such as interpolation and fogging.
+ */
+ brw_wm_pass_fp(c);
+
+ /* Translate to intermediate representation. Build register usage
+ * chains.
+ */
+ brw_wm_pass0(c);
+
+ /* Dead code removal.
+ */
+ brw_wm_pass1(c);
+
+ /* Hal optimization
+ */
+ brw_wm_pass_hal (c);
+
+ /* Register allocation.
+ */
+ c->grf_limit = BRW_WM_MAX_GRF/2;
+
+ /* This is where we start emitting gen4 code:
+ */
+ brw_init_compile(&c->func);
+
+ brw_wm_pass2(c);
+
+ c->prog_data.total_grf = c->max_wm_grf;
+ if (c->last_scratch) {
+ c->prog_data.total_scratch =
+ c->last_scratch + 0x40;
+ } else {
+ c->prog_data.total_scratch = 0;
+ }
+
+ /* Emit GEN4 code.
+ */
+ brw_wm_emit(c);
}
-
- /* Emit GEN4 code.
- */
- brw_wm_emit(c);
-
/* get the program
*/
program = brw_get_program(&c->func, &program_size);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 6dcf4732a9..440b5357d5 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -194,6 +194,7 @@ struct brw_wm_compile {
GLuint nr_fp_insns;
GLuint fp_temp;
GLuint fp_interp_emitted;
+ GLuint fp_deriv_emitted;
struct prog_src_register pixel_xy;
struct prog_src_register delta_xy;
@@ -231,6 +232,15 @@ struct brw_wm_compile {
GLuint grf_limit;
GLuint max_wm_grf;
GLuint last_scratch;
+
+ struct {
+ GLboolean inited;
+ struct brw_reg reg;
+ } wm_regs[PROGRAM_PAYLOAD+1][256][4];
+ struct brw_reg stack;
+ struct brw_reg emit_mask_reg;
+ GLuint reg_index;
+ GLuint tmp_index;
};
@@ -259,4 +269,6 @@ void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
struct brw_wm_prog_key *key );
+GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp);
+void brw_wm_glsl_emit(struct brw_wm_compile *c);
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index fd60515972..1f7158f7a7 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -229,20 +229,20 @@ static void emit_cinterp( struct brw_compile *p,
GLuint mask,
const struct brw_reg *arg0 )
{
- struct brw_reg interp[4];
- GLuint nr = arg0[0].nr;
- GLuint i;
-
- interp[0] = brw_vec1_grf(nr, 0);
- interp[1] = brw_vec1_grf(nr, 4);
- interp[2] = brw_vec1_grf(nr+1, 0);
- interp[3] = brw_vec1_grf(nr+1, 4);
-
- for(i = 0; i < 4; i++ ) {
- if (mask & (1<<i)) {
- brw_MOV(p, dst[i], suboffset(interp[i],3)); /* TODO: optimize away like other moves */
- }
- }
+ struct brw_reg interp[4];
+ GLuint nr = arg0[0].nr;
+ GLuint i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ brw_MOV(p, dst[i], suboffset(interp[i],3)); /* TODO: optimize away like other moves */
+ }
+ }
}
@@ -343,11 +343,10 @@ static void emit_lrp( struct brw_compile *p,
}
}
}
-
-
-static void emit_slt( struct brw_compile *p,
+static void emit_sop( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
+ GLuint cond,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
@@ -356,34 +355,66 @@ static void emit_slt( struct brw_compile *p,
for (i = 0; i < 4; i++) {
if (mask & (1<<i)) {
brw_MOV(p, dst[i], brw_imm_f(0));
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
+ brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
brw_MOV(p, dst[i], brw_imm_f(1.0));
brw_set_predicate_control_flag_value(p, 0xff);
}
}
}
-/* Isn't this just the same as the above with the args swapped?
- */
-static void emit_sge( struct brw_compile *p,
+static void emit_slt( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
- GLuint i;
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
+}
- for (i = 0; i < 4; i++) {
- if (mask & (1<<i)) {
- brw_MOV(p, dst[i], brw_imm_f(0));
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], arg1[i]);
- brw_MOV(p, dst[i], brw_imm_f(1.0));
- brw_set_predicate_control_flag_value(p, 0xff);
- }
- }
+static void emit_sle( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1);
+}
+
+static void emit_sgt( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1);
+}
+
+static void emit_sge( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1);
}
+static void emit_seq( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1);
+}
+static void emit_sne( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1);
+}
static void emit_cmp( struct brw_compile *p,
const struct brw_reg *dst,
@@ -543,8 +574,8 @@ static void emit_math1( struct brw_compile *p,
GLuint mask,
const struct brw_reg *arg0 )
{
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
- function == BRW_MATH_FUNCTION_SINCOS);
+ //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
+ // function == BRW_MATH_FUNCTION_SINCOS);
brw_MOV(p, brw_message_reg(2), arg0[0]);
@@ -671,6 +702,8 @@ static void emit_tex( struct brw_wm_compile *c,
msgLength,
0);
+ if (shadow)
+ brw_MOV(p, dst[3], brw_imm_f(1.0));
}
@@ -1208,9 +1241,21 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_slt(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, dst_flags, args[0], args[1]);
+ break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SEQ:
+ emit_seq(p, dst, dst_flags, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_LIT:
emit_lit(p, dst, dst_flags, args[0]);
@@ -1231,7 +1276,8 @@ void brw_wm_emit( struct brw_wm_compile *c )
break;
default:
- assert(0);
+ _mesa_printf("unsupport opcode %d in fragment program\n",
+ inst->opcode);
}
for (i = 0; i < 4; i++)
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 67154c1b13..1b26005169 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -176,6 +176,7 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c,
{
struct prog_instruction *inst = get_fp_inst(c);
*inst = *inst0;
+ inst->Data = (void *)inst0;
return inst;
}
@@ -201,7 +202,6 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
inst->SrcReg[0] = src0;
inst->SrcReg[1] = src1;
inst->SrcReg[2] = src2;
-
return inst;
}
@@ -361,6 +361,37 @@ static void emit_interp( struct brw_wm_compile *c,
c->fp_interp_emitted |= 1<<idx;
}
+static void emit_ddx( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ GLuint idx = inst->SrcReg[0].Index;
+ struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+ c->fp_deriv_emitted |= 1<<idx;
+ emit_op(c,
+ OPCODE_DDX,
+ inst->DstReg,
+ 0, 0, 0,
+ interp,
+ get_pixel_w(c),
+ src_undef());
+}
+
+static void emit_ddy( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ GLuint idx = inst->SrcReg[0].Index;
+ struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+ c->fp_deriv_emitted |= 1<<idx;
+ emit_op(c,
+ OPCODE_DDY,
+ inst->DstReg,
+ 0, 0, 0,
+ interp,
+ get_pixel_w(c),
+ src_undef());
+}
/***********************************************************************
* Hacks to extend the program parameter and constant lists.
@@ -957,8 +988,16 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
*/
out->DstReg.WriteMask = 0;
break;
-
+ case OPCODE_DDX:
+ emit_ddx(c, inst);
+ break;
+ case OPCODE_DDY:
+ emit_ddy(c, inst);
+ break;
case OPCODE_END:
+ emit_fog(c);
+ emit_fb_write(c);
+ break;
case OPCODE_PRINT:
break;
@@ -967,15 +1006,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
break;
}
}
-
- emit_fog(c);
- emit_fb_write(c);
-
if (INTEL_DEBUG & DEBUG_WM) {
- _mesa_printf("\n\n\npass_fp:\n");
- print_insns( c->prog_instructions, c->nr_fp_insns );
- _mesa_printf("\n");
+ _mesa_printf("\n\n\npass_fp:\n");
+ print_insns( c->prog_instructions, c->nr_fp_insns );
+ _mesa_printf("\n");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
new file mode 100644
index 0000000000..4b273fefe9
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -0,0 +1,1354 @@
+#include "macros.h"
+#include "shader/prog_parameter.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_wm.h"
+
+/* Only guess, need a flag in gl_fragment_program later */
+GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp)
+{
+ int i;
+ for (i = 0; i < fp->Base.NumInstructions; i++) {
+ struct prog_instruction *inst = &fp->Base.Instructions[i];
+ switch (inst->Opcode) {
+ case OPCODE_IF:
+ case OPCODE_INT:
+ case OPCODE_ENDIF:
+ case OPCODE_CAL:
+ case OPCODE_BRK:
+ case OPCODE_RET:
+ case OPCODE_DDX:
+ case OPCODE_DDY:
+ case OPCODE_BGNLOOP:
+ return GL_TRUE;
+ default:
+ break;
+ }
+ }
+ return GL_FALSE;
+}
+
+static void set_reg(struct brw_wm_compile *c, int file, int index,
+ int component, struct brw_reg reg)
+{
+ c->wm_regs[file][index][component].reg = reg;
+ c->wm_regs[file][index][component].inited = GL_TRUE;
+}
+
+static int get_scalar_dst_index(struct prog_instruction *inst)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ if (inst->DstReg.WriteMask & (1<<i))
+ break;
+ return i;
+}
+
+static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
+{
+ struct brw_reg reg;
+ reg = brw_vec8_grf(c->tmp_index--, 0);
+ return reg;
+}
+
+static void release_tmps(struct brw_wm_compile *c)
+{
+ c->tmp_index = 127;
+}
+
+static struct brw_reg
+get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GLuint neg, GLuint abs)
+{
+ struct brw_reg reg;
+ switch (file) {
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_UNIFORM:
+ file = PROGRAM_STATE_VAR;
+ break;
+ case PROGRAM_UNDEFINED:
+ return brw_null_reg();
+ default:
+ break;
+ }
+
+ if(c->wm_regs[file][index][component].inited)
+ reg = c->wm_regs[file][index][component].reg;
+ else
+ reg = brw_vec8_grf(c->reg_index, 0);
+
+ if(!c->wm_regs[file][index][component].inited) {
+ set_reg(c, file, index, component, reg);
+ c->reg_index++;
+ }
+
+ if (neg & (1<< component)) {
+ reg = negate(reg);
+ }
+ if (abs)
+ reg = brw_abs(reg);
+ return reg;
+}
+
+static void prealloc_reg(struct brw_wm_compile *c)
+{
+ int i, j;
+ struct brw_reg reg;
+ int nr_interp_regs = 0;
+ GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
+
+ for (i = 0; i < 4; i++) {
+ reg = (i < c->key.nr_depth_regs)
+ ? brw_vec8_grf(i*2, 0) : brw_vec8_grf(0, 0);
+ set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
+ }
+ c->reg_index += 2*c->key.nr_depth_regs;
+ {
+ int nr_params = c->fp->program.Base.Parameters->NumParameters;
+ struct gl_program_parameter_list *plist =
+ c->fp->program.Base.Parameters;
+ int index = 0;
+ c->prog_data.nr_params = 4*nr_params;
+ for (i = 0; i < nr_params; i++) {
+ for (j = 0; j < 4; j++, index++) {
+ reg = brw_vec1_grf(c->reg_index + index/8,
+ index%8);
+ c->prog_data.param[index] =
+ &plist->ParameterValues[i][j];
+ set_reg(c, PROGRAM_STATE_VAR, i, j, reg);
+ }
+ }
+ c->nr_creg = 2*((4*nr_params+15)/16);
+ c->reg_index += c->nr_creg;
+ }
+ for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
+ if (inputs & (1<<i)) {
+ nr_interp_regs++;
+ reg = brw_vec8_grf(c->reg_index, 0);
+ for (j = 0; j < 4; j++)
+ set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
+ c->reg_index += 2;
+
+ }
+ }
+ c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+ c->prog_data.urb_read_length = nr_interp_regs * 2;
+ c->prog_data.curb_read_length = c->nr_creg;
+ c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+ c->reg_index++;
+ c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+ c->reg_index += 2;
+}
+
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
+ struct prog_instruction *inst, int component, int nr)
+{
+ return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
+ 0, 0);
+}
+
+static struct brw_reg get_src_reg(struct brw_wm_compile *c,
+ struct prog_src_register *src, int index, int nr)
+{
+ int component = GET_SWZ(src->Swizzle, index);
+ return get_reg(c, src->File, src->Index, component, nr,
+ src->NegateBase, src->Abs);
+}
+
+static void emit_abs( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for (i = 0; i < 4; i++) {
+ if (inst->DstReg.WriteMask & (1<<i)) {
+ struct brw_reg src, dst;
+ dst = get_dst_reg(c, inst, i, 1);
+ src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_MOV(p, dst, brw_abs(src));
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_int( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ struct brw_reg src, dst;
+ dst = get_dst_reg(c, inst, i, 1) ;
+ src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_RNDD(p, dst, src);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_mov( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ struct brw_reg src, dst;
+ dst = get_dst_reg(c, inst, i, 1);
+ src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_MOV(p, dst, src);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_pixel_xy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg r1 = brw_vec1_grf(1, 0);
+ struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
+
+ struct brw_reg dst0, dst1;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ dst0 = get_dst_reg(c, inst, 0, 1);
+ dst1 = get_dst_reg(c, inst, 1, 1);
+ /* Calculate pixel centers by adding 1 or 0 to each of the
+ * micro-tile coordinates passed in r1.
+ */
+ if (mask & WRITEMASK_X) {
+ brw_ADD(p,
+ vec8(retype(dst0, BRW_REGISTER_TYPE_UW)),
+ stride(suboffset(r1_uw, 4), 2, 4, 0),
+ brw_imm_v(0x10101010));
+ }
+
+ if (mask & WRITEMASK_Y) {
+ brw_ADD(p,
+ vec8(retype(dst1, BRW_REGISTER_TYPE_UW)),
+ stride(suboffset(r1_uw, 5), 2, 4, 0),
+ brw_imm_v(0x11001100));
+ }
+
+}
+
+static void emit_delta_xy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg r1 = brw_vec1_grf(1, 0);
+ struct brw_reg dst0, dst1, src0, src1;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ dst0 = get_dst_reg(c, inst, 0, 1);
+ dst1 = get_dst_reg(c, inst, 1, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+ /* Calc delta X,Y by subtracting origin in r1 from the pixel
+ * centers.
+ */
+ if (mask & WRITEMASK_X) {
+ brw_ADD(p,
+ dst0,
+ retype(src0, BRW_REGISTER_TYPE_UW),
+ negate(r1));
+ }
+
+ if (mask & WRITEMASK_Y) {
+ brw_ADD(p,
+ dst1,
+ retype(src1, BRW_REGISTER_TYPE_UW),
+ negate(suboffset(r1,1)));
+
+ }
+
+}
+
+
+static void fire_fb_write( struct brw_wm_compile *c,
+ GLuint base_reg,
+ GLuint nr )
+{
+ struct brw_compile *p = &c->func;
+
+ /* Pass through control information:
+ */
+ /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */
+ {
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
+ brw_MOV(p,
+ brw_message_reg(base_reg + 1),
+ brw_vec8_grf(1, 0));
+ brw_pop_insn_state(p);
+ }
+ /* Send framebuffer write message: */
+ brw_fb_WRITE(p,
+ 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 */
+ nr,
+ 0,
+ 1);
+}
+
+static void emit_fb_write(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ int nr = 2;
+ int channel;
+ struct brw_reg src0;//, src1, src2, dst;
+
+ /* Reserve a space for AA - may not be needed:
+ */
+ if (c->key.aa_dest_stencil_reg)
+ nr += 1;
+ {
+ brw_push_insn_state(p);
+ for (channel = 0; channel < 4; channel++) {
+ src0 = get_src_reg(c, &inst->SrcReg[0], channel, 1);
+ /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */
+ /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */
+ brw_MOV(p, brw_message_reg(nr + channel), src0);
+ }
+ /* skip over the regs populated above: */
+ nr += 8;
+ brw_pop_insn_state(p);
+ }
+ fire_fb_write(c, 0, nr);
+}
+
+static void emit_pixel_w( struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ if (mask & WRITEMASK_W) {
+ struct brw_reg dst, src0, delta0, delta1;
+ struct brw_reg interp3;
+
+ dst = get_dst_reg(c, inst, 3, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+ delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+
+ interp3 = brw_vec1_grf(src0.nr+1, 4);
+ /* Calc 1/w - just linterp wpos[3] optimized by putting the
+ * result straight into a message reg.
+ */
+ brw_LINE(p, brw_null_reg(), interp3, delta0);
+ brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1);
+
+ /* Calc w */
+ brw_math_16( p, dst,
+ BRW_MATH_FUNCTION_INV,
+ BRW_MATH_SATURATE_NONE,
+ 2, brw_null_reg(),
+ BRW_MATH_PRECISION_FULL);
+ }
+}
+
+static void emit_linterp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg interp[4];
+ struct brw_reg dst, delta0, delta1;
+ struct brw_reg src0;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+ delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+ GLuint nr = src0.nr;
+ int i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_LINE(p, brw_null_reg(), interp[i], delta0);
+ brw_MAC(p, dst, suboffset(interp[i],1), delta1);
+ }
+ }
+}
+
+static void emit_cinterp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ struct brw_reg interp[4];
+ struct brw_reg dst, src0;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ GLuint nr = src0.nr;
+ int i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_MOV(p, dst, suboffset(interp[i],3));
+ }
+ }
+}
+
+static void emit_pinterp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+
+ struct brw_reg interp[4];
+ struct brw_reg dst, delta0, delta1;
+ struct brw_reg src0, w;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+ delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+ w = get_src_reg(c, &inst->SrcReg[2], 3, 1);
+ GLuint nr = src0.nr;
+ int i;
+
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_LINE(p, brw_null_reg(), interp[i], delta0);
+ brw_MAC(p, dst, suboffset(interp[i],1),
+ delta1);
+ brw_MUL(p, dst, dst, w);
+ }
+ }
+}
+
+static void emit_xpd(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ int i;
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ for (i = 0; i < 4; i++) {
+ GLuint i2 = (i+2)%3;
+ GLuint i1 = (i+1)%3;
+ if (mask & (1<<i)) {
+ struct brw_reg src0, src1, dst;
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = negate(get_src_reg(c, &inst->SrcReg[0], i2, 1));
+ src1 = get_src_reg(c, &inst->SrcReg[1], i1, 1);
+ brw_MUL(p, brw_null_reg(), src0, src1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i1, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i2, 1);
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ brw_MAC(p, dst, src0, src1);
+ brw_set_saturate(p, 0);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_dp3(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg src0[3], src1[3], dst;
+ int i;
+ struct brw_compile *p = &c->func;
+ for (i = 0; i < 3; i++) {
+ src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ }
+
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+ brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MAC(p, dst, src0[2], src1[2]);
+ brw_set_saturate(p, 0);
+}
+
+static void emit_dp4(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg src0[4], src1[4], dst;
+ int i;
+ struct brw_compile *p = &c->func;
+ for (i = 0; i < 4; i++) {
+ src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ }
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+ brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+ brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MAC(p, dst, src0[3], src1[3]);
+ brw_set_saturate(p, 0);
+}
+
+static void emit_dph(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_reg src0[4], src1[4], dst;
+ int i;
+ struct brw_compile *p = &c->func;
+ for (i = 0; i < 4; i++) {
+ src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ }
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+ brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+ brw_MAC(p, dst, src0[2], src1[2]);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_ADD(p, dst, src0[3], src1[3]);
+ brw_set_saturate(p, 0);
+}
+
+static void emit_math1(struct brw_wm_compile *c,
+ struct prog_instruction *inst, GLuint func)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, dst;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ brw_MOV(p, brw_message_reg(2), src0);
+ brw_math(p,
+ dst,
+ func,
+ (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+ 2,
+ brw_null_reg(),
+ BRW_MATH_DATA_VECTOR,
+ BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_rcp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
+}
+
+static void emit_rsq(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
+}
+
+static void emit_sin(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
+}
+
+static void emit_cos(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
+}
+
+static void emit_ex2(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
+}
+
+static void emit_lg2(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
+}
+
+static void emit_add(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, src1, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_ADD(p, dst, src0, src1);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_sub(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, src1, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_ADD(p, dst, src0, negate(src1));
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_mul(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, src1, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_MUL(p, dst, src0, src1);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_frc(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_FRC(p, dst, src0);
+ }
+ }
+ if (inst->SaturateMode != SATURATE_OFF)
+ brw_set_saturate(p, 0);
+}
+
+static void emit_flr(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg src0, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int i;
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ for (i = 0 ; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ brw_RNDD(p, dst, src0);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_max(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg src0, src1, dst;
+ int i;
+ brw_push_insn_state(p);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MOV(p, dst, src0);
+ brw_set_saturate(p, 0);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, src1);
+ brw_set_saturate(p, 0);
+ brw_set_predicate_control_flag_value(p, 0xff);
+ }
+ }
+ brw_pop_insn_state(p);
+}
+
+static void emit_min(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg src0, src1, dst;
+ int i;
+ brw_push_insn_state(p);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MOV(p, dst, src0);
+ brw_set_saturate(p, 0);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, src1);
+ brw_set_saturate(p, 0);
+ brw_set_predicate_control_flag_value(p, 0xff);
+ }
+ }
+ brw_pop_insn_state(p);
+}
+
+static void emit_pow(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg dst, src0, src1;
+ dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+
+ brw_MOV(p, brw_message_reg(2), src0);
+ brw_MOV(p, brw_message_reg(3), src1);
+
+ brw_math(p,
+ dst,
+ BRW_MATH_FUNCTION_POW,
+ (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+ 2,
+ brw_null_reg(),
+ BRW_MATH_DATA_VECTOR,
+ BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_lrp(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
+ int i;
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+
+ if (src1.nr == dst.nr) {
+ tmp1 = alloc_tmp(c);
+ brw_MOV(p, tmp1, src1);
+ } else
+ tmp1 = src1;
+
+ src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+ if (src2.nr == dst.nr) {
+ tmp2 = alloc_tmp(c);
+ brw_MOV(p, tmp2, src2);
+ } else
+ tmp2 = src2;
+
+ brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
+ brw_MUL(p, brw_null_reg(), dst, tmp2);
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_MAC(p, dst, src0, tmp1);
+ brw_set_saturate(p, 0);
+ }
+ release_tmps(c);
+ }
+}
+
+static void emit_kil(struct brw_wm_compile *c)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+ brw_AND(p, depth, c->emit_mask_reg, depth);
+ brw_pop_insn_state(p);
+}
+
+static void emit_mad(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg dst, src0, src1, src2;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+ brw_MUL(p, dst, src0, src1);
+
+ brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+ brw_ADD(p, dst, dst, src2);
+ brw_set_saturate(p, 0);
+ }
+ }
+}
+
+static void emit_sop(struct brw_wm_compile *c,
+ struct prog_instruction *inst, GLuint cond)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg dst, src0, src1;
+ int i;
+
+ brw_push_insn_state(p);
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+ src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+ brw_CMP(p, brw_null_reg(), cond, src0, src1);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_MOV(p, dst, brw_imm_f(0.0));
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, brw_imm_f(1.0));
+ }
+ }
+ brw_pop_insn_state(p);
+}
+
+static void emit_slt(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_L);
+}
+
+static void emit_sle(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_LE);
+}
+
+static void emit_sgt(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_G);
+}
+
+static void emit_sge(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_GE);
+}
+
+static void emit_seq(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_EQ);
+}
+
+static void emit_sne(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
+}
+
+static void emit_ddx(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg interp[4];
+ struct brw_reg dst;
+ struct brw_reg src0, w;
+ GLuint nr, i;
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+ nr = src0.nr;
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_MOV(p, dst, interp[i]);
+ brw_MUL(p, dst, dst, w);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_ddy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg interp[4];
+ struct brw_reg dst;
+ struct brw_reg src0, w;
+ GLuint nr, i;
+
+ src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ nr = src0.nr;
+ w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+ interp[0] = brw_vec1_grf(nr, 0);
+ interp[1] = brw_vec1_grf(nr, 4);
+ interp[2] = brw_vec1_grf(nr+1, 0);
+ interp[3] = brw_vec1_grf(nr+1, 4);
+ brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+ for(i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ dst = get_dst_reg(c, inst, i, 1);
+ brw_MOV(p, dst, suboffset(interp[i], 1));
+ brw_MUL(p, dst, dst, w);
+ }
+ }
+ brw_set_saturate(p, 0);
+}
+
+static void emit_wpos_xy(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ struct brw_reg src0[2], dst[2];
+
+ dst[0] = get_dst_reg(c, inst, 0, 1);
+ dst[1] = get_dst_reg(c, inst, 1, 1);
+
+ src0[0] = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+ src0[1] = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+
+ /* Calc delta X,Y by subtracting origin in r1 from the pixel
+ * centers.
+ */
+ if (mask & WRITEMASK_X) {
+ brw_MOV(p,
+ dst[0],
+ retype(src0[0], BRW_REGISTER_TYPE_UW));
+ }
+
+ if (mask & WRITEMASK_Y) {
+ /* TODO -- window_height - Y */
+ brw_MOV(p,
+ dst[1],
+ retype(src0[1], BRW_REGISTER_TYPE_UW));
+
+ }
+}
+
+/* TODO
+ BIAS on SIMD8 not workind yet...
+ */
+static void emit_txb(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg dst[4], src[4], payload_reg;
+ GLuint i;
+ payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+ for (i = 0; i < 4; i++)
+ dst[i] = get_dst_reg(c, inst, i, 1);
+ for (i = 0; i < 4; i++)
+ src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX:
+ brw_MOV(p, brw_message_reg(2), src[0]);
+ brw_MOV(p, brw_message_reg(3), brw_imm_f(0));
+ brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+ break;
+ case TEXTURE_2D_INDEX:
+ case TEXTURE_RECT_INDEX:
+ brw_MOV(p, brw_message_reg(2), src[0]);
+ brw_MOV(p, brw_message_reg(3), src[1]);
+ brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+ break;
+ default:
+ brw_MOV(p, brw_message_reg(2), src[0]);
+ brw_MOV(p, brw_message_reg(3), src[1]);
+ brw_MOV(p, brw_message_reg(4), src[2]);
+ break;
+ }
+ brw_MOV(p, brw_message_reg(5), src[3]);
+ brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+ brw_SAMPLE(p,
+ retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
+ 1,
+ retype(payload_reg, BRW_REGISTER_TYPE_UW),
+ inst->TexSrcUnit + 1, /* surface */
+ inst->TexSrcUnit, /* sampler */
+ inst->DstReg.WriteMask,
+ BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
+ 4,
+ 4,
+ 0);
+}
+
+static void emit_tex(struct brw_wm_compile *c,
+ struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg dst[4], src[4], payload_reg;
+ GLuint msg_len;
+ GLuint i, nr;
+ GLuint emit;
+ GLboolean shadow = (c->key.shadowtex_mask & (1<<inst->TexSrcUnit)) ? 1 : 0;
+
+ payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+
+ for (i = 0; i < 4; i++)
+ dst[i] = get_dst_reg(c, inst, i, 1);
+ for (i = 0; i < 4; i++)
+ src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX:
+ emit = WRITEMASK_X;
+ nr = 1;
+ break;
+ case TEXTURE_2D_INDEX:
+ case TEXTURE_RECT_INDEX:
+ emit = WRITEMASK_XY;
+ nr = 2;
+ break;
+ default:
+ emit = WRITEMASK_XYZ;
+ nr = 3;
+ break;
+ }
+ msg_len = 1;
+
+ for (i = 0; i < nr; i++) {
+ static const GLuint swz[4] = {0,1,2,2};
+ if (emit & (1<<i))
+ brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
+ else
+ brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
+ msg_len += 1;
+ }
+
+ if (shadow) {
+ brw_MOV(p, brw_message_reg(5), brw_imm_f(0));
+ brw_MOV(p, brw_message_reg(6), src[2]);
+ }
+
+ brw_SAMPLE(p,
+ retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
+ 1,
+ retype(payload_reg, BRW_REGISTER_TYPE_UW),
+ inst->TexSrcUnit + 1, /* surface */
+ inst->TexSrcUnit, /* sampler */
+ inst->DstReg.WriteMask,
+ BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
+ 4,
+ shadow ? 6 : 4,
+ 0);
+
+ if (shadow)
+ brw_MOV(p, dst[3], brw_imm_f(1.0));
+}
+
+static void post_wm_emit( struct brw_wm_compile *c )
+{
+ GLuint nr_insns = c->fp->program.Base.NumInstructions;
+ GLuint insn, target_insn;
+ struct prog_instruction *inst1, *inst2;
+ struct brw_instruction *brw_inst1, *brw_inst2;
+ int offset;
+ for (insn = 0; insn < nr_insns; insn++) {
+ inst1 = &c->fp->program.Base.Instructions[insn];
+ brw_inst1 = inst1->Data;
+ switch (inst1->Opcode) {
+ case OPCODE_CAL:
+ target_insn = inst1->BranchTarget;
+ inst2 = &c->fp->program.Base.Instructions[target_insn];
+ brw_inst2 = inst2->Data;
+ offset = brw_inst2 - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void brw_wm_emit_glsl(struct brw_wm_compile *c)
+
+{
+#define MAX_IFSN 32
+#define MAX_LOOP_DEPTH 32
+ struct brw_instruction *if_inst[MAX_IFSN], *loop_inst[MAX_LOOP_DEPTH];
+ struct brw_instruction *inst0, *inst1;
+ int i, if_insn = 0, loop_insn = 0;
+ struct brw_compile *p = &c->func;
+ struct brw_indirect stack_index = brw_indirect(0, 0);
+
+ brw_init_compile(&c->func);
+ c->reg_index = 0;
+ prealloc_reg(c);
+ brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+ brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
+
+ for (i = 0; i < c->nr_fp_insns; i++) {
+ struct prog_instruction *inst = &c->prog_instructions[i];
+ struct prog_instruction *orig_inst;
+
+ if ((orig_inst = inst->Data) != 0)
+ orig_inst->Data = current_insn(p);
+
+ if (inst->CondUpdate)
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+ else
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+
+ switch (inst->Opcode) {
+ case WM_PIXELXY:
+ emit_pixel_xy(c, inst);
+ break;
+ case WM_DELTAXY:
+ emit_delta_xy(c, inst);
+ break;
+ case WM_PIXELW:
+ emit_pixel_w(c, inst);
+ break;
+ case WM_LINTERP:
+ emit_linterp(c, inst);
+ break;
+ case WM_PINTERP:
+ emit_pinterp(c, inst);
+ break;
+ case WM_CINTERP:
+ emit_cinterp(c, inst);
+ break;
+ case WM_WPOSXY:
+ emit_wpos_xy(c, inst);
+ break;
+ case WM_FB_WRITE:
+ emit_fb_write(c, inst);
+ break;
+ case OPCODE_ABS:
+ emit_abs(c, inst);
+ break;
+ case OPCODE_ADD:
+ emit_add(c, inst);
+ break;
+ case OPCODE_SUB:
+ emit_sub(c, inst);
+ break;
+ case OPCODE_FRC:
+ emit_frc(c, inst);
+ break;
+ case OPCODE_FLR:
+ emit_flr(c, inst);
+ break;
+ case OPCODE_LRP:
+ emit_lrp(c, inst);
+ break;
+ case OPCODE_INT:
+ emit_int(c, inst);
+ break;
+ case OPCODE_MOV:
+ emit_mov(c, inst);
+ break;
+ case OPCODE_DP3:
+ emit_dp3(c, inst);
+ break;
+ case OPCODE_DP4:
+ emit_dp4(c, inst);
+ break;
+ case OPCODE_XPD:
+ emit_xpd(c, inst);
+ break;
+ case OPCODE_DPH:
+ emit_dph(c, inst);
+ break;
+ case OPCODE_RCP:
+ emit_rcp(c, inst);
+ break;
+ case OPCODE_RSQ:
+ emit_rsq(c, inst);
+ break;
+ case OPCODE_SIN:
+ emit_sin(c, inst);
+ break;
+ case OPCODE_COS:
+ emit_cos(c, inst);
+ break;
+ case OPCODE_EX2:
+ emit_ex2(c, inst);
+ break;
+ case OPCODE_LG2:
+ emit_lg2(c, inst);
+ break;
+ case OPCODE_MAX:
+ emit_max(c, inst);
+ break;
+ case OPCODE_MIN:
+ emit_min(c, inst);
+ break;
+ case OPCODE_DDX:
+ emit_ddx(c, inst);
+ break;
+ case OPCODE_DDY:
+ emit_ddy(c, inst);
+ break;
+ case OPCODE_SLT:
+ emit_slt(c, inst);
+ break;
+ case OPCODE_SLE:
+ emit_sle(c, inst);
+ break;
+ case OPCODE_SGT:
+ emit_sgt(c, inst);
+ break;
+ case OPCODE_SGE:
+ emit_sge(c, inst);
+ break;
+ case OPCODE_SEQ:
+ emit_seq(c, inst);
+ break;
+ case OPCODE_SNE:
+ emit_sne(c, inst);
+ break;
+ case OPCODE_MUL:
+ emit_mul(c, inst);
+ break;
+ case OPCODE_POW:
+ emit_pow(c, inst);
+ break;
+ case OPCODE_MAD:
+ emit_mad(c, inst);
+ break;
+ case OPCODE_TEX:
+ emit_tex(c, inst);
+ break;
+ case OPCODE_TXB:
+ emit_txb(c, inst);
+ break;
+ case OPCODE_KIL_NV:
+ emit_kil(c);
+ break;
+ case OPCODE_IF:
+ assert(if_insn < MAX_IFSN);
+ if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_ELSE:
+ if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
+ break;
+ case OPCODE_ENDIF:
+ assert(if_insn > 0);
+ brw_ENDIF(p, if_inst[--if_insn]);
+ break;
+ case OPCODE_BGNSUB:
+ case OPCODE_ENDSUB:
+ break;
+ case OPCODE_CAL:
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_ADD(p, deref_1ud(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(4));
+ orig_inst = inst->Data;
+ orig_inst->Data = &p->store[p->nr_insn];
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ brw_pop_insn_state(p);
+ break;
+
+ case OPCODE_RET:
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_ADD(p, get_addr_reg(stack_index),
+ get_addr_reg(stack_index), brw_imm_d(-4));
+ brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_MOV(p, brw_ip_reg(), deref_1ud(stack_index, 0));
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ brw_pop_insn_state(p);
+
+ break;
+ case OPCODE_BGNLOOP:
+ loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_BRK:
+ brw_BREAK(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case OPCODE_CONT:
+ brw_CONT(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case OPCODE_ENDLOOP:
+ loop_insn--;
+ inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]);
+ /* patch all the BREAK instructions from
+ last BEGINLOOP */
+ while (inst0 > loop_inst[loop_insn]) {
+ inst0--;
+ if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+ inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
+ inst0->bits3.if_else.pop_count = 0;
+ } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+ inst0->bits3.if_else.jump_count = inst1 - inst0;
+ inst0->bits3.if_else.pop_count = 0;
+ }
+ }
+ break;
+ default:
+ _mesa_printf("unsupported IR in fragment shader %d\n",
+ inst->Opcode);
+ }
+ if (inst->CondUpdate)
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ else
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ }
+ post_wm_emit(c);
+ for (i = 0; i < c->fp->program.Base.NumInstructions; i++)
+ c->fp->program.Base.Instructions[i].Data = NULL;
+}
+
+void brw_wm_glsl_emit(struct brw_wm_compile *c)
+{
+ brw_wm_pass_fp(c);
+ c->tmp_index = 127;
+ brw_wm_emit_glsl(c);
+ c->prog_data.total_grf = c->reg_index;
+ c->prog_data.total_scratch = 0;
+}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 00f6f6b9a4..1bfae5a069 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -168,6 +168,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
case PROGRAM_PAYLOAD:
case PROGRAM_TEMPORARY:
case PROGRAM_OUTPUT:
+ case PROGRAM_VARYING:
break;
case PROGRAM_LOCAL_PARAM:
@@ -179,6 +180,8 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
break;
case PROGRAM_STATE_VAR:
+ case PROGRAM_UNIFORM:
+ case PROGRAM_CONSTANT:
case PROGRAM_NAMED_PARAM: {
struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters;
@@ -197,6 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
break;
case PROGRAM_STATE_VAR:
+ case PROGRAM_UNIFORM:
/* These may change from run to run:
*/
ref = get_param_ref(c, &plist->ParameterValues[idx][component] );
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index d668def700..26c044d400 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -155,7 +155,11 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_SUB:
case OPCODE_SLT:
+ case OPCODE_SLE:
case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SEQ:
+ case OPCODE_SNE:
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
@@ -257,7 +261,6 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_DST:
case OPCODE_TXP:
default:
- assert(0);
break;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index a1edbd6168..c1ce6a9b6b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -328,7 +328,7 @@ void brw_wm_pass2( struct brw_wm_compile *c )
c->state = PASS2_DONE;
if (INTEL_DEBUG & DEBUG_WM) {
- brw_wm_print_program(c, "pass2/done");
+ brw_wm_print_program(c, "pass2/done");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 5b4f2abd0e..7856da0896 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -34,6 +34,7 @@
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
+#include "brw_wm.h"
#include "bufmgr.h"
/***********************************************************************
@@ -62,7 +63,7 @@ static void upload_wm_unit(struct brw_context *brw )
memset(&wm, 0, sizeof(wm));
/* CACHE_NEW_WM_PROG */
- wm.thread0.grf_reg_count = ((brw->wm.prog_data->total_grf-1) & ~15) / 16;
+ wm.thread0.grf_reg_count = ALIGN(brw->wm.prog_data->total_grf, 16) / 16 - 1;
wm.thread0.kernel_start_pointer = brw->wm.prog_gs_offset >> 6;
wm.thread3.dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
wm.thread3.urb_entry_read_length = brw->wm.prog_data->urb_read_length;
@@ -71,7 +72,7 @@ static void upload_wm_unit(struct brw_context *brw )
wm.wm5.max_threads = max_threads;
if (brw->wm.prog_data->total_scratch) {
- GLuint per_thread = (brw->wm.prog_data->total_scratch + 1023) / 1024;
+ GLuint per_thread = ALIGN(brw->wm.prog_data->total_scratch, 1024);
GLuint total = per_thread * (max_threads + 1);
/* Scratch space -- just have to make sure there is sufficient
@@ -134,9 +135,13 @@ static void upload_wm_unit(struct brw_context *brw )
if (fp->UsesKill ||
brw->attribs.Color->AlphaEnabled)
wm.wm5.program_uses_killpixel = 1;
+
+ if (brw_wm_is_glsl(fp))
+ wm.wm5.enable_8_pix = 1;
+ else
+ wm.wm5.enable_16_pix = 1;
}
- wm.wm5.enable_16_pix = 1;
wm.wm5.thread_dispatch_enable = 1; /* AKA: color_write */
wm.wm5.legacy_line_rast = 0;
wm.wm5.legacy_global_depth_bias = 0;
diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c
index a85121122f..65760c40d4 100644
--- a/src/mesa/drivers/dri/i965/bufmgr_fake.c
+++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c
@@ -168,7 +168,7 @@ static GLboolean alloc_from_pool( struct intel_context *intel,
if (!block)
return GL_FALSE;
- sz = (buf->size + align-1) & ~(align-1);
+ sz = ALIGN(buf->size, align);
block->mem = mmAllocMem(pool->heap,
sz,
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index fb58c0e708..7a6293b557 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -37,7 +37,7 @@ static void intel_batchbuffer_reset( struct intel_batchbuffer *batch )
assert(batch->map == NULL);
batch->offset = (unsigned long)batch->ptr;
- batch->offset = (batch->offset + 63) & ~63;
+ batch->offset = ALIGN(batch->offset, 64);
batch->ptr = (unsigned char *) batch->offset;
if (BATCH_SZ - batch->offset < BATCH_REFILL) {
@@ -208,7 +208,7 @@ void intel_batchbuffer_align( struct intel_batchbuffer *batch,
GLuint sz )
{
unsigned long ptr = (unsigned long) batch->ptr;
- unsigned long aptr = (ptr + align) & ~((unsigned long)align-1);
+ unsigned long aptr = ALIGN(ptr, align);
GLuint fixup = aptr - ptr;
if (intel_batchbuffer_space(batch) < fixup + sz)
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
index 25e0a65e99..c40cad9638 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
@@ -121,6 +121,12 @@ void intel_batchbuffer_align( struct intel_batchbuffer *batch,
#define BATCH_LOCALS
#define BEGIN_BATCH(n, flags) intel_batchbuffer_require_space(intel->batch, n*4, flags)
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
+
+#define OUT_RELOC(buf, flags, delta) do { \
+ assert((delta) >= 0); \
+ OUT_BATCH(bmBufferOffset(intel, buf) + delta); \
+} while (0)
+
#define ADVANCE_BATCH() do { } while(0)
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
index f88cbb2328..31fe20fb2a 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.c
+++ b/src/mesa/drivers/dri/i965/intel_blit.c
@@ -49,7 +49,7 @@
/*
* Copy the back buffer to the front buffer.
*/
-void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
+void intelCopyBuffer( __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect )
{
struct intel_context *intel;
@@ -76,7 +76,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
if (!rect)
{
UNLOCK_HARDWARE( intel );
- driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, &missed_target );
LOCK_HARDWARE( intel );
}
@@ -110,8 +110,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
}
else {
BR13 = (0xCC << 16) | (1<<24) | (1<<25);
- CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
if (src->tiled) {
@@ -145,10 +144,10 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
OUT_BATCH( dst_pitch | BR13 );
OUT_BATCH( (tmp.y1 << 16) | tmp.x1 );
OUT_BATCH( (tmp.y2 << 16) | tmp.x2 );
- OUT_BATCH( bmBufferOffset(intel, dst->buffer) );
+ OUT_RELOC( dst->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, 0 );
OUT_BATCH( (tmp.y1 << 16) | tmp.x1 );
OUT_BATCH( src_pitch );
- OUT_BATCH( bmBufferOffset(intel, src->buffer) );
+ OUT_RELOC( src->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0 );
ADVANCE_BATCH();
}
}
@@ -199,8 +198,7 @@ void intelEmitFillBlit( struct intel_context *intel,
break;
case 4:
BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
- CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
+ CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
return;
@@ -216,7 +214,7 @@ void intelEmitFillBlit( struct intel_context *intel,
OUT_BATCH( dst_pitch | BR13 );
OUT_BATCH( (y << 16) | x );
OUT_BATCH( ((y+h) << 16) | (x+w) );
- OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset );
+ OUT_RELOC( dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset );
OUT_BATCH( color );
ADVANCE_BATCH();
}
@@ -290,8 +288,7 @@ void intelEmitCopyBlit( struct intel_context *intel,
case 4:
BR13 = (translate_raster_op(logic_op) << 16) | (1<<24) |
(1<<25);
- CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
return;
@@ -328,10 +325,12 @@ void intelEmitCopyBlit( struct intel_context *intel,
OUT_BATCH( dst_pitch | BR13 );
OUT_BATCH( (dst_y << 16) | dst_x );
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
- OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset );
+ OUT_RELOC( dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ dst_offset );
OUT_BATCH( (src_y << 16) | src_x );
OUT_BATCH( src_pitch );
- OUT_BATCH( bmBufferOffset(intel, src_buffer) + src_offset );
+ OUT_RELOC( src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ src_offset );
ADVANCE_BATCH();
}
else {
@@ -340,10 +339,11 @@ void intelEmitCopyBlit( struct intel_context *intel,
OUT_BATCH( (dst_pitch & 0xffff) | BR13 );
OUT_BATCH( (0 << 16) | dst_x );
OUT_BATCH( (h << 16) | dst_x2 );
- OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset + dst_y * dst_pitch );
- OUT_BATCH( (0 << 16) | src_x );
+ OUT_RELOC( dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ dst_offset + dst_y * dst_pitch );
OUT_BATCH( (src_pitch & 0xffff) );
- OUT_BATCH( bmBufferOffset(intel, src_buffer) + src_offset + src_y * src_pitch );
+ OUT_RELOC( src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ src_offset + src_y * src_pitch );
ADVANCE_BATCH();
}
}
@@ -388,12 +388,11 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
break;
case 4:
BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
- BACK_CMD = FRONT_CMD = (XY_COLOR_BLT_CMD |
- XY_COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
+ BACK_CMD = FRONT_CMD = XY_COLOR_BLT_CMD |
+ XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
DEPTH_CMD = XY_COLOR_BLT_CMD;
- if (flags & BUFFER_BIT_DEPTH) DEPTH_CMD |= XY_COLOR_BLT_WRITE_RGB;
- if (flags & BUFFER_BIT_STENCIL) DEPTH_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
+ if (flags & BUFFER_BIT_DEPTH) DEPTH_CMD |= XY_BLT_WRITE_RGB;
+ if (flags & BUFFER_BIT_STENCIL) DEPTH_CMD |= XY_BLT_WRITE_ALPHA;
break;
default:
return;
@@ -484,7 +483,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
OUT_BATCH( front_pitch | BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
- OUT_BATCH( bmBufferOffset(intel, front->buffer) );
+ OUT_RELOC( front->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ 0 );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
@@ -495,7 +495,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
OUT_BATCH( back_pitch | BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
- OUT_BATCH( bmBufferOffset(intel, back->buffer) );
+ OUT_RELOC( back->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ 0 );
OUT_BATCH( clear_color );
ADVANCE_BATCH();
}
@@ -506,7 +507,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
OUT_BATCH( depth_pitch | BR13 );
OUT_BATCH( (b.y1 << 16) | b.x1 );
OUT_BATCH( (b.y2 << 16) | b.x2 );
- OUT_BATCH( bmBufferOffset(intel, depth->buffer) );
+ OUT_RELOC( depth->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ 0 );
OUT_BATCH( clear_depth );
ADVANCE_BATCH();
}
@@ -517,11 +519,6 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
}
-
-#define BR13_565 0x1
-#define BR13_8888 0x3
-
-
void
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
@@ -535,9 +532,9 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLshort w, GLshort h,
GLenum logic_op)
{
- struct xy_setup_blit setup;
struct xy_text_immediate_blit text;
- int dwords = ((src_size + 7) & ~7) / 4;
+ int dwords = ALIGN(src_size, 8) / 4;
+ uint32_t opcode, br13;
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
@@ -554,31 +551,6 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
__FUNCTION__,
dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
- memset(&setup, 0, sizeof(setup));
-
- setup.br0.client = CLIENT_2D;
- setup.br0.opcode = OPCODE_XY_SETUP_BLT;
- setup.br0.write_alpha = (cpp == 4);
- setup.br0.write_rgb = (cpp == 4);
- setup.br0.dst_tiled = dst_tiled;
- setup.br0.length = (sizeof(setup) / sizeof(int)) - 2;
-
- setup.br13.dest_pitch = dst_pitch;
- setup.br13.rop = translate_raster_op(logic_op);
- setup.br13.color_depth = (cpp == 4) ? BR13_8888 : BR13_565;
- setup.br13.clipping_enable = 0;
- setup.br13.mono_source_transparency = 1;
-
- setup.dw2.clip_y1 = 0;
- setup.dw2.clip_x1 = 0;
- setup.dw3.clip_y2 = 100;
- setup.dw3.clip_x2 = 100;
-
- setup.dest_base_addr = bmBufferOffset(intel, dst_buffer) + dst_offset;
- setup.background_color = 0;
- setup.foreground_color = fg_color;
- setup.pattern_base_addr = 0;
-
memset(&text, 0, sizeof(text));
text.dw0.client = CLIENT_2D;
text.dw0.opcode = OPCODE_XY_TEXT_IMMEDIATE_BLT;
@@ -594,15 +566,33 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
text.dw2.dest_x2 = x + w;
intel_batchbuffer_require_space( intel->batch,
- sizeof(setup) +
+ (8 * 4) +
sizeof(text) +
dwords,
INTEL_BATCH_NO_CLIPRECTS );
- intel_batchbuffer_data( intel->batch,
- &setup,
- sizeof(setup),
- INTEL_BATCH_NO_CLIPRECTS );
+ opcode = XY_SETUP_BLT_CMD;
+ if (cpp == 4)
+ opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
+ if (dst_tiled)
+ opcode |= XY_DST_TILED;
+
+ br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
+ if (cpp == 2)
+ br13 |= BR13_565;
+ else
+ br13 |= BR13_8888;
+
+ BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
+ OUT_BATCH(opcode);
+ OUT_BATCH(br13);
+ OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
+ OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
+ OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset);
+ OUT_BATCH(0); /* bg */
+ OUT_BATCH(fg_color); /* fg */
+ OUT_BATCH(0); /* pattern base addr */
+ ADVANCE_BATCH();
intel_batchbuffer_data( intel->batch,
&text,
diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h
index e361545c8f..1412baf1c0 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.h
+++ b/src/mesa/drivers/dri/i965/intel_blit.h
@@ -33,7 +33,7 @@
struct buffer;
-extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv,
+extern void intelCopyBuffer( __DRIdrawablePrivate *dpriv,
const drm_clip_rect_t *rect );
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask);
diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c
index 6c8b073502..406aa93d06 100644
--- a/src/mesa/drivers/dri/i965/intel_buffers.c
+++ b/src/mesa/drivers/dri/i965/intel_buffers.c
@@ -33,6 +33,8 @@
#include "context.h"
#include "framebuffer.h"
#include "macros.h"
+#include "utils.h"
+#include "vblank.h"
#include "swrast/swrast.h"
GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
@@ -190,6 +192,50 @@ void intelWindowMoved( struct intel_context *intel )
}
}
+ /* Get updated plane info so we sync against the right vblank counter */
+ if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
+ drmI830Sarea *sarea = intel->sarea;
+ drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
+ .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
+ drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
+ .x2 = sarea->planeA_x + sarea->planeA_w,
+ .y2 = sarea->planeA_y + sarea->planeA_h };
+ drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
+ .x2 = sarea->planeB_x + sarea->planeB_w,
+ .y2 = sarea->planeB_y + sarea->planeB_h };
+ GLint areaA = driIntersectArea( drw_rect, planeA_rect );
+ GLint areaB = driIntersectArea( drw_rect, planeB_rect );
+ GLuint flags = dPriv->vblFlags;
+
+ /* Update vblank info
+ */
+ if (areaB > areaA || (areaA == areaB && areaB > 0)) {
+ flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
+ } else {
+ flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
+ }
+
+ /* Check to see if we changed pipes */
+ if (flags != dPriv->vblFlags && dPriv->vblFlags &&
+ !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+ int64_t count;
+
+ /*
+ * Update msc_base from old pipe
+ */
+ driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
+ dPriv->msc_base = count;
+ /*
+ * Then get new vblank_base and vblSeq values
+ */
+ dPriv->vblFlags = flags;
+ driGetCurrentVBlank(dPriv);
+ dPriv->vblank_base = dPriv->vblSeq;
+ }
+ } else {
+ dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
+ }
+
_mesa_resize_framebuffer(&intel->ctx,
(GLframebuffer*)dPriv->driverPrivate,
dPriv->w, dPriv->h);
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 2cf311c713..49431b2a0b 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -84,6 +84,11 @@ int INTEL_DEBUG = (0);
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_EXT_point_parameters
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_shader
+
#include "extension_helper.h"
#ifndef VERBOSE
@@ -190,6 +195,13 @@ const struct dri_extension card_extensions[] =
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
+ { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions},
+ { "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_fragment_shader", NULL },
+ /* XXX not implement yet, to compile builtin glsl lib */
+ { "GL_ARB_draw_buffers", NULL },
{ NULL, NULL }
};
@@ -330,8 +342,8 @@ GLboolean intelInitContext( struct intel_context *intel,
GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
- volatile drmI830Sarea *saPriv = (volatile drmI830Sarea *)
- (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
+ volatile drmI830Sarea *saPriv = (drmI830Sarea *)
+ (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
if (!_mesa_initialize_context(&intel->ctx,
mesaVis, shareCtx,
@@ -349,9 +361,6 @@ GLboolean intelInitContext( struct intel_context *intel,
driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
intel->driScreen->myNum, "i965");
- intel->vblank_flags = (intel->intelScreen->irq_active != 0)
- ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
-
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
if (getenv("INTEL_STRICT_CONFORMANCE")) {
@@ -498,7 +507,7 @@ GLboolean intelInitContext( struct intel_context *intel,
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
_mesa_enable_extension( ctx, "GL_S3_s3tc" );
}
- else if (driQueryOptionb (&intelScreen->optionCache, "force_s3tc_enable")) {
+ else if (driQueryOptionb (&intel->optionCache, "force_s3tc_enable")) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
}
@@ -559,6 +568,8 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
#endif
/* free the Mesa context */
+ intel->ctx.VertexProgram.Current = NULL;
+ intel->ctx.FragmentProgram.Current = NULL;
_mesa_destroy_context(&intel->ctx);
}
@@ -583,12 +594,16 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
}
if ( intel->driDrawable != driDrawPriv ) {
- /* Shouldn't the readbuffer be stored also? */
- driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
- &intel->vbl_seq );
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
+ ? driGetDefaultVBlankFlags(&intel->optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+ driDrawableInitVBlank( driDrawPriv );
+ }
intel->driDrawable = driDrawPriv;
intelWindowMoved( intel );
+ /* Shouldn't the readbuffer be stored also? */
}
_mesa_make_current(&intel->ctx,
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index f63c2f613d..5848d0c1ba 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -231,11 +231,6 @@ struct intel_context
*/
driOptionCache optionCache;
- /* VBI
- */
- GLuint vbl_seq;
- GLuint vblank_flags;
-
int64_t swap_ust;
int64_t swap_missed_ust;
@@ -252,6 +247,8 @@ void UNLOCK_HARDWARE( struct intel_context *intel );
#define SUBPIXEL_X 0.125
#define SUBPIXEL_Y 0.125
+#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
+
/* ================================================================
* Color packing:
*/
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 0fb33e27f4..268a982a97 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -233,8 +233,8 @@ GLboolean intel_miptree_image_data(struct intel_context *intel,
if (dst->compressed) {
alignment = intel_compressed_alignment(dst->internal_format);
- src_row_pitch = ((src_row_pitch + alignment - 1) & ~(alignment - 1));
- width = ((width + alignment - 1) & ~(alignment - 1));
+ src_row_pitch = ALIGN(src_row_pitch, alignment);
+ width = ALIGN(width, alignment);
height = (height + 3) / 4;
}
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
index 79c1fee9c0..3777422619 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
@@ -91,11 +91,6 @@ static void set_bit( GLubyte *dest,
dest[bit/8] |= 1 << (bit % 8);
}
-static int align(int x, int align)
-{
- return (x + align - 1) & ~(align - 1);
-}
-
/* Extract a rectangle's worth of data from the bitmap. Called
* per-cliprect.
*/
@@ -147,7 +142,7 @@ static GLuint get_bitmap_rect(GLsizei width, GLsizei height,
}
if (row_align)
- bit = (bit + row_align - 1) & ~(row_align - 1);
+ bit = ALIGN(bit, row_align);
}
return count;
@@ -268,7 +263,7 @@ do_blit_bitmap( GLcontext *ctx,
for (px = 0; px < box_w; px += DX) {
int h = MIN2(DY, box_h - py);
int w = MIN2(DX, box_w - px);
- GLuint sz = align(align(w,8) * h, 64)/8;
+ GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
ctx->Color.LogicOp : GL_COPY;
diff --git a/src/mesa/drivers/dri/i965/intel_reg.h b/src/mesa/drivers/dri/i965/intel_reg.h
deleted file mode 100644
index 3c448b3559..0000000000
--- a/src/mesa/drivers/dri/i965/intel_reg.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef _INTEL_REG_H_
-#define _INTEL_REG_H_
-
-
-
-#define CMD_3D (0x3<<29)
-
-
-#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24))
-#define PRIM_INDIRECT (1<<23)
-#define PRIM_INLINE (0<<23)
-#define PRIM_INDIRECT_SEQUENTIAL (0<<17)
-#define PRIM_INDIRECT_ELTS (1<<17)
-
-#define PRIM3D_TRILIST (0x0<<18)
-#define PRIM3D_TRISTRIP (0x1<<18)
-#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
-#define PRIM3D_TRIFAN (0x3<<18)
-#define PRIM3D_POLY (0x4<<18)
-#define PRIM3D_LINELIST (0x5<<18)
-#define PRIM3D_LINESTRIP (0x6<<18)
-#define PRIM3D_RECTLIST (0x7<<18)
-#define PRIM3D_POINTLIST (0x8<<18)
-#define PRIM3D_DIB (0x9<<18)
-#define PRIM3D_MASK (0x1f<<18)
-
-#define I915PACKCOLOR4444(r,g,b,a) \
- ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
-
-#define I915PACKCOLOR1555(r,g,b,a) \
- ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
- ((a) ? 0x8000 : 0))
-
-#define I915PACKCOLOR565(r,g,b) \
- ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
-
-#define I915PACKCOLOR8888(r,g,b,a) \
- ((a<<24) | (r<<16) | (g<<8) | b)
-
-
-
-
-#define BR00_BITBLT_CLIENT 0x40000000
-#define BR00_OP_COLOR_BLT 0x10000000
-#define BR00_OP_SRC_COPY_BLT 0x10C00000
-#define BR13_SOLID_PATTERN 0x80000000
-
-#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
-#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
-#define XY_COLOR_BLT_WRITE_RGB (1<<20)
-
-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
-
-#define XY_SRC_TILED (1<<15)
-#define XY_DST_TILED (1<<11)
-
-#define FENCE_LINEAR 0
-#define FENCE_XMAJOR 1
-#define FENCE_YMAJOR 2
-
-#endif
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 5dac50df32..77fd9e386a 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -264,14 +264,19 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
intelPrintSAREA(sarea);
}
+static const __DRIextension *intelExtensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+};
static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen;
I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void * const psc = sPriv->psc->screenConfigs;
volatile drmI830Sarea *sarea;
if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
@@ -317,7 +322,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
return GL_FALSE;
}
- intelScreen->drmMinor = sPriv->drmMinor;
+ intelScreen->drmMinor = sPriv->drm_version.minor;
/* Determine if IRQs are active? */
{
@@ -351,14 +356,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
}
}
- if (glx_enable_extension != NULL) {
- (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
- (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
- (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
- (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" );
- }
+ sPriv->extensions = intelExtensions;
return GL_TRUE;
}
@@ -541,7 +539,6 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
static const struct __DriverAPIRec intelAPI = {
- .InitDriver = intelInitDriver,
.DestroyScreen = intelDestroyScreen,
.CreateContext = intelCreateContext,
.DestroyContext = intelDestroyContext,
@@ -552,6 +549,7 @@ static const struct __DriverAPIRec intelAPI = {
.UnbindContext = intelUnbindContext,
.GetSwapInfo = intelGetSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
@@ -640,62 +638,44 @@ intelFillInModes( unsigned pixel_bits, unsigned depth_bits,
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 6, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 3, 0 };
+ I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
- dri_interface = interface;
-
+ psp->DriverAPI = intelAPI;
if ( ! driCheckDriDdxDrmVersions2( "i915",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
- return NULL;
+ &psp->dri_version, &dri_expected,
+ &psp->ddx_version, &ddx_expected,
+ &psp->drm_version, &drm_expected ) ) {
+ return NULL;
}
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &intelAPI);
- if ( psp != NULL ) {
- I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
- *driver_modes = intelFillInModes( dri_priv->cpp * 8,
- (dri_priv->cpp == 2) ? 16 : 24,
- (dri_priv->cpp == 2) ? 0 : 8,
- GL_TRUE );
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- intelInitExtensions(NULL, GL_FALSE);
- }
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ intelInitExtensions(NULL, GL_FALSE);
+
+ if (!intelInitDriver(psp))
+ return NULL;
- return (void *) psp;
+ return intelFillInModes( dri_priv->cpp * 8,
+ (dri_priv->cpp == 2) ? 16 : 24,
+ (dri_priv->cpp == 2) ? 0 : 8,
+ GL_TRUE );
}
diff --git a/src/mesa/drivers/dri/i965/server/intel_dri.c b/src/mesa/drivers/dri/i965/server/intel_dri.c
new file mode 120000
index 0000000000..a2043afb47
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/server/intel_dri.c
@@ -0,0 +1 @@
+../intel/server/intel_dri.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i915/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h
index 7828ba6ad3..b9bbcdc704 100644
--- a/src/mesa/drivers/dri/i915/intel_reg.h
+++ b/src/mesa/drivers/dri/intel/intel_reg.h
@@ -25,16 +25,19 @@
*
**************************************************************************/
+#define CMD_MI (0x0 << 29)
+#define CMD_2D (0x2 << 29)
+#define CMD_3D (0x3 << 29)
-#ifndef _INTEL_REG_H_
-#define _INTEL_REG_H_
-
-
-
-#define CMD_3D (0x3<<29)
+#define MI_BATCH_BUFFER_END (CMD_MI | 0xA << 23)
+/* Stalls command execution waiting for the given events to have occurred. */
+#define MI_WAIT_FOR_EVENT (CMD_MI | (0x3 << 23))
+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
-#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24))
+/* Primitive dispatch on 830-945 */
+#define _3DPRIMITIVE (CMD_3D | (0x1f << 24))
#define PRIM_INDIRECT (1<<23)
#define PRIM_INLINE (0<<23)
#define PRIM_INDIRECT_SEQUENTIAL (0<<17)
@@ -52,37 +55,22 @@
#define PRIM3D_DIB (0x9<<18)
#define PRIM3D_MASK (0x1f<<18)
-#define I915PACKCOLOR4444(r,g,b,a) \
- ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
-
-#define I915PACKCOLOR1555(r,g,b,a) \
- ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
- ((a) ? 0x8000 : 0))
-
-#define I915PACKCOLOR565(r,g,b) \
- ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+#define XY_SETUP_BLT_CMD (CMD_2D | (0x011 << 22) | 6)
-#define I915PACKCOLOR8888(r,g,b,a) \
- ((a<<24) | (r<<16) | (g<<8) | b)
+#define XY_COLOR_BLT_CMD (CMD_2D | (0x50 << 22) | 4)
+#define XY_SRC_COPY_BLT_CMD (CMD_2D | (0x53 << 22) | 6)
+/* BR00 */
+#define XY_BLT_WRITE_ALPHA (1 << 21)
+#define XY_BLT_WRITE_RGB (1 << 20)
+#define XY_SRC_TILED (1 << 15)
+#define XY_DST_TILED (1 << 11)
+/* BR13 */
+#define BR13_565 (0x1 << 24)
+#define BR13_8888 (0x3 << 24)
-#define BR00_BITBLT_CLIENT 0x40000000
-#define BR00_OP_COLOR_BLT 0x10000000
-#define BR00_OP_SRC_COPY_BLT 0x10C00000
-#define BR13_SOLID_PATTERN 0x80000000
-
-#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
-#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
-#define XY_COLOR_BLT_WRITE_RGB (1<<20)
-
-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
-
-#define MI_WAIT_FOR_EVENT ((0x3<<23))
-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
-
-#endif
+#define FENCE_LINEAR 0
+#define FENCE_XMAJOR 1
+#define FENCE_YMAJOR 2
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index fdecd3e186..4da636021b 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -32,14 +32,9 @@
#include "intel_mipmap_tree.h"
#include "intel_tex_layout.h"
+#include "intel_context.h"
#include "macros.h"
-
-static int align(int value, int alignment)
-{
- return (value + alignment - 1) & ~(alignment - 1);
-}
-
GLuint intel_compressed_alignment(GLenum internalFormat)
{
GLuint alignment = 4;
@@ -70,7 +65,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
if (mt->compressed) {
align_w = intel_compressed_alignment(mt->internal_format);
- mt->pitch = align(mt->width0, align_w);
+ mt->pitch = ALIGN(mt->width0, align_w);
}
/* May need to adjust pitch to accomodate the placement of
@@ -82,10 +77,10 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
GLuint mip1_width;
if (mt->compressed) {
- mip1_width = align(minify(mt->width0), align_w)
- + align(minify(minify(mt->width0)), align_w);
+ mip1_width = ALIGN(minify(mt->width0), align_w)
+ + ALIGN(minify(minify(mt->width0)), align_w);
} else {
- mip1_width = align(minify(mt->width0), align_w)
+ mip1_width = ALIGN(minify(mt->width0), align_w)
+ minify(minify(mt->width0));
}
@@ -97,7 +92,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
+ mt->pitch = ALIGN(mt->pitch * mt->cpp, 4) / mt->cpp;
mt->total_height = 0;
for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
@@ -109,7 +104,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
if (mt->compressed)
img_height = MAX2(1, height/4);
else
- img_height = align(height, align_h);
+ img_height = ALIGN(height, align_h);
/* Because the images are packed better, the final offset
@@ -120,7 +115,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
/* Layout_below: step right after second mipmap.
*/
if (level == mt->first_level + 1) {
- x += align(width, align_w);
+ x += ALIGN(width, align_w);
}
else {
y += img_height;
diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/intel/server/i830_common.h
index f1fd3939ab..f1fd3939ab 100644
--- a/src/mesa/drivers/dri/i915/server/i830_common.h
+++ b/src/mesa/drivers/dri/intel/server/i830_common.h
diff --git a/src/mesa/drivers/dri/i915/server/i830_dri.h b/src/mesa/drivers/dri/intel/server/i830_dri.h
index c2a3af8cbf..c2a3af8cbf 100644
--- a/src/mesa/drivers/dri/i915/server/i830_dri.h
+++ b/src/mesa/drivers/dri/intel/server/i830_dri.h
diff --git a/src/mesa/drivers/dri/i915/server/intel.h b/src/mesa/drivers/dri/intel/server/intel.h
index 6ea72499c1..6ea72499c1 100644
--- a/src/mesa/drivers/dri/i915/server/intel.h
+++ b/src/mesa/drivers/dri/intel/server/intel.h
diff --git a/src/mesa/drivers/dri/intel/server/intel_dri.c b/src/mesa/drivers/dri/intel/server/intel_dri.c
new file mode 100644
index 0000000000..e49c4214ad
--- /dev/null
+++ b/src/mesa/drivers/dri/intel/server/intel_dri.c
@@ -0,0 +1,1306 @@
+/**
+ * \file server/intel_dri.c
+ * \brief File to perform the device-specific initialization tasks typically
+ * done in the X server.
+ *
+ * Here they are converted to run in the client (or perhaps a standalone
+ * process), and to work with the frame buffer device rather than the X
+ * server infrastructure.
+ *
+ * Copyright (C) 2006 Dave Airlie (airlied@linux.ie)
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sub license, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial portions
+ of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "driver.h"
+#include "drm.h"
+
+#include "intel.h"
+#include "i830_dri.h"
+
+#include "memops.h"
+#include "pciaccess.h"
+
+static size_t drm_page_size;
+static int nextTile = 0;
+#define xf86DrvMsg(...) do {} while(0)
+
+static const int pitches[] = {
+ 128 * 8,
+ 128 * 16,
+ 128 * 32,
+ 128 * 64,
+ 0
+};
+
+static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea);
+
+static unsigned long
+GetBestTileAlignment(unsigned long size)
+{
+ unsigned long i;
+
+ for (i = KB(512); i < size; i <<= 1)
+ ;
+
+ if (i > MB(64))
+ i = MB(64);
+
+ return i;
+}
+
+static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ int i;
+ unsigned char *MMIO = ctx->MMIOAddress;
+
+ for (i = 0; i < 8; i++) {
+ OUTREG(FENCE + i * 4, pI830->Fence[i]);
+ // if (I810_DEBUG & DEBUG_VERBOSE_VGA)
+ fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]);
+ }
+}
+
+/* Tiled memory is good... really, really good...
+ *
+ * Need to make it less likely that we miss out on this - probably
+ * need to move the frontbuffer away from the 'guarenteed' alignment
+ * of the first memory segment, or perhaps allocate a discontigous
+ * framebuffer to get more alignment 'sweet spots'.
+ */
+static void
+SetFence(const DRIDriverContext *ctx, I830Rec *pI830,
+ int nr, unsigned int start, unsigned int pitch,
+ unsigned int size)
+{
+ unsigned int val;
+ unsigned int fence_mask = 0;
+ unsigned int fence_pitch;
+
+ if (nr < 0 || nr > 7) {
+ fprintf(stderr,
+ "SetFence: fence %d out of range\n",nr);
+ return;
+ }
+
+ pI830->Fence[nr] = 0;
+
+ if (IS_I9XX(pI830))
+ fence_mask = ~I915G_FENCE_START_MASK;
+ else
+ fence_mask = ~I830_FENCE_START_MASK;
+
+ if (start & fence_mask) {
+ fprintf(stderr,
+ "SetFence: %d: start (0x%08x) is not %s aligned\n",
+ nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
+ return;
+ }
+
+ if (start % size) {
+ fprintf(stderr,
+ "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n",
+ nr, start, size / 1024);
+ return;
+ }
+
+ if (pitch & 127) {
+ fprintf(stderr,
+ "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n",
+ nr, pitch);
+ return;
+ }
+
+ val = (start | FENCE_X_MAJOR | FENCE_VALID);
+
+ if (IS_I9XX(pI830)) {
+ switch (size) {
+ case MB(1):
+ val |= I915G_FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= I915G_FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= I915G_FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= I915G_FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= I915G_FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= I915G_FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= I915G_FENCE_SIZE_64M;
+ break;
+ default:
+ fprintf(stderr,
+ "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
+ return;
+ }
+ } else {
+ switch (size) {
+ case KB(512):
+ val |= FENCE_SIZE_512K;
+ break;
+ case MB(1):
+ val |= FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= FENCE_SIZE_64M;
+ break;
+ default:
+ fprintf(stderr,
+ "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
+ return;
+ }
+ }
+
+ if (IS_I9XX(pI830))
+ fence_pitch = pitch / 512;
+ else
+ fence_pitch = pitch / 128;
+
+ switch (fence_pitch) {
+ case 1:
+ val |= FENCE_PITCH_1;
+ break;
+ case 2:
+ val |= FENCE_PITCH_2;
+ break;
+ case 4:
+ val |= FENCE_PITCH_4;
+ break;
+ case 8:
+ val |= FENCE_PITCH_8;
+ break;
+ case 16:
+ val |= FENCE_PITCH_16;
+ break;
+ case 32:
+ val |= FENCE_PITCH_32;
+ break;
+ case 64:
+ val |= FENCE_PITCH_64;
+ break;
+ default:
+ fprintf(stderr,
+ "SetFence: %d: illegal pitch (%d)\n", nr, pitch);
+ return;
+ }
+
+ pI830->Fence[nr] = val;
+}
+
+static Bool
+MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem)
+{
+ int pitch, ntiles, i;
+
+ pitch = pMem->Pitch * ctx->cpp;
+ /*
+ * Simply try to break the region up into at most four pieces of size
+ * equal to the alignment.
+ */
+ ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment;
+ if (ntiles >= 4) {
+ return FALSE;
+ }
+
+ for (i = 0; i < ntiles; i++, nextTile++) {
+ SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment,
+ pitch, pMem->Alignment);
+ }
+ return TRUE;
+}
+
+static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ int i;
+
+ /* Clear out */
+ for (i = 0; i < 8; i++)
+ pI830->Fence[i] = 0;
+
+ nextTile = 0;
+
+ if (pI830->BackBuffer.Alignment >= KB(512)) {
+ if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) {
+ fprintf(stderr,
+ "Activating tiled memory for the back buffer.\n");
+ } else {
+ fprintf(stderr,
+ "MakeTiles failed for the back buffer.\n");
+ pI830->allowPageFlip = FALSE;
+ }
+ }
+
+ if (pI830->DepthBuffer.Alignment >= KB(512)) {
+ if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) {
+ fprintf(stderr,
+ "Activating tiled memory for the depth buffer.\n");
+ } else {
+ fprintf(stderr,
+ "MakeTiles failed for the depth buffer.\n");
+ }
+ }
+
+ return;
+}
+
+static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ struct pci_device host_bridge, ig_dev;
+ uint32_t gmch_ctrl;
+ int memsize = 0;
+ int range;
+ uint32_t aper_size;
+ uint32_t membase2 = 0;
+
+ memset(&host_bridge, 0, sizeof(host_bridge));
+ memset(&ig_dev, 0, sizeof(ig_dev));
+
+ ig_dev.dev = 2;
+
+ pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL);
+
+ if (IS_I830(pI830) || IS_845G(pI830)) {
+ if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
+ aper_size = 0x80000000;
+ } else {
+ aper_size = 0x40000000;
+ }
+ } else {
+ if (IS_I9XX(pI830)) {
+ int ret;
+ ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18);
+ if (membase2 & 0x08000000)
+ aper_size = 0x8000000;
+ else
+ aper_size = 0x10000000;
+
+ fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret);
+ } else
+ aper_size = 0x8000000;
+ }
+
+ pI830->aper_size = aper_size;
+
+
+ /* We need to reduce the stolen size, by the GTT and the popup.
+ * The GTT varying according the the FbMapSize and the popup is 4KB */
+ range = (ctx->shared.fbSize / (1024*1024)) + 4;
+
+ if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
+ switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+ case I855_GMCH_GMS_STOLEN_1M:
+ memsize = MB(1) - KB(range);
+ break;
+ case I855_GMCH_GMS_STOLEN_4M:
+ memsize = MB(4) - KB(range);
+ break;
+ case I855_GMCH_GMS_STOLEN_8M:
+ memsize = MB(8) - KB(range);
+ break;
+ case I855_GMCH_GMS_STOLEN_16M:
+ memsize = MB(16) - KB(range);
+ break;
+ case I855_GMCH_GMS_STOLEN_32M:
+ memsize = MB(32) - KB(range);
+ break;
+ case I915G_GMCH_GMS_STOLEN_48M:
+ if (IS_I9XX(pI830))
+ memsize = MB(48) - KB(range);
+ break;
+ case I915G_GMCH_GMS_STOLEN_64M:
+ if (IS_I9XX(pI830))
+ memsize = MB(64) - KB(range);
+ break;
+ }
+ } else {
+ switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+ case I830_GMCH_GMS_STOLEN_512:
+ memsize = KB(512) - KB(range);
+ break;
+ case I830_GMCH_GMS_STOLEN_1024:
+ memsize = MB(1) - KB(range);
+ break;
+ case I830_GMCH_GMS_STOLEN_8192:
+ memsize = MB(8) - KB(range);
+ break;
+ case I830_GMCH_GMS_LOCAL:
+ memsize = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Local memory found, but won't be used.\n");
+ break;
+ }
+ }
+ if (memsize > 0) {
+ fprintf(stderr,
+ "detected %d kB stolen memory.\n", memsize / 1024);
+ } else {
+ fprintf(stderr,
+ "no video memory detected.\n");
+ }
+ return memsize;
+}
+
+static int AgpInit(const DRIDriverContext *ctx, I830Rec *info)
+{
+ unsigned long mode = 0x4;
+
+ if (drmAgpAcquire(ctx->drmFD) < 0) {
+ fprintf(stderr, "[gart] AGP not available\n");
+ return 0;
+ }
+
+ if (drmAgpEnable(ctx->drmFD, mode) < 0) {
+ fprintf(stderr, "[gart] AGP not enabled\n");
+ drmAgpRelease(ctx->drmFD);
+ return 0;
+ }
+ else
+ fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode);
+
+ return 1;
+}
+
+/*
+ * Allocate memory from the given pool. Grow the pool if needed and if
+ * possible.
+ */
+static unsigned long
+AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830,
+ I830MemRange *result, I830MemPool *pool,
+ long size, unsigned long alignment, int flags)
+{
+ long needed, start, end;
+
+ if (!result || !pool || !size)
+ return 0;
+
+ /* Calculate how much space is needed. */
+ if (alignment <= GTT_PAGE_SIZE)
+ needed = size;
+ else {
+ start = ROUND_TO(pool->Free.Start, alignment);
+ end = ROUND_TO(start + size, alignment);
+ needed = end - pool->Free.Start;
+ }
+ if (needed > pool->Free.Size) {
+ return 0;
+ }
+
+ result->Start = ROUND_TO(pool->Free.Start, alignment);
+ pool->Free.Start += needed;
+ result->End = pool->Free.Start;
+
+ pool->Free.Size = pool->Free.End - pool->Free.Start;
+ result->Size = result->End - result->Start;
+ result->Pool = pool;
+ result->Alignment = alignment;
+ return needed;
+}
+
+static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result)
+{
+ unsigned long start, end;
+ unsigned long newApStart, newApEnd;
+ int ret;
+ if (!result || !size)
+ return 0;
+
+ if (!alignment)
+ alignment = 4;
+
+ start = ROUND_TO(pI830->MemoryAperture.Start, alignment);
+ end = ROUND_TO(start + size, alignment);
+ newApStart = end;
+ newApEnd = pI830->MemoryAperture.End;
+
+ ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key));
+
+ if (ret)
+ {
+ fprintf(stderr,"drmAgpAlloc failed %d\n", ret);
+ return 0;
+ }
+ pI830->allocatedMemory += size;
+ pI830->MemoryAperture.Start = newApStart;
+ pI830->MemoryAperture.End = newApEnd;
+ pI830->MemoryAperture.Size = newApEnd - newApStart;
+ // pI830->FreeMemory -= size;
+ result->Start = start;
+ result->End = start + size;
+ result->Size = size;
+ result->Offset = start;
+ result->Alignment = alignment;
+ result->Pool = NULL;
+
+ return size;
+}
+
+unsigned long
+I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830,
+ I830MemRange *result, I830MemPool *pool, long size,
+ unsigned long alignment, int flags)
+{
+ unsigned long ret;
+
+ if (!result)
+ return 0;
+
+ /* Make sure these are initialised. */
+ result->Size = 0;
+ result->Key = -1;
+
+ if (!size) {
+ return 0;
+ }
+
+ if (pool->Free.Size < size) {
+ ret = AllocFromAGP(ctx, pI830, size, alignment, result);
+ }
+ else {
+ ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags);
+ if (ret == 0)
+ ret = AllocFromAGP(ctx, pI830, size, alignment, result);
+ }
+ return ret;
+}
+
+static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem)
+{
+ if (!mem)
+ return FALSE;
+
+ if (mem->Key == -1)
+ return TRUE;
+
+ return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset);
+}
+
+/* simple memory allocation routines needed */
+/* put ring buffer in low memory */
+/* need to allocate front, back, depth buffers aligned correctly,
+ allocate ring buffer,
+*/
+
+/* */
+static Bool
+I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ unsigned long size, ret;
+ unsigned long lines, lineSize, align;
+
+ /* allocate ring buffer */
+ memset(pI830->LpRing, 0, sizeof(I830RingBuffer));
+ pI830->LpRing->mem.Key = -1;
+
+ size = PRIMARY_RINGBUFFER_SIZE;
+
+ ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0);
+
+ if (ret != size)
+ {
+ fprintf(stderr,"unable to allocate ring buffer %ld\n", ret);
+ return FALSE;
+ }
+
+ pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1;
+
+
+ /* allocate front buffer */
+ memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
+ pI830->FrontBuffer.Key = -1;
+ pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth;
+
+ align = KB(512);
+
+ lineSize = ctx->shared.virtualWidth * ctx->cpp;
+ lines = (ctx->shared.virtualHeight + 15) / 16 * 16;
+ size = lineSize * lines;
+ size = ROUND_TO_PAGE(size);
+
+ align = GetBestTileAlignment(size);
+
+ ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
+ {
+ fprintf(stderr,"unable to allocate front buffer %ld\n", ret);
+ return FALSE;
+ }
+
+ memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
+ pI830->BackBuffer.Key = -1;
+ pI830->BackBuffer.Pitch = ctx->shared.virtualWidth;
+
+ ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
+ {
+ fprintf(stderr,"unable to allocate back buffer %ld\n", ret);
+ return FALSE;
+ }
+
+ memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
+ pI830->DepthBuffer.Key = -1;
+ pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth;
+
+ ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
+ {
+ fprintf(stderr,"unable to allocate depth buffer %ld\n", ret);
+ return FALSE;
+ }
+
+ memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
+ pI830->ContextMem.Key = -1;
+ size = KB(32);
+
+ ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0);
+ if (ret < size)
+ {
+ fprintf(stderr,"unable to allocate context buffer %ld\n", ret);
+ return FALSE;
+ }
+
+#if 0
+ memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
+ pI830->TexMem.Key = -1;
+
+ size = 32768 * 1024;
+ ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem);
+ if (ret < size)
+ {
+ fprintf(stderr,"unable to allocate texture memory %ld\n", ret);
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+static Bool
+I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ if (!BindAgpRange(ctx, &pI830->LpRing->mem))
+ return FALSE;
+ if (!BindAgpRange(ctx, &pI830->FrontBuffer))
+ return FALSE;
+ if (!BindAgpRange(ctx, &pI830->BackBuffer))
+ return FALSE;
+ if (!BindAgpRange(ctx, &pI830->DepthBuffer))
+ return FALSE;
+ if (!BindAgpRange(ctx, &pI830->ContextMem))
+ return FALSE;
+#if 0
+ if (!BindAgpRange(ctx, &pI830->TexMem))
+ return FALSE;
+#endif
+ return TRUE;
+}
+
+static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
+ unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
+
+ fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize);
+ if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) {
+ fprintf(stderr,
+ "DRM MM Initialization Failed\n");
+ } else {
+ fprintf(stderr,
+ "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart);
+ }
+
+}
+
+static Bool
+I830CleanupDma(const DRIDriverContext *ctx)
+{
+ drmI830Init info;
+
+ memset(&info, 0, sizeof(drmI830Init));
+ info.func = I830_CLEANUP_DMA;
+
+ if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
+ &info, sizeof(drmI830Init))) {
+ fprintf(stderr, "I830 Dma Cleanup Failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ I830RingBuffer *ring = pI830->LpRing;
+ drmI830Init info;
+
+ memset(&info, 0, sizeof(drmI830Init));
+ info.func = I830_INIT_DMA;
+
+ info.ring_start = ring->mem.Start + pI830->LinearAddr;
+ info.ring_end = ring->mem.End + pI830->LinearAddr;
+ info.ring_size = ring->mem.Size;
+
+ info.mmio_offset = (unsigned int)ctx->MMIOStart;
+
+ info.sarea_priv_offset = sizeof(drm_sarea_t);
+
+ info.front_offset = pI830->FrontBuffer.Start;
+ info.back_offset = pI830->BackBuffer.Start;
+ info.depth_offset = pI830->DepthBuffer.Start;
+ info.w = ctx->shared.virtualWidth;
+ info.h = ctx->shared.virtualHeight;
+ info.pitch = ctx->shared.virtualWidth;
+ info.back_pitch = pI830->BackBuffer.Pitch;
+ info.depth_pitch = pI830->DepthBuffer.Pitch;
+ info.cpp = ctx->cpp;
+
+ if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
+ &info, sizeof(drmI830Init))) {
+ fprintf(stderr,
+ "I830 Dma Initialization Failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int I830CheckDRMVersion( const DRIDriverContext *ctx,
+ I830Rec *pI830 )
+{
+ drmVersionPtr version;
+
+ version = drmGetVersion(ctx->drmFD);
+
+ if (version) {
+ int req_minor, req_patch;
+
+ req_minor = 4;
+ req_patch = 0;
+
+ if (version->version_major != 1 ||
+ version->version_minor < req_minor ||
+ (version->version_minor == req_minor &&
+ version->version_patchlevel < req_patch)) {
+ /* Incompatible drm version */
+ fprintf(stderr,
+ "[dri] I830DRIScreenInit failed because of a version "
+ "mismatch.\n"
+ "[dri] i915.o kernel module version is %d.%d.%d "
+ "but version 1.%d.%d or newer is needed.\n"
+ "[dri] Disabling DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel,
+ req_minor,
+ req_patch);
+ drmFreeVersion(version);
+ return 0;
+ }
+
+ pI830->drmMinor = version->version_minor;
+ drmFreeVersion(version);
+ }
+ return 1;
+}
+
+static void
+I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ unsigned int itemp;
+ unsigned char *MMIO = ctx->MMIOAddress;
+
+ OUTREG(LP_RING + RING_LEN, 0);
+ OUTREG(LP_RING + RING_TAIL, 0);
+ OUTREG(LP_RING + RING_HEAD, 0);
+
+ if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
+ pI830->LpRing->mem.Start) {
+ fprintf(stderr,
+ "I830SetRingRegs: Ring buffer start (%lx) violates its "
+ "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
+ }
+ /* Don't care about the old value. Reserved bits must be zero anyway. */
+ itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
+ OUTREG(LP_RING + RING_START, itemp);
+
+ if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
+ pI830->LpRing->mem.Size - 4096) {
+ fprintf(stderr,
+ "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
+ "mask (%x)\n", pI830->LpRing->mem.Size - 4096,
+ I830_RING_NR_PAGES);
+ }
+ /* Don't care about the old value. Reserved bits must be zero anyway. */
+ itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
+ itemp |= (RING_NO_REPORT | RING_VALID);
+ OUTREG(LP_RING + RING_LEN, itemp);
+
+ pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
+ pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
+ pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
+ if (pI830->LpRing->space < 0)
+ pI830->LpRing->space += pI830->LpRing->mem.Size;
+
+ SetFenceRegs(ctx, pI830);
+
+ /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky
+ hacky hacky */
+ OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr);
+
+}
+
+static Bool
+I830SetParam(const DRIDriverContext *ctx, int param, int value)
+{
+ drmI830SetParam sp;
+
+ memset(&sp, 0, sizeof(sp));
+ sp.param = param;
+ sp.value = value;
+
+ if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) {
+ fprintf(stderr, "I830 SetParam Failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
+{
+ fprintf(stderr,
+ "[drm] Mapping front buffer\n");
+
+ if (drmAddMap(ctx->drmFD,
+ (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
+ sarea->front_size,
+ DRM_FRAME_BUFFER, /*DRM_AGP,*/
+ 0,
+ &sarea->front_handle) < 0) {
+ fprintf(stderr,
+ "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
+ return FALSE;
+ }
+ ctx->shared.hFrameBuffer = sarea->front_handle;
+ ctx->shared.fbSize = sarea->front_size;
+ fprintf(stderr, "[drm] Front Buffer = 0x%08x\n",
+ sarea->front_handle);
+
+ if (drmAddMap(ctx->drmFD,
+ (drm_handle_t)(sarea->back_offset),
+ sarea->back_size, DRM_AGP, 0,
+ &sarea->back_handle) < 0) {
+ fprintf(stderr,
+ "[drm] drmAddMap(back_handle) failed. Disabling DRI\n");
+ return FALSE;
+ }
+ fprintf(stderr, "[drm] Back Buffer = 0x%08x\n",
+ sarea->back_handle);
+
+ if (drmAddMap(ctx->drmFD,
+ (drm_handle_t)sarea->depth_offset,
+ sarea->depth_size, DRM_AGP, 0,
+ &sarea->depth_handle) < 0) {
+ fprintf(stderr,
+ "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
+ return FALSE;
+ }
+ fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n",
+ sarea->depth_handle);
+
+#if 0
+ if (drmAddMap(ctx->drmFD,
+ (drm_handle_t)sarea->tex_offset,
+ sarea->tex_size, DRM_AGP, 0,
+ &sarea->tex_handle) < 0) {
+ fprintf(stderr,
+ "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
+ return FALSE;
+ }
+ fprintf(stderr, "[drm] textures = 0x%08x\n",
+ sarea->tex_handle);
+#endif
+ return TRUE;
+}
+
+
+static void
+I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
+{
+#if 1
+ if (sarea->front_handle) {
+ drmRmMap(ctx->drmFD, sarea->front_handle);
+ sarea->front_handle = 0;
+ }
+#endif
+ if (sarea->back_handle) {
+ drmRmMap(ctx->drmFD, sarea->back_handle);
+ sarea->back_handle = 0;
+ }
+ if (sarea->depth_handle) {
+ drmRmMap(ctx->drmFD, sarea->depth_handle);
+ sarea->depth_handle = 0;
+ }
+ if (sarea->tex_handle) {
+ drmRmMap(ctx->drmFD, sarea->tex_handle);
+ sarea->tex_handle = 0;
+ }
+}
+
+static Bool
+I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
+{
+ if (drmAddMap(ctx->drmFD,
+ (drm_handle_t)pI830->LpRing->mem.Start,
+ pI830->LpRing->mem.Size, DRM_AGP, 0,
+ &pI830->ring_map) < 0) {
+ fprintf(stderr,
+ "[drm] drmAddMap(ring_map) failed. Disabling DRI\n");
+ return FALSE;
+ }
+ fprintf(stderr, "[drm] ring buffer = 0x%08x\n",
+ pI830->ring_map);
+
+ if (I830InitDma(ctx, pI830) == FALSE) {
+ return FALSE;
+ }
+
+ /* init to zero to be safe */
+
+ I830DRIMapScreenRegions(ctx, pI830, sarea);
+ SetupDRIMM(ctx, pI830);
+
+ if (ctx->pciDevice != PCI_CHIP_845_G &&
+ ctx->pciDevice != PCI_CHIP_I830_M) {
+ I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 );
+ }
+
+ /* Okay now initialize the dma engine */
+ {
+ pI830->irq = drmGetInterruptFromBusID(ctx->drmFD,
+ ctx->pciBus,
+ ctx->pciDevice,
+ ctx->pciFunc);
+
+ if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) {
+ fprintf(stderr,
+ "[drm] failure adding irq handler\n");
+ pI830->irq = 0;
+ return FALSE;
+ }
+ else
+ fprintf(stderr,
+ "[drm] dma control initialized, using IRQ %d\n",
+ pI830->irq);
+ }
+
+ fprintf(stderr, "[dri] visual configs initialized\n");
+
+ return TRUE;
+}
+
+static Bool
+I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
+{
+ /* need to drmMap front and back buffers and zero them */
+ drmAddress map_addr;
+ int ret;
+
+ ret = drmMap(ctx->drmFD,
+ sarea->front_handle,
+ sarea->front_size,
+ &map_addr);
+
+ if (ret)
+ {
+ fprintf(stderr, "Unable to map front buffer\n");
+ return FALSE;
+ }
+
+ drimemsetio((char *)map_addr,
+ 0,
+ sarea->front_size);
+ drmUnmap(map_addr, sarea->front_size);
+
+
+ ret = drmMap(ctx->drmFD,
+ sarea->back_handle,
+ sarea->back_size,
+ &map_addr);
+
+ if (ret)
+ {
+ fprintf(stderr, "Unable to map back buffer\n");
+ return FALSE;
+ }
+
+ drimemsetio((char *)map_addr,
+ 0,
+ sarea->back_size);
+ drmUnmap(map_addr, sarea->back_size);
+
+ return TRUE;
+}
+
+static Bool
+I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
+
+{
+ I830DRIPtr pI830DRI;
+ drmI830Sarea *pSAREAPriv;
+ int err;
+
+ drm_page_size = getpagesize();
+
+ pI830->registerSize = ctx->MMIOSize;
+ /* This is a hack for now. We have to have more than a 4k page here
+ * because of the size of the state. However, the state should be
+ * in a per-context mapping. This will be added in the Mesa 3.5 port
+ * of the I830 driver.
+ */
+ ctx->shared.SAREASize = SAREA_MAX;
+
+ /* Note that drmOpen will try to load the kernel module, if needed. */
+ ctx->drmFD = drmOpen("i915", NULL );
+ if (ctx->drmFD < 0) {
+ fprintf(stderr, "[drm] drmOpen failed\n");
+ return 0;
+ }
+
+ if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
+ fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
+ ctx->drmFD, ctx->pciBusID, strerror(-err));
+ return 0;
+ }
+
+ if (drmAddMap( ctx->drmFD,
+ 0,
+ ctx->shared.SAREASize,
+ DRM_SHM,
+ DRM_CONTAINS_LOCK,
+ &ctx->shared.hSAREA) < 0)
+ {
+ fprintf(stderr, "[drm] drmAddMap failed\n");
+ return 0;
+ }
+
+ fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n",
+ ctx->shared.SAREASize, ctx->shared.hSAREA);
+
+ if (drmMap( ctx->drmFD,
+ ctx->shared.hSAREA,
+ ctx->shared.SAREASize,
+ (drmAddressPtr)(&ctx->pSAREA)) < 0)
+ {
+ fprintf(stderr, "[drm] drmMap failed\n");
+ return 0;
+
+ }
+
+ memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
+ fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n",
+ ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
+
+
+ if (drmAddMap(ctx->drmFD,
+ ctx->MMIOStart,
+ ctx->MMIOSize,
+ DRM_REGISTERS,
+ DRM_READ_ONLY,
+ &pI830->registerHandle) < 0) {
+ fprintf(stderr, "[drm] drmAddMap mmio failed\n");
+ return 0;
+ }
+ fprintf(stderr,
+ "[drm] register handle = 0x%08x\n", pI830->registerHandle);
+
+
+ if (!I830CheckDRMVersion(ctx, pI830)) {
+ return FALSE;
+ }
+
+ /* Create a 'server' context so we can grab the lock for
+ * initialization ioctls.
+ */
+ if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
+ fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
+ return 0;
+ }
+
+ DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
+
+ /* Initialize the SAREA private data structure */
+ pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) +
+ sizeof(drm_sarea_t));
+ memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+
+ pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830);
+ pI830->StolenMemory.Start = 0;
+ pI830->StolenMemory.End = pI830->StolenMemory.Size;
+
+ pI830->MemoryAperture.Start = pI830->StolenMemory.End;
+ pI830->MemoryAperture.End = KB(40000);
+ pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start;
+
+ pI830->StolenPool.Fixed = pI830->StolenMemory;
+ pI830->StolenPool.Total = pI830->StolenMemory;
+ pI830->StolenPool.Free = pI830->StolenPool.Total;
+ pI830->FreeMemory = pI830->StolenPool.Total.Size;
+
+ if (!AgpInit(ctx, pI830))
+ return FALSE;
+
+ if (I830AllocateMemory(ctx, pI830) == FALSE)
+ {
+ return FALSE;
+ }
+
+ if (I830BindMemory(ctx, pI830) == FALSE)
+ {
+ return FALSE;
+ }
+
+ pSAREAPriv->rotated_offset = -1;
+ pSAREAPriv->rotated_size = 0;
+ pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth;
+
+ pSAREAPriv->front_offset = pI830->FrontBuffer.Start;
+ pSAREAPriv->front_size = pI830->FrontBuffer.Size;
+ pSAREAPriv->width = ctx->shared.virtualWidth;
+ pSAREAPriv->height = ctx->shared.virtualHeight;
+ pSAREAPriv->pitch = ctx->shared.virtualWidth;
+ pSAREAPriv->virtualX = ctx->shared.virtualWidth;
+ pSAREAPriv->virtualY = ctx->shared.virtualHeight;
+ pSAREAPriv->back_offset = pI830->BackBuffer.Start;
+ pSAREAPriv->back_size = pI830->BackBuffer.Size;
+ pSAREAPriv->depth_offset = pI830->DepthBuffer.Start;
+ pSAREAPriv->depth_size = pI830->DepthBuffer.Size;
+#if 0
+ pSAREAPriv->tex_offset = pI830->TexMem.Start;
+ pSAREAPriv->tex_size = pI830->TexMem.Size;
+#endif
+ pSAREAPriv->log_tex_granularity = pI830->TexGranularity;
+
+ ctx->driverClientMsg = malloc(sizeof(I830DRIRec));
+ ctx->driverClientMsgSize = sizeof(I830DRIRec);
+ pI830DRI = (I830DRIPtr)ctx->driverClientMsg;
+ pI830DRI->deviceID = pI830->Chipset;
+ pI830DRI->regsSize = I830_REG_SIZE;
+ pI830DRI->width = ctx->shared.virtualWidth;
+ pI830DRI->height = ctx->shared.virtualHeight;
+ pI830DRI->mem = ctx->shared.fbSize;
+ pI830DRI->cpp = ctx->cpp;
+
+ pI830DRI->bitsPerPixel = ctx->bpp;
+ pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t);
+
+ err = I830DRIDoMappings(ctx, pI830, pSAREAPriv);
+ if (err == FALSE)
+ return FALSE;
+
+ I830SetupMemoryTiling(ctx, pI830);
+
+ /* Quick hack to clear the front & back buffers. Could also use
+ * the clear ioctl to do this, but would need to setup hw state
+ * first.
+ */
+ I830ClearScreen(ctx, pI830, pSAREAPriv);
+
+ I830SetRingRegs(ctx, pI830);
+
+ return TRUE;
+}
+
+
+/**
+ * \brief Validate the fbdev mode.
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Saves some registers and returns 1.
+ *
+ * \sa radeonValidateMode().
+ */
+static int i830ValidateMode( const DRIDriverContext *ctx )
+{
+ return 1;
+}
+
+/**
+ * \brief Examine mode returned by fbdev.
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Restores registers that fbdev has clobbered and returns 1.
+ *
+ * \sa i810ValidateMode().
+ */
+static int i830PostValidateMode( const DRIDriverContext *ctx )
+{
+ I830Rec *pI830 = ctx->driverPrivate;
+
+ I830SetRingRegs(ctx, pI830);
+ return 1;
+}
+
+
+/**
+ * \brief Initialize the framebuffer device mode
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Fills in \p info with some default values and some information from \p ctx
+ * and then calls I810ScreenInit() for the screen initialization.
+ *
+ * Before exiting clears the framebuffer memory accessing it directly.
+ */
+static int i830InitFBDev( DRIDriverContext *ctx )
+{
+ I830Rec *pI830 = calloc(1, sizeof(I830Rec));
+ int i;
+
+ {
+ int dummy = ctx->shared.virtualWidth;
+
+ switch (ctx->bpp / 8) {
+ case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
+ case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
+ case 3:
+ case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
+ }
+
+ ctx->shared.virtualWidth = dummy;
+ ctx->shared.Width = ctx->shared.virtualWidth;
+ }
+
+
+ for (i = 0; pitches[i] != 0; i++) {
+ if (pitches[i] >= ctx->shared.virtualWidth) {
+ ctx->shared.virtualWidth = pitches[i];
+ break;
+ }
+ }
+
+ ctx->driverPrivate = (void *)pI830;
+
+ pI830->LpRing = calloc(1, sizeof(I830RingBuffer));
+ pI830->Chipset = ctx->chipset;
+ pI830->LinearAddr = ctx->FBStart;
+
+ if (!I830ScreenInit( ctx, pI830 ))
+ return 0;
+
+
+ return 1;
+}
+
+
+/**
+ * \brief The screen is being closed, so clean up any state and free any
+ * resources used by the DRI.
+ *
+ * \param ctx display handle.
+ *
+ * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
+ * private data.
+ */
+static void i830HaltFBDev( DRIDriverContext *ctx )
+{
+ drmI830Sarea *pSAREAPriv;
+ I830Rec *pI830 = ctx->driverPrivate;
+
+ if (pI830->irq) {
+ drmCtlUninstHandler(ctx->drmFD);
+ pI830->irq = 0; }
+
+ I830CleanupDma(ctx);
+
+ pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) +
+ sizeof(drm_sarea_t));
+
+ I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv);
+ drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
+ drmClose(ctx->drmFD);
+
+ if (ctx->driverPrivate) {
+ free(ctx->driverPrivate);
+ ctx->driverPrivate = 0;
+ }
+}
+
+
+extern void i810NotifyFocus( int );
+
+/**
+ * \brief Exported driver interface for Mini GLX.
+ *
+ * \sa DRIDriverRec.
+ */
+const struct DRIDriverRec __driDriver = {
+ i830ValidateMode,
+ i830PostValidateMode,
+ i830InitFBDev,
+ i830HaltFBDev,
+ NULL,//I830EngineShutdown,
+ NULL, //I830EngineRestore,
+#ifndef _EMBEDDED
+ 0,
+#else
+ i810NotifyFocus,
+#endif
+};
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c
index ad661e198c..f730c831e4 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.c
+++ b/src/mesa/drivers/dri/mach64/mach64_context.c
@@ -253,9 +253,6 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS"));
- mmesa->vblank_flags = (mmesa->do_irqs)
- ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
driContextPriv->driverPrivate = (void *)mmesa;
if (driQueryOptionb(&mmesa->optionCache, "no_rast")) {
@@ -330,10 +327,15 @@ mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
}
- driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags,
- &newMach64Ctx->vbl_seq );
-
if ( newMach64Ctx->driDrawable != driDrawPriv ) {
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags = (newMach64Ctx->do_irqs)
+ ? driGetDefaultVBlankFlags(&newMach64Ctx->optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank( driDrawPriv );
+ }
+
newMach64Ctx->driDrawable = driDrawPriv;
mach64CalcViewport( newMach64Ctx->glCtx );
}
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h
index 8d89452412..c602333024 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.h
+++ b/src/mesa/drivers/dri/mach64/mach64_context.h
@@ -263,8 +263,6 @@ struct mach64_context {
/* VBI
*/
- GLuint vbl_seq;
- GLuint vblank_flags;
GLuint do_irqs;
/* Configuration cache
diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c
index 36e7d3c5d3..3bcec50cf8 100644
--- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c
+++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c
@@ -279,7 +279,7 @@ static int mach64WaitForFrameCompletion( mach64ContextPtr mmesa )
/* Copy the back color buffer to the front color buffer.
*/
-void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv )
+void mach64CopyBuffer( __DRIdrawablePrivate *dPriv )
{
mach64ContextPtr mmesa;
GLint nbox, i, ret;
@@ -320,7 +320,7 @@ void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv )
#endif
UNLOCK_HARDWARE( mmesa );
- driWaitForVBlank( dPriv, &mmesa->vbl_seq, mmesa->vblank_flags, &missed_target );
+ driWaitForVBlank( dPriv, &missed_target );
LOCK_HARDWARE( mmesa );
/* use front buffer cliprects */
diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.h b/src/mesa/drivers/dri/mach64/mach64_ioctl.h
index 52fe863484..c28bf31c49 100644
--- a/src/mesa/drivers/dri/mach64/mach64_ioctl.h
+++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.h
@@ -78,7 +78,7 @@ extern void mach64FireBlitLocked( mach64ContextPtr mmesa, void *buffer,
GLint offset, GLint pitch, GLint format,
GLint x, GLint y, GLint width, GLint height );
-extern void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv );
+extern void mach64CopyBuffer( __DRIdrawablePrivate *dPriv );
#if ENABLE_PERF_BOXES
extern void mach64PerformanceCounters( mach64ContextPtr mmesa );
extern void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa );
diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c
index 4e9e216e7d..a04b775484 100644
--- a/src/mesa/drivers/dri/mach64/mach64_screen.c
+++ b/src/mesa/drivers/dri/mach64/mach64_screen.c
@@ -208,9 +208,7 @@ mach64CreateScreen( __DRIscreenPrivate *sPriv )
{
mach64ScreenPtr mach64Screen;
ATIDRIPtr serverInfo = (ATIDRIPtr)sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void * const psc = sPriv->psc->screenConfigs;
+ int i;
if (sPriv->devPrivSize != sizeof(ATIDRIRec)) {
fprintf(stderr,"\nERROR! sizeof(ATIDRIRec) does not match passed size from device driver\n");
@@ -319,15 +317,14 @@ mach64CreateScreen( __DRIscreenPrivate *sPriv )
mach64Screen->driScreen = sPriv;
- if ( glx_enable_extension != NULL ) {
- if ( mach64Screen->irq != 0 ) {
- (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
- (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
- }
-
- (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
+ i = 0;
+ mach64Screen->extensions[i++] = &driFrameTrackingExtension.base;
+ if ( mach64Screen->irq != 0 ) {
+ mach64Screen->extensions[i++] = &driSwapControlExtension.base;
+ mach64Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
}
+ mach64Screen->extensions[i++] = NULL;
+ sPriv->extensions = mach64Screen->extensions;
return mach64Screen;
}
@@ -477,7 +474,6 @@ mach64InitDriver( __DRIscreenPrivate *driScreen )
static struct __DriverAPIRec mach64API = {
- .InitDriver = mach64InitDriver,
.DestroyScreen = mach64DestroyScreen,
.CreateContext = mach64CreateContext,
.DestroyContext = mach64DestroyContext,
@@ -488,6 +484,7 @@ static struct __DriverAPIRec mach64API = {
.UnbindContext = mach64UnbindContext,
.GetSwapInfo = NULL,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -495,63 +492,41 @@ static struct __DriverAPIRec mach64API = {
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 6, 4, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 2, 0, 0 };
+ ATIDRIPtr dri_priv = (ATIDRIPtr) psp->pDevPriv;
- dri_interface = interface;
-
+ psp->DriverAPI = mach64API;
if ( ! driCheckDriDdxDrmVersions2( "Mach64",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) ) {
return NULL;
}
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ if (!mach64InitDriver(psp))
+ return NULL;
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &mach64API);
- if ( psp != NULL ) {
- ATIDRIPtr dri_priv = (ATIDRIPtr) psp->pDevPriv;
- *driver_modes = mach64FillInModes( dri_priv->cpp * 8,
- 16,
- 0,
- 1);
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- }
-
- return (void *) psp;
+ return mach64FillInModes( dri_priv->cpp * 8, 16, 0, 1);
}
diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.h b/src/mesa/drivers/dri/mach64/mach64_screen.h
index 5305058e2f..766554d7e4 100644
--- a/src/mesa/drivers/dri/mach64/mach64_screen.h
+++ b/src/mesa/drivers/dri/mach64/mach64_screen.h
@@ -73,6 +73,8 @@ typedef struct {
__DRIscreenPrivate *driScreen;
driOptionCache optionCache;
+
+ const __DRIextension *extensions[4];
} mach64ScreenRec, *mach64ScreenPtr;
#endif /* __MACH64_SCREEN_H__ */
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index f4e651afa0..896f2d94fc 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -75,11 +75,13 @@
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
#define need_GL_EXT_fog_coord
+#define need_GL_EXT_gpu_program_parameters
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#if 0
#define need_GL_EXT_paletted_texture
#endif
+#define need_GL_APPLE_vertex_array_object
#define need_GL_NV_vertex_program
#include "extension_helper.h"
@@ -193,14 +195,19 @@ mgaFillInModes( unsigned pixel_bits, unsigned depth_bits,
}
+static const __DRIextension *mgaExtensions[] = {
+ &driReadDrawableExtension,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+};
+
static GLboolean
mgaInitDriver(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen;
MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void * const psc = sPriv->psc->screenConfigs;
if (sPriv->devPrivSize != sizeof(MGADRIRec)) {
fprintf(stderr,"\nERROR! sizeof(MGADRIRec) does not match passed size from device driver\n");
@@ -217,7 +224,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv)
mgaScreen->sPriv = sPriv;
sPriv->private = (void *)mgaScreen;
- if (sPriv->drmMinor >= 1) {
+ if (sPriv->drm_version.minor >= 1) {
int ret;
drm_mga_getparam_t gp;
@@ -235,13 +242,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv)
}
}
- if ( glx_enable_extension != NULL ) {
- (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
- (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
- (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
- (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
- }
+ sPriv->extensions = mgaExtensions;
if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
serverInfo->chipset != MGA_CARD_TYPE_G400) {
@@ -274,7 +275,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv)
* there is a new, in-kernel mechanism for handling the wait.
*/
- if (mgaScreen->sPriv->drmMinor < 2) {
+ if (mgaScreen->sPriv->drm_version.minor < 2) {
mgaScreen->mmio.handle = serverInfo->registers.handle;
mgaScreen->mmio.size = serverInfo->registers.size;
if ( drmMap( sPriv->fd,
@@ -412,13 +413,15 @@ static const struct dri_extension card_extensions[] =
#endif
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
+ { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
{ NULL, NULL }
};
-static const struct dri_extension ARB_vp_extension[] = {
+static const struct dri_extension ARB_vp_extensions[] = {
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
{ NULL, NULL }
};
@@ -623,7 +626,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
}
if ( driQueryOptionb( &mmesa->optionCache, "arb_vertex_program" ) ) {
- driInitSingleExtension( ctx, ARB_vp_extension );
+ driInitExtensions(ctx, ARB_vp_extensions, GL_FALSE);
}
if ( driQueryOptionb( &mmesa->optionCache, "nv_vertex_program" ) ) {
@@ -647,9 +650,6 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
debug_control );
#endif
- mmesa->vblank_flags = (mmesa->mgaScreen->irq == 0)
- ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache);
-
(*dri_interface->getUST)( & mmesa->swap_ust );
if (driQueryOptionb(&mmesa->optionCache, "no_rast")) {
@@ -879,8 +879,14 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
if (mmesa->driDrawable != driDrawPriv) {
- driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags,
- &mmesa->vbl_seq );
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags = (mmesa->mgaScreen->irq == 0)
+ ? VBLANK_FLAG_NO_IRQ
+ : driGetDefaultVBlankFlags(&mmesa->optionCache);
+
+ driDrawableInitVBlank( driDrawPriv );
+ }
+
mmesa->driDrawable = driDrawPriv;
mmesa->dirty = ~0;
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
@@ -935,7 +941,6 @@ void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
static const struct __DriverAPIRec mgaAPI = {
- .InitDriver = mgaInitDriver,
.DestroyScreen = mgaDestroyScreen,
.CreateContext = mgaCreateContext,
.DestroyContext = mgaDestroyContext,
@@ -946,6 +951,7 @@ static const struct __DriverAPIRec mgaAPI = {
.UnbindContext = mgaUnbindContext,
.GetSwapInfo = getSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -953,69 +959,50 @@ static const struct __DriverAPIRec mgaAPI = {
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 2, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 3, 0, 0 };
+ MGADRIPtr dri_priv = (MGADRIPtr) psp->pDevPriv;
- dri_interface = interface;
-
+ psp->DriverAPI = mgaAPI;
if ( ! driCheckDriDdxDrmVersions2( "MGA",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
return NULL;
- }
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &mgaAPI);
- if ( psp != NULL ) {
- MGADRIPtr dri_priv = (MGADRIPtr) psp->pDevPriv;
- *driver_modes = mgaFillInModes( dri_priv->cpp * 8,
- (dri_priv->cpp == 2) ? 16 : 24,
- (dri_priv->cpp == 2) ? 0 : 8,
- (dri_priv->backOffset != dri_priv->depthOffset) );
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- driInitExtensions( NULL, g400_extensions, GL_FALSE );
- driInitSingleExtension( NULL, ARB_vp_extension );
- driInitExtensions( NULL, NV_vp_extensions, GL_FALSE );
- }
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+ driInitExtensions( NULL, g400_extensions, GL_FALSE );
+ driInitExtensions(NULL, ARB_vp_extensions, GL_FALSE);
+ driInitExtensions( NULL, NV_vp_extensions, GL_FALSE );
+
+ if (!mgaInitDriver(psp))
+ return NULL;
- return (void *) psp;
+ return mgaFillInModes( dri_priv->cpp * 8,
+ (dri_priv->cpp == 2) ? 16 : 24,
+ (dri_priv->cpp == 2) ? 0 : 8,
+ (dri_priv->backOffset != dri_priv->depthOffset) );
}
diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h
index 2124006ade..2681976fc2 100644
--- a/src/mesa/drivers/dri/mga/mgacontext.h
+++ b/src/mesa/drivers/dri/mga/mgacontext.h
@@ -258,11 +258,6 @@ struct mga_context_t {
drmBufPtr vertex_dma_buffer;
drmBufPtr iload_buffer;
- /* VBI
- */
- GLuint vbl_seq;
- GLuint vblank_flags;
-
int64_t swap_ust;
int64_t swap_missed_ust;
diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c
index b1d5e0c48f..6d18bd83d8 100644
--- a/src/mesa/drivers/dri/mga/mgadd.c
+++ b/src/mesa/drivers/dri/mga/mgadd.c
@@ -41,7 +41,7 @@
#include "mga_xmesa.h"
#include "utils.h"
-#define DRIVER_DATE "20061030"
+#define DRIVER_DATE "20071017"
/***************************************
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c
index f8587fc541..ff26b9475b 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.c
+++ b/src/mesa/drivers/dri/mga/mgaioctl.c
@@ -55,7 +55,7 @@ mgaSetFence( mgaContextPtr mmesa, uint32_t * fence )
{
int ret = ENOSYS;
- if ( mmesa->driScreen->drmMinor >= 2 ) {
+ if ( mmesa->driScreen->drm_version.minor >= 2 ) {
ret = drmCommandWriteRead( mmesa->driScreen->fd, DRM_MGA_SET_FENCE,
fence, sizeof( uint32_t ));
if (ret) {
@@ -73,7 +73,7 @@ mgaWaitFence( mgaContextPtr mmesa, uint32_t fence, uint32_t * curr_fence )
{
int ret = ENOSYS;
- if ( mmesa->driScreen->drmMinor >= 2 ) {
+ if ( mmesa->driScreen->drm_version.minor >= 2 ) {
uint32_t temp = fence;
ret = drmCommandWriteRead( mmesa->driScreen->fd,
@@ -409,7 +409,7 @@ static void mgaWaitForFrameCompletion( mgaContextPtr mmesa )
/*
* Copy the back buffer to the front buffer.
*/
-void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv )
+void mgaCopyBuffer( __DRIdrawablePrivate *dPriv )
{
mgaContextPtr mmesa;
drm_clip_rect_t *pbox;
@@ -428,8 +428,7 @@ void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv )
FLUSH_BATCH( mmesa );
mgaWaitForFrameCompletion( mmesa );
- driWaitForVBlank( dPriv, & mmesa->vbl_seq, mmesa->vblank_flags,
- & missed_target );
+ driWaitForVBlank( dPriv, & missed_target );
if ( missed_target ) {
mmesa->swap_missed_count++;
(void) (*dri_interface->getUST)( & mmesa->swap_missed_ust );
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.h b/src/mesa/drivers/dri/mga/mgaioctl.h
index f3ae749ca9..0ea0ba1acd 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.h
+++ b/src/mesa/drivers/dri/mga/mgaioctl.h
@@ -33,7 +33,7 @@
#include "mgacontext.h"
#include "mga_xmesa.h"
-void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv );
+void mgaCopyBuffer( __DRIdrawablePrivate *dPriv );
void mgaWaitForVBlank( mgaContextPtr mmesa );
void mgaGetILoadBufferLocked( mgaContextPtr mmesa );
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
index c20a76f29e..88f2175cc3 100644
--- a/src/mesa/drivers/dri/mga/mgastate.c
+++ b/src/mesa/drivers/dri/mga/mgastate.c
@@ -778,8 +778,6 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
{
__DRIdrawablePrivate *const driDrawable = mmesa->driDrawable;
__DRIdrawablePrivate *const driReadable = mmesa->driReadable;
- drm_mga_sarea_t *sarea = mmesa->sarea;
-
mmesa->dirty_cliprects = 0;
@@ -790,9 +788,6 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
mga_set_cliprects(mmesa);
- sarea->req_drawable = driDrawable->draw;
- sarea->req_draw_buffer = mmesa->draw_buffer;
-
mgaUpdateClipping( mmesa->glCtx );
mgaCalcViewport( mmesa->glCtx );
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
index b1a0e7bfd1..94f170e057 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
@@ -72,10 +72,10 @@ static nouveau_card nouveau_card_list[]={
{0x014D, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
{0x014E, "Quadro FX 540", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
{0x014F, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
-{0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
-{0x0151, "GeForce2 Ti", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
-{0x0152, "GeForce2 Ultra, Bladerunner", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
-{0x0153, "Quadro2 Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0151, "GeForce2 Ti", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0152, "GeForce2 Ultra, Bladerunner", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0153, "Quadro2 Pro", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
{0x0161, "GeForce 6200 TurboCache(TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
{0x0162, "GeForce 6200 SE TurboCache (TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
{0x0163, "GeForce 6200 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
@@ -132,20 +132,20 @@ static nouveau_card nouveau_card_list[]={
{0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
{0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
{0x0244, "Geforce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
-{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
-{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
+{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
{0x0290, "GeForce 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
{0x0291, "GeForce 7900 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
{0x0292, "GeForce 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
@@ -176,21 +176,21 @@ static nouveau_card nouveau_card_list[]={
{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
-{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
-{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
{0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
{0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
{0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index f36483a3d4..4f4128c875 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -283,7 +283,13 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
struct gl_framebuffer *read_fb =
(struct gl_framebuffer*)driReadPriv->driverPrivate;
- driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags =
+ driGetDefaultVBlankFlags(&nmesa->optionCache);
+
+ driDrawableInitVBlank(driDrawPriv);
+ }
+
nmesa->driDrawable = driDrawPriv;
_mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
@@ -378,3 +384,39 @@ void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
{
}
+void nouveauClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer,
+ int fill, int mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int dimensions;
+
+ if (!buffer) {
+ return;
+ }
+
+ /* FIXME: only support 32 bits atm */
+
+ /* Surface that we will work on */
+ nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
+
+ BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
+ OUT_RING(0x0b); /* Y32 color format */
+ OUT_RING((buffer->pitch<<16)|buffer->pitch);
+ OUT_RING(buffer->offset);
+ OUT_RING(buffer->offset);
+
+ /* Now clear a rectangle */
+ dimensions = ((buffer->mesa.Height)<<16) | (buffer->mesa.Width);
+
+ nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText);
+
+ BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
+ OUT_RING(3); /* SRCCOPY */
+
+ BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL, 5);
+ OUT_RING(0); /* top left */
+ OUT_RING(dimensions); /* bottom right */
+ OUT_RING(fill);
+ OUT_RING(0); /* top left */
+ OUT_RING(dimensions); /* bottom right */
+}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h
index 77fe13a9cd..a617dd6282 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -133,9 +133,6 @@ typedef struct nouveau_context {
nouveau_renderbuffer_t *color_buffer;
nouveau_renderbuffer_t *depth_buffer;
- /* Color buffer clear value */
- uint32_t clear_color_value;
-
/* Depth/stencil clear value */
uint32_t clear_value;
@@ -185,10 +182,6 @@ typedef struct nouveau_context {
/* Configuration cache */
driOptionCache optionCache;
- /* vblank stuff */
- uint32_t vblank_flags;
- uint32_t vblank_seq;
-
GLuint new_state;
GLuint new_render_state;
GLuint render_index;
@@ -234,6 +227,9 @@ extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv);
extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
int x, int y, int w, int h);
+extern void nouveauClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer,
+ int fill, int mask);
+
/* Debugging utils: */
extern int NOUVEAU_DEBUG;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
index 4851c66835..8b76779002 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
@@ -35,6 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "framebuffer.h"
#include "utils.h"
+#include "colormac.h"
/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */
GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa,
@@ -135,7 +136,74 @@ static void nouveauFinish( GLcontext *ctx )
/* glClear */
static void nouveauClear( GLcontext *ctx, GLbitfield mask )
{
- // XXX we really should do something here...
+ uint32_t clear_value;
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* FIXME: should we clear front buffer, even if asked to do it? */
+ if (mask & (BUFFER_BIT_FRONT_LEFT|BUFFER_BIT_BACK_LEFT)) {
+ GLubyte c[4];
+ int color_bits = 32;
+ int color_mask = 0xffffffff;
+
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,ctx->Color.ClearColor);
+ clear_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
+
+ if (ctx->DrawBuffer) {
+ /* FIXME: find correct color buffer, instead of [0][0] */
+ if (ctx->DrawBuffer->_ColorDrawBuffers[0][0]) {
+ color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0][0]->RedBits;
+ color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->GreenBits;
+ color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->BlueBits;
+ color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->AlphaBits;
+ }
+ }
+
+ if (color_bits<24) {
+ clear_value = PACK_COLOR_565(c[0],c[1],c[2]);
+ color_mask = 0xffff;
+ }
+
+ nouveauClearBuffer(ctx, nmesa->color_buffer,
+ clear_value, color_mask);
+ }
+
+ if (mask & (BUFFER_BIT_DEPTH)) {
+ int depth_bits = 24;
+ int depth_mask;
+ if (ctx->DrawBuffer) {
+ if (ctx->DrawBuffer->_DepthBuffer) {
+ depth_bits = ctx->DrawBuffer->_DepthBuffer->DepthBits;
+ }
+ }
+
+ switch(depth_bits) {
+ case 16:
+ clear_value = (uint32_t) (ctx->Depth.Clear * 32767.0);
+ depth_mask = 0xffff;
+ break;
+ default:
+ clear_value = ((uint32_t) (ctx->Depth.Clear * 16777215.0)) << 8;
+ depth_mask = 0xffffff00;
+ break;
+ }
+
+ nouveauClearBuffer(ctx, nmesa->depth_buffer,
+ clear_value, depth_mask);
+ }
+
+ if (mask & (BUFFER_BIT_STENCIL)) {
+ int stencil_bits = 0;
+ if (ctx->DrawBuffer) {
+ if (ctx->DrawBuffer->_StencilBuffer) {
+ stencil_bits = ctx->DrawBuffer->_StencilBuffer->StencilBits;
+ }
+ }
+
+ if (stencil_bits>0) {
+ nouveauClearBuffer(ctx, nmesa->depth_buffer,
+ ctx->Stencil.Clear, (1<<stencil_bits)-1);
+ }
+ }
}
void nouveauDriverInitFunctions( struct dd_function_table *functions )
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index 065aa81746..533b4b1e6e 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -195,7 +195,6 @@ nouveauGetSwapInfo(__DRIdrawablePrivate *dpriv, __DRIswapInfo *sInfo)
}
static const struct __DriverAPIRec nouveauAPI = {
- .InitDriver = nouveauInitDriver,
.DestroyScreen = nouveauDestroyScreen,
.CreateContext = nouveauCreateContext,
.DestroyContext = nouveauDestroyContext,
@@ -206,6 +205,7 @@ static const struct __DriverAPIRec nouveauAPI = {
.UnbindContext = nouveauUnbindContext,
.GetSwapInfo = nouveauGetSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
@@ -285,81 +285,62 @@ nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits,
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes)
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 2, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
+ NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv;
+
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
#error nouveau_drm.h version doesn't match expected version
#endif
- dri_interface = interface;
if (!driCheckDriDdxDrmVersions2("nouveau",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected)) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected))
return NULL;
- }
// temporary lock step versioning
- if (drm_expected.patch!=drm_version->patch) {
+ if (drm_expected.patch != psp->drm_version.patch) {
__driUtilMessage("%s: wrong DRM version, expected %d, got %d\n",
- __func__,
- drm_expected.patch, drm_version->patch);
+ __func__,
+ drm_expected.patch, psp->drm_version.patch);
return NULL;
}
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &nouveauAPI);
- if ( psp != NULL ) {
- NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv;
-
- *driver_modes = nouveauFillInModes(dri_priv->bpp,
- (dri_priv->bpp == 16) ? 16 : 24,
- (dri_priv->bpp == 16) ? 0 : 8,
- 1
- );
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, common_extensions, GL_FALSE );
- driInitExtensions( NULL, nv10_extensions, GL_FALSE );
- driInitExtensions( NULL, nv10_extensions, GL_FALSE );
- driInitExtensions( NULL, nv30_extensions, GL_FALSE );
- driInitExtensions( NULL, nv40_extensions, GL_FALSE );
- driInitExtensions( NULL, nv50_extensions, GL_FALSE );
- }
+ psp->DriverAPI = nouveauAPI;
+
+ /* Calling driInitExtensions here, with a NULL context
+ * pointer, does not actually enable the extensions. It just
+ * makes sure that all the dispatch offsets for all the
+ * extensions that *might* be enables are known. This is
+ * needed because the dispatch offsets need to be known when
+ * _mesa_context_create is called, but we can't enable the
+ * extensions until we have a context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, common_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv10_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv10_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv30_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv40_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv50_extensions, GL_FALSE );
+
+ if (!nouveauInitDriver(psp))
+ return NULL;
- return (void *) psp;
+ return nouveauFillInModes(dri_priv->bpp,
+ (dri_priv->bpp == 16) ? 16 : 24,
+ (dri_priv->bpp == 16) ? 0 : 8,
+ 1);
}
diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c
index 8cbe72020f..3e5bfe093f 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_state.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_state.c
@@ -110,91 +110,19 @@ static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac
OUT_RING_CACHE(dfactorRGB);
}
-static void nv10ClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer, int fill, int mask)
-{
- nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
- int dimensions;
-
- if (!buffer) {
- return;
- }
-
- /* Surface that we will work on */
- nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
-
- BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
- OUT_RING(0x0b); /* Y32 color format */
- OUT_RING((buffer->pitch<<16)|buffer->pitch);
- OUT_RING(buffer->offset);
- OUT_RING(buffer->offset);
-
- /* Now clear a rectangle */
- dimensions = ((buffer->mesa.Height)<<16) | (buffer->mesa.Width);
-
- nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText);
-
- BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
- OUT_RING(3); /* SRCCOPY */
-
- BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL, 5);
- OUT_RING(0); /* top left */
- OUT_RING(dimensions); /* bottom right */
- OUT_RING(fill);
- OUT_RING(0); /* top left */
- OUT_RING(dimensions); /* bottom right */
-}
-
-static void nv10Clear(GLcontext *ctx, GLbitfield mask)
-{
- nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-
- if (mask & (BUFFER_BIT_FRONT_LEFT|BUFFER_BIT_BACK_LEFT)) {
- nv10ClearBuffer(ctx, nmesa->color_buffer,
- nmesa->clear_color_value, 0xffffffff);
- }
- /* FIXME: check depth bits */
- if (mask & (BUFFER_BIT_DEPTH)) {
- nv10ClearBuffer(ctx, nmesa->depth_buffer,
- nmesa->clear_value, 0xffffff00);
- }
- /* FIXME: check about stencil? */
- if (mask & (BUFFER_BIT_STENCIL)) {
- nv10ClearBuffer(ctx, nmesa->depth_buffer,
- nmesa->clear_value, 0x000000ff);
- }
-}
-
static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4])
{
- nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
- GLubyte c[4];
- UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
- nmesa->clear_color_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
+ /* Not for NV10 */
}
static void nv10ClearDepth(GLcontext *ctx, GLclampd d)
{
- nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-
-/* switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) {
- case 16:
- nmesa->clear_value = (uint32_t)(d*0x7FFF);
- break;
- case 24:*/
- nmesa->clear_value = ((nmesa->clear_value&0x000000FF) |
- (((uint32_t)(d*0xFFFFFF))<<8));
-/* break;
- }*/
+ /* Not for NV10 */
}
static void nv10ClearStencil(GLcontext *ctx, GLint s)
{
- nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-
-/* if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) {*/
- nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)|
- (s&0x000000FF));
-/* }*/
+ /* Not for NV10 */
}
static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
@@ -1037,10 +965,10 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
func->BlendColor = nv10BlendColor;
func->BlendEquationSeparate = nv10BlendEquationSeparate;
func->BlendFuncSeparate = nv10BlendFuncSeparate;
- func->Clear = nv10Clear;
- func->ClearColor = nv10ClearColor;
- func->ClearDepth = nv10ClearDepth;
- func->ClearStencil = nv10ClearStencil;
+/* func->Clear = nv10Clear;*/ /* Not for NV10 */
+ func->ClearColor = nv10ClearColor; /* Not for NV10 */
+ func->ClearDepth = nv10ClearDepth; /* Not for NV10 */
+ func->ClearStencil = nv10ClearStencil; /* Not for NV10 */
func->ClipPlane = nv10ClipPlane;
func->ColorMask = nv10ColorMask;
func->ColorMaterial = nv10ColorMaterial;
diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c
index 95e54a6af5..cdea77642b 100644
--- a/src/mesa/drivers/dri/r128/r128_context.c
+++ b/src/mesa/drivers/dri/r128/r128_context.c
@@ -254,7 +254,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
_tnl_allow_vertex_fog( ctx, GL_TRUE );
driInitExtensions( ctx, card_extensions, GL_TRUE );
- if (sPriv->drmMinor >= 4)
+ if (sPriv->drm_version.minor >= 4)
_mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
r128InitTriFuncs( ctx );
@@ -262,9 +262,6 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
r128DDInitSpanFuncs( ctx );
r128DDInitState( rmesa );
- rmesa->vblank_flags = (rmesa->r128Screen->irq != 0)
- ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
driContextPriv->driverPrivate = (void *)rmesa;
#if DO_DEBUG
@@ -347,8 +344,13 @@ r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
newR128Ctx->dirty = R128_UPLOAD_ALL;
}
- driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags,
- &newR128Ctx->vbl_seq );
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags = (newR128Ctx->r128Screen->irq != 0)
+ ? driGetDefaultVBlankFlags(&newR128Ctx->optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank( driDrawPriv );
+ }
newR128Ctx->driDrawable = driDrawPriv;
_mesa_make_current( newR128Ctx->glCtx,
diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h
index c51dd7fa58..3f7416e9cc 100644
--- a/src/mesa/drivers/dri/r128/r128_context.h
+++ b/src/mesa/drivers/dri/r128/r128_context.h
@@ -210,11 +210,6 @@ struct r128_context {
GLuint c_textureBytes;
GLuint c_vertexBuffers;
- /* VBI
- */
- GLuint vbl_seq;
- GLuint vblank_flags;
-
/* Configuration cache
*/
driOptionCache optionCache;
diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c
index b0dba7d04e..034261a535 100644
--- a/src/mesa/drivers/dri/r128/r128_ioctl.c
+++ b/src/mesa/drivers/dri/r128/r128_ioctl.c
@@ -249,7 +249,7 @@ static int r128WaitForFrameCompletion( r128ContextPtr rmesa )
/* Copy the back color buffer to the front color buffer.
*/
-void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
+void r128CopyBuffer( __DRIdrawablePrivate *dPriv )
{
r128ContextPtr rmesa;
GLint nbox, i, ret;
@@ -282,7 +282,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
}
UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
+ driWaitForVBlank( dPriv, &missed_target );
LOCK_HARDWARE( rmesa );
nbox = dPriv->numClipRects; /* must be in locked region */
@@ -328,7 +328,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
#endif
}
-void r128PageFlip( const __DRIdrawablePrivate *dPriv )
+void r128PageFlip( __DRIdrawablePrivate *dPriv )
{
r128ContextPtr rmesa;
GLint ret;
@@ -359,7 +359,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv )
}
UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
+ driWaitForVBlank( dPriv, &missed_target );
LOCK_HARDWARE( rmesa );
/* The kernel will have been initialized to perform page flipping
diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.h b/src/mesa/drivers/dri/r128/r128_ioctl.h
index 95779f09be..0f9d11fe69 100644
--- a/src/mesa/drivers/dri/r128/r128_ioctl.h
+++ b/src/mesa/drivers/dri/r128/r128_ioctl.h
@@ -86,8 +86,8 @@ extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa,
extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n,
const GLint x[], const GLint y[] );
-extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv );
-extern void r128PageFlip( const __DRIdrawablePrivate *dPriv );
+extern void r128CopyBuffer( __DRIdrawablePrivate *dPriv );
+extern void r128PageFlip( __DRIdrawablePrivate *dPriv );
void r128WaitForVBlank( r128ContextPtr rmesa );
extern void r128WaitForIdleLocked( r128ContextPtr rmesa );
diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c
index 880dee85c2..719f9367c0 100644
--- a/src/mesa/drivers/dri/r128/r128_screen.c
+++ b/src/mesa/drivers/dri/r128/r128_screen.c
@@ -98,9 +98,7 @@ r128CreateScreen( __DRIscreenPrivate *sPriv )
{
r128ScreenPtr r128Screen;
R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void * const psc = sPriv->psc->screenConfigs;
+ int i;
if (sPriv->devPrivSize != sizeof(R128DRIRec)) {
fprintf(stderr,"\nERROR! sizeof(R128DRIRec) does not match passed size from device driver\n");
@@ -121,7 +119,7 @@ r128CreateScreen( __DRIscreenPrivate *sPriv )
r128Screen->IsPCI = r128DRIPriv->IsPCI;
r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;
- if (sPriv->drmMinor >= 3) {
+ if (sPriv->drm_version.minor >= 3) {
drm_r128_getparam_t gp;
int ret;
@@ -226,15 +224,14 @@ r128CreateScreen( __DRIscreenPrivate *sPriv )
r128Screen->driScreen = sPriv;
- if ( glx_enable_extension != NULL ) {
- if ( r128Screen->irq != 0 ) {
- (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
- (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
- }
-
- (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
+ i = 0;
+ r128Screen->extensions[i++] = &driFrameTrackingExtension.base;
+ if ( r128Screen->irq != 0 ) {
+ r128Screen->extensions[i++] = &driSwapControlExtension.base;
+ r128Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
}
+ r128Screen->extensions[i++] = NULL;
+ sPriv->extensions = r128Screen->extensions;
return r128Screen;
}
@@ -404,7 +401,6 @@ r128InitDriver( __DRIscreenPrivate *sPriv )
static struct __DriverAPIRec r128API = {
- .InitDriver = r128InitDriver,
.DestroyScreen = r128DestroyScreen,
.CreateContext = r128CreateContext,
.DestroyContext = r128DestroyContext,
@@ -415,6 +411,7 @@ static struct __DriverAPIRec r128API = {
.UnbindContext = r128UnbindContext,
.GetSwapInfo = NULL,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -504,64 +501,43 @@ r128FillInModes( unsigned pixel_bits, unsigned depth_bits,
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 4, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 2, 2, 0 };
+ R128DRIPtr dri_priv = (R128DRIPtr) psp->pDevPriv;
-
- dri_interface = interface;
-
+ psp->DriverAPI = r128API;
if ( ! driCheckDriDdxDrmVersions2( "Rage128",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
return NULL;
- }
-
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &r128API);
- if ( psp != NULL ) {
- R128DRIPtr dri_priv = (R128DRIPtr) psp->pDevPriv;
- *driver_modes = r128FillInModes( dri_priv->bpp,
- (dri_priv->bpp == 16) ? 16 : 24,
- (dri_priv->bpp == 16) ? 0 : 8,
- (dri_priv->backOffset != dri_priv->depthOffset) );
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- }
- return (void *) psp;
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ if (!r128InitDriver(psp))
+ return NULL;
+
+ return r128FillInModes( dri_priv->bpp,
+ (dri_priv->bpp == 16) ? 16 : 24,
+ (dri_priv->bpp == 16) ? 0 : 8,
+ (dri_priv->backOffset != dri_priv->depthOffset) );
}
diff --git a/src/mesa/drivers/dri/r128/r128_screen.h b/src/mesa/drivers/dri/r128/r128_screen.h
index 8db8eea358..c333713766 100644
--- a/src/mesa/drivers/dri/r128/r128_screen.h
+++ b/src/mesa/drivers/dri/r128/r128_screen.h
@@ -78,6 +78,8 @@ typedef struct {
/* Configuration cache with default values for all contexts */
driOptionCache optionCache;
+ const __DRIextension *extensions[4];
+
} r128ScreenRec, *r128ScreenPtr;
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 5a178442bd..982bd9e62a 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -277,14 +277,14 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
"def_max_anisotropy");
if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
- if ( sPriv->drmMinor < 13 )
+ if ( sPriv->drm_version.minor < 13 )
fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
- "disabling.\n",sPriv->drmMinor );
+ "disabling.\n", sPriv->drm_version.minor );
else
rmesa->using_hyperz = GL_TRUE;
}
- if ( sPriv->drmMinor >= 15 )
+ if ( sPriv->drm_version.minor >= 15 )
rmesa->texmicrotile = GL_TRUE;
/* Init default driver functions then plug in our R200-specific functions
@@ -317,7 +317,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
rmesa->dri.hwContext = driContextPriv->hHWContext;
rmesa->dri.hwLock = &sPriv->pSAREA->lock;
rmesa->dri.fd = sPriv->fd;
- rmesa->dri.drmMinor = sPriv->drmMinor;
+ rmesa->dri.drmMinor = sPriv->drm_version.minor;
rmesa->r200Screen = screen;
rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
@@ -499,9 +499,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
fthrottle_mode,
rmesa->r200Screen->irq);
- rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
- ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
rmesa->prefer_gart_client_texturing =
(getenv("R200_GART_CLIENT_TEXTURES") != 0);
@@ -666,15 +663,18 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
if (R200_DEBUG & DEBUG_DRI)
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
- if ( newCtx->dri.drawable != driDrawPriv ) {
- driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
- &newCtx->vbl_seq );
- }
-
newCtx->dri.readable = driReadPriv;
if ( newCtx->dri.drawable != driDrawPriv ||
newCtx->lastStamp != driDrawPriv->lastStamp ) {
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags = (newCtx->r200Screen->irq != 0)
+ ? driGetDefaultVBlankFlags(&newCtx->optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank( driDrawPriv );
+ }
+
newCtx->dri.drawable = driDrawPriv;
r200SetCliprects(newCtx);
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index c80180bdbc..be73507995 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -893,11 +893,8 @@ struct r200_context {
GLuint TexGenCompSel;
GLmatrix tmpmat;
- /* VBI / buffer swap
+ /* buffer swap
*/
- GLuint vbl_seq;
- GLuint vblank_flags;
-
int64_t swap_ust;
int64_t swap_missed_ust;
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c
index 2366bde525..34e7ada34b 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.c
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.c
@@ -419,7 +419,7 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa )
/* Copy the back color buffer to the front color buffer.
*/
-void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
+void r200CopyBuffer( __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
r200ContextPtr rmesa;
@@ -449,7 +449,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
if (!rect)
{
UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, & missed_target );
LOCK_HARDWARE( rmesa );
}
@@ -513,7 +513,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
}
}
-void r200PageFlip( const __DRIdrawablePrivate *dPriv )
+void r200PageFlip( __DRIdrawablePrivate *dPriv )
{
r200ContextPtr rmesa;
GLint ret;
@@ -553,7 +553,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
*/
r200WaitForFrameCompletion( rmesa );
UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, & missed_target );
if ( missed_target ) {
rmesa->swap_missed_count++;
(void) (*dri_interface->getUST)( & rmesa->swap_missed_ust );
@@ -857,7 +857,7 @@ void r200Finish( GLcontext *ctx )
* the kernel data structures, and the current context to get the
* device fd.
*/
-void *r200AllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLsizei size,
+void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size,
GLfloat readfreq, GLfloat writefreq,
GLfloat priority)
{
@@ -899,7 +899,7 @@ void *r200AllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLsizei size,
/* Called via glXFreeMemoryMESA() */
-void r200FreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer)
+void r200FreeMemoryMESA(__DRIscreen *screen, GLvoid *pointer)
{
GET_CURRENT_CONTEXT(ctx);
r200ContextPtr rmesa;
@@ -936,7 +936,7 @@ void r200FreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer)
}
/* Called via glXGetMemoryOffsetMESA() */
-GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer)
+GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer)
{
GET_CURRENT_CONTEXT(ctx);
r200ContextPtr rmesa;
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h
index 5ed1555f6a..4521fbabf1 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.h
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.h
@@ -89,19 +89,19 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa,
struct r200_dma_region *region,
const char *caller );
-extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable,
+extern void r200CopyBuffer( __DRIdrawablePrivate *drawable,
const drm_clip_rect_t *rect);
-extern void r200PageFlip( const __DRIdrawablePrivate *drawable );
+extern void r200PageFlip( __DRIdrawablePrivate *drawable );
extern void r200Flush( GLcontext *ctx );
extern void r200Finish( GLcontext *ctx );
extern void r200WaitForIdleLocked( r200ContextPtr rmesa );
extern void r200WaitForVBlank( r200ContextPtr rmesa );
extern void r200InitIoctlFuncs( struct dd_function_table *functions );
-extern void *r200AllocateMemoryMESA( __DRInativeDisplay *dpy, int scrn, GLsizei size, GLfloat readfreq,
+extern void *r200AllocateMemoryMESA( __DRIscreen *screen, GLsizei size, GLfloat readfreq,
GLfloat writefreq, GLfloat priority );
-extern void r200FreeMemoryMESA( __DRInativeDisplay *dpy, int scrn, GLvoid *pointer );
-extern GLuint r200GetMemoryOffsetMESA( __DRInativeDisplay *dpy, int scrn, const GLvoid *pointer );
+extern void r200FreeMemoryMESA( __DRIscreen *screen, GLvoid *pointer );
+extern GLuint r200GetMemoryOffsetMESA( __DRIscreen *screen, const GLvoid *pointer );
extern GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
GLint size );
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 14e0f052fd..d2ed3105d1 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -93,6 +93,8 @@ int hw_tcl_on = 1;
const struct dri_extension card_extensions[] = {
/* *INDENT-OFF* */
+ {"GL_ARB_depth_texture", NULL},
+ {"GL_ARB_fragment_program", NULL},
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_texture_border_clamp", NULL},
@@ -105,7 +107,6 @@ const struct dri_extension card_extensions[] = {
{"GL_ARB_texture_mirrored_repeat", NULL},
{"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
{"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
- {"GL_ARB_fragment_program", NULL},
{"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
{"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
{"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
@@ -130,6 +131,7 @@ const struct dri_extension card_extensions[] = {
{"GL_NV_blend_square", NULL},
{"GL_NV_vertex_program", GL_NV_vertex_program_functions},
{"GL_SGIS_generate_mipmap", NULL},
+ {"GL_SGIX_depth_texture", NULL},
{NULL, NULL}
/* *INDENT-ON* */
};
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index cce8e68586..78ed44b09c 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -951,6 +951,10 @@ static void emit_tex(struct r300_fragment_program *fp,
if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) {
rdest = dest;
dest = get_temp_reg_tex(fp);
+ } else if (fpi->DstReg.WriteMask != WRITEMASK_XYZW) {
+ /* in case write mask isn't XYZW */
+ rdest = dest;
+ dest = get_temp_reg_tex(fp);
}
hwdest =
t_hw_dst(fp, dest, GL_TRUE,
@@ -1016,7 +1020,7 @@ static void emit_tex(struct r300_fragment_program *fp,
/* Copy from temp to output if needed */
if (REG_GET_VALID(rdest)) {
- emit_arith(fp, PFS_OP_MAD, rdest, WRITEMASK_XYZW, dest,
+ emit_arith(fp, PFS_OP_MAD, rdest, fpi->DstReg.WriteMask, dest,
pfs_one, pfs_zero, 0);
free_temp(fp, dest);
}
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 1baa74c526..ee556d347e 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -886,6 +886,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
+
+ /* These two values are wrong, but they're the only values that
+ * produce any even vaguely correct results. Can r300 only do 16-bit
+ * depth textures?
+ */
+# define R300_TX_FORMAT_X24_Y8 0x1e
+# define R300_TX_FORMAT_X32 0x1e
+
/* 0x16 - some 16 bit green format.. ?? */
# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
# define R300_TX_FORMAT_CUBIC_MAP (1 << 26)
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
index 1805cecd0a..adf69a3c25 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.c
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
@@ -482,6 +482,25 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
case GL_RGBA32F_ARB:
return &_mesa_texformat_rgba_float32;
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+#if 0
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT:
+ return &_mesa_texformat_z16;
+ case GL_UNSIGNED_INT:
+ return &_mesa_texformat_z32;
+ case GL_UNSIGNED_INT_24_8_EXT:
+ default:
+ return &_mesa_texformat_z24_s8;
+ }
+#else
+ return &_mesa_texformat_z16;
+#endif
+
default:
_mesa_problem(ctx,
"unexpected internalFormat 0x%x in r300ChooseTextureFormat",
@@ -1057,6 +1076,19 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
driSwapOutTextureObject((driTextureObject *) t);
break;
+ case GL_DEPTH_TEXTURE_MODE:
+ if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat
+ == GL_DEPTH_COMPONENT) {
+ r300SetDepthTexMode(texObj);
+ break;
+ } else {
+ /* If the texture isn't a depth texture, changing this
+ * state won't cause any changes to the hardware.
+ * Don't force a flush of texture state.
+ */
+ return;
+ }
+
default:
return;
}
diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h
index f67a8e6ba6..b86d45bfe0 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.h
+++ b/src/mesa/drivers/dri/r300/r300_tex.h
@@ -35,6 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef __r300_TEX_H__
#define __r300_TEX_H__
+extern void r300SetDepthTexMode(struct gl_texture_object *tObj);
+
extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
unsigned long long offset, GLint depth,
GLuint pitch);
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 1d2909fd21..efa201a52d 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -115,11 +115,80 @@ static const struct tx_table {
_ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
_ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
_ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
+ _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
+ _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
+ _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
/* *INDENT-ON* */
};
#undef _ASSIGN
+void r300SetDepthTexMode(struct gl_texture_object *tObj)
+{
+ static const GLuint formats[3][3] = {
+ {
+ R300_EASY_TX_FORMAT(X, X, X, X, X16),
+ R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
+ R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
+ },
+ {
+ R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
+ R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
+ R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
+ },
+ {
+ R300_EASY_TX_FORMAT(X, X, X, X, X32),
+ R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
+ R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
+ },
+ };
+ const GLuint *format;
+ r300TexObjPtr t;
+
+ if (!tObj)
+ return;
+
+ t = (r300TexObjPtr) tObj->DriverData;
+
+
+ switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
+ case MESA_FORMAT_Z16:
+ format = formats[0];
+ break;
+ case MESA_FORMAT_Z24_S8:
+ format = formats[1];
+ break;
+ case MESA_FORMAT_Z32:
+ format = formats[2];
+ break;
+ default:
+ /* Error...which should have already been caught by higher
+ * levels of Mesa.
+ */
+ ASSERT(0);
+ return;
+ }
+
+ switch (tObj->DepthMode) {
+ case GL_LUMINANCE:
+ t->format = format[0];
+ break;
+ case GL_INTENSITY:
+ t->format = format[1];
+ break;
+ case GL_ALPHA:
+ t->format = format[2];
+ break;
+ default:
+ /* Error...which should have already been caught by higher
+ * levels of Mesa.
+ */
+ ASSERT(0);
+ return;
+ }
+}
+
+
/**
* This function computes the number of bytes of storage needed for
* the given texture object (all mipmap levels, all cube faces).
@@ -146,7 +215,12 @@ static void r300SetTexImages(r300ContextPtr rmesa,
*/
if (!t->image_override
&& VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
- t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
+ if (baseImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
+ r300SetDepthTexMode(tObj);
+ } else {
+ t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
+ }
+
t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter;
} else if (!t->image_override) {
_mesa_problem(NULL, "unexpected texture format in %s",
diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
index e9634b427a..787d4b5c57 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.c
+++ b/src/mesa/drivers/dri/r300/radeon_context.c
@@ -156,7 +156,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
radeon->dri.hwContext = driContextPriv->hHWContext;
radeon->dri.hwLock = &sPriv->pSAREA->lock;
radeon->dri.fd = sPriv->fd;
- radeon->dri.drmMinor = sPriv->drmMinor;
+ radeon->dri.drmMinor = sPriv->drm_version.minor;
radeon->radeonScreen = screen;
radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
@@ -177,9 +177,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
radeon->do_usleeps ? "usleeps" : "busy waits",
fthrottle_mode, radeon->radeonScreen->irq);
- radeon->vblank_flags = (radeon->radeonScreen->irq != 0)
- ? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ;
-
(*dri_interface->getUST) (&radeon->swap_ust);
return GL_TRUE;
@@ -277,9 +274,15 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
radeon->glCtx);
if (radeon->dri.drawable != driDrawPriv) {
- driDrawableInitVBlank(driDrawPriv,
- radeon->vblank_flags,
- &radeon->vbl_seq);
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags =
+ (radeon->radeonScreen->irq != 0)
+ ? driGetDefaultVBlankFlags(&radeon->
+ optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank(driDrawPriv);
+ }
}
radeon->dri.readable = driReadPriv;
diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h
index 2f239417a9..38d8930601 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.h
+++ b/src/mesa/drivers/dri/r300/radeon_context.h
@@ -182,10 +182,7 @@ struct radeon_context {
GLuint irqsEmitted;
drm_radeon_irq_wait_t iw;
- /* VBI / buffer swap */
- GLuint vbl_seq;
- GLuint vblank_flags;
-
+ /* buffer swap */
int64_t swap_ust;
int64_t swap_missed_ust;
diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c
index 0b8656b9c1..866b1deaa0 100644
--- a/src/mesa/drivers/dri/r300/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c
@@ -157,7 +157,7 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
/* Copy the back color buffer to the front color buffer.
*/
-void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
+void radeonCopyBuffer(__DRIdrawablePrivate * dPriv,
const drm_clip_rect_t * rect)
{
radeonContextPtr radeon;
@@ -187,8 +187,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
if (!rect)
{
UNLOCK_HARDWARE(radeon);
- driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
- &missed_target);
+ driWaitForVBlank(dPriv, &missed_target);
LOCK_HARDWARE(radeon);
}
@@ -253,7 +252,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
}
}
-void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
+void radeonPageFlip(__DRIdrawablePrivate * dPriv)
{
radeonContextPtr radeon;
GLint ret;
@@ -293,8 +292,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
*/
radeonWaitForFrameCompletion(radeon);
UNLOCK_HARDWARE(radeon);
- driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
- &missed_target);
+ driWaitForVBlank(dPriv, &missed_target);
if (missed_target) {
radeon->swap_missed_count++;
(void)(*dri_interface->getUST) (&radeon->swap_missed_ust);
diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.h b/src/mesa/drivers/dri/r300/radeon_ioctl.h
index 3a80d36c62..210001e8e0 100644
--- a/src/mesa/drivers/dri/r300/radeon_ioctl.h
+++ b/src/mesa/drivers/dri/r300/radeon_ioctl.h
@@ -46,9 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#include "radeon_drm.h"
-extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable,
+extern void radeonCopyBuffer(__DRIdrawablePrivate * drawable,
const drm_clip_rect_t * rect);
-extern void radeonPageFlip(const __DRIdrawablePrivate * drawable);
+extern void radeonPageFlip(__DRIdrawablePrivate * drawable);
extern void radeonFlush(GLcontext * ctx);
extern void radeonFinish(GLcontext * ctx);
extern void radeonWaitForIdleLocked(radeonContextPtr radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index b302275c71..18d9b0b65a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -233,14 +233,14 @@ radeonCreateContext( const __GLcontextModes *glVisual,
"def_max_anisotropy");
if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
- if ( sPriv->drmMinor < 13 )
+ if ( sPriv->drm_version.minor < 13 )
fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
- "disabling.\n",sPriv->drmMinor );
+ "disabling.\n", sPriv->drm_version.minor );
else
rmesa->using_hyperz = GL_TRUE;
}
- if ( sPriv->drmMinor >= 15 )
+ if ( sPriv->drm_version.minor >= 15 )
rmesa->texmicrotile = GL_TRUE;
/* Init default driver functions then plug in our Radeon-specific functions
@@ -271,7 +271,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
rmesa->dri.hwContext = driContextPriv->hHWContext;
rmesa->dri.hwLock = &sPriv->pSAREA->lock;
rmesa->dri.fd = sPriv->fd;
- rmesa->dri.drmMinor = sPriv->drmMinor;
+ rmesa->dri.drmMinor = sPriv->drm_version.minor;
rmesa->radeonScreen = screen;
rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
@@ -424,9 +424,6 @@ radeonCreateContext( const __GLcontextModes *glVisual,
rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
- rmesa->vblank_flags = (rmesa->radeonScreen->irq != 0)
- ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
(*dri_interface->getUST)( & rmesa->swap_ust );
@@ -592,16 +589,18 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
if (RADEON_DEBUG & DEBUG_DRI)
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) newCtx->glCtx);
- if ( newCtx->dri.drawable != driDrawPriv ) {
- /* XXX we may need to validate the drawable here!!! */
- driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
- &newCtx->vbl_seq );
- }
-
newCtx->dri.readable = driReadPriv;
if ( (newCtx->dri.drawable != driDrawPriv) ||
newCtx->lastStamp != driDrawPriv->lastStamp ) {
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags = (newCtx->radeonScreen->irq != 0)
+ ? driGetDefaultVBlankFlags(&newCtx->optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank( driDrawPriv );
+ }
+
newCtx->dri.drawable = driDrawPriv;
radeonSetCliprects(newCtx);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 8dedd66f56..b4ffde5d54 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -667,9 +667,6 @@ struct radeon_context {
/* VBI
*/
- GLuint vbl_seq;
- GLuint vblank_flags;
-
int64_t swap_ust;
int64_t swap_missed_ust;
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 4c64bc201a..2430158db2 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -863,7 +863,7 @@ static void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
/* Copy the back color buffer to the front color buffer.
*/
-void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv,
+void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
radeonContextPtr rmesa;
@@ -891,7 +891,7 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv,
if (!rect)
{
UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, & missed_target );
LOCK_HARDWARE( rmesa );
}
@@ -952,7 +952,7 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv,
}
}
-void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
+void radeonPageFlip( __DRIdrawablePrivate *dPriv )
{
radeonContextPtr rmesa;
GLint ret;
@@ -987,7 +987,7 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
*/
radeonWaitForFrameCompletion( rmesa );
UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, & missed_target );
if ( missed_target ) {
rmesa->swap_missed_count++;
(void) (*dri_interface->getUST)( & rmesa->swap_missed_ust );
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h
index 11a7d02b1b..b8d68eec86 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h
@@ -87,9 +87,9 @@ extern void radeonReleaseDmaRegion( radeonContextPtr rmesa,
struct radeon_dma_region *region,
const char *caller );
-extern void radeonCopyBuffer( const __DRIdrawablePrivate *drawable,
+extern void radeonCopyBuffer( __DRIdrawablePrivate *drawable,
const drm_clip_rect_t *rect);
-extern void radeonPageFlip( const __DRIdrawablePrivate *drawable );
+extern void radeonPageFlip( __DRIdrawablePrivate *drawable );
extern void radeonFlush( GLcontext *ctx );
extern void radeonFinish( GLcontext *ctx );
extern void radeonWaitForIdleLocked( radeonContextPtr rmesa );
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 682cf3a5ee..4cc87a95ae 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -332,6 +332,21 @@ radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
return modes;
}
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+static const __DRIallocateExtension r200AllocateExtension = {
+ { __DRI_ALLOCATE, __DRI_ALLOCATE_VERSION },
+ r200AllocateMemoryMESA,
+ r200FreeMemoryMESA,
+ r200GetMemoryOffsetMESA
+};
+#endif
+
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+static const __DRItexOffsetExtension r300texOffsetExtension = {
+ { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
+ r300SetTexOffset,
+};
+#endif
/* Create the device specific screen private data struct.
*/
@@ -341,9 +356,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
radeonScreenPtr screen;
RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
unsigned char *RADEONMMIO;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void * const psc = sPriv->psc->screenConfigs;
+ int i;
if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
fprintf(stderr,"\nERROR! sizeof(RADEONDRIRec) does not match passed size from device driver\n");
@@ -396,13 +409,13 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
return NULL;
}
- screen->drmSupportsCubeMapsR200 = (sPriv->drmMinor >= 7);
- screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
- screen->drmSupportsTriPerf = (sPriv->drmMinor >= 16);
- screen->drmSupportsFragShader = (sPriv->drmMinor >= 18);
- screen->drmSupportsPointSprites = (sPriv->drmMinor >= 13);
- screen->drmSupportsCubeMapsR100 = (sPriv->drmMinor >= 15);
- screen->drmSupportsVertexProgram = (sPriv->drmMinor >= 25);
+ screen->drmSupportsCubeMapsR200 = (sPriv->drm_version.minor >= 7);
+ screen->drmSupportsBlendColor = (sPriv->drm_version.minor >= 11);
+ screen->drmSupportsTriPerf = (sPriv->drm_version.minor >= 16);
+ screen->drmSupportsFragShader = (sPriv->drm_version.minor >= 18);
+ screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13);
+ screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15);
+ screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25);
}
screen->mmio.handle = dri_priv->registerHandle;
@@ -667,7 +680,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
return NULL;
}
if ((screen->chip_family == CHIP_FAMILY_R350 || screen->chip_family == CHIP_FAMILY_R300) &&
- sPriv->ddxMinor < 2) {
+ sPriv->ddx_version.minor < 2) {
fprintf(stderr, "xf86-video-ati-6.6.2 or newer needed for Radeon 9500/9700/9800 cards.\n");
return NULL;
}
@@ -684,7 +697,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
- if ( sPriv->drmMinor >= 10 ) {
+ if ( sPriv->drm_version.minor >= 10 ) {
drm_radeon_setparam_t sp;
sp.param = RADEON_SETPARAM_FB_LOCATION;
@@ -702,7 +715,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
screen->depthPitch = dri_priv->depthPitch;
/* Check if ddx has set up a surface reg to cover depth buffer */
- screen->depthHasSurface = ((sPriv->ddxMajor > 4) &&
+ screen->depthHasSurface = ((sPriv->ddx_version.major > 4) &&
(screen->chip_flags & RADEON_CHIPSET_TCL));
if ( dri_priv->textureSize == 0 ) {
@@ -732,29 +745,28 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
dri_priv->log2GARTTexGran;
}
- if ( glx_enable_extension != NULL ) {
- if ( screen->irq != 0 ) {
- (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
- (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
- }
-
- (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
- if (IS_R200_CLASS(screen))
- (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
+ i = 0;
+ screen->extensions[i++] = &driCopySubBufferExtension.base;
+ screen->extensions[i++] = &driFrameTrackingExtension.base;
+ screen->extensions[i++] = &driReadDrawableExtension;
- (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" );
- (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
+ if ( screen->irq != 0 ) {
+ screen->extensions[i++] = &driSwapControlExtension.base;
+ screen->extensions[i++] = &driMediaStreamCounterExtension.base;
}
#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
- if (IS_R200_CLASS(screen)) {
- sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
- sPriv->psc->freeMemory = (void *) r200FreeMemoryMESA;
- sPriv->psc->memoryOffset = (void *) r200GetMemoryOffsetMESA;
- }
+ if (IS_R200_CLASS(screen))
+ screen->extensions[i++] = &r200AllocateExtension.base;
+#endif
+
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+ screen->extensions[i++] = &r300texOffsetExtension.base;
#endif
+ screen->extensions[i++] = NULL;
+ sPriv->extensions = screen->extensions;
+
screen->driScreen = sPriv;
screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
return screen;
@@ -939,7 +951,6 @@ static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
static struct __DriverAPIRec radeonAPI = {
- .InitDriver = radeonInitDriver,
.DestroyScreen = radeonDestroyScreen,
.CreateContext = radeonCreateContext,
.DestroyContext = radeonDestroyContext,
@@ -950,17 +961,14 @@ static struct __DriverAPIRec radeonAPI = {
.UnbindContext = radeonUnbindContext,
.GetSwapInfo = getSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
.CopySubBuffer = radeonCopySubBuffer,
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
- .setTexOffset = r300SetTexOffset,
-#endif
};
#else
static const struct __DriverAPIRec r200API = {
- .InitDriver = radeonInitDriver,
.DestroyScreen = radeonDestroyScreen,
.CreateContext = r200CreateContext,
.DestroyContext = r200DestroyContext,
@@ -971,6 +979,7 @@ static const struct __DriverAPIRec r200API = {
.UnbindContext = r200UnbindContext,
.GetSwapInfo = getSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
@@ -979,30 +988,16 @@ static const struct __DriverAPIRec r200API = {
};
#endif
+
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC void *
-__driCreateNewScreen_20050727( __DRInativeDisplay *dpy,
- int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
#if !RADEON_COMMON
static const char *driver_name = "Radeon";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
@@ -1019,57 +1014,46 @@ __driCreateNewScreen_20050727( __DRInativeDisplay *dpy,
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 24, 0 };
#endif
-
- dri_interface = interface;
+ RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
if ( ! driCheckDriDdxDrmVersions3( driver_name,
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) ) {
return NULL;
}
#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &radeonAPI);
+ psp->DriverAPI = radeonAPI;
#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &r200API);
+ psp->DriverAPI = r200API;
#endif
- if ( psp != NULL ) {
- RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
- if (driver_modes) {
- *driver_modes = radeonFillInModes( dri_priv->bpp,
- (dri_priv->bpp == 16) ? 16 : 24,
- (dri_priv->bpp == 16) ? 0 : 8,
- (dri_priv->backOffset != dri_priv->depthOffset) );
- }
-
- /* Calling driInitExtensions here, with a NULL context pointer,
- * does not actually enable the extensions. It just makes sure
- * that all the dispatch offsets for all the extensions that
- * *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create
- * is called, but we can't enable the extensions until we have a
- * context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create
+ * is called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
- driInitExtensions( NULL, blend_extensions, GL_FALSE );
- driInitSingleExtension( NULL, ARB_vp_extension );
- driInitSingleExtension( NULL, NV_vp_extension );
- driInitSingleExtension( NULL, ATI_fs_extension );
- driInitExtensions( NULL, point_extensions, GL_FALSE );
+ driInitExtensions( NULL, blend_extensions, GL_FALSE );
+ driInitSingleExtension( NULL, ARB_vp_extension );
+ driInitSingleExtension( NULL, NV_vp_extension );
+ driInitSingleExtension( NULL, ATI_fs_extension );
+ driInitExtensions( NULL, point_extensions, GL_FALSE );
#endif
- }
- return (void *) psp;
+ if (!radeonInitDriver(psp))
+ return NULL;
+
+ return radeonFillInModes( dri_priv->bpp,
+ (dri_priv->bpp == 16) ? 16 : 24,
+ (dri_priv->bpp == 16) ? 0 : 8,
+ (dri_priv->backOffset != dri_priv->depthOffset) );
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
index 25e6fcf399..184b0d225e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
@@ -103,6 +103,8 @@ typedef struct {
/* Configuration cache with default values for all contexts */
driOptionCache optionCache;
+
+ const __DRIextension *extensions[8];
} radeonScreenRec, *radeonScreenPtr;
#define IS_R100_CLASS(screen) \
diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
index c66fd6dac3..7b0b006b69 100644
--- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c
+++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
@@ -329,7 +329,6 @@ s3vUnbindContext( __DRIcontextPrivate *driContextPriv )
static struct __DriverAPIRec s3vAPI = {
- s3vInitDriver,
s3vDestroyScreen,
s3vCreateContext,
s3vDestroyContext,
@@ -355,6 +354,9 @@ void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
DEBUG(("__driCreateScreen: psp = %p\n", psp));
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &s3vAPI);
DEBUG(("__driCreateScreen: psp = %p\n", psp));
+ if (!s3vInitDriver(psp))
+ return NULLL
+
return (void *) psp;
}
#endif
diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c
index 43422db9a8..013e88216f 100644
--- a/src/mesa/drivers/dri/savage/savage_xmesa.c
+++ b/src/mesa/drivers/dri/savage/savage_xmesa.c
@@ -168,6 +168,10 @@ static const struct tnl_pipeline_stage *savage_pipeline[] = {
};
+static const __DRIextension *savageExtensions[] = {
+ &driReadDrawableExtension,
+};
+
/* this is first function called in dirver*/
static GLboolean
@@ -175,9 +179,6 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
{
savageScreenPrivate *savageScreen;
SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
-
if (sPriv->devPrivSize != sizeof(SAVAGEDRIRec)) {
fprintf(stderr,"\nERROR! sizeof(SAVAGEDRIRec) does not match passed size from device driver\n");
@@ -265,10 +266,7 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
driParseOptionInfo (&savageScreen->optionCache,
__driConfigOptions, __driNConfigOptions);
- if (glx_enable_extension != NULL) {
- (*glx_enable_extension)(sPriv->psc->screenConfigs,
- "GLX_SGI_make_current_read");
- }
+ sPriv->extensions = savageExtensions;
#if 0
savageDDFastPathInit();
@@ -525,7 +523,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,
"enable_fastpath");
/* DRM versions before 2.1.3 would only render triangle lists. ELTS
* support was added in 2.2.0. */
- if (imesa->enable_fastpath && sPriv->drmMinor < 2) {
+ if (imesa->enable_fastpath && sPriv->drm_version.minor < 2) {
fprintf (stderr,
"*** Disabling fast path because your DRM version is buggy "
"or doesn't\n*** support ELTS. You need at least Savage DRM "
@@ -920,7 +918,6 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )
static const struct __DriverAPIRec savageAPI = {
- savageInitDriver,
savageDestroyScreen,
savageCreateContext,
savageDestroyContext,
@@ -1017,63 +1014,44 @@ savageFillInModes( unsigned pixel_bits, unsigned depth_bits,
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 2, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 2, 1, 0 };
-
- dri_interface = interface;
+ SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv;
if ( ! driCheckDriDdxDrmVersions2( "Savage",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
return NULL;
- }
-
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &savageAPI);
- if ( psp != NULL ) {
- SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv;
- *driver_modes = savageFillInModes( dri_priv->cpp*8,
- (dri_priv->cpp == 2) ? 16 : 24,
- (dri_priv->cpp == 2) ? 0 : 8,
- (dri_priv->backOffset != dri_priv->depthOffset) );
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- }
- return (void *) psp;
+ psp->DriverAPI = savageAPI;
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ if (!savageInitDriver(psp))
+ return NULL;
+
+ return savageFillInModes( dri_priv->cpp*8,
+ (dri_priv->cpp == 2) ? 16 : 24,
+ (dri_priv->cpp == 2) ? 0 : 8,
+ (dri_priv->backOffset != dri_priv->depthOffset) );
}
diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c
index 719e50f964..1dcfee291f 100644
--- a/src/mesa/drivers/dri/savage/savagetex.c
+++ b/src/mesa/drivers/dri/savage/savagetex.c
@@ -1016,7 +1016,7 @@ static void savageUploadTexImages( savageContextPtr imesa, savageTexObjPtr t )
/* Heap timestamps are only reliable with Savage DRM 2.3.x or
* later. Earlier versions had only 16 bit time stamps which
* would wrap too frequently. */
- if (imesa->savageScreen->driScrnPriv->drmMinor >= 3) {
+ if (imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) {
unsigned int heap = t->base.heap->heapId;
LOCK_HARDWARE(imesa);
savageWaitEvent (imesa, imesa->textureHeaps[heap]->timestamp);
@@ -1713,7 +1713,7 @@ static void savageTimestampTextures( savageContextPtr imesa )
* Only useful with long-lived 32-bit event tags available
* with Savage DRM 2.3.x or later. */
if ((imesa->CurrentTexObj[0] || imesa->CurrentTexObj[1]) &&
- imesa->savageScreen->driScrnPriv->drmMinor >= 3) {
+ imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) {
unsigned int e;
FLUSH_BATCH(imesa);
e = savageEmitEvent(imesa, SAVAGE_WAIT_3D);
diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c
index 89d734ba78..671193577d 100644
--- a/src/mesa/drivers/dri/sis/sis_screen.c
+++ b/src/mesa/drivers/dri/sis/sis_screen.c
@@ -304,7 +304,6 @@ sisInitDriver( __DRIscreenPrivate *sPriv )
}
static struct __DriverAPIRec sisAPI = {
- .InitDriver = sisInitDriver,
.DestroyScreen = sisDestroyScreen,
.CreateContext = sisCreateContext,
.DestroyContext = sisDestroyContext,
@@ -315,6 +314,7 @@ static struct __DriverAPIRec sisAPI = {
.UnbindContext = sisUnbindContext,
.GetSwapInfo = NULL,
.GetMSC = NULL,
+ .GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -323,60 +323,42 @@ static struct __DriverAPIRec sisAPI = {
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn,
- __DRIscreen *psc,
- const __GLcontextModes *modes,
- const __DRIversion *ddx_version,
- const __DRIversion *dri_version,
- const __DRIversion *drm_version,
- const __DRIframebuffer *frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes **driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = {0, 8, 0};
static const __DRIversion dri_expected = {4, 0, 0};
static const __DRIversion drm_expected = {1, 0, 0};
static const char *driver_name = "SiS";
- dri_interface = interface;
+ SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv;
- if (!driCheckDriDdxDrmVersions2(driver_name, dri_version, &dri_expected,
- ddx_version, &ddx_expected,
- drm_version, &drm_expected)) {
+ if (!driCheckDriDdxDrmVersions2(driver_name,
+ &psp->dri_version, &dri_expected,
+ &psp->ddx_version, &ddx_expected,
+ &psp->drm_version, &drm_expected))
return NULL;
- }
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &sisAPI);
- if (psp != NULL) {
- SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv;
- *driver_modes = sisFillInModes(dri_priv->bytesPerPixel * 8);
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- }
+ psp->DriverAPI = sisAPI;
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ if (!sisInitDriver(psp))
+ return NULL;
- return (void *)psp;
+ return sisFillInModes(dri_priv->bytesPerPixel * 8);
}
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
index 1f9ff4e30c..6298de82f4 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
@@ -63,6 +63,10 @@ DRI_CONF_BEGIN
DRI_CONF_SECTION_END
DRI_CONF_END;
+static const __DRIextension *tdfxExtensions[] = {
+ &driReadDrawableExtension,
+};
+
static const GLuint __driNConfigOptions = 1;
extern const struct dri_extension card_extensions[];
@@ -73,9 +77,6 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
{
tdfxScreenPrivate *fxScreen;
TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void *const psc = sPriv->psc->screenConfigs;
if (sPriv->devPrivSize != sizeof(TDFXDRIRec)) {
fprintf(stderr,"\nERROR! sizeof(TDFXDRIRec) does not match passed size from device driver\n");
@@ -116,9 +117,7 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
return GL_FALSE;
}
- if (glx_enable_extension != NULL) {
- (*glx_enable_extension)(psc, "GLX_SGI_make_current_read");
- }
+ sPriv->extensions = tdfxExtensions;
return GL_TRUE;
}
@@ -346,7 +345,6 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
static const struct __DriverAPIRec tdfxAPI = {
- .InitDriver = tdfxInitDriver,
.DestroyScreen = tdfxDestroyScreen,
.CreateContext = tdfxCreateContext,
.DestroyContext = tdfxDestroyContext,
@@ -357,6 +355,7 @@ static const struct __DriverAPIRec tdfxAPI = {
.UnbindContext = tdfxUnbindContext,
.GetSwapInfo = NULL,
.GetMSC = NULL,
+ .GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -432,69 +431,50 @@ static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits,
}
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 1, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 0, 0 };
- dri_interface = interface;
+ /* divined from tdfx_dri.c, sketchy */
+ TDFXDRIPtr dri_priv = (TDFXDRIPtr) psp->pDevPriv;
+
+ /* XXX i wish it was like this */
+ /* bpp = dri_priv->bpp */
+ int bpp = (dri_priv->cpp > 2) ? 24 : 16;
if ( ! driCheckDriDdxDrmVersions2( "tdfx",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
return NULL;
- }
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &tdfxAPI);
-
- if (psp != NULL) {
- /* divined from tdfx_dri.c, sketchy */
- TDFXDRIPtr dri_priv = (TDFXDRIPtr) psp->pDevPriv;
- int bpp = (dri_priv->cpp > 2) ? 24 : 16;
+ psp->DriverAPI = tdfxAPI;
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+ driInitExtensions( NULL, napalm_extensions, GL_FALSE );
- /* XXX i wish it was like this */
- /* bpp = dri_priv->bpp */
+ if (!tdfxInitDriver(psp))
+ return NULL;
- *driver_modes = tdfxFillInModes(bpp, (bpp == 16) ? 16 : 24,
- (bpp == 16) ? 0 : 8,
- (dri_priv->backOffset!=dri_priv->depthOffset));
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- driInitExtensions( NULL, napalm_extensions, GL_FALSE );
- }
-
- return (void *)psp;
+ return tdfxFillInModes(bpp, (bpp == 16) ? 16 : 24,
+ (bpp == 16) ? 0 : 8,
+ (dri_priv->backOffset!=dri_priv->depthOffset));
}
diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c
index 8dc7f0dc78..81098bc9cd 100644
--- a/src/mesa/drivers/dri/trident/trident_context.c
+++ b/src/mesa/drivers/dri/trident/trident_context.c
@@ -418,7 +418,6 @@ tridentInitDriver(__DRIscreenPrivate *sPriv)
}
static struct __DriverAPIRec tridentAPI = {
- tridentInitDriver,
tridentDestroyScreen,
tridentCreateContext,
tridentDestroyContext,
@@ -430,43 +429,36 @@ static struct __DriverAPIRec tridentAPI = {
};
-PUBLIC void *__driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn,
- __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
+ */
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 4, 0, 0 };
static const __DRIversion dri_expected = { 3, 1, 0 };
static const __DRIversion drm_expected = { 1, 0, 0 };
-
- dri_interface = interface;
-
+
if ( ! driCheckDriDdxDrmVersions2( "Trident",
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected ) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
return NULL;
- }
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &tridentAPI);
+ psp->DriverAPI = tridentAPI;
+
+ if (!tridentInitDriver(psp))
+ return NULL;
- if ( psp != NULL ) {
+ /* Wait... what? This driver doesn't report any modes... */
#if 0
- TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv;
- *driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8,
- GL_TRUE );
+ TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv;
+ *driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8,
+ GL_TRUE );
#endif
- }
- return (void *) psp;
+
+ return NULL;
}
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 7c73877720..1551be5e75 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -601,9 +601,6 @@ viaCreateContext(const __GLcontextModes *visual,
_tnl_allow_pixel_fog(ctx, GL_FALSE);
_tnl_allow_vertex_fog(ctx, GL_TRUE);
-/* vmesa->display = dpy; */
- vmesa->display = sPriv->display;
-
vmesa->hHWContext = driContextPriv->hHWContext;
vmesa->driFd = sPriv->fd;
vmesa->driHwLock = &sPriv->pSAREA->lock;
@@ -661,10 +658,6 @@ viaCreateContext(const __GLcontextModes *visual,
driQueryOptionb(&vmesa->optionCache, "no_rast"))
FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
- vmesa->vblank_flags =
- vmesa->viaScreen->irqEnabled ?
- driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
if (getenv("VIA_PAGEFLIP"))
vmesa->allowPageFlip = 1;
@@ -840,13 +833,17 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
- if (vmesa->driDrawable != driDrawPriv) {
- driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags,
- &vmesa->vbl_seq);
- }
-
if ((vmesa->driDrawable != driDrawPriv)
|| (vmesa->driReadable != driReadPriv)) {
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ driDrawPriv->vblFlags =
+ vmesa->viaScreen->irqEnabled ?
+ driGetDefaultVBlankFlags(&vmesa->optionCache) :
+ VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank(driDrawPriv);
+ }
+
vmesa->driDrawable = driDrawPriv;
vmesa->driReadable = driReadPriv;
diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h
index fecd2782fb..acd6f2e2b1 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.h
+++ b/src/mesa/drivers/dri/unichrome/via_context.h
@@ -289,7 +289,6 @@ struct via_context {
drm_context_t hHWContext;
drm_hw_lock_t *driHwLock;
int driFd;
- __DRInativeDisplay *display;
/**
* DRI drawable bound to this context for drawing.
@@ -322,9 +321,6 @@ struct via_context {
*/
driOptionCache optionCache;
- GLuint vblank_flags;
- GLuint vbl_seq;
-
int64_t swap_ust;
int64_t swap_missed_ust;
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
index 4a733fb00c..a14a4613d3 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.c
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c
@@ -507,7 +507,7 @@ void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light )
* except that WAIT_IDLE() will spin the CPU polling, while this is
* IRQ driven.
*/
-static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv,
+static void viaWaitIdleVBlank( __DRIdrawablePrivate *dPriv,
struct via_context *vmesa,
GLuint value )
{
@@ -523,8 +523,7 @@ static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv,
vmesa->thrashing)
viaSwapOutWork(vmesa);
- driWaitForVBlank( dPriv, & vmesa->vbl_seq,
- vmesa->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, & missed_target );
if ( missed_target ) {
vmesa->swap_missed_count++;
(*dri_interface->getUST)( &vmesa->swap_missed_ust );
@@ -591,7 +590,7 @@ void viaResetPageFlippingLocked(struct via_context *vmesa)
/*
* Copy the back buffer to the front buffer.
*/
-void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
+void viaCopyBuffer(__DRIdrawablePrivate *dPriv)
{
struct via_context *vmesa =
(struct via_context *)dPriv->driContextPriv->driverPrivate;
@@ -607,7 +606,7 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
VIA_FLUSH_DMA(vmesa);
- if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+ if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
vmesa->lastBreadcrumbWrite > 1)
viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1);
else
@@ -634,14 +633,14 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
}
-void viaPageFlip(const __DRIdrawablePrivate *dPriv)
+void viaPageFlip(__DRIdrawablePrivate *dPriv)
{
struct via_context *vmesa =
(struct via_context *)dPriv->driContextPriv->driverPrivate;
struct via_renderbuffer buffer_tmp;
VIA_FLUSH_DMA(vmesa);
- if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+ if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
vmesa->lastBreadcrumbWrite > 1)
viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1);
else
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h
index a81b427d80..44fc439c9f 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.h
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h
@@ -33,8 +33,8 @@ void viaFlushDma(struct via_context *vmesa);
void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags);
void viaInitIoctlFuncs(GLcontext *ctx);
-void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
-void viaPageFlip(const __DRIdrawablePrivate *dpriv);
+void viaCopyBuffer(__DRIdrawablePrivate *dpriv);
+void viaPageFlip(__DRIdrawablePrivate *dpriv);
void viaCheckDma(struct via_context *vmesa, GLuint bytes);
void viaResetPageFlippingLocked(struct via_context *vmesa);
void viaWaitIdle(struct via_context *vmesa, GLboolean light);
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c
index 90f76be44d..0ad18b4300 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.c
+++ b/src/mesa/drivers/dri/unichrome/via_screen.c
@@ -98,9 +98,7 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
{
viaScreenPrivate *viaScreen;
VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
- PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
- (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
- void * const psc = sPriv->psc->screenConfigs;
+ int i;
if (sPriv->devPrivSize != sizeof(VIADRIRec)) {
fprintf(stderr,"\nERROR! sizeof(VIADRIRec) does not match passed size from device driver\n");
@@ -175,17 +173,17 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset;
- if ( glx_enable_extension != NULL ) {
- if ( viaScreen->irqEnabled ) {
- (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
- (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
- }
-
- (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
- (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
+ i = 0;
+ viaScreen->extensions[i++] = &driFrameTrackingExtension.base;
+ viaScreen->extensions[i++] = &driReadDrawableExtension;
+ if ( viaScreen->irqEnabled ) {
+ viaScreen->extensions[i++] = &driSwapControlExtension.base;
+ viaScreen->extensions[i++] = &driMediaStreamCounterExtension.base;
}
+ viaScreen->extensions[i++] = NULL;
+ sPriv->extensions = viaScreen->extensions;
+
return GL_TRUE;
}
@@ -326,7 +324,6 @@ viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
static struct __DriverAPIRec viaAPI = {
- .InitDriver = viaInitDriver,
.DestroyScreen = viaDestroyScreen,
.CreateContext = viaCreateContext,
.DestroyContext = viaDestroyContext,
@@ -337,6 +334,7 @@ static struct __DriverAPIRec viaAPI = {
.UnbindContext = viaUnbindContext,
.GetSwapInfo = getSwapInfo,
.GetMSC = driGetMSC32,
+ .GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@@ -408,67 +406,47 @@ viaFillInModes( unsigned pixel_bits, GLboolean have_back_buffer )
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
*
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- * failure.
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn,
- __DRIscreen *psc,
- const __GLcontextModes * modes,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { VIA_DRIDDX_VERSION_MAJOR,
VIA_DRIDDX_VERSION_MINOR,
VIA_DRIDDX_VERSION_PATCH };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 2, 3, 0 };
static const char *driver_name = "Unichrome";
-
- dri_interface = interface;
+ VIADRIPtr dri_priv = (VIADRIPtr) psp->pDevPriv;
if ( ! driCheckDriDdxDrmVersions2( driver_name,
- dri_version, & dri_expected,
- ddx_version, & ddx_expected,
- drm_version, & drm_expected) ) {
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected) )
return NULL;
- }
-
- psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
- ddx_version, dri_version, drm_version,
- frame_buffer, pSAREA, fd,
- internal_api_version, &viaAPI);
- if ( psp != NULL ) {
- VIADRIPtr dri_priv = (VIADRIPtr) psp->pDevPriv;
- *driver_modes = viaFillInModes( dri_priv->bytesPerPixel * 8,
- GL_TRUE );
-
- /* Calling driInitExtensions here, with a NULL context pointer, does not actually
- * enable the extensions. It just makes sure that all the dispatch offsets for all
- * the extensions that *might* be enables are known. This is needed because the
- * dispatch offsets need to be known when _mesa_context_create is called, but we can't
- * enable the extensions until we have a context pointer.
- *
- * Hello chicken. Hello egg. How are you two today?
- */
- driInitExtensions( NULL, card_extensions, GL_FALSE );
- }
- return (void *) psp;
+ psp->DriverAPI = viaAPI;
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ if (!viaInitDriver(psp))
+ return NULL;
+
+ return viaFillInModes( dri_priv->bytesPerPixel * 8, GL_TRUE );
+
}
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.h b/src/mesa/drivers/dri/unichrome/via_screen.h
index 84aa5aef88..c3ef722ff0 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.h
+++ b/src/mesa/drivers/dri/unichrome/via_screen.h
@@ -70,6 +70,8 @@ typedef struct {
/* Configuration cache with default values for all contexts */
driOptionCache optionCache;
+
+ const __DRIextension *extensions[5];
} viaScreenPrivate;