summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-12-01 10:57:37 +0000
committerKeith Whitwell <keithw@vmware.com>2009-12-01 10:57:37 +0000
commit06d3732a9094030fc33120f16f162e0d405f132c (patch)
tree185159951093f49f1877e78eaf01f6d1ea01e560 /src
parent853d4807fe220b17cf5af5a76b24f2466238013b (diff)
parentf17dbe256bb38c35d885260be7e5856f1561de97 (diff)
Merge commit 'origin/mesa_7_7_branch'
Conflicts: src/gallium/drivers/svga/svga_screen_texture.c src/gallium/state_trackers/xorg/xorg_composite.c src/gallium/state_trackers/xorg/xorg_exa.c src/gallium/state_trackers/xorg/xorg_renderer.c src/gallium/state_trackers/xorg/xorg_xv.c src/mesa/main/texgetimage.c src/mesa/main/version.h
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/rbug/README4
-rw-r--r--src/gallium/auxiliary/util/u_mm.c7
-rw-r--r--src/gallium/drivers/svga/Makefile3
-rw-r--r--src/gallium/drivers/svga/svga_context.c4
-rw-r--r--src/gallium/drivers/svga/svga_context.h5
-rw-r--r--src/gallium/drivers/svga/svga_debug.h1
-rw-r--r--src/gallium/drivers/svga/svga_draw.c7
-rw-r--r--src/gallium/drivers/svga/svga_pipe_blit.c8
-rw-r--r--src/gallium/drivers/svga/svga_pipe_clear.c6
-rw-r--r--src/gallium/drivers/svga/svga_pipe_flush.c3
-rw-r--r--src/gallium/drivers/svga/svga_screen.c5
-rw-r--r--src/gallium/drivers/svga/svga_screen_buffer.c16
-rw-r--r--src/gallium/drivers/svga/svga_screen_cache.c109
-rw-r--r--src/gallium/drivers/svga/svga_screen_cache.h17
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c159
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.h16
-rw-r--r--src/gallium/drivers/svga/svga_state_framebuffer.c3
-rw-r--r--src/gallium/drivers/svga/svga_tgsi.c14
-rw-r--r--src/gallium/state_trackers/xorg/Makefile3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c87
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.h4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c79
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c68
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c566
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c289
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h9
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c33
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c44
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c388
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h27
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h28
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c27
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_surface.c8
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/Makefile19
-rw-r--r--src/glu/sgi/libutil/mipmap.c5
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c11
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h1
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c32
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.c9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.c9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c85
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c56
-rw-r--r--src/mesa/drivers/dri/swrast/swrast_span.c72
-rw-r--r--src/mesa/main/compiler.h7
-rw-r--r--src/mesa/main/points.c7
-rw-r--r--src/mesa/main/texenv.c5
-rw-r--r--src/mesa/main/texgen.c10
-rw-r--r--src/mesa/main/texparam.c15
50 files changed, 1445 insertions, 957 deletions
diff --git a/src/gallium/auxiliary/rbug/README b/src/gallium/auxiliary/rbug/README
index 33d76371de..d984067893 100644
--- a/src/gallium/auxiliary/rbug/README
+++ b/src/gallium/auxiliary/rbug/README
@@ -16,6 +16,10 @@ for information about applications look in:
progs/rbug/README
+for a GUI see:
+
+ http://cgit.freedesktop.org/mesa/rbug-gui
+
--
Jakob Bornecrantz <jakob@vmware.com>
diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c
index 4b75d4ba1d..82f83702d1 100644
--- a/src/gallium/auxiliary/util/u_mm.c
+++ b/src/gallium/auxiliary/util/u_mm.c
@@ -39,13 +39,20 @@ u_mmDumpMemInfo(const struct mem_block *heap)
}
else {
const struct mem_block *p;
+ int total_used = 0, total_free = 0;
for (p = heap->next; p != heap; p = p->next) {
debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
p->free ? 'F':'.',
p->reserved ? 'R':'.');
+ if (p->free)
+ total_free += p->size;
+ else
+ total_used += p->size;
}
+ debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n",
+ total_used + total_free, total_used, total_free);
debug_printf("\nFree list:\n");
for (p = heap->next_free; p != heap; p = p->next_free) {
diff --git a/src/gallium/drivers/svga/Makefile b/src/gallium/drivers/svga/Makefile
index 38b63394e3..f361908187 100644
--- a/src/gallium/drivers/svga/Makefile
+++ b/src/gallium/drivers/svga/Makefile
@@ -50,6 +50,9 @@ C_SOURCES = \
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/svga/include
+# With linux-debug we get a lots of warnings, filter out the bad flags.
+CFLAGS := $(filter-out -pedantic, $(filter-out -ansi, $(CFLAGS)))
+
LIBRARY_DEFINES = \
-std=gnu99 -fvisibility=hidden \
-DHAVE_STDINT_H -DHAVE_SYS_TYPES_H
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 73233957f3..c3de12b4a3 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -230,7 +230,9 @@ void svga_context_flush( struct svga_context *svga,
struct pipe_fence_handle **pfence )
{
struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
-
+
+ svga->curr.nr_fbs = 0;
+
/* Unmap upload manager buffers:
*/
u_upload_flush(svga->upload_vb);
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 9a3e92fd8d..e650a251d1 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -191,6 +191,11 @@ struct svga_state
struct pipe_framebuffer_state framebuffer;
float depthscale;
+ /* Hack to limit the number of different render targets between
+ * flushes. Helps avoid blowing out our surface cache in EXA.
+ */
+ int nr_fbs;
+
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct pipe_blend_color blend_color;
diff --git a/src/gallium/drivers/svga/svga_debug.h b/src/gallium/drivers/svga/svga_debug.h
index b7bb5686ed..3a3fcd8fae 100644
--- a/src/gallium/drivers/svga/svga_debug.h
+++ b/src/gallium/drivers/svga/svga_debug.h
@@ -43,6 +43,7 @@
#define DEBUG_FLUSH 0x1000 /* flush after every draw */
#define DEBUG_SYNC 0x2000 /* sync after every flush */
#define DEBUG_QUERY 0x4000
+#define DEBUG_CACHE 0x8000
#ifdef DEBUG
extern int SVGA_DEBUG;
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index 1b371cecc6..8db40d0fd5 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -29,10 +29,13 @@
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "svga_context.h"
#include "svga_draw.h"
#include "svga_draw_private.h"
+#include "svga_debug.h"
#include "svga_screen.h"
#include "svga_screen_buffer.h"
+#include "svga_screen_texture.h"
#include "svga_winsys.h"
#include "svga_cmd.h"
@@ -160,6 +163,10 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
ib_handle[i] = handle;
}
+ SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
+ svga_surface(svga->curr.framebuffer.cbufs[0])->handle,
+ hwtnl->cmd.prim_count);
+
ret = SVGA3D_BeginDrawPrimitives(swc,
&vdecl,
hwtnl->cmd.vdecl_count,
diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c
index 5a4a8c0f5f..4f575b06e6 100644
--- a/src/gallium/drivers/svga/svga_pipe_blit.c
+++ b/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -25,6 +25,7 @@
#include "svga_screen_texture.h"
#include "svga_context.h"
+#include "svga_debug.h"
#include "svga_cmd.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -43,6 +44,13 @@ static void svga_surface_copy(struct pipe_context *pipe,
svga_hwtnl_flush_retry( svga );
+ SVGA_DBG(DEBUG_DMA, "blit to sid %p (%d,%d), from sid %p (%d,%d) sz %dx%d\n",
+ svga_surface(dest)->handle,
+ destx, desty,
+ svga_surface(src)->handle,
+ srcx, srcy,
+ width, height);
+
ret = SVGA3D_BeginSurfaceCopy(svga->swc,
src,
dest,
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index 8977d26541..6195c3897e 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -24,12 +24,14 @@
**********************************************************/
#include "svga_cmd.h"
+#include "svga_debug.h"
#include "pipe/p_defines.h"
#include "util/u_pack_color.h"
#include "svga_context.h"
#include "svga_state.h"
+#include "svga_screen_texture.h"
static enum pipe_error
@@ -98,6 +100,10 @@ svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
{
struct svga_context *svga = svga_context( pipe );
int ret;
+
+ if (buffers & PIPE_CLEAR_COLOR)
+ SVGA_DBG(DEBUG_DMA, "clear sid %p\n",
+ svga_surface(svga->curr.framebuffer.cbufs[0])->handle);
ret = try_clear( svga, buffers, rgba, depth, stencil );
diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c
index 942366de72..0becb0765a 100644
--- a/src/gallium/drivers/svga/svga_pipe_flush.c
+++ b/src/gallium/drivers/svga/svga_pipe_flush.c
@@ -59,6 +59,9 @@ static void svga_flush( struct pipe_context *pipe,
/* Flush command queue.
*/
svga_context_flush(svga, fence);
+
+ SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s flags %x fence_ptr %p\n",
+ __FUNCTION__, flags, fence ? *fence : 0x0);
}
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 3afcaffff5..fc1b3c980e 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -57,6 +57,7 @@ static const struct debug_named_value svga_debug_flags[] = {
{ "perf", DEBUG_PERF },
{ "flush", DEBUG_FLUSH },
{ "sync", DEBUG_SYNC },
+ { "cache", DEBUG_CACHE },
{NULL, 0}
};
#endif
@@ -297,6 +298,10 @@ svga_fence_finish(struct pipe_screen *screen,
unsigned flag)
{
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
+
+ SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
+ __FUNCTION__, fence);
+
return sws->fence_finish(sws, fence, flag);
}
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c
index 3b7811734e..1f8a889672 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.c
+++ b/src/gallium/drivers/svga/svga_screen_buffer.c
@@ -71,7 +71,10 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
sbuf->key.numFaces = 1;
sbuf->key.numMipLevels = 1;
+ sbuf->key.cachable = 1;
+ SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size);
+
sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
if(!sbuf->handle)
return PIPE_ERROR_OUT_OF_MEMORY;
@@ -82,7 +85,7 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
*/
sbuf->hw.flags.discard = TRUE;
- SVGA_DBG(DEBUG_DMA, " grab sid %p sz %d\n", sbuf->handle, sbuf->base.size);
+ SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
}
return PIPE_OK;
@@ -444,7 +447,7 @@ svga_buffer_map_range( struct pipe_screen *screen,
enum pipe_error ret;
struct pipe_fence_handle *fence = NULL;
- SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p, bytes %u - %u\n",
+ SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n",
sbuf->handle, 0, sbuf->base.size);
memset(&flags, 0, sizeof flags);
@@ -776,12 +779,11 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
/*
* We are not the creator of this surface and therefore we must not
- * cache it for reuse. The caching code only caches SVGA3D_BUFFER surfaces
- * so make sure this isn't one of those.
+ * cache it for reuse. Set the cacheable flag to zero in the key to
+ * prevent this.
*/
-
- assert(format != SVGA3D_BUFFER);
sbuf->key.format = format;
+ sbuf->key.cachable = 0;
sws->surface_reference(sws, &sbuf->handle, srf);
return buf;
@@ -794,6 +796,8 @@ svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer)
struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen);
struct svga_winsys_surface *vsurf = NULL;
+ assert(svga_buffer(buffer)->key.cachable == 0);
+ svga_buffer(buffer)->key.cachable = 0;
sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle);
return vsurf;
}
diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c
index 7360c1688b..8a06383f61 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.c
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -24,6 +24,7 @@
**********************************************************/
#include "util/u_memory.h"
+#include "util/u_hash.h"
#include "svga_debug.h"
#include "svga_winsys.h"
@@ -36,24 +37,11 @@
/**
* Compute the bucket for this key.
- *
- * We simply compute log2(width) for now, but
*/
static INLINE unsigned
svga_screen_cache_bucket(const struct svga_host_surface_cache_key *key)
{
- unsigned bucket = 0;
- unsigned size = key->size.width;
-
- while ((size >>= 1))
- ++bucket;
-
- if(key->flags & SVGA3D_SURFACE_HINT_INDEXBUFFER)
- bucket += 32;
-
- assert(bucket < SVGA_HOST_SURFACE_CACHE_BUCKETS);
-
- return bucket;
+ return util_hash_crc32( key, sizeof *key ) % SVGA_HOST_SURFACE_CACHE_BUCKETS;
}
@@ -69,6 +57,8 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen,
unsigned bucket;
unsigned tries = 0;
+ assert(key->cachable);
+
bucket = svga_screen_cache_bucket(key);
pipe_mutex_lock(cache->mutex);
@@ -104,11 +94,9 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen,
pipe_mutex_unlock(cache->mutex);
-#if 0
- _debug_printf("%s: cache %s after %u tries\n", __FUNCTION__, handle ? "hit" : "miss", tries);
-#else
- (void)tries;
-#endif
+ if (SVGA_DEBUG & DEBUG_DMA)
+ debug_printf("%s: cache %s after %u tries (bucket %d)\n", __FUNCTION__,
+ handle ? "hit" : "miss", tries, bucket);
return handle;
}
@@ -128,6 +116,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
struct svga_host_surface_cache_entry *entry = NULL;
struct svga_winsys_surface *handle = *p_handle;
+ assert(key->cachable);
assert(handle);
if(!handle)
@@ -137,15 +126,16 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
pipe_mutex_lock(cache->mutex);
if(!LIST_IS_EMPTY(&cache->empty)) {
- /* use the first empty entry */
- entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head);
+ /* use the first empty entry */
+ entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head);
- LIST_DEL(&entry->head);
- }
+ LIST_DEL(&entry->head);
+ }
else if(!LIST_IS_EMPTY(&cache->unused)) {
/* free the last used buffer and reuse its entry */
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->unused.prev, head);
- SVGA_DBG(DEBUG_DMA, "unref sid %p\n", entry->handle);
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "unref sid %p (make space)\n", entry->handle);
sws->surface_reference(sws, &entry->handle, NULL);
LIST_DEL(&entry->bucket_head);
@@ -157,11 +147,14 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
entry->handle = handle;
memcpy(&entry->key, key, sizeof entry->key);
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "cache sid %p\n", entry->handle);
LIST_ADD(&entry->head, &cache->validated);
}
else {
/* Couldn't cache the buffer -- this really shouldn't happen */
- SVGA_DBG(DEBUG_DMA, "unref sid %p\n", handle);
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "unref sid %p (couldn't find space)\n", handle);
sws->surface_reference(sws, &handle, NULL);
}
@@ -220,7 +213,8 @@ svga_screen_cache_cleanup(struct svga_screen *svgascreen)
for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) {
if(cache->entries[i].handle) {
- SVGA_DBG(DEBUG_DMA, "unref sid %p\n", cache->entries[i].handle);
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "unref sid %p (shutdown)\n", cache->entries[i].handle);
sws->surface_reference(sws, &cache->entries[i].handle, NULL);
}
@@ -261,18 +255,45 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
{
struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_winsys_surface *handle = NULL;
+ boolean cachable = SVGA_SURFACE_CACHE_ENABLED && key->cachable;
+
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "%s sz %dx%dx%d mips %d faces %d cachable %d\n",
+ __FUNCTION__,
+ key->size.width,
+ key->size.height,
+ key->size.depth,
+ key->numMipLevels,
+ key->numFaces,
+ key->cachable);
+
+ if (cachable) {
+ if (key->format == SVGA3D_BUFFER) {
+ /* For buffers, round the buffer size up to the nearest power
+ * of two to increase the probability of cache hits. Keep
+ * texture surface dimensions unchanged.
+ */
+ uint32_t size = 1;
+ while(size < key->size.width)
+ size <<= 1;
+ key->size.width = size;
+ }
- if (SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) {
- /* round the buffer size up to the nearest power of two to increase the
- * probability of cache hits */
- uint32_t size = 1;
- while(size < key->size.width)
- size <<= 1;
- key->size.width = size;
-
handle = svga_screen_cache_lookup(svgascreen, key);
- if (handle)
- SVGA_DBG(DEBUG_DMA, " reuse sid %p sz %d\n", handle, size);
+ if (handle) {
+ if (key->format == SVGA3D_BUFFER)
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "reuse sid %p sz %d (buffer)\n", handle,
+ key->size.width);
+ else
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ "reuse sid %p sz %dx%dx%d mips %d faces %d\n", handle,
+ key->size.width,
+ key->size.height,
+ key->size.depth,
+ key->numMipLevels,
+ key->numFaces);
+ }
}
if (!handle) {
@@ -283,7 +304,12 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
key->numFaces,
key->numMipLevels);
if (handle)
- SVGA_DBG(DEBUG_DMA, "create sid %p sz %d\n", handle, key->size);
+ SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+ " CREATE sid %p sz %dx%dx%d\n",
+ handle,
+ key->size.width,
+ key->size.height,
+ key->size.depth);
}
return handle;
@@ -297,11 +323,16 @@ svga_screen_surface_destroy(struct svga_screen *svgascreen,
{
struct svga_winsys_screen *sws = svgascreen->sws;
- if(SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) {
+ /* We only set the cachable flag for surfaces of which we are the
+ * exclusive owner. So just hold onto our existing reference in
+ * that case.
+ */
+ if(SVGA_SURFACE_CACHE_ENABLED && key->cachable) {
svga_screen_cache_add(svgascreen, key, p_handle);
}
else {
- SVGA_DBG(DEBUG_DMA, "unref sid %p\n", *p_handle);
+ SVGA_DBG(DEBUG_DMA,
+ "unref sid %p (uncachable)\n", *p_handle);
sws->surface_reference(sws, p_handle, NULL);
}
}
diff --git a/src/gallium/drivers/svga/svga_screen_cache.h b/src/gallium/drivers/svga/svga_screen_cache.h
index 1bbe987768..f5aa740d40 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.h
+++ b/src/gallium/drivers/svga/svga_screen_cache.h
@@ -36,10 +36,18 @@
#include "util/u_double_list.h"
-/* TODO: Reduce this once we don't allocate an index buffer per draw call */
+/* Guess the storage size of cached surfaces and try and keep it under
+ * this amount:
+ */
+#define SVGA_HOST_SURFACE_CACHE_BYTES 16*1024*1024
+
+/* Maximum number of discrete surfaces in the cache:
+ */
#define SVGA_HOST_SURFACE_CACHE_SIZE 1024
-#define SVGA_HOST_SURFACE_CACHE_BUCKETS 64
+/* Number of hash buckets:
+ */
+#define SVGA_HOST_SURFACE_CACHE_BUCKETS 256
struct svga_winsys_surface;
@@ -53,8 +61,9 @@ struct svga_host_surface_cache_key
SVGA3dSurfaceFlags flags;
SVGA3dSurfaceFormat format;
SVGA3dSize size;
- uint32_t numFaces;
- uint32_t numMipLevels;
+ uint32_t numFaces:24;
+ uint32_t numMipLevels:7;
+ uint32_t cachable:1; /* False if this is a shared surface */
};
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index fb11b80dcf..6e10d65a20 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -266,14 +266,8 @@ svga_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
struct svga_screen *svgascreen = svga_screen(screen);
- struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_texture *tex = CALLOC_STRUCT(svga_texture);
unsigned width, height, depth;
- SVGA3dSurfaceFlags flags = 0;
- SVGA3dSurfaceFormat format;
- SVGA3dSize size;
- uint32 numFaces;
- uint32 numMipLevels;
unsigned level;
if (!tex)
@@ -298,23 +292,24 @@ svga_texture_create(struct pipe_screen *screen,
depth = u_minify(depth, 1);
}
- size.width = templat->width0;
- size.height = templat->height0;
- size.depth = templat->depth0;
+ tex->key.flags = 0;
+ tex->key.size.width = templat->width0;
+ tex->key.size.height = templat->height0;
+ tex->key.size.depth = templat->depth0;
if(templat->target == PIPE_TEXTURE_CUBE) {
- flags |= SVGA3D_SURFACE_CUBEMAP;
- numFaces = 6;
+ tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
+ tex->key.numFaces = 6;
}
else {
- numFaces = 1;
+ tex->key.numFaces = 1;
}
if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
- flags |= SVGA3D_SURFACE_HINT_TEXTURE;
+ tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
- flags |= SVGA3D_SURFACE_HINT_SCANOUT;
+ tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
/*
* XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
@@ -325,21 +320,24 @@ svga_texture_create(struct pipe_screen *screen,
#if 0
if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
!pf_is_compressed(templat->format))
- flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
+ tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
#endif
if(templat->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
- flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
+ tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
- numMipLevels = templat->last_level + 1;
+ tex->key.numMipLevels = templat->last_level + 1;
- format = svga_translate_format(templat->format);
- if(format == SVGA3D_FORMAT_INVALID)
+ tex->key.format = svga_translate_format(templat->format);
+ if(tex->key.format == SVGA3D_FORMAT_INVALID)
goto error2;
+
+ tex->key.cachable = 1;
- tex->handle = sws->surface_create(sws, flags, format, size, numFaces, numMipLevels);
+ SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
+ tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
if (tex->handle)
- SVGA_DBG(DEBUG_DMA, "create sid %p (texture)\n", tex->handle);
+ SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle);
return &tex->base;
@@ -395,6 +393,7 @@ svga_texture_blanket(struct pipe_screen * screen,
return NULL;
tex->base = *base;
+
if (sbuf->key.format == 1)
tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM;
@@ -404,6 +403,12 @@ svga_texture_blanket(struct pipe_screen * screen,
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
+ SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle);
+
+ /* We don't own this storage, so don't try to cache it.
+ */
+ assert(sbuf->key.cachable == 0);
+ tex->key.cachable = 0;
sws->surface_reference(sws, &tex->handle, sbuf->handle);
return &tex->base;
@@ -424,7 +429,7 @@ svga_texture_destroy(struct pipe_texture *pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
- ss->sws->surface_reference(ss->sws, &tex->handle, NULL);
+ svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
FREE(tex);
}
@@ -515,43 +520,47 @@ svga_texture_view_surface(struct pipe_context *pipe,
unsigned start_mip,
unsigned num_mip,
int face_pick,
- int zslice_pick)
+ int zslice_pick,
+ struct svga_host_surface_cache_key *key) /* OUT */
{
struct svga_screen *ss = svga_screen(tex->base.screen);
- struct svga_winsys_screen *sws = ss->sws;
struct svga_winsys_surface *handle;
int i, j;
- SVGA3dSurfaceFlags flags = 0;
- SVGA3dSize size;
- uint32 numFaces;
- uint32 numMipLevels = num_mip;
unsigned z_offset = 0;
SVGA_DBG(DEBUG_PERF,
"svga: Create surface view: face %d zslice %d mips %d..%d\n",
face_pick, zslice_pick, start_mip, start_mip+num_mip-1);
- size.width = u_minify(tex->base.width0, start_mip);
- size.height = u_minify(tex->base.height0, start_mip);
- size.depth = zslice_pick < 0 ? u_minify(tex->base.depth0, start_mip) : 1;
- assert(size.depth == 1);
+ key->flags = 0;
+ key->format = format;
+ key->numMipLevels = num_mip;
+ key->size.width = u_minify(tex->base.width0, start_mip);
+ key->size.height = u_minify(tex->base.height0, start_mip);
+ key->size.depth = zslice_pick < 0 ? u_minify(tex->base.depth0, start_mip) : 1;
+ key->cachable = 1;
+ assert(key->size.depth == 1);
if(tex->base.target == PIPE_TEXTURE_CUBE && face_pick < 0) {
- flags |= SVGA3D_SURFACE_CUBEMAP;
- numFaces = 6;
+ key->flags |= SVGA3D_SURFACE_CUBEMAP;
+ key->numFaces = 6;
} else {
- numFaces = 1;
+ key->numFaces = 1;
}
- if(format == SVGA3D_FORMAT_INVALID)
+ if(key->format == SVGA3D_FORMAT_INVALID) {
+ key->cachable = 0;
return NULL;
+ }
- handle = sws->surface_create(sws, flags, format, size, numFaces, numMipLevels);
-
- if (!handle)
+ SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
+ handle = svga_screen_surface_create(ss, key);
+ if (!handle) {
+ key->cachable = 0;
return NULL;
+ }
- SVGA_DBG(DEBUG_DMA, "create sid %p (texture view)\n", handle);
+ SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
if (face_pick < 0)
face_pick = 0;
@@ -559,15 +568,23 @@ svga_texture_view_surface(struct pipe_context *pipe,
if (zslice_pick >= 0)
z_offset = zslice_pick;
- for (i = 0; i < num_mip; i++) {
- for (j = 0; j < numFaces; j++) {
+ for (i = 0; i < key->numMipLevels; i++) {
+ for (j = 0; j < key->numFaces; j++) {
if(tex->defined[j + face_pick][i + start_mip]) {
- unsigned depth = zslice_pick < 0 ? u_minify(tex->base.depth0, i + start_mip) : 1;
- svga_texture_copy_handle(svga_context(pipe), ss,
- tex->handle, 0, 0, z_offset, i + start_mip, j + face_pick,
+ unsigned depth = (zslice_pick < 0 ?
+ u_minify(tex->base.depth0, i + start_mip) :
+ 1);
+
+ svga_texture_copy_handle(svga_context(pipe),
+ ss,
+ tex->handle,
+ 0, 0, z_offset,
+ i + start_mip,
+ j + face_pick,
handle, 0, 0, 0, i, j,
u_minify(tex->base.width0, i + start_mip),
- u_minify(tex->base.height0, i + start_mip), depth);
+ u_minify(tex->base.height0, i + start_mip),
+ depth);
}
}
}
@@ -584,25 +601,23 @@ svga_get_tex_surface(struct pipe_screen *screen,
{
struct svga_texture *tex = svga_texture(pt);
struct svga_surface *s;
- struct pipe_surface *ps;
boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE;
boolean view = FALSE;
SVGA3dSurfaceFormat format;
s = CALLOC_STRUCT(svga_surface);
- ps = &s->base;
- if (!ps)
+ if (!s)
return NULL;
- pipe_reference_init(&ps->reference, 1);
- pipe_texture_reference(&ps->texture, pt);
- ps->format = pt->format;
- ps->width = u_minify(pt->width0, level);
- ps->height = u_minify(pt->height0, level);
- ps->usage = flags;
- ps->level = level;
- ps->face = face;
- ps->zslice = zslice;
+ pipe_reference_init(&s->base.reference, 1);
+ pipe_texture_reference(&s->base.texture, pt);
+ s->base.format = pt->format;
+ s->base.width = u_minify(pt->width0, level);
+ s->base.height = u_minify(pt->height0, level);
+ s->base.usage = flags;
+ s->base.level = level;
+ s->base.face = face;
+ s->base.zslice = zslice;
if (!render)
format = svga_translate_format(pt->format);
@@ -617,11 +632,13 @@ svga_get_tex_surface(struct pipe_screen *screen,
view = TRUE;
/* Currently only used for compressed textures */
- if (render && (format != svga_translate_format(pt->format))) {
+ if (render &&
+ format != svga_translate_format(pt->format)) {
view = TRUE;
}
- if (level != 0 && svga_screen(screen)->debug.force_level_surface_view)
+ if (level != 0 &&
+ svga_screen(screen)->debug.force_level_surface_view)
view = TRUE;
if (pt->target == PIPE_TEXTURE_3D)
@@ -632,9 +649,10 @@ svga_get_tex_surface(struct pipe_screen *screen,
if (view) {
SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
- pt, level, face, zslice, ps);
+ pt, level, face, zslice, s);
- s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice);
+ s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
+ &s->key);
s->real_face = 0;
s->real_level = 0;
s->real_zslice = 0;
@@ -642,15 +660,16 @@ svga_get_tex_surface(struct pipe_screen *screen,
struct svga_winsys_screen *sws = svga_winsys_screen(screen);
SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
- pt, level, face, zslice, ps);
+ pt, level, face, zslice, s);
+ memset(&s->key, 0, sizeof s->key);
sws->surface_reference(sws, &s->handle, tex->handle);
s->real_face = face;
s->real_level = level;
s->real_zslice = zslice;
}
- return ps;
+ return &s->base;
}
@@ -661,7 +680,8 @@ svga_tex_surface_destroy(struct pipe_surface *surf)
struct svga_screen *ss = svga_screen(surf->texture->screen);
SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
- ss->sws->surface_reference(ss->sws, &s->handle, NULL);
+ assert(s->key.cachable == 0);
+ svga_screen_surface_destroy(ss, &s->key, &s->handle);
pipe_texture_reference(&surf->texture, NULL);
FREE(surf);
}
@@ -956,6 +976,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
pt->height0,
pt->depth0,
pt->last_level);
+ sv->key.cachable = 0;
sws->surface_reference(sws, &sv->handle, tex->handle);
return sv;
}
@@ -973,10 +994,12 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
sv->handle = svga_texture_view_surface(pipe, tex, format,
min_lod,
max_lod - min_lod + 1,
- -1, -1);
+ -1, -1,
+ &sv->key);
if (!sv->handle) {
assert(0);
+ sv->key.cachable = 0;
sws->surface_reference(sws, &sv->handle, tex->handle);
return sv;
}
@@ -1029,7 +1052,7 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
struct svga_screen *ss = svga_screen(v->texture->base.screen);
SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
- ss->sws->surface_reference(ss->sws, &v->handle, NULL);
+ svga_screen_surface_destroy(ss, &v->key, &v->handle);
FREE(v);
}
@@ -1059,6 +1082,8 @@ svga_screen_texture_get_winsys_surface(struct pipe_texture *texture)
struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
struct svga_winsys_surface *vsurf = NULL;
+ assert(svga_texture(texture)->key.cachable == 0);
+ svga_texture(texture)->key.cachable = 0;
sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle);
return vsurf;
}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
index 1e6fef59a3..1cc4063e65 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -29,7 +29,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
-
+#include "svga_screen_cache.h"
struct pipe_context;
struct pipe_screen;
@@ -68,6 +68,7 @@ struct svga_sampler_view
unsigned age;
+ struct svga_host_surface_cache_key key;
struct svga_winsys_surface *handle;
};
@@ -76,8 +77,6 @@ struct svga_texture
{
struct pipe_texture base;
- struct svga_winsys_surface *handle;
-
boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
struct svga_sampler_view *cached_view;
@@ -86,6 +85,16 @@ struct svga_texture
unsigned age;
boolean views_modified;
+
+ /**
+ * Creation key for the host surface handle.
+ *
+ * This structure describes all the host surface characteristics so that it
+ * can be looked up in cache, since creating a host surface is often a slow
+ * operation.
+ */
+ struct svga_host_surface_cache_key key;
+ struct svga_winsys_surface *handle;
};
@@ -93,6 +102,7 @@ struct svga_surface
{
struct pipe_surface base;
+ struct svga_host_surface_cache_key key;
struct svga_winsys_surface *handle;
unsigned real_face;
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
index 7d7f93d8e3..cfdcae4ee4 100644
--- a/src/gallium/drivers/svga/svga_state_framebuffer.c
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -54,6 +54,9 @@ static int emit_framebuffer( struct svga_context *svga,
for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
if (curr->cbufs[i] != hw->cbufs[i]) {
+ if (svga->curr.nr_fbs++ > 8)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]);
if (ret != PIPE_OK)
return ret;
diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c
index 81eea1a145..b8ef137c01 100644
--- a/src/gallium/drivers/svga/svga_tgsi.c
+++ b/src/gallium/drivers/svga/svga_tgsi.c
@@ -222,6 +222,20 @@ svga_tgsi_translate( const struct svga_shader *shader,
result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned);
memcpy(&result->key, &key, sizeof key);
+ if (SVGA_DEBUG & DEBUG_TGSI)
+ {
+ debug_printf( "#####################################\n" );
+ debug_printf( "Shader %u below\n", shader->id );
+ tgsi_dump( shader->tokens, 0 );
+ if (SVGA_DEBUG & DEBUG_TGSI) {
+ debug_printf( "Shader %u compiled below\n", shader->id );
+ svga_shader_dump( result->tokens,
+ result->nr_tokens ,
+ FALSE );
+ }
+ debug_printf( "#####################################\n" );
+ }
+
return result;
fail:
diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile
index 22c107370e..cb2c3aea41 100644
--- a/src/gallium/state_trackers/xorg/Makefile
+++ b/src/gallium/state_trackers/xorg/Makefile
@@ -7,6 +7,9 @@ LIBRARY_INCLUDES = \
-DHAVE_CONFIG_H \
$(shell pkg-config xextproto --atleast-version=7.0.99.1 \
&& echo "-DHAVE_XEXTPROTO_71") \
+ $(shell pkg-config libkms --atleast-version=1.0 \
+ && echo "-DHAVE_LIBKMS") \
+ $(shell pkg-config libkms --silence-errors --cflags-only-I) \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/auxiliary \
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 69a83b1523..1c248a629e 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -232,15 +232,25 @@ bind_blend_state(struct exa_context *exa, int op,
}
static unsigned
-picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask)
+picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
+ PicturePtr pDstPicture)
{
boolean set_alpha = FALSE;
boolean swizzle = FALSE;
unsigned ret = 0;
if (pSrc->picture_format == pSrcPicture->format) {
- if (pSrc->picture_format == PICT_a8)
- return mask ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE;
+ if (pSrc->picture_format == PICT_a8) {
+ if (mask)
+ return FS_MASK_LUMINANCE;
+ else if (pDstPicture->format != PICT_a8) {
+ /* if both dst and src are luminance then
+ * we don't want to swizzle the alpha (X) of the
+ * source into W component of the dst because
+ * it will break our destination */
+ return FS_SRC_LUMINANCE;
+ }
+ }
return 0;
}
@@ -285,7 +295,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool
static void
bind_shaders(struct exa_context *exa, int op,
- PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
{
unsigned vs_traits = 0, fs_traits = 0;
@@ -313,7 +323,7 @@ bind_shaders(struct exa_context *exa, int op,
vs_traits |= VS_COMPOSITE;
}
- fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE);
+ fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
}
if (pMaskPicture) {
@@ -331,7 +341,7 @@ bind_shaders(struct exa_context *exa, int op,
fs_traits |= FS_CA_FULL;
}
- fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE);
+ fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
}
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
@@ -411,40 +421,7 @@ bind_samplers(struct exa_context *exa, int op,
exa->bound_textures);
}
-static void
-setup_vs_constant_buffer(struct exa_context *exa,
- int width, int height)
-{
- const int param_bytes = 8 * sizeof(float);
- float vs_consts[8] = {
- 2.f/width, 2.f/height, 1, 1,
- -1, -1, 0, 0
- };
- renderer_set_constants(exa->renderer, PIPE_SHADER_VERTEX,
- vs_consts, param_bytes);
-}
-
-
-static void
-setup_fs_constant_buffer(struct exa_context *exa)
-{
- const int param_bytes = 4 * sizeof(float);
- const float fs_consts[8] = {
- 0, 0, 0, 1,
- };
- renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT,
- fs_consts, param_bytes);
-}
-
-static void
-setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
-{
- int width = pDst->tex->width0;
- int height = pDst->tex->height0;
- setup_vs_constant_buffer(exa, width, height);
- setup_fs_constant_buffer(exa);
-}
static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
{
@@ -493,14 +470,16 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
struct exa_pixmap_priv *pMask,
struct exa_pixmap_priv *pDst)
{
- renderer_bind_framebuffer(exa->renderer, pDst);
- renderer_bind_viewport(exa->renderer, pDst);
+ struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
+
+ renderer_bind_destination(exa->renderer, dst_surf,
+ pDst->width,
+ pDst->height);
+
bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
- renderer_bind_rasterizer(exa->renderer);
- bind_shaders(exa, op, pSrcPicture, pMaskPicture, pSrc, pMask);
+ bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
bind_samplers(exa, op, pSrcPicture, pMaskPicture,
pDstPicture, pSrc, pMask, pDst);
- setup_constant_buffers(exa, pDst);
setup_transforms(exa, pSrcPicture, pMaskPicture);
@@ -512,6 +491,8 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
exa->num_bound_samplers);
}
+
+ pipe_surface_reference(&dst_surf, NULL);
return TRUE;
}
@@ -546,6 +527,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
struct exa_pixmap_priv *pixmap,
Pixel fg)
{
+ struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap);
unsigned vs_traits, fs_traits;
struct xorg_shader shader;
@@ -563,13 +545,11 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
vs_traits = VS_SOLID_FILL;
fs_traits = FS_SOLID_FILL;
- renderer_bind_framebuffer(exa->renderer, pixmap);
- renderer_bind_viewport(exa->renderer, pixmap);
- renderer_bind_rasterizer(exa->renderer);
+ renderer_bind_destination(exa->renderer, dst_surf,
+ pixmap->width, pixmap->height);
bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
cso_set_samplers(exa->renderer->cso, 0, NULL);
cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
- setup_constant_buffers(exa, pixmap);
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
@@ -577,6 +557,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
renderer_begin_solid(exa->renderer);
+ pipe_surface_reference(&dst_surf, NULL);
return TRUE;
}
@@ -588,3 +569,13 @@ void xorg_solid(struct exa_context *exa,
x0, y0, x1, y1, exa->solid_color);
}
+void
+xorg_composite_done(struct exa_context *exa)
+{
+ renderer_draw_flush(exa->renderer);
+
+ exa->transform.has_src = FALSE;
+ exa->transform.has_mask = FALSE;
+ exa->has_solid_color = FALSE;
+ exa->num_bound_samplers = 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h
index 236addf1ce..ec71ebfe0d 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.h
+++ b/src/gallium/state_trackers/xorg/xorg_composite.h
@@ -29,4 +29,8 @@ void xorg_solid(struct exa_context *exa,
struct exa_pixmap_priv *pixmap,
int x0, int y0, int x1, int y1);
+
+void
+xorg_composite_done(struct exa_context *exa);
+
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index c4751724c9..9e8c14d741 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -52,12 +52,18 @@
#include "pipe/p_inlines.h"
#include "util/u_rect.h"
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
+
struct crtc_private
{
drmModeCrtcPtr drm_crtc;
/* hwcursor */
struct pipe_texture *cursor_tex;
+ struct kms_bo *cursor_bo;
+
unsigned cursor_handle;
};
@@ -134,6 +140,7 @@ static void
crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
int size)
{
+ /* XXX: hockup */
}
static void *
@@ -160,6 +167,7 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
static void
crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
{
+ /* XXX: See if this one is needed, as we only support ARGB cursors */
}
static void
@@ -170,8 +178,9 @@ crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y);
}
+
static void
-crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
+crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
{
unsigned char *ptr;
modesettingPtr ms = modesettingPTR(crtc->scrn);
@@ -214,13 +223,63 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
ms->screen->tex_transfer_destroy(transfer);
}
+#if HAVE_LIBKMS
+static void
+crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
+{
+ modesettingPtr ms = modesettingPTR(crtc->scrn);
+ struct crtc_private *crtcp = crtc->driver_private;
+ unsigned char *ptr;
+
+ if (!crtcp->cursor_bo) {
+ unsigned attr[8];
+
+ attr[0] = KMS_BO_TYPE;
+ attr[1] = KMS_BO_TYPE_CURSOR;
+ attr[2] = KMS_WIDTH;
+ attr[3] = 64;
+ attr[4] = KMS_HEIGHT;
+ attr[5] = 64;
+ attr[6] = 0;
+
+ if (kms_bo_create(ms->kms, attr, &crtcp->cursor_bo))
+ return;
+
+ if (kms_bo_get_prop(crtcp->cursor_bo, KMS_HANDLE,
+ &crtcp->cursor_handle))
+ goto err_bo_destroy;
+ }
+
+ kms_bo_map(crtcp->cursor_bo, (void**)&ptr);
+ memcpy(ptr, image, 64*64*4);
+ kms_bo_unmap(crtcp->cursor_bo);
+
+ return;
+
+err_bo_destroy:
+ kms_bo_destroy(crtcp->cursor_bo);
+}
+#endif
+
+static void
+crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
+{
+ modesettingPtr ms = modesettingPTR(crtc->scrn);
+ if (ms->screen)
+ crtc_load_cursor_argb_ga3d(crtc, image);
+#ifdef HAVE_LIBKMS
+ else if (ms->kms)
+ crtc_load_cursor_argb_kms(crtc, image);
+#endif
+}
+
static void
crtc_show_cursor(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_tex)
+ if (crtcp->cursor_tex || crtcp->cursor_bo)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
crtcp->cursor_handle, 64, 64);
}
@@ -234,14 +293,22 @@ crtc_hide_cursor(xf86CrtcPtr crtc)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
}
+/**
+ * Called at vt leave
+ */
void
-crtc_cursor_destroy(xf86CrtcPtr crtc)
+xorg_crtc_cursor_destroy(xf86CrtcPtr crtc)
{
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_tex) {
+ if (crtcp->cursor_tex)
pipe_texture_reference(&crtcp->cursor_tex, NULL);
- }
+#ifdef HAVE_LIBKMS
+ if (crtcp->cursor_bo)
+ kms_bo_destroy(crtcp->cursor_bo);
+#endif
+
+ xfree(crtcp);
}
/*
@@ -279,7 +346,7 @@ static const xf86CrtcFuncsRec crtc_funcs = {
};
void
-crtc_init(ScrnInfoPtr pScrn)
+xorg_crtc_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcPtr crtc;
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 406e0afff4..2394f004d2 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -55,7 +55,7 @@ typedef struct {
} *BufferPrivatePtr;
static Bool
-driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
+dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
{
struct pipe_texture *tex = NULL;
ScreenPtr pScreen = pDraw->pScreen;
@@ -157,7 +157,7 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
}
static void
-driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -174,7 +174,7 @@ driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
#if DRI2INFOREC_VERSION >= 2
static DRI2Buffer2Ptr
-driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
+dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
{
DRI2Buffer2Ptr buffer;
BufferPrivatePtr private;
@@ -192,7 +192,7 @@ driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
buffer->driverPrivate = private;
/* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */
- if (driDoCreateBuffer(pDraw, (DRI2BufferPtr)buffer, format))
+ if (dri2_do_create_buffer(pDraw, (DRI2BufferPtr)buffer, format))
return buffer;
xfree(private);
@@ -202,10 +202,10 @@ fail:
}
static void
-driDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
+dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
{
/* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */
- driDoDestroyBuffer(pDraw, (DRI2BufferPtr)buffer);
+ dri2_do_destroy_buffer(pDraw, (DRI2BufferPtr)buffer);
xfree(buffer->driverPrivate);
xfree(buffer);
@@ -214,7 +214,7 @@ driDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
#else /* DRI2INFOREC_VERSION < 2 */
static DRI2BufferPtr
-driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
+dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count)
{
BufferPrivatePtr privates;
DRI2BufferPtr buffers;
@@ -232,7 +232,7 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
buffers[i].attachment = attachments[i];
buffers[i].driverPrivate = &privates[i];
- if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
+ if (!dri2_do_create_buffer(pDraw, &buffers[i], 0))
goto fail;
}
@@ -247,12 +247,12 @@ fail_buffers:
}
static void
-driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
+dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{
int i;
for (i = 0; i < count; i++) {
- driDoDestroyBuffer(pDraw, &buffers[i]);
+ dri2_do_destroy_buffer(pDraw, &buffers[i]);
}
if (buffers) {
@@ -264,16 +264,16 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
#endif /* DRI2INFOREC_VERSION >= 2 */
static void
-driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
- DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
+dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
+ DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;
BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate;
- PixmapPtr src_pixmap;
- PixmapPtr dst_pixmap;
+ DrawablePtr src_draw;
+ DrawablePtr dst_draw;
GCPtr gc;
RegionPtr copy_clip;
Bool save_accel;
@@ -284,12 +284,10 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
* We need to use the real drawable in CopyArea
* so that cliprects and offsets are correct.
*/
- src_pixmap = src_priv->pPixmap;
- dst_pixmap = dst_priv->pPixmap;
- if (pSrcBuffer->attachment == DRI2BufferFrontLeft)
- src_pixmap = (PixmapPtr)pDraw;
- if (pDestBuffer->attachment == DRI2BufferFrontLeft)
- dst_pixmap = (PixmapPtr)pDraw;
+ src_draw = (pSrcBuffer->attachment == DRI2BufferFrontLeft) ? pDraw :
+ &src_priv->pPixmap->drawable;
+ dst_draw = (pDestBuffer->attachment == DRI2BufferFrontLeft) ? pDraw :
+ &dst_priv->pPixmap->drawable;
/*
* The clients implements glXWaitX with a copy front to fake and then
@@ -308,7 +306,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
* must in the glXWaitGL case but we don't know if this is a glXWaitGL
* or a glFlush/glFinish call.
*/
- if (dst_pixmap == src_pixmap) {
+ if (dst_priv->pPixmap == src_priv->pPixmap) {
/* pixmap glXWaitX */
if (pSrcBuffer->attachment == DRI2BufferFrontLeft &&
pDestBuffer->attachment == DRI2BufferFakeFrontLeft) {
@@ -329,7 +327,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
copy_clip = REGION_CREATE(pScreen, NULL, 0);
REGION_COPY(pScreen, copy_clip, pRegion);
(*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
- ValidateGC(&dst_pixmap->drawable, gc);
+ ValidateGC(dst_draw, gc);
/* If this is a full buffer swap, throttle on the previous one */
if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
@@ -342,9 +340,19 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
}
}
+ /* Try to make sure the blit will be accelerated */
save_accel = ms->exa->accel;
ms->exa->accel = TRUE;
- (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc,
+
+ /* In case it won't be though, make sure the GPU copy contents of the
+ * source pixmap will be used for the software fallback - presumably the
+ * client modified them before calling in here.
+ */
+ exaMoveInPixmap(src_priv->pPixmap);
+ DamageRegionAppend(src_draw, pRegion);
+ DamageRegionProcessPending(src_draw);
+
+ (*gc->ops->CopyArea)(src_draw, dst_draw, gc,
0, 0, pDraw->width, pDraw->height, 0, 0);
ms->exa->accel = save_accel;
@@ -356,7 +364,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
}
Bool
-driScreenInit(ScreenPtr pScreen)
+xorg_dri2_init(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -373,13 +381,13 @@ driScreenInit(ScreenPtr pScreen)
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
#if DRI2INFOREC_VERSION >= 2
- dri2info.CreateBuffer = driCreateBuffer;
- dri2info.DestroyBuffer = driDestroyBuffer;
+ dri2info.CreateBuffer = dri2_create_buffer;
+ dri2info.DestroyBuffer = dri2_destroy_buffer;
#else
- dri2info.CreateBuffers = driCreateBuffers;
- dri2info.DestroyBuffers = driDestroyBuffers;
+ dri2info.CreateBuffers = dri2_create_buffers;
+ dri2info.DestroyBuffers = dri2_destroy_buffers;
#endif
- dri2info.CopyRegion = driCopyRegion;
+ dri2info.CopyRegion = dri2_copy_region;
dri2info.Wait = NULL;
ms->d_depth_bits_last =
@@ -395,7 +403,7 @@ driScreenInit(ScreenPtr pScreen)
}
void
-driCloseScreen(ScreenPtr pScreen)
+xorg_dri2_close(ScreenPtr pScreen)
{
DRI2CloseScreen(pScreen);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index d949167adc..1291591298 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -56,34 +56,38 @@
#include "xorg_tracker.h"
#include "xorg_winsys.h"
-static void AdjustFrame(int scrnIndex, int x, int y, int flags);
-static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool EnterVT(int scrnIndex, int flags);
-static Bool SaveHWState(ScrnInfoPtr pScrn);
-static Bool RestoreHWState(ScrnInfoPtr pScrn);
-
-
-static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
- int flags);
-static void FreeScreen(int scrnIndex, int flags);
-static void LeaveVT(int scrnIndex, int flags);
-static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
-static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
- char **argv);
-static Bool PreInit(ScrnInfoPtr pScrn, int flags);
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
+
+/*
+ * Functions and symbols exported to Xorg via pointers.
+ */
+
+static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags);
+static Bool drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags);
+static void drv_adjust_frame(int scrnIndex, int x, int y, int flags);
+static Bool drv_enter_vt(int scrnIndex, int flags);
+static void drv_leave_vt(int scrnIndex, int flags);
+static void drv_free_screen(int scrnIndex, int flags);
+static ModeStatus drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
typedef enum
{
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
-} modesettingOpts;
+} drv_option_enums;
-static const OptionInfoRec Options[] = {
+static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
+
/*
* Exported Xorg driver functions to winsys
*/
@@ -91,28 +95,39 @@ static const OptionInfoRec Options[] = {
const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid)
{
- return Options;
+ return drv_options;
}
void
xorg_tracker_set_functions(ScrnInfoPtr scrn)
{
- scrn->PreInit = PreInit;
- scrn->ScreenInit = ScreenInit;
- scrn->SwitchMode = SwitchMode;
- scrn->AdjustFrame = AdjustFrame;
- scrn->EnterVT = EnterVT;
- scrn->LeaveVT = LeaveVT;
- scrn->FreeScreen = FreeScreen;
- scrn->ValidMode = ValidMode;
+ scrn->PreInit = drv_pre_init;
+ scrn->ScreenInit = drv_screen_init;
+ scrn->SwitchMode = drv_switch_mode;
+ scrn->AdjustFrame = drv_adjust_frame;
+ scrn->EnterVT = drv_enter_vt;
+ scrn->LeaveVT = drv_leave_vt;
+ scrn->FreeScreen = drv_free_screen;
+ scrn->ValidMode = drv_valid_mode;
}
+
/*
- * Static Xorg funtctions
+ * Internal function definitions
+ */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn);
+static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen);
+static Bool drv_save_hw_state(ScrnInfoPtr pScrn);
+static Bool drv_restore_hw_state(ScrnInfoPtr pScrn);
+
+
+/*
+ * Internal functions
*/
static Bool
-GetRec(ScrnInfoPtr pScrn)
+drv_get_rec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate)
return TRUE;
@@ -123,7 +138,7 @@ GetRec(ScrnInfoPtr pScrn)
}
static void
-FreeRec(ScrnInfoPtr pScrn)
+drv_free_rec(ScrnInfoPtr pScrn)
{
if (!pScrn)
return;
@@ -137,88 +152,21 @@ FreeRec(ScrnInfoPtr pScrn)
}
static void
-ProbeDDC(ScrnInfoPtr pScrn, int index)
+drv_probe_ddc(ScrnInfoPtr pScrn, int index)
{
ConfiguredMonitor = NULL;
}
static Bool
-CreateFrontBuffer(ScrnInfoPtr pScrn)
-{
- modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
- struct pipe_texture *tex;
-
- ms->noEvict = TRUE;
-
- tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
- pScrn->depth, pScrn->bitsPerPixel);
-
- if (!tex)
- return FALSE;
-
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- tex,
- &stride,
- &handle))
- return FALSE;
-
- drmModeAddFB(ms->fd,
- pScrn->virtualX,
- pScrn->virtualY,
- pScrn->depth,
- pScrn->bitsPerPixel,
- stride,
- handle,
- &ms->fb_id);
-
- pScrn->frameX0 = 0;
- pScrn->frameY0 = 0;
- AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- pipe_texture_reference(&ms->root_texture, tex);
- pipe_texture_reference(&tex, NULL);
- return TRUE;
-}
-
-static Bool
-BindTextureToRoot(ScrnInfoPtr pScrn)
-{
- modesettingPtr ms = modesettingPTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
- struct pipe_texture *check;
- PixmapPtr rootPixmap;
-
- rootPixmap = pScreen->GetScreenPixmap(pScreen);
-
- xorg_exa_set_displayed_usage(rootPixmap);
- xorg_exa_set_shared_usage(rootPixmap);
- xorg_exa_set_texture(rootPixmap, ms->root_texture);
- if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
- FatalError("Couldn't adjust screen pixmap\n");
-
- check = xorg_exa_get_texture(rootPixmap);
- if (ms->root_texture != check)
- FatalError("Created new root texture\n");
-
- pipe_texture_reference(&check, NULL);
-
- return TRUE;
-}
-
-static Bool
-crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
PixmapPtr rootPixmap;
ScreenPtr pScreen = pScrn->pScreen;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
- ErrorF("RESIZING TO %dx%d\n", width, height);
-
pScrn->virtualX = width;
pScrn->virtualY = height;
@@ -226,44 +174,26 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
* Remove the old framebuffer & texture.
*/
drmModeRmFB(ms->fd, ms->fb_id);
- pipe_texture_reference(&ms->root_texture, NULL);
-
+ if (!ms->destroy_front_buffer(pScrn))
+ FatalError("failed to destroy front buffer\n");
rootPixmap = pScreen->GetScreenPixmap(pScreen);
if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
return FALSE;
- /* takes one ref */
- ms->root_texture = xorg_exa_get_texture(rootPixmap);
-
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- ms->root_texture,
- &stride,
- &handle))
- FatalError("Could not get handle and stride from texture\n");
-
- drmModeAddFB(ms->fd,
- pScrn->virtualX,
- pScrn->virtualY,
- pScrn->depth,
- pScrn->bitsPerPixel,
- stride,
- handle,
- &ms->fb_id);
-
/* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
/* now create new frontbuffer */
- return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn);
+ return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
- crtc_resize
+ .resize = drv_crtc_resize
};
static Bool
-InitDRM(ScrnInfoPtr pScrn)
+drv_init_drm(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
@@ -283,18 +213,62 @@ InitDRM(ScrnInfoPtr pScrn)
return FALSE;
}
- if (!ms->api) {
- ms->api = drm_api_create();
+ return TRUE;
+}
- if (!ms->api)
- return FALSE;
+static Bool
+drv_init_resource_management(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+
+ if (ms->screen || ms->kms)
+ return TRUE;
+
+ ms->api = drm_api_create();
+ if (ms->api) {
+ ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+
+ if (ms->screen)
+ return TRUE;
+
+ if (ms->api->destroy)
+ ms->api->destroy(ms->api);
+
+ ms->api = NULL;
}
+#ifdef HAVE_LIBKMS
+ if (!kms_create(ms->fd, &ms->kms))
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+static Bool
+drv_close_resource_management(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+
+ if (ms->screen)
+ ms->screen->destroy(ms->screen);
+ ms->screen = NULL;
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+ ms->api = NULL;
+
+#ifdef HAVE_LIBKMS
+ if (ms->kms)
+ kms_destroy(ms->kms);
+ ms->kms = NULL;
+#endif
+
return TRUE;
}
static Bool
-PreInit(ScrnInfoPtr pScrn, int flags)
+drv_pre_init(ScrnInfoPtr pScrn, int flags)
{
xf86CrtcConfigPtr xf86_config;
modesettingPtr ms;
@@ -309,12 +283,12 @@ PreInit(ScrnInfoPtr pScrn, int flags)
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (flags & PROBE_DETECT) {
- ProbeDDC(pScrn, pEnt->index);
+ drv_probe_ddc(pScrn, pEnt->index);
return TRUE;
}
/* Allocate driverPrivate */
- if (!GetRec(pScrn))
+ if (!drv_get_rec(pScrn))
return FALSE;
ms = modesettingPTR(pScrn);
@@ -351,7 +325,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ms->fd = -1;
ms->api = NULL;
- if (!InitDRM(pScrn))
+ if (!drv_init_drm(pScrn))
return FALSE;
pScrn->monitor = pScrn->confScreen->monitor;
@@ -383,9 +357,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
/* Process the options */
xf86CollectOptions(pScrn, NULL);
- if (!(ms->Options = xalloc(sizeof(Options))))
+ if (!(ms->Options = xalloc(sizeof(drv_options))))
return FALSE;
- memcpy(ms->Options, Options, sizeof(Options));
+ memcpy(ms->Options, drv_options, sizeof(drv_options));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
/* Allocate an xf86CrtcConfig */
@@ -400,18 +374,18 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ms->SWCursor = TRUE;
}
- SaveHWState(pScrn);
+ drv_save_hw_state(pScrn);
- crtc_init(pScrn);
- output_init(pScrn);
+ xorg_crtc_init(pScrn);
+ xorg_output_init(pScrn);
if (!xf86InitialConfiguration(pScrn, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
return FALSE;
}
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
@@ -435,21 +409,23 @@ PreInit(ScrnInfoPtr pScrn, int flags)
xf86SetDpi(pScrn, 0, 0);
/* Load the required sub modules */
- if (!xf86LoadSubModule(pScrn, "fb")) {
+ if (!xf86LoadSubModule(pScrn, "fb"))
return FALSE;
- }
- xf86LoadSubModule(pScrn, "exa");
+ /* XXX: these aren't needed when we are using libkms */
+ if (!xf86LoadSubModule(pScrn, "exa"))
+ return FALSE;
#ifdef DRI2
- xf86LoadSubModule(pScrn, "dri2");
+ if (!xf86LoadSubModule(pScrn, "dri2"))
+ return FALSE;
#endif
return TRUE;
}
static Bool
-SaveHWState(ScrnInfoPtr pScrn)
+drv_save_hw_state(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
@@ -457,24 +433,45 @@ SaveHWState(ScrnInfoPtr pScrn)
}
static Bool
-RestoreHWState(ScrnInfoPtr pScrn)
+drv_restore_hw_state(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
return TRUE;
}
-static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
- pointer pReadmask)
+static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
+ pointer pReadmask)
{
ScreenPtr pScreen = screenInfo.screens[i];
modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
pScreen->BlockHandler = ms->blockHandler;
pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
- pScreen->BlockHandler = xorgBlockHandler;
-
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ pScreen->BlockHandler = drv_block_handler;
+
+ if (ms->ctx) {
+ int j;
+
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
+
#ifdef DRM_MODE_FEATURE_DIRTYFB
{
@@ -504,7 +501,7 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
}
static Bool
-CreateScreenResources(ScreenPtr pScreen)
+drv_create_screen_resources(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -515,13 +512,13 @@ CreateScreenResources(ScreenPtr pScreen)
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
- pScreen->CreateScreenResources = CreateScreenResources;
+ pScreen->CreateScreenResources = drv_create_screen_resources;
- BindTextureToRoot(pScrn);
+ ms->bind_front_buffer(pScrn);
ms->noEvict = FALSE;
- AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
#ifdef DRM_MODE_FEATURE_DIRTYFB
rootPixmap = pScreen->GetScreenPixmap(pScreen);
@@ -545,22 +542,25 @@ CreateScreenResources(ScreenPtr pScreen)
}
static Bool
-ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
VisualPtr visual;
- if (!InitDRM(pScrn))
+ if (!drv_init_drm(pScrn)) {
+ FatalError("Could not init DRM");
return FALSE;
+ }
- if (!ms->screen) {
- ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+ if (!drv_init_resource_management(pScrn)) {
+ FatalError("Could not init resource management (!pipe_screen && !libkms)");
+ return FALSE;
+ }
- if (!ms->screen) {
- FatalError("Could not init pipe_screen\n");
- return FALSE;
- }
+ if (!drv_init_front_buffer_functions(pScrn)) {
+ FatalError("Could not init front buffer manager");
+ return FALSE;
}
pScrn->pScreen = pScreen;
@@ -605,17 +605,22 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
ms->blockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xorgBlockHandler;
+ pScreen->BlockHandler = drv_block_handler;
ms->createScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = CreateScreenResources;
+ pScreen->CreateScreenResources = drv_create_screen_resources;
xf86SetBlackWhitePixels(pScreen);
- ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
- OPTION_2D_ACCEL, TRUE));
- ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+ if (ms->screen) {
+ ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
+ OPTION_2D_ACCEL, TRUE));
+ ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
- xorg_init_video(pScreen);
+ xorg_xv_init(pScreen);
+#ifdef DRI2
+ xorg_dri2_init(pScreen);
+#endif
+ }
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -634,7 +639,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScreen->SaveScreen = xf86SaveScreen;
ms->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = CloseScreen;
+ pScreen->CloseScreen = drv_close_screen;
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
@@ -647,17 +652,11 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
-#if 1
-#ifdef DRI2
- driScreenInit(pScreen);
-#endif
-#endif
-
- return EnterVT(scrnIndex, 1);
+ return drv_enter_vt(scrnIndex, 1);
}
static void
-AdjustFrame(int scrnIndex, int x, int y, int flags)
+drv_adjust_frame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -673,13 +672,13 @@ AdjustFrame(int scrnIndex, int x, int y, int flags)
}
static void
-FreeScreen(int scrnIndex, int flags)
+drv_free_screen(int scrnIndex, int flags)
{
- FreeRec(xf86Screens[scrnIndex]);
+ drv_free_rec(xf86Screens[scrnIndex]);
}
static void
-LeaveVT(int scrnIndex, int flags)
+drv_leave_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -689,7 +688,7 @@ LeaveVT(int scrnIndex, int flags)
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
- crtc_cursor_destroy(crtc);
+ xorg_crtc_cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@@ -701,7 +700,7 @@ LeaveVT(int scrnIndex, int flags)
drmModeRmFB(ms->fd, ms->fb_id);
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
if (drmDropMaster(ms->fd))
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -714,7 +713,7 @@ LeaveVT(int scrnIndex, int flags)
* This gets called when gaining control of the VT, and from ScreenInit().
*/
static Bool
-EnterVT(int scrnIndex, int flags)
+drv_enter_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -736,13 +735,13 @@ EnterVT(int scrnIndex, int flags)
*/
if (ms->SaveGeneration != serverGeneration) {
ms->SaveGeneration = serverGeneration;
- SaveHWState(pScrn);
+ drv_save_hw_state(pScrn);
}
- if (!CreateFrontBuffer(pScrn))
+ if (!ms->create_front_buffer(pScrn))
return FALSE;
- if (!flags && !BindTextureToRoot(pScrn))
+ if (!flags && !ms->bind_front_buffer(pScrn))
return FALSE;
if (!xf86SetDesiredModes(pScrn))
@@ -752,7 +751,7 @@ EnterVT(int scrnIndex, int flags)
}
static Bool
-SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
@@ -760,16 +759,18 @@ SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
}
static Bool
-CloseScreen(int scrnIndex, ScreenPtr pScreen)
+drv_close_screen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
if (pScrn->vtSema) {
- LeaveVT(scrnIndex, 0);
+ drv_leave_vt(scrnIndex, 0);
}
+
#ifdef DRI2
- driCloseScreen(pScreen);
+ if (ms->screen)
+ xorg_dri2_close(pScreen);
#endif
pScreen->BlockHandler = ms->blockHandler;
@@ -783,14 +784,14 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
#endif
- pipe_texture_reference(&ms->root_texture, NULL);
+ drmModeRmFB(ms->fd, ms->fb_id);
+ ms->destroy_front_buffer(pScrn);
if (ms->exa)
xorg_exa_close(pScrn);
+ ms->exa = NULL;
- if (ms->api && ms->api->destroy)
- ms->api->destroy(ms->api);
- ms->api = NULL;
+ drv_close_resource_management(pScrn);
drmClose(ms->fd);
ms->fd = -1;
@@ -801,9 +802,190 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
static ModeStatus
-ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
return MODE_OK;
}
+
+/*
+ * Front buffer backing store functions.
+ */
+
+static Bool
+drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ pipe_texture_reference(&ms->root_texture, NULL);
+ return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned handle, stride;
+ struct pipe_texture *tex;
+
+ ms->noEvict = TRUE;
+
+ tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
+ pScrn->depth, pScrn->bitsPerPixel);
+
+ if (!tex)
+ return FALSE;
+
+ if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
+ tex,
+ &stride,
+ &handle))
+ return FALSE;
+
+ drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+
+ pScrn->frameX0 = 0;
+ pScrn->frameY0 = 0;
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ pipe_texture_reference(&ms->root_texture, tex);
+ pipe_texture_reference(&tex, NULL);
+
+ return TRUE;
+}
+
+static Bool
+drv_bind_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ struct pipe_texture *check;
+
+ xorg_exa_set_displayed_usage(rootPixmap);
+ xorg_exa_set_shared_usage(rootPixmap);
+ xorg_exa_set_texture(rootPixmap, ms->root_texture);
+ if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
+ FatalError("Couldn't adjust screen pixmap\n");
+
+ check = xorg_exa_get_texture(rootPixmap);
+ if (ms->root_texture != check)
+ FatalError("Created new root texture\n");
+
+ pipe_texture_reference(&check, NULL);
+ return TRUE;
+}
+
+#ifdef HAVE_LIBKMS
+static Bool
+drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+
+ if (!ms->root_bo)
+ return TRUE;
+
+ kms_bo_unmap(ms->root_bo);
+ kms_bo_destroy(ms->root_bo);
+ ms->root_bo = NULL;
+ return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned handle, stride;
+ struct kms_bo *bo;
+ unsigned attr[8];
+
+ attr[0] = KMS_BO_TYPE;
+ attr[1] = KMS_BO_TYPE_SCANOUT;
+ attr[2] = KMS_WIDTH;
+ attr[3] = pScrn->virtualX;
+ attr[4] = KMS_HEIGHT;
+ attr[5] = pScrn->virtualY;
+ attr[6] = 0;
+
+ if (kms_bo_create(ms->kms, attr, &bo))
+ return FALSE;
+
+ if (kms_bo_get_prop(bo, KMS_PITCH, &stride))
+ goto err_destroy;
+
+ if (kms_bo_get_prop(bo, KMS_HANDLE, &handle))
+ goto err_destroy;
+
+ drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+
+ pScrn->frameX0 = 0;
+ pScrn->frameY0 = 0;
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ ms->root_bo = bo;
+
+ return TRUE;
+
+err_destroy:
+ kms_bo_destroy(bo);
+ return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ unsigned stride;
+ void *ptr;
+
+ if (kms_bo_get_prop(ms->root_bo, KMS_PITCH, &stride))
+ return FALSE;
+
+ if (kms_bo_map(ms->root_bo, &ptr))
+ return FALSE;
+
+ pScreen->ModifyPixmapHeader(rootPixmap,
+ pScreen->width,
+ pScreen->height,
+ pScreen->rootDepth,
+ pScrn->bitsPerPixel,
+ stride,
+ ptr);
+ return TRUE;
+}
+#endif /* HAVE_LIBKMS */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ if (ms->screen) {
+ ms->destroy_front_buffer = drv_destroy_front_buffer_ga3d;
+ ms->create_front_buffer = drv_create_front_buffer_ga3d;
+ ms->bind_front_buffer = drv_bind_front_buffer_ga3d;
+#ifdef HAVE_LIBKMS
+ } else if (ms->kms) {
+ ms->destroy_front_buffer = drv_destroy_front_buffer_kms;
+ ms->create_front_buffer = drv_create_front_buffer_kms;
+ ms->bind_front_buffer = drv_bind_front_buffer_kms;
+#endif
+ } else
+ return FALSE;
+
+ return TRUE;
+}
+
/* vim: set sw=4 ts=8 sts=4: */
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index a68a626fa4..16e683019c 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -44,8 +44,11 @@
#include "pipe/p_inlines.h"
#include "util/u_rect.h"
+#include "util/u_math.h"
+#include "util/u_debug.h"
#define DEBUG_PRINT 0
+#define ROUND_UP_TEXTURES 1
/*
* Helper functions
@@ -149,18 +152,6 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_
}
}
-static void
-xorg_exa_common_done(struct exa_context *exa)
-{
- renderer_draw_flush(exa->renderer);
-
- exa->copy.src = NULL;
- exa->copy.dst = NULL;
- exa->transform.has_src = FALSE;
- exa->transform.has_mask = FALSE;
- exa->has_solid_color = FALSE;
- exa->num_bound_samplers = 0;
-}
/*
* Static exported EXA functions
@@ -178,6 +169,11 @@ ExaMarkSync(ScreenPtr pScreen)
return 1;
}
+
+/***********************************************************************
+ * Screen upload/download
+ */
+
static Bool
ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
int dst_pitch)
@@ -278,13 +274,22 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
PIPE_REFERENCED_FOR_WRITE)
exa->pipe->flush(exa->pipe, 0, NULL);
+ assert(pPix->drawable.width <= priv->tex->width0);
+ assert(pPix->drawable.height <= priv->tex->height0);
+
priv->map_transfer =
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
#ifdef EXA_MIXED_PIXMAPS
PIPE_TRANSFER_MAP_DIRECTLY |
#endif
PIPE_TRANSFER_READ_WRITE,
+<<<<<<< HEAD:src/gallium/state_trackers/xorg/xorg_exa.c
0, 0, priv->tex->width0, priv->tex->height0);
+=======
+ 0, 0,
+ pPix->drawable.width,
+ pPix->drawable.height );
+>>>>>>> origin/mesa_7_7_branch:src/gallium/state_trackers/xorg/xorg_exa.c
if (!priv->map_transfer)
#ifdef EXA_MIXED_PIXMAPS
return FALSE;
@@ -327,29 +332,9 @@ ExaFinishAccess(PixmapPtr pPix, int index)
}
}
-static void
-ExaDone(PixmapPtr pPixmap)
-{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- struct exa_context *exa = ms->exa;
-
- if (!priv)
- return;
-
- xorg_exa_common_done(exa);
-}
-
-static void
-ExaDoneComposite(PixmapPtr pPixmap)
-{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
-
- xorg_exa_common_done(exa);
-}
+/***********************************************************************
+ * Solid Fills
+ */
static Bool
ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
@@ -395,9 +380,34 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
#endif
+ if (x0 == 0 && y0 == 0 &&
+ x1 == pPixmap->drawable.width && y1 == pPixmap->drawable.height) {
+ exa->pipe->clear(exa->pipe, PIPE_CLEAR_COLOR, exa->solid_color, 0.0, 0);
+ return;
+ }
+
xorg_solid(exa, priv, x0, y0, x1, y1) ;
}
+
+static void
+ExaDoneSolid(PixmapPtr pPixmap)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct exa_context *exa = ms->exa;
+
+ if (!priv)
+ return;
+
+ xorg_composite_done(exa);
+}
+
+/***********************************************************************
+ * Copy Blits
+ */
+
static Bool
ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
int ydir, int alu, Pixel planeMask)
@@ -439,6 +449,51 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
exa->copy.src = src_priv;
exa->copy.dst = priv;
+ /* For same-surface copies, the pipe->surface_copy path is clearly
+ * superior, providing it is implemented. In other cases it's not
+ * clear what the better path would be, and eventually we'd
+ * probably want to gather timings and choose dynamically.
+ */
+ if (exa->pipe->surface_copy &&
+ exa->copy.src == exa->copy.dst) {
+
+ exa->copy.use_surface_copy = TRUE;
+
+ exa->copy.src_surface =
+ exa->scrn->get_tex_surface( exa->scrn,
+ exa->copy.src->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ);
+
+ exa->copy.dst_surface =
+ exa->scrn->get_tex_surface( exa->scrn,
+ exa->copy.dst->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE );
+ }
+ else {
+ exa->copy.use_surface_copy = FALSE;
+
+ if (exa->copy.dst == exa->copy.src)
+ exa->copy.src_texture = renderer_clone_texture( exa->renderer,
+ exa->copy.src->tex );
+ else
+ pipe_texture_reference(&exa->copy.src_texture,
+ exa->copy.src->tex);
+
+ exa->copy.dst_surface =
+ exa->scrn->get_tex_surface(exa->scrn,
+ exa->copy.dst->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+ renderer_copy_prepare(exa->renderer,
+ exa->copy.dst_surface,
+ exa->copy.src_texture );
+ }
+
+
return exa->accel;
}
@@ -458,11 +513,48 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
debug_assert(priv == exa->copy.dst);
- renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY,
- exa->copy.src, srcX, srcY,
- width, height);
+ if (exa->copy.use_surface_copy) {
+ /* XXX: consider exposing >1 box in surface_copy interface.
+ */
+ exa->pipe->surface_copy( exa->pipe,
+ exa->copy.dst_surface,
+ dstX, dstY,
+ exa->copy.src_surface,
+ srcX, srcY,
+ width, height );
+ }
+ else {
+ renderer_copy_pixmap(exa->renderer,
+ dstX, dstY,
+ srcX, srcY,
+ width, height,
+ exa->copy.src_texture->width0,
+ exa->copy.src_texture->height0);
+ }
}
+static void
+ExaDoneCopy(PixmapPtr pPixmap)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct exa_context *exa = ms->exa;
+
+ if (!priv)
+ return;
+
+ renderer_draw_flush(exa->renderer);
+
+ exa->copy.src = NULL;
+ exa->copy.dst = NULL;
+ pipe_surface_reference(&exa->copy.src_surface, NULL);
+ pipe_surface_reference(&exa->copy.dst_surface, NULL);
+ pipe_texture_reference(&exa->copy.src_texture, NULL);
+}
+
+
+
static Bool
picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
{
@@ -498,6 +590,30 @@ picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
return FALSE;
}
+/***********************************************************************
+ * Composite entrypoints
+ */
+
+static Bool
+ExaCheckComposite(int op,
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+ boolean accelerated = xorg_composite_accelerated(op,
+ pSrcPicture,
+ pMaskPicture,
+ pDstPicture);
+#if DEBUG_PRINT
+ debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
+ op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
+#endif
+ return exa->accel && accelerated;
+}
+
+
static Bool
ExaPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -548,8 +664,6 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
render_format_name(priv->picture_format),
render_format_name(pSrcPicture->format));
- if (priv->picture_format == PICT_a8)
- XORG_FALLBACK("pSrc pic_format == PICT_a8");
}
if (pMask) {
@@ -596,25 +710,23 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
dstX, dstY, width, height);
}
-static Bool
-ExaCheckComposite(int op,
- PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture)
+
+
+static void
+ExaDoneComposite(PixmapPtr pPixmap)
{
- ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
- boolean accelerated = xorg_composite_accelerated(op,
- pSrcPicture,
- pMaskPicture,
- pDstPicture);
-#if DEBUG_PRINT
- debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
- op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
-#endif
- return exa->accel && accelerated;
+
+ xorg_composite_done(exa);
}
+
+/***********************************************************************
+ * Pixmaps
+ */
+
static void *
ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
{
@@ -718,6 +830,22 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
}
static Bool
+size_match( int width, int tex_width )
+{
+#if ROUND_UP_TEXTURES
+ if (width > tex_width)
+ return FALSE;
+
+ if (width * 2 < tex_width)
+ return FALSE;
+
+ return TRUE;
+#else
+ return width == tex_width;
+#endif
+}
+
+static Bool
ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
int depth, int bitsPerPixel, int devKind,
pointer pPixData)
@@ -731,6 +859,17 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
if (!priv || pPixData)
return FALSE;
+ if (0) {
+ debug_printf("%s pixmap %p sz %dx%dx%d devKind %d\n",
+ __FUNCTION__, pPixmap, width, height, bitsPerPixel, devKind);
+
+ if (priv->tex)
+ debug_printf(" ==> old texture %dx%d\n",
+ priv->tex->width0,
+ priv->tex->height0);
+ }
+
+
if (depth <= 0)
depth = pPixmap->drawable.depth;
@@ -749,12 +888,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
miModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, NULL);
+ priv->width = width;
+ priv->height = height;
+
/* Deal with screen resize */
if ((exa->accel || priv->flags) &&
(!priv->tex ||
- (priv->tex->width0 != width ||
- priv->tex->height0 != height ||
- priv->tex_flags != priv->flags))) {
+ !size_match(width, priv->tex->width0) ||
+ !size_match(height, priv->tex->height0) ||
+ priv->tex_flags != priv->flags)) {
struct pipe_texture *texture = NULL;
struct pipe_texture template;
@@ -762,8 +904,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
template.target = PIPE_TEXTURE_2D;
exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
pf_get_block(template.format, &template.block);
- template.width0 = width;
- template.height0 = height;
+ if (ROUND_UP_TEXTURES && priv->flags == 0) {
+ template.width0 = util_next_power_of_two(width);
+ template.height0 = util_next_power_of_two(height);
+ }
+ else {
+ template.width0 = width;
+ template.height0 = height;
+ }
+
template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
@@ -777,15 +926,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
dst_surf = exa->scrn->get_tex_surface(
exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
src_surf = xorg_gpu_surface(exa->pipe->screen, priv);
- if (exa->pipe->surface_copy) {
- exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
- 0, 0, min(width, texture->width0),
- min(height, texture->height0));
- } else {
- util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
- 0, 0, min(width, texture->width0),
- min(height, texture->height0));
- }
+ if (exa->pipe->surface_copy) {
+ exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
+ 0, 0, min(width, texture->width0),
+ min(height, texture->height0));
+ } else {
+ util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
+ 0, 0, min(width, texture->width0),
+ min(height, texture->height0));
+ }
exa->scrn->tex_surface_destroy(dst_surf);
exa->scrn->tex_surface_destroy(src_surf);
}
@@ -907,10 +1056,10 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
pExa->MarkSync = ExaMarkSync;
pExa->PrepareSolid = ExaPrepareSolid;
pExa->Solid = ExaSolid;
- pExa->DoneSolid = ExaDone;
+ pExa->DoneSolid = ExaDoneSolid;
pExa->PrepareCopy = ExaPrepareCopy;
pExa->Copy = ExaCopy;
- pExa->DoneCopy = ExaDone;
+ pExa->DoneCopy = ExaDoneCopy;
pExa->CheckComposite = ExaCheckComposite;
pExa->PrepareComposite = ExaPrepareComposite;
pExa->Composite = ExaComposite;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 15cc29d662..f2cefe23b9 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -35,13 +35,22 @@ struct exa_context
} transform;
struct {
+ boolean use_surface_copy;
+
struct exa_pixmap_priv *src;
struct exa_pixmap_priv *dst;
+
+ struct pipe_surface *src_surface;
+ struct pipe_surface *dst_surface;
+
+ struct pipe_texture *src_texture;
} copy;
};
struct exa_pixmap_priv
{
+ int width, height;
+
int flags;
int tex_flags;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index 52b97af163..89b794a09a 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -396,15 +396,11 @@ xrender_tex(struct ureg_program *ureg,
struct ureg_dst dst,
struct ureg_src coords,
struct ureg_src sampler,
+ struct ureg_src imm0,
boolean repeat_none,
boolean swizzle,
boolean set_alpha)
{
- struct ureg_src imm0 = { 0 };
-
- if (repeat_none || set_alpha)
- imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
-
if (repeat_none) {
struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
@@ -466,6 +462,7 @@ create_fs(struct pipe_context *pipe,
struct ureg_src /*dst_pos,*/ src_input, mask_pos;
struct ureg_dst src, mask;
struct ureg_dst out;
+ struct ureg_src imm0 = { 0 };
unsigned has_mask = (fs_traits & FS_MASK) != 0;
unsigned is_fill = (fs_traits & FS_FILL) != 0;
unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
@@ -483,8 +480,6 @@ create_fs(struct pipe_context *pipe,
unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
- if (src_luminance)
- assert(!"src_luminance not supported");
#if 0
print_fs_traits(fs_traits);
#else
@@ -502,6 +497,11 @@ create_fs(struct pipe_context *pipe,
TGSI_SEMANTIC_COLOR,
0);
+ if (src_repeat_none || mask_repeat_none ||
+ src_set_alpha || mask_set_alpha ||
+ src_luminance) {
+ imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
+ }
if (is_composite) {
src_sampler = ureg_DECL_sampler(ureg, 0);
src_input = ureg_DECL_fs_input(ureg,
@@ -540,16 +540,17 @@ create_fs(struct pipe_context *pipe,
TGSI_INTERPOLATE_PERSPECTIVE);
#endif
+
if (is_composite) {
- if (has_mask)
+ if (has_mask || src_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
- xrender_tex(ureg, src, src_input, src_sampler,
+ xrender_tex(ureg, src, src_input, src_sampler, imm0,
src_repeat_none, src_swizzle, src_set_alpha);
} else if (is_fill) {
if (is_solid) {
- if (has_mask)
+ if (has_mask || src_luminance)
src = ureg_dst(src_input);
else
ureg_MOV(ureg, out, src_input);
@@ -557,7 +558,7 @@ create_fs(struct pipe_context *pipe,
struct ureg_src coords, const0124,
matrow0, matrow1, matrow2;
- if (has_mask)
+ if (has_mask || src_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
@@ -582,10 +583,18 @@ create_fs(struct pipe_context *pipe,
} else
debug_assert(!"Unknown fill type!");
}
+ if (src_luminance) {
+ ureg_MOV(ureg, src,
+ ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
+ ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
+ ureg_scalar(imm0, TGSI_SWIZZLE_X));
+ if (!has_mask)
+ ureg_MOV(ureg, out, ureg_src(src));
+ }
if (has_mask) {
mask = ureg_DECL_temporary(ureg);
- xrender_tex(ureg, mask, mask_pos, mask_sampler,
+ xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
mask_repeat_none, mask_swizzle, mask_set_alpha);
/* src IN mask */
src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index bfeddc5e11..251f331ea7 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -53,7 +53,7 @@
#include "xorg_tracker.h"
-static char *connector_enum_list[] = {
+static char *output_enum_list[] = {
"Unknown",
"VGA",
"DVI",
@@ -70,19 +70,19 @@ static char *connector_enum_list[] = {
};
static void
-create_resources(xf86OutputPtr output)
+output_create_resources(xf86OutputPtr output)
{
#ifdef RANDR_12_INTERFACE
#endif /* RANDR_12_INTERFACE */
}
static void
-dpms(xf86OutputPtr output, int mode)
+output_dpms(xf86OutputPtr output, int mode)
{
}
static xf86OutputStatus
-detect(xf86OutputPtr output)
+output_detect(xf86OutputPtr output)
{
drmModeConnectorPtr drm_connector = output->driver_private;
@@ -97,7 +97,7 @@ detect(xf86OutputPtr output)
}
static DisplayModePtr
-get_modes(xf86OutputPtr output)
+output_get_modes(xf86OutputPtr output)
{
drmModeConnectorPtr drm_connector = output->driver_private;
drmModeModeInfoPtr drm_mode = NULL;
@@ -110,7 +110,6 @@ get_modes(xf86OutputPtr output)
mode = xcalloc(1, sizeof(DisplayModeRec));
if (!mode)
continue;
- mode->type = 0;
mode->Clock = drm_mode->clock;
mode->HDisplay = drm_mode->hdisplay;
mode->HSyncStart = drm_mode->hsync_start;
@@ -125,6 +124,11 @@ get_modes(xf86OutputPtr output)
mode->VScan = drm_mode->vscan;
mode->VRefresh = xf86ModeVRefresh(mode);
mode->Private = (void *)drm_mode;
+ mode->type = 0;
+ if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
+ mode->type |= M_T_PREFERRED;
+ if (drm_mode->type & DRM_MODE_TYPE_DRIVER)
+ mode->type |= M_T_DRIVER;
xf86SetModeDefaultName(mode);
modes = xf86ModesAdd(modes, mode);
xf86PrintModeline(0, mode);
@@ -135,14 +139,14 @@ get_modes(xf86OutputPtr output)
}
static int
-mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
return MODE_OK;
}
#ifdef RANDR_12_INTERFACE
static Bool
-set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
+output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
{
return TRUE;
}
@@ -150,36 +154,36 @@ set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
#ifdef RANDR_13_INTERFACE
static Bool
-get_property(xf86OutputPtr output, Atom property)
+output_get_property(xf86OutputPtr output, Atom property)
{
return TRUE;
}
#endif /* RANDR_13_INTERFACE */
static void
-destroy(xf86OutputPtr output)
+output_destroy(xf86OutputPtr output)
{
drmModeFreeConnector(output->driver_private);
}
static const xf86OutputFuncsRec output_funcs = {
- .create_resources = create_resources,
+ .create_resources = output_create_resources,
#ifdef RANDR_12_INTERFACE
- .set_property = set_property,
+ .set_property = output_set_property,
#endif
#ifdef RANDR_13_INTERFACE
- .get_property = get_property,
+ .get_property = output_get_property,
#endif
- .dpms = dpms,
- .detect = detect,
+ .dpms = output_dpms,
+ .detect = output_detect,
- .get_modes = get_modes,
- .mode_valid = mode_valid,
- .destroy = destroy,
+ .get_modes = output_get_modes,
+ .mode_valid = output_mode_valid,
+ .destroy = output_destroy,
};
void
-output_init(ScrnInfoPtr pScrn)
+xorg_output_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
xf86OutputPtr output;
@@ -220,7 +224,7 @@ output_init(ScrnInfoPtr pScrn)
#endif
snprintf(name, 32, "%s%d",
- connector_enum_list[drm_connector->connector_type],
+ output_enum_list[drm_connector->connector_type],
drm_connector->connector_type_id);
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 418a8dd88b..8f73ec5fe1 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -13,11 +13,6 @@
#include <math.h>
-enum AxisOrientation {
- Y0_BOTTOM,
- Y0_TOP
-};
-
#define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
#define floatIsZero(x) (floatsEqual((x) + 1, 1))
@@ -96,10 +91,18 @@ static void
renderer_init_state(struct xorg_renderer *r)
{
struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_rasterizer_state raster;
/* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
cso_set_depth_stencil_alpha(r->cso, &dsa);
+
+
+ /* XXX: move to renderer_init_state? */
+ memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
+ raster.gl_rasterization_rules = 1;
+ cso_set_rasterizer(r->cso, &raster);
+
}
@@ -186,23 +189,6 @@ add_vertex_data1(struct xorg_renderer *r,
add_vertex_1tex(r, dstX, dstY + height, s3, t3);
}
-static struct pipe_buffer *
-setup_vertex_data_tex(struct xorg_renderer *r,
- float x0, float y0, float x1, float y1,
- float s0, float t0, float s1, float t1,
- float z)
-{
- /* 1st vertex */
- add_vertex_1tex(r, x0, y0, s0, t0);
- /* 2nd vertex */
- add_vertex_1tex(r, x1, y0, s1, t0);
- /* 3rd vertex */
- add_vertex_1tex(r, x1, y1, s1, t1);
- /* 4th vertex */
- add_vertex_1tex(r, x0, y1, s0, t1);
-
- return renderer_buffer_create(r);
-}
static INLINE void
add_vertex_2tex(struct xorg_renderer *r,
@@ -322,15 +308,32 @@ setup_vertex_data_yuv(struct xorg_renderer *r,
-static void
-set_viewport(struct xorg_renderer *r, int width, int height,
- enum AxisOrientation orientation)
+/* Set up framebuffer, viewport and vertex shader constant buffer
+ * state for a particular destinaton surface. In all our rendering,
+ * these concepts are linked.
+ */
+void renderer_bind_destination(struct xorg_renderer *r,
+ struct pipe_surface *surface,
+ int width,
+ int height )
{
+
+ struct pipe_framebuffer_state fb;
struct pipe_viewport_state viewport;
- float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f;
+ /* Framebuffer uses actual surface width/height
+ */
+ memset(&fb, 0, sizeof fb);
+ fb.width = surface->width;
+ fb.height = surface->height;
+ fb.nr_cbufs = 1;
+ fb.cbufs[0] = surface;
+ fb.zsbuf = 0;
+
+ /* Viewport just touches the bit we're interested in:
+ */
viewport.scale[0] = width / 2.f;
- viewport.scale[1] = height / y_scale;
+ viewport.scale[1] = height / 2.f;
viewport.scale[2] = 1.0;
viewport.scale[3] = 1.0;
viewport.translate[0] = width / 2.f;
@@ -338,11 +341,28 @@ set_viewport(struct xorg_renderer *r, int width, int height,
viewport.translate[2] = 0.0;
viewport.translate[3] = 0.0;
+ /* Constant buffer set up to match viewport dimensions:
+ */
+ if (r->fb_width != width ||
+ r->fb_height != height)
+ {
+ float vs_consts[8] = {
+ 2.f/width, 2.f/height, 1, 1,
+ -1, -1, 0, 0
+ };
+
+ r->fb_width = width;
+ r->fb_height = height;
+
+ renderer_set_constants(r, PIPE_SHADER_VERTEX,
+ vs_consts, sizeof vs_consts);
+ }
+
+ cso_set_framebuffer(r->cso, &fb);
cso_set_viewport(r->cso, &viewport);
}
-
struct xorg_renderer * renderer_create(struct pipe_context *pipe)
{
struct xorg_renderer *renderer = CALLOC_STRUCT(xorg_renderer);
@@ -379,51 +399,9 @@ void renderer_destroy(struct xorg_renderer *r)
}
}
-void renderer_bind_framebuffer(struct xorg_renderer *r,
- struct exa_pixmap_priv *priv)
-{
- unsigned i;
- struct pipe_framebuffer_state state;
- struct pipe_surface *surface = xorg_gpu_surface(r->pipe->screen, priv);
- memset(&state, 0, sizeof(struct pipe_framebuffer_state));
-
- state.width = priv->tex->width0;
- state.height = priv->tex->height0;
-
- state.nr_cbufs = 1;
- state.cbufs[0] = surface;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- state.cbufs[i] = 0;
-
- /* currently we don't use depth/stencil */
- state.zsbuf = 0;
-
- cso_set_framebuffer(r->cso, &state);
-
- /* we do fire and forget for the framebuffer, this is the forget part */
- pipe_surface_reference(&surface, NULL);
-}
-
-void renderer_bind_viewport(struct xorg_renderer *r,
- struct exa_pixmap_priv *dst)
-{
- int width = dst->tex->width0;
- int height = dst->tex->height0;
- /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
- set_viewport(r, width, height, Y0_TOP);
-}
-void renderer_bind_rasterizer(struct xorg_renderer *r)
-{
- struct pipe_rasterizer_state raster;
-
- /* XXX: move to renderer_init_state? */
- memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
- raster.gl_rasterization_rules = 1;
- cso_set_rasterizer(r->cso, &raster);
-}
void renderer_set_constants(struct xorg_renderer *r,
int shader_type,
@@ -446,182 +424,20 @@ void renderer_set_constants(struct xorg_renderer *r,
r->pipe->set_constant_buffer(r->pipe, shader_type, 0, cbuf);
}
-static void
-setup_vs_constant_buffer(struct xorg_renderer *r,
- int width, int height)
-{
- const int param_bytes = 8 * sizeof(float);
- float vs_consts[8] = {
- 2.f/width, 2.f/height, 1, 1,
- -1, -1, 0, 0
- };
- renderer_set_constants(r, PIPE_SHADER_VERTEX,
- vs_consts, param_bytes);
-}
-static void
-setup_fs_constant_buffer(struct xorg_renderer *r)
-{
- const int param_bytes = 4 * sizeof(float);
- const float fs_consts[8] = {
- 0, 0, 0, 1,
- };
- renderer_set_constants(r, PIPE_SHADER_FRAGMENT,
- fs_consts, param_bytes);
-}
-
-static INLINE void shift_rectx(float coords[4],
- const float *bounds,
- const float shift)
-{
- coords[0] += shift;
- coords[2] -= shift;
- if (bounds) {
- coords[2] = MIN2(coords[2], bounds[2]);
- /* bound x/y + width/height */
- if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
- coords[2] = (bounds[0] + bounds[2]) - coords[0];
- }
- }
-}
-
-static INLINE void shift_recty(float coords[4],
- const float *bounds,
- const float shift)
-{
- coords[1] += shift;
- coords[3] -= shift;
- if (bounds) {
- coords[3] = MIN2(coords[3], bounds[3]);
- if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
- coords[3] = (bounds[1] + bounds[3]) - coords[1];
- }
- }
-}
-
-static INLINE void bound_rect(float coords[4],
- const float bounds[4],
- float shift[4])
-{
- /* if outside the bounds */
- if (coords[0] > (bounds[0] + bounds[2]) ||
- coords[1] > (bounds[1] + bounds[3]) ||
- (coords[0] + coords[2]) < bounds[0] ||
- (coords[1] + coords[3]) < bounds[1]) {
- coords[0] = 0.f;
- coords[1] = 0.f;
- coords[2] = 0.f;
- coords[3] = 0.f;
- shift[0] = 0.f;
- shift[1] = 0.f;
- return;
- }
-
- /* bound x */
- if (coords[0] < bounds[0]) {
- shift[0] = bounds[0] - coords[0];
- coords[2] -= shift[0];
- coords[0] = bounds[0];
- } else
- shift[0] = 0.f;
-
- /* bound y */
- if (coords[1] < bounds[1]) {
- shift[1] = bounds[1] - coords[1];
- coords[3] -= shift[1];
- coords[1] = bounds[1];
- } else
- shift[1] = 0.f;
-
- shift[2] = bounds[2] - coords[2];
- shift[3] = bounds[3] - coords[3];
- /* bound width/height */
- coords[2] = MIN2(coords[2], bounds[2]);
- coords[3] = MIN2(coords[3], bounds[3]);
-
- /* bound x/y + width/height */
- if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
- coords[2] = (bounds[0] + bounds[2]) - coords[0];
- }
- if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
- coords[3] = (bounds[1] + bounds[3]) - coords[1];
- }
-
- /* if outside the bounds */
- if ((coords[0] + coords[2]) < bounds[0] ||
- (coords[1] + coords[3]) < bounds[1]) {
- coords[0] = 0.f;
- coords[1] = 0.f;
- coords[2] = 0.f;
- coords[3] = 0.f;
- return;
- }
-}
-
-static INLINE void sync_size(float *src_loc, float *dst_loc)
-{
- src_loc[2] = MIN2(src_loc[2], dst_loc[2]);
- src_loc[3] = MIN2(src_loc[3], dst_loc[3]);
- dst_loc[2] = src_loc[2];
- dst_loc[3] = src_loc[3];
-}
-
-static void renderer_copy_texture(struct xorg_renderer *r,
- struct pipe_texture *src,
- float sx1, float sy1,
- float sx2, float sy2,
- struct pipe_texture *dst,
- float dx1, float dy1,
- float dx2, float dy2)
+void renderer_copy_prepare(struct xorg_renderer *r,
+ struct pipe_surface *dst_surface,
+ struct pipe_texture *src_texture)
{
struct pipe_context *pipe = r->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_buffer *buf;
- struct pipe_surface *dst_surf = screen->get_tex_surface(
- screen, dst, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
- struct pipe_framebuffer_state fb;
- float s0, t0, s1, t1;
struct xorg_shader shader;
- assert(src->width0 != 0);
- assert(src->height0 != 0);
- assert(dst->width0 != 0);
- assert(dst->height0 != 0);
-
-#if 1
- s0 = sx1 / src->width0;
- s1 = sx2 / src->width0;
- t0 = sy1 / src->height0;
- t1 = sy2 / src->height0;
-#else
- s0 = 0;
- s1 = 1;
- t0 = 0;
- t1 = 1;
-#endif
-
-#if 0
- debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
- sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2,
- s0, t0, s1, t1);
-#endif
-
- assert(screen->is_format_supported(screen, dst_surf->format,
+ assert(screen->is_format_supported(screen, dst_surface->format,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET,
0));
- /* save state (restored below) */
- cso_save_blend(r->cso);
- cso_save_samplers(r->cso);
- cso_save_sampler_textures(r->cso);
- cso_save_framebuffer(r->cso);
- cso_save_fragment_shader(r->cso);
- cso_save_vertex_shader(r->cso);
-
- cso_save_viewport(r->cso);
-
/* set misc state we care about */
{
@@ -650,12 +466,12 @@ static void renderer_copy_texture(struct xorg_renderer *r,
cso_single_sampler_done(r->cso);
}
- set_viewport(r, dst_surf->width, dst_surf->height, Y0_TOP);
+ renderer_bind_destination(r, dst_surface,
+ dst_surface->width,
+ dst_surface->height);
/* texture */
- cso_set_sampler_textures(r->cso, 1, &src);
-
- renderer_bind_rasterizer(r);
+ cso_set_sampler_textures(r->cso, 1, &src_texture);
/* shaders */
shader = xorg_shaders_get(r->shaders,
@@ -664,51 +480,12 @@ static void renderer_copy_texture(struct xorg_renderer *r,
cso_set_vertex_shader_handle(r->cso, shader.vs);
cso_set_fragment_shader_handle(r->cso, shader.fs);
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst_surf->width;
- fb.height = dst_surf->height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst_surf;
- {
- int i;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- fb.cbufs[i] = 0;
- }
- cso_set_framebuffer(r->cso, &fb);
- setup_vs_constant_buffer(r, fb.width, fb.height);
- setup_fs_constant_buffer(r);
-
- /* draw quad */
- buf = setup_vertex_data_tex(r,
- dx1, dy1,
- dx2, dy2,
- s0, t0, s1, t1,
- 0.0f);
-
- if (buf) {
- util_draw_vertex_buffer(r->pipe, buf, 0,
- PIPE_PRIM_QUADS,
- 4, /* verts */
- 2); /* attribs/vert */
-
- pipe_buffer_reference(&buf, NULL);
- }
-
- /* restore state we changed */
- cso_restore_blend(r->cso);
- cso_restore_samplers(r->cso);
- cso_restore_sampler_textures(r->cso);
- cso_restore_framebuffer(r->cso);
- cso_restore_vertex_shader(r->cso);
- cso_restore_fragment_shader(r->cso);
- cso_restore_viewport(r->cso);
-
- pipe_surface_reference(&dst_surf, NULL);
+ r->buffer_size = 0;
+ r->attrs_per_vertex = 2;
}
-static struct pipe_texture *
-create_sampler_texture(struct xorg_renderer *r,
+struct pipe_texture *
+renderer_clone_texture(struct xorg_renderer *r,
struct pipe_texture *src)
{
enum pipe_format format;
@@ -717,7 +494,9 @@ create_sampler_texture(struct xorg_renderer *r,
struct pipe_texture *pt;
struct pipe_texture templ;
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ if (pipe->is_texture_referenced(pipe, src, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* the coming in texture should already have that invariance */
debug_assert(screen->is_format_supported(screen, src->format,
@@ -771,16 +550,16 @@ create_sampler_texture(struct xorg_renderer *r,
void renderer_copy_pixmap(struct xorg_renderer *r,
- struct exa_pixmap_priv *dst_priv, int dx, int dy,
- struct exa_pixmap_priv *src_priv, int sx, int sy,
- int width, int height)
+ int dx, int dy,
+ int sx, int sy,
+ int width, int height,
+ float src_width,
+ float src_height)
{
- float dst_loc[4], src_loc[4];
- float dst_bounds[4], src_bounds[4];
- float src_shift[4], dst_shift[4], shift[4];
- struct pipe_texture *dst = dst_priv->tex;
- struct pipe_texture *src = src_priv->tex;
+ float s0, t0, s1, t1;
+ float x0, y0, x1, y1;
+<<<<<<< HEAD:src/gallium/state_trackers/xorg/xorg_renderer.c
if (r->pipe->is_texture_referenced(r->pipe, src, 0, 0) &
PIPE_REFERENCED_FOR_WRITE)
r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
@@ -842,8 +621,33 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
if (src == dst)
pipe_texture_reference(&temp_src, NULL);
}
+=======
+
+ /* XXX: could put the texcoord scaling calculation into the vertex
+ * shader.
+ */
+ s0 = sx / src_width;
+ s1 = (sx + width) / src_width;
+ t0 = sy / src_height;
+ t1 = (sy + height) / src_height;
+
+ x0 = dx;
+ x1 = dx + width;
+ y0 = dy;
+ y1 = dy + height;
+
+ /* draw quad */
+ renderer_draw_conditional(r, 4*8);
+ add_vertex_1tex(r, x0, y0, s0, t0);
+ add_vertex_1tex(r, x1, y0, s1, t0);
+ add_vertex_1tex(r, x1, y1, s1, t1);
+ add_vertex_1tex(r, x0, y1, s0, t1);
+>>>>>>> origin/mesa_7_7_branch:src/gallium/state_trackers/xorg/xorg_renderer.c
}
+
+
+
void renderer_draw_yuv(struct xorg_renderer *r,
int src_x, int src_y, int src_w, int src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 2f0b865dbd..5272cde2b3 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -21,6 +21,8 @@ struct xorg_renderer {
struct cso_context *cso;
struct xorg_shaders *shaders;
+ int fb_width;
+ int fb_height;
struct pipe_constant_buffer vs_const_buffer;
struct pipe_constant_buffer fs_const_buffer;
@@ -35,19 +37,19 @@ struct xorg_renderer {
struct xorg_renderer *renderer_create(struct pipe_context *pipe);
void renderer_destroy(struct xorg_renderer *renderer);
+void renderer_bind_destination(struct xorg_renderer *r,
+ struct pipe_surface *surface,
+ int width,
+ int height );
+
void renderer_bind_framebuffer(struct xorg_renderer *r,
struct exa_pixmap_priv *priv);
void renderer_bind_viewport(struct xorg_renderer *r,
struct exa_pixmap_priv *dst);
-void renderer_bind_rasterizer(struct xorg_renderer *r);
void renderer_set_constants(struct xorg_renderer *r,
int shader_type,
const float *buffer,
int size);
-void renderer_copy_pixmap(struct xorg_renderer *r,
- struct exa_pixmap_priv *dst_priv, int dx, int dy,
- struct exa_pixmap_priv *src_priv, int sx, int sy,
- int width, int height);
void renderer_draw_yuv(struct xorg_renderer *r,
@@ -74,5 +76,20 @@ void renderer_texture(struct xorg_renderer *r,
void renderer_draw_flush(struct xorg_renderer *r);
+struct pipe_texture *
+renderer_clone_texture(struct xorg_renderer *r,
+ struct pipe_texture *src);
+
+void renderer_copy_prepare(struct xorg_renderer *r,
+ struct pipe_surface *dst_surface,
+ struct pipe_texture *src_texture);
+
+void renderer_copy_pixmap(struct xorg_renderer *r,
+ int dx, int dy,
+ int sx, int sy,
+ int width, int height,
+ float src_width,
+ float src_height);
+
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 20c9259c7b..c6c7b2fe15 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -51,6 +51,8 @@
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
+struct kms_bo;
+struct kms_driver;
struct exa_context;
typedef struct
@@ -61,6 +63,8 @@ typedef struct
ScrnInfoPtr pScrn_2;
} EntRec, *EntPtr;
+#define XORG_NR_FENCES 3
+
typedef struct _modesettingRec
{
/* drm */
@@ -84,8 +88,19 @@ typedef struct _modesettingRec
unsigned int SaveGeneration;
void (*blockHandler)(int, pointer, pointer, pointer);
+ struct pipe_fence_handle *fence[XORG_NR_FENCES];
+
CreateScreenResourcesProcPtr createScreenResources;
+ /* for frontbuffer backing store */
+ Bool (*destroy_front_buffer)(ScrnInfoPtr pScrn);
+ Bool (*create_front_buffer)(ScrnInfoPtr pScrn);
+ Bool (*bind_front_buffer)(ScrnInfoPtr pScrn);
+
+ /* kms */
+ struct kms_driver *kms;
+ struct kms_bo *root_bo;
+
/* gallium */
struct drm_api *api;
struct pipe_screen *screen;
@@ -141,33 +156,34 @@ xorg_exa_close(ScrnInfoPtr pScrn);
* xorg_dri2.c
*/
Bool
-driScreenInit(ScreenPtr pScreen);
+xorg_dri2_init(ScreenPtr pScreen);
void
-driCloseScreen(ScreenPtr pScreen);
+xorg_dri2_close(ScreenPtr pScreen);
/***********************************************************************
* xorg_crtc.c
*/
void
-crtc_init(ScrnInfoPtr pScrn);
+xorg_crtc_init(ScrnInfoPtr pScrn);
void
-crtc_cursor_destroy(xf86CrtcPtr crtc);
+xorg_crtc_cursor_destroy(xf86CrtcPtr crtc);
/***********************************************************************
* xorg_output.c
*/
void
-output_init(ScrnInfoPtr pScrn);
+xorg_output_init(ScrnInfoPtr pScrn);
+
/***********************************************************************
* xorg_xv.c
*/
void
-xorg_init_video(ScreenPtr pScreen);
+xorg_xv_init(ScreenPtr pScreen);
#endif /* _XORG_TRACKER_H_ */
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index bb515a0f49..b8eca8c817 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -319,21 +319,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
static void
-setup_vs_video_constants(struct xorg_renderer *r, struct exa_pixmap_priv *dst)
-{
- int width = dst->tex->width0;
- int height = dst->tex->height0;
- const int param_bytes = 8 * sizeof(float);
- float vs_consts[8] = {
- 2.f/width, 2.f/height, 1, 1,
- -1, -1, 0, 0
- };
-
- renderer_set_constants(r, PIPE_SHADER_VERTEX,
- vs_consts, param_bytes);
-}
-
-static void
setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
{
const int param_bytes = 12 * sizeof(float);
@@ -446,6 +431,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
Bool hdtv;
int x, y, w, h;
struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap);
+ struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
if (dst && !dst->tex) {
xorg_exa_set_shared_usage(pPixmap);
@@ -466,13 +452,12 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
pbox = REGION_RECTS(dstRegion);
nbox = REGION_NUM_RECTS(dstRegion);
- renderer_bind_framebuffer(pPriv->r, dst);
- renderer_bind_viewport(pPriv->r, dst);
+ renderer_bind_destination(pPriv->r, dst_surf,
+ dst_surf->width, dst_surf->height);
+
bind_blend_state(pPriv);
- renderer_bind_rasterizer(pPriv->r);
bind_shaders(pPriv);
bind_samplers(pPriv);
- setup_vs_video_constants(pPriv->r, dst);
setup_fs_video_constants(pPriv->r, hdtv);
exaMoveInPixmap(pPixmap);
@@ -506,6 +491,8 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
}
DamageRegionProcessPending(&pPixmap->drawable);
+ pipe_surface_reference(&dst_surf, NULL);
+
return TRUE;
}
@@ -689,7 +676,7 @@ xorg_setup_textured_adapter(ScreenPtr pScreen)
}
void
-xorg_init_video(ScreenPtr pScreen)
+xorg_xv_init(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
/*modesettingPtr ms = modesettingPTR(pScrn);*/
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.c b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
index c19e556df9..64eb32f8b9 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_surface.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
@@ -37,11 +37,13 @@ vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
{
struct pipe_reference *src_ref;
struct pipe_reference *dst_ref;
- struct vmw_svga_winsys_surface *dst = *pdst;
-
+ struct vmw_svga_winsys_surface *dst;
+
if(pdst == NULL || *pdst == src)
return;
-
+
+ dst = *pdst;
+
src_ref = src ? &src->refcnt : NULL;
dst_ref = dst ? &dst->refcnt : NULL;
diff --git a/src/gallium/winsys/drm/vmware/xorg/Makefile b/src/gallium/winsys/drm/vmware/xorg/Makefile
index e152263256..48a9b08aa7 100644
--- a/src/gallium/winsys/drm/vmware/xorg/Makefile
+++ b/src/gallium/winsys/drm/vmware/xorg/Makefile
@@ -7,7 +7,6 @@ include $(TOP)/configs/current
INCLUDES = \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
- -I../gem \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary \
@@ -20,19 +19,29 @@ LIBS = \
$(TOP)/src/gallium/drivers/svga/libsvga.a \
$(GALLIUM_AUXILIARIES)
+LINKS = \
+ $(shell pkg-config --libs --silence-errors libkms) \
+ $(shell pkg-config --libs libdrm)
+
DRIVER_DEFINES = \
-DHAVE_CONFIG_H
+TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
#############################################
-all default: $(TARGET)
+all default: $(TARGET) $(TARGET_STAGING)
+
+$(TARGET): $(OBJECTS) Makefile $(LIBS)
+ $(MKLIB) -noprefix -o $@ $(OBJECTS) $(LIBS) $(LINKS)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ mkdir -p $@
-$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
- $(TOP)/bin/mklib -noprefix -o $@ \
- $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
+$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+ $(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium
clean:
rm -rf $(OBJECTS) $(TARGET)
diff --git a/src/glu/sgi/libutil/mipmap.c b/src/glu/sgi/libutil/mipmap.c
index c5faebd6a3..d1fd5a7d72 100644
--- a/src/glu/sgi/libutil/mipmap.c
+++ b/src/glu/sgi/libutil/mipmap.c
@@ -3608,6 +3608,7 @@ int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+ free(newImage);
return GLU_OUT_OF_MEMORY;
}
}
@@ -4107,6 +4108,7 @@ static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+ free(srcImage);
return GLU_OUT_OF_MEMORY;
}
/* level userLevel+1 is in srcImage; level userLevel already saved */
@@ -4349,6 +4351,7 @@ static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+ free(srcImage);
return GLU_OUT_OF_MEMORY;
}
}
@@ -8098,6 +8101,7 @@ static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
+ free(srcImage);
return GLU_OUT_OF_MEMORY;
}
/* level userLevel+1 is in srcImage; level userLevel already saved */
@@ -8232,6 +8236,7 @@ static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
+ free(srcImage);
return GLU_OUT_OF_MEMORY;
}
}
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index e48e10d7c0..da81ec9de5 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -167,11 +167,12 @@ static int driBindContext(__DRIcontext *pcp,
__DRIdrawable *pdp,
__DRIdrawable *prp)
{
- __DRIscreenPrivate *psp = pcp->driScreenPriv;
+ __DRIscreenPrivate *psp;
/* Bind the drawable to the context */
if (pcp) {
+ psp = pcp->driScreenPriv;
pcp->driDrawablePriv = pdp;
pcp->driReadablePriv = prp;
if (pdp) {
@@ -498,11 +499,11 @@ static void dri_put_drawable(__DRIdrawable *pdp)
{
__DRIscreenPrivate *psp;
- pdp->refcount--;
- if (pdp->refcount)
- return;
-
if (pdp) {
+ pdp->refcount--;
+ if (pdp->refcount)
+ return;
+
psp = pdp->driScreenPriv;
(*psp->DriverAPI.DestroyBuffer)(pdp);
if (pdp->pClipRects) {
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 082d614442..25418d5f7a 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -39,6 +39,7 @@
#define I915_FALLBACK_LOGICOP 0x20000
#define I915_FALLBACK_POLYGON_SMOOTH 0x40000
#define I915_FALLBACK_POINT_SMOOTH 0x80000
+#define I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN 0x100000
#define I915_UPLOAD_CTX 0x1
#define I915_UPLOAD_BUFFERS 0x2
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index b60efea75b..cc98d125db 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -585,7 +585,7 @@ i915PointSize(GLcontext * ctx, GLfloat size)
{
struct i915_context *i915 = I915_CONTEXT(ctx);
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
- GLint point_size = (int) size;
+ GLint point_size = (int) round(size);
DBG("%s\n", __FUNCTION__);
@@ -599,6 +599,24 @@ i915PointSize(GLcontext * ctx, GLfloat size)
}
+static void
+i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params)
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ /* This could be supported, but it would require modifying the fragment
+ * program to invert the y component of the texture coordinate by
+ * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction.
+ */
+ FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN,
+ (params[0] != GL_UPPER_LEFT));
+ break;
+ }
+}
+
+
/* =============================================================
* Color masks
*/
@@ -939,6 +957,17 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
case GL_POLYGON_SMOOTH:
break;
+ case GL_POINT_SPRITE:
+ /* This state change is handled in i915_reduced_primitive_state because
+ * the hardware bit should only be set when rendering points.
+ */
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+ if (state)
+ i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE;
+ else
+ i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE;
+ break;
+
case GL_POINT_SMOOTH:
break;
@@ -1108,6 +1137,7 @@ i915InitStateFunctions(struct dd_function_table *functions)
functions->LineWidth = i915LineWidth;
functions->LogicOpcode = i915LogicOp;
functions->PointSize = i915PointSize;
+ functions->PointParameterfv = i915PointParameterfv;
functions->PolygonStipple = i915PolygonStipple;
functions->Scissor = i915Scissor;
functions->ShadeModel = i915ShadeModel;
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 669becdab4..3b7015b5ad 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -268,6 +268,8 @@ intel_bufferobj_map(GLcontext * ctx,
if (intel_obj->sys_buffer) {
obj->Pointer = intel_obj->sys_buffer;
+ obj->Length = obj->Size;
+ obj->Offset = 0;
return obj->Pointer;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c
index 89a99974e2..b8c65f4ce6 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.c
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.c
@@ -205,6 +205,7 @@ again_alloc:
counter on unused buffers for later freeing them from
begin of list */
dma_bo = last_elem(&rmesa->dma.free);
+ assert(dma_bo->bo->cref == 1);
remove_from_list(dma_bo);
insert_at_head(&rmesa->dma.reserved, dma_bo);
}
@@ -301,10 +302,6 @@ static int radeon_bo_is_idle(struct radeon_bo* bo)
WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n"
"This may cause small performance drop for you.\n");
}
- /* Protect against bug in legacy bo handling that causes bos stay
- * referenced even after they should be freed */
- if (bo->cref != 1)
- return 0;
return ret != -EBUSY;
}
@@ -341,9 +338,7 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa)
foreach_s(dma_bo, temp, &rmesa->dma.wait) {
if (dma_bo->expire_counter == time) {
WARN_ONCE("Leaking dma buffer object!\n");
- /* force free of buffer so we don't realy start
- * leaking stuff now*/
- while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {}
+ radeon_bo_unref(dma_bo->bo);
remove_from_list(dma_bo);
FREE(dma_bo);
continue;
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index 02de8e5fd1..7ad781ba61 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -62,8 +62,6 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
__DRIdrawablePrivate *const readable = radeon_get_readable(rmesa);
__DRIscreenPrivate *sPriv = rmesa->dri.screen;
- assert(drawable != NULL);
-
drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags);
/* The window might have moved, so we might need to get new clip
@@ -74,12 +72,13 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
* Since the hardware state depends on having the latest drawable
* clip rects, all state checking must be done _after_ this call.
*/
- DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
- if (drawable != readable) {
+ if (drawable)
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
+ if (readable && drawable != readable) {
DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable);
}
- if (rmesa->lastStamp != drawable->lastStamp) {
+ if (drawable && (rmesa->lastStamp != drawable->lastStamp)) {
radeon_window_moved(rmesa);
rmesa->lastStamp = drawable->lastStamp;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index f2f7b2a9fd..bdbb9460bf 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -140,20 +140,19 @@ static GLuint minify(GLuint size, GLuint levels)
static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
{
- GLuint curOffset;
- GLuint i;
- GLuint face;
+ GLuint curOffset, i, face, level;
assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
curOffset = 0;
for(face = 0; face < mt->faces; face++) {
- for(i = 0; i < mt->numLevels; i++) {
- mt->levels[i].width = minify(mt->width0, i);
- mt->levels[i].height = minify(mt->height0, i);
- mt->levels[i].depth = minify(mt->depth0, i);
- compute_tex_image_offset(rmesa, mt, face, i, &curOffset);
+ for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) {
+ mt->levels[level].valid = 1;
+ mt->levels[level].width = minify(mt->width0, i);
+ mt->levels[level].height = minify(mt->height0, i);
+ mt->levels[level].depth = minify(mt->depth0, i);
+ compute_tex_image_offset(rmesa, mt, face, level, &curOffset);
}
}
@@ -163,21 +162,21 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_
static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
{
- GLuint curOffset;
- GLuint i;
+ GLuint curOffset, i, level;
assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
curOffset = 0;
- for(i = 0; i < mt->numLevels; i++) {
+ for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) {
GLuint face;
- mt->levels[i].width = minify(mt->width0, i);
- mt->levels[i].height = minify(mt->height0, i);
- mt->levels[i].depth = minify(mt->depth0, i);
+ mt->levels[level].valid = 1;
+ mt->levels[level].width = minify(mt->width0, i);
+ mt->levels[level].height = minify(mt->height0, i);
+ mt->levels[level].depth = minify(mt->depth0, i);
for(face = 0; face < mt->faces; face++)
- compute_tex_image_offset(rmesa, mt, face, i, &curOffset);
+ compute_tex_image_offset(rmesa, mt, face, level, &curOffset);
}
/* Note the required size in memory */
@@ -293,18 +292,19 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,
* given face and level.
*/
GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
- struct gl_texture_image *texImage, GLuint face, GLuint mtLevel)
+ struct gl_texture_image *texImage, GLuint face, GLuint level)
{
radeon_mipmap_level *lvl;
- if (face >= mt->faces || mtLevel > mt->numLevels)
+ if (face >= mt->faces)
return GL_FALSE;
if (texImage->TexFormat != mt->mesaFormat)
return GL_FALSE;
- lvl = &mt->levels[mtLevel];
- if (lvl->width != texImage->Width ||
+ lvl = &mt->levels[level];
+ if (!lvl->valid ||
+ lvl->width != texImage->Width ||
lvl->height != texImage->Height ||
lvl->depth != texImage->Depth)
return GL_FALSE;
@@ -410,38 +410,17 @@ radeon_miptree_image_offset(radeon_mipmap_tree *mt,
}
/**
- * Convert radeon miptree texture level to GL texture level
- * @param[in] tObj texture object whom level is to be converted
- * @param[in] level radeon miptree texture level
- * @return GL texture level
- */
-unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level)
-{
- return level + tObj->BaseLevel;
-}
-
-/**
- * Convert GL texture level to radeon miptree texture level
- * @param[in] tObj texture object whom level is to be converted
- * @param[in] level GL texture level
- * @return radeon miptree texture level
- */
-unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level)
-{
- return level - tObj->BaseLevel;
-}
-
-/**
* Ensure that the given image is stored in the given miptree from now on.
*/
static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
radeon_texture_image *image,
- int face, int mtLevel)
+ int face, int level)
{
- radeon_mipmap_level *dstlvl = &mt->levels[mtLevel];
+ radeon_mipmap_level *dstlvl = &mt->levels[level];
unsigned char *dest;
assert(image->mt != mt);
+ assert(dstlvl->valid);
assert(dstlvl->width == image->base.Width);
assert(dstlvl->height == image->base.Height);
assert(dstlvl->depth == image->base.Depth);
@@ -458,6 +437,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
+ assert(image->mtlevel == level);
assert(srclvl->size == dstlvl->size);
assert(srclvl->rowstride == dstlvl->rowstride);
@@ -495,7 +475,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
radeon_miptree_reference(mt, &image->mt);
image->mtface = face;
- image->mtlevel = mtLevel;
+ image->mtlevel = level;
}
/**
@@ -522,7 +502,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
if (!img)
break;
- if (!img->mt || !radeon_miptree_matches_texture(img->mt, &texObj->base))
+ if (!img->mt)
continue;
for (int i = 0; i < mtCount; ++i) {
@@ -533,8 +513,8 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
}
}
- if (!found) {
- mtSizes[mtCount] += img->mt->levels[img->mtlevel].size;
+ if (!found && radeon_miptree_matches_texture(img->mt, &texObj->base)) {
+ mtSizes[mtCount] = img->mt->levels[img->mtlevel].size;
mts[mtCount] = img->mt;
mtCount++;
}
@@ -592,6 +572,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
radeon_miptree_unreference(&t->mt);
radeon_try_alloc_miptree(rmesa, t);
dst_miptree = t->mt;
+ if (RADEON_DEBUG & RADEON_TEXTURE) {
+ fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt);
+ }
+ } else if (RADEON_DEBUG & RADEON_TEXTURE) {
+ fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt);
}
const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
@@ -610,7 +595,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
if (RADEON_DEBUG & RADEON_TEXTURE) {
fprintf(stderr, "MIGRATING\n");
}
- migrate_image_to_miptree(dst_miptree, img, face, radeon_gl_level_to_miptree_level(texObj, level));
+ struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo;
+ if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) {
+ radeon_firevertices(rmesa);
+ }
+ migrate_image_to_miptree(dst_miptree, img, face, level);
} else if (RADEON_DEBUG & RADEON_TEXTURE) {
fprintf(stderr, "OK\n");
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
index 28b8485095..a10649b5ae 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
@@ -44,6 +44,7 @@ struct _radeon_mipmap_level {
GLuint depth;
GLuint size; /** Size of each image, in bytes */
GLuint rowstride; /** in bytes */
+ GLuint valid;
radeon_mipmap_image faces[6];
};
@@ -70,9 +71,9 @@ struct _radeon_mipmap_tree {
GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */
GLuint numLevels; /** Number of mip levels stored in this mipmap tree */
- GLuint width0; /** Width of firstLevel image */
- GLuint height0; /** Height of firstLevel image */
- GLuint depth0; /** Depth of firstLevel image */
+ GLuint width0; /** Width of baseLevel image */
+ GLuint height0; /** Height of baseLevel image */
+ GLuint depth0; /** Depth of baseLevel image */
GLuint tilebits; /** RADEON_TXO_xxx_TILE */
@@ -89,8 +90,5 @@ GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
GLuint face, GLuint level);
void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets);
-unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level);
-unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level);
-
uint32_t get_base_teximage_offset(radeonTexObj *texObj);
#endif /* __RADEON_MIPMAP_TREE_H_ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 1ee9e2792a..0390d376ba 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -509,6 +509,27 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx,
return MESA_FORMAT_NONE; /* never get here */
}
+/** Check if given image is valid within current texture object.
+ */
+static int image_matches_texture_obj(struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ unsigned level)
+{
+ const struct gl_texture_image *baseImage = texObj->Image[0][level];
+
+ if (level < texObj->BaseLevel || level > texObj->MaxLevel)
+ return 0;
+
+ const unsigned levelDiff = level - texObj->BaseLevel;
+ const unsigned refWidth = baseImage->Width >> levelDiff;
+ const unsigned refHeight = baseImage->Height >> levelDiff;
+ const unsigned refDepth = baseImage->Depth >> levelDiff;
+
+ return (texImage->Width == refWidth &&
+ texImage->Height == refHeight &&
+ texImage->Depth == refDepth);
+}
+
static void teximage_assign_miptree(radeonContextPtr rmesa,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
@@ -518,18 +539,28 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
radeonTexObj *t = radeon_tex_obj(texObj);
radeon_texture_image* image = get_radeon_texture_image(texImage);
+ /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
+ * don't allocate the miptree if the teximage won't fit.
+ */
+ if (!image_matches_texture_obj(texObj, texImage, level))
+ return;
+
/* Try using current miptree, or create new if there isn't any */
- if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face,
- radeon_gl_level_to_miptree_level(texObj, level))) {
+ if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
radeon_miptree_unreference(&t->mt);
radeon_try_alloc_miptree(rmesa, t);
+ if (RADEON_DEBUG & RADEON_TEXTURE) {
+ fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, "
+ "texObj miptree doesn't match, allocated new miptree %p\n",
+ __FUNCTION__, texObj, texImage, face, level, t->mt);
+ }
}
/* Miptree alocation may have failed,
* when there was no image for baselevel specified */
if (t->mt) {
image->mtface = face;
- image->mtlevel = radeon_gl_level_to_miptree_level(texObj, level);
+ image->mtlevel = level;
radeon_miptree_reference(t->mt, &image->mt);
}
}
@@ -585,6 +616,8 @@ static void radeon_store_teximage(GLcontext* ctx, int dims,
dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
}
+ assert(dstRowStride);
+
if (dims == 3) {
unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth);
@@ -670,6 +703,11 @@ static void radeon_teximage(
}
}
+ if (RADEON_DEBUG & RADEON_TEXTURE) {
+ fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n",
+ dims, texObj, texImage, face, level);
+ }
+
t->validated = GL_FALSE;
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
@@ -694,12 +732,17 @@ static void radeon_teximage(
if (!t->bo) {
teximage_assign_miptree(rmesa, texObj, texImage, face, level);
- if (!t->mt) {
+ if (!image->mt) {
int size = _mesa_format_image_size(texImage->TexFormat,
texImage->Width,
texImage->Height,
texImage->Depth);
texImage->Data = _mesa_alloc_texmemory(size);
+ if (RADEON_DEBUG & RADEON_TEXTURE) {
+ fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, "
+ " no miptree assigned, using local memory %p\n",
+ dims, texObj, texImage, texImage->Data);
+ }
}
}
@@ -801,6 +844,11 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
}
}
+ if (RADEON_DEBUG & RADEON_TEXTURE) {
+ fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n",
+ dims, texObj, texImage, radeon_face_for_target(target), level);
+ }
+
t->validated = GL_FALSE;
if (compressed) {
pixels = _mesa_validate_pbo_compressed_teximage(
diff --git a/src/mesa/drivers/dri/swrast/swrast_span.c b/src/mesa/drivers/dri/swrast/swrast_span.c
index 2d3c25dcbe..f8e503463f 100644
--- a/src/mesa/drivers/dri/swrast/swrast_span.c
+++ b/src/mesa/drivers/dri/swrast/swrast_span.c
@@ -63,56 +63,42 @@ static const GLubyte kernel[16] = {
/* 32-bit BGRA */
#define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
- DST[3] = VALUE[ACOMP]; \
- DST[2] = VALUE[RCOMP]; \
- DST[1] = VALUE[GCOMP]; \
- DST[0] = VALUE[BCOMP]
+ *DST = VALUE[ACOMP] << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
#define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
- DST[3] = 0xff; \
- DST[2] = VALUE[RCOMP]; \
- DST[1] = VALUE[GCOMP]; \
- DST[0] = VALUE[BCOMP]
+ *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
#define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
- DST[ACOMP] = SRC[3]; \
- DST[RCOMP] = SRC[2]; \
- DST[GCOMP] = SRC[1]; \
- DST[BCOMP] = SRC[0]
+ DST[ACOMP] = *SRC >> 24; \
+ DST[RCOMP] = (*SRC >> 16) & 0xff; \
+ DST[GCOMP] = (*SRC >> 8) & 0xff; \
+ DST[BCOMP] = *SRC & 0xff
/* 32-bit BGRX */
#define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \
- DST[3] = 0xff; \
- DST[2] = VALUE[RCOMP]; \
- DST[1] = VALUE[GCOMP]; \
- DST[0] = VALUE[BCOMP]
+ *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
#define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \
- DST[3] = 0xff; \
- DST[2] = VALUE[RCOMP]; \
- DST[1] = VALUE[GCOMP]; \
- DST[0] = VALUE[BCOMP]
+ *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
#define FETCH_PIXEL_X8R8G8B8(DST, SRC) \
- DST[ACOMP] = 0xff; \
- DST[RCOMP] = SRC[2]; \
- DST[GCOMP] = SRC[1]; \
- DST[BCOMP] = SRC[0]
+ DST[ACOMP] = 0xff; \
+ DST[RCOMP] = (*SRC >> 16) & 0xff; \
+ DST[GCOMP] = (*SRC >> 8) & 0xff; \
+ DST[BCOMP] = *SRC & 0xff
/* 16-bit BGR */
#define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
do { \
int d = DITHER_COMP(X, Y) >> 6; \
- GLushort *p = (GLushort *)DST; \
- *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
- ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
- ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
+ *DST = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
+ ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
+ ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
} while(0)
#define FETCH_PIXEL_R5G6B5(DST, SRC) \
do { \
- GLushort p = *(GLushort *)SRC; \
DST[ACOMP] = 0xff; \
- DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
- DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
- DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
+ DST[RCOMP] = ((*SRC >> 8) & 0xf8) * 255 / 0xf8; \
+ DST[GCOMP] = ((*SRC >> 3) & 0xfc) * 255 / 0xfc; \
+ DST[BCOMP] = ((*SRC << 3) & 0xf8) * 255 / 0xf8; \
} while(0)
@@ -145,8 +131,8 @@ static const GLubyte kernel[16] = {
#define SPAN_VARS \
struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
#define INIT_PIXEL_PTR(P, X, Y) \
- GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
-#define INC_PIXEL_PTR(P) P += 4
+ GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X)
+#define INC_PIXEL_PTR(P) P++
#define STORE_PIXEL(DST, X, Y, VALUE) \
STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -163,8 +149,8 @@ static const GLubyte kernel[16] = {
#define SPAN_VARS \
struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
#define INIT_PIXEL_PTR(P, X, Y) \
- GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
-#define INC_PIXEL_PTR(P) P += 4
+ GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X);
+#define INC_PIXEL_PTR(P) P++
#define STORE_PIXEL(DST, X, Y, VALUE) \
STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -181,8 +167,8 @@ static const GLubyte kernel[16] = {
#define SPAN_VARS \
struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
#define INIT_PIXEL_PTR(P, X, Y) \
- GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
-#define INC_PIXEL_PTR(P) P += 2
+ GLushort *P = (GLushort *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 2 + (X);
+#define INC_PIXEL_PTR(P) P++
#define STORE_PIXEL(DST, X, Y, VALUE) \
STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
#define FETCH_PIXEL(DST, SRC) \
@@ -234,8 +220,8 @@ static const GLubyte kernel[16] = {
#define SPAN_VARS \
struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
#define INIT_PIXEL_PTR(P, X, Y) \
- GLubyte *P = (GLubyte *)row;
-#define INC_PIXEL_PTR(P) P += 4
+ GLuint *P = (GLuint *)row;
+#define INC_PIXEL_PTR(P) P++
#define STORE_PIXEL(DST, X, Y, VALUE) \
STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -252,8 +238,8 @@ static const GLubyte kernel[16] = {
#define SPAN_VARS \
struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
#define INIT_PIXEL_PTR(P, X, Y) \
- GLubyte *P = (GLubyte *)row;
-#define INC_PIXEL_PTR(P) P += 4
+ GLuint *P = (GLuint *)row;
+#define INC_PIXEL_PTR(P) P++
#define STORE_PIXEL(DST, X, Y, VALUE) \
STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -270,7 +256,7 @@ static const GLubyte kernel[16] = {
#define SPAN_VARS \
struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
#define INIT_PIXEL_PTR(P, X, Y) \
- GLubyte *P = (GLubyte *)row;
+ GLushort *P = (GLushort *)row;
#define INC_PIXEL_PTR(P) P += 2
#define STORE_PIXEL(DST, X, Y, VALUE) \
STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index 380663ec97..87c3b2e562 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -234,7 +234,12 @@ extern "C" {
#elif defined(__APPLE__)
#include <CoreFoundation/CFByteOrder.h>
#define CPU_TO_LE32( x ) CFSwapInt32HostToLittle( x )
-#else /*__linux__ __APPLE__*/
+#elif defined(_AIX)
+#define CPU_TO_LE32( x ) x = ((x & 0x000000ff) << 24) | \
+ ((x & 0x0000ff00) << 8) | \
+ ((x & 0x00ff0000) >> 8) | \
+ ((x & 0xff000000) >> 24);
+#else /*__linux__ */
#include <sys/endian.h>
#define CPU_TO_LE32( x ) bswap32( x )
#endif /*__linux__*/
diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c
index 4c8fc1f72e..b330544890 100644
--- a/src/mesa/main/points.c
+++ b/src/mesa/main/points.c
@@ -200,7 +200,12 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params)
}
break;
case GL_POINT_SPRITE_COORD_ORIGIN:
- if (ctx->Extensions.ARB_point_sprite || ctx->Extensions.NV_point_sprite) {
+ /* This is not completely correct. GL_POINT_SPRITE_COORD_ORIGIN was
+ * added to point sprites when the extension was merged into OpenGL
+ * 2.0. It is expected that an implementation supporting OpenGL 1.4
+ * and GL_ARB_point_sprite will generate an error here.
+ */
+ if (ctx->Extensions.ARB_point_sprite) {
GLenum value = (GLenum) params[0];
if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
_mesa_error(ctx, GL_INVALID_VALUE,
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 6d86a4275c..4442fb8cf8 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -598,7 +598,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
void GLAPIENTRY
_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
{
- _mesa_TexEnvfv( target, pname, &param );
+ GLfloat p[4];
+ p[0] = param;
+ p[1] = p[2] = p[3] = 0.0;
+ _mesa_TexEnvfv( target, pname, p );
}
diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c
index 733e129fcf..5abb1ff0ab 100644
--- a/src/mesa/main/texgen.c
+++ b/src/mesa/main/texgen.c
@@ -211,14 +211,20 @@ _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
static void GLAPIENTRY
_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
{
- _mesa_TexGenfv(coord, pname, &param);
+ GLfloat p[4];
+ p[0] = param;
+ p[1] = p[2] = p[3] = 0.0F;
+ _mesa_TexGenfv(coord, pname, p);
}
void GLAPIENTRY
_mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
{
- _mesa_TexGeniv( coord, pname, &param );
+ GLint p[4];
+ p[0] = param;
+ p[1] = p[2] = p[3] = 0;
+ _mesa_TexGeniv( coord, pname, p );
}
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index ab170cde35..310d594cd5 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -547,13 +547,20 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
case GL_DEPTH_TEXTURE_MODE_ARB:
{
/* convert float param to int */
- GLint p = (GLint) param;
- need_update = set_tex_parameteri(ctx, texObj, pname, &p);
+ GLint p[4];
+ p[0] = (GLint) param;
+ p[1] = p[2] = p[3] = 0;
+ need_update = set_tex_parameteri(ctx, texObj, pname, p);
}
break;
default:
- /* this will generate an error if pname is illegal */
- need_update = set_tex_parameterf(ctx, texObj, pname, &param);
+ {
+ /* this will generate an error if pname is illegal */
+ GLfloat p[4];
+ p[0] = param;
+ p[1] = p[2] = p[3] = 0.0F;
+ need_update = set_tex_parameterf(ctx, texObj, pname, p);
+ }
}
if (ctx->Driver.TexParameter && need_update) {