diff options
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 14 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_miptree.c | 160 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 38 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_query.c | 84 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state.c | 26 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_surface.c | 33 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tex.c | 43 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_texture.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 4 |
10 files changed, 349 insertions, 70 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 0958bba334..061a4c064b 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -67,11 +67,18 @@ struct nv50_rasterizer_stateobj { struct nouveau_stateobj *so; }; +struct nv50_miptree_level { + struct pipe_buffer **image; + int *image_offset; + unsigned image_dirty_cpu[512/32]; + unsigned image_dirty_gpu[512/32]; +}; + struct nv50_miptree { struct pipe_texture base; struct pipe_buffer *buffer; - int *image_offset; + struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS]; int image_nr; int total_size; }; @@ -84,7 +91,6 @@ nv50_miptree(struct pipe_texture *pt) struct nv50_surface { struct pipe_surface base; - struct pipe_buffer *untiled; }; static INLINE struct nv50_surface * @@ -186,4 +192,8 @@ extern boolean nv50_state_validate(struct nv50_context *nv50); /* nv50_tex.c */ extern void nv50_tex_validate(struct nv50_context *); +/* nv50_miptree.c */ +extern void nv50_miptree_sync(struct pipe_screen *, struct nv50_miptree *, + unsigned level, unsigned image); + #endif diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 2497371232..63a23d06b8 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -27,14 +27,16 @@ #include "nv50_context.h" static struct pipe_texture * -nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) +nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) { struct pipe_winsys *ws = pscreen->winsys; struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); - unsigned usage, width = pt->width[0], height = pt->height[0]; - int i; + struct pipe_texture *pt = &mt->base; + unsigned usage, width = tmp->width[0], height = tmp->height[0]; + unsigned depth = tmp->depth[0]; + int i, l; - mt->base = *pt; + mt->base = *tmp; mt->base.refcount = 1; mt->base.screen = pscreen; @@ -59,17 +61,38 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->image_nr = 1; break; } - mt->image_offset = CALLOC(mt->image_nr, sizeof(int)); + + for (l = 0; l <= pt->last_level; l++) { + struct nv50_miptree_level *lvl = &mt->level[l]; + + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); + + lvl->image_offset = CALLOC(mt->image_nr, sizeof(int)); + lvl->image = CALLOC(mt->image_nr, sizeof(struct pipe_buffer *)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + depth = MAX2(1, depth >> 1); + } for (i = 0; i < mt->image_nr; i++) { - int image_size; + for (l = 0; l <= pt->last_level; l++) { + struct nv50_miptree_level *lvl = &mt->level[l]; + int size; + + size = align(pt->width[l], 8) * pt->block.size; + size = align(size, 64); + size *= align(pt->height[l], 8) * pt->block.size; - image_size = align(width, 8) * pt->block.size; - image_size = align(image_size, 64); - image_size *= align(height, 8) * pt->block.size; + lvl->image[i] = ws->buffer_create(ws, 256, 0, size); + lvl->image_offset[i] = mt->total_size; - mt->image_offset[i] = mt->total_size; - mt->total_size += image_size; + mt->total_size += size; + } } mt->buffer = ws->buffer_create(ws, 256, usage, mt->total_size); @@ -81,6 +104,24 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) return &mt->base; } +static INLINE void +mark_dirty(uint32_t *flags, unsigned image) +{ + flags[image / 32] |= (1 << (image % 32)); +} + +static INLINE void +mark_clean(uint32_t *flags, unsigned image) +{ + flags[image / 32] &= ~(1 << (image % 32)); +} + +static INLINE int +is_dirty(uint32_t *flags, unsigned image) +{ + return !!(flags[image / 32] & (1 << (image % 32))); +} + static void nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) { @@ -96,12 +137,86 @@ nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) } } +void +nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt, + unsigned level, unsigned image) +{ + struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; + struct nv50_miptree_level *lvl = &mt->level[level]; + struct pipe_surface *dst, *src; + unsigned face = 0, zslice = 0; + + if (!is_dirty(lvl->image_dirty_cpu, image)) + return; + + if (mt->base.target == PIPE_TEXTURE_CUBE) + face = image; + else + if (mt->base.target == PIPE_TEXTURE_3D) + zslice = image; + + /* Mark as clean already - so we don't continually call this function + * trying to get a GPU_WRITE pipe_surface! + */ + mark_clean(lvl->image_dirty_cpu, image); + + /* Pretend we're doing CPU access so we get the backing pipe_surface + * and not a view into the larger miptree. + */ + src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + + /* Pretend we're only reading with the GPU so surface doesn't get marked + * as dirtied by the GPU. + */ + dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, + PIPE_BUFFER_USAGE_GPU_READ); + + nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height); + + pscreen->tex_surface_release(pscreen, &dst); + pscreen->tex_surface_release(pscreen, &src); +} + +/* The reverse of the above */ +void +nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt, + unsigned level, unsigned image) +{ + struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; + struct nv50_miptree_level *lvl = &mt->level[level]; + struct pipe_surface *dst, *src; + unsigned face = 0, zslice = 0; + + if (!is_dirty(lvl->image_dirty_gpu, image)) + return; + + if (mt->base.target == PIPE_TEXTURE_CUBE) + face = image; + else + if (mt->base.target == PIPE_TEXTURE_3D) + zslice = image; + + mark_clean(lvl->image_dirty_gpu, image); + + src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, + PIPE_BUFFER_USAGE_GPU_READ); + dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + + nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height); + + pscreen->tex_surface_release(pscreen, &dst); + pscreen->tex_surface_release(pscreen, &src); +} + static struct pipe_surface * nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { struct nv50_miptree *mt = nv50_miptree(pt); + struct nv50_miptree_level *lvl = &mt->level[level]; struct nv50_surface *s; struct pipe_surface *ps; int img; @@ -128,12 +243,29 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; ps->stride = ps->width * ps->block.size; - ps->offset = mt->image_offset[img]; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; - pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer); + if (flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { + assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE)); + nv50_miptree_sync_cpu(pscreen, mt, level, img); + + ps->offset = 0; + pipe_texture_reference(&ps->texture, pt); + pipe_buffer_reference(pscreen, &ps->buffer, lvl->image[img]); + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + mark_dirty(lvl->image_dirty_cpu, img); + } else { + nv50_miptree_sync(pscreen, mt, level, img); + + ps->offset = lvl->image_offset[img]; + pipe_texture_reference(&ps->texture, pt); + pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer); + + if (flags & PIPE_BUFFER_USAGE_GPU_WRITE) + mark_dirty(lvl->image_dirty_gpu, img); + } return ps; } diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index d66e1d0949..7686f746eb 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -32,7 +32,7 @@ #include "nv50_context.h" #define NV50_SU_MAX_TEMP 64 -#define NV50_PROGRAM_DUMP +//#define NV50_PROGRAM_DUMP /* ARL - gallium craps itself on progs/vp/arl.txt * @@ -841,6 +841,28 @@ emit_neg(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, e); } +static void +emit_kil(struct nv50_pc *pc, struct nv50_reg *src) +{ + struct nv50_program_exec *e; + const int r_pred = 1; + + /* Sets predicate reg ? */ + e = exec(pc); + e->inst[0] = 0xa00001fd; + e->inst[1] = 0xc4014788; + set_src_0(pc, src, e); + set_pred_wr(pc, 1, r_pred, e); + emit(pc, e); + + /* This is probably KILP */ + e = exec(pc); + e->inst[0] = 0x000001fe; + set_long(pc, e); + set_pred(pc, 1 /* LT? */, r_pred, e); + emit(pc, e); +} + static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -1069,6 +1091,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } free_temp(pc, temp); break; + case TGSI_OPCODE_KIL: + emit_kil(pc, src[0][0]); + emit_kil(pc, src[0][1]); + emit_kil(pc, src[0][2]); + emit_kil(pc, src[0][3]); + break; case TGSI_OPCODE_LIT: emit_lit(pc, &dst[0], mask, &src[0][0]); break; @@ -1602,13 +1630,19 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (!upload) return; +#ifdef NV50_PROGRAM_DUMP NOUVEAU_ERR("-------\n"); up = ptr = MALLOC(p->exec_size * 4); for (e = p->exec_head; e; e = e->next) { NOUVEAU_ERR("0x%08x\n", e->inst[0]); if (is_long(e)) NOUVEAU_ERR("0x%08x\n", e->inst[1]); + } +#endif + + up = ptr = MALLOC(p->exec_size * 4); + for (e = p->exec_head; e; e = e->next) { *(ptr++) = e->inst[0]; if (is_long(e)) *(ptr++) = e->inst[1]; @@ -1705,7 +1739,7 @@ nv50_fragprog_validate(struct nv50_context *nv50) so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_method(so, tesla, 0x1904, 4); - so_data (so, 0x01040404); /* p: 0x01000404 */ + so_data (so, 0x00040404); /* p: 0x01000404 */ so_data (so, 0x00000004); so_data (so, 0x00000000); so_data (so, 0x00000000); diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 777e77906d..b923c820eb 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -21,41 +21,101 @@ */ #include "pipe/p_context.h" +#include "pipe/p_inlines.h" #include "nv50_context.h" +struct nv50_query { + struct pipe_buffer *buffer; + unsigned type; + boolean ready; + uint64_t result; +}; + +static INLINE struct nv50_query * +nv50_query(struct pipe_query *pipe) +{ + return (struct nv50_query *)pipe; +} + static struct pipe_query * nv50_query_create(struct pipe_context *pipe, unsigned type) { - NOUVEAU_ERR("unimplemented\n"); - return NULL; + struct pipe_winsys *ws = pipe->winsys; + struct nv50_query *q = CALLOC_STRUCT(nv50_query); + + assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER); + q->type = type; + + q->buffer = ws->buffer_create(ws, 256, 0, 16); + if (!q->buffer) { + FREE(q); + return NULL; + } + + return (struct pipe_query *)q; } static void -nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *q) +nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) { - NOUVEAU_ERR("unimplemented\n"); + struct nv50_query *q = nv50_query(pq); + + if (q) { + pipe_buffer_reference(pipe, &q->buffer, NULL); + FREE(q); + } } static void -nv50_query_begin(struct pipe_context *pipe, struct pipe_query *q) +nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq) { - NOUVEAU_ERR("unimplemented\n"); + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_query *q = nv50_query(pq); + + BEGIN_RING(tesla, 0x1530, 1); + OUT_RING (1); + BEGIN_RING(tesla, 0x1514, 1); + OUT_RING (1); + + q->ready = FALSE; } static void -nv50_query_end(struct pipe_context *pipe, struct pipe_query *q) +nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) { - NOUVEAU_ERR("unimplemented\n"); + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_query *q = nv50_query(pq); + + BEGIN_RING(tesla, 0x1b00, 4); + OUT_RELOCh(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (0x00000000); + OUT_RING (0x0100f002); + FIRE_RING (NULL); } static boolean -nv50_query_result(struct pipe_context *pipe, struct pipe_query *q, +nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, boolean wait, uint64_t *result) { - NOUVEAU_ERR("unimplemented\n"); - *result = 0xdeadcafe; - return TRUE; + struct pipe_winsys *ws = pipe->winsys; + struct nv50_query *q = nv50_query(pq); + + /*XXX: Want to be able to return FALSE here instead of blocking + * until the result is available.. + */ + + if (!q->ready) { + uint32_t *map = ws->buffer_map(ws, q->buffer, + PIPE_BUFFER_USAGE_CPU_READ); + q->result = map[1]; + q->ready = TRUE; + ws->buffer_unmap(ws, q->buffer); + } + + *result = q->result; + return q->ready; } void diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 52f6a40688..ef46233f83 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -57,6 +57,10 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_A8L8_UNORM: + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: return TRUE; default: break; @@ -90,23 +94,23 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return 32; case PIPE_CAP_NPOT_TEXTURES: - return 0; + return 1; case PIPE_CAP_TWO_SIDED_STENCIL: return 1; case PIPE_CAP_GLSL: return 0; case PIPE_CAP_S3TC: - return 0; + return 1; case PIPE_CAP_ANISOTROPIC_FILTER: - return 0; + return 1; case PIPE_CAP_POINT_SPRITE: return 0; case PIPE_CAP_MAX_RENDER_TARGETS: return 8; case PIPE_CAP_OCCLUSION_QUERY: - return 0; + return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 0; + return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return 13; case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 95f9d408b5..38c1d938b8 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -175,6 +175,32 @@ nv50_sampler_state_create(struct pipe_context *pipe, break; } + if (cso->max_anisotropy >= 16.0) + tsc[0] |= (7 << 20); + else + if (cso->max_anisotropy >= 12.0) + tsc[0] |= (6 << 20); + else + if (cso->max_anisotropy >= 10.0) + tsc[0] |= (5 << 20); + else + if (cso->max_anisotropy >= 8.0) + tsc[0] |= (4 << 20); + else + if (cso->max_anisotropy >= 6.0) + tsc[0] |= (3 << 20); + else + if (cso->max_anisotropy >= 4.0) + tsc[0] |= (2 << 20); + else + if (cso->max_anisotropy >= 2.0) + tsc[0] |= (1 << 20); + + if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + tsc[0] |= (1 << 8); + tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7); + } + return (void *)tsc; } diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 5bf97d3a6b..3f45a2fe18 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -63,48 +63,17 @@ static void * nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps, unsigned flags ) { - struct nouveau_winsys *nvws = nv50_screen(screen)->nvws; struct pipe_winsys *ws = screen->winsys; - struct nv50_surface *s = nv50_surface(ps); - struct nv50_surface m = *s; - void *map; - if (!s->untiled) { - s->untiled = ws->buffer_create(ws, 0, 0, ps->buffer->size); - - m.base.buffer = s->untiled; - nvws->surface_copy(nvws, &m.base, 0, 0, &s->base, 0, 0, - ps->width, ps->height); - } - - /* Map original tiled surface to disallow it being validated while - * untiled mirror is mapped. - */ - ws->buffer_map(ws, ps->buffer, flags); - - map = ws->buffer_map(ws, s->untiled, flags); - if (!map) - return NULL; - - return map; + return ws->buffer_map(ws, ps->buffer, flags); } static void nv50_surface_unmap(struct pipe_screen *pscreen, struct pipe_surface *ps) { - struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; struct pipe_winsys *ws = pscreen->winsys; - struct nv50_surface *s = nv50_surface(ps); - struct nv50_surface m = *s; - ws->buffer_unmap(ws, s->untiled); ws->buffer_unmap(ws, ps->buffer); - - m.base.buffer = s->untiled; - nvws->surface_copy(nvws, &s->base, 0, 0, &m.base, 0, 0, - ps->width, ps->height); - - pipe_buffer_reference(pscreen, &s->untiled, NULL); } void diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index fde3c97c05..239407c92b 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -85,6 +85,34 @@ nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt) NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_8_8); break; + case PIPE_FORMAT_DXT1_RGB: + so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_DXT1); + break; + case PIPE_FORMAT_DXT1_RGBA: + so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_DXT1); + break; + case PIPE_FORMAT_DXT3_RGBA: + so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_DXT3); + break; + case PIPE_FORMAT_DXT5_RGBA: + so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_DXT5); + break; default: return 1; } @@ -105,14 +133,23 @@ nv50_tex_validate(struct nv50_context *nv50) { struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_stateobj *so; - int i; + int unit, level, image; so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); so_method(so, tesla, 0x0f00, 1); so_data (so, NV50_CB_TIC); so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); - for (i = 0; i < nv50->miptree_nr; i++) { - if (nv50_tex_construct(so, nv50->miptree[i])) { + for (unit = 0; unit < nv50->miptree_nr; unit++) { + struct nv50_miptree *mt = nv50->miptree[unit]; + + for (level = 0; level <= mt->base.last_level; level++) { + for (image = 0; image < mt->image_nr; image++) { + nv50_miptree_sync(&nv50->screen->pipe, mt, + level, image); + } + } + + if (nv50_tex_construct(so, mt)) { NOUVEAU_ERR("failed tex validate\n"); so_ref(NULL, &so); return; diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h index 6861d67b4d..aca622c73b 100644 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -50,6 +50,9 @@ #define NV50TIC_0_0_FMT_5_6_5 0x00000015 #define NV50TIC_0_0_FMT_8_8 0x00000018 #define NV50TIC_0_0_FMT_8 0x0000001d +#define NV50TIC_0_0_FMT_DXT1 0x00000024 +#define NV50TIC_0_0_FMT_DXT3 0x00000025 +#define NV50TIC_0_0_FMT_DXT5 0x00000026 #define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff #define NV50TIC_0_1_OFFSET_LOW_SHIFT 0 diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 584336682e..435dc9777d 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -60,6 +60,10 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, OUT_RING (0); BEGIN_RING(tesla, 0x142c, 1); OUT_RING (0); + BEGIN_RING(tesla, 0x1440, 1); + OUT_RING (0); + BEGIN_RING(tesla, 0x1334, 1); + OUT_RING (0); BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1); OUT_RING (nv50_prim(mode)); |