summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c65
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.h12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c70
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c185
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h23
-rw-r--r--src/gallium/drivers/r300/r300_context.c4
-rw-r--r--src/gallium/drivers/r300/r300_debug.c1
-rw-r--r--src/gallium/drivers/r300/r300_emit.c2
-rw-r--r--src/gallium/drivers/r300/r300_emit.h3
-rw-r--r--src/gallium/drivers/r300/r300_reg.h4
-rw-r--r--src/gallium/drivers/r300/r300_render.c33
-rw-r--r--src/gallium/drivers/r300/r300_screen.h5
-rw-r--r--src/gallium/drivers/r300/r300_state.c11
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h12
-rw-r--r--src/gallium/state_trackers/glx/xlib/Makefile3
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c14
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_winsys.h3
-rw-r--r--src/gallium/winsys/xlib/Makefile3
22 files changed, 348 insertions, 142 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index cb3a1559ed..672e06c992 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -84,8 +84,12 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->wrap_t = sampler->wrap_t;
state->wrap_r = sampler->wrap_r;
state->min_img_filter = sampler->min_img_filter;
- state->min_mip_filter = sampler->min_mip_filter;
state->mag_img_filter = sampler->mag_img_filter;
+ if (texture->last_level) {
+ state->min_mip_filter = sampler->min_mip_filter;
+ } else {
+ state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ }
state->compare_mode = sampler->compare_mode;
if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 1b4e889935..7d0abb33e9 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -92,3 +92,68 @@ llvmpipe_flush( struct pipe_context *pipe,
#endif
}
+
+/**
+ * Flush context if necessary.
+ *
+ * TODO: move this logic to an auxiliary library?
+ *
+ * FIXME: We must implement DISCARD/DONTBLOCK/UNSYNCHRONIZED/etc for
+ * textures to avoid blocking.
+ */
+boolean
+llvmpipe_flush_texture(struct pipe_context *pipe,
+ struct pipe_resource *texture,
+ unsigned face,
+ unsigned level,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_flush)
+{
+ struct pipe_fence_handle *last_fence = NULL;
+ unsigned referenced;
+
+ referenced = pipe->is_resource_referenced(pipe, texture, face, level);
+
+ if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
+ ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
+
+ if (do_not_flush)
+ return FALSE;
+
+ /*
+ * TODO: The semantics of these flush flags are too obtuse. They should
+ * disappear and the pipe driver should just ensure that all visible
+ * side-effects happen when they need to happen.
+ */
+ if (referenced & PIPE_REFERENCED_FOR_WRITE)
+ flush_flags |= PIPE_FLUSH_RENDER_CACHE;
+
+ if (referenced & PIPE_REFERENCED_FOR_READ)
+ flush_flags |= PIPE_FLUSH_TEXTURE_CACHE;
+
+ if (cpu_access) {
+ /*
+ * Flush and wait.
+ */
+
+ struct pipe_fence_handle *fence = NULL;
+
+ pipe->flush(pipe, flush_flags, &fence);
+
+ if (last_fence) {
+ pipe->screen->fence_finish(pipe->screen, fence, 0);
+ pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+ }
+ } else {
+ /*
+ * Just flush.
+ */
+
+ pipe->flush(pipe, flush_flags, NULL);
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h
index 10b2b52583..2375d22b85 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.h
+++ b/src/gallium/drivers/llvmpipe/lp_flush.h
@@ -28,10 +28,22 @@
#ifndef LP_FLUSH_H
#define LP_FLUSH_H
+#include "pipe/p_compiler.h"
+
struct pipe_context;
struct pipe_fence_handle;
void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence);
+boolean
+llvmpipe_flush_texture(struct pipe_context *pipe,
+ struct pipe_resource *texture,
+ unsigned face,
+ unsigned level,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_flush);
+
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index f521bc148b..497bfb0994 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -62,18 +62,20 @@ lp_rast_begin( struct lp_rasterizer *rast,
rast->state.write_color = write_color;
for (i = 0; i < rast->state.nr_cbufs; i++) {
+ struct pipe_surface *cbuf = scene->fb.cbufs[i];
rast->cbuf[i].map = scene->cbuf_map[i];
- rast->cbuf[i].format = scene->cbuf_transfer[i]->resource->format;
- rast->cbuf[i].width = scene->cbuf_transfer[i]->box.width;
- rast->cbuf[i].height = scene->cbuf_transfer[i]->box.height;
- rast->cbuf[i].stride = scene->cbuf_transfer[i]->stride;
+ rast->cbuf[i].format = cbuf->texture->format;
+ rast->cbuf[i].width = cbuf->width;
+ rast->cbuf[i].height = cbuf->height;
+ rast->cbuf[i].stride = llvmpipe_resource_stride(cbuf->texture, cbuf->level);
}
if (write_zstencil) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
rast->zsbuf.map = scene->zsbuf_map;
- rast->zsbuf.stride = scene->zsbuf_transfer->stride;
+ rast->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level);
rast->zsbuf.blocksize =
- util_format_get_blocksize(scene->zsbuf_transfer->resource->format);
+ util_format_get_blocksize(zsbuf->texture->format);
}
lp_scene_bin_iter_begin( scene );
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index e060cdcd7d..a8aab157ed 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -397,7 +397,6 @@ end:
static boolean
lp_scene_map_buffers( struct lp_scene *scene )
{
- struct pipe_context *pipe = scene->pipe;
struct pipe_surface *cbuf, *zsbuf;
int i;
@@ -409,20 +408,10 @@ lp_scene_map_buffers( struct lp_scene *scene )
for (i = 0; i < scene->fb.nr_cbufs; i++) {
cbuf = scene->fb.cbufs[i];
if (cbuf) {
- scene->cbuf_transfer[i] = pipe_get_transfer(pipe,
- cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice,
- PIPE_TRANSFER_READ_WRITE,
- 0, 0,
- cbuf->width,
- cbuf->height);
- if (!scene->cbuf_transfer[i])
- goto fail;
-
- scene->cbuf_map[i] = pipe->transfer_map(pipe,
- scene->cbuf_transfer[i]);
+ scene->cbuf_map[i] = llvmpipe_resource_map(cbuf->texture,
+ cbuf->face,
+ cbuf->level,
+ cbuf->zslice);
if (!scene->cbuf_map[i])
goto fail;
}
@@ -432,20 +421,10 @@ lp_scene_map_buffers( struct lp_scene *scene )
*/
zsbuf = scene->fb.zsbuf;
if (zsbuf) {
- scene->zsbuf_transfer = pipe_get_transfer(pipe,
- zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice,
- PIPE_TRANSFER_READ_WRITE,
- 0, 0,
- zsbuf->width,
- zsbuf->height);
- if (!scene->zsbuf_transfer)
- goto fail;
-
- scene->zsbuf_map = pipe->transfer_map(pipe,
- scene->zsbuf_transfer);
+ scene->zsbuf_map = llvmpipe_resource_map(zsbuf->texture,
+ zsbuf->face,
+ zsbuf->level,
+ zsbuf->zslice);
if (!scene->zsbuf_map)
goto fail;
}
@@ -469,28 +448,27 @@ fail:
static void
lp_scene_unmap_buffers( struct lp_scene *scene )
{
- struct pipe_context *pipe = scene->pipe;
unsigned i;
for (i = 0; i < scene->fb.nr_cbufs; i++) {
- if (scene->cbuf_map[i])
- pipe->transfer_unmap(pipe, scene->cbuf_transfer[i]);
-
- if (scene->cbuf_transfer[i])
- pipe->transfer_destroy(pipe, scene->cbuf_transfer[i]);
-
- scene->cbuf_transfer[i] = NULL;
- scene->cbuf_map[i] = NULL;
+ if (scene->cbuf_map[i]) {
+ struct pipe_surface *cbuf = scene->fb.cbufs[i];
+ llvmpipe_resource_unmap(cbuf->texture,
+ cbuf->face,
+ cbuf->level,
+ cbuf->zslice);
+ scene->cbuf_map[i] = NULL;
+ }
}
- if (scene->zsbuf_map)
- pipe->transfer_unmap(pipe, scene->zsbuf_transfer);
-
- if (scene->zsbuf_transfer)
- pipe->transfer_destroy(pipe, scene->zsbuf_transfer);
-
- scene->zsbuf_transfer = NULL;
- scene->zsbuf_map = NULL;
+ if (scene->zsbuf_map) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
+ llvmpipe_resource_unmap(zsbuf->texture,
+ zsbuf->face,
+ zsbuf->level,
+ zsbuf->zslice);
+ scene->zsbuf_map = NULL;
+ }
util_unreference_framebuffer_state( &scene->fb );
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index a6d181f193..a1fb8bf541 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -114,8 +114,6 @@ struct texture_ref {
*/
struct lp_scene {
struct pipe_context *pipe;
- struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS];
- struct pipe_transfer *zsbuf_transfer;
/* Scene's buffers are mapped at the time the scene is enqueued:
*/
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 6110b0a193..ca3d62c361 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -27,6 +27,7 @@
#include "util/u_rect.h"
#include "lp_context.h"
+#include "lp_flush.h"
#include "lp_surface.h"
@@ -36,6 +37,20 @@ lp_surface_copy(struct pipe_context *pipe,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
+ llvmpipe_flush_texture(pipe,
+ dest->texture, dest->face, dest->level,
+ 0, /* flush_flags */
+ FALSE, /* read_only */
+ FALSE, /* cpu_access */
+ FALSE); /* do_not_flush */
+
+ llvmpipe_flush_texture(pipe,
+ src->texture, src->face, src->level,
+ 0, /* flush_flags */
+ TRUE, /* read_only */
+ FALSE, /* cpu_access */
+ FALSE); /* do_not_flush */
+
util_surface_copy(pipe, FALSE,
dest, destx, desty,
src, srcx, srcy,
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 779b486bfd..8cb9385196 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -41,6 +41,7 @@
#include "lp_context.h"
#include "lp_screen.h"
+#include "lp_flush.h"
#include "lp_texture.h"
#include "lp_setup.h"
#include "lp_tile_size.h"
@@ -166,6 +167,92 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
}
+/**
+ * Map a texture. Without any synchronization.
+ */
+void *
+llvmpipe_resource_map(struct pipe_resource *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice)
+{
+ struct llvmpipe_resource *lpt = llvmpipe_resource(texture);
+ uint8_t *map;
+
+ if (lpt->dt) {
+ /* display target */
+ struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen);
+ struct sw_winsys *winsys = screen->winsys;
+ const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+
+ assert(face == 0);
+ assert(level == 0);
+ assert(zslice == 0);
+
+ /* FIXME: keep map count? */
+ map = winsys->displaytarget_map(winsys, lpt->dt, usage);
+ }
+ else {
+ /* regular texture */
+ unsigned offset;
+ unsigned stride;
+
+ map = lpt->data;
+
+ assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+
+ offset = lpt->level_offset[level];
+ stride = lpt->stride[level];
+
+ /* XXX shouldn't that rather be
+ tex_height = align(u_minify(texture->height0, level), 2)
+ to account for alignment done in llvmpipe_resource_layout ?
+ */
+ if (texture->target == PIPE_TEXTURE_CUBE) {
+ unsigned tex_height = u_minify(texture->height0, level);
+ offset += face * util_format_get_nblocksy(texture->format, tex_height) * stride;
+ }
+ else if (texture->target == PIPE_TEXTURE_3D) {
+ unsigned tex_height = u_minify(texture->height0, level);
+ offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * stride;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+
+ map += offset;
+ }
+
+ return map;
+}
+
+
+/**
+ * Unmap a texture. Without any synchronization.
+ */
+void
+llvmpipe_resource_unmap(struct pipe_resource *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice)
+{
+ struct llvmpipe_resource *lpt = llvmpipe_resource(texture);
+
+ if (lpt->dt) {
+ /* display target */
+ struct llvmpipe_screen *lp_screen = llvmpipe_screen(texture->screen);
+ struct sw_winsys *winsys = lp_screen->winsys;
+
+ assert(face == 0);
+ assert(level == 0);
+ assert(zslice == 0);
+
+ winsys->displaytarget_unmap(winsys, lpt->dt);
+ }
+}
+
+
static struct pipe_surface *
llvmpipe_get_tex_surface(struct pipe_screen *screen,
struct pipe_resource *pt,
@@ -184,7 +271,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->format = pt->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
- ps->offset = lpt->level_offset[level];
ps->usage = usage;
/* Because we are llvmpipe, anything that the state tracker
@@ -210,23 +296,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->face = face;
ps->level = level;
ps->zslice = zslice;
-
- /* XXX shouldn't that rather be
- tex_height = align(ps->height, 2);
- to account for alignment done in llvmpipe_resource_layout ?
- */
- if (pt->target == PIPE_TEXTURE_CUBE) {
- unsigned tex_height = ps->height;
- ps->offset += face * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
- }
- else if (pt->target == PIPE_TEXTURE_3D) {
- unsigned tex_height = ps->height;
- ps->offset += zslice * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
}
return ps;
}
@@ -266,31 +335,6 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
pt->stride = lptex->stride[sr.level];
pt->usage = usage;
- /* XXX: this is bogus - the caller should be doing this, not
- * imposing it on all transfers.
- */
- pt->box.width = align(pt->box.width, TILE_SIZE);
- pt->box.height = align(pt->box.height, TILE_SIZE);
-
- pt->stride = lptex->stride[sr.level];
- lpt->offset = lptex->level_offset[sr.level];
-
- /* XXX shouldn't that rather be
- tex_height = align(u_minify(resource->height0, level), 2)
- to account for alignment done in llvmpipe_resource_layout ?
- */
- if (resource->target == PIPE_TEXTURE_CUBE) {
- unsigned tex_height = u_minify(resource->height0, sr.level);
- lpt->offset += sr.face * util_format_get_nblocksy(resource->format, tex_height) * pt->stride;
- }
- else if (resource->target == PIPE_TEXTURE_3D) {
- unsigned tex_height = u_minify(resource->height0, sr.level);
- lpt->offset += box->z * util_format_get_nblocksy(resource->format, tex_height) * pt->stride;
- }
- else {
- assert(sr.face == 0);
- assert(box->z == 0);
- }
return pt;
}
return NULL;
@@ -316,7 +360,7 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
- ubyte *map, *xfer_map;
+ ubyte *map;
struct llvmpipe_resource *lpt;
enum pipe_format format;
@@ -324,34 +368,38 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
lpt = llvmpipe_resource(transfer->resource);
format = lpt->base.format;
- if (lpt->dt) {
- /* display target */
- struct sw_winsys *winsys = screen->winsys;
-
- map = winsys->displaytarget_map(winsys, lpt->dt,
- transfer->usage);
- if (map == NULL)
- return NULL;
- }
- else {
- /* regular resource */
- map = lpt->data;
- }
+ /*
+ * Transfers, like other pipe operations, must happen in order, so flush the
+ * context if necessary.
+ */
+ llvmpipe_flush_texture(pipe,
+ transfer->resource,
+ transfer->sr.face,
+ transfer->sr.level,
+ 0, /* flush_flags */
+ !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
+ TRUE, /* cpu_access */
+ FALSE); /* do_not_flush */
+
+ map = llvmpipe_resource_map(transfer->resource,
+ transfer->sr.face,
+ transfer->sr.level,
+ transfer->box.z);
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (transfer->resource && (transfer->usage & PIPE_TRANSFER_WRITE)) {
- /* Do something to notify sharing contexts of a resource change.
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ /* Do something to notify sharing contexts of a texture change.
*/
screen->timestamp++;
}
- xfer_map = map + llvmpipe_transfer(transfer)->offset +
+ map +=
transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
- /*printf("map = %p xfer map = %p\n", map, xfer_map);*/
- return xfer_map;
+
+ return map;
}
@@ -359,17 +407,12 @@ static void
llvmpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
- struct llvmpipe_resource *lpt;
-
assert(transfer->resource);
- lpt = llvmpipe_resource(transfer->resource);
- if (lpt->dt) {
- /* display target */
- struct sw_winsys *winsys = lp_screen->winsys;
- winsys->displaytarget_unmap(winsys, lpt->dt);
- }
+ llvmpipe_resource_unmap(transfer->resource,
+ transfer->sr.face,
+ transfer->sr.level,
+ transfer->box.z);
}
static unsigned int
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 9306a25286..ca67b5bdb0 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -99,4 +99,27 @@ llvmpipe_transfer(struct pipe_transfer *pt)
void llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen);
void llvmpipe_init_context_resource_funcs(struct pipe_context *pipe);
+static INLINE unsigned
+llvmpipe_resource_stride(struct pipe_resource *texture,
+ unsigned level)
+{
+ struct llvmpipe_resource *lpt = llvmpipe_resource(texture);
+ assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+ return lpt->stride[level];
+}
+
+
+void *
+llvmpipe_resource_map(struct pipe_resource *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice);
+
+void
+llvmpipe_resource_unmap(struct pipe_resource *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice);
+
+
#endif /* LP_TEXTURE_H */
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 8606c0004e..ed24fb54ab 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -162,8 +162,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300)
return NULL;
- r300screen->ctx = (struct pipe_context*)r300;
-
r300->winsys = radeon_winsys;
r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
@@ -212,8 +210,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300_init_transfer_functions(r300);
- /* r300_init_surface_functions(r300); */
-
r300_init_state_functions(r300);
r300->invariant_state.dirty = TRUE;
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index b881730848..d6177577c8 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -37,6 +37,7 @@ static struct debug_option debug_options[] = {
{ "draw", DBG_DRAW, "Draw and emit" },
{ "tex", DBG_TEX, "Textures" },
{ "fall", DBG_FALL, "Fallbacks" },
+ { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking purposes only!)" },
{ "all", ~0, "Convenience option that enables all debug flags" },
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index fc8a8a2773..2f689e75bc 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -448,7 +448,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
END_CS;
}
-static void r300_emit_query_start(struct r300_context *r300)
+void r300_emit_query_start(struct r300_context *r300)
{
struct r300_capabilities *caps = r300_screen(r300->context.screen)->caps;
struct r300_query *query = r300->query_current;
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 449e640a88..7db2fc6a1a 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -57,8 +57,7 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state);
-void r300_emit_query_begin(struct r300_context* r300,
- struct r300_query* query);
+void r300_emit_query_start(struct r300_context* r300);
void r300_emit_query_end(struct r300_context* r300);
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index c67cc86871..1c2b252887 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -1500,6 +1500,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_ANISO_THRESHOLD_MASK (7<<17)
# define R500_MACRO_SWITCH (1<<22)
+# define R500_TX_MAX_ANISO(x) ((x) << 23)
+# define R500_TX_MAX_ANISO_MASK (63 << 23)
+# define R500_TX_ANISO_HIGH_QUALITY (1 << 30)
+
# define R500_BORDER_FIX (1<<31)
#define R300_TX_FORMAT0_0 0x4480
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index ccf39876a5..971e7f3521 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -131,9 +131,38 @@ static boolean r300_reserve_cs_space(struct r300_context *r300,
}
static boolean immd_is_good_idea(struct r300_context *r300,
- unsigned count)
+ unsigned count)
{
- return count <= 4;
+ struct pipe_vertex_element* velem;
+ struct pipe_vertex_buffer* vbuf;
+ boolean checked[PIPE_MAX_ATTRIBS] = {0};
+ unsigned vertex_element_count = r300->velems->count;
+ unsigned i, vbi;
+
+ if (count > 4) {
+ return FALSE;
+ }
+
+ /* We shouldn't map buffers referenced by CS, busy buffers,
+ * and ones placed in VRAM. */
+ /* XXX Check for VRAM buffers. */
+ for (i = 0; i < vertex_element_count; i++) {
+ velem = &r300->velems->velem[i];
+ vbi = velem->vertex_buffer_index;
+
+ if (!checked[vbi]) {
+ vbuf = &r300->vertex_buffer[vbi];
+
+ if (r300->winsys->is_buffer_referenced(r300->winsys,
+ vbuf->buffer)) {
+ /* It's a very bad idea to map it... */
+ return FALSE;
+ }
+ checked[vbi] = TRUE;
+ }
+ }
+
+ return TRUE;
}
static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 484bde6a6b..abc1303e12 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -38,10 +38,6 @@ struct r300_screen {
struct radeon_winsys* radeon_winsys;
- /* XXX This hack will be removed once texture transfers become part of
- * pipe_context. */
- struct pipe_context* ctx;
-
/* Chipset capabilities */
struct r300_capabilities* caps;
@@ -77,6 +73,7 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
#define DBG_DRAW 0x0000010
#define DBG_TEX 0x0000020
#define DBG_FALL 0x0000040
+#define DBG_ANISOHQ 0x0000080
/*@}*/
static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index d4b7376f12..a732bc8d80 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -849,6 +849,7 @@ static void*
{
struct r300_context* r300 = r300_context(pipe);
struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
+ boolean is_r500 = r300_screen(pipe->screen)->caps->is_r500;
int lod_bias;
union util_color uc;
@@ -864,6 +865,8 @@ static void*
state->min_mip_filter,
state->max_anisotropy > 0);
+ sampler->filter0 |= r300_anisotropy(state->max_anisotropy);
+
/* Unfortunately, r300-r500 don't support floating-point mipmap lods. */
/* We must pass these to the merge function to clamp them properly. */
sampler->min_lod = MAX2((unsigned)state->min_lod, 0);
@@ -873,7 +876,13 @@ static void*
sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
- sampler->filter1 |= r300_anisotropy(state->max_anisotropy);
+ /* This is very high quality anisotropic filtering for R5xx.
+ * It's good for benchmarking the performance of texturing but
+ * in practice we don't want to slow down the driver because it's
+ * a pretty good performance killer. Feel free to play with it. */
+ if (DBG_ON(r300, DBG_ANISOHQ) && is_r500) {
+ sampler->filter1 |= r500_anisotropy(state->max_anisotropy);
+ }
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
sampler->border_color = uc.ui;
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index a32924ed0a..8485d4f8f9 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -327,6 +327,18 @@ static INLINE uint32_t r300_anisotropy(unsigned max_aniso)
}
}
+static INLINE uint32_t r500_anisotropy(unsigned max_aniso)
+{
+ if (!max_aniso) {
+ return 0;
+ }
+ max_aniso -= 1;
+
+ // Map the range [0, 15] to [0, 63].
+ return R500_TX_MAX_ANISO(MIN2((unsigned)(max_aniso*4.2001), 63)) |
+ R500_TX_ANISO_HIGH_QUALITY;;
+}
+
/* Non-CSO state. (For now.) */
static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile
index 7b2adc62c3..8c7cc524df 100644
--- a/src/gallium/state_trackers/glx/xlib/Makefile
+++ b/src/gallium/state_trackers/glx/xlib/Makefile
@@ -5,7 +5,8 @@ LIBNAME = xlib
LIBRARY_INCLUDES = \
-I$(TOP)/include \
- -I$(TOP)/src/mesa
+ -I$(TOP)/src/mesa \
+ $(X_CFLAGS)
C_SOURCES = \
glx_api.c \
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index daa032af6f..25b58b2926 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -213,6 +213,18 @@ static void radeon_buffer_unmap(struct pipe_winsys *ws,
}
}
+static boolean radeon_is_buffer_referenced(struct radeon_winsys *ws,
+ struct pipe_buffer *buffer)
+{
+ struct radeon_pipe_buffer *radeon_buffer =
+ (struct radeon_pipe_buffer*)buffer;
+ uint32_t domain;
+
+ /* Referenced by CS or HW. */
+ return radeon_bo_is_referenced_by_cs(radeon_buffer->bo, ws->priv->cs) ||
+ radeon_bo_is_busy(radeon_buffer->bo, &domain);
+}
+
static void radeon_buffer_set_tiling(struct radeon_winsys *ws,
struct pipe_buffer *buffer,
uint32_t pitch,
@@ -370,5 +382,7 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
radeon_ws->buffer_from_handle = radeon_buffer_from_handle;
radeon_ws->buffer_get_handle = radeon_buffer_get_handle;
+ radeon_ws->is_buffer_referenced = radeon_is_buffer_referenced;
+
return radeon_ws;
}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
index 37eeb45979..887a381cc4 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
@@ -118,6 +118,9 @@ struct radeon_winsys {
uint32_t pitch,
boolean microtiled,
boolean macrotiled);
+
+ boolean (*is_buffer_referenced)(struct radeon_winsys *winsys,
+ struct pipe_buffer *buffer);
};
#endif
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index 68542b488d..18357a4112 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/xlib/Makefile
@@ -6,7 +6,8 @@ LIBNAME = ws_xlib
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/auxiliary
+ -I$(TOP)/src/gallium/auxiliary \
+ $(X_CFLAGS)
C_SOURCES = \
xlib_sw_winsys.c