X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnv40%2Fnv40_screen.c;h=ab128fecda7bedda6ff919508b6c8055febf2a97;hb=01cbd764962ff49bf104e5997914ced53360ef81;hp=ed0215b4862d53889a6a17439c054931a2cef78b;hpb=19171ab1d30f14ac0d39894125a3d53a91ca5b89;p=mesa.git diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index ed0215b4862..ab128fecda7 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -1,5 +1,4 @@ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv40_context.h" #include "nv40_screen.h" @@ -57,6 +56,11 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + return 0; /* We have 4 - but unsupported currently */ case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: @@ -91,10 +95,11 @@ nv40_screen_get_paramf(struct pipe_screen *pscreen, int param) static boolean nv40_screen_surface_format_supported(struct pipe_screen *pscreen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -104,13 +109,13 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R16_SNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: @@ -125,10 +130,7 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - default: - assert(0); - }; + } return FALSE; } @@ -137,22 +139,75 @@ static void * nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, unsigned flags ) { - struct pipe_winsys *ws = screen->winsys; - void *map; + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface *surface_to_map; + void *map; + + if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; + + if (!mt->shadow_tex) { + unsigned old_tex_usage = surface->texture->tex_usage; + surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR | + PIPE_TEXTURE_USAGE_DYNAMIC; + mt->shadow_tex = screen->texture_create(screen, surface->texture); + surface->texture->tex_usage = old_tex_usage; + + assert(mt->shadow_tex->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR); + } + + mt->shadow_surface = screen->get_tex_surface + ( + screen, mt->shadow_tex, + surface->face, surface->level, surface->zslice, + surface->usage + ); - map = ws->buffer_map(ws, surface->buffer, flags); + surface_to_map = mt->shadow_surface; + } + else + surface_to_map = surface; + + assert(surface_to_map); + + map = ws->buffer_map(ws, surface_to_map->buffer, flags); if (!map) return NULL; - return map + surface->offset; + return map + surface_to_map->offset; } static void nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) { - struct pipe_winsys *ws = screen->winsys; + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface *surface_to_unmap; - ws->buffer_unmap(ws, surface->buffer); + /* TODO: Copy from shadow just before push buffer is flushed instead. + There are probably some programs that map/unmap excessively + before rendering. */ + if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; + + assert(mt->shadow_tex); + + surface_to_unmap = mt->shadow_surface; + } + else + surface_to_unmap = surface; + + assert(surface_to_unmap); + + ws->buffer_unmap(ws, surface_to_unmap->buffer); + + if (surface_to_unmap != surface) { + struct nv40_screen *nvscreen = nv40_screen(screen); + + nvscreen->nvws->surface_copy(nvscreen->nvws, + surface, 0, 0, + surface_to_unmap, 0, 0, + surface->width, surface->height); + } } static void