Commit 42910ebe authored by Keith Whitwell's avatar Keith Whitwell

Merge commit 'origin/master' into gallium-sampler-view

Conflicts:
	src/gallium/drivers/nv30/nv30_context.h
	src/gallium/drivers/nv30/nv30_state.c
	src/gallium/drivers/nv40/nv40_context.h
	src/gallium/drivers/nv40/nv40_state.c
	src/gallium/drivers/r300/r300_emit.c
parents 47bfbd45 68e58a96
......@@ -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
......@@ -1358,7 +1360,7 @@ AC_ARG_ENABLE([gallium-nouveau],
[enable_gallium_nouveau=no])
if test "x$enable_gallium_nouveau" = xyes; then
GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS nouveau"
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv30 nv40 nv50"
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50"
fi
dnl
......
......@@ -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_texture *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_texture_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_texture *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]->texture->format;
rast->cbuf[i].width = scene->cbuf_transfer[i]->width;
rast->cbuf[i].height = scene->cbuf_transfer[i]->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_texture_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_texture_stride(zsbuf->texture, zsbuf->level);
rast->zsbuf.blocksize =
util_format_get_blocksize(scene->zsbuf_transfer->texture->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_tex_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_texture_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_tex_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_texture_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->tex_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_texture_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->tex_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_texture_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,
......
......@@ -40,6 +40,7 @@
#include "lp_context.h"
#include "lp_screen.h"
#include "lp_flush.h"
#include "lp_texture.h"
#include "lp_tile_size.h"
#include "state_tracker/sw_winsys.h"
......@@ -163,6 +164,92 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
}
/**
* Map a texture. Without any synchronization.
*/
void *
llvmpipe_texture_map(struct pipe_texture *texture,
unsigned face,
unsigned level,
unsigned zslice)
{
struct llvmpipe_texture *lpt = llvmpipe_texture(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_texture_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_texture_unmap(struct pipe_texture *texture,
unsigned face,
unsigned level,
unsigned zslice)
{
struct llvmpipe_texture *lpt = llvmpipe_texture(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_texture *pt,
......@@ -181,7 +268,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
......@@ -207,23 +293,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_texture_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;
}
......@@ -269,24 +338,6 @@ llvmpipe_get_tex_transfer(struct pipe_context *pipe,
pt->level = level;
pt->zslice = zslice;
lpt->offset = lptex->level_offset[level];
/* XXX shouldn't that rather be
tex_height = align(u_minify(texture->height0, level), 2)
to account for alignment done in llvmpipe_texture_layout ?
*/
if (texture->target == PIPE_TEXTURE_CUBE) {
unsigned tex_height = u_minify(texture->height0, level);
lpt->offset += face * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
}
else if (texture->target == PIPE_TEXTURE_3D) {
unsigned tex_height = u_minify(texture->height0, level);
lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
}
else {
assert(face == 0);
assert(zslice == 0);
}
return pt;
}
return NULL;
......@@ -312,7 +363,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_texture *lpt;
enum pipe_format format;
......@@ -320,34 +371,34 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
lpt = llvmpipe_texture(transfer->texture);
format = lpt->base.format;
if (lpt->dt) {
/* display target */
struct sw_winsys *winsys = screen->winsys;
/*
* Transfers, like other pipe operations, must happen in order, so flush the
* context if necessary.
*/
llvmpipe_flush_texture(pipe,
transfer->texture, transfer->face, transfer->level,
0, /* flush_flags */
!(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
TRUE, /* cpu_access */
FALSE); /* do_not_flush */
map = winsys->displaytarget_map(winsys, lpt->dt,
pipe_transfer_buffer_flags(transfer));
if (map == NULL)
return NULL;
}
else {
/* regular texture */
map = lpt->data;
}
map = llvmpipe_texture_map(transfer->texture,
transfer->face, transfer->level, transfer->zslice);
/* May want to different things here depending on read/write nature
* of the map:
*/
if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) {
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->y / util_format_get_blockheight(format) * transfer->stride +
transfer->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;
}
......@@ -355,17 +406,10 @@ static void
llvmpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
struct llvmpipe_texture *lpt;
assert(transfer->texture);
lpt = llvmpipe_texture(transfer->texture);
if (lpt->dt) {
/* display target */
struct sw_winsys *winsys = lp_screen->winsys;
winsys->displaytarget_unmap(winsys, lpt->dt);
}
llvmpipe_texture_unmap(transfer->texture,
transfer->face, transfer->level, transfer->zslice);
}
......
......@@ -95,6 +95,28 @@ llvmpipe_transfer(struct pipe_transfer *pt)
}
static INLINE unsigned
llvmpipe_texture_stride(struct pipe_texture *texture,
unsigned level)
{
struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
assert(level < LP_MAX_TEXTURE_2D_LEVELS);
return lpt->stride[level];
}
void *
llvmpipe_texture_map(struct pipe_texture *texture,
unsigned face,
unsigned level,
unsigned zslice);
void
llvmpipe_texture_unmap(struct pipe_texture *texture,
unsigned face,
unsigned level,
unsigned zslice);
extern void
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
......
......@@ -4,7 +4,6 @@ include $(TOP)/configs/current
LIBNAME = nouveau
C_SOURCES = nouveau_screen.c \
nouveau_context.c \
nv04_surface_2d.c
nouveau_context.c
include ../../Makefile.template
......@@ -33,7 +33,7 @@ nouveau_vbuf_split(unsigned remaining, unsigned overhead, unsigned vpp,
max = max - (max % 3);
break;
case PIPE_PRIM_QUADS:
max = max & 3;
max = max & ~3;
break;
case PIPE_PRIM_LINE_LOOP:
case PIPE_PRIM_LINE_STRIP:
......
......@@ -27,10 +27,7 @@
#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19)
extern struct pipe_screen *
nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_screen *
nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
......
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = nv30
C_SOURCES = \
nv30_clear.c \
nv30_context.c \
nv30_draw.c \
nv30_fragprog.c \
nv30_fragtex.c \
nv30_miptree.c \
nv30_query.c \
nv30_screen.c \
nv30_state.c \
nv30_state_blend.c \
nv30_state_emit.c \
nv30_state_fb.c \
nv30_state_rasterizer.c \
nv30_state_scissor.c \
nv30_state_stipple.c \