Commit 9bfa07af authored by Keith Whitwell's avatar Keith Whitwell

Merge commit 'origin/master' into gallium-resources

Conflicts:
	src/gallium/drivers/llvmpipe/lp_rast.c
	src/gallium/drivers/llvmpipe/lp_scene.c
	src/gallium/drivers/llvmpipe/lp_texture.c
	src/gallium/drivers/llvmpipe/lp_texture.h
	src/gallium/drivers/softpipe/sp_texture.c
	src/gallium/drivers/svga/svga_screen_texture.c
parents 65757a14 08cddfe2
......@@ -24,6 +24,8 @@ RADEON_CFLAGS = @RADEON_CFLAGS@
RADEON_LDFLAGS = @RADEON_LDFLAGS@
INTEL_LIBS = @INTEL_LIBS@
INTEL_CFLAGS = @INTEL_CFLAGS@
X_LIBS = @X_LIBS@
X_CFLAGS = @X_CFLAGS@
# Assembler
MESA_ASM_SOURCES = @MESA_ASM_SOURCES@
......
......@@ -547,7 +547,9 @@ else
x11_pkgconfig=no
fi
dnl Use the autoconf macro if no pkg-config files
if test "$x11_pkgconfig" = no; then
if test "$x11_pkgconfig" = yes; then
PKG_CHECK_MODULES([X], [x11])
else
AC_PATH_XTRA
fi
......
......@@ -57,13 +57,13 @@ peglgears: peglgears.o $(HEADERS) $(LIB_DEP)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) -lm
xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm -L$(libdir) -lX11
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X_LIBS)
xeglthreads: xeglthreads.o $(HEADERS) $(LIB_DEP)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm -L$(libdir) -lX11
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X_LIBS)
xegl_tri: xegl_tri.o $(HEADERS) $(LIB_DEP)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm -L$(libdir) -lX11
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X_LIBS)
clean:
-rm -f *.o *~
......
......@@ -9,9 +9,9 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
# Add X11 and pthread libs to satisfy GNU gold.
APP_LIB_DEPS += -lX11 -lpthread
APP_LIB_DEPS += $(X_LIBS) -lpthread
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -L$(libdir) $(APP_LIB_DEPS)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = \
corender \
......
......@@ -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) {
......
......@@ -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;
}
......@@ -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
......@@ -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 );
......
......@@ -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 );
}
......
......@@ -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:
*/
......
......@@ -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,
......
......@@ -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
......
......@@ -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 */
......@@ -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;
......
......@@ -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" },
......
......@@ -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;
......
......@@ -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);
......
......@@ -1500,6 +1500,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_ANISO_THRESHOLD_MASK (7<<17)
# define R500_MACRO_SWITCH (1<<22)