diff options
author | Christian König <[email protected]> | 2011-03-04 17:15:43 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2011-03-04 17:15:43 +0100 |
commit | 54f11a27a1ec28fcf9734f4454dee870bc0113f8 (patch) | |
tree | 2dc71d95b1ad5d2ca966bbb6726fba45b4cfbac1 /src/gallium | |
parent | 0eccb1038a620bc76ba45ac00c293b3e88427510 (diff) | |
parent | 6838c9ce74f16c765474c0d2b4ae1469dd4a64d5 (diff) |
Merge remote branch 'origin/master' into pipe-video
Diffstat (limited to 'src/gallium')
77 files changed, 9110 insertions, 8220 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 6576c74fbde..9cf74a838fe 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1084,7 +1084,7 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, }*/ int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]; assert(pos >= 0); - assert(pos < Elements(mach->Inputs)); + assert(pos < TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS); chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i]; } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 92ba8b8f033..664946b00f6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -28,7 +28,9 @@ #include "pipe/p_config.h" -#if defined(PIPE_ARCH_X86) +#include "tgsi/tgsi_sse2.h" + +#if defined(PIPE_ARCH_X86) && 0 /* See FIXME notes below */ #include "util/u_debug.h" #include "pipe/p_shader_tokens.h" @@ -42,7 +44,6 @@ #include "tgsi/tgsi_util.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_exec.h" -#include "tgsi/tgsi_sse2.h" #include "rtasm/rtasm_x86sse.h" @@ -118,6 +119,7 @@ get_machine_base( void ) static struct x86_reg get_input_base( void ) { + /* FIXME: tgsi_exec_machine::Inputs is a pointer now! */ return x86_make_disp( get_machine_base(), Offset(struct tgsi_exec_machine, Inputs) ); @@ -126,6 +128,7 @@ get_input_base( void ) static struct x86_reg get_output_base( void ) { + /* FIXME: tgsi_exec_machine::Ouputs is a pointer now! */ return x86_make_disp( get_machine_base(), Offset(struct tgsi_exec_machine, Outputs) ); @@ -2760,6 +2763,7 @@ static void aos_to_soa( struct x86_function *func, x86_mov( func, aos_input, x86_fn_arg( func, arg_aos ) ); x86_mov( func, soa_input, x86_fn_arg( func, arg_machine ) ); + /* FIXME: tgsi_exec_machine::Inputs is a pointer now! */ x86_lea( func, soa_input, x86_make_disp( soa_input, Offset(struct tgsi_exec_machine, Inputs) ) ); @@ -2828,6 +2832,7 @@ static void soa_to_aos( struct x86_function *func, x86_mov( func, aos_output, x86_fn_arg( func, arg_aos ) ); x86_mov( func, soa_output, x86_fn_arg( func, arg_machine ) ); + /* FIXME: tgsi_exec_machine::Ouputs is a pointer now! */ x86_lea( func, soa_output, x86_make_disp( soa_output, Offset(struct tgsi_exec_machine, Outputs) ) ); @@ -3082,4 +3087,16 @@ tgsi_emit_sse2( return ok; } -#endif /* PIPE_ARCH_X86 */ +#else /* !PIPE_ARCH_X86 */ + +unsigned +tgsi_emit_sse2( + const struct tgsi_token *tokens, + struct x86_function *func, + float (*immediates)[4], + boolean do_swizzles ) +{ + return 0; +} + +#endif /* !PIPE_ARCH_X86 */ diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index a33bf5ebc28..3210d1ff77b 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -7,6 +7,9 @@ LIBRARY_INCLUDES = \ $(LIBDRM_CFLAGS) \ -I$(TOP)/src/gallium/drivers/nouveau/include -C_SOURCES = nouveau_screen.c +C_SOURCES = nouveau_screen.c \ + nouveau_fence.c \ + nouveau_mm.c \ + nouveau_buffer.c include ../../Makefile.template diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c new file mode 100644 index 00000000000..d0cc29104b8 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -0,0 +1,488 @@ + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "nouveau_screen.h" +#include "nouveau_context.h" +#include "nouveau_winsys.h" +#include "nouveau_fence.h" +#include "nouveau_buffer.h" +#include "nouveau_mm.h" + +struct nouveau_transfer { + struct pipe_transfer base; +}; + +static INLINE struct nouveau_transfer * +nouveau_transfer(struct pipe_transfer *transfer) +{ + return (struct nouveau_transfer *)transfer; +} + +static INLINE boolean +nouveau_buffer_allocate(struct nouveau_screen *screen, + struct nv04_resource *buf, unsigned domain) +{ + if (domain == NOUVEAU_BO_VRAM) { + buf->mm = nouveau_mm_allocate(screen->mm_VRAM, buf->base.width0, + &buf->bo, &buf->offset); + if (!buf->bo) + return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART); + } else + if (domain == NOUVEAU_BO_GART) { + buf->mm = nouveau_mm_allocate(screen->mm_GART, buf->base.width0, + &buf->bo, &buf->offset); + if (!buf->bo) + return FALSE; + } + if (domain != NOUVEAU_BO_GART) { + if (!buf->data) { + buf->data = MALLOC(buf->base.width0); + if (!buf->data) + return FALSE; + } + } + buf->domain = domain; + return TRUE; +} + +static INLINE void +release_allocation(struct nouveau_mm_allocation **mm, + struct nouveau_fence *fence) +{ + nouveau_fence_work(fence, nouveau_mm_free_work, *mm); + (*mm) = NULL; +} + +INLINE void +nouveau_buffer_release_gpu_storage(struct nv04_resource *buf) +{ + nouveau_bo_ref(NULL, &buf->bo); + + if (buf->mm) + release_allocation(&buf->mm, buf->fence); + + buf->domain = 0; +} + +static INLINE boolean +nouveau_buffer_reallocate(struct nouveau_screen *screen, + struct nv04_resource *buf, unsigned domain) +{ + nouveau_buffer_release_gpu_storage(buf); + + return nouveau_buffer_allocate(screen, buf, domain); +} + +static void +nouveau_buffer_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource) +{ + struct nv04_resource *res = nv04_resource(presource); + + nouveau_buffer_release_gpu_storage(res); + + if (res->data && !(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) + FREE(res->data); + + FREE(res); +} + +/* Maybe just migrate to GART right away if we actually need to do this. */ +boolean +nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf, + unsigned start, unsigned size) +{ + struct nouveau_mm_allocation *mm; + struct nouveau_bo *bounce = NULL; + uint32_t offset; + + assert(buf->domain == NOUVEAU_BO_VRAM); + + mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset); + if (!bounce) + return FALSE; + + nv->copy_data(nv, bounce, offset, NOUVEAU_BO_GART, + buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size); + + if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD)) + return FALSE; + memcpy(buf->data + start, bounce->map, size); + nouveau_bo_unmap(bounce); + + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; + + nouveau_bo_ref(NULL, &bounce); + if (mm) + nouveau_mm_free(mm); + return TRUE; +} + +static boolean +nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf, + unsigned start, unsigned size) +{ + struct nouveau_mm_allocation *mm; + struct nouveau_bo *bounce = NULL; + uint32_t offset; + + if (size <= 192) { + nv->push_data(nv, buf->bo, buf->offset + start, buf->domain, + size, buf->data + start); + return TRUE; + } + + mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset); + if (!bounce) + return FALSE; + + nouveau_bo_map_range(bounce, offset, size, + NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); + memcpy(bounce->map, buf->data + start, size); + nouveau_bo_unmap(bounce); + + nv->copy_data(nv, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, + bounce, offset, NOUVEAU_BO_GART, size); + + nouveau_bo_ref(NULL, &bounce); + if (mm) + release_allocation(&mm, nv->screen->fence.current); + + if (start == 0 && size == buf->base.width0) + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; + return TRUE; +} + +static struct pipe_transfer * +nouveau_buffer_transfer_get(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, unsigned usage, + const struct pipe_box *box) +{ + struct nv04_resource *buf = nv04_resource(resource); + struct nouveau_context *nv = nouveau_context(pipe); + struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_transfer); + if (!xfr) + return NULL; + + xfr->base.resource = resource; + xfr->base.box.x = box->x; + xfr->base.box.width = box->width; + xfr->base.usage = usage; + + if (buf->domain == NOUVEAU_BO_VRAM) { + if (usage & PIPE_TRANSFER_READ) { + if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) + nouveau_buffer_download(nv, buf, 0, buf->base.width0); + } + } + + return &xfr->base; +} + +static void +nouveau_buffer_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_transfer *xfr = nouveau_transfer(transfer); + struct nouveau_context *nv = nouveau_context(pipe); + + if (xfr->base.usage & PIPE_TRANSFER_WRITE) { + /* writing is worse */ + nouveau_buffer_adjust_score(nv, buf, -5000); + + if (buf->domain == NOUVEAU_BO_VRAM) { + nouveau_buffer_upload(nv, buf, transfer->box.x, transfer->box.width); + } + + if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | + PIPE_BIND_INDEX_BUFFER))) + nouveau_context(pipe)->vbo_dirty = TRUE; + } + + FREE(xfr); +} + +static INLINE boolean +nouveau_buffer_sync(struct nv04_resource *buf, unsigned rw) +{ + if (rw == PIPE_TRANSFER_READ) { + if (!buf->fence_wr) + return TRUE; + if (!nouveau_fence_wait(buf->fence_wr)) + return FALSE; + } else { + if (!buf->fence) + return TRUE; + if (!nouveau_fence_wait(buf->fence)) + return FALSE; + + nouveau_fence_ref(NULL, &buf->fence); + } + nouveau_fence_ref(NULL, &buf->fence_wr); + + return TRUE; +} + +static INLINE boolean +nouveau_buffer_busy(struct nv04_resource *buf, unsigned rw) +{ + if (rw == PIPE_TRANSFER_READ) + return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr)); + else + return (buf->fence && !nouveau_fence_signalled(buf->fence)); +} + +static void * +nouveau_buffer_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct nouveau_transfer *xfr = nouveau_transfer(transfer); + struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_bo *bo = buf->bo; + uint8_t *map; + int ret; + uint32_t offset = xfr->base.box.x; + uint32_t flags; + + nouveau_buffer_adjust_score(nouveau_context(pipe), buf, -250); + + if (buf->domain != NOUVEAU_BO_GART) + return buf->data + offset; + + if (buf->mm) + flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR; + else + flags = nouveau_screen_transfer_flags(xfr->base.usage); + + offset += buf->offset; + + ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags); + if (ret) + return NULL; + map = bo->map; + + /* Unmap right now. Since multiple buffers can share a single nouveau_bo, + * not doing so might make future maps fail or trigger "reloc while mapped" + * errors. For now, mappings to userspace are guaranteed to be persistent. + */ + nouveau_bo_unmap(bo); + + if (buf->mm) { + if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) { + if (nouveau_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE)) + return NULL; + } else + if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { + nouveau_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE); + } + } + return map; +} + + + +static void +nouveau_buffer_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct nv04_resource *res = nv04_resource(transfer->resource); + struct nouveau_bo *bo = res->bo; + unsigned offset = res->offset + transfer->box.x + box->x; + + /* not using non-snoop system memory yet, no need for cflush */ + if (1) + return; + + /* XXX: maybe need to upload for VRAM buffers here */ + + nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width); +} + +static void +nouveau_buffer_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + /* we've called nouveau_bo_unmap right after map */ +} + +const struct u_resource_vtbl nouveau_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + nouveau_buffer_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + nouveau_buffer_transfer_get, /* get_transfer */ + nouveau_buffer_transfer_destroy, /* transfer_destroy */ + nouveau_buffer_transfer_map, /* transfer_map */ + nouveau_buffer_transfer_flush_region, /* transfer_flush_region */ + nouveau_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + +struct pipe_resource * +nouveau_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *templ) +{ + struct nouveau_screen *screen = nouveau_screen(pscreen); + struct nv04_resource *buffer; + boolean ret; + + buffer = CALLOC_STRUCT(nv04_resource); + if (!buffer) + return NULL; + + buffer->base = *templ; + buffer->vtbl = &nouveau_buffer_vtbl; + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = pscreen; + + if ((buffer->base.bind & screen->sysmem_bindings) == screen->sysmem_bindings) + ret = nouveau_buffer_allocate(screen, buffer, 0); + else + ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); + + if (ret == FALSE) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + + +struct pipe_resource * +nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr, + unsigned bytes, unsigned bind) +{ + struct nv04_resource *buffer; + + buffer = CALLOC_STRUCT(nv04_resource); + if (!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->vtbl = &nouveau_buffer_vtbl; + buffer->base.screen = pscreen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; + buffer->base.usage = PIPE_USAGE_IMMUTABLE; + buffer->base.bind = bind; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + + buffer->data = ptr; + buffer->status = NOUVEAU_BUFFER_STATUS_USER_MEMORY; + + return &buffer->base; +} + +/* Like download, but for GART buffers. Merge ? */ +static INLINE boolean +nouveau_buffer_data_fetch(struct nv04_resource *buf, struct nouveau_bo *bo, + unsigned offset, unsigned size) +{ + if (!buf->data) { + buf->data = MALLOC(size); + if (!buf->data) + return FALSE; + } + if (nouveau_bo_map_range(bo, offset, size, NOUVEAU_BO_RD)) + return FALSE; + memcpy(buf->data, bo->map, size); + nouveau_bo_unmap(bo); + + return TRUE; +} + +/* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */ +boolean +nouveau_buffer_migrate(struct nouveau_context *nv, + struct nv04_resource *buf, const unsigned new_domain) +{ + struct nouveau_screen *screen = nv->screen; + struct nouveau_bo *bo; + const unsigned old_domain = buf->domain; + unsigned size = buf->base.width0; + unsigned offset; + int ret; + + assert(new_domain != old_domain); + + if (new_domain == NOUVEAU_BO_GART && old_domain == 0) { + if (!nouveau_buffer_allocate(screen, buf, new_domain)) + return FALSE; + ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR | + NOUVEAU_BO_NOSYNC); + if (ret) + return ret; + memcpy(buf->bo->map, buf->data, size); + nouveau_bo_unmap(buf->bo); + FREE(buf->data); + } else + if (old_domain != 0 && new_domain != 0) { + struct nouveau_mm_allocation *mm = buf->mm; + + if (new_domain == NOUVEAU_BO_VRAM) { + /* keep a system memory copy of our data in case we hit a fallback */ + if (!nouveau_buffer_data_fetch(buf, buf->bo, buf->offset, size)) + return FALSE; + debug_printf("migrating %u KiB to VRAM\n", size / 1024); + } + + offset = buf->offset; + bo = buf->bo; + buf->bo = NULL; + buf->mm = NULL; + nouveau_buffer_allocate(screen, buf, new_domain); + + nv->copy_data(nv, buf->bo, buf->offset, new_domain, + bo, offset, old_domain, buf->base.width0); + + nouveau_bo_ref(NULL, &bo); + if (mm) + release_allocation(&mm, screen->fence.current); + } else + if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { + if (!nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) + return FALSE; + if (!nouveau_buffer_upload(nv, buf, 0, buf->base.width0)) + return FALSE; + } else + return FALSE; + + assert(buf->domain == new_domain); + return TRUE; +} + +/* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART. + * We'd like to only allocate @size bytes here, but then we'd have to rebase + * the vertex indices ... + */ +boolean +nouveau_user_buffer_upload(struct nv04_resource *buf, + unsigned base, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(buf->base.screen); + int ret; + + assert(buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY); + + buf->base.width0 = base + size; + if (!nouveau_buffer_reallocate(screen, buf, NOUVEAU_BO_GART)) + return FALSE; + + ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size, + NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); + if (ret) + return FALSE; + memcpy(buf->bo->map, buf->data + base, size); + nouveau_bo_unmap(buf->bo); + + return TRUE; +} diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h new file mode 100644 index 00000000000..46e3554bdf7 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -0,0 +1,139 @@ +#ifndef __NOUVEAU_BUFFER_H__ +#define __NOUVEAU_BUFFER_H__ + +#include "util/u_transfer.h" +#include "util/u_double_list.h" + +struct pipe_resource; +struct nouveau_context; +struct nouveau_bo; + +#define NOUVEAU_BUFFER_SCORE_MIN -25000 +#define NOUVEAU_BUFFER_SCORE_MAX 25000 +#define NOUVEAU_BUFFER_SCORE_VRAM_THRESHOLD 20000 + +/* DIRTY: buffer was (or will be after the next flush) written to by GPU and + * resource->data has not been updated to reflect modified VRAM contents + * + * USER_MEMORY: resource->data is a pointer to client memory and may change + * between GL calls + */ +#define NOUVEAU_BUFFER_STATUS_GPU_READING (1 << 0) +#define NOUVEAU_BUFFER_STATUS_GPU_WRITING (1 << 1) +#define NOUVEAU_BUFFER_STATUS_USER_MEMORY (1 << 7) + +/* Resources, if mapped into the GPU's address space, are guaranteed to + * have constant virtual addresses (nv50+). + * + * The address of a resource will lie within the nouveau_bo referenced, + * and this bo should be added to the memory manager's validation list. + */ +struct nv04_resource { + struct pipe_resource base; + const struct u_resource_vtbl *vtbl; + + uint8_t *data; + struct nouveau_bo *bo; + uint32_t offset; + + uint8_t status; + uint8_t domain; + + int16_t score; /* low if mapped very often, if high can move to VRAM */ + + struct nouveau_fence *fence; + struct nouveau_fence *fence_wr; + + struct nouveau_mm_allocation *mm; +}; + +void +nouveau_buffer_release_gpu_storage(struct nv04_resource *); + +boolean +nouveau_buffer_download(struct nouveau_context *, struct nv04_resource *, + unsigned start, unsigned size); + +boolean +nouveau_buffer_migrate(struct nouveau_context *, + struct nv04_resource *, unsigned domain); + +static INLINE void +nouveau_buffer_adjust_score(struct nouveau_context *pipe, + struct nv04_resource *res, int16_t score) +{ + if (score < 0) { + if (res->score > NOUVEAU_BUFFER_SCORE_MIN) + res->score += score; + } else + if (score > 0){ + if (res->score < NOUVEAU_BUFFER_SCORE_MAX) + res->score += score; + if (res->domain == NOUVEAU_BO_GART && + res->score > NOUVEAU_BUFFER_SCORE_VRAM_THRESHOLD) + nouveau_buffer_migrate(pipe, res, NOUVEAU_BO_VRAM); + } +} + +/* XXX: wait for fence (atm only using this for vertex push) */ +static INLINE void * +nouveau_resource_map_offset(struct nouveau_context *pipe, + struct nv04_resource *res, uint32_t offset, + uint32_t flags) +{ + void *map; + + nouveau_buffer_adjust_score(pipe, res, -250); + + if ((res->domain == NOUVEAU_BO_VRAM) && + (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)) + nouveau_buffer_download(pipe, res, 0, res->base.width0); + + if ((res->domain != NOUVEAU_BO_GART) || + (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) + return res->data + offset; + + if (res->mm) + flags |= NOUVEAU_BO_NOSYNC; + + if (nouveau_bo_map_range(res->bo, res->offset + offset, + res->base.width0, flags)) + return NULL; + + map = res->bo->map; + nouveau_bo_unmap(res->bo); + return map; +} + +static INLINE void +nouveau_resource_unmap(struct nv04_resource *res) +{ + /* no-op */ +} + +static INLINE struct nv04_resource * +nv04_resource(struct pipe_resource *resource) +{ + return (struct nv04_resource *)resource; +} + +/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */ +static INLINE boolean +nouveau_resource_mapped_by_gpu(struct pipe_resource *resource) +{ + return nv04_resource(resource)->domain != 0; +} + +struct pipe_resource * +nouveau_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *templ); + +struct pipe_resource * +nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr, + unsigned bytes, unsigned usage); + +boolean +nouveau_user_buffer_upload(struct nv04_resource *, unsigned base, + unsigned size); + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h new file mode 100644 index 00000000000..696e0d3f24e --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -0,0 +1,26 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "pipe/p_context.h" + +struct nouveau_context { + struct pipe_context pipe; + struct nouveau_screen *screen; + + boolean vbo_dirty; + + void (*copy_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + struct nouveau_bo *src, unsigned, unsigned, unsigned); + void (*push_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + unsigned, void *); +}; + +static INLINE struct nouveau_context * +nouveau_context(struct pipe_context *pipe) +{ + return (struct nouveau_context *)pipe; +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c new file mode 100644 index 00000000000..18bdb18ad41 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -0,0 +1,220 @@ +/* + * Copyright 2010 Christoph Bumiller + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "util/u_double_list.h" + +#include "nouveau_screen.h" +#include "nouveau_fence.h" + +#include "nouveau/nouveau_pushbuf.h" + +#ifdef PIPE_OS_UNIX +#include <sched.h> +#endif + +boolean +nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence, + boolean emit) +{ + *fence = CALLOC_STRUCT(nouveau_fence); + if (!*fence) + return FALSE; + + (*fence)->screen = screen; + (*fence)->ref = 1; + LIST_INITHEAD(&(*fence)->work); + + if (emit) + nouveau_fence_emit(*fence); + + return TRUE; +} + +static void +nouveau_fence_trigger_work(struct nouveau_fence *fence) +{ + struct nouveau_fence_work *work, *tmp; + + LIST_FOR_EACH_ENTRY_SAFE(work, tmp, &fence->work, list) { + work->func(work->data); + LIST_DEL(&work->list); + FREE(work); + } +} + +boolean +nouveau_fence_work(struct nouveau_fence *fence, + void (*func)(void *), void *data) +{ + struct nouveau_fence_work *work; + + if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) { + func(data); + return TRUE; + } + + work = CALLOC_STRUCT(nouveau_fence_work); + if (!work) + return FALSE; + work->func = func; + work->data = data; + LIST_ADD(&work->list, &fence->work); + return TRUE; +} + +void +nouveau_fence_emit(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + + fence->sequence = ++screen->fence.sequence; + + assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE); + + screen->fence.emit(&screen->base, fence->sequence); + + ++fence->ref; + + if (screen->fence.tail) + screen->fence.tail->next = fence; + else + screen->fence.head = fence; + + screen->fence.tail = fence; + + fence->state = NOUVEAU_FENCE_STATE_EMITTED; +} + +void +nouveau_fence_del(struct nouveau_fence *fence) +{ + struct nouveau_fence *it; + struct nouveau_screen *screen = fence->screen; + + if (fence->state == NOUVEAU_FENCE_STATE_EMITTED || + fence->state == NOUVEAU_FENCE_STATE_FLUSHED) { + if (fence == screen->fence.head) { + screen->fence.head = fence->next; + if (!screen->fence.head) + screen->fence.tail = NULL; + } else { + for (it = screen->fence.head; it && it->next != fence; it = it->next); + it->next = fence->next; + if (screen->fence.tail == fence) + screen->fence.tail = it; + } + } + + if (!LIST_IS_EMPTY(&fence->work)) { + debug_printf("WARNING: deleting fence with work still pending !\n"); + nouveau_fence_trigger_work(fence); + } + + FREE(fence); +} + +void +nouveau_fence_update(struct nouveau_screen *screen, boolean flushed) +{ + struct nouveau_fence *fence; + struct nouveau_fence *next = NULL; + u32 sequence = screen->fence.update(&screen->base); + + if (screen->fence.sequence_ack == sequence) + return; + screen->fence.sequence_ack = sequence; + + for (fence = screen->fence.head; fence; fence = next) { + next = fence->next; + sequence = fence->sequence; + + fence->state = NOUVEAU_FENCE_STATE_SIGNALLED; + + nouveau_fence_trigger_work(fence); + nouveau_fence_ref(NULL, &fence); + + if (sequence == screen->fence.sequence_ack) + break; + } + screen->fence.head = next; + if (!next) + screen->fence.tail = NULL; + + if (flushed) { + for (fence = next; fence; fence = fence->next) + fence->state = NOUVEAU_FENCE_STATE_FLUSHED; + } +} + +#define NOUVEAU_FENCE_MAX_SPINS (1 << 31) + +boolean +nouveau_fence_signalled(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + + if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED) + nouveau_fence_update(screen, FALSE); + + return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED; +} + +boolean +nouveau_fence_wait(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + uint32_t spins = 0; + + if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) { + nouveau_fence_emit(fence); + + if (fence == screen->fence.current) + nouveau_fence_new(screen, &screen->fence.current, FALSE); + } + if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) + FIRE_RING(screen->channel); + + do { + nouveau_fence_update(screen, FALSE); + + if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) + return TRUE; + spins++; +#ifdef PIPE_OS_UNIX + if (!(spins % 8)) /* donate a few cycles */ + sched_yield(); +#endif + } while (spins < NOUVEAU_FENCE_MAX_SPINS); + + debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n", + fence->sequence, + screen->fence.sequence_ack, screen->fence.sequence); + + return FALSE; +} + +void +nouveau_fence_next(struct nouveau_screen *screen) +{ + nouveau_fence_emit(screen->fence.current); + nouveau_fence_new(screen, &screen->fence.current, FALSE); +} diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h new file mode 100644 index 00000000000..680c75e99f9 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -0,0 +1,59 @@ + +#ifndef __NOUVEAU_FENCE_H__ +#define __NOUVEAU_FENCE_H__ + +#include "util/u_inlines.h" +#include "util/u_double_list.h" + +#define NOUVEAU_FENCE_STATE_AVAILABLE 0 +#define NOUVEAU_FENCE_STATE_EMITTED 1 +#define NOUVEAU_FENCE_STATE_FLUSHED 2 +#define NOUVEAU_FENCE_STATE_SIGNALLED 3 + +struct nouveau_fence_work { + struct list_head list; + void (*func)(void *); + void *data; +}; + +struct nouveau_fence { + struct nouveau_fence *next; + struct nouveau_screen *screen; + int state; + int ref; + uint32_t sequence; + struct list_head work; +}; + +void nouveau_fence_emit(struct nouveau_fence *); +void nouveau_fence_del(struct nouveau_fence *); + +boolean nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **, + boolean emit); +boolean nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *); +void nouveau_fence_update(struct nouveau_screen *, boolean flushed); +void nouveau_fence_next(struct nouveau_screen *); +boolean nouveau_fence_wait(struct nouveau_fence *); +boolean nouveau_fence_signalled(struct nouveau_fence *); + +static INLINE void +nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref) +{ + if (fence) + ++fence->ref; + + if (*ref) { + if (--(*ref)->ref == 0) + nouveau_fence_del(*ref); + } + + *ref = fence; +} + +static INLINE struct nouveau_fence * +nouveau_fence(struct pipe_fence_handle *fence) +{ + return (struct nouveau_fence *)fence; +} + +#endif // __NOUVEAU_FENCE_H__ diff --git a/src/gallium/drivers/nvc0/nvc0_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 516d2e31b55..7edeb4d21d6 100644 --- a/src/gallium/drivers/nvc0/nvc0_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -3,7 +3,10 @@ #include "util/u_memory.h" #include "util/u_double_list.h" -#include "nvc0_screen.h" +#include "nouveau_screen.h" +#include "nouveau_mm.h" + +#include "nouveau/nouveau_bo.h" #define MM_MIN_ORDER 7 #define MM_MAX_ORDER 20 @@ -20,7 +23,7 @@ struct mm_bucket { int num_free; }; -struct nvc0_mman { +struct nouveau_mman { struct nouveau_device *dev; struct mm_bucket bucket[MM_NUM_BUCKETS]; uint32_t storage_type; @@ -31,7 +34,7 @@ struct nvc0_mman { struct mm_slab { struct list_head head; struct nouveau_bo *bo; - struct nvc0_mman *cache; + struct nouveau_mman *cache; int order; int count; int free; @@ -79,7 +82,7 @@ mm_get_order(uint32_t size) } static struct mm_bucket * -mm_bucket_by_order(struct nvc0_mman *cache, int order) +mm_bucket_by_order(struct nouveau_mman *cache, int order) { if (order > MM_MAX_ORDER) return NULL; @@ -87,7 +90,7 @@ mm_bucket_by_order(struct nvc0_mman *cache, int order) } static struct mm_bucket * -mm_bucket_by_size(struct nvc0_mman *cache, unsigned size) +mm_bucket_by_size(struct nouveau_mman *cache, unsigned size) { return mm_bucket_by_order(cache, mm_get_order(size)); } @@ -107,7 +110,7 @@ mm_default_slab_size(unsigned chunk_order) } static int -mm_slab_new(struct nvc0_mman *cache, int chunk_order) +mm_slab_new(struct nouveau_mman *cache, int chunk_order) { struct mm_slab *slab; int words, ret; @@ -147,13 +150,13 @@ mm_slab_new(struct nvc0_mman *cache, int chunk_order) } /* @return token to identify slab or NULL if we just allocated a new bo */ -struct nvc0_mm_allocation * -nvc0_mm_allocate(struct nvc0_mman *cache, +struct nouveau_mm_allocation * +nouveau_mm_allocate(struct nouveau_mman *cache, uint32_t size, struct nouveau_bo **bo, uint32_t *offset) { struct mm_bucket *bucket; struct mm_slab *slab; - struct nvc0_mm_allocation *alloc; + struct nouveau_mm_allocation *alloc; int ret; bucket = mm_bucket_by_size(cache, size); @@ -181,7 +184,7 @@ nvc0_mm_allocate(struct nvc0_mman *cache, *offset = mm_slab_alloc(slab) << slab->order; - alloc = MALLOC_STRUCT(nvc0_mm_allocation); + alloc = MALLOC_STRUCT(nouveau_mm_allocation); if (!alloc) return NULL; @@ -200,7 +203,7 @@ nvc0_mm_allocate(struct nvc0_mman *cache, } void -nvc0_mm_free(struct nvc0_mm_allocation *alloc) +nouveau_mm_free(struct nouveau_mm_allocation *alloc) { struct mm_slab *slab = (struct mm_slab *)alloc->priv; struct mm_bucket *bucket = mm_bucket_by_order(slab->cache, slab->order); @@ -219,11 +222,17 @@ nvc0_mm_free(struct nvc0_mm_allocation *alloc) FREE(alloc); } -struct nvc0_mman * -nvc0_mm_create(struct nouveau_device *dev, uint32_t domain, +void +nouveau_mm_free_work(void *data) +{ + nouveau_mm_free(data); +} + +struct nouveau_mman * +nouveau_mm_create(struct nouveau_device *dev, uint32_t domain, uint32_t storage_type) { - struct nvc0_mman *cache = MALLOC_STRUCT(nvc0_mman); + struct nouveau_mman *cache = MALLOC_STRUCT(nouveau_mman); int i; if (!cache) @@ -244,7 +253,7 @@ nvc0_mm_create(struct nouveau_device *dev, uint32_t domain, } static INLINE void -nvc0_mm_free_slabs(struct list_head *head) +nouveau_mm_free_slabs(struct list_head *head) { struct mm_slab *slab, *next; @@ -256,19 +265,24 @@ nvc0_mm_free_slabs(struct list_head *head) } void -nvc0_mm_destroy(struct nvc0_mman *cache) +nouveau_mm_destroy(struct nouveau_mman *cache) { int i; + if (!cache) + return; + for (i = 0; i < MM_NUM_BUCKETS; ++i) { if (!LIST_IS_EMPTY(&cache->bucket[i].used) || !LIST_IS_EMPTY(&cache->bucket[i].full)) debug_printf("WARNING: destroying GPU memory cache " "with some buffers still in use\n"); - nvc0_mm_free_slabs(&cache->bucket[i].free); - nvc0_mm_free_slabs(&cache->bucket[i].used); - nvc0_mm_free_slabs(&cache->bucket[i].full); + nouveau_mm_free_slabs(&cache->bucket[i].free); + nouveau_mm_free_slabs(&cache->bucket[i].used); + nouveau_mm_free_slabs(&cache->bucket[i].full); } + + FREE(cache); } diff --git a/src/gallium/drivers/nouveau/nouveau_mm.h b/src/gallium/drivers/nouveau/nouveau_mm.h new file mode 100644 index 00000000000..5b57c8ba4f2 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_mm.h @@ -0,0 +1,32 @@ +#ifndef __NOUVEAU_MM_H__ +#define __NOUVEAU_MM_H__ + +struct nouveau_mman; + +/* Since a resource can be migrated, we need to decouple allocations from + * them. This struct is linked with fences for delayed freeing of allocs. + */ +struct nouveau_mm_allocation { + struct nouveau_mm_allocation *next; + void *priv; + uint32_t offset; +}; + +extern struct nouveau_mman * +nouveau_mm_create(struct nouveau_device *, uint32_t domain, + uint32_t storage_type); + +extern void +nouveau_mm_destroy(struct nouveau_mman *); + +extern struct nouveau_mm_allocation * +nouveau_mm_allocate(struct nouveau_mman *, uint32_t size, + struct nouveau_bo **, uint32_t *offset); + +extern void +nouveau_mm_free(struct nouveau_mm_allocation *); + +extern void +nouveau_mm_free_work(void *); + +#endif // __NOUVEAU_MM_H__ diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index a9426df686f..e6cd3064c9a 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -14,6 +14,7 @@ #include "nouveau/nouveau_bo.h" #include "nouveau_winsys.h" #include "nouveau_screen.h" +#include "nouveau_fence.h" /* XXX this should go away */ #include "state_tracker/drm_driver.h" @@ -150,7 +151,7 @@ nouveau_screen_fence_ref(struct pipe_screen *pscreen, struct pipe_fence_handle **ptr, struct pipe_fence_handle *pfence) { - *ptr = pfence; + nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr); } static int @@ -158,7 +159,7 @@ nouveau_screen_fence_signalled(struct pipe_screen *screen, struct pipe_fence_handle *pfence, unsigned flags) { - return 0; + return !nouveau_fence_signalled(nouveau_fence(pfence)); } static int @@ -166,7 +167,7 @@ nouveau_screen_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *pfence, unsigned flags) { - return 0; + return !nouveau_fence_wait(nouveau_fence(pfence)); } @@ -250,6 +251,10 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) util_format_s3tc_init(); + screen->mm_GART = nouveau_mm_create(dev, + NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0x000); + screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); return 0; } @@ -257,7 +262,12 @@ void nouveau_screen_fini(struct nouveau_screen *screen) { struct pipe_winsys *ws = screen->base.winsys; + + nouveau_mm_destroy(screen->mm_GART); + nouveau_mm_destroy(screen->mm_VRAM); + nouveau_channel_free(&screen->channel); + if (ws) ws->destroy(ws); } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 1f4e5171c01..c091abf2786 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -2,6 +2,10 @@ #define __NOUVEAU_SCREEN_H__ #include "pipe/p_screen.h" +#include "util/u_memory.h" +typedef uint32_t u32; + +struct nouveau_bo; struct nouveau_screen { struct pipe_screen base; @@ -12,6 +16,20 @@ struct nouveau_screen { * these almost always should be set to the same value */ unsigned vertex_buffer_flags; unsigned index_buffer_flags; + unsigned sysmem_bindings; + + struct { + struct nouveau_fence *head; + struct nouveau_fence *tail; + struct nouveau_fence *current; + u32 sequence; + u32 sequence_ack; + void (*emit)(struct pipe_screen *, u32 sequence); + u32 (*update)(struct pipe_screen *); + } fence; + + struct nouveau_mman *mm_VRAM; + struct nouveau_mman *mm_GART; }; static INLINE struct nouveau_screen * diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h deleted file mode 100644 index e920cf9f3bc..00000000000 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ /dev/null @@ -1,316 +0,0 @@ -#ifndef __NOUVEAU_STATEOBJ_H__ -#define __NOUVEAU_STATEOBJ_H__ - -#include "util/u_debug.h" - -#ifdef DEBUG -#define DEBUG_NOUVEAU_STATEOBJ -#endif /* DEBUG */ - -struct nouveau_stateobj_reloc { - struct nouveau_bo *bo; - - struct nouveau_grobj *gr; - uint32_t push_offset; - uint32_t mthd; - - uint32_t data; - unsigned flags; - unsigned vor; - unsigned tor; -}; - -struct nouveau_stateobj_start { - struct nouveau_grobj *gr; - uint32_t mthd; - uint32_t size; - unsigned offset; -}; - -struct nouveau_stateobj { - struct pipe_reference reference; - - struct nouveau_stateobj_start *start; - struct nouveau_stateobj_reloc *reloc; - - /* Common memory pool for data. */ - uint32_t *pool; - unsigned pool_cur; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - unsigned start_alloc; - unsigned reloc_alloc; - unsigned pool_alloc; -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - unsigned total; /* includes begin_ring */ - unsigned cur; /* excludes begin_ring, offset from "cur_start" */ - unsigned cur_start; - unsigned cur_reloc; -}; - -static INLINE void -so_dump(struct nouveau_stateobj *so) -{ - unsigned i, nr, total = 0; - - for (i = 0; i < so->cur_start; i++) { - if (so->start[i].gr->subc > -1) - debug_printf("+0x%04x: 0x%08x\n", total++, - (so->start[i].size << 18) | (so->start[i].gr->subc << 13) - | so->start[i].mthd); - else - debug_printf("+0x%04x: 0x%08x\n", total++, - (so->start[i].size << 18) | so->start[i].mthd); - for (nr = 0; nr < so->start[i].size; nr++, total++) - debug_printf("+0x%04x: 0x%08x\n", total, - so->pool[so->start[i].offset + nr]); - } -} - -static INLINE struct nouveau_stateobj * -so_new(unsigned start, unsigned push, unsigned reloc) -{ - struct nouveau_stateobj *so; - - so = MALLOC(sizeof(struct nouveau_stateobj)); - pipe_reference_init(&so->reference, 1); - so->total = so->cur = so->cur_start = so->cur_reloc = 0; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - so->start_alloc = start; - so->reloc_alloc = reloc; - so->pool_alloc = push; -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - so->start = MALLOC(start * sizeof(struct nouveau_stateobj_start)); - so->reloc = MALLOC(reloc * sizeof(struct nouveau_stateobj_reloc)); - so->pool = MALLOC(push * sizeof(uint32_t)); - so->pool_cur = 0; - - if (!so->start || !so->reloc || !so->pool) { - debug_printf("malloc failed\n"); - assert(0); - } - - return so; -} - -static INLINE void -so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso) -{ - struct nouveau_stateobj *so = *pso; - int i; - - if (pipe_reference(&(*pso)->reference, &ref->reference)) { - FREE(so->start); - for (i = 0; i < so->cur_reloc; i++) - nouveau_bo_ref(NULL, &so->reloc[i].bo); - FREE(so->reloc); - FREE(so->pool); - FREE(so); - } - *pso = ref; -} - -static INLINE void -so_data(struct nouveau_stateobj *so, uint32_t data) -{ -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->cur >= so->start[so->cur_start - 1].size) { - debug_printf("exceeding specified size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - so->pool[so->start[so->cur_start - 1].offset + so->cur++] = data; -} - -static INLINE void -so_datap(struct nouveau_stateobj *so, uint32_t *data, unsigned size) -{ -#ifdef DEBUG_NOUVEAU_STATEOBJ - if ((so->cur + size) > so->start[so->cur_start - 1].size) { - debug_printf("exceeding specified size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - while (size--) - so->pool[so->start[so->cur_start - 1].offset + so->cur++] = - *data++; -} - -static INLINE void -so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr, - unsigned mthd, unsigned size) -{ - struct nouveau_stateobj_start *start; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->start_alloc <= so->cur_start) { - debug_printf("exceeding num_start size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - start = so->start; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->cur_start > 0 && start[so->cur_start - 1].size > so->cur) { - debug_printf("previous so_method was not filled\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - start[so->cur_start].gr = gr; - start[so->cur_start].mthd = mthd; - start[so->cur_start].size = size; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->pool_alloc < (size + so->pool_cur)) { - debug_printf("exceeding num_pool size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - start[so->cur_start].offset = so->pool_cur; - so->pool_cur += size; - - so->cur_start++; - /* The 1 is for *this* begin_ring. */ - so->total += so->cur + 1; - so->cur = 0; -} - -static INLINE void -so_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - struct nouveau_stateobj_reloc *r; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->reloc_alloc <= so->cur_reloc) { - debug_printf("exceeding num_reloc size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - r = so->reloc; - - r[so->cur_reloc].bo = NULL; - nouveau_bo_ref(bo, &(r[so->cur_reloc].bo)); - r[so->cur_reloc].gr = so->start[so->cur_start-1].gr; - r[so->cur_reloc].push_offset = so->total + so->cur; - r[so->cur_reloc].data = data; - r[so->cur_reloc].flags = flags; - r[so->cur_reloc].mthd = so->start[so->cur_start-1].mthd + - (so->cur << 2); - r[so->cur_reloc].vor = vor; - r[so->cur_reloc].tor = tor; - - so_data(so, data); - so->cur_reloc++; -} - -/* Determine if this buffer object is referenced by this state object. */ -static INLINE boolean -so_bo_is_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo) -{ - int i; - - for (i = 0; i < so->cur_reloc; i++) - if (so->reloc[i].bo == bo) - return true; - - return false; -} - -static INLINE void -so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) -{ - unsigned nr, i; - int ret = 0; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->start[so->cur_start - 1].size > so->cur) { - debug_printf("emit: previous so_method was not filled\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - /* We cannot update total in case we so_emit again. */ - nr = so->total + so->cur; - - /* This will flush if we need space. - * We don't actually need the marker. - */ - if ((ret = nouveau_pushbuf_marker_emit(chan, nr, so->cur_reloc))) { - debug_printf("so_emit failed marker emit with error %d\n", ret); - assert(0); - } - - /* Submit data. This will ensure proper binding of objects. */ - for (i = 0; i < so->cur_start; i++) { - BEGIN_RING(chan, so->start[i].gr, so->start[i].mthd, so->start[i].size); - OUT_RINGp(chan, &(so->pool[so->start[i].offset]), so->start[i].size); - } - - for (i = 0; i < so->cur_reloc; i++) { - struct nouveau_stateobj_reloc *r = &so->reloc[i]; - - if ((ret = nouveau_pushbuf_emit_reloc(chan, chan->cur - nr + - r->push_offset, r->bo, r->data, - 0, r->flags, r->vor, r->tor))) { - debug_printf("so_emit failed reloc with error %d\n", ret); - assert(0); - } - } -} - -static INLINE void -so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so) -{ - unsigned i; - int ret = 0; - - if (!so) - return; - - /* If we need to flush in flush notify, then we have a problem anyway. */ - for (i = 0; i < so->cur_reloc; i++) { - struct nouveau_stateobj_reloc *r = &so->reloc[i]; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (r->mthd & 0x40000000) { - debug_printf("error: NI mthd 0x%08X\n", r->mthd); - continue; - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - /* We don't need to autobind, since there are enough subchannels - * for all objects we use. If this is changed, account for the extra - * space in callers of this function. - */ - assert(r->gr->bound != NOUVEAU_GROBJ_UNBOUND); - - /* Some relocs really don't like to be hammered, - * NOUVEAU_BO_DUMMY makes sure it only - * happens when needed. - */ - ret = OUT_RELOC(chan, r->bo, (r->gr->subc << 13) | (1<< 18) | - r->mthd, (r->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART - | NOUVEAU_BO_RDWR)) | NOUVEAU_BO_DUMMY, 0, 0); - if (ret) { - debug_printf("OUT_RELOC failed %d\n", ret); - assert(0); - } - - ret = OUT_RELOC(chan, r->bo, r->data, r->flags | - NOUVEAU_BO_DUMMY, r->vor, r->tor); - if (ret) { - debug_printf("OUT_RELOC failed %d\n", ret); - assert(0); - } - } -} - -#endif diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 8dfb84a596f..484f870bd86 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -9,7 +9,6 @@ #include "nouveau/nouveau_device.h" #include "nouveau/nouveau_grobj.h" #include "nouveau/nouveau_notifier.h" -#include "nouveau/nouveau_resource.h" #ifndef NOUVEAU_NVC0 #include "nouveau/nv04_pushbuf.h" #endif diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index b3535c0976e..02bcc26cfb3 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -4,13 +4,10 @@ include $(TOP)/configs/current LIBNAME = nv50 C_SOURCES = \ - nv50_buffer.c \ - nv50_clear.c \ nv50_context.c \ nv50_draw.c \ nv50_formats.c \ nv50_miptree.c \ - nv50_query.c \ nv50_resource.c \ nv50_screen.c \ nv50_state.c \ @@ -19,7 +16,6 @@ C_SOURCES = \ nv50_tex.c \ nv50_transfer.c \ nv50_vbo.c \ - nv50_push.c \ nv50_program.c \ nv50_shader_state.c \ nv50_pc.c \ @@ -27,7 +23,9 @@ C_SOURCES = \ nv50_pc_emit.c \ nv50_tgsi_to_nc.c \ nv50_pc_optimize.c \ - nv50_pc_regalloc.c + nv50_pc_regalloc.c \ + nv50_push.c \ + nv50_query.c LIBRARY_INCLUDES = \ $(LIBDRM_CFLAGS) diff --git a/src/gallium/drivers/nv50/SConscript b/src/gallium/drivers/nv50/SConscript index 8e7892a9ab6..84644515ede 100644 --- a/src/gallium/drivers/nv50/SConscript +++ b/src/gallium/drivers/nv50/SConscript @@ -6,12 +6,10 @@ nv50 = env.ConvenienceLibrary( target = 'nv50', source = [ 'nv50_buffer.c', - 'nv50_clear.c', 'nv50_context.c', 'nv50_draw.c', 'nv50_formats.c', 'nv50_miptree.c', - 'nv50_query.c', 'nv50_resource.c', 'nv50_screen.c', 'nv50_state.c', @@ -20,7 +18,6 @@ nv50 = env.ConvenienceLibrary( 'nv50_tex.c', 'nv50_transfer.c', 'nv50_vbo.c', - 'nv50_push.c', 'nv50_program.c', 'nv50_shader_state.c', 'nv50_pc.c', @@ -29,6 +26,11 @@ nv50 = env.ConvenienceLibrary( 'nv50_tgsi_to_nc.c', 'nv50_pc_optimize.c', 'nv50_pc_regalloc.c', + 'nv50_push.c', + 'nv50_push2.c', + 'nv50_fence.c', + 'nv50_mm.c', + 'nv50_query.c' ]) Export('nv50') diff --git a/src/gallium/drivers/nv50/nv50_2d.xml.h b/src/gallium/drivers/nv50/nv50_2d.xml.h new file mode 100644 index 00000000000..bc9bcf7839e --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_2d.xml.h @@ -0,0 +1,393 @@ +#ifndef NV50_2D_XML +#define NV50_2D_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://0x04.net/cgit/index.cgi/rules-ng-ng +git clone git://0x04.net/rules-ng-ng + +The rules-ng-ng source files this header was generated from are: +- nv50_2d.xml ( 9799 bytes, from 2010-12-28 17:17:11) +- copyright.xml ( 6452 bytes, from 2010-12-15 23:45:18) +- nv_object.xml ( 11898 bytes, from 2010-12-28 17:17:11) +- nvchipsets.xml ( 3074 bytes, from 2010-12-15 23:45:18) +- nv_defs.xml ( 4437 bytes, from 2010-12-15 23:45:18) +- nv50_defs.xml ( 4487 bytes, from 2010-12-15 23:45:18) + +Copyright (C) 2006-2010 by the following authors: +- Artur Huillet <[email protected]> (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. <[email protected]> (koala_br) +- Carlos Martin <[email protected]> (carlosmn) +- Christoph Bumiller <[email protected]> (calim, chrisbmr) +- Dawid Gajownik <[email protected]> (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov <[email protected]> (lumag) +- EdB <[email protected]> (edb_) +- Erik Waling <[email protected]> (erikwaling) +- Francisco Jerez <[email protected]> (curro) +- imirkin <[email protected]> (imirkin) +- jb17bsome <[email protected]> (jb17bsome) +- Jeremy Kolb <[email protected]> (kjeremy) +- Laurent Carlier <[email protected]> (lordheavy) +- Luca Barbieri <[email protected]> (lb, lb1) +- Maarten Maathuis <[email protected]> (stillunknown) +- Marcin Kościelnicki <[email protected]> (mwk, koriakin) +- Mark Carey <[email protected]> (careym) +- Matthieu Castet <[email protected]> (mat-c) +- nvidiaman <[email protected]> (nvidiaman) +- Patrice Mandin <[email protected]> (pmandin, pmdata) +- Pekka Paalanen <[email protected]> (pq, ppaalanen) +- Peter Popov <[email protected]> (ironpeter) +- Richard Hughes <[email protected]> (hughsient) +- Rudi Cilibrasi <[email protected]> (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet <[email protected]> (leroutier) +- Stephane Marchesin <[email protected]> (marcheu) +- sturmflut <[email protected]> (sturmflut) +- Sylvain Munaut <[email protected]> +- Victor Stinner <[email protected]> (haypo) +- Wladmir van der Laan <[email protected]> (miathan6) +- Younes Manton <[email protected]> (ymanton) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + + + +#define NV50_2D_DMA_NOTIFY 0x00000180 + +#define NV50_2D_DMA_DST 0x00000184 + +#define NV50_2D_DMA_SRC 0x00000188 + +#define NV50_2D_DMA_COND 0x0000018c + +#define NV50_2D_DST_FORMAT 0x00000200 + +#define NV50_2D_DST_LINEAR 0x00000204 + +#define NV50_2D_DST_TILE_MODE 0x00000208 + +#define NV50_2D_DST_DEPTH 0x0000020c + +#define NV50_2D_DST_LAYER 0x00000210 + +#define NV50_2D_DST_PITCH 0x00000214 + +#define NV50_2D_DST_WIDTH 0x00000218 + +#define NV50_2D_DST_HEIGHT 0x0000021c + +#define NV50_2D_DST_ADDRESS_HIGH 0x00000220 + +#define NV50_2D_DST_ADDRESS_LOW 0x00000224 + +#define NV50_2D_UNK228 0x00000228 + +#define NV50_2D_SRC_FORMAT 0x00000230 + +#define NV50_2D_SRC_LINEAR 0x00000234 + +#define NV50_2D_SRC_TILE_MODE 0x00000238 + +#define NV50_2D_SRC_DEPTH 0x0000023c + +#define NV50_2D_SRC_LAYER 0x00000240 + +#define NV50_2D_SRC_PITCH 0x00000244 +#define NV50_2D_SRC_PITCH__MAX 0x00040000 + +#define NV50_2D_SRC_WIDTH 0x00000248 +#define NV50_2D_SRC_WIDTH__MAX 0x00010000 + +#define NV50_2D_SRC_HEIGHT 0x0000024c +#define NV50_2D_SRC_HEIGHT__MAX 0x00010000 + +#define NV50_2D_SRC_ADDRESS_HIGH 0x00000250 + +#define NV50_2D_SRC_ADDRESS_LOW 0x00000254 + +#define NV50_2D_UNK258 0x00000258 + +#define NV50_2D_UNK260 0x00000260 + +#define NV50_2D_COND_ADDRESS_HIGH 0x00000264 + +#define NV50_2D_COND_ADDRESS_LOW 0x00000268 + +#define NV50_2D_COND_MODE 0x0000026c +#define NV50_2D_COND_MODE_NEVER 0x00000000 +#define NV50_2D_COND_MODE_ALWAYS 0x00000001 +#define NV50_2D_COND_MODE_RES_NON_ZERO 0x00000002 +#define NV50_2D_COND_MODE_EQUAL 0x00000003 +#define NV50_2D_COND_MODE_NOT_EQUAL 0x00000004 + +#define NV50_2D_CLIP_X 0x00000280 + +#define NV50_2D_CLIP_Y 0x00000284 + +#define NV50_2D_CLIP_W 0x00000288 + +#define NV50_2D_CLIP_H 0x0000028c + +#define NV50_2D_CLIP_ENABLE 0x00000290 + +#define NV50_2D_COLOR_KEY_FORMAT 0x00000294 +#define NV50_2D_COLOR_KEY_FORMAT_16BPP 0x00000000 +#define NV50_2D_COLOR_KEY_FORMAT_15BPP 0x00000001 +#define NV50_2D_COLOR_KEY_FORMAT_24BPP 0x00000002 +#define NV50_2D_COLOR_KEY_FORMAT_30BPP 0x00000003 +#define NV50_2D_COLOR_KEY_FORMAT_8BPP 0x00000004 +#define NV50_2D_COLOR_KEY_FORMAT_16BPP2 0x00000005 +#define NV50_2D_COLOR_KEY_FORMAT_32BPP 0x00000006 + +#define NV50_2D_COLOR_KEY 0x00000298 + +#define NV50_2D_COLOR_KEY_ENABLE 0x0000029c + +#define NV50_2D_ROP 0x000002a0 + +#define NV50_2D_BETA1 0x000002a4 + +#define NV50_2D_BETA4 0x000002a8 + +#define NV50_2D_OPERATION 0x000002ac +#define NV50_2D_OPERATION_SRCCOPY_AND 0x00000000 +#define NV50_2D_OPERATION_ROP_AND 0x00000001 +#define NV50_2D_OPERATION_BLEND_AND 0x00000002 +#define NV50_2D_OPERATION_SRCCOPY 0x00000003 +#define NV50_2D_OPERATION_UNK4 0x00000004 +#define NV50_2D_OPERATION_SRCCOPY_PREMULT 0x00000005 +#define NV50_2D_OPERATION_BLEND_PREMULT 0x00000006 + +#define NV50_2D_UNK2B0 0x000002b0 +#define NV50_2D_UNK2B0_UNK0__MASK 0x0000003f +#define NV50_2D_UNK2B0_UNK0__SHIFT 0 +#define NV50_2D_UNK2B0_UNK1__MASK 0x00003f00 +#define NV50_2D_UNK2B0_UNK1__SHIFT 8 + +#define NV50_2D_PATTERN_SELECT 0x000002b4 +#define NV50_2D_PATTERN_SELECT_MONO_8X8 0x00000000 +#define NV50_2D_PATTERN_SELECT_MONO_64X1 0x00000001 +#define NV50_2D_PATTERN_SELECT_MONO_1X64 0x00000002 +#define NV50_2D_PATTERN_SELECT_COLOR 0x00000003 + +#define NV50_2D_PATTERN_COLOR_FORMAT 0x000002e8 +#define NV50_2D_PATTERN_COLOR_FORMAT_16BPP 0x00000000 +#define NV50_2D_PATTERN_COLOR_FORMAT_15BPP 0x00000001 +#define NV50_2D_PATTERN_COLOR_FORMAT_32BPP 0x00000002 +#define NV50_2D_PATTERN_COLOR_FORMAT_8BPP 0x00000003 +#define NV50_2D_PATTERN_COLOR_FORMAT_UNK4 0x00000004 +#define NV50_2D_PATTERN_COLOR_FORMAT_UNK5 0x00000005 + +#define NV50_2D_PATTERN_MONO_FORMAT 0x000002ec +#define NV50_2D_PATTERN_MONO_FORMAT_CGA6 0x00000000 +#define NV50_2D_PATTERN_MONO_FORMAT_LE 0x00000001 + +#define NV50_2D_PATTERN_COLOR(i0) (0x000002f0 + 0x4*(i0)) +#define NV50_2D_PATTERN_COLOR__ESIZE 0x00000004 +#define NV50_2D_PATTERN_COLOR__LEN 0x00000002 + +#define NV50_2D_PATTERN_BITMAP(i0) (0x000002f8 + 0x4*(i0)) +#define NV50_2D_PATTERN_BITMAP__ESIZE 0x00000004 +#define NV50_2D_PATTERN_BITMAP__LEN 0x00000002 + +#define NV50_2D_PATTERN_X8R8G8B8(i0) (0x00000300 + 0x4*(i0)) +#define NV50_2D_PATTERN_X8R8G8B8__ESIZE 0x00000004 +#define NV50_2D_PATTERN_X8R8G8B8__LEN 0x00000040 +#define NV50_2D_PATTERN_X8R8G8B8_B__MASK 0x000000ff +#define NV50_2D_PATTERN_X8R8G8B8_B__SHIFT 0 +#define NV50_2D_PATTERN_X8R8G8B8_G__MASK 0x0000ff00 +#define NV50_2D_PATTERN_X8R8G8B8_G__SHIFT 8 +#define NV50_2D_PATTERN_X8R8G8B8_R__MASK 0x00ff0000 +#define NV50_2D_PATTERN_X8R8G8B8_R__SHIFT 16 + +#define NV50_2D_PATTERN_R5G6B5(i0) (0x00000400 + 0x4*(i0)) +#define NV50_2D_PATTERN_R5G6B5__ESIZE 0x00000004 +#define NV50_2D_PATTERN_R5G6B5__LEN 0x00000020 +#define NV50_2D_PATTERN_R5G6B5_B0__MASK 0x0000001f +#define NV50_2D_PATTERN_R5G6B5_B0__SHIFT 0 +#define NV50_2D_PATTERN_R5G6B5_G0__MASK 0x000007e0 +#define NV50_2D_PATTERN_R5G6B5_G0__SHIFT 5 +#define NV50_2D_PATTERN_R5G6B5_R0__MASK 0x0000f800 +#define NV50_2D_PATTERN_R5G6B5_R0__SHIFT 11 +#define NV50_2D_PATTERN_R5G6B5_B1__MASK 0x001f0000 +#define NV50_2D_PATTERN_R5G6B5_B1__SHIFT 16 +#define NV50_2D_PATTERN_R5G6B5_G1__MASK 0x07e00000 +#define NV50_2D_PATTERN_R5G6B5_G1__SHIFT 21 +#define NV50_2D_PATTERN_R5G6B5_R1__MASK 0xf8000000 +#define NV50_2D_PATTERN_R5G6B5_R1__SHIFT 27 + +#define NV50_2D_PATTERN_X1R5G5B5(i0) (0x00000480 + 0x4*(i0)) +#define NV50_2D_PATTERN_X1R5G5B5__ESIZE 0x00000004 +#define NV50_2D_PATTERN_X1R5G5B5__LEN 0x00000020 +#define NV50_2D_PATTERN_X1R5G5B5_B0__MASK 0x0000001f +#define NV50_2D_PATTERN_X1R5G5B5_B0__SHIFT 0 +#define NV50_2D_PATTERN_X1R5G5B5_G0__MASK 0x000003e0 +#define NV50_2D_PATTERN_X1R5G5B5_G0__SHIFT 5 +#define NV50_2D_PATTERN_X1R5G5B5_R0__MASK 0x00007c00 +#define NV50_2D_PATTERN_X1R5G5B5_R0__SHIFT 10 +#define NV50_2D_PATTERN_X1R5G5B5_B1__MASK 0x001f0000 +#define NV50_2D_PATTERN_X1R5G5B5_B1__SHIFT 16 +#define NV50_2D_PATTERN_X1R5G5B5_G1__MASK 0x03e00000 +#define NV50_2D_PATTERN_X1R5G5B5_G1__SHIFT 21 +#define NV50_2D_PATTERN_X1R5G5B5_R1__MASK 0x7c000000 +#define NV50_2D_PATTERN_X1R5G5B5_R1__SHIFT 26 + +#define NV50_2D_PATTERN_Y8(i0) (0x00000500 + 0x4*(i0)) +#define NV50_2D_PATTERN_Y8__ESIZE 0x00000004 +#define NV50_2D_PATTERN_Y8__LEN 0x00000010 +#define NV50_2D_PATTERN_Y8_Y0__MASK 0x000000ff +#define NV50_2D_PATTERN_Y8_Y0__SHIFT 0 +#define NV50_2D_PATTERN_Y8_Y1__MASK 0x0000ff00 +#define NV50_2D_PATTERN_Y8_Y1__SHIFT 8 +#define NV50_2D_PATTERN_Y8_Y2__MASK 0x00ff0000 +#define NV50_2D_PATTERN_Y8_Y2__SHIFT 16 +#define NV50_2D_PATTERN_Y8_Y3__MASK 0xff000000 +#define NV50_2D_PATTERN_Y8_Y3__SHIFT 24 + +#define NV50_2D_DRAW_SHAPE 0x00000580 +#define NV50_2D_DRAW_SHAPE_POINTS 0x00000000 +#define NV50_2D_DRAW_SHAPE_LINES 0x00000001 +#define NV50_2D_DRAW_SHAPE_LINE_STRIP 0x00000002 +#define NV50_2D_DRAW_SHAPE_TRIANGLES 0x00000003 +#define NV50_2D_DRAW_SHAPE_RECTANGLES 0x00000004 + +#define NV50_2D_DRAW_COLOR_FORMAT 0x00000584 + +#define NV50_2D_DRAW_COLOR 0x00000588 + +#define NV50_2D_UNK58C 0x0000058c +#define NV50_2D_UNK58C_0 0x00000001 +#define NV50_2D_UNK58C_1 0x00000010 +#define NV50_2D_UNK58C_2 0x00000100 +#define NV50_2D_UNK58C_3 0x00001000 + +#define NV50_2D_DRAW_POINT16 0x000005e0 +#define NV50_2D_DRAW_POINT16_X__MASK 0x0000ffff +#define NV50_2D_DRAW_POINT16_X__SHIFT 0 +#define NV50_2D_DRAW_POINT16_Y__MASK 0xffff0000 +#define NV50_2D_DRAW_POINT16_Y__SHIFT 16 + +#define NV50_2D_DRAW_POINT32_X(i0) (0x00000600 + 0x8*(i0)) +#define NV50_2D_DRAW_POINT32_X__ESIZE 0x00000008 +#define NV50_2D_DRAW_POINT32_X__LEN 0x00000040 + +#define NV50_2D_DRAW_POINT32_Y(i0) (0x00000604 + 0x8*(i0)) +#define NV50_2D_DRAW_POINT32_Y__ESIZE 0x00000008 +#define NV50_2D_DRAW_POINT32_Y__LEN 0x00000040 + +#define NV50_2D_SIFC_BITMAP_ENABLE 0x00000800 + +#define NV50_2D_SIFC_FORMAT 0x00000804 + +#define NV50_2D_SIFC_BITMAP_FORMAT 0x00000808 +#define NV50_2D_SIFC_BITMAP_FORMAT_I1 0x00000000 +#define NV50_2D_SIFC_BITMAP_FORMAT_I4 0x00000001 +#define NV50_2D_SIFC_BITMAP_FORMAT_I8 0x00000002 + +#define NV50_2D_SIFC_BITMAP_LSB_FIRST 0x0000080c + +#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE 0x00000810 +#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_PACKED 0x00000000 +#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE 0x00000001 +#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_WORD 0x00000002 + +#define NV50_2D_SIFC_BITMAP_COLOR_BIT0 0x00000814 + +#define NV50_2D_SIFC_BITMAP_COLOR_BIT1 0x00000818 + +#define NV50_2D_SIFC_BITMAP_WRITE_BIT0_ENABLE 0x0000081c + +#define NV50_2D_SIFC_WIDTH 0x00000838 + +#define NV50_2D_SIFC_HEIGHT 0x0000083c + +#define NV50_2D_SIFC_DX_DU_FRACT 0x00000840 + +#define NV50_2D_SIFC_DX_DU_INT 0x00000844 + +#define NV50_2D_SIFC_DY_DV_FRACT 0x00000848 + +#define NV50_2D_SIFC_DY_DV_INT 0x0000084c + +#define NV50_2D_SIFC_DST_X_FRACT 0x00000850 + +#define NV50_2D_SIFC_DST_X_INT 0x00000854 + +#define NV50_2D_SIFC_DST_Y_FRACT 0x00000858 + +#define NV50_2D_SIFC_DST_Y_INT 0x0000085c + +#define NV50_2D_SIFC_DATA 0x00000860 + +#define NV50_2D_UNK0870 0x00000870 + +#define NV50_2D_UNK0880 0x00000880 + +#define NV50_2D_UNK0884 0x00000884 + +#define NV50_2D_UNK0888 0x00000888 + +#define NV50_2D_BLIT_CONTROL 0x0000088c +#define NV50_2D_BLIT_CONTROL_ORIGIN__MASK 0x00000001 +#define NV50_2D_BLIT_CONTROL_ORIGIN__SHIFT 0 +#define NV50_2D_BLIT_CONTROL_ORIGIN_CENTER 0x00000000 +#define NV50_2D_BLIT_CONTROL_ORIGIN_CORNER 0x00000001 +#define NV50_2D_BLIT_CONTROL_FILTER__MASK 0x00000010 +#define NV50_2D_BLIT_CONTROL_FILTER__SHIFT 4 +#define NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE 0x00000000 +#define NV50_2D_BLIT_CONTROL_FILTER_BILINEAR 0x00000010 + +#define NV50_2D_BLIT_DST_X 0x000008b0 + +#define NV50_2D_BLIT_DST_Y 0x000008b4 + +#define NV50_2D_BLIT_DST_W 0x000008b8 + +#define NV50_2D_BLIT_DST_H 0x000008bc + +#define NV50_2D_BLIT_DU_DX_FRACT 0x000008c0 + +#define NV50_2D_BLIT_DU_DX_INT 0x000008c4 + +#define NV50_2D_BLIT_DV_DY_FRACT 0x000008c8 + +#define NV50_2D_BLIT_DV_DY_INT 0x000008cc + +#define NV50_2D_BLIT_SRC_X_FRACT 0x000008d0 + +#define NV50_2D_BLIT_SRC_X_INT 0x000008d4 + +#define NV50_2D_BLIT_SRC_Y_FRACT 0x000008d8 + +#define NV50_2D_BLIT_SRC_Y_INT 0x000008dc + +#define NVC0_2D_FIRMWARE(i0) (0x000008e0 + 0x4*(i0)) +#define NVC0_2D_FIRMWARE__ESIZE 0x00000004 +#define NVC0_2D_FIRMWARE__LEN 0x00000020 + + +#endif /* NV50_2D_XML */ diff --git a/src/gallium/drivers/nv50/nv50_3d.xml.h b/src/gallium/drivers/nv50/nv50_3d.xml.h new file mode 100644 index 00000000000..9bb3211728c --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_3d.xml.h @@ -0,0 +1,2084 @@ +#ifndef NV50_3D_XML +#define NV50_3D_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://0x04.net/cgit/index.cgi/rules-ng-ng +git clone git://0x04.net/rules-ng-ng + +The rules-ng-ng source files this header was generated from are: +- nv50_3d.xml ( 64479 bytes, from 2011-02-27 17:58:08) +- copyright.xml ( 6452 bytes, from 2010-12-15 23:45:18) +- nv_defs.xml ( 4437 bytes, from 2010-12-15 23:45:18) +- nv50_defs.xml ( 4487 bytes, from 2010-12-15 23:45:18) +- nv_3ddefs.xml ( 16394 bytes, from 2010-12-15 23:45:18) +- nv_object.xml ( 12191 bytes, from 2011-02-27 17:58:08) +- nvchipsets.xml ( 3074 bytes, from 2011-02-27 17:58:08) + +Copyright (C) 2006-2011 by the following authors: +- Artur Huillet <[email protected]> (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. <[email protected]> (koala_br) +- Carlos Martin <[email protected]> (carlosmn) +- Christoph Bumiller <[email protected]> (calim, chrisbmr) +- Dawid Gajownik <[email protected]> (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov <[email protected]> (lumag) +- EdB <[email protected]> (edb_) +- Erik Waling <[email protected]> (erikwaling) +- Francisco Jerez <[email protected]> (curro) +- imirkin <[email protected]> (imirkin) +- jb17bsome <[email protected]> (jb17bsome) +- Jeremy Kolb <[email protected]> (kjeremy) +- Laurent Carlier <[email protected]> (lordheavy) +- Luca Barbieri <[email protected]> (lb, lb1) +- Maarten Maathuis <[email protected]> (stillunknown) +- Marcin Kościelnicki <[email protected]> (mwk, koriakin) +- Mark Carey <[email protected]> (careym) +- Matthieu Castet <[email protected]> (mat-c) +- nvidiaman <[email protected]> (nvidiaman) +- Patrice Mandin <[email protected]> (pmandin, pmdata) +- Pekka Paalanen <[email protected]> (pq, ppaalanen) +- Peter Popov <[email protected]> (ironpeter) +- Richard Hughes <[email protected]> (hughsient) +- Rudi Cilibrasi <[email protected]> (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet <[email protected]> (leroutier) +- Stephane Marchesin <[email protected]> (marcheu) +- sturmflut <[email protected]> (sturmflut) +- Sylvain Munaut <[email protected]> +- Victor Stinner <[email protected]> (haypo) +- Wladmir van der Laan <[email protected]> (miathan6) +- Younes Manton <[email protected]> (ymanton) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#define NV50_3D_SERIALIZE 0x00000110 + +#define NV50_3D_DMA_NOTIFY 0x00000180 + +#define NV50_3D_DMA_ZETA 0x00000184 + +#define NV50_3D_DMA_QUERY 0x00000188 + +#define NV50_3D_DMA_VTXBUF 0x0000018c + +#define NV50_3D_DMA_LOCAL 0x00000190 + +#define NV50_3D_DMA_STACK 0x00000194 + +#define NV50_3D_DMA_CODE_CB 0x00000198 + +#define NV50_3D_DMA_TSC 0x0000019c + +#define NV50_3D_DMA_TIC 0x000001a0 + +#define NV50_3D_DMA_TEXTURE 0x000001a4 + +#define NV50_3D_DMA_STRMOUT 0x000001a8 + +#define NV50_3D_DMA_CLIPID 0x000001ac + +#define NV50_3D_DMA_COLOR(i0) (0x000001c0 + 0x4*(i0)) +#define NV50_3D_DMA_COLOR__ESIZE 0x00000004 +#define NV50_3D_DMA_COLOR__LEN 0x00000008 + +#define NV50_3D_RT(i0) (0x00000200 + 0x20*(i0)) +#define NV50_3D_RT__ESIZE 0x00000020 +#define NV50_3D_RT__LEN 0x00000008 + +#define NV50_3D_RT_ADDRESS_HIGH(i0) (0x00000200 + 0x20*(i0)) + +#define NV50_3D_RT_ADDRESS_LOW(i0) (0x00000204 + 0x20*(i0)) + +#define NV50_3D_RT_FORMAT(i0) (0x00000208 + 0x20*(i0)) + +#define NV50_3D_RT_TILE_MODE(i0) (0x0000020c + 0x20*(i0)) +#define NV50_3D_RT_TILE_MODE_X__MASK 0x0000000f +#define NV50_3D_RT_TILE_MODE_X__SHIFT 0 +#define NV50_3D_RT_TILE_MODE_Y__MASK 0x000000f0 +#define NV50_3D_RT_TILE_MODE_Y__SHIFT 4 +#define NV50_3D_RT_TILE_MODE_Z__MASK 0x00000f00 +#define NV50_3D_RT_TILE_MODE_Z__SHIFT 8 + +#define NV50_3D_RT_LAYER_STRIDE(i0) (0x00000210 + 0x20*(i0)) +#define NV50_3D_RT_LAYER_STRIDE__SHR 2 + +#define NV50_3D_RT_UNK14(i0) (0x00000214 + 0x20*(i0)) + +#define NV50_3D_VTX_ATTR_1F(i0) (0x00000300 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_1F__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_1F__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_2H(i0) (0x00000340 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_2H__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_2H__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_2H_X__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_2H_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_2H_Y__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_2H_Y__SHIFT 16 + +#define NV50_3D_VTX_ATTR_2F_X(i0) (0x00000380 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_2F_X__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_2F_X__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_2F_Y(i0) (0x00000384 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_2F_Y__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_2F_Y__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_3F_X(i0) (0x00000400 + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_3F_X__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_3F_X__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_3F_Y(i0) (0x00000404 + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_3F_Y__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_3F_Y__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_3F_Z(i0) (0x00000408 + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_3F_Z__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_3F_Z__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_4F_X(i0) (0x00000500 + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_4F_X__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_4F_X__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_4F_Y(i0) (0x00000504 + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_4F_Y__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_4F_Y__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_4F_Z(i0) (0x00000508 + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_4F_Z__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_4F_Z__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_4F_W(i0) (0x0000050c + 0x10*(i0)) +#define NV50_3D_VTX_ATTR_4F_W__ESIZE 0x00000010 +#define NV50_3D_VTX_ATTR_4F_W__LEN 0x00000010 + +#define NV50_3D_VTX_ATTR_4H_0(i0) (0x00000600 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_4H_0__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_4H_0__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4H_0_X__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_4H_0_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4H_0_Y__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_4H_0_Y__SHIFT 16 + +#define NV50_3D_VTX_ATTR_4H_1(i0) (0x00000604 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_4H_1__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_4H_1__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4H_1_Z__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_4H_1_Z__SHIFT 0 +#define NV50_3D_VTX_ATTR_4H_1_W__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_4H_1_W__SHIFT 16 + +#define NV50_3D_VTX_ATTR_2I(i0) (0x00000680 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_2I__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_2I__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_2I_X__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_2I_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_2I_Y__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_2I_Y__SHIFT 16 + +#define NV50_3D_VTX_ATTR_2NI(i0) (0x000006c0 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_2NI__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_2NI__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_2NI_X__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_2NI_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_2NI_Y__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_2NI_Y__SHIFT 16 + +#define NV50_3D_VTX_ATTR_4I_0(i0) (0x00000700 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_4I_0__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_4I_0__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4I_0_X__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_4I_0_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4I_0_Y__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_4I_0_Y__SHIFT 16 + +#define NV50_3D_VTX_ATTR_4I_1(i0) (0x00000704 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_4I_1__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_4I_1__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4I_1_Z__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_4I_1_Z__SHIFT 0 +#define NV50_3D_VTX_ATTR_4I_1_W__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_4I_1_W__SHIFT 16 + +#define NV50_3D_VTX_ATTR_4NI_0(i0) (0x00000780 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_4NI_0__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_4NI_0__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4NI_0_X__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_4NI_0_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4NI_0_Y__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_4NI_0_Y__SHIFT 16 + +#define NV50_3D_VTX_ATTR_4NI_1(i0) (0x00000784 + 0x8*(i0)) +#define NV50_3D_VTX_ATTR_4NI_1__ESIZE 0x00000008 +#define NV50_3D_VTX_ATTR_4NI_1__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4NI_1_Z__MASK 0x0000ffff +#define NV50_3D_VTX_ATTR_4NI_1_Z__SHIFT 0 +#define NV50_3D_VTX_ATTR_4NI_1_W__MASK 0xffff0000 +#define NV50_3D_VTX_ATTR_4NI_1_W__SHIFT 16 + +#define NV50_3D_VTX_ATTR_4UB(i0) (0x00000800 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_4UB__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_4UB__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4UB_X__MASK 0x000000ff +#define NV50_3D_VTX_ATTR_4UB_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4UB_Y__MASK 0x0000ff00 +#define NV50_3D_VTX_ATTR_4UB_Y__SHIFT 8 +#define NV50_3D_VTX_ATTR_4UB_Z__MASK 0x00ff0000 +#define NV50_3D_VTX_ATTR_4UB_Z__SHIFT 16 +#define NV50_3D_VTX_ATTR_4UB_W__MASK 0xff000000 +#define NV50_3D_VTX_ATTR_4UB_W__SHIFT 24 + +#define NV50_3D_VTX_ATTR_4B(i0) (0x00000840 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_4B__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_4B__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4B_X__MASK 0x000000ff +#define NV50_3D_VTX_ATTR_4B_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4B_Y__MASK 0x0000ff00 +#define NV50_3D_VTX_ATTR_4B_Y__SHIFT 8 +#define NV50_3D_VTX_ATTR_4B_Z__MASK 0x00ff0000 +#define NV50_3D_VTX_ATTR_4B_Z__SHIFT 16 +#define NV50_3D_VTX_ATTR_4B_W__MASK 0xff000000 +#define NV50_3D_VTX_ATTR_4B_W__SHIFT 24 + +#define NV50_3D_VTX_ATTR_4NUB(i0) (0x00000880 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_4NUB__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_4NUB__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4NUB_X__MASK 0x000000ff +#define NV50_3D_VTX_ATTR_4NUB_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4NUB_Y__MASK 0x0000ff00 +#define NV50_3D_VTX_ATTR_4NUB_Y__SHIFT 8 +#define NV50_3D_VTX_ATTR_4NUB_Z__MASK 0x00ff0000 +#define NV50_3D_VTX_ATTR_4NUB_Z__SHIFT 16 +#define NV50_3D_VTX_ATTR_4NUB_W__MASK 0xff000000 +#define NV50_3D_VTX_ATTR_4NUB_W__SHIFT 24 + +#define NV50_3D_VTX_ATTR_4NB(i0) (0x000008c0 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_4NB__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_4NB__LEN 0x00000010 +#define NV50_3D_VTX_ATTR_4NB_X__MASK 0x000000ff +#define NV50_3D_VTX_ATTR_4NB_X__SHIFT 0 +#define NV50_3D_VTX_ATTR_4NB_Y__MASK 0x0000ff00 +#define NV50_3D_VTX_ATTR_4NB_Y__SHIFT 8 +#define NV50_3D_VTX_ATTR_4NB_Z__MASK 0x00ff0000 +#define NV50_3D_VTX_ATTR_4NB_Z__SHIFT 16 +#define NV50_3D_VTX_ATTR_4NB_W__MASK 0xff000000 +#define NV50_3D_VTX_ATTR_4NB_W__SHIFT 24 + +#define NV50_3D_VERTEX_ARRAY_FETCH(i0) (0x00000900 + 0x10*(i0)) +#define NV50_3D_VERTEX_ARRAY_FETCH__ESIZE 0x00000010 +#define NV50_3D_VERTEX_ARRAY_FETCH__LEN 0x00000010 +#define NV50_3D_VERTEX_ARRAY_FETCH_STRIDE__MASK 0x00000fff +#define NV50_3D_VERTEX_ARRAY_FETCH_STRIDE__SHIFT 0 +#define NV50_3D_VERTEX_ARRAY_FETCH_ENABLE 0x20000000 + +#define NV50_3D_VERTEX_ARRAY_START_HIGH(i0) (0x00000904 + 0x10*(i0)) +#define NV50_3D_VERTEX_ARRAY_START_HIGH__ESIZE 0x00000010 +#define NV50_3D_VERTEX_ARRAY_START_HIGH__LEN 0x00000010 + +#define NV50_3D_VERTEX_ARRAY_START_LOW(i0) (0x00000908 + 0x10*(i0)) +#define NV50_3D_VERTEX_ARRAY_START_LOW__ESIZE 0x00000010 +#define NV50_3D_VERTEX_ARRAY_START_LOW__LEN 0x00000010 + +#define NV50_3D_VERTEX_ARRAY_DIVISOR(i0) (0x0000090c + 0x10*(i0)) +#define NV50_3D_VERTEX_ARRAY_DIVISOR__ESIZE 0x00000010 +#define NV50_3D_VERTEX_ARRAY_DIVISOR__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_SCALE_X(i0) (0x00000a00 + 0x20*(i0)) +#define NV50_3D_VIEWPORT_SCALE_X__ESIZE 0x00000020 +#define NV50_3D_VIEWPORT_SCALE_X__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_SCALE_Y(i0) (0x00000a04 + 0x20*(i0)) +#define NV50_3D_VIEWPORT_SCALE_Y__ESIZE 0x00000020 +#define NV50_3D_VIEWPORT_SCALE_Y__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_SCALE_Z(i0) (0x00000a08 + 0x20*(i0)) +#define NV50_3D_VIEWPORT_SCALE_Z__ESIZE 0x00000020 +#define NV50_3D_VIEWPORT_SCALE_Z__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_TRANSLATE_X(i0) (0x00000a0c + 0x20*(i0)) +#define NV50_3D_VIEWPORT_TRANSLATE_X__ESIZE 0x00000020 +#define NV50_3D_VIEWPORT_TRANSLATE_X__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_TRANSLATE_Y(i0) (0x00000a10 + 0x20*(i0)) +#define NV50_3D_VIEWPORT_TRANSLATE_Y__ESIZE 0x00000020 +#define NV50_3D_VIEWPORT_TRANSLATE_Y__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_TRANSLATE_Z(i0) (0x00000a14 + 0x20*(i0)) +#define NV50_3D_VIEWPORT_TRANSLATE_Z__ESIZE 0x00000020 +#define NV50_3D_VIEWPORT_TRANSLATE_Z__LEN 0x00000010 + +#define NV50_3D_VIEWPORT_HORIZ(i0) (0x00000c00 + 0x10*(i0)) +#define NV50_3D_VIEWPORT_HORIZ__ESIZE 0x00000010 +#define NV50_3D_VIEWPORT_HORIZ__LEN 0x00000010 +#define NV50_3D_VIEWPORT_HORIZ_X__MASK 0x0000ffff +#define NV50_3D_VIEWPORT_HORIZ_X__SHIFT 0 +#define NV50_3D_VIEWPORT_HORIZ_W__MASK 0xffff0000 +#define NV50_3D_VIEWPORT_HORIZ_W__SHIFT 16 + +#define NV50_3D_VIEWPORT_VERT(i0) (0x00000c04 + 0x10*(i0)) +#define NV50_3D_VIEWPORT_VERT__ESIZE 0x00000010 +#define NV50_3D_VIEWPORT_VERT__LEN 0x00000010 +#define NV50_3D_VIEWPORT_VERT_Y__MASK 0x0000ffff +#define NV50_3D_VIEWPORT_VERT_Y__SHIFT 0 +#define NV50_3D_VIEWPORT_VERT_H__MASK 0xffff0000 +#define NV50_3D_VIEWPORT_VERT_H__SHIFT 16 + +#define NV50_3D_DEPTH_RANGE_NEAR(i0) (0x00000c08 + 0x10*(i0)) +#define NV50_3D_DEPTH_RANGE_NEAR__ESIZE 0x00000010 +#define NV50_3D_DEPTH_RANGE_NEAR__LEN 0x00000010 + +#define NV50_3D_DEPTH_RANGE_FAR(i0) (0x00000c0c + 0x10*(i0)) +#define NV50_3D_DEPTH_RANGE_FAR__ESIZE 0x00000010 +#define NV50_3D_DEPTH_RANGE_FAR__LEN 0x00000010 + +#define NV50_3D_CLIP_RECT_HORIZ(i0) (0x00000d00 + 0x8*(i0)) +#define NV50_3D_CLIP_RECT_HORIZ__ESIZE 0x00000008 +#define NV50_3D_CLIP_RECT_HORIZ__LEN 0x00000008 +#define NV50_3D_CLIP_RECT_HORIZ_MIN__MASK 0x0000ffff +#define NV50_3D_CLIP_RECT_HORIZ_MIN__SHIFT 0 +#define NV50_3D_CLIP_RECT_HORIZ_MAX__MASK 0xffff0000 +#define NV50_3D_CLIP_RECT_HORIZ_MAX__SHIFT 16 + +#define NV50_3D_CLIP_RECT_VERT(i0) (0x00000d04 + 0x8*(i0)) +#define NV50_3D_CLIP_RECT_VERT__ESIZE 0x00000008 +#define NV50_3D_CLIP_RECT_VERT__LEN 0x00000008 +#define NV50_3D_CLIP_RECT_VERT_MIN__MASK 0x0000ffff +#define NV50_3D_CLIP_RECT_VERT_MIN__SHIFT 0 +#define NV50_3D_CLIP_RECT_VERT_MAX__MASK 0xffff0000 +#define NV50_3D_CLIP_RECT_VERT_MAX__SHIFT 16 + +#define NV50_3D_CLIPID_REGION_HORIZ(i0) (0x00000d40 + 0x8*(i0)) +#define NV50_3D_CLIPID_REGION_HORIZ__ESIZE 0x00000008 +#define NV50_3D_CLIPID_REGION_HORIZ__LEN 0x00000004 +#define NV50_3D_CLIPID_REGION_HORIZ_X__MASK 0x0000ffff +#define NV50_3D_CLIPID_REGION_HORIZ_X__SHIFT 0 +#define NV50_3D_CLIPID_REGION_HORIZ_W__MASK 0xffff0000 +#define NV50_3D_CLIPID_REGION_HORIZ_W__SHIFT 16 + +#define NV50_3D_CLIPID_REGION_VERT(i0) (0x00000d44 + 0x8*(i0)) +#define NV50_3D_CLIPID_REGION_VERT__ESIZE 0x00000008 +#define NV50_3D_CLIPID_REGION_VERT__LEN 0x00000004 +#define NV50_3D_CLIPID_REGION_VERT_Y__MASK 0x0000ffff +#define NV50_3D_CLIPID_REGION_VERT_Y__SHIFT 0 +#define NV50_3D_CLIPID_REGION_VERT_H__MASK 0xffff0000 +#define NV50_3D_CLIPID_REGION_VERT_H__SHIFT 16 + +#define NV50_3D_UNK0D60 0x00000d60 + +#define NV50_3D_UNK0D64 0x00000d64 + +#define NV50_3D_COUNTER_ENABLE 0x00000d68 +#define NV50_3D_COUNTER_ENABLE_VFETCH_VERTICES 0x00000001 +#define NV50_3D_COUNTER_ENABLE_VFETCH_PRIMITIVES 0x00000002 +#define NV50_3D_COUNTER_ENABLE_VP_LAUNCHES 0x00000004 +#define NV50_3D_COUNTER_ENABLE_GP_LAUNCHES 0x00000008 +#define NV50_3D_COUNTER_ENABLE_GP_PRIMITIVES_OUT 0x00000010 +#define NV50_3D_COUNTER_ENABLE_TRANSFORM_FEEDBACK 0x00000020 +#define NV50_3D_COUNTER_ENABLE_GENERATED_PRIMITIVES 0x00000040 +#define NV50_3D_COUNTER_ENABLE_RAST_PRIMITIVES_PRECLIP 0x00000080 +#define NV50_3D_COUNTER_ENABLE_RAST_PRIMITIVES_POSTCLIP 0x00000100 +#define NV50_3D_COUNTER_ENABLE_FP_PIXELS 0x00000200 +#define NV84_3D_COUNTER_ENABLE_UNK0A 0x00000400 + +#define NV50_3D_UNK0D6C(i0) (0x00000d6c + 0x4*(i0)) +#define NV50_3D_UNK0D6C__ESIZE 0x00000004 +#define NV50_3D_UNK0D6C__LEN 0x00000002 +#define NV50_3D_UNK0D6C_X__MASK 0x0000ffff +#define NV50_3D_UNK0D6C_X__SHIFT 0 +#define NV50_3D_UNK0D6C_Y__MASK 0xffff0000 +#define NV50_3D_UNK0D6C_Y__SHIFT 16 + +#define NV50_3D_VERTEX_BUFFER_FIRST 0x00000d74 + +#define NV50_3D_VERTEX_BUFFER_COUNT 0x00000d78 + +#define NV50_3D_UNK0D7C 0x00000d7c + +#define NV50_3D_CLEAR_COLOR(i0) (0x00000d80 + 0x4*(i0)) +#define NV50_3D_CLEAR_COLOR__ESIZE 0x00000004 +#define NV50_3D_CLEAR_COLOR__LEN 0x00000004 + +#define NV50_3D_CLEAR_DEPTH 0x00000d90 + +#define NV50_3D_STACK_ADDRESS_HIGH 0x00000d94 + +#define NV50_3D_STACK_ADDRESS_LOW 0x00000d98 + +#define NV50_3D_STACK_SIZE_LOG 0x00000d9c + +#define NV50_3D_CLEAR_STENCIL 0x00000da0 + +#define NV50_3D_STRMOUT_PARAMS_LATCH 0x00000da4 + +#define NV50_3D_STRMOUT_PRIMITIVE_LIMIT 0x00000da8 + +#define NV50_3D_POLYGON_MODE_FRONT 0x00000dac +#define NV50_3D_POLYGON_MODE_FRONT_POINT 0x00001b00 +#define NV50_3D_POLYGON_MODE_FRONT_LINE 0x00001b01 +#define NV50_3D_POLYGON_MODE_FRONT_FILL 0x00001b02 + +#define NV50_3D_POLYGON_MODE_BACK 0x00000db0 +#define NV50_3D_POLYGON_MODE_BACK_POINT 0x00001b00 +#define NV50_3D_POLYGON_MODE_BACK_LINE 0x00001b01 +#define NV50_3D_POLYGON_MODE_BACK_FILL 0x00001b02 + +#define NV50_3D_POLYGON_SMOOTH_ENABLE 0x00000db4 + +#define NV50_3D_UNK0DB8 0x00000db8 + +#define NV50_3D_ZCULL_UNK0DBC 0x00000dbc +#define NV50_3D_ZCULL_UNK0DBC_UNK0 0x00000001 +#define NV50_3D_ZCULL_UNK0DBC_UNK16__MASK 0x00030000 +#define NV50_3D_ZCULL_UNK0DBC_UNK16__SHIFT 16 + +#define NV50_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000dc0 + +#define NV50_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000dc4 + +#define NV50_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000dc8 + +#define NV50_3D_UNK0DCC 0x00000dcc + +#define NV50_3D_VTX_ATTR_MASK_UNK0DD0(i0) (0x00000dd0 + 0x4*(i0)) +#define NV50_3D_VTX_ATTR_MASK_UNK0DD0__ESIZE 0x00000004 +#define NV50_3D_VTX_ATTR_MASK_UNK0DD0__LEN 0x00000002 + +#define NV50_3D_ZCULL_UNK0DD8 0x00000dd8 +#define NV50_3D_ZCULL_UNK0DD8_UNK0__MASK 0x00000007 +#define NV50_3D_ZCULL_UNK0DD8_UNK0__SHIFT 0 +#define NVA3_3D_ZCULL_UNK0DD8_UNK9 0x00000200 +#define NV50_3D_ZCULL_UNK0DD8_UNK16__MASK 0xffff0000 +#define NV50_3D_ZCULL_UNK0DD8_UNK16__SHIFT 16 + +#define NV50_3D_UNK0DDC 0x00000ddc + +#define NV50_3D_UNK0DE0 0x00000de0 + +#define NV50_3D_WATCHDOG_TIMER 0x00000de4 + +#define NV50_3D_UNK0DE8 0x00000de8 + +#define NV50_3D_UNK0DEC 0x00000dec + +#define NV50_3D_UNK0DF0 0x00000df0 +#define NV50_3D_UNK0DF0_UNK0 0x00000001 +#define NV50_3D_UNK0DF0_UNK1__MASK 0x00000ff0 +#define NV50_3D_UNK0DF0_UNK1__SHIFT 4 + +#define NV50_3D_UNK0DF4 0x00000df4 + +#define NV50_3D_WINDOW_OFFSET_X 0x00000df8 + +#define NV50_3D_WINDOW_OFFSET_Y 0x00000dfc + +#define NV50_3D_SCISSOR_ENABLE(i0) (0x00000e00 + 0x10*(i0)) +#define NV50_3D_SCISSOR_ENABLE__ESIZE 0x00000010 +#define NV50_3D_SCISSOR_ENABLE__LEN 0x00000010 + +#define NV50_3D_SCISSOR_HORIZ(i0) (0x00000e04 + 0x10*(i0)) +#define NV50_3D_SCISSOR_HORIZ__ESIZE 0x00000010 +#define NV50_3D_SCISSOR_HORIZ__LEN 0x00000010 +#define NV50_3D_SCISSOR_HORIZ_MIN__MASK 0x0000ffff +#define NV50_3D_SCISSOR_HORIZ_MIN__SHIFT 0 +#define NV50_3D_SCISSOR_HORIZ_MAX__MASK 0xffff0000 +#define NV50_3D_SCISSOR_HORIZ_MAX__SHIFT 16 + +#define NV50_3D_SCISSOR_VERT(i0) (0x00000e08 + 0x10*(i0)) +#define NV50_3D_SCISSOR_VERT__ESIZE 0x00000010 +#define NV50_3D_SCISSOR_VERT__LEN 0x00000010 +#define NV50_3D_SCISSOR_VERT_MIN__MASK 0x0000ffff +#define NV50_3D_SCISSOR_VERT_MIN__SHIFT 0 +#define NV50_3D_SCISSOR_VERT_MAX__MASK 0xffff0000 +#define NV50_3D_SCISSOR_VERT_MAX__SHIFT 16 + +#define NV50_3D_CB_ADDR 0x00000f00 +#define NV50_3D_CB_ADDR_ID__MASK 0x003fff00 +#define NV50_3D_CB_ADDR_ID__SHIFT 8 +#define NV50_3D_CB_ADDR_BUFFER__MASK 0x0000007f +#define NV50_3D_CB_ADDR_BUFFER__SHIFT 0 + +#define NV50_3D_CB_DATA(i0) (0x00000f04 + 0x4*(i0)) +#define NV50_3D_CB_DATA__ESIZE 0x00000004 +#define NV50_3D_CB_DATA__LEN 0x00000010 + +#define NV50_3D_LOCAL_WARPS_LOG_ALLOC 0x00000f44 + +#define NV50_3D_LOCAL_WARPS_NO_CLAMP 0x00000f48 + +#define NV50_3D_STACK_WARPS_LOG_ALLOC 0x00000f4c + +#define NV50_3D_STACK_WARPS_NO_CLAMP 0x00000f50 + +#define NV50_3D_STENCIL_BACK_FUNC_REF 0x00000f54 + +#define NV50_3D_STENCIL_BACK_MASK 0x00000f58 + +#define NV50_3D_STENCIL_BACK_FUNC_MASK 0x00000f5c + +#define NV50_3D_UNK0F60(i0) (0x00000f60 + 0x4*(i0)) +#define NV50_3D_UNK0F60__ESIZE 0x00000004 +#define NV50_3D_UNK0F60__LEN 0x00000004 + +#define NV50_3D_GP_ADDRESS_HIGH 0x00000f70 + +#define NV50_3D_GP_ADDRESS_LOW 0x00000f74 + +#define NV50_3D_UNK0F78 0x00000f78 + +#define NV50_3D_VP_ADDRESS_HIGH 0x00000f7c + +#define NV50_3D_VP_ADDRESS_LOW 0x00000f80 + +#define NV50_3D_VERTEX_RUNOUT_ADDRESS_HIGH 0x00000f84 + +#define NV50_3D_VERTEX_RUNOUT_ADDRESS_LOW 0x00000f88 + +#define NV50_3D_UNK0F8C 0x00000f8c + +#define NV50_3D_UNK0F90 0x00000f90 + +#define NV50_3D_UNK0F94 0x00000f94 + +#define NV50_3D_UNK0F98 0x00000f98 + +#define NV50_3D_DEPTH_BOUNDS(i0) (0x00000f9c + 0x4*(i0)) +#define NV50_3D_DEPTH_BOUNDS__ESIZE 0x00000004 +#define NV50_3D_DEPTH_BOUNDS__LEN 0x00000002 + +#define NV50_3D_FP_ADDRESS_HIGH 0x00000fa4 + +#define NV50_3D_FP_ADDRESS_LOW 0x00000fa8 + +#define NV50_3D_UNK0FAC 0x00000fac +#define NV50_3D_UNK0FAC_UNK0 0x00000001 +#define NVA0_3D_UNK0FAC_UNK2 0x00000002 +#define NV50_3D_UNK0FAC_UNK1__MASK 0x000ffff0 +#define NV50_3D_UNK0FAC_UNK1__SHIFT 4 + +#define NV50_3D_UNK0FB0 0x00000fb0 + +#define NV50_3D_UNK0FB4 0x00000fb4 + +#define NV50_3D_UNK0FB8 0x00000fb8 + +#define NV50_3D_MSAA_MASK(i0) (0x00000fbc + 0x4*(i0)) +#define NV50_3D_MSAA_MASK__ESIZE 0x00000004 +#define NV50_3D_MSAA_MASK__LEN 0x00000004 + +#define NV50_3D_CLIPID_ADDRESS_HIGH 0x00000fcc + +#define NV50_3D_CLIPID_ADDRESS_LOW 0x00000fd0 + +#define NV50_3D_MAP_SEMANTIC_5 0x00000fd4 +#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__MASK 0x000000ff +#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__SHIFT 0 + +#define NV50_3D_UNK0FD8 0x00000fd8 +#define NV50_3D_UNK0FD8_UNK0 0x00000001 +#define NV50_3D_UNK0FD8_UNK1 0x00000010 + +#define NV50_3D_UNK0FDC 0x00000fdc + +#define NV50_3D_ZETA_ADDRESS_HIGH 0x00000fe0 + +#define NV50_3D_ZETA_ADDRESS_LOW 0x00000fe4 + +#define NV50_3D_ZETA_FORMAT 0x00000fe8 + +#define NV50_3D_ZETA_TILE_MODE 0x00000fec + +#define NV50_3D_ZETA_LAYER_STRIDE 0x00000ff0 +#define NV50_3D_ZETA_LAYER_STRIDE__SHR 2 + +#define NV50_3D_SCREEN_SCISSOR_HORIZ 0x00000ff4 +#define NV50_3D_SCREEN_SCISSOR_HORIZ_W__MASK 0xffff0000 +#define NV50_3D_SCREEN_SCISSOR_HORIZ_W__SHIFT 16 +#define NV50_3D_SCREEN_SCISSOR_HORIZ_X__MASK 0x0000ffff +#define NV50_3D_SCREEN_SCISSOR_HORIZ_X__SHIFT 0 + +#define NV50_3D_SCREEN_SCISSOR_VERT 0x00000ff8 +#define NV50_3D_SCREEN_SCISSOR_VERT_H__MASK 0xffff0000 +#define NV50_3D_SCREEN_SCISSOR_VERT_H__SHIFT 16 +#define NV50_3D_SCREEN_SCISSOR_VERT_Y__MASK 0x0000ffff +#define NV50_3D_SCREEN_SCISSOR_VERT_Y__SHIFT 0 + +#define NV50_3D_UNK0FFC 0x00000ffc + +#define NV50_3D_VERTEX_ARRAY_PER_INSTANCE(i0) (0x00001000 + 0x4*(i0)) +#define NV50_3D_VERTEX_ARRAY_PER_INSTANCE__ESIZE 0x00000004 +#define NV50_3D_VERTEX_ARRAY_PER_INSTANCE__LEN 0x00000010 + +#define NV50_3D_UNK1040(i0) (0x00001040 + 0x4*(i0)) +#define NV50_3D_UNK1040__ESIZE 0x00000004 +#define NV50_3D_UNK1040__LEN 0x00000010 + +#define NV50_3D_VERTEX_ARRAY_LIMIT_HIGH(i0) (0x00001080 + 0x8*(i0)) +#define NV50_3D_VERTEX_ARRAY_LIMIT_HIGH__ESIZE 0x00000008 +#define NV50_3D_VERTEX_ARRAY_LIMIT_HIGH__LEN 0x00000010 + +#define NV50_3D_VERTEX_ARRAY_LIMIT_LOW(i0) (0x00001084 + 0x8*(i0)) +#define NV50_3D_VERTEX_ARRAY_LIMIT_LOW__ESIZE 0x00000008 +#define NV50_3D_VERTEX_ARRAY_LIMIT_LOW__LEN 0x00000010 + +#define NV50_3D_UNK1100 0x00001100 + +#define NV84_3D_UNK1104 0x00001104 +#define NV84_3D_UNK1104_0__MASK 0x0000ffff +#define NV84_3D_UNK1104_0__SHIFT 0 +#define NV84_3D_UNK1104_0__MAX 0x00002000 +#define NV84_3D_UNK1104_0__ALIGN 0x00000040 +#define NV84_3D_UNK1104_1__MASK 0xffff0000 +#define NV84_3D_UNK1104_1__SHIFT 16 +#define NV84_3D_UNK1104_1__MAX 0x00002000 +#define NV84_3D_UNK1104_1__ALIGN 0x00000040 + +#define NV84_3D_UNK1108 0x00001108 +#define NV84_3D_UNK1108_0 0x00000001 +#define NV84_3D_UNK1108_1 0x00000010 + +#define NV84_3D_UNK110C 0x0000110c + +#define NV84_3D_UNK1110 0x00001110 + +#define NV84_3D_WRCACHE_FLUSH 0x00001114 + +#define NV84_3D_VERTEX_ID_BASE 0x00001118 + +#define NV84_3D_PRIMITIVE_ID 0x0000111c + +#define NVA3_3D_VTX_ATTR_MASK_UNK0DD0_ALT(i0) (0x00001120 + 0x4*(i0)) +#define NVA3_3D_VTX_ATTR_MASK_UNK0DD0_ALT__ESIZE 0x00000004 +#define NVA3_3D_VTX_ATTR_MASK_UNK0DD0_ALT__LEN 0x00000004 + +#define NVA3_3D_VP_ATTR_EN_ALT(i0) (0x00001130 + 0x4*(i0)) +#define NVA3_3D_VP_ATTR_EN_ALT__ESIZE 0x00000004 +#define NVA3_3D_VP_ATTR_EN_ALT__LEN 0x00000004 +#define NVA3_3D_VP_ATTR_EN_ALT_7__MASK 0xf0000000 +#define NVA3_3D_VP_ATTR_EN_ALT_7__SHIFT 28 +#define NVA3_3D_VP_ATTR_EN_ALT_7_X 0x10000000 +#define NVA3_3D_VP_ATTR_EN_ALT_7_Y 0x20000000 +#define NVA3_3D_VP_ATTR_EN_ALT_7_Z 0x40000000 +#define NVA3_3D_VP_ATTR_EN_ALT_7_W 0x80000000 +#define NVA3_3D_VP_ATTR_EN_ALT_6__MASK 0x0f000000 +#define NVA3_3D_VP_ATTR_EN_ALT_6__SHIFT 24 +#define NVA3_3D_VP_ATTR_EN_ALT_6_X 0x01000000 +#define NVA3_3D_VP_ATTR_EN_ALT_6_Y 0x02000000 +#define NVA3_3D_VP_ATTR_EN_ALT_6_Z 0x04000000 +#define NVA3_3D_VP_ATTR_EN_ALT_6_W 0x08000000 +#define NVA3_3D_VP_ATTR_EN_ALT_5__MASK 0x00f00000 +#define NVA3_3D_VP_ATTR_EN_ALT_5__SHIFT 20 +#define NVA3_3D_VP_ATTR_EN_ALT_5_X 0x00100000 +#define NVA3_3D_VP_ATTR_EN_ALT_5_Y 0x00200000 +#define NVA3_3D_VP_ATTR_EN_ALT_5_Z 0x00400000 +#define NVA3_3D_VP_ATTR_EN_ALT_5_W 0x00800000 +#define NVA3_3D_VP_ATTR_EN_ALT_4__MASK 0x000f0000 +#define NVA3_3D_VP_ATTR_EN_ALT_4__SHIFT 16 +#define NVA3_3D_VP_ATTR_EN_ALT_4_X 0x00010000 +#define NVA3_3D_VP_ATTR_EN_ALT_4_Y 0x00020000 +#define NVA3_3D_VP_ATTR_EN_ALT_4_Z 0x00040000 +#define NVA3_3D_VP_ATTR_EN_ALT_4_W 0x00080000 +#define NVA3_3D_VP_ATTR_EN_ALT_3__MASK 0x0000f000 +#define NVA3_3D_VP_ATTR_EN_ALT_3__SHIFT 12 +#define NVA3_3D_VP_ATTR_EN_ALT_3_X 0x00001000 +#define NVA3_3D_VP_ATTR_EN_ALT_3_Y 0x00002000 +#define NVA3_3D_VP_ATTR_EN_ALT_3_Z 0x00004000 +#define NVA3_3D_VP_ATTR_EN_ALT_3_W 0x00008000 +#define NVA3_3D_VP_ATTR_EN_ALT_2__MASK 0x00000f00 +#define NVA3_3D_VP_ATTR_EN_ALT_2__SHIFT 8 +#define NVA3_3D_VP_ATTR_EN_ALT_2_X 0x00000100 +#define NVA3_3D_VP_ATTR_EN_ALT_2_Y 0x00000200 +#define NVA3_3D_VP_ATTR_EN_ALT_2_Z 0x00000400 +#define NVA3_3D_VP_ATTR_EN_ALT_2_W 0x00000800 +#define NVA3_3D_VP_ATTR_EN_ALT_1__MASK 0x000000f0 +#define NVA3_3D_VP_ATTR_EN_ALT_1__SHIFT 4 +#define NVA3_3D_VP_ATTR_EN_ALT_1_X 0x00000010 +#define NVA3_3D_VP_ATTR_EN_ALT_1_Y 0x00000020 +#define NVA3_3D_VP_ATTR_EN_ALT_1_Z 0x00000040 +#define NVA3_3D_VP_ATTR_EN_ALT_1_W 0x00000080 +#define NVA3_3D_VP_ATTR_EN_ALT_0__MASK 0x0000000f +#define NVA3_3D_VP_ATTR_EN_ALT_0__SHIFT 0 +#define NVA3_3D_VP_ATTR_EN_ALT_0_X 0x00000001 +#define NVA3_3D_VP_ATTR_EN_ALT_0_Y 0x00000002 +#define NVA3_3D_VP_ATTR_EN_ALT_0_Z 0x00000004 +#define NVA3_3D_VP_ATTR_EN_ALT_0_W 0x00000008 + +#define NVA3_3D_UNK1140 0x00001140 + +#define NVA0_3D_UNK1144 0x00001144 + +#define NVA0_3D_VTX_ATTR_DEFINE 0x0000114c +#define NVA0_3D_VTX_ATTR_DEFINE_ATTR__MASK 0x000000ff +#define NVA0_3D_VTX_ATTR_DEFINE_ATTR__SHIFT 0 +#define NVA0_3D_VTX_ATTR_DEFINE_COMP__MASK 0x00000700 +#define NVA0_3D_VTX_ATTR_DEFINE_COMP__SHIFT 8 +#define NVA0_3D_VTX_ATTR_DEFINE_COMP__MIN 0x00000001 +#define NVA0_3D_VTX_ATTR_DEFINE_COMP__MAX 0x00000004 +#define NVA0_3D_VTX_ATTR_DEFINE_SIZE__MASK 0x00007000 +#define NVA0_3D_VTX_ATTR_DEFINE_SIZE__SHIFT 12 +#define NVA0_3D_VTX_ATTR_DEFINE_SIZE_8 0x00001000 +#define NVA0_3D_VTX_ATTR_DEFINE_SIZE_16 0x00002000 +#define NVA0_3D_VTX_ATTR_DEFINE_SIZE_32 0x00004000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE__MASK 0x00070000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE__SHIFT 16 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_SNORM 0x00010000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_UNORM 0x00020000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_SINT 0x00030000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_UINT 0x00040000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_USCALED 0x00050000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_SSCALED 0x00060000 +#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_FLOAT 0x00070000 + +#define NVA0_3D_VTX_ATTR_DATA(i0) (0x00001150 + 0x4*(i0)) +#define NVA0_3D_VTX_ATTR_DATA__ESIZE 0x00000004 +#define NVA0_3D_VTX_ATTR_DATA__LEN 0x00000004 + +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT(i0) (0x00001160 + 0x4*(i0)) +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT__ESIZE 0x00000004 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT__LEN 0x00000020 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_BUFFER__MASK 0x0000001f +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_BUFFER__SHIFT 0 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_CONST 0x00000040 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_OFFSET__MASK 0x001fff80 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_OFFSET__SHIFT 7 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT__MASK 0x07e00000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT__SHIFT 21 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32_32_32_32 0x00200000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32_32_32 0x00400000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16_16_16_16 0x00600000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32_32 0x00800000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16_16_16 0x00a00000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8_8_8_8 0x01400000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16_16 0x01e00000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32 0x02400000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8_8_8 0x02600000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8_8 0x03000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16 0x03600000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8 0x03a00000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_2_10_10_10 0x06000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE__MASK 0x38000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE__SHIFT 27 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_SNORM 0x08000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_UNORM 0x10000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_SINT 0x18000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_UINT 0x20000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_USCALED 0x28000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_SSCALED 0x30000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_FLOAT 0x38000000 +#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_BGRA 0x80000000 + +#define NV50_3D_RT_CONTROL 0x0000121c +#define NV50_3D_RT_CONTROL_COUNT__MASK 0x0000000f +#define NV50_3D_RT_CONTROL_COUNT__SHIFT 0 +#define NV50_3D_RT_CONTROL_MAP0__MASK 0x00000070 +#define NV50_3D_RT_CONTROL_MAP0__SHIFT 4 +#define NV50_3D_RT_CONTROL_MAP1__MASK 0x00000380 +#define NV50_3D_RT_CONTROL_MAP1__SHIFT 7 +#define NV50_3D_RT_CONTROL_MAP2__MASK 0x00001c00 +#define NV50_3D_RT_CONTROL_MAP2__SHIFT 10 +#define NV50_3D_RT_CONTROL_MAP3__MASK 0x0000e000 +#define NV50_3D_RT_CONTROL_MAP3__SHIFT 13 +#define NV50_3D_RT_CONTROL_MAP4__MASK 0x00070000 +#define NV50_3D_RT_CONTROL_MAP4__SHIFT 16 +#define NV50_3D_RT_CONTROL_MAP5__MASK 0x00380000 +#define NV50_3D_RT_CONTROL_MAP5__SHIFT 19 +#define NV50_3D_RT_CONTROL_MAP6__MASK 0x01c00000 +#define NV50_3D_RT_CONTROL_MAP6__SHIFT 22 +#define NV50_3D_RT_CONTROL_MAP7__MASK 0x0e000000 +#define NV50_3D_RT_CONTROL_MAP7__SHIFT 25 + +#define NV50_3D_UNK1220 0x00001220 + +#define NV50_3D_RT_ARRAY_MODE 0x00001224 +#define NV50_3D_RT_ARRAY_MODE_LAYERS__MASK 0x0000ffff +#define NV50_3D_RT_ARRAY_MODE_LAYERS__SHIFT 0 +#define NV50_3D_RT_ARRAY_MODE_MODE__MASK 0x00010000 +#define NV50_3D_RT_ARRAY_MODE_MODE__SHIFT 16 +#define NV50_3D_RT_ARRAY_MODE_MODE_2D_ARRAY 0x00000000 +#define NV50_3D_RT_ARRAY_MODE_MODE_3D 0x00010000 + +#define NV50_3D_ZETA_HORIZ 0x00001228 + +#define NV50_3D_ZETA_VERT 0x0000122c + +#define NV50_3D_ZETA_ARRAY_MODE 0x00001230 +#define NV50_3D_ZETA_ARRAY_MODE_LAYERS__MASK 0x0000ffff +#define NV50_3D_ZETA_ARRAY_MODE_LAYERS__SHIFT 0 +#define NV50_3D_ZETA_ARRAY_MODE_UNK 0x00010000 + +#define NV50_3D_LINKED_TSC 0x00001234 + +#define NV50_3D_UNK1238 0x00001238 + +#define NVA0_3D_DRAW_TFB_BYTES 0x0000123c + +#define NV50_3D_RT_HORIZ(i0) (0x00001240 + 0x8*(i0)) +#define NV50_3D_RT_HORIZ__ESIZE 0x00000008 +#define NV50_3D_RT_HORIZ__LEN 0x00000008 +#define NV50_3D_RT_HORIZ_WIDTH__MASK 0x0fffffff +#define NV50_3D_RT_HORIZ_WIDTH__SHIFT 0 +#define NV50_3D_RT_HORIZ_LINEAR 0x80000000 + +#define NV50_3D_RT_VERT(i0) (0x00001244 + 0x8*(i0)) +#define NV50_3D_RT_VERT__ESIZE 0x00000008 +#define NV50_3D_RT_VERT__LEN 0x00000008 + +#define NV50_3D_CB_DEF_ADDRESS_HIGH 0x00001280 + +#define NV50_3D_CB_DEF_ADDRESS_LOW 0x00001284 + +#define NV50_3D_CB_DEF_SET 0x00001288 +#define NV50_3D_CB_DEF_SET_SIZE__MASK 0x0000ffff +#define NV50_3D_CB_DEF_SET_SIZE__SHIFT 0 +#define NV50_3D_CB_DEF_SET_BUFFER__MASK 0x007f0000 +#define NV50_3D_CB_DEF_SET_BUFFER__SHIFT 16 + +#define NV50_3D_UNK128C 0x0000128c +#define NV50_3D_UNK128C_0__MASK 0x00000003 +#define NV50_3D_UNK128C_0__SHIFT 0 +#define NV50_3D_UNK128C_1__MASK 0x00000030 +#define NV50_3D_UNK128C_1__SHIFT 4 +#define NV50_3D_UNK128C_2__MASK 0x00000300 +#define NV50_3D_UNK128C_2__SHIFT 8 +#define NV50_3D_UNK128C_3__MASK 0x00003000 +#define NV50_3D_UNK128C_3__SHIFT 12 + +#define NV50_3D_CALL_LIMIT_LOG 0x00001290 +#define NV50_3D_CALL_LIMIT_LOG_VP__MASK 0x0000000f +#define NV50_3D_CALL_LIMIT_LOG_VP__SHIFT 0 +#define NV50_3D_CALL_LIMIT_LOG_GP__MASK 0x000000f0 +#define NV50_3D_CALL_LIMIT_LOG_GP__SHIFT 4 +#define NV50_3D_CALL_LIMIT_LOG_FP__MASK 0x00000f00 +#define NV50_3D_CALL_LIMIT_LOG_FP__SHIFT 8 + +#define NV50_3D_STRMOUT_BUFFERS_CTRL 0x00001294 +#define NV50_3D_STRMOUT_BUFFERS_CTRL_INTERLEAVED 0x00000001 +#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE__MASK 0x00000002 +#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE__SHIFT 1 +#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE_PRIMITIVES 0x00000000 +#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE_OFFSET 0x00000002 +#define NV50_3D_STRMOUT_BUFFERS_CTRL_SEPARATE__MASK 0x000000f0 +#define NV50_3D_STRMOUT_BUFFERS_CTRL_SEPARATE__SHIFT 4 +#define NV50_3D_STRMOUT_BUFFERS_CTRL_STRIDE__MASK 0x000fff00 +#define NV50_3D_STRMOUT_BUFFERS_CTRL_STRIDE__SHIFT 8 +#define NV50_3D_STRMOUT_BUFFERS_CTRL_STRIDE__MAX 0x00000800 + +#define NV50_3D_FP_RESULT_COUNT 0x00001298 + +#define NV50_3D_VTX_UNK129C 0x0000129c + +#define NV50_3D_UNK12A0 0x000012a0 + +#define NV50_3D_UNK12A8 0x000012a8 +#define NV50_3D_UNK12A8_UNK1 0x00000001 +#define NV50_3D_UNK12A8_UNK2__MASK 0x000ffff0 +#define NV50_3D_UNK12A8_UNK2__SHIFT 4 + +#define NV50_3D_UNK12AC 0x000012ac + +#define NV50_3D_UNK12B0 0x000012b0 +#define NV50_3D_UNK12B0_UNK0__MASK 0x000000ff +#define NV50_3D_UNK12B0_UNK0__SHIFT 0 +#define NV50_3D_UNK12B0_UNK1__MASK 0x0000ff00 +#define NV50_3D_UNK12B0_UNK1__SHIFT 8 +#define NV50_3D_UNK12B0_UNK2__MASK 0x00ff0000 +#define NV50_3D_UNK12B0_UNK2__SHIFT 16 +#define NV50_3D_UNK12B0_UNK3__MASK 0xff000000 +#define NV50_3D_UNK12B0_UNK3__SHIFT 24 +#define NV50_3D_UNK12B0_UNK3__MAX 0x00000080 + +#define NV50_3D_UNK12B4 0x000012b4 + +#define NV50_3D_UNK12B8 0x000012b8 + +#define NV50_3D_DEPTH_TEST_ENABLE 0x000012cc + +#define NV50_3D_D3D_FILL_MODE 0x000012d0 +#define NV50_3D_D3D_FILL_MODE_POINT 0x00000001 +#define NV50_3D_D3D_FILL_MODE_WIREFRAME 0x00000002 +#define NV50_3D_D3D_FILL_MODE_SOLID 0x00000003 + +#define NV50_3D_SHADE_MODEL 0x000012d4 +#define NV50_3D_SHADE_MODEL_FLAT 0x00001d00 +#define NV50_3D_SHADE_MODEL_SMOOTH 0x00001d01 + +#define NV50_3D_LOCAL_ADDRESS_HIGH 0x000012d8 + +#define NV50_3D_LOCAL_ADDRESS_LOW 0x000012dc + +#define NV50_3D_LOCAL_SIZE_LOG 0x000012e0 + +#define NV50_3D_BLEND_INDEPENDENT 0x000012e4 + +#define NV50_3D_DEPTH_WRITE_ENABLE 0x000012e8 + +#define NV50_3D_ALPHA_TEST_ENABLE 0x000012ec + +#define NV50_3D_PM_SET(i0) (0x000012f0 + 0x4*(i0)) +#define NV50_3D_PM_SET__ESIZE 0x00000004 +#define NV50_3D_PM_SET__LEN 0x00000004 + +#define NV50_3D_VB_ELEMENT_U8_SETUP 0x00001300 +#define NV50_3D_VB_ELEMENT_U8_SETUP_OFFSET__MASK 0xc0000000 +#define NV50_3D_VB_ELEMENT_U8_SETUP_OFFSET__SHIFT 30 +#define NV50_3D_VB_ELEMENT_U8_SETUP_COUNT__MASK 0x3fffffff +#define NV50_3D_VB_ELEMENT_U8_SETUP_COUNT__SHIFT 0 + +#define NV50_3D_VB_ELEMENT_U8 0x00001304 +#define NV50_3D_VB_ELEMENT_U8_I0__MASK 0x000000ff +#define NV50_3D_VB_ELEMENT_U8_I0__SHIFT 0 +#define NV50_3D_VB_ELEMENT_U8_I1__MASK 0x0000ff00 +#define NV50_3D_VB_ELEMENT_U8_I1__SHIFT 8 +#define NV50_3D_VB_ELEMENT_U8_I2__MASK 0x00ff0000 +#define NV50_3D_VB_ELEMENT_U8_I2__SHIFT 16 +#define NV50_3D_VB_ELEMENT_U8_I3__MASK 0xff000000 +#define NV50_3D_VB_ELEMENT_U8_I3__SHIFT 24 + +#define NV50_3D_D3D_CULL_MODE 0x00001308 +#define NV50_3D_D3D_CULL_MODE_NONE 0x00000001 +#define NV50_3D_D3D_CULL_MODE_FRONT 0x00000002 +#define NV50_3D_D3D_CULL_MODE_BACK 0x00000003 + +#define NV50_3D_DEPTH_TEST_FUNC 0x0000130c +#define NV50_3D_DEPTH_TEST_FUNC_NEVER 0x00000200 +#define NV50_3D_DEPTH_TEST_FUNC_LESS 0x00000201 +#define NV50_3D_DEPTH_TEST_FUNC_EQUAL 0x00000202 +#define NV50_3D_DEPTH_TEST_FUNC_LEQUAL 0x00000203 +#define NV50_3D_DEPTH_TEST_FUNC_GREATER 0x00000204 +#define NV50_3D_DEPTH_TEST_FUNC_NOTEQUAL 0x00000205 +#define NV50_3D_DEPTH_TEST_FUNC_GEQUAL 0x00000206 +#define NV50_3D_DEPTH_TEST_FUNC_ALWAYS 0x00000207 + +#define NV50_3D_ALPHA_TEST_REF 0x00001310 + +#define NV50_3D_ALPHA_TEST_FUNC 0x00001314 +#define NV50_3D_ALPHA_TEST_FUNC_NEVER 0x00000200 +#define NV50_3D_ALPHA_TEST_FUNC_LESS 0x00000201 +#define NV50_3D_ALPHA_TEST_FUNC_EQUAL 0x00000202 +#define NV50_3D_ALPHA_TEST_FUNC_LEQUAL 0x00000203 +#define NV50_3D_ALPHA_TEST_FUNC_GREATER 0x00000204 +#define NV50_3D_ALPHA_TEST_FUNC_NOTEQUAL 0x00000205 +#define NV50_3D_ALPHA_TEST_FUNC_GEQUAL 0x00000206 +#define NV50_3D_ALPHA_TEST_FUNC_ALWAYS 0x00000207 + +#define NVA0_3D_DRAW_TFB_STRIDE 0x00001318 +#define NVA0_3D_DRAW_TFB_STRIDE__MIN 0x00000001 +#define NVA0_3D_DRAW_TFB_STRIDE__MAX 0x00000fff + +#define NV50_3D_BLEND_COLOR(i0) (0x0000131c + 0x4*(i0)) +#define NV50_3D_BLEND_COLOR__ESIZE 0x00000004 +#define NV50_3D_BLEND_COLOR__LEN 0x00000004 + +#define NV50_3D_UNK132C 0x0000132c + +#define NV50_3D_TSC_FLUSH 0x00001330 +#define NV50_3D_TSC_FLUSH_SPECIFIC 0x00000001 +#define NV50_3D_TSC_FLUSH_ENTRY__MASK 0x03fffff0 +#define NV50_3D_TSC_FLUSH_ENTRY__SHIFT 4 + +#define NV50_3D_TIC_FLUSH 0x00001334 +#define NV50_3D_TIC_FLUSH_SPECIFIC 0x00000001 +#define NV50_3D_TIC_FLUSH_ENTRY__MASK 0x03fffff0 +#define NV50_3D_TIC_FLUSH_ENTRY__SHIFT 4 + +#define NV50_3D_TEX_CACHE_CTL 0x00001338 +#define NV50_3D_TEX_CACHE_CTL_UNK1__MASK 0x00000030 +#define NV50_3D_TEX_CACHE_CTL_UNK1__SHIFT 4 + +#define NV50_3D_UNK133C 0x0000133c + +#define NV50_3D_BLEND_EQUATION_RGB 0x00001340 +#define NV50_3D_BLEND_EQUATION_RGB_FUNC_ADD 0x00008006 +#define NV50_3D_BLEND_EQUATION_RGB_MIN 0x00008007 +#define NV50_3D_BLEND_EQUATION_RGB_MAX 0x00008008 +#define NV50_3D_BLEND_EQUATION_RGB_FUNC_SUBTRACT 0x0000800a +#define NV50_3D_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT 0x0000800b + +#define NV50_3D_BLEND_FUNC_SRC_RGB 0x00001344 + +#define NV50_3D_BLEND_FUNC_DST_RGB 0x00001348 + +#define NV50_3D_BLEND_EQUATION_ALPHA 0x0000134c +#define NV50_3D_BLEND_EQUATION_ALPHA_FUNC_ADD 0x00008006 +#define NV50_3D_BLEND_EQUATION_ALPHA_MIN 0x00008007 +#define NV50_3D_BLEND_EQUATION_ALPHA_MAX 0x00008008 +#define NV50_3D_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT 0x0000800a +#define NV50_3D_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT 0x0000800b + +#define NV50_3D_BLEND_FUNC_SRC_ALPHA 0x00001350 + +#define NV50_3D_UNK1354 0x00001354 + +#define NV50_3D_BLEND_FUNC_DST_ALPHA 0x00001358 + +#define NV50_3D_UNK135C 0x0000135c + +#define NV50_3D_BLEND_ENABLE(i0) (0x00001360 + 0x4*(i0)) +#define NV50_3D_BLEND_ENABLE__ESIZE 0x00000004 +#define NV50_3D_BLEND_ENABLE__LEN 0x00000008 + +#define NV50_3D_STENCIL_ENABLE 0x00001380 + +#define NV50_3D_STENCIL_FRONT_OP_FAIL 0x00001384 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_ZERO 0x00000000 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_INVERT 0x0000150a +#define NV50_3D_STENCIL_FRONT_OP_FAIL_KEEP 0x00001e00 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_REPLACE 0x00001e01 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_INCR 0x00001e02 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_DECR 0x00001e03 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_INCR_WRAP 0x00008507 +#define NV50_3D_STENCIL_FRONT_OP_FAIL_DECR_WRAP 0x00008508 + +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL 0x00001388 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_ZERO 0x00000000 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_INVERT 0x0000150a +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_KEEP 0x00001e00 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_REPLACE 0x00001e01 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_INCR 0x00001e02 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_DECR 0x00001e03 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP 0x00008508 + +#define NV50_3D_STENCIL_FRONT_OP_ZPASS 0x0000138c +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_ZERO 0x00000000 +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_INVERT 0x0000150a +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_KEEP 0x00001e00 +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_REPLACE 0x00001e01 +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_INCR 0x00001e02 +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_DECR 0x00001e03 +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV50_3D_STENCIL_FRONT_OP_ZPASS_DECR_WRAP 0x00008508 + +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC 0x00001390 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_NEVER 0x00000200 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_LESS 0x00000201 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_EQUAL 0x00000202 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_LEQUAL 0x00000203 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_GEQUAL 0x00000206 +#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_ALWAYS 0x00000207 + +#define NV50_3D_STENCIL_FRONT_FUNC_REF 0x00001394 + +#define NV50_3D_STENCIL_FRONT_MASK 0x00001398 + +#define NV50_3D_STENCIL_FRONT_FUNC_MASK 0x0000139c + +#define NV50_3D_UNK13A0 0x000013a0 + +#define NVA0_3D_DRAW_TFB_BASE 0x000013a4 + +#define NV50_3D_FRAG_COLOR_CLAMP_EN 0x000013a8 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_0 0x00000001 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_1 0x00000010 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_2 0x00000100 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_3 0x00001000 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_4 0x00010000 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_5 0x00100000 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_6 0x01000000 +#define NV50_3D_FRAG_COLOR_CLAMP_EN_7 0x10000000 + +#define NV50_3D_SCREEN_Y_CONTROL 0x000013ac +#define NV50_3D_SCREEN_Y_CONTROL_Y_NEGATE 0x00000001 +#define NV50_3D_SCREEN_Y_CONTROL_TRIANGLE_RAST_FLIP 0x00000010 + +#define NV50_3D_LINE_WIDTH 0x000013b0 + +#define NV50_3D_TEX_LIMITS(i0) (0x000013b4 + 0x4*(i0)) +#define NV50_3D_TEX_LIMITS__ESIZE 0x00000004 +#define NV50_3D_TEX_LIMITS__LEN 0x00000003 +#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__MASK 0x0000000f +#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__SHIFT 0 +#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__MIN 0x00000000 +#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__MAX 0x00000004 +#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__MASK 0x000000f0 +#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__SHIFT 4 +#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__MIN 0x00000000 +#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__MAX 0x00000007 + +#define NV50_3D_POINT_COORD_REPLACE_MAP(i0) (0x000013c0 + 0x4*(i0)) +#define NV50_3D_POINT_COORD_REPLACE_MAP__ESIZE 0x00000004 +#define NV50_3D_POINT_COORD_REPLACE_MAP__LEN 0x00000010 + +#define NV50_3D_UNK1400_LANES 0x00001400 + +#define NV50_3D_UNK1404 0x00001404 + +#define NV50_3D_UNK1408 0x00001408 + +#define NV50_3D_VP_START_ID 0x0000140c + +#define NV50_3D_GP_START_ID 0x00001410 + +#define NV50_3D_FP_START_ID 0x00001414 + +#define NVA3_3D_UNK1418 0x00001418 + +#define NV50_3D_UNK141C 0x0000141c + +#define NV50_3D_GP_VERTEX_OUTPUT_COUNT 0x00001420 +#define NV50_3D_GP_VERTEX_OUTPUT_COUNT__MIN 0x00000001 +#define NV50_3D_GP_VERTEX_OUTPUT_COUNT__MAX 0x00000400 + +#define NV50_3D_VERTEX_ARRAY_FLUSH 0x0000142c + +#define NV50_3D_UNK1430 0x00001430 +#define NV50_3D_UNK1430_UNK0 0x00000010 +#define NV50_3D_UNK1430_UNK1 0x00000100 + +#define NV50_3D_VB_ELEMENT_BASE 0x00001434 + +#define NV50_3D_VB_INSTANCE_BASE 0x00001438 + +#define NV50_3D_CLEAR_FLAGS 0x0000143c +#define NV50_3D_CLEAR_FLAGS_STENCIL_MASK 0x00000001 +#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT__MASK 0x00000010 +#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT__SHIFT 4 +#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT_SCISSOR 0x00000000 +#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT 0x00000010 + +#define NV50_3D_CODE_CB_FLUSH 0x00001440 + +#define NV50_3D_BIND_TSC(i0) (0x00001444 + 0x8*(i0)) +#define NV50_3D_BIND_TSC__ESIZE 0x00000008 +#define NV50_3D_BIND_TSC__LEN 0x00000003 +#define NV50_3D_BIND_TSC_VALID 0x00000001 +#define NV50_3D_BIND_TSC_SAMPLER__MASK 0x000000f0 +#define NV50_3D_BIND_TSC_SAMPLER__SHIFT 4 +#define NV50_3D_BIND_TSC_TSC__MASK 0x001ff000 +#define NV50_3D_BIND_TSC_TSC__SHIFT 12 + +#define NV50_3D_BIND_TIC(i0) (0x00001448 + 0x8*(i0)) +#define NV50_3D_BIND_TIC__ESIZE 0x00000008 +#define NV50_3D_BIND_TIC__LEN 0x00000003 +#define NV50_3D_BIND_TIC_VALID 0x00000001 +#define NV50_3D_BIND_TIC_TEXTURE__MASK 0x000001fe +#define NV50_3D_BIND_TIC_TEXTURE__SHIFT 1 +#define NV50_3D_BIND_TIC_TIC__MASK 0x7ffffe00 +#define NV50_3D_BIND_TIC_TIC__SHIFT 9 + +#define NV50_3D_BIND_TSC2(i0) (0x00001468 + 0x8*(i0)) +#define NV50_3D_BIND_TSC2__ESIZE 0x00000008 +#define NV50_3D_BIND_TSC2__LEN 0x00000003 +#define NV50_3D_BIND_TSC2_VALID 0x00000001 +#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x000000f0 +#define NV50_3D_BIND_TSC2_SAMPLER__SHIFT 4 +#define NV50_3D_BIND_TSC2_TSC__MASK 0x001ff000 +#define NV50_3D_BIND_TSC2_TSC__SHIFT 12 + +#define NV50_3D_BIND_TIC2(i0) (0x0000146c + 0x8*(i0)) +#define NV50_3D_BIND_TIC2__ESIZE 0x00000008 +#define NV50_3D_BIND_TIC2__LEN 0x00000003 +#define NV50_3D_BIND_TIC2_VALID 0x00000001 +#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x000001fe +#define NV50_3D_BIND_TIC2_TEXTURE__SHIFT 1 +#define NV50_3D_BIND_TIC2_TIC__MASK 0x7ffffe00 +#define NV50_3D_BIND_TIC2_TIC__SHIFT 9 + +#define NV50_3D_STRMOUT_MAP(i0) (0x00001480 + 0x4*(i0)) +#define NV50_3D_STRMOUT_MAP__ESIZE 0x00000004 +#define NV50_3D_STRMOUT_MAP__LEN 0x00000020 + +#define NV50_3D_CLIPID_HEIGHT 0x00001504 +#define NV50_3D_CLIPID_HEIGHT__MAX 0x00002000 + +#define NV50_3D_CLIPID_FILL_RECT_HORIZ 0x00001508 +#define NV50_3D_CLIPID_FILL_RECT_HORIZ_LOW__MASK 0x0000ffff +#define NV50_3D_CLIPID_FILL_RECT_HORIZ_LOW__SHIFT 0 +#define NV50_3D_CLIPID_FILL_RECT_HORIZ_HIGH__MASK 0xffff0000 +#define NV50_3D_CLIPID_FILL_RECT_HORIZ_HIGH__SHIFT 16 + +#define NV50_3D_CLIPID_FILL_RECT_VERT 0x0000150c +#define NV50_3D_CLIPID_FILL_RECT_VERT_LOW__MASK 0x0000ffff +#define NV50_3D_CLIPID_FILL_RECT_VERT_LOW__SHIFT 0 +#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK 0xffff0000 +#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT 16 + +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE 0x00001510 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_0 0x00000001 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_1 0x00000002 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_2 0x00000004 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_3 0x00000008 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_4 0x00000010 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_5 0x00000020 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_6 0x00000040 +#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_7 0x00000080 + +#define NV50_3D_SAMPLECNT_ENABLE 0x00001514 + +#define NV50_3D_POINT_SIZE 0x00001518 + +#define NV50_3D_ZCULL_STATCTRS_ENABLE 0x0000151c + +#define NV50_3D_POINT_SPRITE_ENABLE 0x00001520 + +#define NVA0_3D_UNK152C 0x0000152c +#define NVA0_3D_UNK152C_UNK0 0x00000001 +#define NVA0_3D_UNK152C_UNK1 0x00000010 +#define NVA0_3D_UNK152C_UNK2 0x00000100 +#define NVA0_3D_UNK152C_UNK3__MASK 0x000ff000 +#define NVA0_3D_UNK152C_UNK3__SHIFT 12 +#define NVA0_3D_UNK152C_UNK3__MAX 0x00000028 + +#define NV50_3D_COUNTER_RESET 0x00001530 +#define NV50_3D_COUNTER_RESET_SAMPLECNT 0x00000001 +#define NV50_3D_COUNTER_RESET_ZCULL_STATS 0x00000002 +#define NVA0_3D_COUNTER_RESET_STRMOUT_VERTICES 0x00000008 +#define NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK 0x00000010 +#define NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES 0x00000011 +#define NV50_3D_COUNTER_RESET_VFETCH_VERTICES 0x00000012 +#define NV50_3D_COUNTER_RESET_VFETCH_PRIMITIVES 0x00000013 +#define NV50_3D_COUNTER_RESET_VP_LAUNCHES 0x00000015 +#define NV50_3D_COUNTER_RESET_GP_LAUNCHES 0x0000001a +#define NV50_3D_COUNTER_RESET_GP_PRIMITIVES_OUT 0x0000001b +#define NV50_3D_COUNTER_RESET_RAST_PRIMITIVES_PRECLIP 0x0000001c +#define NV50_3D_COUNTER_RESET_RAST_PRIMITIVES_POSTCLIP 0x0000001d +#define NV50_3D_COUNTER_RESET_FP_PIXELS 0x0000001e + +#define NV50_3D_MULTISAMPLE_ENABLE 0x00001534 + +#define NV50_3D_ZETA_ENABLE 0x00001538 + +#define NV50_3D_MULTISAMPLE_CTRL 0x0000153c +#define NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE 0x00000001 +#define NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE 0x00000010 + +#define NV50_3D_NOPERSPECTIVE_BITMAP(i0) (0x00001540 + 0x4*(i0)) +#define NV50_3D_NOPERSPECTIVE_BITMAP__ESIZE 0x00000004 +#define NV50_3D_NOPERSPECTIVE_BITMAP__LEN 0x00000004 + +#define NV50_3D_COND_ADDRESS_HIGH 0x00001550 + +#define NV50_3D_COND_ADDRESS_LOW 0x00001554 + +#define NV50_3D_COND_MODE 0x00001558 +#define NV50_3D_COND_MODE_NEVER 0x00000000 +#define NV50_3D_COND_MODE_ALWAYS 0x00000001 +#define NV50_3D_COND_MODE_RES_NON_ZERO 0x00000002 +#define NV50_3D_COND_MODE_EQUAL 0x00000003 +#define NV50_3D_COND_MODE_NOT_EQUAL 0x00000004 + +#define NV50_3D_TSC_ADDRESS_HIGH 0x0000155c + +#define NV50_3D_TSC_ADDRESS_LOW 0x00001560 +#define NV50_3D_TSC_ADDRESS_LOW__ALIGN 0x00000020 + +#define NV50_3D_TSC_LIMIT 0x00001564 +#define NV50_3D_TSC_LIMIT__MAX 0x00001fff + +#define NV50_3D_UNK1568 0x00001568 + +#define NV50_3D_POLYGON_OFFSET_FACTOR 0x0000156c + +#define NV50_3D_LINE_SMOOTH_ENABLE 0x00001570 + +#define NV50_3D_TIC_ADDRESS_HIGH 0x00001574 + +#define NV50_3D_TIC_ADDRESS_LOW 0x00001578 + +#define NV50_3D_TIC_LIMIT 0x0000157c + +#define NV50_3D_PM_CONTROL(i0) (0x00001580 + 0x4*(i0)) +#define NV50_3D_PM_CONTROL__ESIZE 0x00000004 +#define NV50_3D_PM_CONTROL__LEN 0x00000004 +#define NV50_3D_PM_CONTROL_UNK0 0x00000001 +#define NV50_3D_PM_CONTROL_UNK1__MASK 0x00000070 +#define NV50_3D_PM_CONTROL_UNK1__SHIFT 4 +#define NV50_3D_PM_CONTROL_UNK2__MASK 0x00ffff00 +#define NV50_3D_PM_CONTROL_UNK2__SHIFT 8 +#define NV50_3D_PM_CONTROL_UNK3__MASK 0xff000000 +#define NV50_3D_PM_CONTROL_UNK3__SHIFT 24 + +#define NV50_3D_ZCULL_REGION 0x00001590 + +#define NV50_3D_STENCIL_TWO_SIDE_ENABLE 0x00001594 + +#define NV50_3D_STENCIL_BACK_OP_FAIL 0x00001598 +#define NV50_3D_STENCIL_BACK_OP_FAIL_ZERO 0x00000000 +#define NV50_3D_STENCIL_BACK_OP_FAIL_INVERT 0x0000150a +#define NV50_3D_STENCIL_BACK_OP_FAIL_KEEP 0x00001e00 +#define NV50_3D_STENCIL_BACK_OP_FAIL_REPLACE 0x00001e01 +#define NV50_3D_STENCIL_BACK_OP_FAIL_INCR 0x00001e02 +#define NV50_3D_STENCIL_BACK_OP_FAIL_DECR 0x00001e03 +#define NV50_3D_STENCIL_BACK_OP_FAIL_INCR_WRAP 0x00008507 +#define NV50_3D_STENCIL_BACK_OP_FAIL_DECR_WRAP 0x00008508 + +#define NV50_3D_STENCIL_BACK_OP_ZFAIL 0x0000159c +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_ZERO 0x00000000 +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_INVERT 0x0000150a +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_KEEP 0x00001e00 +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_REPLACE 0x00001e01 +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_INCR 0x00001e02 +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_DECR 0x00001e03 +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV50_3D_STENCIL_BACK_OP_ZFAIL_DECR_WRAP 0x00008508 + +#define NV50_3D_STENCIL_BACK_OP_ZPASS 0x000015a0 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_ZERO 0x00000000 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_INVERT 0x0000150a +#define NV50_3D_STENCIL_BACK_OP_ZPASS_KEEP 0x00001e00 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_REPLACE 0x00001e01 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_INCR 0x00001e02 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_DECR 0x00001e03 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV50_3D_STENCIL_BACK_OP_ZPASS_DECR_WRAP 0x00008508 + +#define NV50_3D_STENCIL_BACK_FUNC_FUNC 0x000015a4 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_NEVER 0x00000200 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_LESS 0x00000201 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_EQUAL 0x00000202 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_LEQUAL 0x00000203 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 +#define NV50_3D_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 + +#define NV50_3D_UNK15A8 0x000015a8 +#define NV50_3D_UNK15A8_UNK1__MASK 0x00000007 +#define NV50_3D_UNK15A8_UNK1__SHIFT 0 +#define NV50_3D_UNK15A8_UNK2__MASK 0x00000070 +#define NV50_3D_UNK15A8_UNK2__SHIFT 4 + +#define NV50_3D_UNK15AC 0x000015ac + +#define NV50_3D_UNK15B0 0x000015b0 +#define NV50_3D_UNK15B0_0 0x00000001 +#define NV50_3D_UNK15B0_1 0x00000010 +#define NV50_3D_UNK15B0_2 0x00000100 + +#define NV50_3D_CSAA_ENABLE 0x000015b4 + +#define NV50_3D_FRAMEBUFFER_SRGB 0x000015b8 + +#define NV50_3D_POLYGON_OFFSET_UNITS 0x000015bc + +#define NVA3_3D_UNK15C4 0x000015c4 + +#define NVA3_3D_UNK15C8 0x000015c8 + +#define NV50_3D_LAYER 0x000015cc +#define NV50_3D_LAYER_IDX__MASK 0x0000ffff +#define NV50_3D_LAYER_IDX__SHIFT 0 +#define NV50_3D_LAYER_USE_GP 0x00010000 + +#define NV50_3D_MULTISAMPLE_MODE 0x000015d0 +#define NV50_3D_MULTISAMPLE_MODE_MS1 0x00000000 +#define NV50_3D_MULTISAMPLE_MODE_MS2 0x00000001 +#define NV50_3D_MULTISAMPLE_MODE_MS4 0x00000002 +#define NV50_3D_MULTISAMPLE_MODE_MS8 0x00000003 +#define NV50_3D_MULTISAMPLE_MODE_MS8_ALT 0x00000004 +#define NV50_3D_MULTISAMPLE_MODE_MS2_ALT 0x00000005 +#define NV50_3D_MULTISAMPLE_MODE_MS4_CS4 0x00000008 +#define NV50_3D_MULTISAMPLE_MODE_MS4_CS12 0x00000009 +#define NV50_3D_MULTISAMPLE_MODE_MS8_CS8 0x0000000a + +#define NV50_3D_VERTEX_BEGIN_D3D 0x000015d4 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK 0x0fffffff +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__SHIFT 0 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_POINTS 0x00000001 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINES 0x00000002 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINE_STRIP 0x00000003 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLES 0x00000004 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLE_STRIP 0x00000005 +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINES_ADJACENCY 0x0000000a +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINE_STRIP_ADJACENCY 0x0000000b +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLES_ADJACENCY 0x0000000c +#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLE_STRIP_ADJACENCY 0x0000000d +#define NV50_3D_VERTEX_BEGIN_D3D_INSTANCE_NEXT 0x10000000 +#define NV84_3D_VERTEX_BEGIN_D3D_PRIMITIVE_ID_CONT 0x20000000 +#define NVA0_3D_VERTEX_BEGIN_D3D_INSTANCE_CONT 0x40000000 + +#define NV50_3D_VERTEX_END_D3D 0x000015d8 +#define NV50_3D_VERTEX_END_D3D_UNK0 0x00000001 +#define NVA0_3D_VERTEX_END_D3D_UNK1 0x00000002 + +#define NV50_3D_VERTEX_BEGIN_GL 0x000015dc +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE__MASK 0x0fffffff +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE__SHIFT 0 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS 0x00000000 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINES 0x00000001 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINE_LOOP 0x00000002 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINE_STRIP 0x00000003 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES 0x00000004 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLE_STRIP 0x00000005 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLE_FAN 0x00000006 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_QUADS 0x00000007 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_QUAD_STRIP 0x00000008 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POLYGON 0x00000009 +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINES_ADJACENCY 0x0000000a +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINE_STRIP_ADJACENCY 0x0000000b +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES_ADJACENCY 0x0000000c +#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLE_STRIP_ADJACENCY 0x0000000d +#define NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT 0x10000000 +#define NV84_3D_VERTEX_BEGIN_GL_PRIMITIVE_ID_CONT 0x20000000 +#define NVA0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT 0x40000000 + +#define NV50_3D_VERTEX_END_GL 0x000015e0 +#define NV50_3D_VERTEX_END_GL_UNK0 0x00000001 +#define NVA0_3D_VERTEX_END_GL_UNK1 0x00000002 + +#define NV50_3D_EDGEFLAG_ENABLE 0x000015e4 + +#define NV50_3D_VB_ELEMENT_U32 0x000015e8 + +#define NV50_3D_VB_ELEMENT_U16_SETUP 0x000015ec +#define NV50_3D_VB_ELEMENT_U16_SETUP_OFFSET__MASK 0xc0000000 +#define NV50_3D_VB_ELEMENT_U16_SETUP_OFFSET__SHIFT 30 +#define NV50_3D_VB_ELEMENT_U16_SETUP_COUNT__MASK 0x3fffffff +#define NV50_3D_VB_ELEMENT_U16_SETUP_COUNT__SHIFT 0 + +#define NV50_3D_VB_ELEMENT_U16 0x000015f0 +#define NV50_3D_VB_ELEMENT_U16_I0__MASK 0x0000ffff +#define NV50_3D_VB_ELEMENT_U16_I0__SHIFT 0 +#define NV50_3D_VB_ELEMENT_U16_I1__MASK 0xffff0000 +#define NV50_3D_VB_ELEMENT_U16_I1__SHIFT 16 + +#define NV50_3D_VERTEX_BASE_HIGH 0x000015f4 + +#define NV50_3D_VERTEX_BASE_LOW 0x000015f8 + +#define NV50_3D_VERTEX_DATA 0x00001640 + +#define NV50_3D_PRIM_RESTART_ENABLE 0x00001644 + +#define NV50_3D_PRIM_RESTART_INDEX 0x00001648 + +#define NV50_3D_VP_GP_BUILTIN_ATTR_EN 0x0000164c +#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID 0x00000001 +#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_INSTANCE_ID 0x00000010 +#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID 0x00000100 +#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_UNK12 0x00001000 + +#define NV50_3D_VP_ATTR_EN(i0) (0x00001650 + 0x4*(i0)) +#define NV50_3D_VP_ATTR_EN__ESIZE 0x00000004 +#define NV50_3D_VP_ATTR_EN__LEN 0x00000002 +#define NV50_3D_VP_ATTR_EN_7__MASK 0xf0000000 +#define NV50_3D_VP_ATTR_EN_7__SHIFT 28 +#define NV50_3D_VP_ATTR_EN_7_X 0x10000000 +#define NV50_3D_VP_ATTR_EN_7_Y 0x20000000 +#define NV50_3D_VP_ATTR_EN_7_Z 0x40000000 +#define NV50_3D_VP_ATTR_EN_7_W 0x80000000 +#define NV50_3D_VP_ATTR_EN_6__MASK 0x0f000000 +#define NV50_3D_VP_ATTR_EN_6__SHIFT 24 +#define NV50_3D_VP_ATTR_EN_6_X 0x01000000 +#define NV50_3D_VP_ATTR_EN_6_Y 0x02000000 +#define NV50_3D_VP_ATTR_EN_6_Z 0x04000000 +#define NV50_3D_VP_ATTR_EN_6_W 0x08000000 +#define NV50_3D_VP_ATTR_EN_5__MASK 0x00f00000 +#define NV50_3D_VP_ATTR_EN_5__SHIFT 20 +#define NV50_3D_VP_ATTR_EN_5_X 0x00100000 +#define NV50_3D_VP_ATTR_EN_5_Y 0x00200000 +#define NV50_3D_VP_ATTR_EN_5_Z 0x00400000 +#define NV50_3D_VP_ATTR_EN_5_W 0x00800000 +#define NV50_3D_VP_ATTR_EN_4__MASK 0x000f0000 +#define NV50_3D_VP_ATTR_EN_4__SHIFT 16 +#define NV50_3D_VP_ATTR_EN_4_X 0x00010000 +#define NV50_3D_VP_ATTR_EN_4_Y 0x00020000 +#define NV50_3D_VP_ATTR_EN_4_Z 0x00040000 +#define NV50_3D_VP_ATTR_EN_4_W 0x00080000 +#define NV50_3D_VP_ATTR_EN_3__MASK 0x0000f000 +#define NV50_3D_VP_ATTR_EN_3__SHIFT 12 +#define NV50_3D_VP_ATTR_EN_3_X 0x00001000 +#define NV50_3D_VP_ATTR_EN_3_Y 0x00002000 +#define NV50_3D_VP_ATTR_EN_3_Z 0x00004000 +#define NV50_3D_VP_ATTR_EN_3_W 0x00008000 +#define NV50_3D_VP_ATTR_EN_2__MASK 0x00000f00 +#define NV50_3D_VP_ATTR_EN_2__SHIFT 8 +#define NV50_3D_VP_ATTR_EN_2_X 0x00000100 +#define NV50_3D_VP_ATTR_EN_2_Y 0x00000200 +#define NV50_3D_VP_ATTR_EN_2_Z 0x00000400 +#define NV50_3D_VP_ATTR_EN_2_W 0x00000800 +#define NV50_3D_VP_ATTR_EN_1__MASK 0x000000f0 +#define NV50_3D_VP_ATTR_EN_1__SHIFT 4 +#define NV50_3D_VP_ATTR_EN_1_X 0x00000010 +#define NV50_3D_VP_ATTR_EN_1_Y 0x00000020 +#define NV50_3D_VP_ATTR_EN_1_Z 0x00000040 +#define NV50_3D_VP_ATTR_EN_1_W 0x00000080 +#define NV50_3D_VP_ATTR_EN_0__MASK 0x0000000f +#define NV50_3D_VP_ATTR_EN_0__SHIFT 0 +#define NV50_3D_VP_ATTR_EN_0_X 0x00000001 +#define NV50_3D_VP_ATTR_EN_0_Y 0x00000002 +#define NV50_3D_VP_ATTR_EN_0_Z 0x00000004 +#define NV50_3D_VP_ATTR_EN_0_W 0x00000008 + +#define NV50_3D_POINT_SMOOTH_ENABLE 0x00001658 + +#define NV50_3D_POINT_RASTER_RULES 0x0000165c +#define NV50_3D_POINT_RASTER_RULES_OGL 0x00000000 +#define NV50_3D_POINT_RASTER_RULES_D3D 0x00000001 + +#define NV50_3D_POINT_SPRITE_CTRL 0x00001660 +#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN__MASK 0x00000010 +#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN__SHIFT 4 +#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN_LOWER_LEFT 0x00000000 +#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN_UPPER_LEFT 0x00000010 + +#define NVA0_3D_TEX_MISC 0x00001664 +#define NVA0_3D_TEX_MISC_UNK1 0x00000002 +#define NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP 0x00000004 + +#define NV50_3D_LINE_SMOOTH_BLUR 0x00001668 +#define NV50_3D_LINE_SMOOTH_BLUR_LOW 0x00000000 +#define NV50_3D_LINE_SMOOTH_BLUR_MEDIUM 0x00000001 +#define NV50_3D_LINE_SMOOTH_BLUR_HIGH 0x00000002 + +#define NV50_3D_LINE_STIPPLE_ENABLE 0x0000166c + +#define NV50_3D_COVERAGE_LUT(i0) (0x00001670 + 0x4*(i0)) +#define NV50_3D_COVERAGE_LUT__ESIZE 0x00000004 +#define NV50_3D_COVERAGE_LUT__LEN 0x00000004 +#define NV50_3D_COVERAGE_LUT_0__MASK 0x000000ff +#define NV50_3D_COVERAGE_LUT_0__SHIFT 0 +#define NV50_3D_COVERAGE_LUT_1__MASK 0x0000ff00 +#define NV50_3D_COVERAGE_LUT_1__SHIFT 8 +#define NV50_3D_COVERAGE_LUT_2__MASK 0x00ff0000 +#define NV50_3D_COVERAGE_LUT_2__SHIFT 16 +#define NV50_3D_COVERAGE_LUT_3__MASK 0xff000000 +#define NV50_3D_COVERAGE_LUT_3__SHIFT 24 + +#define NV50_3D_LINE_STIPPLE 0x00001680 +#define NV50_3D_LINE_STIPPLE_FACTOR_M1__MASK 0x000000ff +#define NV50_3D_LINE_STIPPLE_FACTOR_M1__SHIFT 0 +#define NV50_3D_LINE_STIPPLE_PATTERN__MASK 0x00ffff00 +#define NV50_3D_LINE_STIPPLE_PATTERN__SHIFT 8 + +#define NV50_3D_PROVOKING_VERTEX_LAST 0x00001684 + +#define NV50_3D_VERTEX_TWO_SIDE_ENABLE 0x00001688 + +#define NV50_3D_POLYGON_STIPPLE_ENABLE 0x0000168c + +#define NV50_3D_UNK1690 0x00001690 +#define NV50_3D_UNK1690_ALWAYS_DERIV 0x00000001 +#define NV50_3D_UNK1690_UNK16 0x00010000 + +#define NV50_3D_SET_PROGRAM_CB 0x00001694 +#define NV50_3D_SET_PROGRAM_CB_PROGRAM__MASK 0x000000f0 +#define NV50_3D_SET_PROGRAM_CB_PROGRAM__SHIFT 4 +#define NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX 0x00000000 +#define NV50_3D_SET_PROGRAM_CB_PROGRAM_GEOMETRY 0x00000020 +#define NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT 0x00000030 +#define NV50_3D_SET_PROGRAM_CB_INDEX__MASK 0x00000f00 +#define NV50_3D_SET_PROGRAM_CB_INDEX__SHIFT 8 +#define NV50_3D_SET_PROGRAM_CB_BUFFER__MASK 0x0007f000 +#define NV50_3D_SET_PROGRAM_CB_BUFFER__SHIFT 12 +#define NV50_3D_SET_PROGRAM_CB_VALID 0x00000001 + +#define NV50_3D_UNK1698 0x00001698 +#define NV50_3D_UNK1698_0 0x00000001 +#define NV50_3D_UNK1698_1 0x00000010 +#define NV50_3D_UNK1698_2 0x00000100 + +#define NVA3_3D_SAMPLE_SHADING 0x0000169c +#define NVA3_3D_SAMPLE_SHADING_MIN_SAMPLES__MASK 0x0000000f +#define NVA3_3D_SAMPLE_SHADING_MIN_SAMPLES__SHIFT 0 +#define NVA3_3D_SAMPLE_SHADING_ENABLE 0x00000010 + +#define NVA3_3D_UNK16A0 0x000016a0 + +#define NV50_3D_VP_RESULT_MAP_SIZE 0x000016ac + +#define NV50_3D_VP_REG_ALLOC_TEMP 0x000016b0 + +#define NVA0_3D_UNK16B4 0x000016b4 +#define NVA0_3D_UNK16B4_UNK0 0x00000001 +#define NVA3_3D_UNK16B4_UNK1 0x00000002 + +#define NV50_3D_VP_REG_ALLOC_RESULT 0x000016b8 + +#define NV50_3D_VP_RESULT_MAP(i0) (0x000016bc + 0x4*(i0)) +#define NV50_3D_VP_RESULT_MAP__ESIZE 0x00000004 +#define NV50_3D_VP_RESULT_MAP__LEN 0x00000011 +#define NV50_3D_VP_RESULT_MAP_0__MASK 0x000000ff +#define NV50_3D_VP_RESULT_MAP_0__SHIFT 0 +#define NV50_3D_VP_RESULT_MAP_1__MASK 0x0000ff00 +#define NV50_3D_VP_RESULT_MAP_1__SHIFT 8 +#define NV50_3D_VP_RESULT_MAP_2__MASK 0x00ff0000 +#define NV50_3D_VP_RESULT_MAP_2__SHIFT 16 +#define NV50_3D_VP_RESULT_MAP_3__MASK 0xff000000 +#define NV50_3D_VP_RESULT_MAP_3__SHIFT 24 + +#define NV50_3D_POLYGON_STIPPLE_PATTERN(i0) (0x00001700 + 0x4*(i0)) +#define NV50_3D_POLYGON_STIPPLE_PATTERN__ESIZE 0x00000004 +#define NV50_3D_POLYGON_STIPPLE_PATTERN__LEN 0x00000020 + +#define NVA0_3D_STRMOUT_OFFSET(i0) (0x00001780 + 0x4*(i0)) +#define NVA0_3D_STRMOUT_OFFSET__ESIZE 0x00000004 +#define NVA0_3D_STRMOUT_OFFSET__LEN 0x00000004 + +#define NV50_3D_GP_ENABLE 0x00001798 + +#define NV50_3D_GP_REG_ALLOC_TEMP 0x000017a0 + +#define NV50_3D_GP_REG_ALLOC_RESULT 0x000017a8 + +#define NV50_3D_GP_RESULT_MAP_SIZE 0x000017ac + +#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE 0x000017b0 +#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_POINTS 0x00000001 +#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP 0x00000002 +#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP 0x00000003 + +#define NV50_3D_RASTERIZE_ENABLE 0x000017b4 + +#define NV50_3D_STRMOUT_ENABLE 0x000017b8 + +#define NV50_3D_GP_RESULT_MAP(i0) (0x000017fc + 0x4*(i0)) +#define NV50_3D_GP_RESULT_MAP__ESIZE 0x00000004 +#define NV50_3D_GP_RESULT_MAP__LEN 0x00000021 +#define NV50_3D_GP_RESULT_MAP_0__MASK 0x000000ff +#define NV50_3D_GP_RESULT_MAP_0__SHIFT 0 +#define NV50_3D_GP_RESULT_MAP_1__MASK 0x0000ff00 +#define NV50_3D_GP_RESULT_MAP_1__SHIFT 8 +#define NV50_3D_GP_RESULT_MAP_2__MASK 0x00ff0000 +#define NV50_3D_GP_RESULT_MAP_2__SHIFT 16 +#define NV50_3D_GP_RESULT_MAP_3__MASK 0xff000000 +#define NV50_3D_GP_RESULT_MAP_3__SHIFT 24 + +#define NV50_3D_UNK187C 0x0000187c + +#define NVA3_3D_VERTEX_ARRAY_PER_INSTANCE_ALT(i0) (0x00001880 + 0x4*(i0)) +#define NVA3_3D_VERTEX_ARRAY_PER_INSTANCE_ALT__ESIZE 0x00000004 +#define NVA3_3D_VERTEX_ARRAY_PER_INSTANCE_ALT__LEN 0x00000020 + +#define NV50_3D_GP_VIEWPORT_ID_ENABLE 0x00001900 + +#define NV50_3D_MAP_SEMANTIC_0 0x00001904 +#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__MASK 0x000000ff +#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT 0 +#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__MASK 0x0000ff00 +#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__SHIFT 8 +#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__MASK 0x00ff0000 +#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__SHIFT 16 +#define NV50_3D_MAP_SEMANTIC_0_CLMP_EN 0xff000000 + +#define NV50_3D_MAP_SEMANTIC_1 0x00001908 +#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__MASK 0x000000ff +#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__SHIFT 0 +#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__MASK 0x00000f00 +#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__SHIFT 8 + +#define NV50_3D_MAP_SEMANTIC_2 0x0000190c +#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__MASK 0x000000ff +#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__SHIFT 0 + +#define NV50_3D_MAP_SEMANTIC_3 0x00001910 +#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK 0x00000001 +#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__SHIFT 0 +#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__MASK 0x00000ff0 +#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__SHIFT 4 + +#define NV50_3D_MAP_SEMANTIC_4 0x00001914 +#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__MASK 0x000000ff +#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__SHIFT 0 + +#define NV50_3D_CULL_FACE_ENABLE 0x00001918 + +#define NV50_3D_FRONT_FACE 0x0000191c +#define NV50_3D_FRONT_FACE_CW 0x00000900 +#define NV50_3D_FRONT_FACE_CCW 0x00000901 + +#define NV50_3D_CULL_FACE 0x00001920 +#define NV50_3D_CULL_FACE_FRONT 0x00000404 +#define NV50_3D_CULL_FACE_BACK 0x00000405 +#define NV50_3D_CULL_FACE_FRONT_AND_BACK 0x00000408 + +#define NV50_3D_UNK1924 0x00001924 + +#define NVA3_3D_FP_MULTISAMPLE 0x00001928 +#define NVA3_3D_FP_MULTISAMPLE_EXPORT_SAMPLE_MASK 0x00000001 +#define NVA3_3D_FP_MULTISAMPLE_FORCE_PER_SAMPLE 0x00000002 + +#define NV50_3D_VIEWPORT_TRANSFORM_EN 0x0000192c + +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL 0x0000193c +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK0 0x00000001 +#define NVA0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1 0x00000002 +#define NVA0_3D_VIEW_VOLUME_CLIP_CTRL_UNK2 0x00000004 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR 0x00000008 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR 0x00000010 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 0x00000080 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK10 0x00000400 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK11 0x00000800 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12__MASK 0x00003000 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12__SHIFT 12 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK0 0x00000000 +#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1 0x00001000 +#define NV84_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2 0x00002000 + +#define NV50_3D_UNK1940 0x00001940 +#define NV50_3D_UNK1940_0 0x00000001 +#define NV50_3D_UNK1940_1 0x00000010 +#define NV50_3D_UNK1940_2 0x00000100 +#define NV50_3D_UNK1940_3 0x00001000 +#define NV50_3D_UNK1940_4 0x00010000 +#define NV50_3D_UNK1940_5 0x00100000 +#define NV50_3D_UNK1940_6 0x01000000 +#define NV50_3D_UNK1940_7 0x10000000 + +#define NVA3_3D_UNK1944 0x00001944 + +#define NV50_3D_CLIP_RECTS_EN 0x0000194c + +#define NV50_3D_CLIP_RECTS_MODE 0x00001950 +#define NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY 0x00000000 +#define NV50_3D_CLIP_RECTS_MODE_OUTSIDE_ALL 0x00000001 +#define NV50_3D_CLIP_RECTS_MODE_NEVER 0x00000002 + +#define NV50_3D_ZCULL_VALIDATE 0x00001954 +#define NV50_3D_ZCULL_VALIDATE_CLEAR_UNK0 0x00000001 +#define NV50_3D_ZCULL_VALIDATE_CLEAR_UNK1 0x00000010 + +#define NV50_3D_ZCULL_INVALIDATE 0x00001958 + +#define NVA3_3D_UNK1960 0x00001960 +#define NVA3_3D_UNK1960_0 0x00000001 +#define NVA3_3D_UNK1960_1 0x00000010 + +#define NV50_3D_UNK1968 0x00001968 +#define NV50_3D_UNK1968_0 0x00000001 +#define NV50_3D_UNK1968_1 0x00000010 + +#define NV50_3D_FP_CTRL_UNK196C 0x0000196c +#define NV50_3D_FP_CTRL_UNK196C_0 0x00000001 +#define NV50_3D_FP_CTRL_UNK196C_1 0x00000010 + +#define NV50_3D_UNK1978 0x00001978 + +#define NV50_3D_CLIPID_ENABLE 0x0000197c + +#define NV50_3D_CLIPID_WIDTH 0x00001980 +#define NV50_3D_CLIPID_WIDTH__MAX 0x00002000 +#define NV50_3D_CLIPID_WIDTH__ALIGN 0x00000040 + +#define NV50_3D_CLIPID_ID 0x00001984 + +#define NV50_3D_FP_INTERPOLANT_CTRL 0x00001988 +#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK__MASK 0xff000000 +#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK__SHIFT 24 +#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_X 0x01000000 +#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_Y 0x02000000 +#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_Z 0x04000000 +#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_W 0x08000000 +#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__MASK 0x00ff0000 +#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__SHIFT 16 +#define NV50_3D_FP_INTERPOLANT_CTRL_OFFSET__MASK 0x0000ff00 +#define NV50_3D_FP_INTERPOLANT_CTRL_OFFSET__SHIFT 8 +#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT__MASK 0x000000ff +#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT__SHIFT 0 + +#define NV50_3D_FP_REG_ALLOC_TEMP 0x0000198c + +#define NV50_3D_REG_MODE 0x000019a0 +#define NV50_3D_REG_MODE_PACKED 0x00000001 +#define NV50_3D_REG_MODE_STRIPED 0x00000002 + +#define NV50_3D_FP_CONTROL 0x000019a8 +#define NV50_3D_FP_CONTROL_MULTIPLE_RESULTS 0x00000001 +#define NV50_3D_FP_CONTROL_EXPORTS_Z 0x00000100 +#define NV50_3D_FP_CONTROL_USES_KIL 0x00100000 + +#define NV50_3D_DEPTH_BOUNDS_EN 0x000019bc + +#define NV50_3D_UNK19C0 0x000019c0 + +#define NV50_3D_LOGIC_OP_ENABLE 0x000019c4 + +#define NV50_3D_LOGIC_OP 0x000019c8 +#define NV50_3D_LOGIC_OP_CLEAR 0x00001500 +#define NV50_3D_LOGIC_OP_AND 0x00001501 +#define NV50_3D_LOGIC_OP_AND_REVERSE 0x00001502 +#define NV50_3D_LOGIC_OP_COPY 0x00001503 +#define NV50_3D_LOGIC_OP_AND_INVERTED 0x00001504 +#define NV50_3D_LOGIC_OP_NOOP 0x00001505 +#define NV50_3D_LOGIC_OP_XOR 0x00001506 +#define NV50_3D_LOGIC_OP_OR 0x00001507 +#define NV50_3D_LOGIC_OP_NOR 0x00001508 +#define NV50_3D_LOGIC_OP_EQUIV 0x00001509 +#define NV50_3D_LOGIC_OP_INVERT 0x0000150a +#define NV50_3D_LOGIC_OP_OR_REVERSE 0x0000150b +#define NV50_3D_LOGIC_OP_COPY_INVERTED 0x0000150c +#define NV50_3D_LOGIC_OP_OR_INVERTED 0x0000150d +#define NV50_3D_LOGIC_OP_NAND 0x0000150e +#define NV50_3D_LOGIC_OP_SET 0x0000150f + +#define NV50_3D_ZETA_COMP_ENABLE 0x000019cc + +#define NV50_3D_CLEAR_BUFFERS 0x000019d0 +#define NV50_3D_CLEAR_BUFFERS_Z 0x00000001 +#define NV50_3D_CLEAR_BUFFERS_S 0x00000002 +#define NV50_3D_CLEAR_BUFFERS_R 0x00000004 +#define NV50_3D_CLEAR_BUFFERS_G 0x00000008 +#define NV50_3D_CLEAR_BUFFERS_B 0x00000010 +#define NV50_3D_CLEAR_BUFFERS_A 0x00000020 +#define NV50_3D_CLEAR_BUFFERS_RT__MASK 0x000003c0 +#define NV50_3D_CLEAR_BUFFERS_RT__SHIFT 6 +#define NV50_3D_CLEAR_BUFFERS_LAYER__MASK 0x001ffc00 +#define NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT 10 + +#define NV50_3D_CLIPID_FILL 0x000019d4 + +#define NV50_3D_UNK19D8(i0) (0x000019d8 + 0x4*(i0)) +#define NV50_3D_UNK19D8__ESIZE 0x00000004 +#define NV50_3D_UNK19D8__LEN 0x00000002 + +#define NV50_3D_RT_COMP_ENABLE(i0) (0x000019e0 + 0x4*(i0)) +#define NV50_3D_RT_COMP_ENABLE__ESIZE 0x00000004 +#define NV50_3D_RT_COMP_ENABLE__LEN 0x00000008 + +#define NV50_3D_COLOR_MASK(i0) (0x00001a00 + 0x4*(i0)) +#define NV50_3D_COLOR_MASK__ESIZE 0x00000004 +#define NV50_3D_COLOR_MASK__LEN 0x00000008 +#define NV50_3D_COLOR_MASK_R 0x0000000f +#define NV50_3D_COLOR_MASK_G 0x000000f0 +#define NV50_3D_COLOR_MASK_B 0x00000f00 +#define NV50_3D_COLOR_MASK_A 0x0000f000 + +#define NV50_3D_UNK1A20 0x00001a20 + +#define NV50_3D_DELAY 0x00001a24 + +#define NV50_3D_UNK1A28 0x00001a28 +#define NV50_3D_UNK1A28_0__MASK 0x000000ff +#define NV50_3D_UNK1A28_0__SHIFT 0 +#define NV50_3D_UNK1A28_1 0x00000100 + +#define NV50_3D_UNK1A2C 0x00001a2c + +#define NV50_3D_UNK1A30 0x00001a30 + +#define NV50_3D_UNK1A34 0x00001a34 + +#define NV50_3D_UNK1A38 0x00001a38 + +#define NV50_3D_UNK1A3C 0x00001a3c + +#define NV50_3D_UNK1A40(i0) (0x00001a40 + 0x4*(i0)) +#define NV50_3D_UNK1A40__ESIZE 0x00000004 +#define NV50_3D_UNK1A40__LEN 0x00000010 +#define NV50_3D_UNK1A40_0__MASK 0x00000007 +#define NV50_3D_UNK1A40_0__SHIFT 0 +#define NV50_3D_UNK1A40_1__MASK 0x00000070 +#define NV50_3D_UNK1A40_1__SHIFT 4 +#define NV50_3D_UNK1A40_2__MASK 0x00000700 +#define NV50_3D_UNK1A40_2__SHIFT 8 +#define NV50_3D_UNK1A40_3__MASK 0x00007000 +#define NV50_3D_UNK1A40_3__SHIFT 12 +#define NV50_3D_UNK1A40_4__MASK 0x00070000 +#define NV50_3D_UNK1A40_4__SHIFT 16 +#define NV50_3D_UNK1A40_5__MASK 0x00700000 +#define NV50_3D_UNK1A40_5__SHIFT 20 +#define NV50_3D_UNK1A40_6__MASK 0x07000000 +#define NV50_3D_UNK1A40_6__SHIFT 24 +#define NV50_3D_UNK1A40_7__MASK 0x70000000 +#define NV50_3D_UNK1A40_7__SHIFT 28 + +#define NV50_3D_STRMOUT_ADDRESS_HIGH(i0) (0x00001a80 + 0x10*(i0)) +#define NV50_3D_STRMOUT_ADDRESS_HIGH__ESIZE 0x00000010 +#define NV50_3D_STRMOUT_ADDRESS_HIGH__LEN 0x00000004 + +#define NV50_3D_STRMOUT_ADDRESS_LOW(i0) (0x00001a84 + 0x10*(i0)) +#define NV50_3D_STRMOUT_ADDRESS_LOW__ESIZE 0x00000010 +#define NV50_3D_STRMOUT_ADDRESS_LOW__LEN 0x00000004 + +#define NV50_3D_STRMOUT_NUM_ATTRIBS(i0) (0x00001a88 + 0x10*(i0)) +#define NV50_3D_STRMOUT_NUM_ATTRIBS__ESIZE 0x00000010 +#define NV50_3D_STRMOUT_NUM_ATTRIBS__LEN 0x00000004 +#define NV50_3D_STRMOUT_NUM_ATTRIBS__MAX 0x00000040 + +#define NVA0_3D_STRMOUT_OFFSET_LIMIT(i0) (0x00001a8c + 0x10*(i0)) +#define NVA0_3D_STRMOUT_OFFSET_LIMIT__ESIZE 0x00000010 +#define NVA0_3D_STRMOUT_OFFSET_LIMIT__LEN 0x00000004 + +#define NV50_3D_VERTEX_ARRAY_ATTRIB(i0) (0x00001ac0 + 0x4*(i0)) +#define NV50_3D_VERTEX_ARRAY_ATTRIB__ESIZE 0x00000004 +#define NV50_3D_VERTEX_ARRAY_ATTRIB__LEN 0x00000010 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_BUFFER__MASK 0x0000000f +#define NV50_3D_VERTEX_ARRAY_ATTRIB_BUFFER__SHIFT 0 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_CONST 0x00000010 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_OFFSET__MASK 0x0007ffe0 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_OFFSET__SHIFT 5 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT__MASK 0x01f80000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT__SHIFT 19 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 0x00080000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32 0x00100000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16_16 0x00180000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32 0x00200000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16 0x00280000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8_8 0x00500000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16_16 0x00780000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32 0x00900000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8 0x00980000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8_8 0x00c00000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16 0x00d80000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8 0x00e80000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_2_10_10_10 0x01800000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE__MASK 0x7e000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE__SHIFT 25 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT 0x7e000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_UNORM 0x24000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_SNORM 0x12000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_USCALED 0x5a000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED 0x6c000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_UINT 0x48000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_SINT 0x36000000 +#define NV50_3D_VERTEX_ARRAY_ATTRIB_BGRA 0x80000000 + +#define NV50_3D_QUERY_ADDRESS_HIGH 0x00001b00 + +#define NV50_3D_QUERY_ADDRESS_LOW 0x00001b04 + +#define NV50_3D_QUERY_SEQUENCE 0x00001b08 + +#define NV50_3D_QUERY_GET 0x00001b0c +#define NV50_3D_QUERY_GET_MODE__MASK 0x00000003 +#define NV50_3D_QUERY_GET_MODE__SHIFT 0 +#define NV50_3D_QUERY_GET_MODE_WRITE_UNK0 0x00000000 +#define NV50_3D_QUERY_GET_MODE_SYNC 0x00000001 +#define NV50_3D_QUERY_GET_MODE_WRITE_UNK2 0x00000002 +#define NV50_3D_QUERY_GET_UNK4 0x00000010 +#define NVA0_3D_QUERY_GET_INDEX__MASK 0x000000e0 +#define NVA0_3D_QUERY_GET_INDEX__SHIFT 5 +#define NV50_3D_QUERY_GET_UNK8 0x00000100 +#define NV50_3D_QUERY_GET_UNIT__MASK 0x0000f000 +#define NV50_3D_QUERY_GET_UNIT__SHIFT 12 +#define NV50_3D_QUERY_GET_UNIT_UNK00 0x00000000 +#define NV50_3D_QUERY_GET_UNIT_VFETCH 0x00001000 +#define NV50_3D_QUERY_GET_UNIT_VP 0x00002000 +#define NV50_3D_QUERY_GET_UNIT_RAST 0x00004000 +#define NV50_3D_QUERY_GET_UNIT_STRMOUT 0x00005000 +#define NV50_3D_QUERY_GET_UNIT_GP 0x00006000 +#define NV50_3D_QUERY_GET_UNIT_ZCULL 0x00007000 +#define NV50_3D_QUERY_GET_UNIT_TPROP 0x0000a000 +#define NV50_3D_QUERY_GET_UNIT_UNK0C 0x0000c000 +#define NV50_3D_QUERY_GET_UNIT_CROP 0x0000f000 +#define NV50_3D_QUERY_GET_SYNC_COND__MASK 0x00010000 +#define NV50_3D_QUERY_GET_SYNC_COND__SHIFT 16 +#define NV50_3D_QUERY_GET_SYNC_COND_NEQUAL 0x00000000 +#define NV50_3D_QUERY_GET_SYNC_COND_GREATER 0x00010000 +#define NV50_3D_QUERY_GET_INTR 0x00100000 +#define NV50_3D_QUERY_GET_TYPE__MASK 0x00800000 +#define NV50_3D_QUERY_GET_TYPE__SHIFT 23 +#define NV50_3D_QUERY_GET_TYPE_QUERY 0x00000000 +#define NV50_3D_QUERY_GET_TYPE_COUNTER 0x00800000 +#define NV50_3D_QUERY_GET_QUERY_SELECT__MASK 0x0f000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT__SHIFT 24 +#define NV50_3D_QUERY_GET_QUERY_SELECT_ZERO 0x00000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT_SAMPLECNT 0x01000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT_STRMOUT_NO_OVERFLOW 0x02000000 +#define NVA0_3D_QUERY_GET_QUERY_SELECT_STRMOUT_DROPPED_PRIMITIVES 0x03000000 +#define NVA0_3D_QUERY_GET_QUERY_SELECT_STRMOUT_VERTICES 0x04000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK0 0x05000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK1 0x06000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK2 0x07000000 +#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK3 0x08000000 +#define NVA0_3D_QUERY_GET_QUERY_SELECT_RT_UNK14 0x0c000000 +#define NVA0_3D_QUERY_GET_QUERY_SELECT_STRMOUT_OFFSET 0x0d000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT__MASK 0x0f000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT__SHIFT 24 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_VFETCH_VERTICES 0x00000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_VFETCH_PRIMITIVES 0x01000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_VP_LAUNCHES 0x02000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_GP_LAUNCHES 0x03000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_GP_PRIMITIVES_OUT 0x04000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_TRANSFORM_FEEDBACK 0x05000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_GENERATED_PRIMITIVES 0x06000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_RAST_PRIMITIVES_PRECLIP 0x07000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_RAST_PRIMITIVES_POSTCLIP 0x08000000 +#define NV50_3D_QUERY_GET_COUNTER_SELECT_FP_PIXELS 0x09000000 +#define NV84_3D_QUERY_GET_COUNTER_SELECT_UNK0A 0x0a000000 +#define NVA0_3D_QUERY_GET_COUNTER_SELECT_UNK0C 0x0c000000 +#define NV50_3D_QUERY_GET_SHORT 0x10000000 + +#define NVA3_3D_VP_RESULT_MAP_ALT(i0) (0x00001b3c + 0x4*(i0)) +#define NVA3_3D_VP_RESULT_MAP_ALT__ESIZE 0x00000004 +#define NVA3_3D_VP_RESULT_MAP_ALT__LEN 0x00000020 +#define NVA3_3D_VP_RESULT_MAP_ALT_0__MASK 0x000000ff +#define NVA3_3D_VP_RESULT_MAP_ALT_0__SHIFT 0 +#define NVA3_3D_VP_RESULT_MAP_ALT_1__MASK 0x0000ff00 +#define NVA3_3D_VP_RESULT_MAP_ALT_1__SHIFT 8 +#define NVA3_3D_VP_RESULT_MAP_ALT_2__MASK 0x00ff0000 +#define NVA3_3D_VP_RESULT_MAP_ALT_2__SHIFT 16 +#define NVA3_3D_VP_RESULT_MAP_ALT_3__MASK 0xff000000 +#define NVA3_3D_VP_RESULT_MAP_ALT_3__SHIFT 24 + +#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT(i0) (0x00001c00 + 0x10*(i0)) +#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT__ESIZE 0x00000010 +#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT__LEN 0x00000020 +#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT_STRIDE__MASK 0x00000fff +#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT_STRIDE__SHIFT 0 +#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT_ENABLE 0x20000000 + +#define NVA3_3D_VERTEX_ARRAY_START_HIGH_ALT(i0) (0x00001c04 + 0x10*(i0)) +#define NVA3_3D_VERTEX_ARRAY_START_HIGH_ALT__ESIZE 0x00000010 +#define NVA3_3D_VERTEX_ARRAY_START_HIGH_ALT__LEN 0x00000020 + +#define NVA3_3D_VERTEX_ARRAY_START_LOW_ALT(i0) (0x00001c08 + 0x10*(i0)) +#define NVA3_3D_VERTEX_ARRAY_START_LOW_ALT__ESIZE 0x00000010 +#define NVA3_3D_VERTEX_ARRAY_START_LOW_ALT__LEN 0x00000020 + +#define NVA3_3D_VERTEX_ARRAY_DIVISOR_ALT(i0) (0x00001c0c + 0x10*(i0)) +#define NVA3_3D_VERTEX_ARRAY_DIVISOR_ALT__ESIZE 0x00000010 +#define NVA3_3D_VERTEX_ARRAY_DIVISOR_ALT__LEN 0x00000020 + +#define NVA3_3D_IBLEND(i0) (0x00001e00 + 0x20*(i0)) +#define NVA3_3D_IBLEND__ESIZE 0x00000020 +#define NVA3_3D_IBLEND__LEN 0x00000008 + +#define NVA3_3D_IBLEND_UNK00(i0) (0x00001e00 + 0x20*(i0)) + +#define NVA3_3D_IBLEND_EQUATION_RGB(i0) (0x00001e04 + 0x20*(i0)) +#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_ADD 0x00008006 +#define NVA3_3D_IBLEND_EQUATION_RGB_MIN 0x00008007 +#define NVA3_3D_IBLEND_EQUATION_RGB_MAX 0x00008008 +#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_SUBTRACT 0x0000800a +#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT 0x0000800b + +#define NVA3_3D_IBLEND_FUNC_SRC_RGB(i0) (0x00001e08 + 0x20*(i0)) + +#define NVA3_3D_IBLEND_FUNC_DST_RGB(i0) (0x00001e0c + 0x20*(i0)) + +#define NVA3_3D_IBLEND_EQUATION_ALPHA(i0) (0x00001e10 + 0x20*(i0)) +#define NVA3_3D_IBLEND_EQUATION_ALPHA_FUNC_ADD 0x00008006 +#define NVA3_3D_IBLEND_EQUATION_ALPHA_MIN 0x00008007 +#define NVA3_3D_IBLEND_EQUATION_ALPHA_MAX 0x00008008 +#define NVA3_3D_IBLEND_EQUATION_ALPHA_FUNC_SUBTRACT 0x0000800a +#define NVA3_3D_IBLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT 0x0000800b + +#define NVA3_3D_IBLEND_FUNC_SRC_ALPHA(i0) (0x00001e14 + 0x20*(i0)) + +#define NVA3_3D_IBLEND_FUNC_DST_ALPHA(i0) (0x00001e18 + 0x20*(i0)) + +#define NVA3_3D_VERTEX_ARRAY_LIMIT_HIGH_ALT(i0) (0x00001f00 + 0x8*(i0)) +#define NVA3_3D_VERTEX_ARRAY_LIMIT_HIGH_ALT__ESIZE 0x00000008 +#define NVA3_3D_VERTEX_ARRAY_LIMIT_HIGH_ALT__LEN 0x00000020 + +#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT(i0) (0x00001f04 + 0x8*(i0)) +#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__ESIZE 0x00000008 +#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__LEN 0x00000020 + + +#endif /* NV50_3D_XML */ diff --git a/src/gallium/drivers/nv50/nv50_3ddefs.xml.h b/src/gallium/drivers/nv50/nv50_3ddefs.xml.h new file mode 100644 index 00000000000..f26ac45da40 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_3ddefs.xml.h @@ -0,0 +1,98 @@ +#ifndef NV_3DDEFS_XML +#define NV_3DDEFS_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://0x04.net/cgit/index.cgi/rules-ng-ng +git clone git://0x04.net/rules-ng-ng + +The rules-ng-ng source files this header was generated from are: +- nv50_3d.xml ( 26312 bytes, from 2010-10-08 10:10:01) +- copyright.xml ( 6498 bytes, from 2010-10-03 13:18:37) +- nv_defs.xml ( 4437 bytes, from 2010-07-06 07:43:58) +- nv_3ddefs.xml ( 16397 bytes, from 2010-10-08 13:30:38) +- nv_object.xml ( 11249 bytes, from 2010-10-07 15:31:28) +- nvchipsets.xml ( 2824 bytes, from 2010-07-07 13:41:20) +- nv50_defs.xml ( 4482 bytes, from 2010-10-03 13:18:37) + +Copyright (C) 2006-2010 by the following authors: +- Artur Huillet <[email protected]> (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. <[email protected]> (koala_br) +- Carlos Martin <[email protected]> (carlosmn) +- Christoph Bumiller <[email protected]> (calim, chrisbmr) +- Dawid Gajownik <[email protected]> (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov <[email protected]> (lumag) +- EdB <[email protected]> (edb_) +- Erik Waling <[email protected]> (erikwaling) +- Francisco Jerez <[email protected]> (curro, curro_, currojerez) +- imirkin <[email protected]> (imirkin) +- jb17bsome <[email protected]> (jb17bsome) +- Jeremy Kolb <[email protected]> (kjeremy) +- Laurent Carlier <[email protected]> (lordheavy) +- Luca Barbieri <[email protected]> (lb, lb1) +- Maarten Maathuis <[email protected]> (stillunknown) +- Marcin Kościelnicki <[email protected]> (mwk, koriakin) +- Mark Carey <[email protected]> (careym) +- Matthieu Castet <[email protected]> (mat-c) +- nvidiaman <[email protected]> (nvidiaman) +- Patrice Mandin <[email protected]> (pmandin, pmdata) +- Pekka Paalanen <[email protected]> (pq, ppaalanen) +- Peter Popov <[email protected]> (ironpeter) +- Richard Hughes <[email protected]> (hughsient) +- Rudi Cilibrasi <[email protected]> (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet <[email protected]> (leroutier) +- Stephane Marchesin <[email protected]> (marcheu) +- sturmflut <[email protected]> (sturmflut) +- Sylvain Munaut <[email protected]> +- Victor Stinner <[email protected]> (haypo) +- Wladmir van der Laan <[email protected]> (miathan6) +- Younes Manton <[email protected]> (ymanton) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#define NV50_3D_BLEND_FACTOR_ZERO 0x00004000 +#define NV50_3D_BLEND_FACTOR_ONE 0x00004001 +#define NV50_3D_BLEND_FACTOR_SRC_COLOR 0x00004300 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_COLOR 0x00004301 +#define NV50_3D_BLEND_FACTOR_SRC_ALPHA 0x00004302 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA 0x00004303 +#define NV50_3D_BLEND_FACTOR_DST_ALPHA 0x00004304 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_ALPHA 0x00004305 +#define NV50_3D_BLEND_FACTOR_DST_COLOR 0x00004306 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_COLOR 0x00004307 +#define NV50_3D_BLEND_FACTOR_SRC_ALPHA_SATURATE 0x00004308 +#define NV50_3D_BLEND_FACTOR_CONSTANT_COLOR 0x0000c001 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR 0x0000c002 +#define NV50_3D_BLEND_FACTOR_CONSTANT_ALPHA 0x0000c003 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 +#define NV50_3D_BLEND_FACTOR_SRC1_COLOR 0x0000c900 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR 0x0000c901 +#define NV50_3D_BLEND_FACTOR_SRC1_ALPHA 0x0000c902 +#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA 0x0000c903 + +#endif /* NV_3DDEFS_XML */ diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c deleted file mode 100644 index 45356f9f637..00000000000 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ /dev/null @@ -1,151 +0,0 @@ - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "nouveau/nouveau_screen.h" -#include "nouveau/nouveau_winsys.h" -#include "nv50_resource.h" - - - -static void nv50_buffer_destroy(struct pipe_screen *pscreen, - struct pipe_resource *presource) -{ - struct nv50_resource *buffer = nv50_resource(presource); - - nouveau_screen_bo_release(pscreen, buffer->bo); - FREE(buffer); -} - - - - -/* Utility functions for transfer create/destroy are hooked in and - * just record the arguments to those functions. - */ -static void * -nv50_buffer_transfer_map( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - struct nv50_resource *buffer = nv50_resource(transfer->resource); - uint8_t *map; - - map = nouveau_screen_bo_map_range( pipe->screen, - buffer->bo, - transfer->box.x, - transfer->box.width, - nouveau_screen_transfer_flags(transfer->usage) ); - if (map == NULL) - return NULL; - - return map + transfer->box.x; -} - - - -static void nv50_buffer_transfer_flush_region( struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct nv50_resource *buffer = nv50_resource(transfer->resource); - - nouveau_screen_bo_map_flush_range(pipe->screen, - buffer->bo, - transfer->box.x + box->x, - box->width); -} - -static void nv50_buffer_transfer_unmap( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - struct nv50_resource *buffer = nv50_resource(transfer->resource); - - nouveau_screen_bo_unmap(pipe->screen, buffer->bo); -} - - - - -const struct u_resource_vtbl nv50_buffer_vtbl = -{ - u_default_resource_get_handle, /* get_handle */ - nv50_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - u_default_get_transfer, /* get_transfer */ - u_default_transfer_destroy, /* transfer_destroy */ - nv50_buffer_transfer_map, /* transfer_map */ - nv50_buffer_transfer_flush_region, /* transfer_flush_region */ - nv50_buffer_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ -}; - - - - -struct pipe_resource * -nv50_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *template) -{ - struct nv50_resource *buffer; - - buffer = CALLOC_STRUCT(nv50_resource); - if (!buffer) - return NULL; - - buffer->base = *template; - buffer->vtbl = &nv50_buffer_vtbl; - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = pscreen; - - buffer->bo = nouveau_screen_bo_new(pscreen, - 16, - buffer->base.usage, - buffer->base.bind, - buffer->base.width0); - - if (buffer->bo == NULL) - goto fail; - - return &buffer->base; - -fail: - FREE(buffer); - return NULL; -} - - -struct pipe_resource * -nv50_user_buffer_create(struct pipe_screen *pscreen, - void *ptr, - unsigned bytes, - unsigned bind) -{ - struct nv50_resource *buffer; - - buffer = CALLOC_STRUCT(nv50_resource); - if (!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->vtbl = &nv50_buffer_vtbl; - buffer->base.screen = pscreen; - buffer->base.format = PIPE_FORMAT_R8_UNORM; - buffer->base.usage = PIPE_USAGE_IMMUTABLE; - buffer->base.bind = bind; - buffer->base.width0 = bytes; - buffer->base.height0 = 1; - buffer->base.depth0 = 1; - buffer->base.array_size = 1; - - buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes); - if (!buffer->bo) - goto fail; - - return &buffer->base; - -fail: - FREE(buffer); - return NULL; -} - diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c deleted file mode 100644 index ee7cf281f4a..00000000000 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2008 Ben Skeggs - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "nv50_context.h" - -void -nv50_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil) -{ - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct pipe_framebuffer_state *fb = &nv50->framebuffer; - unsigned mode = 0, i; - const unsigned dirty = nv50->dirty; - - /* don't need NEW_BLEND, NV50TCL_COLOR_MASK doesn't affect CLEAR_BUFFERS */ - nv50->dirty &= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR; - if (!nv50_state_validate(nv50, 64)) - return; - - if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4); - OUT_RING (chan, fui(rgba[0])); - OUT_RING (chan, fui(rgba[1])); - OUT_RING (chan, fui(rgba[2])); - OUT_RING (chan, fui(rgba[3])); - mode |= 0x3c; - } - - if (buffers & PIPE_CLEAR_DEPTH) { - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1); - OUT_RING (chan, fui(depth)); - mode |= NV50TCL_CLEAR_BUFFERS_Z; - } - if (buffers & PIPE_CLEAR_STENCIL) { - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1); - OUT_RING (chan, stencil & 0xff); - mode |= NV50TCL_CLEAR_BUFFERS_S; - } - - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1); - OUT_RING (chan, mode); - - for (i = 1; i < fb->nr_cbufs; i++) { - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1); - OUT_RING (chan, (i << 6) | 0x3c); - } - nv50->dirty = dirty; -} - diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 4f976161760..912367b8391 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Ben Skeggs + * Copyright 2010 Christoph Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -27,80 +27,160 @@ #include "nv50_screen.h" #include "nv50_resource.h" +#include "nouveau/nouveau_reloc.h" + static void nv50_flush(struct pipe_context *pipe, unsigned flags, - struct pipe_fence_handle **fence) + struct pipe_fence_handle **fence) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); + OUT_RING (chan, 0x20); + } + + if (fence) + nouveau_fence_ref(nv50->screen->base.fence.current, + (struct nouveau_fence **)fence); + + if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME)) + FIRE_RING(chan); +} + +void +nv50_default_flush_notify(struct nouveau_channel *chan) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_context *nv50 = chan->user_private; - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - BEGIN_RING(chan, nv50->screen->tesla, 0x1338, 1); - OUT_RING (chan, 0x20); - } + if (!nv50) + return; - if (flags & PIPE_FLUSH_FRAME) - FIRE_RING(chan); + nouveau_fence_update(&nv50->screen->base, TRUE); + nouveau_fence_next(&nv50->screen->base); } static void nv50_destroy(struct pipe_context *pipe) { - struct nv50_context *nv50 = nv50_context(pipe); - int i; - - for (i = 0; i < nv50->vtxbuf_nr; i++) { - pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL); - } - - for (i = 0; i < 64; i++) { - if (!nv50->state.hw[i]) - continue; - so_ref(NULL, &nv50->state.hw[i]); - } + struct nv50_context *nv50 = nv50_context(pipe); - draw_destroy(nv50->draw); + draw_destroy(nv50->draw); - if (nv50->screen->cur_ctx == nv50) - nv50->screen->cur_ctx = NULL; + if (nv50->screen->cur_ctx == nv50) { + nv50->screen->base.channel->user_private = NULL; + nv50->screen->cur_ctx = NULL; + } - FREE(nv50); + FREE(nv50); } - struct pipe_context * nv50_create(struct pipe_screen *pscreen, void *priv) { - struct pipe_winsys *pipe_winsys = pscreen->winsys; - struct nv50_screen *screen = nv50_screen(pscreen); - struct nv50_context *nv50; + struct pipe_winsys *pipe_winsys = pscreen->winsys; + struct nv50_screen *screen = nv50_screen(pscreen); + struct nv50_context *nv50; + struct pipe_context *pipe; + + nv50 = CALLOC_STRUCT(nv50_context); + if (!nv50) + return NULL; + pipe = &nv50->base.pipe; + + nv50->screen = screen; + nv50->base.screen = &screen->base; + nv50->base.copy_data = nv50_m2mf_copy_linear; + nv50->base.push_data = nv50_sifc_linear_u8; + + pipe->winsys = pipe_winsys; + pipe->screen = pscreen; + pipe->priv = priv; + + pipe->destroy = nv50_destroy; + + pipe->draw_vbo = nv50_draw_vbo; + pipe->clear = nv50_clear; - nv50 = CALLOC_STRUCT(nv50_context); - if (!nv50) - return NULL; - nv50->screen = screen; + pipe->flush = nv50_flush; - nv50->pipe.winsys = pipe_winsys; - nv50->pipe.screen = pscreen; - nv50->pipe.priv = priv; + if (!screen->cur_ctx) + screen->cur_ctx = nv50; + screen->base.channel->user_private = nv50; + screen->base.channel->flush_notify = nv50_default_flush_notify; - nv50->pipe.destroy = nv50_destroy; + nv50_init_query_functions(nv50); + nv50_init_surface_functions(nv50); + nv50_init_state_functions(nv50); + nv50_init_resource_functions(pipe); - nv50->pipe.draw_vbo = nv50_draw_vbo; - nv50->pipe.clear = nv50_clear; + nv50->draw = draw_create(pipe); + assert(nv50->draw); + draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); - nv50->pipe.flush = nv50_flush; + return pipe; +} + +struct resident { + struct nv04_resource *res; + uint32_t flags; +}; + +void +nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, + struct nv04_resource *resource, uint32_t flags) +{ + struct resident rsd = { resource, flags }; + + if (!resource->bo) + return; + + /* We don't need to reference the resource here, it will be referenced + * in the context/state, and bufctx will be reset when state changes. + */ + util_dynarray_append(&nv50->residents[ctx], struct resident, rsd); +} + +void +nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx, + struct nv04_resource *resource) +{ + struct resident *rsd, *top; + unsigned i; + + for (i = 0; i < nv50->residents[ctx].size / sizeof(struct resident); ++i) { + rsd = util_dynarray_element(&nv50->residents[ctx], struct resident, i); + + if (rsd->res == resource) { + top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident); + if (rsd != top) + *rsd = *top; + break; + } + } +} + +void +nv50_bufctx_emit_relocs(struct nv50_context *nv50) +{ + struct resident *rsd; + struct util_dynarray *array; + unsigned ctx, i, n; - screen->base.channel->user_private = nv50; + for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) { + array = &nv50->residents[ctx]; - nv50_init_surface_functions(nv50); - nv50_init_state_functions(nv50); - nv50_init_query_functions(nv50); - nv50_init_resource_functions(&nv50->pipe); + n = array->size / sizeof(struct resident); + MARK_RING(nv50->screen->base.channel, n, n); + for (i = 0; i < n; ++i) { + rsd = util_dynarray_element(array, struct resident, i); - nv50->draw = draw_create(&nv50->pipe); - assert(nv50->draw); - draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); + nv50_resource_validate(rsd->res, rsd->flags); + } + } - return &nv50->pipe; + nv50_screen_make_buffers_resident(nv50->screen); } diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index b2b0b72fe26..46e6c2250af 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -5,265 +5,230 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_compiler.h" #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_inlines.h" +#include "util/u_dynarray.h" #include "draw/draw_vertex.h" -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_stateobj.h" -#include "nv50_reg.h" - +#include "nv50_winsys.h" +#include "nv50_stateobj.h" #include "nv50_screen.h" #include "nv50_program.h" +#include "nv50_resource.h" -#define NOUVEAU_ERR(fmt, args...) \ - fprintf(stderr, "%s:%d - "fmt, __FUNCTION__, __LINE__, ##args); -#define NOUVEAU_MSG(fmt, args...) \ - fprintf(stderr, "nouveau: "fmt, ##args); - -#define nouveau_bo_tile_layout(nvbo) \ - ((nvbo)->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) - -/* Constant buffer assignment */ -#define NV50_CB_PMISC 0 -#define NV50_CB_PVP 1 -#define NV50_CB_PFP 2 -#define NV50_CB_PGP 3 -#define NV50_CB_AUX 4 - -#define NV50_NEW_BLEND (1 << 0) -#define NV50_NEW_ZSA (1 << 1) -#define NV50_NEW_BLEND_COLOUR (1 << 2) -#define NV50_NEW_STIPPLE (1 << 3) -#define NV50_NEW_SCISSOR (1 << 4) -#define NV50_NEW_VIEWPORT (1 << 5) -#define NV50_NEW_RASTERIZER (1 << 6) -#define NV50_NEW_FRAMEBUFFER (1 << 7) -#define NV50_NEW_VERTPROG (1 << 8) -#define NV50_NEW_VERTPROG_CB (1 << 9) -#define NV50_NEW_FRAGPROG (1 << 10) -#define NV50_NEW_FRAGPROG_CB (1 << 11) -#define NV50_NEW_GEOMPROG (1 << 12) -#define NV50_NEW_GEOMPROG_CB (1 << 13) -#define NV50_NEW_ARRAYS (1 << 14) -#define NV50_NEW_SAMPLER (1 << 15) -#define NV50_NEW_TEXTURE (1 << 16) -#define NV50_NEW_STENCIL_REF (1 << 17) -#define NV50_NEW_CLIP (1 << 18) - -struct nv50_blend_stateobj { - struct pipe_blend_state pipe; - struct nouveau_stateobj *so; -}; - -struct nv50_zsa_stateobj { - struct pipe_depth_stencil_alpha_state pipe; - struct nouveau_stateobj *so; -}; +#include "nouveau/nouveau_context.h" +#include "nouveau/nv_object.xml.h" +#include "nouveau/nv_m2mf.xml.h" +#include "nv50_3ddefs.xml.h" +#include "nv50_3d.xml.h" +#include "nv50_2d.xml.h" -struct nv50_rasterizer_stateobj { - struct pipe_rasterizer_state pipe; - struct nouveau_stateobj *so; -}; +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __FUNCTION__, __LINE__, ##args); -struct nv50_sampler_stateobj { - boolean normalized; - unsigned tsc[8]; -}; +#ifdef NOUVEAU_DEBUG +# define NOUVEAU_DBG(args...) printf(args); +#else +# define NOUVEAU_DBG(args...) +#endif -struct nv50_sampler_view { - struct pipe_sampler_view pipe; - uint32_t tic[8]; -}; +#define NV50_NEW_BLEND (1 << 0) +#define NV50_NEW_RASTERIZER (1 << 1) +#define NV50_NEW_ZSA (1 << 2) +#define NV50_NEW_VERTPROG (1 << 3) +#define NV50_NEW_GMTYPROG (1 << 6) +#define NV50_NEW_FRAGPROG (1 << 7) +#define NV50_NEW_BLEND_COLOUR (1 << 8) +#define NV50_NEW_STENCIL_REF (1 << 9) +#define NV50_NEW_CLIP (1 << 10) +#define NV50_NEW_SAMPLE_MASK (1 << 11) +#define NV50_NEW_FRAMEBUFFER (1 << 12) +#define NV50_NEW_STIPPLE (1 << 13) +#define NV50_NEW_SCISSOR (1 << 14) +#define NV50_NEW_VIEWPORT (1 << 15) +#define NV50_NEW_ARRAYS (1 << 16) +#define NV50_NEW_VERTEX (1 << 17) +#define NV50_NEW_CONSTBUF (1 << 18) +#define NV50_NEW_TEXTURES (1 << 19) +#define NV50_NEW_SAMPLERS (1 << 20) + +#define NV50_BUFCTX_CONSTANT 0 +#define NV50_BUFCTX_FRAME 1 +#define NV50_BUFCTX_VERTEX 2 +#define NV50_BUFCTX_TEXTURES 3 +#define NV50_BUFCTX_COUNT 4 + +/* fixed constant buffer binding points - low indices for user's constbufs */ +#define NV50_CB_PVP 124 +#define NV50_CB_PGP 126 +#define NV50_CB_PFP 125 +#define NV50_CB_AUX 127 -struct nv50_vtxelt_stateobj { - struct pipe_vertex_element pipe[16]; - unsigned num_elements; - uint32_t hw[16]; +struct nv50_context { + struct nouveau_context base; + + struct nv50_screen *screen; + + struct util_dynarray residents[NV50_BUFCTX_COUNT]; + + uint32_t dirty; + + struct { + uint32_t instance_elts; /* bitmask of per-instance elements */ + uint32_t instance_base; + uint32_t interpolant_ctrl; + int32_t index_bias; + boolean prim_restart; + boolean point_sprite; + uint8_t num_vtxbufs; + uint8_t num_vtxelts; + uint8_t num_textures[3]; + uint8_t num_samplers[3]; + uint16_t scissor; + } state; + + struct nv50_blend_stateobj *blend; + struct nv50_rasterizer_stateobj *rast; + struct nv50_zsa_stateobj *zsa; + struct nv50_vertex_stateobj *vertex; + + struct nv50_program *vertprog; + struct nv50_program *gmtyprog; + struct nv50_program *fragprog; + + struct pipe_resource *constbuf[3][16]; + uint16_t constbuf_dirty[3]; + + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + unsigned num_vtxbufs; + struct pipe_index_buffer idxbuf; + uint32_t vbo_fifo; /* bitmask of vertex elements to be pushed to FIFO */ + uint32_t vbo_user; /* bitmask of vertex buffers pointing to user memory */ + unsigned vbo_min_index; /* from pipe_draw_info, for vertex upload */ + unsigned vbo_max_index; + + struct pipe_sampler_view *textures[3][PIPE_MAX_SAMPLERS]; + unsigned num_textures[3]; + struct nv50_tsc_entry *samplers[3][PIPE_MAX_SAMPLERS]; + unsigned num_samplers[3]; + + struct pipe_framebuffer_state framebuffer; + struct pipe_blend_color blend_colour; + struct pipe_stencil_ref stencil_ref; + struct pipe_poly_stipple stipple; + struct pipe_scissor_state scissor; + struct pipe_viewport_state viewport; + struct pipe_clip_state clip; + + unsigned sample_mask; + + boolean vbo_push_hint; + + struct draw_context *draw; }; -static INLINE struct nv50_sampler_view * -nv50_sampler_view(struct pipe_sampler_view *view) -{ - return (struct nv50_sampler_view *)view; -} - -static INLINE unsigned -get_tile_height(uint32_t tile_mode) -{ - return 1 << ((tile_mode & 0xf) + 2); -} - -static INLINE unsigned -get_tile_depth(uint32_t tile_mode) +static INLINE struct nv50_context * +nv50_context(struct pipe_context *pipe) { - return 1 << (tile_mode >> 4); + return (struct nv50_context *)pipe; } - struct nv50_surface { - struct pipe_surface base; - unsigned offset; + struct pipe_surface base; + uint32_t offset; + uint32_t width; + uint16_t height; + uint16_t depth; }; static INLINE struct nv50_surface * -nv50_surface(struct pipe_surface *pt) +nv50_surface(struct pipe_surface *ps) { - return (struct nv50_surface *)pt; + return (struct nv50_surface *)ps; } -struct nv50_state { - struct nouveau_stateobj *hw[64]; - uint64_t hw_dirty; - - unsigned sampler_view_nr[3]; - struct nouveau_stateobj *vtxbuf; - struct nouveau_stateobj *vtxattr; - unsigned vtxelt_nr; -}; +/* nv50_context.c */ +struct pipe_context *nv50_create(struct pipe_screen *, void *); -struct nv50_context { - struct pipe_context pipe; - - struct nv50_screen *screen; - - struct draw_context *draw; - - struct nv50_state state; - - unsigned dirty; - struct nv50_blend_stateobj *blend; - struct nv50_zsa_stateobj *zsa; - struct nv50_rasterizer_stateobj *rasterizer; - struct pipe_blend_color blend_colour; - struct pipe_stencil_ref stencil_ref; - struct pipe_poly_stipple stipple; - struct pipe_scissor_state scissor; - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state framebuffer; - struct pipe_clip_state clip; - struct nv50_program *vertprog; - struct nv50_program *fragprog; - struct nv50_program *geomprog; - struct pipe_resource *constbuf[PIPE_SHADER_TYPES]; - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; - unsigned vtxbuf_nr; - struct pipe_index_buffer idxbuf; - struct nv50_vtxelt_stateobj *vtxelt; - struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS]; - unsigned sampler_nr[3]; - struct pipe_sampler_view *sampler_views[3][PIPE_MAX_SAMPLERS]; - unsigned sampler_view_nr[3]; - - unsigned vbo_fifo; - unsigned req_lmem; -}; +void nv50_default_flush_notify(struct nouveau_channel *); -static INLINE struct nv50_context * -nv50_context(struct pipe_context *pipe) +void nv50_bufctx_emit_relocs(struct nv50_context *); +void nv50_bufctx_add_resident(struct nv50_context *, int ctx, + struct nv04_resource *, uint32_t flags); +void nv50_bufctx_del_resident(struct nv50_context *, int ctx, + struct nv04_resource *); +static INLINE void +nv50_bufctx_reset(struct nv50_context *nv50, int ctx) { - return (struct nv50_context *)pipe; + util_dynarray_resize(&nv50->residents[ctx], 0); } -extern void nv50_init_surface_functions(struct nv50_context *nv50); -extern void nv50_init_state_functions(struct nv50_context *nv50); -extern void nv50_init_query_functions(struct nv50_context *nv50); -extern void nv50_init_transfer_functions(struct nv50_context *nv50); - -extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen); - -extern int -nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, - int dx, int dy, struct pipe_surface *src, int sx, int sy, - int w, int h); - /* nv50_draw.c */ -extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); +extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *); -/* nv50_vbo.c */ -extern void nv50_draw_vbo(struct pipe_context *pipe, - const struct pipe_draw_info *info); -extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso); -extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50); +/* nv50_program.c */ +boolean nv50_program_translate(struct nv50_program *); +void nv50_program_destroy(struct nv50_context *, struct nv50_program *); -/* nv50_push.c */ -extern void -nv50_push_elements_instanced(struct pipe_context *, struct pipe_resource *, - unsigned idxsize, int idxbias, - unsigned mode, unsigned start, - unsigned count, unsigned i_start, - unsigned i_count); +/* nv50_query.c */ +void nv50_init_query_functions(struct nv50_context *); -/* nv50_clear.c */ -extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil); +/* nv50_shader_state.c */ +void nv50_vertprog_validate(struct nv50_context *); +void nv50_gmtyprog_validate(struct nv50_context *); +void nv50_fragprog_validate(struct nv50_context *); +void nv50_fp_linkage_validate(struct nv50_context *); +void nv50_gp_linkage_validate(struct nv50_context *); +void nv50_constbufs_validate(struct nv50_context *); +void nv50_sprite_coords_validate(struct nv50_context *); -/* nv50_program.c */ -extern struct nouveau_stateobj * -nv50_vertprog_validate(struct nv50_context *nv50); -extern struct nouveau_stateobj * -nv50_fragprog_validate(struct nv50_context *nv50); -extern struct nouveau_stateobj * -nv50_geomprog_validate(struct nv50_context *nv50); -extern struct nouveau_stateobj * -nv50_fp_linkage_validate(struct nv50_context *nv50); -extern struct nouveau_stateobj * -nv50_gp_linkage_validate(struct nv50_context *nv50); -extern void nv50_program_destroy(struct nv50_context *nv50, - struct nv50_program *p); +/* nv50_state.c */ +extern void nv50_init_state_functions(struct nv50_context *); /* nv50_state_validate.c */ -extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords); +extern boolean nv50_state_validate(struct nv50_context *); -extern void nv50_so_init_sifc(struct nv50_context *nv50, - struct nouveau_stateobj *so, - struct nouveau_bo *bo, unsigned reloc, - unsigned offset, unsigned size); +/* nv50_surface.c */ +extern void nv50_clear(struct pipe_context *, unsigned buffers, + const float *rgba, double depth, unsigned stencil); +extern void nv50_init_surface_functions(struct nv50_context *); /* nv50_tex.c */ -extern boolean nv50_tex_construct(struct nv50_sampler_view *view); -extern void nv50_tex_relocs(struct nv50_context *); -extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *); +void nv50_validate_textures(struct nv50_context *); +void nv50_validate_samplers(struct nv50_context *); + +struct pipe_sampler_view * +nv50_create_sampler_view(struct pipe_context *, + struct pipe_resource *, + const struct pipe_sampler_view *); + +/* nv50_transfer.c */ +void +nv50_sifc_linear_u8(struct nouveau_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, + unsigned size, void *data); +void +nv50_m2mf_copy_linear(struct nouveau_context *pipe, + struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, + struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, + unsigned size); + +/* nv50_vbo.c */ +void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *); +void * +nv50_vertex_state_create(struct pipe_context *pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements); +void +nv50_vertex_state_delete(struct pipe_context *pipe, void *hwcso); -/* nv50_context.c */ -struct pipe_context * -nv50_create(struct pipe_screen *pscreen, void *priv); +void nv50_vertex_arrays_validate(struct nv50_context *nv50); -static INLINE unsigned -nv50_prim(unsigned mode) -{ - switch (mode) { - case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS; - case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES; - case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP; - case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP; - case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES; - case PIPE_PRIM_TRIANGLE_STRIP: - return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP; - case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN; - case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS; - case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP; - case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON; - case PIPE_PRIM_LINES_ADJACENCY: - return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY; - case PIPE_PRIM_LINE_STRIP_ADJACENCY: - return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY; - case PIPE_PRIM_TRIANGLES_ADJACENCY: - return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY; - case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: - return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY; - default: - break; - } - - NOUVEAU_ERR("invalid primitive type %d\n", mode); - return NV50TCL_VERTEX_BEGIN_POINTS; -} +/* nv50_push.c */ +void nv50_push_vbo(struct nv50_context *, const struct pipe_draw_info *); #endif diff --git a/src/gallium/drivers/nv50/nv50_defs.xml.h b/src/gallium/drivers/nv50/nv50_defs.xml.h new file mode 100644 index 00000000000..1bf2f802b56 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_defs.xml.h @@ -0,0 +1,142 @@ +#ifndef NV50_DEFS_XML +#define NV50_DEFS_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://0x04.net/cgit/index.cgi/rules-ng-ng +git clone git://0x04.net/rules-ng-ng + +The rules-ng-ng source files this header was generated from are: +- nv50_defs.xml ( 4482 bytes, from 2010-10-03 13:18:37) +- copyright.xml ( 6498 bytes, from 2010-10-03 13:18:37) + +Copyright (C) 2006-2010 by the following authors: +- Artur Huillet <[email protected]> (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. <[email protected]> (koala_br) +- Carlos Martin <[email protected]> (carlosmn) +- Christoph Bumiller <[email protected]> (calim, chrisbmr) +- Dawid Gajownik <[email protected]> (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov <[email protected]> (lumag) +- EdB <[email protected]> (edb_) +- Erik Waling <[email protected]> (erikwaling) +- Francisco Jerez <[email protected]> (curro, curro_, currojerez) +- imirkin <[email protected]> (imirkin) +- jb17bsome <[email protected]> (jb17bsome) +- Jeremy Kolb <[email protected]> (kjeremy) +- Laurent Carlier <[email protected]> (lordheavy) +- Luca Barbieri <[email protected]> (lb, lb1) +- Maarten Maathuis <[email protected]> (stillunknown) +- Marcin Kościelnicki <[email protected]> (mwk, koriakin) +- Mark Carey <[email protected]> (careym) +- Matthieu Castet <[email protected]> (mat-c) +- nvidiaman <[email protected]> (nvidiaman) +- Patrice Mandin <[email protected]> (pmandin, pmdata) +- Pekka Paalanen <[email protected]> (pq, ppaalanen) +- Peter Popov <[email protected]> (ironpeter) +- Richard Hughes <[email protected]> (hughsient) +- Rudi Cilibrasi <[email protected]> (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet <[email protected]> (leroutier) +- Stephane Marchesin <[email protected]> (marcheu) +- sturmflut <[email protected]> (sturmflut) +- Sylvain Munaut <[email protected]> +- Victor Stinner <[email protected]> (haypo) +- Wladmir van der Laan <[email protected]> (miathan6) +- Younes Manton <[email protected]> (ymanton) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#define NV50_SURFACE_FORMAT_R32G32B32A32_FLOAT 0x000000c0 +#define NV50_SURFACE_FORMAT_R32G32B32A32_SINT 0x000000c1 +#define NV50_SURFACE_FORMAT_R32G32B32A32_UINT 0x000000c2 +#define NV50_SURFACE_FORMAT_R32G32B32X32_FLOAT 0x000000c3 +#define NV50_SURFACE_FORMAT_R16G16B16A16_UNORM 0x000000c6 +#define NV50_SURFACE_FORMAT_R16G16B16A16_SNORM 0x000000c7 +#define NV50_SURFACE_FORMAT_R16G16B16A16_SINT 0x000000c8 +#define NV50_SURFACE_FORMAT_R16G16B16A16_UINT 0x000000c9 +#define NV50_SURFACE_FORMAT_R16G16B16A16_FLOAT 0x000000ca +#define NV50_SURFACE_FORMAT_R32G32_FLOAT 0x000000cb +#define NV50_SURFACE_FORMAT_R32G32_SINT 0x000000cc +#define NV50_SURFACE_FORMAT_R32G32_UINT 0x000000cd +#define NV50_SURFACE_FORMAT_R16G16B16X16_FLOAT 0x000000ce +#define NV50_SURFACE_FORMAT_A8R8G8B8_UNORM 0x000000cf +#define NV50_SURFACE_FORMAT_A8R8G8B8_SRGB 0x000000d0 +#define NV50_SURFACE_FORMAT_A2B10G10R10_UNORM 0x000000d1 +#define NV50_SURFACE_FORMAT_A2B10G10R10_UINT 0x000000d2 +#define NV50_SURFACE_FORMAT_A8B8G8R8_UNORM 0x000000d5 +#define NV50_SURFACE_FORMAT_A8B8G8R8_SRGB 0x000000d6 +#define NV50_SURFACE_FORMAT_A8B8G8R8_SNORM 0x000000d7 +#define NV50_SURFACE_FORMAT_A8B8G8R8_SINT 0x000000d8 +#define NV50_SURFACE_FORMAT_A8B8G8R8_UINT 0x000000d9 +#define NV50_SURFACE_FORMAT_R16G16_UNORM 0x000000da +#define NV50_SURFACE_FORMAT_R16G16_SNORM 0x000000db +#define NV50_SURFACE_FORMAT_R16G16_SINT 0x000000dc +#define NV50_SURFACE_FORMAT_R16G16_UINT 0x000000dd +#define NV50_SURFACE_FORMAT_R16G16_FLOAT 0x000000de +#define NV50_SURFACE_FORMAT_A2R10G10B10_UNORM 0x000000df +#define NV50_SURFACE_FORMAT_B10G11R11_FLOAT 0x000000e0 +#define NV50_SURFACE_FORMAT_R32_FLOAT 0x000000e5 +#define NV50_SURFACE_FORMAT_X8R8G8B8_UNORM 0x000000e6 +#define NV50_SURFACE_FORMAT_X8R8G8B8_SRGB 0x000000e7 +#define NV50_SURFACE_FORMAT_R5G6B5_UNORM 0x000000e8 +#define NV50_SURFACE_FORMAT_A1R5G5B5_UNORM 0x000000e9 +#define NV50_SURFACE_FORMAT_R8G8_UNORM 0x000000ea +#define NV50_SURFACE_FORMAT_R8G8_SNORM 0x000000eb +#define NV50_SURFACE_FORMAT_R8G8_SINT 0x000000ec +#define NV50_SURFACE_FORMAT_R8G8_UINT 0x000000ed +#define NV50_SURFACE_FORMAT_R16_UNORM 0x000000ee +#define NV50_SURFACE_FORMAT_R16_SNORM 0x000000ef +#define NV50_SURFACE_FORMAT_R16_SINT 0x000000f0 +#define NV50_SURFACE_FORMAT_R16_UINT 0x000000f1 +#define NV50_SURFACE_FORMAT_R16_FLOAT 0x000000f2 +#define NV50_SURFACE_FORMAT_R8_UNORM 0x000000f3 +#define NV50_SURFACE_FORMAT_R8_SNORM 0x000000f4 +#define NV50_SURFACE_FORMAT_R8_SINT 0x000000f5 +#define NV50_SURFACE_FORMAT_R8_UINT 0x000000f6 +#define NV50_SURFACE_FORMAT_A8_UNORM 0x000000f7 +#define NV50_SURFACE_FORMAT_X1R5G5B5_UNORM 0x000000f8 +#define NV50_SURFACE_FORMAT_X8B8G8R8_UNORM 0x000000f9 +#define NV50_SURFACE_FORMAT_X8B8G8R8_SRGB 0x000000fa +#define NV50_ZETA_FORMAT_Z32_FLOAT 0x0000000a +#define NV50_ZETA_FORMAT_Z16_UNORM 0x00000013 +#define NV50_ZETA_FORMAT_Z24S8_UNORM 0x00000014 +#define NV50_ZETA_FORMAT_X8Z24_UNORM 0x00000015 +#define NV50_ZETA_FORMAT_S8Z24_UNORM 0x00000016 +#define NV50_ZETA_FORMAT_UNK18 0x00000018 +#define NV50_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM 0x00000019 +#define NV50_ZETA_FORMAT_UNK1D 0x0000001d +#define NV50_ZETA_FORMAT_UNK1E 0x0000001e +#define NV50_ZETA_FORMAT_UNK1F 0x0000001f +#define NV50_QUERY__SIZE 0x00000010 +#define NV50_QUERY_COUNTER 0x00000000 + +#define NV50_QUERY_RES 0x00000004 + +#define NV50_QUERY_TIME 0x00000008 + + +#endif /* NV50_DEFS_XML */ diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c index 2f6f607261e..1d8598829c5 100644 --- a/src/gallium/drivers/nv50/nv50_draw.c +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -25,32 +25,32 @@ #include "nv50_context.h" struct nv50_render_stage { - struct draw_stage stage; - struct nv50_context *nv50; + struct draw_stage stage; + struct nv50_context *nv50; }; static INLINE struct nv50_render_stage * nv50_render_stage(struct draw_stage *stage) { - return (struct nv50_render_stage *)stage; + return (struct nv50_render_stage *)stage; } static void nv50_render_point(struct draw_stage *stage, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + NOUVEAU_ERR("\n"); } static void nv50_render_line(struct draw_stage *stage, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + NOUVEAU_ERR("\n"); } static void nv50_render_tri(struct draw_stage *stage, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + NOUVEAU_ERR("\n"); } static void @@ -61,29 +61,28 @@ nv50_render_flush(struct draw_stage *stage, unsigned flags) static void nv50_render_reset_stipple_counter(struct draw_stage *stage) { - NOUVEAU_ERR("\n"); + NOUVEAU_ERR("\n"); } static void nv50_render_destroy(struct draw_stage *stage) { - FREE(stage); + FREE(stage); } struct draw_stage * nv50_draw_render_stage(struct nv50_context *nv50) { - struct nv50_render_stage *rs = CALLOC_STRUCT(nv50_render_stage); + struct nv50_render_stage *rs = CALLOC_STRUCT(nv50_render_stage); - rs->nv50 = nv50; - rs->stage.draw = nv50->draw; - rs->stage.destroy = nv50_render_destroy; - rs->stage.point = nv50_render_point; - rs->stage.line = nv50_render_line; - rs->stage.tri = nv50_render_tri; - rs->stage.flush = nv50_render_flush; - rs->stage.reset_stipple_counter = nv50_render_reset_stipple_counter; + rs->nv50 = nv50; + rs->stage.draw = nv50->draw; + rs->stage.destroy = nv50_render_destroy; + rs->stage.point = nv50_render_point; + rs->stage.line = nv50_render_line; + rs->stage.tri = nv50_render_tri; + rs->stage.flush = nv50_render_flush; + rs->stage.reset_stipple_counter = nv50_render_reset_stipple_counter; - return &rs->stage; + return &rs->stage; } - diff --git a/src/gallium/drivers/nv50/nv50_formats.c b/src/gallium/drivers/nv50/nv50_formats.c index 42828094547..194e826fa66 100644 --- a/src/gallium/drivers/nv50/nv50_formats.c +++ b/src/gallium/drivers/nv50/nv50_formats.c @@ -21,26 +21,34 @@ */ #include "nv50_screen.h" -#include "nv50_texture.h" -#include "nv50_reg.h" +#include "nv50_texture.xml.h" +#include "nv50_defs.xml.h" +#include "nv50_3d.xml.h" #include "pipe/p_defines.h" -#define A_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r) \ - NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 | \ - NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 | \ - NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 | \ - NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 | \ - NV50TIC_0_0_FMT_##sz, \ - NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_##sz | \ - NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_##t0 | \ - (NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_##t0 << 3) | (r << 31) - -#define B_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r) \ - NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 | \ - NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 | \ - NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 | \ - NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 | \ - NV50TIC_0_0_FMT_##sz, 0 +#define A_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r) \ + (NV50_TIC_MAP_##cr << NV50_TIC_0_MAPR__SHIFT) | \ + (NV50_TIC_TYPE_##t0 << NV50_TIC_0_TYPE0__SHIFT) | \ + (NV50_TIC_MAP_##cg << NV50_TIC_0_MAPG__SHIFT) | \ + (NV50_TIC_TYPE_##t1 << NV50_TIC_0_TYPE1__SHIFT) | \ + (NV50_TIC_MAP_##cb << NV50_TIC_0_MAPB__SHIFT) | \ + (NV50_TIC_TYPE_##t2 << NV50_TIC_0_TYPE2__SHIFT) | \ + (NV50_TIC_MAP_##ca << NV50_TIC_0_MAPA__SHIFT) | \ + (NV50_TIC_TYPE_##t3 << NV50_TIC_0_TYPE3__SHIFT) | \ + NV50_TIC_0_FMT_##sz, \ + NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_##sz | \ + NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_##t0 | (r << 31) + +#define B_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r) \ + (NV50_TIC_MAP_##cr << NV50_TIC_0_MAPR__SHIFT) | \ + (NV50_TIC_TYPE_##t0 << NV50_TIC_0_TYPE0__SHIFT) | \ + (NV50_TIC_MAP_##cg << NV50_TIC_0_MAPG__SHIFT) | \ + (NV50_TIC_TYPE_##t1 << NV50_TIC_0_TYPE1__SHIFT) | \ + (NV50_TIC_MAP_##cb << NV50_TIC_0_MAPB__SHIFT) | \ + (NV50_TIC_TYPE_##t2 << NV50_TIC_0_TYPE2__SHIFT) | \ + (NV50_TIC_MAP_##ca << NV50_TIC_0_MAPA__SHIFT) | \ + (NV50_TIC_TYPE_##t3 << NV50_TIC_0_TYPE3__SHIFT) | \ + NV50_TIC_0_FMT_##sz, 0 #define VERTEX_BUFFER PIPE_BIND_VERTEX_BUFFER #define SAMPLER_VIEW PIPE_BIND_SAMPLER_VIEW @@ -49,98 +57,96 @@ #define SCANOUT PIPE_BIND_SCANOUT /* for vertex buffers: */ -#define NV50TIC_0_0_FMT_8_8_8 NV50TIC_0_0_FMT_8_8_8_8 -#define NV50TIC_0_0_FMT_16_16_16 NV50TIC_0_0_FMT_16_16_16_16 -#define NV50TIC_0_0_FMT_32_32_32 NV50TIC_0_0_FMT_32_32_32_32 - -/* NOTE: using NV50_2D_DST_FORMAT for substitute formats used with 2D engine */ +#define NV50_TIC_0_FMT_8_8_8 NV50_TIC_0_FMT_8_8_8_8 +#define NV50_TIC_0_FMT_16_16_16 NV50_TIC_0_FMT_16_16_16_16 +#define NV50_TIC_0_FMT_32_32_32 NV50_TIC_0_FMT_32_32_32_32 const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = { /* COMMON FORMATS */ - [PIPE_FORMAT_B8G8R8A8_UNORM] = { NV50TCL_RT_FORMAT_A8R8G8B8_UNORM, + [PIPE_FORMAT_B8G8R8A8_UNORM] = { NV50_SURFACE_FORMAT_A8R8G8B8_UNORM, A_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET | SCANOUT }, - [PIPE_FORMAT_B8G8R8X8_UNORM] = { NV50TCL_RT_FORMAT_X8R8G8B8_UNORM, + [PIPE_FORMAT_B8G8R8X8_UNORM] = { NV50_SURFACE_FORMAT_X8R8G8B8_UNORM, A_(C2, C1, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET | SCANOUT }, - [PIPE_FORMAT_B8G8R8A8_SRGB] = { NV50TCL_RT_FORMAT_A8R8G8B8_SRGB, + [PIPE_FORMAT_B8G8R8A8_SRGB] = { NV50_SURFACE_FORMAT_A8R8G8B8_SRGB, A_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_B8G8R8X8_SRGB] = { NV50TCL_RT_FORMAT_X8R8G8B8_SRGB, + [PIPE_FORMAT_B8G8R8X8_SRGB] = { NV50_SURFACE_FORMAT_X8R8G8B8_SRGB, A_(C2, C1, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_B5G6R5_UNORM] = { NV50TCL_RT_FORMAT_R5G6B5_UNORM, + [PIPE_FORMAT_B5G6R5_UNORM] = { NV50_SURFACE_FORMAT_R5G6B5_UNORM, B_(C2, C1, C0, ONE, UNORM, UNORM, UNORM, UNORM, 5_6_5, 1), SAMPLER_VIEW | RENDER_TARGET | SCANOUT }, - [PIPE_FORMAT_B5G5R5A1_UNORM] = { NV50TCL_RT_FORMAT_A1R5G5B5_UNORM, + [PIPE_FORMAT_B5G5R5A1_UNORM] = { NV50_SURFACE_FORMAT_A1R5G5B5_UNORM, B_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 1_5_5_5, 1), SAMPLER_VIEW | RENDER_TARGET | SCANOUT }, - [PIPE_FORMAT_B4G4R4A4_UNORM] = { NV50_2D_DST_FORMAT_R16_UNORM, + [PIPE_FORMAT_B4G4R4A4_UNORM] = { NV50_SURFACE_FORMAT_R16_UNORM, B_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 4_4_4_4, 1), SAMPLER_VIEW }, - [PIPE_FORMAT_R10G10B10A2_UNORM] = { NV50TCL_RT_FORMAT_A2B10G10R10_UNORM, + [PIPE_FORMAT_R10G10B10A2_UNORM] = { NV50_SURFACE_FORMAT_A2B10G10R10_UNORM, A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 2_10_10_10, 0), SAMPLER_VIEW | RENDER_TARGET | VERTEX_BUFFER | SCANOUT }, - [PIPE_FORMAT_B10G10R10A2_UNORM] = { NV50TCL_RT_FORMAT_A2R10G10B10_UNORM, + [PIPE_FORMAT_B10G10R10A2_UNORM] = { NV50_SURFACE_FORMAT_A2R10G10B10_UNORM, A_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 2_10_10_10, 1), SAMPLER_VIEW | RENDER_TARGET | VERTEX_BUFFER }, /* DEPTH/STENCIL FORMATS */ - [PIPE_FORMAT_Z16_UNORM] = { NV50TCL_ZETA_FORMAT_Z16_UNORM, - B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 16_DEPTH, 0), + [PIPE_FORMAT_Z16_UNORM] = { NV50_ZETA_FORMAT_Z16_UNORM, + B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 16_ZETA, 0), SAMPLER_VIEW | DEPTH_STENCIL }, - [PIPE_FORMAT_Z24_UNORM_S8_USCALED] = { NV50TCL_ZETA_FORMAT_S8Z24_UNORM, + [PIPE_FORMAT_Z24_UNORM_S8_USCALED] = { NV50_ZETA_FORMAT_S8Z24_UNORM, B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 8_24, 0), SAMPLER_VIEW | DEPTH_STENCIL }, - [PIPE_FORMAT_Z24X8_UNORM] = { NV50TCL_ZETA_FORMAT_X8Z24_UNORM, + [PIPE_FORMAT_Z24X8_UNORM] = { NV50_ZETA_FORMAT_X8Z24_UNORM, B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 8_24, 0), SAMPLER_VIEW | DEPTH_STENCIL }, - [PIPE_FORMAT_S8_USCALED_Z24_UNORM] = { NV50TCL_ZETA_FORMAT_S8Z24_UNORM, + [PIPE_FORMAT_S8_USCALED_Z24_UNORM] = { NV50_ZETA_FORMAT_Z24S8_UNORM, B_(C1, C1, C1, ONE, UINT, UNORM, UINT, UINT, 24_8, 0), SAMPLER_VIEW | DEPTH_STENCIL }, - [PIPE_FORMAT_Z32_FLOAT] = { NV50TCL_ZETA_FORMAT_Z32_FLOAT, - B_(C0, C0, C0, ONE, FLOAT, UINT, UINT, UINT, 32_DEPTH, 0), + [PIPE_FORMAT_Z32_FLOAT] = { NV50_ZETA_FORMAT_Z32_FLOAT, + B_(C0, C0, C0, ONE, FLOAT, UINT, UINT, UINT, 32_ZETA, 0), SAMPLER_VIEW | DEPTH_STENCIL }, [PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED] = { - NV50TCL_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM, + NV50_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM, B_(C0, C0, C0, ONE, FLOAT, UINT, UINT, UINT, 32_8, 0), SAMPLER_VIEW | DEPTH_STENCIL }, /* LUMINANCE, ALPHA, INTENSITY */ - [PIPE_FORMAT_L8_UNORM] = { NV50_2D_DST_FORMAT_R8_UNORM, + [PIPE_FORMAT_L8_UNORM] = { NV50_SURFACE_FORMAT_R8_UNORM, A_(C0, C0, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8, 0), SAMPLER_VIEW }, - [PIPE_FORMAT_L8_SRGB] = { NV50_2D_DST_FORMAT_R8_UNORM, + [PIPE_FORMAT_L8_SRGB] = { NV50_SURFACE_FORMAT_R8_UNORM, A_(C0, C0, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8, 0), SAMPLER_VIEW }, - [PIPE_FORMAT_I8_UNORM] = { NV50_2D_DST_FORMAT_R8_UNORM, + [PIPE_FORMAT_I8_UNORM] = { NV50_SURFACE_FORMAT_R8_UNORM, A_(C0, C0, C0, C0, UNORM, UNORM, UNORM, UNORM, 8, 0), SAMPLER_VIEW }, - [PIPE_FORMAT_A8_UNORM] = { NV50TCL_RT_FORMAT_A8_UNORM, + [PIPE_FORMAT_A8_UNORM] = { NV50_SURFACE_FORMAT_A8_UNORM, A_(ZERO, ZERO, ZERO, C0, UNORM, UNORM, UNORM, UNORM, 8, 0), SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_L8A8_UNORM] = { NV50_2D_DST_FORMAT_R16_UNORM, + [PIPE_FORMAT_L8A8_UNORM] = { NV50_SURFACE_FORMAT_R16_UNORM, A_(C0, C0, C0, C1, UNORM, UNORM, UNORM, UNORM, 8_8, 0), SAMPLER_VIEW }, @@ -184,48 +190,48 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = /* FLOAT 16 */ - [PIPE_FORMAT_R16G16B16A16_FLOAT] = { NV50TCL_RT_FORMAT_R16G16B16A16_FLOAT, + [PIPE_FORMAT_R16G16B16A16_FLOAT] = { NV50_SURFACE_FORMAT_R16G16B16A16_FLOAT, A_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 16_16_16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R16G16B16_FLOAT] = { NV50TCL_RT_FORMAT_R16G16B16X16_FLOAT, + [PIPE_FORMAT_R16G16B16_FLOAT] = { NV50_SURFACE_FORMAT_R16G16B16X16_FLOAT, A_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 16_16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R16G16_FLOAT] = { NV50TCL_RT_FORMAT_R16G16_FLOAT, + [PIPE_FORMAT_R16G16_FLOAT] = { NV50_SURFACE_FORMAT_R16G16_FLOAT, A_(C0, C1, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R16_FLOAT] = { NV50TCL_RT_FORMAT_R16_FLOAT, + [PIPE_FORMAT_R16_FLOAT] = { NV50_SURFACE_FORMAT_R16_FLOAT, A_(C0, ZERO, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, /* FLOAT 32 */ - [PIPE_FORMAT_R32G32B32A32_FLOAT] = { NV50TCL_RT_FORMAT_R32G32B32A32_FLOAT, + [PIPE_FORMAT_R32G32B32A32_FLOAT] = { NV50_SURFACE_FORMAT_R32G32B32A32_FLOAT, A_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R32G32B32_FLOAT] = { NV50TCL_RT_FORMAT_R32G32B32X32_FLOAT, + [PIPE_FORMAT_R32G32B32_FLOAT] = { NV50_SURFACE_FORMAT_R32G32B32X32_FLOAT, A_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R32G32_FLOAT] = { NV50TCL_RT_FORMAT_R32G32_FLOAT, + [PIPE_FORMAT_R32G32_FLOAT] = { NV50_SURFACE_FORMAT_R32G32_FLOAT, A_(C0, C1, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R32_FLOAT] = { NV50TCL_RT_FORMAT_R32_FLOAT, + [PIPE_FORMAT_R32_FLOAT] = { NV50_SURFACE_FORMAT_R32_FLOAT, A_(C0, ZERO, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, /* ODD FORMATS */ - [PIPE_FORMAT_R11G11B10_FLOAT] = { NV50TCL_RT_FORMAT_B10G11R11_FLOAT, + [PIPE_FORMAT_R11G11B10_FLOAT] = { NV50_SURFACE_FORMAT_B10G11R11_FLOAT, B_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 10_11_11, 0), SAMPLER_VIEW | RENDER_TARGET }, [PIPE_FORMAT_R9G9B9E5_FLOAT] = { 0, - B_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 5_9_9_9, 0), + B_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, E5_9_9_9, 0), SAMPLER_VIEW }, /* SNORM 32 */ @@ -266,7 +272,7 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = /* SNORM 16 */ - [PIPE_FORMAT_R16G16B16A16_SNORM] = { NV50TCL_RT_FORMAT_R16G16B16A16_SNORM, + [PIPE_FORMAT_R16G16B16A16_SNORM] = { NV50_SURFACE_FORMAT_R16G16B16A16_SNORM, A_(C0, C1, C2, C3, SNORM, SNORM, SNORM, SNORM, 16_16_16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, @@ -274,17 +280,17 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = A_(C0, C1, C2, ONE, SNORM, SNORM, SNORM, SNORM, 16_16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW }, - [PIPE_FORMAT_R16G16_SNORM] = { NV50TCL_RT_FORMAT_R16G16_SNORM, + [PIPE_FORMAT_R16G16_SNORM] = { NV50_SURFACE_FORMAT_R16G16_SNORM, A_(C0, C1, C2, C3, SNORM, SNORM, SNORM, SNORM, 16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R16_SNORM] = { NV50TCL_RT_FORMAT_R16_SNORM, + [PIPE_FORMAT_R16_SNORM] = { NV50_SURFACE_FORMAT_R16_SNORM, A_(C0, ZERO, ZERO, ONE, SNORM, SNORM, SNORM, SNORM, 16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, /* UNORM 16 */ - [PIPE_FORMAT_R16G16B16A16_UNORM] = { NV50TCL_RT_FORMAT_R16G16B16A16_UNORM, + [PIPE_FORMAT_R16G16B16A16_UNORM] = { NV50_SURFACE_FORMAT_R16G16B16A16_UNORM, A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 16_16_16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, @@ -292,17 +298,17 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = A_(C0, C1, C2, ONE, UNORM, UNORM, UNORM, UNORM, 16_16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW }, - [PIPE_FORMAT_R16G16_UNORM] = { NV50TCL_RT_FORMAT_R16G16_UNORM, + [PIPE_FORMAT_R16G16_UNORM] = { NV50_SURFACE_FORMAT_R16G16_UNORM, A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 16_16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R16_UNORM] = { NV50TCL_RT_FORMAT_R16_UNORM, + [PIPE_FORMAT_R16_UNORM] = { NV50_SURFACE_FORMAT_R16_UNORM, A_(C0, ZERO, ZERO, ONE, UNORM, UNORM, UNORM, UNORM, 16, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, /* SNORM 8 */ - [PIPE_FORMAT_R8G8B8A8_SNORM] = { NV50TCL_RT_FORMAT_A8B8G8R8_SNORM, + [PIPE_FORMAT_R8G8B8A8_SNORM] = { NV50_SURFACE_FORMAT_A8B8G8R8_SNORM, A_(C0, C1, C2, C3, SNORM, SNORM, SNORM, SNORM, 8_8_8_8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, @@ -310,37 +316,37 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = A_(C0, C1, C2, ONE, SNORM, SNORM, SNORM, SNORM, 8_8_8, 0), VERTEX_BUFFER | SAMPLER_VIEW }, - [PIPE_FORMAT_R8G8_SNORM] = { NV50TCL_RT_FORMAT_R8G8_SNORM, + [PIPE_FORMAT_R8G8_SNORM] = { NV50_SURFACE_FORMAT_R8G8_SNORM, A_(C0, C1, ZERO, ONE, SNORM, SNORM, SNORM, SNORM, 8_8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R8_SNORM] = { NV50TCL_RT_FORMAT_R8_SNORM, + [PIPE_FORMAT_R8_SNORM] = { NV50_SURFACE_FORMAT_R8_SNORM, A_(C0, ZERO, ZERO, ONE, SNORM, SNORM, SNORM, SNORM, 8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, /* UNORM 8 */ - [PIPE_FORMAT_R8G8B8A8_UNORM] = { NV50TCL_RT_FORMAT_A8B8G8R8_UNORM, + [PIPE_FORMAT_R8G8B8A8_UNORM] = { NV50_SURFACE_FORMAT_A8B8G8R8_UNORM, A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R8G8B8A8_SRGB] = { NV50TCL_RT_FORMAT_A8B8G8R8_SRGB, + [PIPE_FORMAT_R8G8B8A8_SRGB] = { NV50_SURFACE_FORMAT_A8B8G8R8_SRGB, A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R8G8B8_UNORM] = { NV50TCL_RT_FORMAT_X8B8G8R8_UNORM, + [PIPE_FORMAT_R8G8B8_UNORM] = { NV50_SURFACE_FORMAT_X8B8G8R8_UNORM, A_(C0, C1, C2, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R8G8B8_SRGB] = { NV50TCL_RT_FORMAT_X8B8G8R8_SRGB, + [PIPE_FORMAT_R8G8B8_SRGB] = { NV50_SURFACE_FORMAT_X8B8G8R8_SRGB, A_(C0, C1, C2, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8, 0), SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R8G8_UNORM] = { NV50TCL_RT_FORMAT_R8G8_UNORM, + [PIPE_FORMAT_R8G8_UNORM] = { NV50_SURFACE_FORMAT_R8G8_UNORM, A_(C0, C1, ZERO, ONE, UNORM, UNORM, UNORM, UNORM, 8_8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, - [PIPE_FORMAT_R8_UNORM] = { NV50TCL_RT_FORMAT_R8_UNORM, + [PIPE_FORMAT_R8_UNORM] = { NV50_SURFACE_FORMAT_R8_UNORM, A_(C0, ZERO, ZERO, ONE, UNORM, UNORM, UNORM, UNORM, 8, 0), VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET }, diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 309b6503ca5..ae6b26af1eb 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -29,300 +29,285 @@ #include "nv50_resource.h" #include "nv50_transfer.h" -/* The restrictions in tile mode selection probably aren't necessary. */ static INLINE uint32_t -get_tile_mode(unsigned ny, unsigned d) +get_tile_dims(unsigned nx, unsigned ny, unsigned nz) { - uint32_t tile_mode = 0x00; - - if (ny > 32) tile_mode = 0x04; /* height 64 tiles */ - else - if (ny > 16) tile_mode = 0x03; /* height 32 tiles */ - else - if (ny > 8) tile_mode = 0x02; /* height 16 tiles */ - else - if (ny > 4) tile_mode = 0x01; /* height 8 tiles */ - - if (d == 1) - return tile_mode; - else - if (tile_mode > 0x02) - tile_mode = 0x02; - - if (d > 16 && tile_mode < 0x02) - return tile_mode | 0x50; /* depth 32 tiles */ - if (d > 8) return tile_mode | 0x40; /* depth 16 tiles */ - if (d > 4) return tile_mode | 0x30; /* depth 8 tiles */ - if (d > 2) return tile_mode | 0x20; /* depth 4 tiles */ - - return tile_mode | 0x10; + uint32_t tile_mode = 0x00; + + if (ny > 32) tile_mode = 0x04; /* height 128 tiles */ + else + if (ny > 16) tile_mode = 0x03; /* height 64 tiles */ + else + if (ny > 8) tile_mode = 0x02; /* height 32 tiles */ + else + if (ny > 4) tile_mode = 0x01; /* height 16 tiles */ + + if (nz == 1) + return tile_mode; + else + if (tile_mode > 0x02) + tile_mode = 0x02; + + if (nz > 16 && tile_mode < 0x02) + return tile_mode | 0x50; /* depth 32 tiles */ + if (nz > 8) return tile_mode | 0x40; /* depth 16 tiles */ + if (nz > 4) return tile_mode | 0x30; /* depth 8 tiles */ + if (nz > 2) return tile_mode | 0x20; /* depth 4 tiles */ + + return tile_mode | 0x10; } static INLINE unsigned -get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h) +calc_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh) { - unsigned tile_h = get_tile_height(tile_mode); - unsigned tile_d = get_tile_depth(tile_mode); + unsigned tile_h = NV50_TILE_HEIGHT(tile_mode); + unsigned tile_d_shift = NV50_TILE_DIM_SHIFT(tile_mode, 1); + unsigned tile_d = 1 << tile_d_shift; - /* pitch_2d == to next slice within this volume-tile */ - /* pitch_3d == size (in bytes) of a volume-tile */ - unsigned pitch_2d = tile_h * 64; - unsigned pitch_3d = tile_d * align(nb_h, tile_h) * pitch; + /* stride_2d == to next slice within this volume tile */ + /* stride_3d == size (in bytes) of a volume tile */ + unsigned stride_2d = tile_h * NV50_TILE_PITCH(tile_mode); + unsigned stride_3d = tile_d * align(nbh, tile_h) * pitch; - return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d; + return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d; } - - - static void -nv50_miptree_destroy(struct pipe_screen *pscreen, - struct pipe_resource *pt) +nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt) { - struct nv50_miptree *mt = nv50_miptree(pt); - unsigned l; + struct nv50_miptree *mt = nv50_miptree(pt); - for (l = 0; l <= pt->last_level; ++l) - FREE(mt->level[l].image_offset); + nouveau_screen_bo_release(pscreen, mt->base.bo); - nouveau_screen_bo_release(pscreen, mt->base.bo); - FREE(mt); + FREE(mt); } static boolean nv50_miptree_get_handle(struct pipe_screen *pscreen, - struct pipe_resource *pt, - struct winsys_handle *whandle) + struct pipe_resource *pt, + struct winsys_handle *whandle) { - struct nv50_miptree *mt = nv50_miptree(pt); - unsigned stride; + struct nv50_miptree *mt = nv50_miptree(pt); + unsigned stride; + if (!mt || !mt->base.bo) + return FALSE; - if (!mt || !mt->base.bo) - return FALSE; + stride = util_format_get_stride(mt->base.base.format, + mt->base.base.width0); - stride = util_format_get_stride(mt->base.base.format, - mt->base.base.width0); - - return nouveau_screen_bo_get_handle(pscreen, - mt->base.bo, - stride, - whandle); + return nouveau_screen_bo_get_handle(pscreen, + mt->base.bo, + stride, + whandle); } - const struct u_resource_vtbl nv50_miptree_vtbl = { - nv50_miptree_get_handle, /* get_handle */ - nv50_miptree_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - nv50_miptree_transfer_new, /* get_transfer */ - nv50_miptree_transfer_del, /* transfer_destroy */ + nv50_miptree_get_handle, /* get_handle */ + nv50_miptree_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + nv50_miptree_transfer_new, /* get_transfer */ + nv50_miptree_transfer_del, /* transfer_destroy */ nv50_miptree_transfer_map, /* transfer_map */ - u_default_transfer_flush_region, /* transfer_flush_region */ - nv50_miptree_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ + u_default_transfer_flush_region, /* transfer_flush_region */ + nv50_miptree_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ }; - - struct pipe_resource * -nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *tmp) +nv50_miptree_create(struct pipe_screen *pscreen, + const struct pipe_resource *templ) { - struct nouveau_device *dev = nouveau_screen(pscreen)->device; - struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); - struct pipe_resource *pt = &mt->base.base; - unsigned width = tmp->width0, height = tmp->height0; - unsigned depth = tmp->depth0, image_alignment; - uint32_t tile_flags; - int ret, i, l; - - if (!mt) - return NULL; - - *pt = *tmp; - mt->base.vtbl = &nv50_miptree_vtbl; - pipe_reference_init(&pt->reference, 1); - pt->screen = pscreen; - - switch (pt->format) { - case PIPE_FORMAT_Z32_FLOAT: - tile_flags = 0x4800; - break; - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - tile_flags = 0x1800; - break; - case PIPE_FORMAT_Z16_UNORM: - tile_flags = 0x6c00; - break; - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - tile_flags = 0x2800; - break; - case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED: - tile_flags = 0xe000; - break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - case PIPE_FORMAT_R32G32B32_FLOAT: - tile_flags = 0x7400; - break; - default: - if ((pt->bind & PIPE_BIND_SCANOUT) && - util_format_get_blocksizebits(pt->format) == 32) - tile_flags = 0x7a00; - else - tile_flags = 0x7000; - break; - } - - /* XXX: texture arrays */ - mt->image_nr = (pt->target == PIPE_TEXTURE_CUBE) ? 6 : 1; - - for (l = 0; l <= pt->last_level; l++) { - struct nv50_miptree_level *lvl = &mt->level[l]; - unsigned nblocksy = util_format_get_nblocksy(pt->format, height); - - lvl->image_offset = CALLOC(mt->image_nr, sizeof(int)); - lvl->pitch = align(util_format_get_stride(pt->format, width), 64); - lvl->tile_mode = get_tile_mode(nblocksy, depth); - - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); - } - - image_alignment = get_tile_height(mt->level[0].tile_mode) * 64; - image_alignment *= get_tile_depth(mt->level[0].tile_mode); - - /* NOTE the distinction between arrays of mip-mapped 2D textures and - * mip-mapped 3D textures. We can't use image_nr == depth for 3D mip. - */ - for (i = 0; i < mt->image_nr; i++) { - for (l = 0; l <= pt->last_level; l++) { - struct nv50_miptree_level *lvl = &mt->level[l]; - int size; - unsigned tile_h = get_tile_height(lvl->tile_mode); - unsigned tile_d = get_tile_depth(lvl->tile_mode); - - size = lvl->pitch; - size *= align(util_format_get_nblocksy(pt->format, u_minify(pt->height0, l)), tile_h); - size *= align(u_minify(pt->depth0, l), tile_d); - - lvl->image_offset[i] = mt->total_size; - - mt->total_size += size; - } - mt->total_size = align(mt->total_size, image_alignment); - } - - ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size, - mt->level[0].tile_mode, tile_flags, - &mt->base.bo); - if (ret) { - for (l = 0; l <= pt->last_level; ++l) - FREE(mt->level[l].image_offset); - FREE(mt); - return NULL; - } - - return pt; + struct nouveau_device *dev = nouveau_screen(pscreen)->device; + struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); + struct pipe_resource *pt = &mt->base.base; + int ret; + unsigned w, h, d, l, alloc_size; + uint32_t tile_flags; + + if (!mt) + return NULL; + + mt->base.vtbl = &nv50_miptree_vtbl; + *pt = *templ; + pipe_reference_init(&pt->reference, 1); + pt->screen = pscreen; + + mt->layout_3d = pt->target == PIPE_TEXTURE_3D; + + w = pt->width0; + h = pt->height0; + d = mt->layout_3d ? pt->depth0 : 1; + + switch (pt->format) { + case PIPE_FORMAT_Z16_UNORM: + tile_flags = 0x6c00; + break; + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + tile_flags = 0x1800; + break; + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + tile_flags = 0x2800; + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + tile_flags = 0x7400; + break; + case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED: + tile_flags = 0x6000; + break; + default: + if ((pt->bind & PIPE_BIND_SCANOUT) && + util_format_get_blocksizebits(pt->format) == 32) + tile_flags = 0x7a00; + else + tile_flags = 0x7000; + break; + } + + /* For 3D textures, a mipmap is spanned by all the layers, for array + * textures and cube maps, each layer contains its own mipmaps. + */ + for (l = 0; l <= pt->last_level; ++l) { + struct nv50_miptree_level *lvl = &mt->level[l]; + unsigned nbx = util_format_get_nblocksx(pt->format, w); + unsigned nby = util_format_get_nblocksy(pt->format, h); + unsigned blocksize = util_format_get_blocksize(pt->format); + + lvl->offset = mt->total_size; + lvl->tile_mode = get_tile_dims(nbx, nby, d); + lvl->pitch = align(nbx * blocksize, NV50_TILE_PITCH(lvl->tile_mode)); + + mt->total_size += lvl->pitch * + align(nby, NV50_TILE_HEIGHT(lvl->tile_mode)) * + align(d, NV50_TILE_DEPTH(lvl->tile_mode)); + + w = u_minify(w, 1); + h = u_minify(h, 1); + d = u_minify(d, 1); + } + + if (pt->array_size > 1) { + mt->layer_stride = align(mt->total_size, + NV50_TILE_SIZE(mt->level[0].tile_mode)); + mt->total_size = mt->layer_stride * pt->array_size; + } + + alloc_size = mt->total_size; + + ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, alloc_size, + mt->level[0].tile_mode, tile_flags, + &mt->base.bo); + if (ret) { + FREE(mt); + return NULL; + } + mt->base.domain = NOUVEAU_BO_VRAM; + + return pt; } - struct pipe_resource * nv50_miptree_from_handle(struct pipe_screen *pscreen, - const struct pipe_resource *template, - struct winsys_handle *whandle) + const struct pipe_resource *templ, + struct winsys_handle *whandle) { - struct nv50_miptree *mt; - unsigned stride; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if ((template->target != PIPE_TEXTURE_2D && - template->target != PIPE_TEXTURE_RECT) || - template->last_level != 0 || - template->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv50_miptree); - if (!mt) - return NULL; - - mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride); - if (mt->base.bo == NULL) { - FREE(mt); - return NULL; - } - - - mt->base.base = *template; - mt->base.vtbl = &nv50_miptree_vtbl; - pipe_reference_init(&mt->base.base.reference, 1); - mt->base.base.screen = pscreen; - mt->image_nr = 1; - mt->level[0].pitch = stride; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - mt->level[0].tile_mode = mt->base.bo->tile_mode; - - /* XXX: Need to adjust bo refcount?? - */ - /* nouveau_bo_ref(bo, &mt->base.bo); */ - return &mt->base.base; + struct nv50_miptree *mt; + unsigned stride; + + /* only supports 2D, non-mipmapped textures for the moment */ + if ((templ->target != PIPE_TEXTURE_2D && + templ->target != PIPE_TEXTURE_RECT) || + templ->last_level != 0 || + templ->depth0 != 1 || + templ->array_size > 1) + return NULL; + + mt = CALLOC_STRUCT(nv50_miptree); + if (!mt) + return NULL; + + mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride); + if (mt->base.bo == NULL) { + FREE(mt); + return NULL; + } + + mt->base.base = *templ; + mt->base.vtbl = &nv50_miptree_vtbl; + pipe_reference_init(&mt->base.base.reference, 1); + mt->base.base.screen = pscreen; + mt->level[0].pitch = stride; + mt->level[0].offset = 0; + mt->level[0].tile_mode = mt->base.bo->tile_mode; + + /* no need to adjust bo reference count */ + return &mt->base.base; } - -/* Surface functions +/* Surface functions. */ struct pipe_surface * -nv50_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt, - const struct pipe_surface *surf_tmpl) +nv50_miptree_surface_new(struct pipe_context *pipe, + struct pipe_resource *pt, + const struct pipe_surface *templ) { - unsigned level = surf_tmpl->u.tex.level; - struct nv50_miptree *mt = nv50_miptree(pt); - struct nv50_miptree_level *lvl = &mt->level[level]; - struct nv50_surface *ns; - unsigned img = 0, zslice = 0; - - assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); - - /* XXX can't unify these here? */ - if (pt->target == PIPE_TEXTURE_CUBE) - img = surf_tmpl->u.tex.first_layer; - else if (pt->target == PIPE_TEXTURE_3D) - zslice = surf_tmpl->u.tex.first_layer; - - ns = CALLOC_STRUCT(nv50_surface); - if (!ns) - return NULL; - pipe_resource_reference(&ns->base.texture, pt); - ns->base.context = pipe; - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = surf_tmpl->usage; - pipe_reference_init(&ns->base.reference, 1); - ns->base.u.tex.level = level; - ns->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer; - ns->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer; - ns->offset = lvl->image_offset[img]; - - if (pt->target == PIPE_TEXTURE_3D) { - unsigned nb_h = util_format_get_nblocksy(pt->format, ns->base.height); - ns->offset += get_zslice_offset(lvl->tile_mode, zslice, - lvl->pitch, nb_h); - } - - return &ns->base; + struct nv50_miptree *mt = nv50_miptree(pt); /* guaranteed */ + struct nv50_surface *ns; + struct pipe_surface *ps; + struct nv50_miptree_level *lvl = &mt->level[templ->u.tex.level]; + + ns = CALLOC_STRUCT(nv50_surface); + if (!ns) + return NULL; + ps = &ns->base; + + pipe_reference_init(&ps->reference, 1); + pipe_resource_reference(&ps->texture, pt); + ps->context = pipe; + ps->format = templ->format; + ps->usage = templ->usage; + ps->u.tex.level = templ->u.tex.level; + ps->u.tex.first_layer = templ->u.tex.first_layer; + ps->u.tex.last_layer = templ->u.tex.last_layer; + + ns->width = u_minify(pt->width0, ps->u.tex.level); + ns->height = u_minify(pt->height0, ps->u.tex.level); + ns->depth = ps->u.tex.last_layer - ps->u.tex.first_layer + 1; + ns->offset = lvl->offset; + + /* comment says there are going to be removed, but they're used by the st */ + ps->width = ns->width; + ps->height = ns->height; + + if (mt->layout_3d) { + unsigned zslice = ps->u.tex.first_layer; + + /* TODO: re-layout the texture to use only depth 1 tiles in this case: */ + if (ns->depth > 1 && (zslice & (NV50_TILE_DEPTH(lvl->tile_mode) - 1))) + NOUVEAU_ERR("Creating unsupported 3D surface of slices [%u:%u].\n", + zslice, ps->u.tex.last_layer); + + ns->offset += calc_zslice_offset(lvl->tile_mode, zslice, lvl->pitch, + util_format_get_nblocksy(pt->format, + ns->height)); + } else { + ns->offset += mt->layer_stride * ps->u.tex.first_layer; + } + + return ps; } void -nv50_miptree_surface_del(struct pipe_context *pipe, - struct pipe_surface *ps) +nv50_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps) { - struct nv50_surface *s = nv50_surface(ps); + struct nv50_surface *s = nv50_surface(ps); + + pipe_resource_reference(&ps->texture, NULL); - pipe_resource_reference(&s->base.texture, NULL); - FREE(s); + FREE(s); } diff --git a/src/gallium/drivers/nv50/nv50_pc.c b/src/gallium/drivers/nv50/nv50_pc.c index c88e7ba742e..82f1b846527 100644 --- a/src/gallium/drivers/nv50/nv50_pc.c +++ b/src/gallium/drivers/nv50/nv50_pc.c @@ -307,7 +307,10 @@ nv_pc_pass_in_order(struct nv_basic_block *root, nv_pc_pass_func f, void *priv) bb[p++] = b->out[j]; break; case CFG_EDGE_LOOP_LEAVE: - bbb[pp++] = b->out[j]; + if (!b->out[j]->priv) { + bbb[pp++] = b->out[j]; + b->out[j]->priv = 1; + } break; default: assert(0); diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h index 2ead80430b0..e6f3815bafe 100644 --- a/src/gallium/drivers/nv50/nv50_pc.h +++ b/src/gallium/drivers/nv50/nv50_pc.h @@ -23,6 +23,8 @@ #ifndef __NV50_COMPILER_H__ #define __NV50_COMPILER_H__ +#define NV50PC_DEBUG + #ifdef NV50PC_DEBUG # define NV50_DBGMSG(args...) debug_printf(args) #else diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c index f37dc51e6aa..252c58dd8ff 100644 --- a/src/gallium/drivers/nv50/nv50_pc_emit.c +++ b/src/gallium/drivers/nv50/nv50_pc_emit.c @@ -762,7 +762,8 @@ emit_flow(struct nv_pc *pc, struct nv_instruction *i, ubyte flow_op) new_fixup(pc, NV50_FIXUP_CODE_RELOC, 0, pos, 0xffff << 11, 9); new_fixup(pc, NV50_FIXUP_CODE_RELOC, 1, pos, 0x3f << 14, -4); - pc->emit[0] |= (pos / 4) << 11; + pc->emit[0] |= ((pos >> 2) & 0xffff) << 11; + pc->emit[1] |= ((pos >> 18) & 0x003f) << 14; } } diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c index 679e5ea1485..281ccf7ac61 100644 --- a/src/gallium/drivers/nv50/nv50_pc_optimize.c +++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c @@ -145,8 +145,9 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b) int j; uint size, n32 = 0; + /* find first non-empty block emitted before b */ for (j = pc->num_blocks - 1; j >= 0 && !pc->bb_list[j]->bin_size; --j); - if (j >= 0) { + for (; j >= 0; --j) { in = pc->bb_list[j]; /* check for no-op branches (BRA $PC+8) */ @@ -160,6 +161,9 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b) nv_nvi_delete(in->exit); } b->bin_pos = in->bin_pos + in->bin_size; + + if (in->bin_size) /* no more no-op branches to b */ + break; } pc->bb_list[pc->num_blocks++] = b; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index db681764910..1c1a4201b60 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -411,11 +411,11 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti) if (ti->scan.writes_z) { p->fp.flags[1] = 0x11; - p->fp.flags[0] |= NV50TCL_FP_CONTROL_EXPORTS_Z; + p->fp.flags[0] |= NV50_3D_FP_CONTROL_EXPORTS_Z; } if (ti->scan.uses_kill) - p->fp.flags[0] |= NV50TCL_FP_CONTROL_USES_KIL; + p->fp.flags[0] |= NV50_3D_FP_CONTROL_USES_KIL; /* FP inputs */ @@ -490,13 +490,13 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti) if (n < m) nvary -= p->in[n].hw; - p->fp.interp |= nvary << NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_SHIFT; - p->fp.interp |= nintp << NV50TCL_FP_INTERPOLANT_CTRL_COUNT_SHIFT; + p->fp.interp |= nvary << NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__SHIFT; + p->fp.interp |= nintp << NV50_3D_FP_INTERPOLANT_CTRL_COUNT__SHIFT; /* FP outputs */ if (p->out_nr > (1 + (ti->scan.writes_z ? 1 : 0))) - p->fp.flags[0] |= NV50TCL_FP_CONTROL_MULTIPLE_RESULTS; + p->fp.flags[0] |= NV50_3D_FP_CONTROL_MULTIPLE_RESULTS; depr = p->out_nr; for (i = 0; i < p->out_nr; ++i) { @@ -608,7 +608,7 @@ nv50_prog_scan(struct nv50_translation_info *ti) } boolean -nv50_program_tx(struct nv50_program *p) +nv50_program_translate(struct nv50_program *p) { struct nv50_translation_info *ti; int ret; @@ -646,9 +646,8 @@ out: void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) { - nouveau_bo_ref(NULL, &p->bo); - - so_ref(NULL, &p->so); + if (p->res) + nouveau_resource_free(&p->res); if (p->code) FREE(p->code); diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index 33c4c8ca6df..8f5b51757d8 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -47,12 +47,9 @@ struct nv50_program { boolean translated; boolean uses_lmem; - struct nouveau_bo *bo; - struct nouveau_stateobj *so; - uint32_t *code; unsigned code_size; - unsigned code_start; /* offset inside bo */ + unsigned code_base; uint32_t *immd; unsigned immd_size; unsigned parm_size; /* size limit of uniform buffer */ @@ -89,6 +86,8 @@ struct nv50_program { /* relocation records */ void *fixups; unsigned num_fixups; + + struct nouveau_resource *res; }; #define NV50_INTERP_LINEAR (1 << 0) diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 380f69406a2..e8ad1ddd38a 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -1,362 +1,297 @@ + #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_inlines.h" #include "util/u_format.h" -#include "util/u_split_prim.h" +#include "translate/translate.h" #include "nv50_context.h" #include "nv50_resource.h" -struct push_context { - struct nv50_context *nv50; +#include "nv50_3d.xml.h" - unsigned vtx_size; +struct push_context { + struct nouveau_channel *chan; void *idxbuf; - int32_t idxbias; - unsigned idxsize; float edgeflag; int edgeflag_attr; - struct { - void *map; - unsigned stride; - unsigned divisor; - unsigned step; - void (*push)(struct nouveau_channel *, void *); - } attr[16]; - unsigned attr_nr; + uint32_t vertex_words; + uint32_t packet_vertex_limit; + + struct translate *translate; + + boolean primitive_restart; + uint32_t prim; + uint32_t restart_index; + uint32_t instance_id; }; -static void -emit_b32_1(struct nouveau_channel *chan, void *data) +static INLINE unsigned +prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index) { - uint32_t *v = data; - - OUT_RING(chan, v[0]); + unsigned i; + for (i = 0; i < push; ++i) + if (elts[i] == index) + break; + return i; } -static void -emit_b32_2(struct nouveau_channel *chan, void *data) +static INLINE unsigned +prim_restart_search_i16(uint16_t *elts, unsigned push, uint16_t index) { - uint32_t *v = data; - - OUT_RING(chan, v[0]); - OUT_RING(chan, v[1]); + unsigned i; + for (i = 0; i < push; ++i) + if (elts[i] == index) + break; + return i; } -static void -emit_b32_3(struct nouveau_channel *chan, void *data) +static INLINE unsigned +prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index) { - uint32_t *v = data; - - OUT_RING(chan, v[0]); - OUT_RING(chan, v[1]); - OUT_RING(chan, v[2]); + unsigned i; + for (i = 0; i < push; ++i) + if (elts[i] == index) + break; + return i; } static void -emit_b32_4(struct nouveau_channel *chan, void *data) +emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) { - uint32_t *v = data; + uint8_t *elts = (uint8_t *)ctx->idxbuf + start; - OUT_RING(chan, v[0]); - OUT_RING(chan, v[1]); - OUT_RING(chan, v[2]); - OUT_RING(chan, v[3]); -} + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size, nr; -static void -emit_b16_1(struct nouveau_channel *chan, void *data) -{ - uint16_t *v = data; + nr = push; + if (ctx->primitive_restart) + nr = prim_restart_search_i08(elts, push, ctx->restart_index); - OUT_RING(chan, v[0]); -} + size = ctx->vertex_words * nr; -static void -emit_b16_3(struct nouveau_channel *chan, void *data) -{ - uint16_t *v = data; + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); - OUT_RING(chan, (v[1] << 16) | v[0]); - OUT_RING(chan, v[2]); -} + ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id, + ctx->chan->cur); -static void -emit_b08_1(struct nouveau_channel *chan, void *data) -{ - uint8_t *v = data; + ctx->chan->cur += size; + count -= nr; + elts += nr; - OUT_RING(chan, v[0]); + if (nr != push) { + count--; + elts++; + BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (ctx->chan, ctx->restart_index); + } + } } static void -emit_b08_3(struct nouveau_channel *chan, void *data) +emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) { - uint8_t *v = data; + uint16_t *elts = (uint16_t *)ctx->idxbuf + start; - OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]); -} + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size, nr; -static INLINE void -emit_vertex(struct push_context *ctx, unsigned n) -{ - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; - int i; - - if (ctx->edgeflag_attr < 16) { - float *edgeflag = (float *) - ((uint8_t *)ctx->attr[ctx->edgeflag_attr].map + - ctx->attr[ctx->edgeflag_attr].stride * n); - - if (*edgeflag != ctx->edgeflag) { - BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, *edgeflag ? 1 : 0); - ctx->edgeflag = *edgeflag; - } - } + nr = push; + if (ctx->primitive_restart) + nr = prim_restart_search_i16(elts, push, ctx->restart_index); - BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size); - for (i = 0; i < ctx->attr_nr; i++) - ctx->attr[i].push(chan, - (uint8_t *)ctx->attr[i].map + ctx->attr[i].stride * n); -} + size = ctx->vertex_words * nr; -static void -emit_edgeflag(void *priv, boolean enabled) -{ - struct push_context *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); - BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, enabled ? 1 : 0); -} + ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id, + ctx->chan->cur); -static void -emit_elt08(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint8_t *idxbuf = ctx->idxbuf; + ctx->chan->cur += size; + count -= nr; + elts += nr; - while (count--) - emit_vertex(ctx, idxbuf[start++]); + if (nr != push) { + count--; + elts++; + BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (ctx->chan, ctx->restart_index); + } + } } static void -emit_elt08_biased(void *priv, unsigned start, unsigned count) +emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) { - struct push_context *ctx = priv; - uint8_t *idxbuf = ctx->idxbuf; + uint32_t *elts = (uint32_t *)ctx->idxbuf + start; - while (count--) - emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); -} + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size, nr; -static void -emit_elt16(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint16_t *idxbuf = ctx->idxbuf; + nr = push; + if (ctx->primitive_restart) + nr = prim_restart_search_i32(elts, push, ctx->restart_index); - while (count--) - emit_vertex(ctx, idxbuf[start++]); -} + size = ctx->vertex_words * nr; -static void -emit_elt16_biased(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint16_t *idxbuf = ctx->idxbuf; + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); - while (count--) - emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); -} + ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id, + ctx->chan->cur); -static void -emit_elt32(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint32_t *idxbuf = ctx->idxbuf; + ctx->chan->cur += size; + count -= nr; + elts += nr; - while (count--) - emit_vertex(ctx, idxbuf[start++]); + if (nr != push) { + count--; + elts++; + BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (ctx->chan, ctx->restart_index); + } + } } static void -emit_elt32_biased(void *priv, unsigned start, unsigned count) +emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count) { - struct push_context *ctx = priv; - uint32_t *idxbuf = ctx->idxbuf; + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size = ctx->vertex_words * push; + + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); - while (count--) - emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); + ctx->translate->run(ctx->translate, start, push, ctx->instance_id, + ctx->chan->cur); + ctx->chan->cur += size; + count -= push; + start += push; + } } -static void -emit_verts(void *priv, unsigned start, unsigned count) + +#define NV50_PRIM_GL_CASE(n) \ + case PIPE_PRIM_##n: return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n + +static INLINE unsigned +nv50_prim_gl(unsigned prim) { - while (count--) - emit_vertex(priv, start++); + switch (prim) { + NV50_PRIM_GL_CASE(POINTS); + NV50_PRIM_GL_CASE(LINES); + NV50_PRIM_GL_CASE(LINE_LOOP); + NV50_PRIM_GL_CASE(LINE_STRIP); + NV50_PRIM_GL_CASE(TRIANGLES); + NV50_PRIM_GL_CASE(TRIANGLE_STRIP); + NV50_PRIM_GL_CASE(TRIANGLE_FAN); + NV50_PRIM_GL_CASE(QUADS); + NV50_PRIM_GL_CASE(QUAD_STRIP); + NV50_PRIM_GL_CASE(POLYGON); + NV50_PRIM_GL_CASE(LINES_ADJACENCY); + NV50_PRIM_GL_CASE(LINE_STRIP_ADJACENCY); + NV50_PRIM_GL_CASE(TRIANGLES_ADJACENCY); + NV50_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY); + /* + NV50_PRIM_GL_CASE(PATCHES); */ + default: + return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS; + break; + } } void -nv50_push_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *idxbuf, - unsigned idxsize, int idxbias, - unsigned mode, unsigned start, unsigned count, - unsigned i_start, unsigned i_count) +nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; struct push_context ctx; - const unsigned p_overhead = 4 + /* begin/end */ - 4; /* potential edgeflag enable/disable */ - const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */ - 2; /* potential edgeflag modification */ - struct util_split_prim s; - unsigned vtx_size; - boolean nzi = FALSE; - int i; - - ctx.nv50 = nv50; - ctx.attr_nr = 0; - ctx.idxbuf = NULL; - ctx.vtx_size = 0; - ctx.edgeflag = 0.5f; - ctx.edgeflag_attr = nv50->vertprog->vp.edgeflag; - - /* map vertex buffers, determine vertex size */ - for (i = 0; i < nv50->vtxelt->num_elements; i++) { - struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; - struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo; - unsigned size, nr_components, n; - - if (!(nv50->vbo_fifo & (1 << i))) - continue; - n = ctx.attr_nr++; - - if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) { - assert(bo->map); + unsigned i, index_size; + unsigned inst = info->instance_count; + boolean apply_bias = info->indexed && info->index_bias; + + ctx.chan = nv50->screen->base.channel; + ctx.translate = nv50->vertex->translate; + ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit; + ctx.vertex_words = nv50->vertex->vertex_size; + + for (i = 0; i < nv50->num_vtxbufs; ++i) { + uint8_t *data; + struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; + struct nv04_resource *res = nv04_resource(vb->buffer); + + data = nouveau_resource_map_offset(&nv50->base, res, + vb->buffer_offset, NOUVEAU_BO_RD); + + if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i)))) + data += info->index_bias * vb->stride; + + ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0); + } + + if (info->indexed) { + ctx.idxbuf = nouveau_resource_map_offset(&nv50->base, + nv04_resource(nv50->idxbuf.buffer), + nv50->idxbuf.offset, NOUVEAU_BO_RD); + if (!ctx.idxbuf) return; - } - ctx.attr[n].map = (uint8_t *)bo->map + vb->buffer_offset + ve->src_offset; - nouveau_bo_unmap(bo); - - ctx.attr[n].stride = vb->stride; - ctx.attr[n].divisor = ve->instance_divisor; - if (ctx.attr[n].divisor) { - ctx.attr[n].step = i_start % ve->instance_divisor; - ctx.attr[n].map = (uint8_t *)ctx.attr[n].map + i_start * vb->stride; - } + index_size = nv50->idxbuf.index_size; + ctx.primitive_restart = info->primitive_restart; + ctx.restart_index = info->restart_index; + } else { + ctx.idxbuf = NULL; + index_size = 0; + ctx.primitive_restart = FALSE; + ctx.restart_index = 0; + } + + ctx.instance_id = info->start_instance; + ctx.prim = nv50_prim_gl(info->mode); - size = util_format_get_component_bits(ve->src_format, - UTIL_FORMAT_COLORSPACE_RGB, 0); - nr_components = util_format_get_nr_components(ve->src_format); - switch (size) { - case 8: - switch (nr_components) { - case 1: ctx.attr[n].push = emit_b08_1; break; - case 2: ctx.attr[n].push = emit_b16_1; break; - case 3: ctx.attr[n].push = emit_b08_3; break; - case 4: ctx.attr[n].push = emit_b32_1; break; - } - ctx.vtx_size++; + if (info->primitive_restart) { + BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 2); + OUT_RING (ctx.chan, 1); + OUT_RING (ctx.chan, info->restart_index); + } else + if (nv50->state.prim_restart) { + BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 1); + OUT_RING (ctx.chan, 0); + } + nv50->state.prim_restart = info->primitive_restart; + + while (inst--) { + BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1); + OUT_RING (ctx.chan, ctx.prim); + switch (index_size) { + case 0: + emit_vertices_seq(&ctx, info->start, info->count); + break; + case 1: + emit_vertices_i08(&ctx, info->start, info->count); break; - case 16: - switch (nr_components) { - case 1: ctx.attr[n].push = emit_b16_1; break; - case 2: ctx.attr[n].push = emit_b32_1; break; - case 3: ctx.attr[n].push = emit_b16_3; break; - case 4: ctx.attr[n].push = emit_b32_2; break; - } - ctx.vtx_size += (nr_components + 1) >> 1; + case 2: + emit_vertices_i16(&ctx, info->start, info->count); break; - case 32: - switch (nr_components) { - case 1: ctx.attr[n].push = emit_b32_1; break; - case 2: ctx.attr[n].push = emit_b32_2; break; - case 3: ctx.attr[n].push = emit_b32_3; break; - case 4: ctx.attr[n].push = emit_b32_4; break; - } - ctx.vtx_size += nr_components; + case 4: + emit_vertices_i32(&ctx, info->start, info->count); break; default: assert(0); - return; + break; } - } - vtx_size = ctx.vtx_size + v_overhead; + BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1); + OUT_RING (ctx.chan, 0); - /* map index buffer, if present */ - if (idxbuf) { - struct nouveau_bo *bo = nv50_resource(idxbuf)->bo; - - if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) { - assert(bo->map); - return; - } - ctx.idxbuf = bo->map; - ctx.idxbias = idxbias; - ctx.idxsize = idxsize; - nouveau_bo_unmap(bo); + ctx.instance_id++; + ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } - s.priv = &ctx; - s.edge = emit_edgeflag; - if (idxbuf) { - if (idxsize == 1) - s.emit = idxbias ? emit_elt08_biased : emit_elt08; - else - if (idxsize == 2) - s.emit = idxbias ? emit_elt16_biased : emit_elt16; - else - s.emit = idxbias ? emit_elt32_biased : emit_elt32; - } else - s.emit = emit_verts; - - /* per-instance loop */ - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); - OUT_RING (chan, NV50_CB_AUX | (24 << 8)); - OUT_RING (chan, i_start); - while (i_count--) { - unsigned max_verts; - boolean done; - - for (i = 0; i < ctx.attr_nr; i++) { - if (!ctx.attr[i].divisor || - ctx.attr[i].divisor != ++ctx.attr[i].step) - continue; - ctx.attr[i].step = 0; - ctx.attr[i].map = (uint8_t *)ctx.attr[i].map + ctx.attr[i].stride; - } + if (info->indexed) + nouveau_resource_unmap(nv04_resource(nv50->idxbuf.buffer)); - util_split_prim_init(&s, mode, start, count); - do { - if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) { - FIRE_RING(chan); - if (!nv50_state_validate(nv50, p_overhead + (6 * vtx_size))) { - assert(0); - return; - } - } - - max_verts = AVAIL_RING(chan); - max_verts -= p_overhead; - max_verts /= vtx_size; - - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); - OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0)); - done = util_split_prim_next(&s, max_verts); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); - OUT_RING (chan, 0); - } while (!done); - - nzi = TRUE; - } + for (i = 0; i < nv50->num_vtxbufs; ++i) + nouveau_resource_unmap(nv04_resource(nv50->vtxbuf[i].buffer)); } diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index f3418df8381..2dce94a4775 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Ben Skeggs + * Copyright 2011 Nouveau Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -18,150 +18,320 @@ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. + * + * Authors: Christoph Bumiller */ -#include "pipe/p_context.h" -#include "util/u_inlines.h" - #include "nv50_context.h" +#include "nouveau/nv_object.xml.h" + +/* XXX: Nested queries, and simultaneous queries on multiple gallium contexts + * (since we use only a single GPU channel per screen) will not work properly. + * + * The first is not that big of an issue because OpenGL does not allow nested + * queries anyway. + */ struct nv50_query { - struct nouveau_bo *bo; - unsigned type; - boolean ready; - uint64_t result; + uint32_t *data; + uint32_t type; + uint32_t sequence; + struct nouveau_bo *bo; + uint32_t base; + uint32_t offset; /* base + i * 16 */ + boolean ready; + boolean is64bit; + struct nouveau_mm_allocation *mm; }; +#define NV50_QUERY_ALLOC_SPACE 128 + static INLINE struct nv50_query * nv50_query(struct pipe_query *pipe) { - return (struct nv50_query *)pipe; + return (struct nv50_query *)pipe; +} + +static boolean +nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) +{ + struct nv50_screen *screen = nv50->screen; + int ret; + + if (q->bo) { + nouveau_bo_ref(NULL, &q->bo); + if (q->mm) { + if (q->ready) + nouveau_mm_free(q->mm); + else + nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm); + } + } + if (size) { + q->mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, &q->base); + if (!q->bo) + return FALSE; + q->offset = q->base; + + ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD | + NOUVEAU_BO_NOSYNC); + if (ret) { + nv50_query_allocate(nv50, q, 0); + return FALSE; + } + q->data = q->bo->map; + nouveau_bo_unmap(q->bo); + } + return TRUE; +} + +static void +nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) +{ + nv50_query_allocate(nv50_context(pipe), nv50_query(pq), 0); + FREE(nv50_query(pq)); } static struct pipe_query * nv50_query_create(struct pipe_context *pipe, unsigned type) { - struct nouveau_device *dev = nouveau_screen(pipe->screen)->device; - struct nv50_query *q = CALLOC_STRUCT(nv50_query); - int ret; + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_query *q; + + q = CALLOC_STRUCT(nv50_query); + if (!q) + return NULL; - assert (type == PIPE_QUERY_OCCLUSION_COUNTER); - q->type = type; + if (!nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE)) { + FREE(q); + return NULL; + } - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 256, - 16, &q->bo); - if (ret) { - FREE(q); - return NULL; - } + q->is64bit = (type == PIPE_QUERY_PRIMITIVES_GENERATED || + type == PIPE_QUERY_PRIMITIVES_EMITTED || + type == PIPE_QUERY_SO_STATISTICS); + q->type = type; - return (struct pipe_query *)q; + if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) { + q->offset -= 16; + q->data -= 16 / sizeof(*q->data); /* we advance before query_begin ! */ + } + + return (struct pipe_query *)q; } static void -nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) +nv50_query_get(struct nouveau_channel *chan, struct nv50_query *q, + unsigned offset, uint32_t get) { - struct nv50_query *q = nv50_query(pq); + offset += q->offset; - if (q) { - nouveau_bo_ref(NULL, &q->bo); - FREE(q); - } + MARK_RING (chan, 5, 2); + BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); + OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (chan, q->sequence); + OUT_RING (chan, get); } static void nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nv50_query *q = nv50_query(pq); + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_query *q = nv50_query(pq); + + /* For occlusion queries we have to change the storage, because a previous + * query might set the initial render conition to FALSE even *after* we re- + * initialized it to TRUE. + */ + if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) { + q->offset += 16; + q->data += 16 / sizeof(*q->data); + if (q->offset - q->base == NV50_QUERY_ALLOC_SPACE) + nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE); - BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_RESET, 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1); - OUT_RING (chan, 1); + /* XXX: can we do this with the GPU, and sync with respect to a previous + * query ? + */ + q->data[1] = 1; /* initial render condition = TRUE */ + } + if (!q->is64bit) + q->data[0] = q->sequence++; /* the previously used one */ - q->ready = FALSE; + switch (q->type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); + OUT_RING (chan, NV50_3D_COUNTER_RESET_SAMPLECNT); + BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1); + OUT_RING (chan, 1); + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: /* store before & after instead ? */ + BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); + OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES); + break; + case PIPE_QUERY_PRIMITIVES_EMITTED: + BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); + OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK); + break; + case PIPE_QUERY_SO_STATISTICS: + BEGIN_RING_NI(chan, RING_3D(COUNTER_RESET), 2); + OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK); + OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES); + break; + case PIPE_QUERY_TIMESTAMP_DISJOINT: + case PIPE_QUERY_TIME_ELAPSED: + nv50_query_get(chan, q, 0x10, 0x00005002); + break; + default: + break; + } + q->ready = FALSE; } static void nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nv50_query *q = nv50_query(pq); - - MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */ - BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); - OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0100f002); - - BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1); - OUT_RING (chan, 0); + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_query *q = nv50_query(pq); + + switch (q->type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + nv50_query_get(chan, q, 0, 0x0100f002); + BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1); + OUT_RING (chan, 0); + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: + nv50_query_get(chan, q, 0, 0x06805002); + break; + case PIPE_QUERY_PRIMITIVES_EMITTED: + nv50_query_get(chan, q, 0, 0x05805002); + break; + case PIPE_QUERY_SO_STATISTICS: + nv50_query_get(chan, q, 0x00, 0x05805002); + nv50_query_get(chan, q, 0x10, 0x06805002); + break; + case PIPE_QUERY_TIMESTAMP_DISJOINT: + case PIPE_QUERY_TIME_ELAPSED: + nv50_query_get(chan, q, 0, 0x00005002); + break; + case PIPE_QUERY_GPU_FINISHED: + nv50_query_get(chan, q, 0, 0x1000f010); + break; + default: + assert(0); + break; + } +} + +static INLINE boolean +nv50_query_ready(struct nv50_query *q) +{ + return q->ready || (!q->is64bit && (q->data[0] == q->sequence)); +} + +static INLINE boolean +nv50_query_wait(struct nv50_query *q) +{ + int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD); + if (ret) + return FALSE; + nouveau_bo_unmap(q->bo); + return TRUE; } static boolean nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, - boolean wait, void *vresult) + boolean wait, void *result) { - uint64_t *result = (uint64_t*)vresult; - struct nv50_query *q = nv50_query(pq); - int ret; - - if (!q->ready) { - ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD | - (wait ? 0 : NOUVEAU_BO_NOWAIT)); - if (ret) - return false; - q->result = ((uint32_t *)q->bo->map)[1]; - q->ready = TRUE; - nouveau_bo_unmap(q->bo); - } - - *result = q->result; - return q->ready; + struct nv50_query *q = nv50_query(pq); + uint64_t *res64 = result; + boolean *res8 = result; + uint64_t *data64 = (uint64_t *)q->data; + + if (q->type == PIPE_QUERY_GPU_FINISHED) { + res8[0] = nv50_query_ready(q); + return TRUE; + } + + if (!q->ready) /* update ? */ + q->ready = nv50_query_ready(q); + if (!q->ready) { + struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel; + if (!wait) { + if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */ + FIRE_RING(chan); + return FALSE; + } + if (!nv50_query_wait(q)) + return FALSE; + } + q->ready = TRUE; + + switch (q->type) { + case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */ + res64[0] = q->data[1]; + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */ + case PIPE_QUERY_PRIMITIVES_EMITTED: /* u64 count, u64 time */ + res64[0] = data64[0]; + break; + case PIPE_QUERY_SO_STATISTICS: + res64[0] = data64[0]; + res64[1] = data64[1]; + break; + case PIPE_QUERY_TIMESTAMP_DISJOINT: /* u32 sequence, u32 0, u64 time */ + res64[0] = 1000000000; + res8[8] = (data64[0] == data64[2]) ? FALSE : TRUE; + break; + case PIPE_QUERY_TIME_ELAPSED: + res64[0] = data64[1] - data64[3]; + break; + default: + return FALSE; + } + + return TRUE; } static void nv50_render_condition(struct pipe_context *pipe, - struct pipe_query *pq, uint mode) + struct pipe_query *pq, uint mode) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nv50_query *q; - - if (!pq) { - BEGIN_RING(chan, tesla, NV50TCL_COND_MODE, 1); - OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS); - return; - } - q = nv50_query(pq); - - if (mode == PIPE_RENDER_COND_WAIT || - mode == PIPE_RENDER_COND_BY_REGION_WAIT) { - /* XXX: big fence, FIFO semaphore might be better */ - BEGIN_RING(chan, tesla, 0x0110, 1); - OUT_RING (chan, 0); - } - - BEGIN_RING(chan, tesla, NV50TCL_COND_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RING (chan, NV50TCL_COND_MODE_RES); + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_query *q; + + if (!pq) { + BEGIN_RING(chan, RING_3D(COND_MODE), 1); + OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS); + return; + } + q = nv50_query(pq); + + if (mode == PIPE_RENDER_COND_WAIT || + mode == PIPE_RENDER_COND_BY_REGION_WAIT) { + BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1); + OUT_RING (chan, 0); + } + + MARK_RING (chan, 4, 2); + BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RING (chan, NV50_3D_COND_MODE_RES_NON_ZERO); } void nv50_init_query_functions(struct nv50_context *nv50) { - nv50->pipe.create_query = nv50_query_create; - nv50->pipe.destroy_query = nv50_query_destroy; - nv50->pipe.begin_query = nv50_query_begin; - nv50->pipe.end_query = nv50_query_end; - nv50->pipe.get_query_result = nv50_query_result; - nv50->pipe.render_condition = nv50_render_condition; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->create_query = nv50_query_create; + pipe->destroy_query = nv50_query_destroy; + pipe->begin_query = nv50_query_begin; + pipe->end_query = nv50_query_end; + pipe->get_query_result = nv50_query_result; + pipe->render_condition = nv50_render_condition; } diff --git a/src/gallium/drivers/nv50/nv50_reg.h b/src/gallium/drivers/nv50/nv50_reg.h deleted file mode 100644 index 949838b33f5..00000000000 --- a/src/gallium/drivers/nv50/nv50_reg.h +++ /dev/null @@ -1,1827 +0,0 @@ -/************************************************************************* - - Autogenerated file, do not edit ! - - This file was generated by renouveau-gen from renouveau.xml, the - XML database of nvidia objects and methods. renouveau-gen and - renouveau.xml can be found in CVS module renouveau of sourceforge.net - project nouveau: - -cvs -z3 -d:pserver:[email protected]:/cvsroot/nouveau co -P renouveau - -************************************************************************** - - Copyright (C) 2006-2008 : - Dmitry Baryshkov, - Laurent Carlier, - Matthieu Castet, - Dawid Gajownik, - Jeremy Kolb, - Stephane Loeuillet, - Patrice Mandin, - Stephane Marchesin, - Serge Martin, - Sylvain Munaut, - Simon Raffeiner, - Ben Skeggs, - Erik Waling, - koala_br, - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*************************************************************************/ - - -#ifndef NOUVEAU_REG_H -#define NOUVEAU_REG_H 1 - - -#define NV04_MEMORY_TO_MEMORY_FORMAT 0x00000039 - -#define NV04_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 -#define NV04_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 -#define NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 -#define NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN 0x00000184 -#define NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT 0x00000188 -#define NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c -#define NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT 0x00000310 -#define NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_IN 0x00000314 -#define NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT 0x00000318 -#define NV04_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN 0x0000031c -#define NV04_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT 0x00000320 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT 0x00000324 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_INPUT_INC_SHIFT 0 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_INPUT_INC_MASK 0x000000ff -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_SHIFT 8 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_MASK 0x0000ff00 -#define NV04_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY 0x00000328 - - -#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 - -#define NV50_MEMORY_TO_MEMORY_FORMAT_SERIALIZE 0x00000110 -#define NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN 0x00000200 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_MODE_IN 0x00000204 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_PITCH_IN 0x00000208 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_HEIGHT_IN 0x0000020c -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_DEPTH_IN 0x00000210 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Z 0x00000214 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN 0x00000218 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_X_SHIFT 0 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_X_MASK 0x0000ffff -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Y_SHIFT 16 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Y_MASK 0xffff0000 -#define NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT 0x0000021c -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_MODE_OUT 0x00000220 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_PITCH_OUT 0x00000224 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_HEIGHT_OUT 0x00000228 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_DEPTH_OUT 0x0000022c -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Z 0x00000230 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT 0x00000234 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_X_SHIFT 0 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_X_MASK 0x0000ffff -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Y_SHIFT 16 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Y_MASK 0xffff0000 -#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 -#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c - - -#define NV50_2D 0x0000502d - -#define NV50_2D_NOP 0x00000100 -#define NV50_2D_NOTIFY 0x00000104 -#define NV50_2D_SERIALIZE 0x00000110 -#define NV50_2D_DMA_NOTIFY 0x00000180 -#define NV50_2D_DMA_DST 0x00000184 -#define NV50_2D_DMA_SRC 0x00000188 -#define NV50_2D_DMA_COND 0x0000018c -#define NV50_2D_DST_FORMAT 0x00000200 -#define NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_DST_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_DST_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_DST_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_DST_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_DST_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_DST_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_DST_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_DST_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_DST_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_DST_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_DST_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_DST_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_DST_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_DST_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_DST_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_DST_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_DST_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_DST_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_DST_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_DST_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_DST_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_DST_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_DST_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_DST_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_DST_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_DST_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_DST_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_DST_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_DST_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_DST_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_DST_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_DST_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_DST_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_DST_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_DST_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_DST_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_DST_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_DST_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_DST_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_DST_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_DST_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_DST_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_DST_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_DST_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_DST_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_DST_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_DST_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_DST_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_DST_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_DST_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_DST_LINEAR 0x00000204 -#define NV50_2D_DST_TILE_MODE 0x00000208 -#define NV50_2D_DST_DEPTH 0x0000020c -#define NV50_2D_DST_LAYER 0x00000210 -#define NV50_2D_DST_PITCH 0x00000214 -#define NV50_2D_DST_WIDTH 0x00000218 -#define NV50_2D_DST_HEIGHT 0x0000021c -#define NV50_2D_DST_ADDRESS_HIGH 0x00000220 -#define NV50_2D_DST_ADDRESS_LOW 0x00000224 -#define NV50_2D_SRC_FORMAT 0x00000230 -#define NV50_2D_SRC_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_SRC_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_SRC_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_SRC_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_SRC_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_SRC_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_SRC_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_SRC_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_SRC_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_SRC_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_SRC_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_SRC_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_SRC_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_SRC_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_SRC_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_SRC_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_SRC_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_SRC_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_SRC_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_SRC_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_SRC_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_SRC_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_SRC_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_SRC_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_SRC_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_SRC_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_SRC_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_SRC_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_SRC_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_SRC_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_SRC_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_SRC_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_SRC_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_SRC_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_SRC_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_SRC_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_SRC_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_SRC_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_SRC_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_SRC_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_SRC_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_SRC_LINEAR 0x00000234 -#define NV50_2D_SRC_TILE_MODE 0x00000238 -#define NV50_2D_SRC_DEPTH 0x0000023c -#define NV50_2D_SRC_LAYER 0x00000240 -#define NV50_2D_SRC_PITCH 0x00000244 -#define NV50_2D_SRC_WIDTH 0x00000248 -#define NV50_2D_SRC_HEIGHT 0x0000024c -#define NV50_2D_SRC_ADDRESS_HIGH 0x00000250 -#define NV50_2D_SRC_ADDRESS_LOW 0x00000254 -#define NV50_2D_COND_ADDRESS_HIGH 0x00000264 -#define NV50_2D_COND_ADDRESS_LOW 0x00000268 -#define NV50_2D_COND_MODE 0x0000026c -#define NV50_2D_COND_MODE_NEVER 0x00000000 -#define NV50_2D_COND_MODE_ALWAYS 0x00000001 -#define NV50_2D_COND_MODE_RES 0x00000002 -#define NV50_2D_COND_MODE_NOT_RES_AND_NOT_ID 0x00000003 -#define NV50_2D_COND_MODE_RES_OR_ID 0x00000004 -#define NV50_2D_CLIP_X 0x00000280 -#define NV50_2D_CLIP_Y 0x00000284 -#define NV50_2D_CLIP_W 0x00000288 -#define NV50_2D_CLIP_H 0x0000028c -#define NV50_2D_CLIP_ENABLE 0x00000290 -#define NV50_2D_COLOR_KEY_FORMAT 0x00000294 -#define NV50_2D_COLOR_KEY_FORMAT_16BPP 0x00000000 -#define NV50_2D_COLOR_KEY_FORMAT_15BPP 0x00000001 -#define NV50_2D_COLOR_KEY_FORMAT_24BPP 0x00000002 -#define NV50_2D_COLOR_KEY_FORMAT_30BPP 0x00000003 -#define NV50_2D_COLOR_KEY_FORMAT_8BPP 0x00000004 -#define NV50_2D_COLOR_KEY_FORMAT_16BPP2 0x00000005 -#define NV50_2D_COLOR_KEY_FORMAT_32BPP 0x00000006 -#define NV50_2D_COLOR_KEY 0x00000298 -#define NV50_2D_COLOR_KEY_ENABLE 0x0000029c -#define NV50_2D_ROP 0x000002a0 -#define NV50_2D_OPERATION 0x000002ac -#define NV50_2D_OPERATION_SRCCOPY_AND 0x00000000 -#define NV50_2D_OPERATION_ROP_AND 0x00000001 -#define NV50_2D_OPERATION_BLEND_AND 0x00000002 -#define NV50_2D_OPERATION_SRCCOPY 0x00000003 -#define NV50_2D_OPERATION_SRCCOPY_PREMULT 0x00000004 -#define NV50_2D_OPERATION_BLEND_PREMULT 0x00000005 -#define NV50_2D_PATTERN_FORMAT 0x000002e8 -#define NV50_2D_PATTERN_FORMAT_16BPP 0x00000000 -#define NV50_2D_PATTERN_FORMAT_15BPP 0x00000001 -#define NV50_2D_PATTERN_FORMAT_32BPP 0x00000002 -#define NV50_2D_PATTERN_FORMAT_8BPP 0x00000003 -#define NV50_2D_PATTERN_COLOR(x) (0x000002f0+((x)*4)) -#define NV50_2D_PATTERN_COLOR__SIZE 0x00000002 -#define NV50_2D_PATTERN_BITMAP(x) (0x000002f8+((x)*4)) -#define NV50_2D_PATTERN_BITMAP__SIZE 0x00000002 -#define NV50_2D_DRAW_SHAPE 0x00000580 -#define NV50_2D_DRAW_SHAPE_POINTS 0x00000000 -#define NV50_2D_DRAW_SHAPE_LINES 0x00000001 -#define NV50_2D_DRAW_SHAPE_LINE_STRIP 0x00000002 -#define NV50_2D_DRAW_SHAPE_TRIANGLES 0x00000003 -#define NV50_2D_DRAW_SHAPE_RECTANGLES 0x00000004 -#define NV50_2D_DRAW_COLOR_FORMAT 0x00000584 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_DRAW_COLOR_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_DRAW_COLOR_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_DRAW_COLOR_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_DRAW_COLOR_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_DRAW_COLOR_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_DRAW_COLOR_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_DRAW_COLOR_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_DRAW_COLOR_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_DRAW_COLOR_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_DRAW_COLOR_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_DRAW_COLOR_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_DRAW_COLOR_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_DRAW_COLOR_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_DRAW_COLOR_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_DRAW_COLOR_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_DRAW_COLOR_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_DRAW_COLOR_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_DRAW_COLOR_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_DRAW_COLOR_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_DRAW_COLOR_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_DRAW_COLOR 0x00000588 -#define NV50_2D_DRAW_POINT16 0x000005e0 -#define NV50_2D_DRAW_POINT16_X_SHIFT 0 -#define NV50_2D_DRAW_POINT16_X_MASK 0x0000ffff -#define NV50_2D_DRAW_POINT16_Y_SHIFT 16 -#define NV50_2D_DRAW_POINT16_Y_MASK 0xffff0000 -#define NV50_2D_DRAW_POINT32_X(x) (0x00000600+((x)*8)) -#define NV50_2D_DRAW_POINT32_X__SIZE 0x00000040 -#define NV50_2D_DRAW_POINT32_Y(x) (0x00000604+((x)*8)) -#define NV50_2D_DRAW_POINT32_Y__SIZE 0x00000040 -#define NV50_2D_SIFC_BITMAP_ENABLE 0x00000800 -#define NV50_2D_SIFC_FORMAT 0x00000804 -#define NV50_2D_SIFC_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_SIFC_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_SIFC_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_SIFC_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_SIFC_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_SIFC_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_SIFC_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_SIFC_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_SIFC_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_SIFC_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_SIFC_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_SIFC_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_SIFC_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_SIFC_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_SIFC_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_SIFC_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_SIFC_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_SIFC_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_SIFC_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_SIFC_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_SIFC_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_SIFC_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_SIFC_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_SIFC_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_SIFC_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_SIFC_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_SIFC_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_SIFC_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_SIFC_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_SIFC_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_SIFC_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_SIFC_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_SIFC_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_SIFC_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_SIFC_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_SIFC_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_SIFC_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_SIFC_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_SIFC_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_SIFC_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_SIFC_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_SIFC_BITMAP_UNK808 0x00000808 -#define NV50_2D_SIFC_BITMAP_LSB_FIRST 0x0000080c -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE 0x00000810 -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_PACKED 0x00000000 -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE 0x00000001 -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_WORD 0x00000002 -#define NV50_2D_SIFC_BITMAP_COLOR_BIT0 0x00000814 -#define NV50_2D_SIFC_BITMAP_COLOR_BIT1 0x00000818 -#define NV50_2D_SIFC_BITMAP_WRITE_BIT0_ENABLE 0x0000081c -#define NV50_2D_SIFC_WIDTH 0x00000838 -#define NV50_2D_SIFC_HEIGHT 0x0000083c -#define NV50_2D_SIFC_DX_DU_FRACT 0x00000840 -#define NV50_2D_SIFC_DX_DU_INT 0x00000844 -#define NV50_2D_SIFC_DY_DV_FRACT 0x00000848 -#define NV50_2D_SIFC_DY_DV_INT 0x0000084c -#define NV50_2D_SIFC_DST_X_FRACT 0x00000850 -#define NV50_2D_SIFC_DST_X_INT 0x00000854 -#define NV50_2D_SIFC_DST_Y_FRACT 0x00000858 -#define NV50_2D_SIFC_DST_Y_INT 0x0000085c -#define NV50_2D_SIFC_DATA 0x00000860 -#define NV50_2D_BLIT_DST_X 0x000008b0 -#define NV50_2D_BLIT_DST_Y 0x000008b4 -#define NV50_2D_BLIT_DST_W 0x000008b8 -#define NV50_2D_BLIT_DST_H 0x000008bc -#define NV50_2D_BLIT_DU_DX_FRACT 0x000008c0 -#define NV50_2D_BLIT_DU_DX_INT 0x000008c4 -#define NV50_2D_BLIT_DV_DY_FRACT 0x000008c8 -#define NV50_2D_BLIT_DV_DY_INT 0x000008cc -#define NV50_2D_BLIT_SRC_X_FRACT 0x000008d0 -#define NV50_2D_BLIT_SRC_X_INT 0x000008d4 -#define NV50_2D_BLIT_SRC_Y_FRACT 0x000008d8 -#define NV50_2D_BLIT_SRC_Y_INT 0x000008dc - - -#define NV50TCL 0x00005097 - -#define NV50TCL_NOP 0x00000100 -#define NV50TCL_NOTIFY 0x00000104 -#define NV50TCL_SERIALIZE 0x00000110 -#define NV50TCL_DMA_NOTIFY 0x00000180 -#define NV50TCL_DMA_ZETA 0x00000184 -#define NV50TCL_DMA_QUERY 0x00000188 -#define NV50TCL_DMA_VTXBUF0 0x0000018c -#define NV50TCL_DMA_LOCAL 0x00000190 -#define NV50TCL_DMA_STACK 0x00000194 -#define NV50TCL_DMA_CODE_CB 0x00000198 -#define NV50TCL_DMA_TSC 0x0000019c -#define NV50TCL_DMA_TIC 0x000001a0 -#define NV50TCL_DMA_TEXTURE 0x000001a4 -#define NV50TCL_DMA_STRMOUT 0x000001a8 -#define NV50TCL_DMA_CLIPID 0x000001ac -#define NV50TCL_DMA_COLOR(x) (0x000001c0+((x)*4)) -#define NV50TCL_DMA_COLOR__SIZE 0x00000008 -#define NV50TCL_RT_ADDRESS_HIGH(x) (0x00000200+((x)*32)) -#define NV50TCL_RT_ADDRESS_HIGH__SIZE 0x00000008 -#define NV50TCL_RT_ADDRESS_LOW(x) (0x00000204+((x)*32)) -#define NV50TCL_RT_ADDRESS_LOW__SIZE 0x00000008 -#define NV50TCL_RT_FORMAT(x) (0x00000208+((x)*32)) -#define NV50TCL_RT_FORMAT__SIZE 0x00000008 -#define NV50TCL_RT_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50TCL_RT_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50TCL_RT_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50TCL_RT_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50TCL_RT_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50TCL_RT_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50TCL_RT_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50TCL_RT_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50TCL_RT_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50TCL_RT_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50TCL_RT_FORMAT_R32G32_SINT 0x000000cc -#define NV50TCL_RT_FORMAT_R32G32_UINT 0x000000cd -#define NV50TCL_RT_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50TCL_RT_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50TCL_RT_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50TCL_RT_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50TCL_RT_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50TCL_RT_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50TCL_RT_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50TCL_RT_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50TCL_RT_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50TCL_RT_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50TCL_RT_FORMAT_R16G16_UNORM 0x000000da -#define NV50TCL_RT_FORMAT_R16G16_SNORM 0x000000db -#define NV50TCL_RT_FORMAT_R16G16_SINT 0x000000dc -#define NV50TCL_RT_FORMAT_R16G16_UINT 0x000000dd -#define NV50TCL_RT_FORMAT_R16G16_FLOAT 0x000000de -#define NV50TCL_RT_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50TCL_RT_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50TCL_RT_FORMAT_R32_FLOAT 0x000000e5 -#define NV50TCL_RT_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50TCL_RT_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50TCL_RT_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50TCL_RT_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50TCL_RT_FORMAT_R8G8_UNORM 0x000000ea -#define NV50TCL_RT_FORMAT_R8G8_SNORM 0x000000eb -#define NV50TCL_RT_FORMAT_R8G8_SINT 0x000000ec -#define NV50TCL_RT_FORMAT_R8G8_UINT 0x000000ed -#define NV50TCL_RT_FORMAT_R16_UNORM 0x000000ee -#define NV50TCL_RT_FORMAT_R16_SNORM 0x000000ef -#define NV50TCL_RT_FORMAT_R16_SINT 0x000000f0 -#define NV50TCL_RT_FORMAT_R16_UINT 0x000000f1 -#define NV50TCL_RT_FORMAT_R16_FLOAT 0x000000f2 -#define NV50TCL_RT_FORMAT_R8_UNORM 0x000000f3 -#define NV50TCL_RT_FORMAT_R8_SNORM 0x000000f4 -#define NV50TCL_RT_FORMAT_R8_SINT 0x000000f5 -#define NV50TCL_RT_FORMAT_R8_UINT 0x000000f6 -#define NV50TCL_RT_FORMAT_A8_UNORM 0x000000f7 -#define NV50TCL_RT_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50TCL_RT_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50TCL_RT_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50TCL_RT_TILE_MODE(x) (0x0000020c+((x)*32)) -#define NV50TCL_RT_TILE_MODE__SIZE 0x00000008 -#define NV50TCL_RT_LAYER_STRIDE(x) (0x00000210+((x)*32)) -#define NV50TCL_RT_LAYER_STRIDE__SIZE 0x00000008 -#define NV50TCL_VTX_ATTR_1F(x) (0x00000300+((x)*4)) -#define NV50TCL_VTX_ATTR_1F__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2H(x) (0x00000340+((x)*4)) -#define NV50TCL_VTX_ATTR_2H__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2H_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_2H_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_2H_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_2H_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_2F_X(x) (0x00000380+((x)*8)) -#define NV50TCL_VTX_ATTR_2F_X__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2F_Y(x) (0x00000384+((x)*8)) -#define NV50TCL_VTX_ATTR_2F_Y__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_3F_X(x) (0x00000400+((x)*16)) -#define NV50TCL_VTX_ATTR_3F_X__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_3F_Y(x) (0x00000404+((x)*16)) -#define NV50TCL_VTX_ATTR_3F_Y__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_3F_Z(x) (0x00000408+((x)*16)) -#define NV50TCL_VTX_ATTR_3F_Z__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_X(x) (0x00000500+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_X__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_Y(x) (0x00000504+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_Y__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_Z(x) (0x00000508+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_Z__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_W(x) (0x0000050c+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_W__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4H_0(x) (0x00000600+((x)*8)) -#define NV50TCL_VTX_ATTR_4H_0__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4H_0_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4H_0_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4H_0_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_4H_0_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4H_1(x) (0x00000604+((x)*8)) -#define NV50TCL_VTX_ATTR_4H_1__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4H_1_Z_SHIFT 0 -#define NV50TCL_VTX_ATTR_4H_1_Z_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4H_1_W_SHIFT 16 -#define NV50TCL_VTX_ATTR_4H_1_W_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_2I(x) (0x00000680+((x)*4)) -#define NV50TCL_VTX_ATTR_2I__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2I_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_2I_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_2I_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_2I_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_2NI(x) (0x000006c0+((x)*4)) -#define NV50TCL_VTX_ATTR_2NI__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2NI_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_2NI_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_2NI_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_2NI_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4I_0(x) (0x00000700+((x)*8)) -#define NV50TCL_VTX_ATTR_4I_0__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4I_0_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4I_0_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4I_0_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_4I_0_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4I_1(x) (0x00000704+((x)*8)) -#define NV50TCL_VTX_ATTR_4I_1__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4I_1_Z_SHIFT 0 -#define NV50TCL_VTX_ATTR_4I_1_Z_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4I_1_W_SHIFT 16 -#define NV50TCL_VTX_ATTR_4I_1_W_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4NI_0(x) (0x00000780+((x)*8)) -#define NV50TCL_VTX_ATTR_4NI_0__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NI_0_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NI_0_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4NI_0_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NI_0_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4NI_1(x) (0x00000784+((x)*8)) -#define NV50TCL_VTX_ATTR_4NI_1__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NI_1_Z_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NI_1_Z_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4NI_1_W_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NI_1_W_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4UB(x) (0x00000800+((x)*4)) -#define NV50TCL_VTX_ATTR_4UB__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4UB_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4UB_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4UB_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4UB_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4UB_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4UB_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4UB_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4UB_W_MASK 0xff000000 -#define NV50TCL_VTX_ATTR_4B(x) (0x00000840+((x)*4)) -#define NV50TCL_VTX_ATTR_4B__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4B_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4B_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4B_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4B_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4B_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4B_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4B_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4B_W_MASK 0xff000000 -#define NV50TCL_VTX_ATTR_4NUB(x) (0x00000880+((x)*4)) -#define NV50TCL_VTX_ATTR_4NUB__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NUB_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NUB_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4NUB_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4NUB_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4NUB_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NUB_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4NUB_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4NUB_W_MASK 0xff000000 -#define NV50TCL_VTX_ATTR_4NB(x) (0x000008c0+((x)*4)) -#define NV50TCL_VTX_ATTR_4NB__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NB_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NB_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4NB_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4NB_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4NB_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NB_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4NB_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4NB_W_MASK 0xff000000 -#define NV50TCL_VERTEX_ARRAY_FORMAT(x) (0x00000900+((x)*16)) -#define NV50TCL_VERTEX_ARRAY_FORMAT__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 0 -#define NV50TCL_VERTEX_ARRAY_FORMAT_STRIDE_MASK 0x00000fff -#define NV50TCL_VERTEX_ARRAY_FORMAT_ENABLE (1 << 29) -#define NV50TCL_VERTEX_ARRAY_START_HIGH(x) (0x00000904+((x)*16)) -#define NV50TCL_VERTEX_ARRAY_START_HIGH__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_START_LOW(x) (0x00000908+((x)*16)) -#define NV50TCL_VERTEX_ARRAY_START_LOW__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_SCALE_X(x) (0x00000a00+((x)*32)) -#define NV50TCL_VIEWPORT_SCALE_X__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_SCALE_Y(x) (0x00000a04+((x)*32)) -#define NV50TCL_VIEWPORT_SCALE_Y__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_SCALE_Z(x) (0x00000a08+((x)*32)) -#define NV50TCL_VIEWPORT_SCALE_Z__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_TRANSLATE_X(x) (0x00000a0c+((x)*32)) -#define NV50TCL_VIEWPORT_TRANSLATE_X__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_TRANSLATE_Y(x) (0x00000a10+((x)*32)) -#define NV50TCL_VIEWPORT_TRANSLATE_Y__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_TRANSLATE_Z(x) (0x00000a14+((x)*32)) -#define NV50TCL_VIEWPORT_TRANSLATE_Z__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_HORIZ(x) (0x00000c00+((x)*16)) -#define NV50TCL_VIEWPORT_HORIZ__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_HORIZ_X_SHIFT 0 -#define NV50TCL_VIEWPORT_HORIZ_X_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_HORIZ_W_SHIFT 16 -#define NV50TCL_VIEWPORT_HORIZ_W_MASK 0xffff0000 -#define NV50TCL_VIEWPORT_VERT(x) (0x00000c04+((x)*16)) -#define NV50TCL_VIEWPORT_VERT__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_VERT_Y_SHIFT 0 -#define NV50TCL_VIEWPORT_VERT_Y_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_VERT_H_SHIFT 16 -#define NV50TCL_VIEWPORT_VERT_H_MASK 0xffff0000 -#define NV50TCL_DEPTH_RANGE_NEAR(x) (0x00000c08+((x)*16)) -#define NV50TCL_DEPTH_RANGE_NEAR__SIZE 0x00000010 -#define NV50TCL_DEPTH_RANGE_FAR(x) (0x00000c0c+((x)*16)) -#define NV50TCL_DEPTH_RANGE_FAR__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_CLIP_HORIZ(x) (0x00000d00+((x)*8)) -#define NV50TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MIN_SHIFT 0 -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MIN_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MAX_SHIFT 16 -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MAX_MASK 0xffff0000 -#define NV50TCL_VIEWPORT_CLIP_VERT(x) (0x00000d04+((x)*8)) -#define NV50TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 -#define NV50TCL_VIEWPORT_CLIP_VERT_MIN_SHIFT 0 -#define NV50TCL_VIEWPORT_CLIP_VERT_MIN_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_CLIP_VERT_MAX_SHIFT 16 -#define NV50TCL_VIEWPORT_CLIP_VERT_MAX_MASK 0xffff0000 -#define NV50TCL_CLIPID_REGION_HORIZ(x) (0x00000d40+((x)*8)) -#define NV50TCL_CLIPID_REGION_HORIZ__SIZE 0x00000004 -#define NV50TCL_CLIPID_REGION_VERT(x) (0x00000d44+((x)*8)) -#define NV50TCL_CLIPID_REGION_VERT__SIZE 0x00000004 -#define NV50TCL_VERTEX_BUFFER_FIRST 0x00000d74 -#define NV50TCL_VERTEX_BUFFER_COUNT 0x00000d78 -#define NV50TCL_CLEAR_COLOR(x) (0x00000d80+((x)*4)) -#define NV50TCL_CLEAR_COLOR__SIZE 0x00000004 -#define NV50TCL_CLEAR_DEPTH 0x00000d90 -#define NV50TCL_STACK_ADDRESS_HIGH 0x00000d94 -#define NV50TCL_STACK_ADDRESS_LOW 0x00000d98 -#define NV50TCL_STACK_SIZE_LOG 0x00000d9c -#define NV50TCL_CLEAR_STENCIL 0x00000da0 -#define NV50TCL_STRMOUT_PRIMITIVE_COUNT 0x00000da8 -#define NV50TCL_POLYGON_MODE_FRONT 0x00000dac -#define NV50TCL_POLYGON_MODE_FRONT_POINT 0x00001b00 -#define NV50TCL_POLYGON_MODE_FRONT_LINE 0x00001b01 -#define NV50TCL_POLYGON_MODE_FRONT_FILL 0x00001b02 -#define NV50TCL_POLYGON_MODE_BACK 0x00000db0 -#define NV50TCL_POLYGON_MODE_BACK_POINT 0x00001b00 -#define NV50TCL_POLYGON_MODE_BACK_LINE 0x00001b01 -#define NV50TCL_POLYGON_MODE_BACK_FILL 0x00001b02 -#define NV50TCL_POLYGON_SMOOTH_ENABLE 0x00000db4 -#define NV50TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000dc0 -#define NV50TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000dc4 -#define NV50TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000dc8 -#define NV50TCL_WATCHDOG_TIMER 0x00000de4 -#define NV50TCL_WINDOW_OFFSET_X 0x00000df8 -#define NV50TCL_WINDOW_OFFSET_Y 0x00000dfc -#define NV50TCL_SCISSOR_ENABLE(x) (0x00000e00+((x)*16)) -#define NV50TCL_SCISSOR_ENABLE__SIZE 0x00000010 -#define NV50TCL_SCISSOR_HORIZ(x) (0x00000e04+((x)*16)) -#define NV50TCL_SCISSOR_HORIZ__SIZE 0x00000010 -#define NV50TCL_SCISSOR_HORIZ_MIN_SHIFT 0 -#define NV50TCL_SCISSOR_HORIZ_MIN_MASK 0x0000ffff -#define NV50TCL_SCISSOR_HORIZ_MAX_SHIFT 16 -#define NV50TCL_SCISSOR_HORIZ_MAX_MASK 0xffff0000 -#define NV50TCL_SCISSOR_VERT(x) (0x00000e08+((x)*16)) -#define NV50TCL_SCISSOR_VERT__SIZE 0x00000010 -#define NV50TCL_SCISSOR_VERT_MIN_SHIFT 0 -#define NV50TCL_SCISSOR_VERT_MIN_MASK 0x0000ffff -#define NV50TCL_SCISSOR_VERT_MAX_SHIFT 16 -#define NV50TCL_SCISSOR_VERT_MAX_MASK 0xffff0000 -#define NV50TCL_CB_ADDR 0x00000f00 -#define NV50TCL_CB_ADDR_ID_SHIFT 8 -#define NV50TCL_CB_ADDR_ID_MASK 0x003fff00 -#define NV50TCL_CB_ADDR_BUFFER_SHIFT 0 -#define NV50TCL_CB_ADDR_BUFFER_MASK 0x0000007f -#define NV50TCL_CB_DATA(x) (0x00000f04+((x)*4)) -#define NV50TCL_CB_DATA__SIZE 0x00000010 -#define NV50TCL_LOCAL_WARPS_LOG_ALLOC 0x00000f44 -#define NV50TCL_LOCAL_WARPS_NO_CLAMP 0x00000f48 -#define NV50TCL_STACK_WARPS_LOG_ALLOC 0x00000f4c -#define NV50TCL_STACK_WARPS_NO_CLAMP 0x00000f50 -#define NV50TCL_STENCIL_BACK_FUNC_REF 0x00000f54 -#define NV50TCL_STENCIL_BACK_MASK 0x00000f58 -#define NV50TCL_STENCIL_BACK_FUNC_MASK 0x00000f5c -#define NV50TCL_GP_ADDRESS_HIGH 0x00000f70 -#define NV50TCL_GP_ADDRESS_LOW 0x00000f74 -#define NV50TCL_VP_ADDRESS_HIGH 0x00000f7c -#define NV50TCL_VP_ADDRESS_LOW 0x00000f80 -#define NV50TCL_VERTEX_RUNOUT_HIGH 0x00000f84 -#define NV50TCL_VERTEX_RUNOUT_LOW 0x00000f88 -#define NV50TCL_DEPTH_BOUNDS(x) (0x00000f9c+((x)*4)) -#define NV50TCL_DEPTH_BOUNDS__SIZE 0x00000002 -#define NV50TCL_FP_ADDRESS_HIGH 0x00000fa4 -#define NV50TCL_FP_ADDRESS_LOW 0x00000fa8 -#define NV50TCL_MSAA_MASK(x) (0x00000fbc+((x)*4)) -#define NV50TCL_MSAA_MASK__SIZE 0x00000004 -#define NV50TCL_CLIPID_ADDRESS_HIGH 0x00000fcc -#define NV50TCL_CLIPID_ADDRESS_LOW 0x00000fd0 -#define NV50TCL_ZETA_ADDRESS_HIGH 0x00000fe0 -#define NV50TCL_ZETA_ADDRESS_LOW 0x00000fe4 -#define NV50TCL_ZETA_FORMAT 0x00000fe8 -#define NV50TCL_ZETA_FORMAT_Z32_FLOAT 0x0000000a -#define NV50TCL_ZETA_FORMAT_Z16_UNORM 0x00000013 -#define NV50TCL_ZETA_FORMAT_Z24S8_UNORM 0x00000014 -#define NV50TCL_ZETA_FORMAT_X8Z24_UNORM 0x00000015 -#define NV50TCL_ZETA_FORMAT_S8Z24_UNORM 0x00000016 -#define NV50TCL_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM 0x00000019 -#define NV50TCL_ZETA_TILE_MODE 0x00000fec -#define NV50TCL_ZETA_LAYER_STRIDE 0x00000ff0 -#define NV50TCL_SCREEN_SCISSOR_HORIZ 0x00000ff4 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_W_SHIFT 16 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_W_MASK 0xffff0000 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_X_SHIFT 0 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_X_MASK 0x0000ffff -#define NV50TCL_SCREEN_SCISSOR_VERT 0x00000ff8 -#define NV50TCL_SCREEN_SCISSOR_VERT_H_SHIFT 16 -#define NV50TCL_SCREEN_SCISSOR_VERT_H_MASK 0xffff0000 -#define NV50TCL_SCREEN_SCISSOR_VERT_Y_SHIFT 0 -#define NV50TCL_SCREEN_SCISSOR_VERT_Y_MASK 0x0000ffff -#define NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(x) (0x00001080+((x)*8)) -#define NV50TCL_VERTEX_ARRAY_LIMIT_HIGH__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_LIMIT_LOW(x) (0x00001084+((x)*8)) -#define NV50TCL_VERTEX_ARRAY_LIMIT_LOW__SIZE 0x00000010 -#define NV50TCL_RT_CONTROL 0x0000121c -#define NV50TCL_RT_CONTROL_COUNT_SHIFT 0 -#define NV50TCL_RT_CONTROL_COUNT_MASK 0x0000000f -#define NV50TCL_RT_CONTROL_MAP0_SHIFT 4 -#define NV50TCL_RT_CONTROL_MAP0_MASK 0x00000070 -#define NV50TCL_RT_CONTROL_MAP1_SHIFT 7 -#define NV50TCL_RT_CONTROL_MAP1_MASK 0x00000380 -#define NV50TCL_RT_CONTROL_MAP2_SHIFT 10 -#define NV50TCL_RT_CONTROL_MAP2_MASK 0x00001c00 -#define NV50TCL_RT_CONTROL_MAP3_SHIFT 13 -#define NV50TCL_RT_CONTROL_MAP3_MASK 0x0000e000 -#define NV50TCL_RT_CONTROL_MAP4_SHIFT 16 -#define NV50TCL_RT_CONTROL_MAP4_MASK 0x00070000 -#define NV50TCL_RT_CONTROL_MAP5_SHIFT 19 -#define NV50TCL_RT_CONTROL_MAP5_MASK 0x00380000 -#define NV50TCL_RT_CONTROL_MAP6_SHIFT 22 -#define NV50TCL_RT_CONTROL_MAP6_MASK 0x01c00000 -#define NV50TCL_RT_CONTROL_MAP7_SHIFT 25 -#define NV50TCL_RT_CONTROL_MAP7_MASK 0x0e000000 -#define NV50TCL_RT_ARRAY_MODE 0x00001224 -#define NV50TCL_RT_ARRAY_MODE_LAYERS_SHIFT 0 -#define NV50TCL_RT_ARRAY_MODE_LAYERS_MASK 0x0000ffff -#define NV50TCL_RT_ARRAY_MODE_VOLUME (1 << 16) -#define NV50TCL_ZETA_HORIZ 0x00001228 -#define NV50TCL_ZETA_VERT 0x0000122c -#define NV50TCL_ZETA_ARRAY_MODE 0x00001230 -#define NV50TCL_ZETA_ARRAY_MODE_LAYERS_SHIFT 0 -#define NV50TCL_ZETA_ARRAY_MODE_LAYERS_MASK 0x0000ffff -#define NV50TCL_ZETA_ARRAY_MODE_UNK (1 << 16) -#define NV50TCL_LINKED_TSC 0x00001234 -#define NV50TCL_RT_HORIZ(x) (0x00001240+((x)*8)) -#define NV50TCL_RT_HORIZ__SIZE 0x00000008 -#define NV50TCL_RT_VERT(x) (0x00001244+((x)*8)) -#define NV50TCL_RT_VERT__SIZE 0x00000008 -#define NV50TCL_CB_DEF_ADDRESS_HIGH 0x00001280 -#define NV50TCL_CB_DEF_ADDRESS_LOW 0x00001284 -#define NV50TCL_CB_DEF_SET 0x00001288 -#define NV50TCL_CB_DEF_SET_SIZE_SHIFT 0 -#define NV50TCL_CB_DEF_SET_SIZE_MASK 0x0000ffff -#define NV50TCL_CB_DEF_SET_BUFFER_SHIFT 16 -#define NV50TCL_CB_DEF_SET_BUFFER_MASK 0x007f0000 -#define NV50TCL_STRMOUT_BUFFERS_CTRL 0x00001294 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_INTERLEAVED (1 << 0) -#define NV50TCL_STRMOUT_BUFFERS_CTRL_SEPARATE_SHIFT 4 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_SEPARATE_MASK 0x000000f0 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_STRIDE_SHIFT 8 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_STRIDE_MASK 0x0000ff00 -#define NV50TCL_FP_RESULT_COUNT 0x00001298 -#define NV50TCL_DEPTH_TEST_ENABLE 0x000012cc -#define NV50TCL_SHADE_MODEL 0x000012d4 -#define NV50TCL_SHADE_MODEL_FLAT 0x00001d00 -#define NV50TCL_SHADE_MODEL_SMOOTH 0x00001d01 -#define NV50TCL_LOCAL_ADDRESS_HIGH 0x000012d8 -#define NV50TCL_LOCAL_ADDRESS_LOW 0x000012dc -#define NV50TCL_LOCAL_SIZE_LOG 0x000012e0 -#define NV50TCL_DEPTH_WRITE_ENABLE 0x000012e8 -#define NV50TCL_ALPHA_TEST_ENABLE 0x000012ec -#define NV50TCL_PM_SET(x) (0x000012f0+((x)*4)) -#define NV50TCL_PM_SET__SIZE 0x00000004 -#define NV50TCL_VB_ELEMENT_U8_SETUP 0x00001300 -#define NV50TCL_VB_ELEMENT_U8_SETUP_OFFSET_SHIFT 30 -#define NV50TCL_VB_ELEMENT_U8_SETUP_OFFSET_MASK 0xc0000000 -#define NV50TCL_VB_ELEMENT_U8_SETUP_COUNT_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U8_SETUP_COUNT_MASK 0x3fffffff -#define NV50TCL_VB_ELEMENT_U8 0x00001304 -#define NV50TCL_VB_ELEMENT_U8_I0_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U8_I0_MASK 0x000000ff -#define NV50TCL_VB_ELEMENT_U8_I1_SHIFT 8 -#define NV50TCL_VB_ELEMENT_U8_I1_MASK 0x0000ff00 -#define NV50TCL_VB_ELEMENT_U8_I2_SHIFT 16 -#define NV50TCL_VB_ELEMENT_U8_I2_MASK 0x00ff0000 -#define NV50TCL_VB_ELEMENT_U8_I3_SHIFT 24 -#define NV50TCL_VB_ELEMENT_U8_I3_MASK 0xff000000 -#define NV50TCL_DEPTH_TEST_FUNC 0x0000130c -#define NV50TCL_DEPTH_TEST_FUNC_NEVER 0x00000200 -#define NV50TCL_DEPTH_TEST_FUNC_LESS 0x00000201 -#define NV50TCL_DEPTH_TEST_FUNC_EQUAL 0x00000202 -#define NV50TCL_DEPTH_TEST_FUNC_LEQUAL 0x00000203 -#define NV50TCL_DEPTH_TEST_FUNC_GREATER 0x00000204 -#define NV50TCL_DEPTH_TEST_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_DEPTH_TEST_FUNC_GEQUAL 0x00000206 -#define NV50TCL_DEPTH_TEST_FUNC_ALWAYS 0x00000207 -#define NV50TCL_ALPHA_TEST_REF 0x00001310 -#define NV50TCL_ALPHA_TEST_FUNC 0x00001314 -#define NV50TCL_ALPHA_TEST_FUNC_NEVER 0x00000200 -#define NV50TCL_ALPHA_TEST_FUNC_LESS 0x00000201 -#define NV50TCL_ALPHA_TEST_FUNC_EQUAL 0x00000202 -#define NV50TCL_ALPHA_TEST_FUNC_LEQUAL 0x00000203 -#define NV50TCL_ALPHA_TEST_FUNC_GREATER 0x00000204 -#define NV50TCL_ALPHA_TEST_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_ALPHA_TEST_FUNC_GEQUAL 0x00000206 -#define NV50TCL_ALPHA_TEST_FUNC_ALWAYS 0x00000207 -#define NV50TCL_BLEND_COLOR(x) (0x0000131c+((x)*4)) -#define NV50TCL_BLEND_COLOR__SIZE 0x00000004 -#define NV50TCL_TIC_FLUSH 0x00001330 -#define NV50TCL_TSC_FLUSH 0x00001334 -#define NV50TCL_TEX_CACHE_CTL 0x00001338 -#define NV50TCL_BLEND_EQUATION_RGB 0x00001340 -#define NV50TCL_BLEND_EQUATION_RGB_FUNC_ADD 0x00008006 -#define NV50TCL_BLEND_EQUATION_RGB_MIN 0x00008007 -#define NV50TCL_BLEND_EQUATION_RGB_MAX 0x00008008 -#define NV50TCL_BLEND_EQUATION_RGB_FUNC_SUBTRACT 0x0000800a -#define NV50TCL_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT 0x0000800b -#define NV50TCL_BLEND_FUNC_SRC_RGB 0x00001344 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_SRC_RGB_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_FUNC_DST_RGB 0x00001348 -#define NV50TCL_BLEND_FUNC_DST_RGB_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_DST_RGB_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_DST_RGB_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_EQUATION_ALPHA 0x0000134c -#define NV50TCL_BLEND_EQUATION_ALPHA_FUNC_ADD 0x00008006 -#define NV50TCL_BLEND_EQUATION_ALPHA_MIN 0x00008007 -#define NV50TCL_BLEND_EQUATION_ALPHA_MAX 0x00008008 -#define NV50TCL_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT 0x0000800a -#define NV50TCL_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT 0x0000800b -#define NV50TCL_BLEND_FUNC_SRC_ALPHA 0x00001350 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_FUNC_DST_ALPHA 0x00001358 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_ENABLE(x) (0x00001360+((x)*4)) -#define NV50TCL_BLEND_ENABLE__SIZE 0x00000008 -#define NV50TCL_STENCIL_FRONT_ENABLE 0x00001380 -#define NV50TCL_STENCIL_FRONT_OP_FAIL 0x00001384 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_FRONT_OP_FAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL 0x00001388 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS 0x0000138c -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_ZERO 0x00000000 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_INVERT 0x0000150a -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_KEEP 0x00001e00 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_INCR 0x00001e02 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_DECR 0x00001e03 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC 0x00001390 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_NEVER 0x00000200 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_LESS 0x00000201 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_EQUAL 0x00000202 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_LEQUAL 0x00000203 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_GEQUAL 0x00000206 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_ALWAYS 0x00000207 -#define NV50TCL_STENCIL_FRONT_FUNC_REF 0x00001394 -#define NV50TCL_STENCIL_FRONT_MASK 0x00001398 -#define NV50TCL_STENCIL_FRONT_FUNC_MASK 0x0000139c -#define NV50TCL_FRAG_COLOR_CLAMP_EN 0x000013a8 -#define NV50TCL_Y_ORIGIN_BOTTOM 0x000013ac -#define NV50TCL_LINE_WIDTH 0x000013b0 -#define NV50TCL_TEX_LIMITS(x) (0x000013b4+((x)*4)) -#define NV50TCL_TEX_LIMITS__SIZE 0x00000003 -#define NV50TCL_TEX_LIMITS_SAMPLERS_LOG2_SHIFT 0 -#define NV50TCL_TEX_LIMITS_SAMPLERS_LOG2_MASK 0x0000000f -#define NV50TCL_TEX_LIMITS_TEXTURES_LOG2_SHIFT 4 -#define NV50TCL_TEX_LIMITS_TEXTURES_LOG2_MASK 0x000000f0 -#define NV50TCL_POINT_COORD_REPLACE_MAP(x) (0x000013c0+((x)*4)) -#define NV50TCL_POINT_COORD_REPLACE_MAP__SIZE 0x00000008 -#define NV50TCL_VP_START_ID 0x0000140c -#define NV50TCL_GP_START_ID 0x00001410 -#define NV50TCL_FP_START_ID 0x00001414 -#define NV50TCL_GP_VERTEX_OUTPUT_COUNT 0x00001420 -#define NV50TCL_VB_ELEMENT_BASE 0x00001434 -#define NV50TCL_CLEAR_FLAGS 0x0000143c -#define NV50TCL_CLEAR_FLAGS_OGL (1 << 0) -#define NV50TCL_CLEAR_FLAGS_D3D (1 << 4) -#define NV50TCL_INSTANCE_BASE 0x00001438 -#define NV50TCL_CODE_CB_FLUSH 0x00001440 -#define NV50TCL_BIND_TSC(x) (0x00001444+((x)*8)) -#define NV50TCL_BIND_TSC__SIZE 0x00000003 -#define NV50TCL_BIND_TSC_VALID (1 << 0) -#define NV50TCL_BIND_TSC_SAMPLER_SHIFT 4 -#define NV50TCL_BIND_TSC_SAMPLER_MASK 0x000000f0 -#define NV50TCL_BIND_TSC_TSC_SHIFT 12 -#define NV50TCL_BIND_TSC_TSC_MASK 0x001ff000 -#define NV50TCL_BIND_TIC(x) (0x00001448+((x)*8)) -#define NV50TCL_BIND_TIC__SIZE 0x00000003 -#define NV50TCL_BIND_TIC_VALID (1 << 0) -#define NV50TCL_BIND_TIC_TEXTURE_SHIFT 1 -#define NV50TCL_BIND_TIC_TEXTURE_MASK 0x000001fe -#define NV50TCL_BIND_TIC_TIC_SHIFT 9 -#define NV50TCL_BIND_TIC_TIC_MASK 0x7ffffe00 -#define NV50TCL_STRMOUT_MAP(x) (0x00001480+((x)*4)) -#define NV50TCL_STRMOUT_MAP__SIZE 0x00000020 -#define NV50TCL_CLIPID_HEIGHT 0x00001504 -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE 0x00001510 -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_0 (1 << 0) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_1 (1 << 1) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_2 (1 << 2) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_3 (1 << 3) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_4 (1 << 4) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_5 (1 << 5) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_6 (1 << 6) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_7 (1 << 7) -#define NV50TCL_SAMPLECNT_ENABLE 0x00001514 -#define NV50TCL_POINT_SIZE 0x00001518 -#define NV50TCL_POINT_SPRITE_ENABLE 0x00001520 -#define NV50TCL_SAMPLECNT_RESET 0x00001530 -#define NV50TCL_ZETA_ENABLE 0x00001538 -#define NV50TCL_MULTISAMPLE_CTRL 0x0000153c -#define NV50TCL_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE (1 << 0) -#define NV50TCL_MULTISAMPLE_CTRL_ALPHA_TO_ONE (1 << 4) -#define NV50TCL_NOPERSPECTIVE_BITMAP(x) (0x00001540+((x)*4)) -#define NV50TCL_NOPERSPECTIVE_BITMAP__SIZE 0x00000004 -#define NV50TCL_COND_ADDRESS_HIGH 0x00001550 -#define NV50TCL_COND_ADDRESS_LOW 0x00001554 -#define NV50TCL_COND_MODE 0x00001558 -#define NV50TCL_COND_MODE_NEVER 0x00000000 -#define NV50TCL_COND_MODE_ALWAYS 0x00000001 -#define NV50TCL_COND_MODE_RES 0x00000002 -#define NV50TCL_COND_MODE_NOT_RES_AND_NOT_ID 0x00000003 -#define NV50TCL_COND_MODE_RES_OR_ID 0x00000004 -#define NV50TCL_TSC_ADDRESS_HIGH 0x0000155c -#define NV50TCL_TSC_ADDRESS_LOW 0x00001560 -#define NV50TCL_TSC_LIMIT 0x00001564 -#define NV50TCL_POLYGON_OFFSET_FACTOR 0x0000156c -#define NV50TCL_LINE_SMOOTH_ENABLE 0x00001570 -#define NV50TCL_TIC_ADDRESS_HIGH 0x00001574 -#define NV50TCL_TIC_ADDRESS_LOW 0x00001578 -#define NV50TCL_TIC_LIMIT 0x0000157c -#define NV50TCL_PM_CONTROL(x) (0x00001580+((x)*4)) -#define NV50TCL_PM_CONTROL__SIZE 0x00000004 -#define NV50TCL_PM_CONTROL_UNK0 (1 << 0) -#define NV50TCL_PM_CONTROL_UNK1_SHIFT 4 -#define NV50TCL_PM_CONTROL_UNK1_MASK 0x00000070 -#define NV50TCL_PM_CONTROL_UNK2_SHIFT 8 -#define NV50TCL_PM_CONTROL_UNK2_MASK 0xffffff00 -#define NV50TCL_STENCIL_BACK_ENABLE 0x00001594 -#define NV50TCL_STENCIL_BACK_OP_FAIL 0x00001598 -#define NV50TCL_STENCIL_BACK_OP_FAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_BACK_OP_FAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_BACK_OP_FAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_BACK_OP_FAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_BACK_OP_FAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_BACK_OP_FAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_BACK_OP_FAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_BACK_OP_FAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL 0x0000159c -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_BACK_OP_ZPASS 0x000015a0 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_ZERO 0x00000000 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_INVERT 0x0000150a -#define NV50TCL_STENCIL_BACK_OP_ZPASS_KEEP 0x00001e00 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_INCR 0x00001e02 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_DECR 0x00001e03 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC 0x000015a4 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_NEVER 0x00000200 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_LESS 0x00000201 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_EQUAL 0x00000202 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_LEQUAL 0x00000203 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 -#define NV50TCL_FRAMEBUFFER_SRGB 0x000015b8 -#define NV50TCL_POLYGON_OFFSET_UNITS 0x000015bc -#define NV50TCL_GP_BUILTIN_RESULT_EN 0x000015cc -#define NV50TCL_GP_BUILTIN_RESULT_EN_VPORT_IDX (1 << 0) -#define NV50TCL_GP_BUILTIN_RESULT_EN_LAYER_IDX (1 << 16) -#define NV50TCL_MULTISAMPLE_MODE 0x000015d0 -#define NV50TCL_MULTISAMPLE_MODE_1X 0x00000000 -#define NV50TCL_MULTISAMPLE_MODE_2XMS 0x00000001 -#define NV50TCL_MULTISAMPLE_MODE_4XMS 0x00000002 -#define NV50TCL_MULTISAMPLE_MODE_8XMS 0x00000004 -#define NV50TCL_MULTISAMPLE_MODE_4XMS_4XCS 0x00000008 -#define NV50TCL_MULTISAMPLE_MODE_4XMS_12XCS 0x00000009 -#define NV50TCL_MULTISAMPLE_MODE_8XMS_8XCS 0x0000000a -#define NV50TCL_VERTEX_BEGIN 0x000015dc -#define NV50TCL_VERTEX_BEGIN_POINTS 0x00000000 -#define NV50TCL_VERTEX_BEGIN_LINES 0x00000001 -#define NV50TCL_VERTEX_BEGIN_LINE_LOOP 0x00000002 -#define NV50TCL_VERTEX_BEGIN_LINE_STRIP 0x00000003 -#define NV50TCL_VERTEX_BEGIN_TRIANGLES 0x00000004 -#define NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP 0x00000005 -#define NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN 0x00000006 -#define NV50TCL_VERTEX_BEGIN_QUADS 0x00000007 -#define NV50TCL_VERTEX_BEGIN_QUAD_STRIP 0x00000008 -#define NV50TCL_VERTEX_BEGIN_POLYGON 0x00000009 -#define NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY 0x0000000a -#define NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY 0x0000000b -#define NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY 0x0000000c -#define NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY 0x0000000d -#define NV50TCL_VERTEX_BEGIN_PATCHES 0x0000000e -#define NV50TCL_VERTEX_END 0x000015e0 -#define NV50TCL_EDGEFLAG_ENABLE 0x000015e4 -#define NV50TCL_VB_ELEMENT_U32 0x000015e8 -#define NV50TCL_VB_ELEMENT_U16_SETUP 0x000015ec -#define NV50TCL_VB_ELEMENT_U16_SETUP_OFFSET_SHIFT 30 -#define NV50TCL_VB_ELEMENT_U16_SETUP_OFFSET_MASK 0xc0000000 -#define NV50TCL_VB_ELEMENT_U16_SETUP_COUNT_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U16_SETUP_COUNT_MASK 0x3fffffff -#define NV50TCL_VB_ELEMENT_U16 0x000015f0 -#define NV50TCL_VB_ELEMENT_U16_I0_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U16_I0_MASK 0x0000ffff -#define NV50TCL_VB_ELEMENT_U16_I1_SHIFT 16 -#define NV50TCL_VB_ELEMENT_U16_I1_MASK 0xffff0000 -#define NV50TCL_VERTEX_BASE_HIGH 0x000015f4 -#define NV50TCL_VERTEX_BASE_LOW 0x000015f8 -#define NV50TCL_VERTEX_DATA 0x00001640 -#define NV50TCL_PRIM_RESTART_ENABLE 0x00001644 -#define NV50TCL_PRIM_RESTART_INDEX 0x00001648 -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN 0x0000164c -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID (1 << 0) -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_INSTANCE_ID (1 << 4) -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID (1 << 8) -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_UNK12 (1 << 12) -#define NV50TCL_VP_ATTR_EN_0 0x00001650 -#define NV50TCL_VP_ATTR_EN_0_7_SHIFT 28 -#define NV50TCL_VP_ATTR_EN_0_7_MASK 0xf0000000 -#define NV50TCL_VP_ATTR_EN_0_7_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNNN 0x10000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYNN 0x20000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYNN 0x30000000 -#define NV50TCL_VP_ATTR_EN_0_7_NNZN 0x40000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNZN 0x50000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYZN 0x60000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYZN 0x70000000 -#define NV50TCL_VP_ATTR_EN_0_7_NNNW 0x80000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNNW 0x90000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYNW 0xa0000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYNW 0xb0000000 -#define NV50TCL_VP_ATTR_EN_0_7_NNZW 0xc0000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNZW 0xd0000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYZW 0xe0000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYZW 0xf0000000 -#define NV50TCL_VP_ATTR_EN_0_6_SHIFT 24 -#define NV50TCL_VP_ATTR_EN_0_6_MASK 0x0f000000 -#define NV50TCL_VP_ATTR_EN_0_6_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNNN 0x01000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYNN 0x02000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYNN 0x03000000 -#define NV50TCL_VP_ATTR_EN_0_6_NNZN 0x04000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNZN 0x05000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYZN 0x06000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYZN 0x07000000 -#define NV50TCL_VP_ATTR_EN_0_6_NNNW 0x08000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNNW 0x09000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYNW 0x0a000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYNW 0x0b000000 -#define NV50TCL_VP_ATTR_EN_0_6_NNZW 0x0c000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNZW 0x0d000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYZW 0x0e000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYZW 0x0f000000 -#define NV50TCL_VP_ATTR_EN_0_5_SHIFT 20 -#define NV50TCL_VP_ATTR_EN_0_5_MASK 0x00f00000 -#define NV50TCL_VP_ATTR_EN_0_5_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_5_XNNN 0x00100000 -#define NV50TCL_VP_ATTR_EN_0_5_NYNN 0x00200000 -#define NV50TCL_VP_ATTR_EN_0_5_XYNN 0x00300000 -#define NV50TCL_VP_ATTR_EN_0_5_NNZN 0x00400000 -#define NV50TCL_VP_ATTR_EN_0_5_XNZN 0x00500000 -#define NV50TCL_VP_ATTR_EN_0_5_NYZN 0x00600000 -#define NV50TCL_VP_ATTR_EN_0_5_XYZN 0x00700000 -#define NV50TCL_VP_ATTR_EN_0_5_NNNW 0x00800000 -#define NV50TCL_VP_ATTR_EN_0_5_XNNW 0x00900000 -#define NV50TCL_VP_ATTR_EN_0_5_NYNW 0x00a00000 -#define NV50TCL_VP_ATTR_EN_0_5_XYNW 0x00b00000 -#define NV50TCL_VP_ATTR_EN_0_5_NNZW 0x00c00000 -#define NV50TCL_VP_ATTR_EN_0_5_XNZW 0x00d00000 -#define NV50TCL_VP_ATTR_EN_0_5_NYZW 0x00e00000 -#define NV50TCL_VP_ATTR_EN_0_5_XYZW 0x00f00000 -#define NV50TCL_VP_ATTR_EN_0_4_SHIFT 16 -#define NV50TCL_VP_ATTR_EN_0_4_MASK 0x000f0000 -#define NV50TCL_VP_ATTR_EN_0_4_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_4_XNNN 0x00010000 -#define NV50TCL_VP_ATTR_EN_0_4_NYNN 0x00020000 -#define NV50TCL_VP_ATTR_EN_0_4_XYNN 0x00030000 -#define NV50TCL_VP_ATTR_EN_0_4_NNZN 0x00040000 -#define NV50TCL_VP_ATTR_EN_0_4_XNZN 0x00050000 -#define NV50TCL_VP_ATTR_EN_0_4_NYZN 0x00060000 -#define NV50TCL_VP_ATTR_EN_0_4_XYZN 0x00070000 -#define NV50TCL_VP_ATTR_EN_0_4_NNNW 0x00080000 -#define NV50TCL_VP_ATTR_EN_0_4_XNNW 0x00090000 -#define NV50TCL_VP_ATTR_EN_0_4_NYNW 0x000a0000 -#define NV50TCL_VP_ATTR_EN_0_4_XYNW 0x000b0000 -#define NV50TCL_VP_ATTR_EN_0_4_NNZW 0x000c0000 -#define NV50TCL_VP_ATTR_EN_0_4_XNZW 0x000d0000 -#define NV50TCL_VP_ATTR_EN_0_4_NYZW 0x000e0000 -#define NV50TCL_VP_ATTR_EN_0_4_XYZW 0x000f0000 -#define NV50TCL_VP_ATTR_EN_0_3_SHIFT 12 -#define NV50TCL_VP_ATTR_EN_0_3_MASK 0x0000f000 -#define NV50TCL_VP_ATTR_EN_0_3_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_3_XNNN 0x00001000 -#define NV50TCL_VP_ATTR_EN_0_3_NYNN 0x00002000 -#define NV50TCL_VP_ATTR_EN_0_3_XYNN 0x00003000 -#define NV50TCL_VP_ATTR_EN_0_3_NNZN 0x00004000 -#define NV50TCL_VP_ATTR_EN_0_3_XNZN 0x00005000 -#define NV50TCL_VP_ATTR_EN_0_3_NYZN 0x00006000 -#define NV50TCL_VP_ATTR_EN_0_3_XYZN 0x00007000 -#define NV50TCL_VP_ATTR_EN_0_3_NNNW 0x00008000 -#define NV50TCL_VP_ATTR_EN_0_3_XNNW 0x00009000 -#define NV50TCL_VP_ATTR_EN_0_3_NYNW 0x0000a000 -#define NV50TCL_VP_ATTR_EN_0_3_XYNW 0x0000b000 -#define NV50TCL_VP_ATTR_EN_0_3_NNZW 0x0000c000 -#define NV50TCL_VP_ATTR_EN_0_3_XNZW 0x0000d000 -#define NV50TCL_VP_ATTR_EN_0_3_NYZW 0x0000e000 -#define NV50TCL_VP_ATTR_EN_0_3_XYZW 0x0000f000 -#define NV50TCL_VP_ATTR_EN_0_2_SHIFT 8 -#define NV50TCL_VP_ATTR_EN_0_2_MASK 0x00000f00 -#define NV50TCL_VP_ATTR_EN_0_2_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_2_XNNN 0x00000100 -#define NV50TCL_VP_ATTR_EN_0_2_NYNN 0x00000200 -#define NV50TCL_VP_ATTR_EN_0_2_XYNN 0x00000300 -#define NV50TCL_VP_ATTR_EN_0_2_NNZN 0x00000400 -#define NV50TCL_VP_ATTR_EN_0_2_XNZN 0x00000500 -#define NV50TCL_VP_ATTR_EN_0_2_NYZN 0x00000600 -#define NV50TCL_VP_ATTR_EN_0_2_XYZN 0x00000700 -#define NV50TCL_VP_ATTR_EN_0_2_NNNW 0x00000800 -#define NV50TCL_VP_ATTR_EN_0_2_XNNW 0x00000900 -#define NV50TCL_VP_ATTR_EN_0_2_NYNW 0x00000a00 -#define NV50TCL_VP_ATTR_EN_0_2_XYNW 0x00000b00 -#define NV50TCL_VP_ATTR_EN_0_2_NNZW 0x00000c00 -#define NV50TCL_VP_ATTR_EN_0_2_XNZW 0x00000d00 -#define NV50TCL_VP_ATTR_EN_0_2_NYZW 0x00000e00 -#define NV50TCL_VP_ATTR_EN_0_2_XYZW 0x00000f00 -#define NV50TCL_VP_ATTR_EN_0_1_SHIFT 4 -#define NV50TCL_VP_ATTR_EN_0_1_MASK 0x000000f0 -#define NV50TCL_VP_ATTR_EN_0_1_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_1_XNNN 0x00000010 -#define NV50TCL_VP_ATTR_EN_0_1_NYNN 0x00000020 -#define NV50TCL_VP_ATTR_EN_0_1_XYNN 0x00000030 -#define NV50TCL_VP_ATTR_EN_0_1_NNZN 0x00000040 -#define NV50TCL_VP_ATTR_EN_0_1_XNZN 0x00000050 -#define NV50TCL_VP_ATTR_EN_0_1_NYZN 0x00000060 -#define NV50TCL_VP_ATTR_EN_0_1_XYZN 0x00000070 -#define NV50TCL_VP_ATTR_EN_0_1_NNNW 0x00000080 -#define NV50TCL_VP_ATTR_EN_0_1_XNNW 0x00000090 -#define NV50TCL_VP_ATTR_EN_0_1_NYNW 0x000000a0 -#define NV50TCL_VP_ATTR_EN_0_1_XYNW 0x000000b0 -#define NV50TCL_VP_ATTR_EN_0_1_NNZW 0x000000c0 -#define NV50TCL_VP_ATTR_EN_0_1_XNZW 0x000000d0 -#define NV50TCL_VP_ATTR_EN_0_1_NYZW 0x000000e0 -#define NV50TCL_VP_ATTR_EN_0_1_XYZW 0x000000f0 -#define NV50TCL_VP_ATTR_EN_0_0_SHIFT 0 -#define NV50TCL_VP_ATTR_EN_0_0_MASK 0x0000000f -#define NV50TCL_VP_ATTR_EN_0_0_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_0_XNNN 0x00000001 -#define NV50TCL_VP_ATTR_EN_0_0_NYNN 0x00000002 -#define NV50TCL_VP_ATTR_EN_0_0_XYNN 0x00000003 -#define NV50TCL_VP_ATTR_EN_0_0_NNZN 0x00000004 -#define NV50TCL_VP_ATTR_EN_0_0_XNZN 0x00000005 -#define NV50TCL_VP_ATTR_EN_0_0_NYZN 0x00000006 -#define NV50TCL_VP_ATTR_EN_0_0_XYZN 0x00000007 -#define NV50TCL_VP_ATTR_EN_0_0_NNNW 0x00000008 -#define NV50TCL_VP_ATTR_EN_0_0_XNNW 0x00000009 -#define NV50TCL_VP_ATTR_EN_0_0_NYNW 0x0000000a -#define NV50TCL_VP_ATTR_EN_0_0_XYNW 0x0000000b -#define NV50TCL_VP_ATTR_EN_0_0_NNZW 0x0000000c -#define NV50TCL_VP_ATTR_EN_0_0_XNZW 0x0000000d -#define NV50TCL_VP_ATTR_EN_0_0_NYZW 0x0000000e -#define NV50TCL_VP_ATTR_EN_0_0_XYZW 0x0000000f -#define NV50TCL_VP_ATTR_EN_1 0x00001654 -#define NV50TCL_VP_ATTR_EN_1_15_SHIFT 28 -#define NV50TCL_VP_ATTR_EN_1_15_MASK 0xf0000000 -#define NV50TCL_VP_ATTR_EN_1_15_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNNN 0x10000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYNN 0x20000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYNN 0x30000000 -#define NV50TCL_VP_ATTR_EN_1_15_NNZN 0x40000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNZN 0x50000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYZN 0x60000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYZN 0x70000000 -#define NV50TCL_VP_ATTR_EN_1_15_NNNW 0x80000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNNW 0x90000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYNW 0xa0000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYNW 0xb0000000 -#define NV50TCL_VP_ATTR_EN_1_15_NNZW 0xc0000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNZW 0xd0000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYZW 0xe0000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYZW 0xf0000000 -#define NV50TCL_VP_ATTR_EN_1_14_SHIFT 24 -#define NV50TCL_VP_ATTR_EN_1_14_MASK 0x0f000000 -#define NV50TCL_VP_ATTR_EN_1_14_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNNN 0x01000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYNN 0x02000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYNN 0x03000000 -#define NV50TCL_VP_ATTR_EN_1_14_NNZN 0x04000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNZN 0x05000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYZN 0x06000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYZN 0x07000000 -#define NV50TCL_VP_ATTR_EN_1_14_NNNW 0x08000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNNW 0x09000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYNW 0x0a000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYNW 0x0b000000 -#define NV50TCL_VP_ATTR_EN_1_14_NNZW 0x0c000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNZW 0x0d000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYZW 0x0e000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYZW 0x0f000000 -#define NV50TCL_VP_ATTR_EN_1_13_SHIFT 20 -#define NV50TCL_VP_ATTR_EN_1_13_MASK 0x00f00000 -#define NV50TCL_VP_ATTR_EN_1_13_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_13_XNNN 0x00100000 -#define NV50TCL_VP_ATTR_EN_1_13_NYNN 0x00200000 -#define NV50TCL_VP_ATTR_EN_1_13_XYNN 0x00300000 -#define NV50TCL_VP_ATTR_EN_1_13_NNZN 0x00400000 -#define NV50TCL_VP_ATTR_EN_1_13_XNZN 0x00500000 -#define NV50TCL_VP_ATTR_EN_1_13_NYZN 0x00600000 -#define NV50TCL_VP_ATTR_EN_1_13_XYZN 0x00700000 -#define NV50TCL_VP_ATTR_EN_1_13_NNNW 0x00800000 -#define NV50TCL_VP_ATTR_EN_1_13_XNNW 0x00900000 -#define NV50TCL_VP_ATTR_EN_1_13_NYNW 0x00a00000 -#define NV50TCL_VP_ATTR_EN_1_13_XYNW 0x00b00000 -#define NV50TCL_VP_ATTR_EN_1_13_NNZW 0x00c00000 -#define NV50TCL_VP_ATTR_EN_1_13_XNZW 0x00d00000 -#define NV50TCL_VP_ATTR_EN_1_13_NYZW 0x00e00000 -#define NV50TCL_VP_ATTR_EN_1_13_XYZW 0x00f00000 -#define NV50TCL_VP_ATTR_EN_1_12_SHIFT 16 -#define NV50TCL_VP_ATTR_EN_1_12_MASK 0x000f0000 -#define NV50TCL_VP_ATTR_EN_1_12_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_12_XNNN 0x00010000 -#define NV50TCL_VP_ATTR_EN_1_12_NYNN 0x00020000 -#define NV50TCL_VP_ATTR_EN_1_12_XYNN 0x00030000 -#define NV50TCL_VP_ATTR_EN_1_12_NNZN 0x00040000 -#define NV50TCL_VP_ATTR_EN_1_12_XNZN 0x00050000 -#define NV50TCL_VP_ATTR_EN_1_12_NYZN 0x00060000 -#define NV50TCL_VP_ATTR_EN_1_12_XYZN 0x00070000 -#define NV50TCL_VP_ATTR_EN_1_12_NNNW 0x00080000 -#define NV50TCL_VP_ATTR_EN_1_12_XNNW 0x00090000 -#define NV50TCL_VP_ATTR_EN_1_12_NYNW 0x000a0000 -#define NV50TCL_VP_ATTR_EN_1_12_XYNW 0x000b0000 -#define NV50TCL_VP_ATTR_EN_1_12_NNZW 0x000c0000 -#define NV50TCL_VP_ATTR_EN_1_12_XNZW 0x000d0000 -#define NV50TCL_VP_ATTR_EN_1_12_NYZW 0x000e0000 -#define NV50TCL_VP_ATTR_EN_1_12_XYZW 0x000f0000 -#define NV50TCL_VP_ATTR_EN_1_11_SHIFT 12 -#define NV50TCL_VP_ATTR_EN_1_11_MASK 0x0000f000 -#define NV50TCL_VP_ATTR_EN_1_11_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_11_XNNN 0x00001000 -#define NV50TCL_VP_ATTR_EN_1_11_NYNN 0x00002000 -#define NV50TCL_VP_ATTR_EN_1_11_XYNN 0x00003000 -#define NV50TCL_VP_ATTR_EN_1_11_NNZN 0x00004000 -#define NV50TCL_VP_ATTR_EN_1_11_XNZN 0x00005000 -#define NV50TCL_VP_ATTR_EN_1_11_NYZN 0x00006000 -#define NV50TCL_VP_ATTR_EN_1_11_XYZN 0x00007000 -#define NV50TCL_VP_ATTR_EN_1_11_NNNW 0x00008000 -#define NV50TCL_VP_ATTR_EN_1_11_XNNW 0x00009000 -#define NV50TCL_VP_ATTR_EN_1_11_NYNW 0x0000a000 -#define NV50TCL_VP_ATTR_EN_1_11_XYNW 0x0000b000 -#define NV50TCL_VP_ATTR_EN_1_11_NNZW 0x0000c000 -#define NV50TCL_VP_ATTR_EN_1_11_XNZW 0x0000d000 -#define NV50TCL_VP_ATTR_EN_1_11_NYZW 0x0000e000 -#define NV50TCL_VP_ATTR_EN_1_11_XYZW 0x0000f000 -#define NV50TCL_VP_ATTR_EN_1_10_SHIFT 8 -#define NV50TCL_VP_ATTR_EN_1_10_MASK 0x00000f00 -#define NV50TCL_VP_ATTR_EN_1_10_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_10_XNNN 0x00000100 -#define NV50TCL_VP_ATTR_EN_1_10_NYNN 0x00000200 -#define NV50TCL_VP_ATTR_EN_1_10_XYNN 0x00000300 -#define NV50TCL_VP_ATTR_EN_1_10_NNZN 0x00000400 -#define NV50TCL_VP_ATTR_EN_1_10_XNZN 0x00000500 -#define NV50TCL_VP_ATTR_EN_1_10_NYZN 0x00000600 -#define NV50TCL_VP_ATTR_EN_1_10_XYZN 0x00000700 -#define NV50TCL_VP_ATTR_EN_1_10_NNNW 0x00000800 -#define NV50TCL_VP_ATTR_EN_1_10_XNNW 0x00000900 -#define NV50TCL_VP_ATTR_EN_1_10_NYNW 0x00000a00 -#define NV50TCL_VP_ATTR_EN_1_10_XYNW 0x00000b00 -#define NV50TCL_VP_ATTR_EN_1_10_NNZW 0x00000c00 -#define NV50TCL_VP_ATTR_EN_1_10_XNZW 0x00000d00 -#define NV50TCL_VP_ATTR_EN_1_10_NYZW 0x00000e00 -#define NV50TCL_VP_ATTR_EN_1_10_XYZW 0x00000f00 -#define NV50TCL_VP_ATTR_EN_1_9_SHIFT 4 -#define NV50TCL_VP_ATTR_EN_1_9_MASK 0x000000f0 -#define NV50TCL_VP_ATTR_EN_1_9_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_9_XNNN 0x00000010 -#define NV50TCL_VP_ATTR_EN_1_9_NYNN 0x00000020 -#define NV50TCL_VP_ATTR_EN_1_9_XYNN 0x00000030 -#define NV50TCL_VP_ATTR_EN_1_9_NNZN 0x00000040 -#define NV50TCL_VP_ATTR_EN_1_9_XNZN 0x00000050 -#define NV50TCL_VP_ATTR_EN_1_9_NYZN 0x00000060 -#define NV50TCL_VP_ATTR_EN_1_9_XYZN 0x00000070 -#define NV50TCL_VP_ATTR_EN_1_9_NNNW 0x00000080 -#define NV50TCL_VP_ATTR_EN_1_9_XNNW 0x00000090 -#define NV50TCL_VP_ATTR_EN_1_9_NYNW 0x000000a0 -#define NV50TCL_VP_ATTR_EN_1_9_XYNW 0x000000b0 -#define NV50TCL_VP_ATTR_EN_1_9_NNZW 0x000000c0 -#define NV50TCL_VP_ATTR_EN_1_9_XNZW 0x000000d0 -#define NV50TCL_VP_ATTR_EN_1_9_NYZW 0x000000e0 -#define NV50TCL_VP_ATTR_EN_1_9_XYZW 0x000000f0 -#define NV50TCL_VP_ATTR_EN_1_8_SHIFT 0 -#define NV50TCL_VP_ATTR_EN_1_8_MASK 0x0000000f -#define NV50TCL_VP_ATTR_EN_1_8_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_8_XNNN 0x00000001 -#define NV50TCL_VP_ATTR_EN_1_8_NYNN 0x00000002 -#define NV50TCL_VP_ATTR_EN_1_8_XYNN 0x00000003 -#define NV50TCL_VP_ATTR_EN_1_8_NNZN 0x00000004 -#define NV50TCL_VP_ATTR_EN_1_8_XNZN 0x00000005 -#define NV50TCL_VP_ATTR_EN_1_8_NYZN 0x00000006 -#define NV50TCL_VP_ATTR_EN_1_8_XYZN 0x00000007 -#define NV50TCL_VP_ATTR_EN_1_8_NNNW 0x00000008 -#define NV50TCL_VP_ATTR_EN_1_8_XNNW 0x00000009 -#define NV50TCL_VP_ATTR_EN_1_8_NYNW 0x0000000a -#define NV50TCL_VP_ATTR_EN_1_8_XYNW 0x0000000b -#define NV50TCL_VP_ATTR_EN_1_8_NNZW 0x0000000c -#define NV50TCL_VP_ATTR_EN_1_8_XNZW 0x0000000d -#define NV50TCL_VP_ATTR_EN_1_8_NYZW 0x0000000e -#define NV50TCL_VP_ATTR_EN_1_8_XYZW 0x0000000f -#define NV50TCL_POINT_SPRITE_CTRL 0x00001660 -#define NV50TCL_LINE_STIPPLE_ENABLE 0x0000166c -#define NV50TCL_LINE_STIPPLE_PATTERN 0x00001680 -#define NV50TCL_PROVOKING_VERTEX_LAST 0x00001684 -#define NV50TCL_VERTEX_TWO_SIDE_ENABLE 0x00001688 -#define NV50TCL_POLYGON_STIPPLE_ENABLE 0x0000168c -#define NV50TCL_SET_PROGRAM_CB 0x00001694 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_SHIFT 4 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_MASK 0x000000f0 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_VERTEX 0x00000000 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_GEOMETRY 0x00000020 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_FRAGMENT 0x00000030 -#define NV50TCL_SET_PROGRAM_CB_INDEX_SHIFT 8 -#define NV50TCL_SET_PROGRAM_CB_INDEX_MASK 0x00000f00 -#define NV50TCL_SET_PROGRAM_CB_BUFFER_SHIFT 12 -#define NV50TCL_SET_PROGRAM_CB_BUFFER_MASK 0x0007f000 -#define NV50TCL_SET_PROGRAM_CB_VALID (1 << 0) -#define NV50TCL_VP_RESULT_MAP_SIZE 0x000016ac -#define NV50TCL_VP_REG_ALLOC_TEMP 0x000016b0 -#define NV50TCL_VP_REG_ALLOC_RESULT 0x000016b8 -#define NV50TCL_VP_RESULT_MAP(x) (0x000016bc+((x)*4)) -#define NV50TCL_VP_RESULT_MAP__SIZE 0x00000010 -#define NV50TCL_VP_RESULT_MAP_0_SHIFT 0 -#define NV50TCL_VP_RESULT_MAP_0_MASK 0x000000ff -#define NV50TCL_VP_RESULT_MAP_1_SHIFT 8 -#define NV50TCL_VP_RESULT_MAP_1_MASK 0x0000ff00 -#define NV50TCL_VP_RESULT_MAP_2_SHIFT 16 -#define NV50TCL_VP_RESULT_MAP_2_MASK 0x00ff0000 -#define NV50TCL_VP_RESULT_MAP_3_SHIFT 24 -#define NV50TCL_VP_RESULT_MAP_3_MASK 0xff000000 -#define NV50TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001700+((x)*4)) -#define NV50TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 -#define NV50TCL_GP_ENABLE 0x00001798 -#define NV50TCL_GP_REG_ALLOC_TEMP 0x000017a0 -#define NV50TCL_GP_REG_ALLOC_RESULT 0x000017a8 -#define NV50TCL_GP_RESULT_MAP_SIZE 0x000017ac -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE 0x000017b0 -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_POINTS 0x00000001 -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP 0x00000002 -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP 0x00000003 -#define NV50TCL_RASTERIZE_ENABLE 0x000017b4 -#define NV50TCL_STRMOUT_ENABLE 0x000017b8 -#define NV50TCL_GP_RESULT_MAP(x) (0x000017fc+((x)*4)) -#define NV50TCL_GP_RESULT_MAP__SIZE 0x00000020 -#define NV50TCL_GP_RESULT_MAP_0_SHIFT 0 -#define NV50TCL_GP_RESULT_MAP_0_MASK 0x000000ff -#define NV50TCL_GP_RESULT_MAP_1_SHIFT 8 -#define NV50TCL_GP_RESULT_MAP_1_MASK 0x0000ff00 -#define NV50TCL_GP_RESULT_MAP_2_SHIFT 16 -#define NV50TCL_GP_RESULT_MAP_2_MASK 0x00ff0000 -#define NV50TCL_GP_RESULT_MAP_3_SHIFT 24 -#define NV50TCL_GP_RESULT_MAP_3_MASK 0xff000000 -#define NV50TCL_MAP_SEMANTIC_0 0x00001904 -#define NV50TCL_MAP_SEMANTIC_0_FFC0_ID_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_0_FFC0_ID_MASK 0x000000ff -#define NV50TCL_MAP_SEMANTIC_0_BFC0_ID_SHIFT 8 -#define NV50TCL_MAP_SEMANTIC_0_BFC0_ID_MASK 0x0000ff00 -#define NV50TCL_MAP_SEMANTIC_0_COLR_NR_SHIFT 16 -#define NV50TCL_MAP_SEMANTIC_0_COLR_NR_MASK 0x00ff0000 -#define NV50TCL_MAP_SEMANTIC_0_CLMP_EN_SHIFT 24 -#define NV50TCL_MAP_SEMANTIC_0_CLMP_EN_MASK 0xff000000 -#define NV50TCL_MAP_SEMANTIC_1 0x00001908 -#define NV50TCL_MAP_SEMANTIC_1_CLIP_LO_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_1_CLIP_LO_MASK 0x000000ff -#define NV50TCL_MAP_SEMANTIC_1_CLIP_HI_SHIFT 8 -#define NV50TCL_MAP_SEMANTIC_1_CLIP_HI_MASK 0x0000ff00 -#define NV50TCL_MAP_SEMANTIC_2 0x0000190c -#define NV50TCL_MAP_SEMANTIC_2_LAYER_ID_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_2_LAYER_ID_MASK 0x000000ff -#define NV50TCL_MAP_SEMANTIC_3 0x00001910 -#define NV50TCL_MAP_SEMANTIC_3_PTSZ_EN (1 << 0) -#define NV50TCL_MAP_SEMANTIC_3_PTSZ_ID_SHIFT 4 -#define NV50TCL_MAP_SEMANTIC_3_PTSZ_ID_MASK 0x00000ff0 -#define NV50TCL_MAP_SEMANTIC_4 0x00001914 -#define NV50TCL_MAP_SEMANTIC_4_PRIM_ID_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_4_PRIM_ID_MASK 0x000000ff -#define NV50TCL_CULL_FACE_ENABLE 0x00001918 -#define NV50TCL_FRONT_FACE 0x0000191c -#define NV50TCL_FRONT_FACE_CW 0x00000900 -#define NV50TCL_FRONT_FACE_CCW 0x00000901 -#define NV50TCL_CULL_FACE 0x00001920 -#define NV50TCL_CULL_FACE_FRONT 0x00000404 -#define NV50TCL_CULL_FACE_BACK 0x00000405 -#define NV50TCL_CULL_FACE_FRONT_AND_BACK 0x00000408 -#define NV50TCL_VIEWPORT_TRANSFORM_EN 0x0000192c -#define NV50TCL_VIEW_VOLUME_CLIP_CTRL 0x0000193c -#define NV50TCL_VIEWPORT_CLIP_RECTS_EN 0x0000194c -#define NV50TCL_VIEWPORT_CLIP_MODE 0x00001950 -#define NV50TCL_VIEWPORT_CLIP_MODE_INCLUDE 0x00000000 -#define NV50TCL_VIEWPORT_CLIP_MODE_EXCLUDE 0x00000001 -#define NV50TCL_VIEWPORT_CLIP_MODE_UNKNOWN 0x00000002 -#define NV50TCL_FP_CTRL_UNK196C 0x0000196c -#define NV50TCL_CLIPID_ENABLE 0x0000197c -#define NV50TCL_CLIPID_WIDTH 0x00001980 -#define NV50TCL_CLIPID_ID 0x00001984 -#define NV50TCL_FP_INTERPOLANT_CTRL 0x00001988 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_SHIFT 24 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_MASK 0xff000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NONE 0x00000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNNN 0x01000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYNN 0x02000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYNN 0x03000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNZN 0x04000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNZN 0x05000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYZN 0x06000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYZN 0x07000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNNW 0x08000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNNW 0x09000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYNW 0x0a000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYNW 0x0b000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNZW 0x0c000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNZW 0x0d000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYZW 0x0e000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYZW 0x0f000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_SHIFT 16 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_MASK 0x00ff0000 -#define NV50TCL_FP_INTERPOLANT_CTRL_OFFSET_SHIFT 8 -#define NV50TCL_FP_INTERPOLANT_CTRL_OFFSET_MASK 0x0000ff00 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_SHIFT 0 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_MASK 0x000000ff -#define NV50TCL_FP_REG_ALLOC_TEMP 0x0000198c -#define NV50TCL_REG_MODE 0x000019a0 -#define NV50TCL_REG_MODE_PACKED 0x00000001 -#define NV50TCL_REG_MODE_STRIPED 0x00000002 -#define NV50TCL_FP_CONTROL 0x000019a8 -#define NV50TCL_FP_CONTROL_MULTIPLE_RESULTS (1 << 0) -#define NV50TCL_FP_CONTROL_EXPORTS_Z (1 << 8) -#define NV50TCL_FP_CONTROL_USES_KIL (1 << 20) -#define NV50TCL_DEPTH_BOUNDS_EN 0x000019bc -#define NV50TCL_LOGIC_OP_ENABLE 0x000019c4 -#define NV50TCL_LOGIC_OP 0x000019c8 -#define NV50TCL_LOGIC_OP_CLEAR 0x00001500 -#define NV50TCL_LOGIC_OP_AND 0x00001501 -#define NV50TCL_LOGIC_OP_AND_REVERSE 0x00001502 -#define NV50TCL_LOGIC_OP_COPY 0x00001503 -#define NV50TCL_LOGIC_OP_AND_INVERTED 0x00001504 -#define NV50TCL_LOGIC_OP_NOOP 0x00001505 -#define NV50TCL_LOGIC_OP_XOR 0x00001506 -#define NV50TCL_LOGIC_OP_OR 0x00001507 -#define NV50TCL_LOGIC_OP_NOR 0x00001508 -#define NV50TCL_LOGIC_OP_EQUIV 0x00001509 -#define NV50TCL_LOGIC_OP_INVERT 0x0000150a -#define NV50TCL_LOGIC_OP_OR_REVERSE 0x0000150b -#define NV50TCL_LOGIC_OP_COPY_INVERTED 0x0000150c -#define NV50TCL_LOGIC_OP_OR_INVERTED 0x0000150d -#define NV50TCL_LOGIC_OP_NAND 0x0000150e -#define NV50TCL_LOGIC_OP_SET 0x0000150f -#define NV50TCL_CLEAR_BUFFERS 0x000019d0 -#define NV50TCL_CLEAR_BUFFERS_Z (1 << 0) -#define NV50TCL_CLEAR_BUFFERS_S (1 << 1) -#define NV50TCL_CLEAR_BUFFERS_R (1 << 2) -#define NV50TCL_CLEAR_BUFFERS_G (1 << 3) -#define NV50TCL_CLEAR_BUFFERS_B (1 << 4) -#define NV50TCL_CLEAR_BUFFERS_A (1 << 5) -#define NV50TCL_CLEAR_BUFFERS_RT_SHIFT 6 -#define NV50TCL_CLEAR_BUFFERS_RT_MASK 0x000003c0 -#define NV50TCL_CLEAR_BUFFERS_LAYER_SHIFT 10 -#define NV50TCL_CLEAR_BUFFERS_LAYER_MASK 0x0007fc00 -#define NV50TCL_COLOR_MASK(x) (0x00001a00+((x)*4)) -#define NV50TCL_COLOR_MASK__SIZE 0x00000008 -#define NV50TCL_COLOR_MASK_R_SHIFT 0 -#define NV50TCL_COLOR_MASK_R_MASK 0x0000000f -#define NV50TCL_COLOR_MASK_G_SHIFT 4 -#define NV50TCL_COLOR_MASK_G_MASK 0x000000f0 -#define NV50TCL_COLOR_MASK_B_SHIFT 8 -#define NV50TCL_COLOR_MASK_B_MASK 0x00000f00 -#define NV50TCL_COLOR_MASK_A_SHIFT 12 -#define NV50TCL_COLOR_MASK_A_MASK 0x0000f000 -#define NV50TCL_STRMOUT_ADDRESS_HIGH(x) (0x00001a80+((x)*16)) -#define NV50TCL_STRMOUT_ADDRESS_HIGH__SIZE 0x00000004 -#define NV50TCL_STRMOUT_ADDRESS_LOW(x) (0x00001a84+((x)*16)) -#define NV50TCL_STRMOUT_ADDRESS_LOW__SIZE 0x00000004 -#define NV50TCL_STRMOUT_NUM_ATTRIBS(x) (0x00001a88+((x)*16)) -#define NV50TCL_STRMOUT_NUM_ATTRIBS__SIZE 0x00000004 -#define NV50TCL_VERTEX_ARRAY_ATTRIB(x) (0x00001ac0+((x)*4)) -#define NV50TCL_VERTEX_ARRAY_ATTRIB__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_BUFFER_SHIFT 0 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_BUFFER_MASK 0x0000000f -#define NV50TCL_VERTEX_ARRAY_ATTRIB_CONST (1 << 4) -#define NV50TCL_VERTEX_ARRAY_ATTRIB_OFFSET_SHIFT 5 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_OFFSET_MASK 0x0007ffe0 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_SHIFT 19 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_MASK 0x01f80000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 0x00080000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32 0x00100000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16_16 0x00180000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32 0x00200000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16 0x00280000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8_8 0x00500000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16 0x00780000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32 0x00900000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8 0x00980000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8 0x00c00000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16 0x00d80000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8 0x00e80000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_2_10_10_10 0x01800000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SHIFT 25 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_MASK 0x0e000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT 0x0e000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM 0x02000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM 0x04000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED 0x0a000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED 0x0c000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UINT 0x08000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SINT 0x06000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_BGRA (1 << 31) -#define NV50TCL_QUERY_ADDRESS_HIGH 0x00001b00 -#define NV50TCL_QUERY_ADDRESS_LOW 0x00001b04 -#define NV50TCL_QUERY_SEQUENCE 0x00001b08 -#define NV50TCL_QUERY_GET 0x00001b0c - - -#define NV84TCL 0x00008297 - - - -#define NVA0TCL 0x00008397 - - - -#define NVA8TCL 0x00008597 - - - -#define NV50_COMPUTE 0x000050c0 - -#define NV50_COMPUTE_NOP 0x00000100 -#define NV50_COMPUTE_NOTIFY 0x00000104 -#define NV50_COMPUTE_SERIALIZE 0x00000110 -#define NV50_COMPUTE_DMA_NOTIFY 0x00000180 -#define NV50_COMPUTE_DMA_GLOBAL 0x000001a0 -#define NV50_COMPUTE_DMA_QUERY 0x000001a4 -#define NV50_COMPUTE_DMA_LOCAL 0x000001b8 -#define NV50_COMPUTE_DMA_STACK 0x000001bc -#define NV50_COMPUTE_DMA_CODE_CB 0x000001c0 -#define NV50_COMPUTE_DMA_TSC 0x000001c4 -#define NV50_COMPUTE_DMA_TIC 0x000001c8 -#define NV50_COMPUTE_DMA_TEXTURE 0x000001cc -#define NV50_COMPUTE_CP_ADDRESS_HIGH 0x00000210 -#define NV50_COMPUTE_CP_ADDRESS_LOW 0x00000214 -#define NV50_COMPUTE_STACK_ADDRESS_HIGH 0x00000218 -#define NV50_COMPUTE_STACK_ADDRESS_LOW 0x0000021c -#define NV50_COMPUTE_STACK_SIZE_LOG 0x00000220 -#define NV50_COMPUTE_TSC_ADDRESS_HIGH 0x0000022c -#define NV50_COMPUTE_TSC_ADDRESS_LOW 0x00000230 -#define NV50_COMPUTE_TSC_LIMIT 0x00000234 -#define NV50_COMPUTE_CB_ADDR 0x00000238 -#define NV50_COMPUTE_CB_ADDR_ID_SHIFT 8 -#define NV50_COMPUTE_CB_ADDR_ID_MASK 0x003fff00 -#define NV50_COMPUTE_CB_ADDR_BUFFER_SHIFT 0 -#define NV50_COMPUTE_CB_ADDR_BUFFER_MASK 0x0000007f -#define NV50_COMPUTE_CB_DATA(x) (0x0000023c+((x)*4)) -#define NV50_COMPUTE_CB_DATA__SIZE 0x00000010 -#define NV50_COMPUTE_DELAY1 0x00000284 -#define NV50_COMPUTE_WATCHDOG_TIMER 0x00000288 -#define NV50_COMPUTE_DELAY2 0x0000028c -#define NV50_COMPUTE_LOCAL_ADDRESS_HIGH 0x00000294 -#define NV50_COMPUTE_LOCAL_ADDRESS_LOW 0x00000298 -#define NV50_COMPUTE_LOCAL_SIZE_LOG 0x0000029c -#define NV50_COMPUTE_CB_DEF_ADDRESS_HIGH 0x000002a4 -#define NV50_COMPUTE_CB_DEF_ADDRESS_LOW 0x000002a8 -#define NV50_COMPUTE_CB_DEF_SET 0x000002ac -#define NV50_COMPUTE_CB_DEF_SET_SIZE_SHIFT 0 -#define NV50_COMPUTE_CB_DEF_SET_SIZE_MASK 0x0000ffff -#define NV50_COMPUTE_CB_DEF_SET_BUFFER_SHIFT 16 -#define NV50_COMPUTE_CB_DEF_SET_BUFFER_MASK 0x007f0000 -#define NV50_COMPUTE_BLOCK_ALLOC 0x000002b4 -#define NV50_COMPUTE_BLOCK_ALLOC_THREADS_SHIFT 0 -#define NV50_COMPUTE_BLOCK_ALLOC_THREADS_MASK 0x0000ffff -#define NV50_COMPUTE_BLOCK_ALLOC_BARRIERS_SHIFT 16 -#define NV50_COMPUTE_BLOCK_ALLOC_BARRIERS_MASK 0xffff0000 -#define NV50_COMPUTE_LANES32_ENABLE 0x000002b8 -#define NV50_COMPUTE_CP_REG_ALLOC_TEMP 0x000002c0 -#define NV50_COMPUTE_TIC_ADDRESS_HIGH 0x000002c4 -#define NV50_COMPUTE_TIC_ADDRESS_LOW 0x000002c8 -#define NV50_COMPUTE_TIC_LIMIT 0x000002cc -#define NV50_COMPUTE_PM_SET(x) (0x000002d0+((x)*4)) -#define NV50_COMPUTE_PM_SET__SIZE 0x00000004 -#define NV50_COMPUTE_PM_CONTROL(x) (0x000002e0+((x)*4)) -#define NV50_COMPUTE_PM_CONTROL__SIZE 0x00000004 -#define NV50_COMPUTE_PM_CONTROL_UNK0 (1 << 0) -#define NV50_COMPUTE_PM_CONTROL_UNK1_SHIFT 4 -#define NV50_COMPUTE_PM_CONTROL_UNK1_MASK 0x00000070 -#define NV50_COMPUTE_PM_CONTROL_UNK2_SHIFT 8 -#define NV50_COMPUTE_PM_CONTROL_UNK2_MASK 0xffffff00 -#define NV50_COMPUTE_LOCAL_WARPS_LOG_ALLOC 0x000002fc -#define NV50_COMPUTE_LOCAL_WARPS_NO_CLAMP 0x00000300 -#define NV50_COMPUTE_STACK_WARPS_LOG_ALLOC 0x00000304 -#define NV50_COMPUTE_STACK_WARPS_NO_CLAMP 0x00000308 -#define NV50_COMPUTE_QUERY_ADDRESS_HIGH 0x00000310 -#define NV50_COMPUTE_QUERY_ADDRESS_LOW 0x00000314 -#define NV50_COMPUTE_QUERY_COUNTER 0x00000318 -#define NV50_COMPUTE_QUERY_GET 0x0000031c -#define NV50_COMPUTE_COND_ADDRESS_HIGH 0x00000320 -#define NV50_COMPUTE_COND_ADDRESS_LOW 0x00000324 -#define NV50_COMPUTE_COND_MODE 0x00000328 -#define NV50_COMPUTE_COND_MODE_NEVER 0x00000000 -#define NV50_COMPUTE_COND_MODE_ALWAYS 0x00000001 -#define NV50_COMPUTE_COND_MODE_RES 0x00000002 -#define NV50_COMPUTE_COND_MODE_NOT_RES_AND_NOT_ID 0x00000003 -#define NV50_COMPUTE_COND_MODE_RES_OR_ID 0x00000004 -#define NV50_COMPUTE_LAUNCH 0x00000368 -#define NV50_COMPUTE_USER_PARAM_COUNT 0x00000374 -#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT_SHIFT 8 -#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT_MASK 0x0000ff00 -#define NV50_COMPUTE_LINKED_TSC 0x00000378 -#define NV50_COMPUTE_CODE_CB_FLUSH 0x00000380 -#define NV50_COMPUTE_GRIDDIM 0x000003a4 -#define NV50_COMPUTE_GRIDDIM_X_SHIFT 0 -#define NV50_COMPUTE_GRIDDIM_X_MASK 0x0000ffff -#define NV50_COMPUTE_GRIDDIM_Y_SHIFT 16 -#define NV50_COMPUTE_GRIDDIM_Y_MASK 0xffff0000 -#define NV50_COMPUTE_SHARED_SIZE 0x000003a8 -#define NV50_COMPUTE_BLOCKDIM_YX 0x000003ac -#define NV50_COMPUTE_BLOCKDIM_YX_X_SHIFT 0 -#define NV50_COMPUTE_BLOCKDIM_YX_X_MASK 0x0000ffff -#define NV50_COMPUTE_BLOCKDIM_YX_Y_SHIFT 16 -#define NV50_COMPUTE_BLOCKDIM_YX_Y_MASK 0xffff0000 -#define NV50_COMPUTE_BLOCKDIM_Z 0x000003b0 -#define NV50_COMPUTE_CP_START_ID 0x000003b4 -#define NV50_COMPUTE_REG_MODE 0x000003b8 -#define NV50_COMPUTE_REG_MODE_PACKED 0x00000001 -#define NV50_COMPUTE_REG_MODE_STRIPED 0x00000002 -#define NV50_COMPUTE_TEX_LIMITS 0x000003bc -#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2_SHIFT 0 -#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2_MASK 0x0000000f -#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2_SHIFT 4 -#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2_MASK 0x000000f0 -#define NV50_COMPUTE_BIND_TSC 0x000003c0 -#define NV50_COMPUTE_BIND_TSC_VALID (1 << 0) -#define NV50_COMPUTE_BIND_TSC_SAMPLER_SHIFT 4 -#define NV50_COMPUTE_BIND_TSC_SAMPLER_MASK 0x000000f0 -#define NV50_COMPUTE_BIND_TSC_TSC_SHIFT 12 -#define NV50_COMPUTE_BIND_TSC_TSC_MASK 0x001ff000 -#define NV50_COMPUTE_BIND_TIC 0x000003c4 -#define NV50_COMPUTE_BIND_TIC_VALID (1 << 0) -#define NV50_COMPUTE_BIND_TIC_TEXTURE_SHIFT 1 -#define NV50_COMPUTE_BIND_TIC_TEXTURE_MASK 0x000001fe -#define NV50_COMPUTE_BIND_TIC_TIC_SHIFT 9 -#define NV50_COMPUTE_BIND_TIC_TIC_MASK 0x7ffffe00 -#define NV50_COMPUTE_SET_PROGRAM_CB 0x000003c8 -#define NV50_COMPUTE_SET_PROGRAM_CB_INDEX_SHIFT 8 -#define NV50_COMPUTE_SET_PROGRAM_CB_INDEX_MASK 0x00000f00 -#define NV50_COMPUTE_SET_PROGRAM_CB_BUFFER_SHIFT 12 -#define NV50_COMPUTE_SET_PROGRAM_CB_BUFFER_MASK 0x0007f000 -#define NV50_COMPUTE_SET_PROGRAM_CB_VALID (1 << 0) -#define NV50_COMPUTE_GLOBAL_ADDRESS_HIGH(x) (0x00000400+((x)*32)) -#define NV50_COMPUTE_GLOBAL_ADDRESS_HIGH__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_ADDRESS_LOW(x) (0x00000404+((x)*32)) -#define NV50_COMPUTE_GLOBAL_ADDRESS_LOW__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_PITCH(x) (0x00000408+((x)*32)) -#define NV50_COMPUTE_GLOBAL_PITCH__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_LIMIT(x) (0x0000040c+((x)*32)) -#define NV50_COMPUTE_GLOBAL_LIMIT__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_MODE(x) (0x00000410+((x)*32)) -#define NV50_COMPUTE_GLOBAL_MODE__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_MODE_LINEAR (1 << 0) -#define NV50_COMPUTE_GLOBAL_MODE_TILE_MODE_SHIFT 8 -#define NV50_COMPUTE_GLOBAL_MODE_TILE_MODE_MASK 0x00000f00 -#define NV50_COMPUTE_USER_PARAM(x) (0x00000600+((x)*4)) -#define NV50_COMPUTE_USER_PARAM__SIZE 0x00000040 - - -#endif /* NOUVEAU_REG_H */ diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c index 6c0a9696355..2a2fb0e32bc 100644 --- a/src/gallium/drivers/nv50/nv50_resource.c +++ b/src/gallium/drivers/nv50/nv50_resource.c @@ -3,65 +3,66 @@ #include "nv50_resource.h" #include "nouveau/nouveau_screen.h" - -/* This doesn't look quite right - this query is supposed to ask - * whether the particular context has references to the resource in - * any unflushed rendering command buffer, and hence requires a - * pipe->flush() for serializing some modification to that resource. - * - * This seems to be answering the question of whether the resource is - * currently on hardware. - */ -static unsigned int +static unsigned nv50_resource_is_referenced(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, int layer) + struct pipe_resource *resource, + unsigned face, int layer) { - return nouveau_reference_flags(nv50_resource(resource)->bo); + struct nv04_resource *res = nv04_resource(resource); + unsigned flags = 0; + unsigned bo_flags = nouveau_bo_pending(res->bo); + + if (bo_flags & NOUVEAU_BO_RD) + flags = PIPE_REFERENCED_FOR_READ; + if (bo_flags & NOUVEAU_BO_WR) + flags |= PIPE_REFERENCED_FOR_WRITE; + + return flags; } static struct pipe_resource * nv50_resource_create(struct pipe_screen *screen, - const struct pipe_resource *template) + const struct pipe_resource *templ) { - if (template->target == PIPE_BUFFER) - return nv50_buffer_create(screen, template); - else - return nv50_miptree_create(screen, template); + switch (templ->target) { + case PIPE_BUFFER: + return nouveau_buffer_create(screen, templ); + default: + return nv50_miptree_create(screen, templ); + } } static struct pipe_resource * nv50_resource_from_handle(struct pipe_screen * screen, - const struct pipe_resource *template, - struct winsys_handle *whandle) + const struct pipe_resource *templ, + struct winsys_handle *whandle) { - if (template->target == PIPE_BUFFER) - return NULL; - else - return nv50_miptree_from_handle(screen, template, whandle); + if (templ->target == PIPE_BUFFER) + return NULL; + else + return nv50_miptree_from_handle(screen, templ, whandle); } void nv50_init_resource_functions(struct pipe_context *pcontext) { - pcontext->get_transfer = u_get_transfer_vtbl; - pcontext->transfer_map = u_transfer_map_vtbl; - pcontext->transfer_flush_region = u_transfer_flush_region_vtbl; - pcontext->transfer_unmap = u_transfer_unmap_vtbl; - pcontext->transfer_destroy = u_transfer_destroy_vtbl; - pcontext->transfer_inline_write = u_transfer_inline_write_vtbl; - pcontext->is_resource_referenced = nv50_resource_is_referenced; - - pcontext->create_surface = nv50_miptree_surface_new; - pcontext->surface_destroy = nv50_miptree_surface_del; + pcontext->get_transfer = u_get_transfer_vtbl; + pcontext->transfer_map = u_transfer_map_vtbl; + pcontext->transfer_flush_region = u_transfer_flush_region_vtbl; + pcontext->transfer_unmap = u_transfer_unmap_vtbl; + pcontext->transfer_destroy = u_transfer_destroy_vtbl; + pcontext->transfer_inline_write = u_transfer_inline_write_vtbl; + pcontext->is_resource_referenced = nv50_resource_is_referenced; + pcontext->create_surface = nv50_miptree_surface_new; + pcontext->surface_destroy = nv50_miptree_surface_del; } void nv50_screen_init_resource_functions(struct pipe_screen *pscreen) { - pscreen->resource_create = nv50_resource_create; - pscreen->resource_from_handle = nv50_resource_from_handle; - pscreen->resource_get_handle = u_resource_get_handle_vtbl; - pscreen->resource_destroy = u_resource_destroy_vtbl; - pscreen->user_buffer_create = nv50_user_buffer_create; + pscreen->resource_create = nv50_resource_create; + pscreen->resource_from_handle = nv50_resource_from_handle; + pscreen->resource_get_handle = u_resource_get_handle_vtbl; + pscreen->resource_destroy = u_resource_destroy_vtbl; + pscreen->user_buffer_create = nouveau_user_buffer_create; } diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index 4b2a75e11ad..0e9f0a2557e 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -1,97 +1,70 @@ -#ifndef NV50_RESOURCE_H -#define NV50_RESOURCE_H +#ifndef __NV50_RESOURCE_H__ +#define __NV50_RESOURCE_H__ #include "util/u_transfer.h" - +#include "util/u_double_list.h" +#define NOUVEAU_NVC0 #include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_buffer.h" +#undef NOUVEAU_NVC0 + +void +nv50_init_resource_functions(struct pipe_context *pcontext); -struct pipe_resource; -struct nouveau_bo; +void +nv50_screen_init_resource_functions(struct pipe_screen *pscreen); +#define NV50_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) -/* This gets further specialized into either buffer or texture - * structures. In the future we'll want to remove much of that - * distinction, but for now try to keep as close to the existing code - * as possible and use the vtbl struct to choose between the two - * underlying implementations. - */ -struct nv50_resource { - struct pipe_resource base; - const struct u_resource_vtbl *vtbl; - struct nouveau_bo *bo; -}; +#define NV50_TILE_PITCH(m) (64 << 0) +#define NV50_TILE_HEIGHT(m) ( 4 << NV50_TILE_DIM_SHIFT(m, 0)) +#define NV50_TILE_DEPTH(m) ( 1 << NV50_TILE_DIM_SHIFT(m, 1)) + +#define NV50_TILE_SIZE_2D(m) ((64 * 4) << \ + NV50_TILE_DIM_SHIFT(m, 0)) + +#define NV50_TILE_SIZE(m) (NV50_TILE_SIZE_2D(m) << NV50_TILE_DIM_SHIFT(m, 1)) struct nv50_miptree_level { - int *image_offset; - unsigned pitch; - unsigned tile_mode; + uint32_t offset; + uint32_t pitch; + uint32_t tile_mode; }; #define NV50_MAX_TEXTURE_LEVELS 16 struct nv50_miptree { - struct nv50_resource base; - - struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS]; - int image_nr; - int total_size; + struct nv04_resource base; + struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS]; + uint32_t total_size; + uint32_t layer_stride; + boolean layout_3d; /* TRUE if layer count varies with mip level */ }; static INLINE struct nv50_miptree * nv50_miptree(struct pipe_resource *pt) { - return (struct nv50_miptree *)pt; -} - - -static INLINE -struct nv50_resource *nv50_resource(struct pipe_resource *resource) -{ - return (struct nv50_resource *)resource; + return (struct nv50_miptree *)pt; } -/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */ -static INLINE boolean -nv50_resource_mapped_by_gpu(struct pipe_resource *resource) -{ - return nv50_resource(resource)->bo->handle; -} - -void -nv50_init_resource_functions(struct pipe_context *pcontext); - -void -nv50_screen_init_resource_functions(struct pipe_screen *pscreen); - -/* Internal functions +/* Internal functions: */ struct pipe_resource * nv50_miptree_create(struct pipe_screen *pscreen, - const struct pipe_resource *tmp); + const struct pipe_resource *tmp); struct pipe_resource * nv50_miptree_from_handle(struct pipe_screen *pscreen, - const struct pipe_resource *template, - struct winsys_handle *whandle); - -struct pipe_resource * -nv50_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *template); - -struct pipe_resource * -nv50_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, - unsigned usage); - + const struct pipe_resource *template, + struct winsys_handle *whandle); struct pipe_surface * -nv50_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt, - const struct pipe_surface *surf_tmpl); +nv50_miptree_surface_new(struct pipe_context *, + struct pipe_resource *, + const struct pipe_surface *templ); void -nv50_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps); - +nv50_miptree_surface_del(struct pipe_context *, struct pipe_surface *); #endif diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index edc3d54d012..ae0365eb5c5 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Ben Skeggs + * Copyright 2010 Christoph Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,596 +25,624 @@ #include "nv50_context.h" #include "nv50_screen.h" -#include "nv50_resource.h" -#include "nv50_program.h" -#include "nouveau/nouveau_stateobj.h" +#include "nouveau/nv_object.xml.h" + +#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS +# define NOUVEAU_GETPARAM_GRAPH_UNITS 13 +#endif + +extern int nouveau_device_get_param(struct nouveau_device *dev, + uint64_t param, uint64_t *value); static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned sample_count, - unsigned usage, unsigned geom_flags) + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned bindings, unsigned geom_flags) { - if (sample_count > 1) - return FALSE; - - if (!util_format_s3tc_enabled) { - switch (format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - return FALSE; - default: - break; - } - } - - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0) - return FALSE; - break; - default: - break; - } - - /* transfers & shared are always supported */ - usage &= ~(PIPE_BIND_TRANSFER_READ | - PIPE_BIND_TRANSFER_WRITE | - PIPE_BIND_SHARED); - - return (nv50_format_table[format].usage & usage) == usage; + if (sample_count > 1) + return FALSE; + + if (!util_format_s3tc_enabled) { + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return FALSE; + default: + break; + } + } + + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + if (nv50_screen(pscreen)->tesla->grclass < NVA0_3D) + return FALSE; + break; + default: + break; + } + + /* transfers & shared are always supported */ + bindings &= ~(PIPE_BIND_TRANSFER_READ | + PIPE_BIND_TRANSFER_WRITE | + PIPE_BIND_SHARED); + + return (nv50_format_table[format].usage & bindings) == bindings; } static int nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) { - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 32; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 32; - case PIPE_CAP_MAX_COMBINED_SAMPLERS: - return 64; - case PIPE_CAP_NPOT_TEXTURES: - return 1; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; - case PIPE_CAP_GLSL: - case PIPE_CAP_SM3: - return 1; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; - case PIPE_CAP_POINT_SPRITE: - return 1; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 8; - case PIPE_CAP_OCCLUSION_QUERY: - return 1; - case PIPE_CAP_TIMER_QUERY: - return 0; - case PIPE_CAP_STREAM_OUTPUT: - return 0; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 13; - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - 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_TEXTURE_SWIZZLE: - return 1; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 1; - case PIPE_CAP_INDEP_BLEND_ENABLE: - return 1; - case PIPE_CAP_INDEP_BLEND_FUNC: - return 0; - case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; - case PIPE_CAP_DEPTH_CLAMP: - return 1; - case PIPE_CAP_SHADER_STENCIL_EXPORT: - return 0; - case PIPE_CAP_PRIMITIVE_RESTART: - return 0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + return 32; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 64; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 13; + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 10; + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 13; + case PIPE_CAP_ARRAY_TEXTURES: /* shader support missing */ + return 0; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + case PIPE_CAP_TEXTURE_SWIZZLE: + case PIPE_CAP_TEXTURE_SHADOW_MAP: + case PIPE_CAP_NPOT_TEXTURES: + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + case PIPE_CAP_DEPTH_CLAMP: + case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_GLSL: + case PIPE_CAP_SM3: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 8; + case PIPE_CAP_TIMER_QUERY: + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + case PIPE_CAP_STREAM_OUTPUT: + return 0; + case PIPE_CAP_BLEND_EQUATION_SEPARATE: + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 1; + case PIPE_CAP_INDEP_BLEND_FUNC: + return nv50_screen(pscreen)->tesla->grclass >= NVA3_3D; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; + case PIPE_CAP_SHADER_STENCIL_EXPORT: + return 0; + case PIPE_CAP_PRIMITIVE_RESTART: + case PIPE_CAP_INSTANCED_DRAWING: + return 1; + default: + NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); + return 0; + } } static int nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, - enum pipe_shader_cap param) + enum pipe_shader_cap param) { - switch(shader) { - case PIPE_SHADER_FRAGMENT: - case PIPE_SHADER_VERTEX: - break; - case PIPE_SHADER_GEOMETRY: - default: - return 0; - } - - switch(param) { - case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: - case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: - case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: - case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: /* arbitrary limit */ - return 16384; - case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */ - return 4; - case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */ - if (shader == PIPE_SHADER_GEOMETRY) - return 128 / 4; - else - return 64 / 4; - case PIPE_SHADER_CAP_MAX_CONSTS: - return 65536 / 16; - case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: /* 16 - 1, but not implemented */ - return 1; - case PIPE_SHADER_CAP_MAX_ADDRS: /* no spilling atm */ - return 1; - case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */ - return 0; - case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */ - return NV50_CAP_MAX_PROGRAM_TEMPS; - case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: - return 1; - case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: - case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: - case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: - case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: - return 1; - case PIPE_SHADER_CAP_SUBROUTINES: - return 0; - default: - return 0; - } + switch (shader) { + case PIPE_SHADER_VERTEX: + case PIPE_SHADER_GEOMETRY: + case PIPE_SHADER_FRAGMENT: + break; + default: + return 0; + } + + switch (param) { + case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: + return 16384; + case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: + return 4; + case PIPE_SHADER_CAP_MAX_INPUTS: + if (shader == PIPE_SHADER_VERTEX) + return 32; + return 0x300 / 16; + case PIPE_SHADER_CAP_MAX_CONSTS: + return 65536 / 16; + case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: + return 14; + case PIPE_SHADER_CAP_MAX_ADDRS: + return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + return shader != PIPE_SHADER_FRAGMENT; + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; + case PIPE_SHADER_CAP_MAX_PREDS: + return 0; + case PIPE_SHADER_CAP_MAX_TEMPS: + return NV50_CAP_MAX_PROGRAM_TEMPS; + case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: + return 1; + case PIPE_SHADER_CAP_SUBROUTINES: + return 0; /* please inline, or provide function declarations */ + default: + NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param); + return 0; + } } static float nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) { - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 10.0; - case PIPE_CAP_MAX_POINT_WIDTH: - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 64.0; - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 16.0; - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 4.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 10.0f; + case PIPE_CAP_MAX_POINT_WIDTH: + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 64.0f; + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 16.0f; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 4.0f; + default: + NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); + return 0.0f; + } } static void nv50_screen_destroy(struct pipe_screen *pscreen) { - struct nv50_screen *screen = nv50_screen(pscreen); - unsigned i; - - for (i = 0; i < 3; i++) { - if (screen->constbuf_parm[i]) - nouveau_bo_ref(NULL, &screen->constbuf_parm[i]); - } - - if (screen->constbuf_misc[0]) - nouveau_bo_ref(NULL, &screen->constbuf_misc[0]); - if (screen->tic) - nouveau_bo_ref(NULL, &screen->tic); - if (screen->tsc) - nouveau_bo_ref(NULL, &screen->tsc); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->tesla); - nouveau_grobj_free(&screen->eng2d); - nouveau_grobj_free(&screen->m2mf); - nouveau_resource_destroy(&screen->immd_heap); - nouveau_screen_fini(&screen->base); - FREE(screen); -} + struct nv50_screen *screen = nv50_screen(pscreen); -#define BGN_RELOC(ch, bo, gr, m, n, fl) \ - OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0) + if (screen->base.fence.current) { + nouveau_fence_wait(screen->base.fence.current); + nouveau_fence_ref (NULL, &screen->base.fence.current); + } -void -nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi) + nouveau_bo_ref(NULL, &screen->code); + nouveau_bo_ref(NULL, &screen->tls_bo); + nouveau_bo_ref(NULL, &screen->stack_bo); + nouveau_bo_ref(NULL, &screen->txc); + nouveau_bo_ref(NULL, &screen->uniforms); + nouveau_bo_ref(NULL, &screen->fence.bo); + + nouveau_resource_destroy(&screen->vp_code_heap); + nouveau_resource_destroy(&screen->gp_code_heap); + nouveau_resource_destroy(&screen->fp_code_heap); + + if (screen->tic.entries) + FREE(screen->tic.entries); + + nouveau_mm_destroy(screen->mm_VRAM_fe0); + + nouveau_grobj_free(&screen->tesla); + nouveau_grobj_free(&screen->eng2d); + nouveau_grobj_free(&screen->m2mf); + + nouveau_notifier_free(&screen->sync); + + nouveau_screen_fini(&screen->base); + + FREE(screen); +} + +static void +nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence) { - struct nouveau_bo *bo; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *tesla = screen->tesla; - unsigned size; - const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; - - switch (cbi) { - case NV50_CB_PMISC: - bo = screen->constbuf_misc[0]; - size = 0x200; - break; - case NV50_CB_PVP: - case NV50_CB_PFP: - case NV50_CB_PGP: - bo = screen->constbuf_parm[cbi - NV50_CB_PVP]; - size = 0; - break; - default: - return; - } - - BGN_RELOC (chan, bo, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl); - OUT_RELOCh(chan, bo, 0, rl); - OUT_RELOCl(chan, bo, 0, rl); - OUT_RELOC (chan, bo, (cbi << 16) | size, rl, 0, 0); + struct nv50_screen *screen = nv50_screen(pscreen); + struct nouveau_channel *chan = screen->base.channel; + + MARK_RING (chan, 5, 2); + BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); + OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); + OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); + OUT_RING (chan, sequence); + OUT_RING (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | + NV50_3D_QUERY_GET_UNK4 | + NV50_3D_QUERY_GET_UNIT_CROP | + NV50_3D_QUERY_GET_TYPE_QUERY | + NV50_3D_QUERY_GET_QUERY_SELECT_ZERO | + NV50_3D_QUERY_GET_SHORT); } -void -nv50_screen_relocs(struct nv50_screen *screen) +static u32 +nv50_screen_fence_update(struct pipe_screen *pscreen) { - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *tesla = screen->tesla; - unsigned i; - const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; + struct nv50_screen *screen = nv50_screen(pscreen); + return screen->fence.map[0]; +} - MARK_RING (chan, 28, 26); +#define FAIL_SCREEN_INIT(str, err) \ + do { \ + NOUVEAU_ERR(str, err); \ + nv50_screen_destroy(pscreen); \ + return NULL; \ + } while(0) - /* cause grobj autobind */ - BEGIN_RING(chan, tesla, 0x0100, 1); - OUT_RING (chan, 0); +struct pipe_screen * +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) +{ + struct nv50_screen *screen; + struct nouveau_channel *chan; + struct pipe_screen *pscreen; + uint64_t value; + uint32_t tesla_class; + unsigned stack_size, max_warps, tls_space; + int ret; + unsigned i, base; + + screen = CALLOC_STRUCT(nv50_screen); + if (!screen) + return NULL; + pscreen = &screen->base.base; + + screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; + + ret = nouveau_screen_init(&screen->base, dev); + if (ret) + FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); + + chan = screen->base.channel; + + pscreen->winsys = ws; + pscreen->destroy = nv50_screen_destroy; + pscreen->context_create = nv50_create; + pscreen->is_format_supported = nv50_screen_is_format_supported; + pscreen->get_param = nv50_screen_get_param; + pscreen->get_shader_param = nv50_screen_get_shader_param; + pscreen->get_paramf = nv50_screen_get_paramf; + + nv50_screen_init_resource_functions(pscreen); + + ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, + &screen->fence.bo); + if (ret) + goto fail; + nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); + screen->fence.map = screen->fence.bo->map; + nouveau_bo_unmap(screen->fence.bo); + screen->base.fence.emit = nv50_screen_fence_emit; + screen->base.fence.update = nv50_screen_fence_update; + + ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); + if (ret) + FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret); + + ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf); + if (ret) + FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); + + BIND_RING (chan, screen->m2mf, NV50_SUBCH_MF); + BEGIN_RING(chan, RING_MF_(NV04_M2MF_DMA_NOTIFY), 3); + OUT_RING (chan, screen->sync->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + + ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); + if (ret) + FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); + + BIND_RING (chan, screen->eng2d, NV50_SUBCH_2D); + BEGIN_RING(chan, RING_2D(DMA_NOTIFY), 4); + OUT_RING (chan, screen->sync->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, RING_2D(OPERATION), 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_2D_(0x0888), 1); + OUT_RING (chan, 1); + + switch (dev->chipset & 0xf0) { + case 0x50: + tesla_class = NV50_3D; + break; + case 0x80: + case 0x90: + tesla_class = NV84_3D; + break; + case 0xa0: + switch (dev->chipset) { + case 0xa0: + case 0xaa: + case 0xac: + tesla_class = NVA0_3D; + break; + case 0xaf: + tesla_class = NVAF_3D; + break; + default: + tesla_class = NVA3_3D; + break; + } + break; + default: + FAIL_SCREEN_INIT("Not a known NV50 chipset: NV%02x\n", dev->chipset); + break; + } + + ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla); + if (ret) + FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); + + BIND_RING (chan, screen->tesla, NV50_SUBCH_3D); + + BEGIN_RING(chan, RING_3D(COND_MODE), 1); + OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS); + + BEGIN_RING(chan, RING_3D(DMA_NOTIFY), 1); + OUT_RING (chan, screen->sync->handle); + BEGIN_RING(chan, RING_3D(DMA_ZETA), 11); + for (i = 0; i < 11; ++i) + OUT_RING(chan, chan->vram->handle); + BEGIN_RING(chan, RING_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); + for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, RING_3D(REG_MODE), 1); + OUT_RING (chan, NV50_3D_REG_MODE_STRIPED); + BEGIN_RING(chan, RING_3D(UNK1400_LANES), 1); + OUT_RING (chan, 0xf); + + BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); + OUT_RING (chan, 1); + + BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); + OUT_RING (chan, NV50_3D_MULTISAMPLE_MODE_MS1); + BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(ZCULL_REGION), 1); /* deactivate ZCULL */ + OUT_RING (chan, 0x3f); + + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, + 3 << NV50_CODE_BO_SIZE_LOG2, &screen->code); + if (ret) + goto fail; + + nouveau_resource_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + nouveau_resource_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + nouveau_resource_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + + base = 1 << NV50_CODE_BO_SIZE_LOG2; + + BEGIN_RING(chan, RING_3D(VP_ADDRESS_HIGH), 2); + OUT_RELOCh(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + BEGIN_RING(chan, RING_3D(FP_ADDRESS_HIGH), 2); + OUT_RELOCh(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + BEGIN_RING(chan, RING_3D(GP_ADDRESS_HIGH), 2); + OUT_RELOCh(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); + + max_warps = util_bitcount(value & 0xffff); + max_warps *= util_bitcount((value >> 24) & 0xf) * 32; + + stack_size = max_warps * 64 * 8; + + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, + &screen->stack_bo); + if (ret) + FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret); + + BEGIN_RING(chan, RING_3D(STACK_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RING (chan, 4); + + tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16; + + screen->tls_size = tls_space * max_warps * 32; + + debug_printf("max_warps = %i, tls_size = %lu KiB\n", + max_warps, screen->tls_size >> 10); + + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, + &screen->tls_bo); + if (ret) + FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret); + + BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RING (chan, util_unsigned_logbase2(tls_space / 8)); + + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, + &screen->uniforms); + if (ret) + goto fail; + + BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, (NV50_CB_PVP << 16) | 0x0000); + + BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, (NV50_CB_PGP << 16) | 0x0000); + + BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, (NV50_CB_PFP << 16) | 0x0000); + + BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200); + + BEGIN_RING_NI(chan, RING_3D(SET_PROGRAM_CB), 6); + OUT_RING (chan, (NV50_CB_PVP << 12) | 0x001); + OUT_RING (chan, (NV50_CB_PGP << 12) | 0x021); + OUT_RING (chan, (NV50_CB_PFP << 12) | 0x031); + OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf01); + OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf21); + OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf31); + + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, + &screen->txc); + if (ret) + FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret); + + /* max TIC (bits 4:8) & TSC bindings, per program type */ + for (i = 0; i < 3; ++i) { + BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1); + OUT_RING (chan, 0x54); + } + + BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, NV50_TIC_MAX_ENTRIES - 1); + + BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, NV50_TSC_MAX_ENTRIES - 1); + + BEGIN_RING(chan, RING_3D(LINKED_TSC), 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1); + OUT_RING (chan, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); + BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2); + for (i = 0; i < 8 * 2; ++i) + OUT_RING(chan, 0); + BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); + OUT_RINGf (chan, 0.0f); + OUT_RINGf (chan, 1.0f); + + BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1); +#ifdef NV50_SCISSORS_CLIPPING + OUT_RING (chan, 0x0000); +#else + OUT_RING (chan, 0x1080); +#endif + + BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1); + OUT_RING (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); - BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl); - OUT_RELOCh(chan, screen->tic, 0, rl); - OUT_RELOCl(chan, screen->tic, 0, rl); + /* We use scissors instead of exact view volume clipping, + * so they're always enabled. + */ + BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3); + OUT_RING (chan, 1); + OUT_RING (chan, 8192 << 16); + OUT_RING (chan, 8192 << 16); - BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl); - OUT_RELOCh(chan, screen->tsc, 0, rl); - OUT_RELOCl(chan, screen->tsc, 0, rl); + BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1); + OUT_RING (chan, NV50_3D_POINT_RASTER_RULES_OGL); + BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); + OUT_RING (chan, 0x11111111); + BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); + OUT_RING (chan, 1); - nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC); + FIRE_RING (chan); - BGN_RELOC (chan, screen->constbuf_misc[0], - tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl); - OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl); - OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl); - OUT_RELOC (chan, screen->constbuf_misc[0], - (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0); + screen->tic.entries = CALLOC(4096, sizeof(void *)); + screen->tsc.entries = screen->tic.entries + 2048; - for (i = 0; i < 3; ++i) - nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i); + screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); - BGN_RELOC (chan, screen->stack_bo, - tesla, NV50TCL_STACK_ADDRESS_HIGH, 2, rl); - OUT_RELOCh(chan, screen->stack_bo, 0, rl); - OUT_RELOCl(chan, screen->stack_bo, 0, rl); + nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); - if (!screen->cur_ctx->req_lmem) - return; + return pscreen; - BGN_RELOC (chan, screen->local_bo, - tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 2, rl); - OUT_RELOCh(chan, screen->local_bo, 0, rl); - OUT_RELOCl(chan, screen->local_bo, 0, rl); +fail: + nv50_screen_destroy(pscreen); + return NULL; } -#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS -# define NOUVEAU_GETPARAM_GRAPH_UNITS 13 -#endif +void +nv50_screen_make_buffers_resident(struct nv50_screen *screen) +{ + struct nouveau_channel *chan = screen->base.channel; -extern int nouveau_device_get_param(struct nouveau_device *dev, - uint64_t param, uint64_t *value); + const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; -struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) + MARK_RING(chan, 5, 5); + nouveau_bo_validate(chan, screen->code, flags); + nouveau_bo_validate(chan, screen->uniforms, flags); + nouveau_bo_validate(chan, screen->txc, flags); + nouveau_bo_validate(chan, screen->tls_bo, flags); + nouveau_bo_validate(chan, screen->stack_bo, flags); +} + +int +nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry) { - struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - uint64_t value; - unsigned chipset = dev->chipset; - unsigned tesla_class = 0; - unsigned stack_size, local_size, max_warps; - int ret, i; - const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv50_screen_destroy; - pscreen->get_param = nv50_screen_get_param; - pscreen->get_shader_param = nv50_screen_get_shader_param; - pscreen->get_paramf = nv50_screen_get_paramf; - pscreen->is_format_supported = nv50_screen_is_format_supported; - pscreen->context_create = nv50_create; - - nv50_screen_init_resource_functions(pscreen); - - /* DMA engine object */ - ret = nouveau_grobj_alloc(chan, 0xbeef5039, - NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf); - if (ret) { - NOUVEAU_ERR("Error creating M2MF object: %d\n", ret); - nv50_screen_destroy(pscreen); - return NULL; - } - - /* 2D object */ - ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); - if (ret) { - NOUVEAU_ERR("Error creating 2D object: %d\n", ret); - nv50_screen_destroy(pscreen); - return NULL; - } - - /* 3D object */ - switch (chipset & 0xf0) { - case 0x50: - tesla_class = NV50TCL; - break; - case 0x80: - case 0x90: - tesla_class = NV84TCL; - break; - case 0xa0: - switch (chipset) { - case 0xa0: - case 0xaa: - case 0xac: - tesla_class = NVA0TCL; - break; - default: - tesla_class = NVA8TCL; - break; - } - break; - default: - NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset); - nv50_screen_destroy(pscreen); - return NULL; - } - - ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, - &screen->tesla); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - nv50_screen_destroy(pscreen); - return NULL; - } - - /* this is necessary for the new RING_3D / statebuffer code */ - BIND_RING(chan, screen->tesla, 7); - - /* Sync notifier */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv50_screen_destroy(pscreen); - return NULL; - } - - /* Static M2MF init */ - BEGIN_RING(chan, screen->m2mf, - NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); - OUT_RING (chan, screen->sync->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - - /* Static 2D init */ - BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4); - OUT_RING (chan, screen->sync->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, screen->eng2d, 0x0888, 1); - OUT_RING (chan, 1); - - /* Static tesla init */ - BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1); - OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS); - BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1); - OUT_RING (chan, screen->sync->handle); - BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11); - for (i = 0; i < 11; i++) - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, screen->tesla, - NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE); - for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++) - OUT_RING (chan, chan->vram->handle); - - BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1); - OUT_RING (chan, 1); - - /* activate all 32 lanes (threads) in a warp */ - BEGIN_RING(chan, screen->tesla, NV50TCL_REG_MODE, 1); - OUT_RING (chan, NV50TCL_REG_MODE_STRIPED); - BEGIN_RING(chan, screen->tesla, 0x1400, 1); - OUT_RING (chan, 0xf); - - /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */ - for (i = 0; i < 3; ++i) { - BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1); - OUT_RING (chan, 0x54); - } - - /* origin is top left (set to 1 for bottom left) */ - BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); - OUT_RING (chan, 8); - - BEGIN_RING(chan, screen->tesla, NV50TCL_CLEAR_FLAGS, 1); - OUT_RING (chan, NV50TCL_CLEAR_FLAGS_D3D); - - /* constant buffers for immediates and VP/FP parameters */ - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4, - &screen->constbuf_misc[0]); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl); - OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl); - OUT_RING (chan, (NV50_CB_PMISC << 16) | 0x0200); - BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl); - OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl); - OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200); - - for (i = 0; i < 3; i++) { - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (4096 * 4) * 4, - &screen->constbuf_parm[i]); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl); - OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl); - /* CB_DEF_SET_SIZE value of 0x0000 means 65536 */ - OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0000); - } - - if (nouveau_resource_init(&screen->immd_heap, 0, 128)) { - NOUVEAU_ERR("Error initialising shader immediates heap.\n"); - nv50_screen_destroy(pscreen); - return NULL; - } - - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4), - &screen->tic); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 3 * 32 - 1); - - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4), - &screen->tsc); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */ - - /* map constant buffers: - * B = buffer ID (maybe more than 1 byte) - * N = CB index used in shader instruction - * P = program type (0 = VP, 2 = GP, 3 = FP) - * SET_PROGRAM_CB = 0x000BBNP1 - */ - BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8); - /* bind immediate buffer */ - OUT_RING (chan, 0x001 | (NV50_CB_PMISC << 12)); - OUT_RING (chan, 0x021 | (NV50_CB_PMISC << 12)); - OUT_RING (chan, 0x031 | (NV50_CB_PMISC << 12)); - /* bind auxiliary constbuf to immediate data bo */ - OUT_RING (chan, 0x201 | (NV50_CB_AUX << 12)); - OUT_RING (chan, 0x221 | (NV50_CB_AUX << 12)); - /* bind parameter buffers */ - OUT_RING (chan, 0x101 | (NV50_CB_PVP << 12)); - OUT_RING (chan, 0x121 | (NV50_CB_PGP << 12)); - OUT_RING (chan, 0x131 | (NV50_CB_PFP << 12)); - - /* shader stack */ - nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); - - max_warps = util_bitcount(value & 0xffff); - max_warps *= util_bitcount((value >> 24) & 0xf) * 32; - - stack_size = max_warps * 64 * 8; - - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, - stack_size, &screen->stack_bo); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, 4); - - local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32; - - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, - local_size, &screen->local_bo); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } - - local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16; - - BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3); - OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, util_unsigned_logbase2(local_size / 8)); - - /* Vertex array limits - max them out */ - for (i = 0; i < 16; i++) { - BEGIN_RING(chan, screen->tesla, - NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2); - OUT_RING (chan, 0x000000ff); - OUT_RING (chan, 0xffffffff); - } - - BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 1.0f); - - BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); - OUT_RING (chan, 1); - - /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */ - BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1); - OUT_RING (chan, 1); - - BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, 1); /* default edgeflag to TRUE */ - - FIRE_RING (chan); - - screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE); - if(!screen->force_push) - screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART; - return pscreen; + int i = screen->tic.next; + + while (screen->tic.lock[i / 32] & (1 << (i % 32))) + i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); + + screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); + + if (screen->tic.entries[i]) + nv50_tic_entry(screen->tic.entries[i])->id = -1; + + screen->tic.entries[i] = entry; + return i; } +int +nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry) +{ + int i = screen->tsc.next; + + while (screen->tsc.lock[i / 32] & (1 << (i % 32))) + i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); + + screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); + + if (screen->tsc.entries[i]) + nv50_tsc_entry(screen->tsc.entries[i])->id = -1; + + screen->tsc.entries[i] = entry; + return i; +} diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 6e15230b486..aea434b8679 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -1,53 +1,148 @@ #ifndef __NV50_SCREEN_H__ #define __NV50_SCREEN_H__ +#define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" +#include "nouveau/nouveau_fence.h" +#include "nouveau/nouveau_mm.h" +#undef NOUVEAU_NVC0 +#include "nv50_winsys.h" +#include "nv50_stateobj.h" + +#define NV50_TIC_MAX_ENTRIES 2048 +#define NV50_TSC_MAX_ENTRIES 2048 struct nv50_context; -struct nv50_screen { - struct nouveau_screen base; +#define NV50_CODE_BO_SIZE_LOG2 19 - struct nouveau_winsys *nvws; +#define NV50_SCRATCH_SIZE (2 << 20) +#define NV50_SCRATCH_NR_BUFFERS 2 - struct nv50_context *cur_ctx; +struct nv50_screen { + struct nouveau_screen base; + struct nouveau_winsys *nvws; + + struct nv50_context *cur_ctx; + + struct nouveau_bo *code; + struct nouveau_bo *uniforms; + struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */ + struct nouveau_bo *stack_bo; + struct nouveau_bo *tls_bo; + + uint64_t tls_size; + + struct nouveau_resource *vp_code_heap; + struct nouveau_resource *gp_code_heap; + struct nouveau_resource *fp_code_heap; + + struct { + void **entries; + int next; + uint32_t lock[NV50_TIC_MAX_ENTRIES / 32]; + } tic; + + struct { + void **entries; + int next; + uint32_t lock[NV50_TSC_MAX_ENTRIES / 32]; + } tsc; + + struct { + uint32_t *map; + struct nouveau_bo *bo; + } fence; + + struct nouveau_notifier *sync; + + struct nouveau_mman *mm_VRAM_fe0; + + struct nouveau_grobj *tesla; + struct nouveau_grobj *eng2d; + struct nouveau_grobj *m2mf; +}; - struct nouveau_grobj *tesla; - struct nouveau_grobj *eng2d; - struct nouveau_grobj *m2mf; - struct nouveau_notifier *sync; +static INLINE struct nv50_screen * +nv50_screen(struct pipe_screen *screen) +{ + return (struct nv50_screen *)screen; +} - struct nouveau_bo *constbuf_misc[1]; - struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES]; +void nv50_screen_make_buffers_resident(struct nv50_screen *); - struct nouveau_resource *immd_heap; +int nv50_screen_tic_alloc(struct nv50_screen *, void *); +int nv50_screen_tsc_alloc(struct nv50_screen *, void *); - struct nouveau_bo *tic; - struct nouveau_bo *tsc; +static INLINE void +nv50_resource_fence(struct nv04_resource *res, uint32_t flags) +{ + struct nv50_screen *screen = nv50_screen(res->base.screen); - struct nouveau_bo *stack_bo; /* control flow stack */ - struct nouveau_bo *local_bo; /* l[] memory */ + if (res->mm) { + nouveau_fence_ref(screen->base.fence.current, &res->fence); - boolean force_push; -}; + if (flags & NOUVEAU_BO_WR) + nouveau_fence_ref(screen->base.fence.current, &res->fence_wr); + } +} -static INLINE struct nv50_screen * -nv50_screen(struct pipe_screen *screen) +static INLINE void +nv50_resource_validate(struct nv04_resource *res, uint32_t flags) { - return (struct nv50_screen *)screen; -} + struct nv50_screen *screen = nv50_screen(res->base.screen); -extern void nv50_screen_relocs(struct nv50_screen *); + if (likely(res->bo)) { + nouveau_bo_validate(screen->base.channel, res->bo, flags); -extern void nv50_screen_reloc_constbuf(struct nv50_screen *, unsigned cbi); + if (flags & NOUVEAU_BO_WR) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + if (flags & NOUVEAU_BO_RD) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; + + nv50_resource_fence(res, flags); + } +} struct nv50_format { - uint32_t rt; - uint32_t tic; - uint32_t vtx; - uint32_t usage; + uint32_t rt; + uint32_t tic; + uint32_t vtx; + uint32_t usage; }; extern const struct nv50_format nv50_format_table[]; +static INLINE void +nv50_screen_tic_unlock(struct nv50_screen *screen, struct nv50_tic_entry *tic) +{ + if (tic->id >= 0) + screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32)); +} + +static INLINE void +nv50_screen_tsc_unlock(struct nv50_screen *screen, struct nv50_tsc_entry *tsc) +{ + if (tsc->id >= 0) + screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32)); +} + +static INLINE void +nv50_screen_tic_free(struct nv50_screen *screen, struct nv50_tic_entry *tic) +{ + if (tic->id >= 0) { + screen->tic.entries[tic->id] = NULL; + screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32)); + } +} + +static INLINE void +nv50_screen_tsc_free(struct nv50_screen *screen, struct nv50_tsc_entry *tsc) +{ + if (tsc->id >= 0) { + screen->tsc.entries[tsc->id] = NULL; + screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32)); + } +} + #endif diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 1c1b66deb3c..bea9c095bb3 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -28,422 +28,266 @@ #include "nv50_context.h" -static void -nv50_transfer_constbuf(struct nv50_context *nv50, - struct pipe_resource *buf, unsigned size, unsigned cbi) +void +nv50_constbufs_validate(struct nv50_context *nv50) { - struct pipe_context *pipe = &nv50->pipe; - struct pipe_transfer *transfer; struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - uint32_t *map; - unsigned count, start; + unsigned s; - if (buf == NULL) - return; + for (s = 0; s < 3; ++s) { + struct nv04_resource *res; + int i; + unsigned p, b; - map = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &transfer); - if (!map) - return; + if (s == PIPE_SHADER_FRAGMENT) + p = NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT; + else + if (s == PIPE_SHADER_GEOMETRY) + p = NV50_3D_SET_PROGRAM_CB_PROGRAM_GEOMETRY; + else + p = NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX; + + while (nv50->constbuf_dirty[s]) { + struct nouveau_bo *bo; + unsigned start = 0; + unsigned words = 0; + + i = ffs(nv50->constbuf_dirty[s]) - 1; + nv50->constbuf_dirty[s] &= ~(1 << i); + + res = nv04_resource(nv50->constbuf[s][i]); + if (!res) { + if (i != 0) { + BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1); + OUT_RING (chan, (i << 8) | p | 0); + } + continue; + } - count = (buf->width0 + 3) / 4; - start = 0; + if (i == 0) { + b = NV50_CB_PVP + s; - while (count) { - unsigned nr = AVAIL_RING(chan); + /* always upload GL uniforms through CB DATA */ + bo = nv50->screen->uniforms; + words = res->base.width0 / 4; + } else { + b = s * 16 + i; - if (nr < 8) { - FIRE_RING(chan); - continue; - } - nr = MIN2(count, nr - 7); - nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); + assert(0); - nv50_screen_reloc_constbuf(nv50->screen, cbi); + if (!nouveau_resource_mapped_by_gpu(&res->base)) { + nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM); - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); - OUT_RING (chan, (start << 8) | cbi); - BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), nr); - OUT_RINGp (chan, map, nr); + BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1); + OUT_RING (chan, 0); + } + MARK_RING (chan, 6, 2); + BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); + OUT_RESRCh(chan, res, 0, NOUVEAU_BO_RD); + OUT_RESRCl(chan, res, 0, NOUVEAU_BO_RD); + OUT_RING (chan, (b << 16) | (res->base.width0 & 0xffff)); + BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1); + OUT_RING (chan, (b << 12) | (i << 8) | p | 1); - count -= nr; - start += nr; - map += nr; - } - - pipe_buffer_unmap(pipe, transfer); -} + bo = res->bo; -static void -nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) -{ - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned cbi; - - if (p->immd_size) { - uint32_t *data = p->immd; - unsigned count = p->immd_size / 4; - unsigned start = 0; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res, + res->domain | NOUVEAU_BO_RD); + } - while (count) { - unsigned nr = AVAIL_RING(chan); + if (words) { + MARK_RING(chan, 8, 1); - if (nr < 8) { - FIRE_RING(chan); - continue; + nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR); } - nr = MIN2(count, nr - 7); - nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); - nv50_screen_reloc_constbuf(nv50->screen, NV50_CB_PMISC); + while (words) { + unsigned nr = AVAIL_RING(chan); - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); - OUT_RING (chan, (start << 8) | NV50_CB_PMISC); - BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), nr); - OUT_RINGp (chan, data, nr); + if (nr < 16) { + FIRE_RING(chan); + nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR); + continue; + } + nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN); - count -= nr; - start += nr; - data += nr; - } - } + BEGIN_RING(chan, RING_3D(CB_ADDR), 1); + OUT_RING (chan, (start << 8) | b); + BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr); + OUT_RINGp (chan, &res->data[start * 4], nr); - /* If the state tracker doesn't change the constbuf, and it is first - * validated with a program that doesn't use it, this check prevents - * it from even being uploaded. */ - /* - if (p->parm_size == 0) - return; - */ - - switch (p->type) { - case PIPE_SHADER_VERTEX: - cbi = NV50_CB_PVP; - break; - case PIPE_SHADER_FRAGMENT: - cbi = NV50_CB_PFP; - break; - case PIPE_SHADER_GEOMETRY: - cbi = NV50_CB_PGP; - break; - default: - assert(0); - return; + start += nr; + words -= nr; + } + } } - - nv50_transfer_constbuf(nv50, nv50->constbuf[p->type], p->parm_size, cbi); } -static void -nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) +static boolean +nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) { - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_grobj *eng2d = nv50->screen->eng2d; + struct nouveau_resource *heap; int ret; - unsigned offset; - unsigned size = p->code_size; - uint32_t *data = p->code; + unsigned size; - assert(p->translated); + if (prog->translated) + return TRUE; - /* TODO: use a single bo (for each type) for shader code */ - if (p->bo) - return; - ret = nouveau_bo_new(chan->device, NOUVEAU_BO_VRAM, 0x100, size, &p->bo); - assert(!ret); - - offset = p->code_start = 0; - - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); - OUT_RING (chan, NV50_2D_DST_FORMAT_R8_UNORM); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 1); - OUT_RING (chan, 0x40000); - BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 2); - OUT_RING (chan, 0x10000); - OUT_RING (chan, 1); - - while (size) { - unsigned nr = size / 4; - - if (AVAIL_RING(chan) < 32) - FIRE_RING(chan); - - nr = MIN2(nr, AVAIL_RING(chan) - 18); - nr = MIN2(nr, 1792); - if (nr < (size / 4)) - nr &= ~0x3f; - assert(!(size & 3)); - - BEGIN_RING(chan, eng2d, NV50_2D_DST_ADDRESS_HIGH, 2); - OUT_RELOCh(chan, p->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, p->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, NV50_2D_SIFC_FORMAT_R8_UNORM); - BEGIN_RING(chan, eng2d, NV50_2D_SIFC_WIDTH, 10); - OUT_RING (chan, nr * 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - - BEGIN_RING_NI(chan, eng2d, NV50_2D_SIFC_DATA, nr); - OUT_RINGp (chan, data, nr); - - data += nr; - offset += nr * 4; - size -= nr * 4; - } + prog->translated = nv50_program_translate(prog); + if (!prog->translated) + return FALSE; - BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1); - OUT_RING (chan, 0); -} + if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap; + else + if (prog->type == PIPE_SHADER_GEOMETRY) heap = nv50->screen->gp_code_heap; + else + heap = nv50->screen->vp_code_heap; -static void -nv50_vp_update_stateobj(struct nv50_context *nv50, struct nv50_program *p) -{ - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(5, 7, 2); - - nv50_program_validate_code(nv50, p); - - so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); - so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2); - so_data (so, p->vp.attrs[0]); - so_data (so, p->vp.attrs[1]); - so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); - so_data (so, p->max_out); - so_method(so, tesla, NV50TCL_VP_REG_ALLOC_TEMP, 1); - so_data (so, p->max_gpr); - so_method(so, tesla, NV50TCL_VP_START_ID, 1); - so_data (so, p->code_start); - - so_ref(so, &p->so); - so_ref(NULL, &so); -} + size = align(prog->code_size, 0x100); -static void -nv50_fp_update_stateobj(struct nv50_context *nv50, struct nv50_program *p) -{ - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(6, 7, 2); - - nv50_program_validate_code(nv50, p); - - so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); - so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, NV50TCL_FP_REG_ALLOC_TEMP, 1); - so_data (so, p->max_gpr); - so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1); - so_data (so, p->max_out); - so_method(so, tesla, NV50TCL_FP_CONTROL, 1); - so_data (so, p->fp.flags[0]); - so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1); - so_data (so, p->fp.flags[1]); - so_method(so, tesla, NV50TCL_FP_START_ID, 1); - so_data (so, p->code_start); - - so_ref(so, &p->so); - so_ref(NULL, &so); -} + ret = nouveau_resource_alloc(heap, size, prog, &prog->res); + if (ret) { + NOUVEAU_ERR("out of code space for shader type %i\n", prog->type); + return FALSE; + } + prog->code_base = prog->res->start; -static void -nv50_gp_update_stateobj(struct nv50_context *nv50, struct nv50_program *p) -{ - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(6, 7, 2); - - nv50_program_validate_code(nv50, p); - - so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2); - so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, NV50TCL_GP_REG_ALLOC_TEMP, 1); - so_data (so, p->max_gpr); - so_method(so, tesla, NV50TCL_GP_REG_ALLOC_RESULT, 1); - so_data (so, p->max_out); - so_method(so, tesla, NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE, 1); - so_data (so, p->gp.prim_type); - so_method(so, tesla, NV50TCL_GP_VERTEX_OUTPUT_COUNT, 1); - so_data (so, p->gp.vert_count); - so_method(so, tesla, NV50TCL_GP_START_ID, 1); - so_data (so, p->code_start); - - so_ref(so, &p->so); - so_ref(NULL, &so); -} + nv50_relocate_program(prog, prog->code_base, 0); -static boolean -nv50_program_validate(struct nv50_program *p) -{ - p->translated = nv50_program_tx(p); - assert(p->translated); - return p->translated; -} + nv50_sifc_linear_u8(&nv50->base, nv50->screen->code, + (prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base, + NOUVEAU_BO_VRAM, prog->code_size, prog->code); -static INLINE void -nv50_program_validate_common(struct nv50_context *nv50, struct nv50_program *p) -{ - nv50_program_validate_code(nv50, p); + BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1); + OUT_RING (nv50->screen->base.channel, 0); - if (p->uses_lmem) - nv50->req_lmem |= 1 << p->type; - else - nv50->req_lmem &= ~(1 << p->type); + return TRUE; } -struct nouveau_stateobj * +void nv50_vertprog_validate(struct nv50_context *nv50) { - struct nv50_program *p = nv50->vertprog; - struct nouveau_stateobj *so = NULL; - - if (!p->translated) { - if (nv50_program_validate(p)) - nv50_vp_update_stateobj(nv50, p); - else - return NULL; - } - - if (nv50->dirty & NV50_NEW_VERTPROG_CB) - nv50_program_validate_data(nv50, p); - - if (!(nv50->dirty & NV50_NEW_VERTPROG)) - return NULL; - - nv50_program_validate_common(nv50, p); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *vp = nv50->vertprog; - so_ref(p->so, &so); - return so; + if (!nv50_program_validate(nv50, vp)) + return; + + BEGIN_RING(chan, RING_3D(VP_ATTR_EN(0)), 2); + OUT_RING (chan, vp->vp.attrs[0]); + OUT_RING (chan, vp->vp.attrs[1]); + BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_RESULT), 1); + OUT_RING (chan, vp->max_out); + BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_TEMP), 1); + OUT_RING (chan, vp->max_gpr); + BEGIN_RING(chan, RING_3D(VP_START_ID), 1); + OUT_RING (chan, vp->code_base); } -struct nouveau_stateobj * +void nv50_fragprog_validate(struct nv50_context *nv50) { - struct nv50_program *p = nv50->fragprog; - struct nouveau_stateobj *so = NULL; - - if (!p->translated) { - if (nv50_program_validate(p)) - nv50_fp_update_stateobj(nv50, p); - else - return NULL; - } - - if (nv50->dirty & NV50_NEW_FRAGPROG_CB) - nv50_program_validate_data(nv50, p); - - if (!(nv50->dirty & NV50_NEW_FRAGPROG)) - return NULL; - - nv50_program_validate_common(nv50, p); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *fp = nv50->fragprog; - so_ref(p->so, &so); - return so; + if (!nv50_program_validate(nv50, fp)) + return; + + BEGIN_RING(chan, RING_3D(FP_REG_ALLOC_TEMP), 1); + OUT_RING (chan, fp->max_gpr); + BEGIN_RING(chan, RING_3D(FP_RESULT_COUNT), 1); + OUT_RING (chan, fp->max_out); + BEGIN_RING(chan, RING_3D(FP_CONTROL), 1); + OUT_RING (chan, fp->fp.flags[0]); + BEGIN_RING(chan, RING_3D(FP_CTRL_UNK196C), 1); + OUT_RING (chan, fp->fp.flags[1]); + BEGIN_RING(chan, RING_3D(FP_START_ID), 1); + OUT_RING (chan, fp->code_base); } -struct nouveau_stateobj * -nv50_geomprog_validate(struct nv50_context *nv50) +void +nv50_gmtyprog_validate(struct nv50_context *nv50) { - struct nv50_program *p = nv50->geomprog; - struct nouveau_stateobj *so = NULL; - - /* GP may be NULL, but VP and FP may not */ - if (!p) - return NULL; /* GP is deactivated in linkage validation */ - - if (!p->translated) { - if (nv50_program_validate(p)) - nv50_gp_update_stateobj(nv50, p); - else - return NULL; - } - - if (nv50->dirty & NV50_NEW_GEOMPROG_CB) - nv50_program_validate_data(nv50, p); - - if (!(nv50->dirty & NV50_NEW_GEOMPROG)) - return NULL; - - nv50_program_validate_common(nv50, p); - - so_ref(p->so, &so); - return so; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *gp = nv50->vertprog; + + if (!nv50_program_validate(nv50, gp)) + return; + + BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1); + OUT_RING (chan, gp->max_gpr); + BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_RESULT), 1); + OUT_RING (chan, gp->max_out); + BEGIN_RING(chan, RING_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1); + OUT_RING (chan, gp->gp.prim_type); + BEGIN_RING(chan, RING_3D(GP_VERTEX_OUTPUT_COUNT), 1); + OUT_RING (chan, gp->gp.vert_count); + BEGIN_RING(chan, RING_3D(GP_START_ID), 1); + OUT_RING (chan, gp->code_base); } -/* XXX: this might not work correctly in all cases yet: we assume that - * an FP generic input that is not written in the VP is gl_PointCoord. - */ -static uint32_t -nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m) +void +nv50_sprite_coords_validate(struct nv50_context *nv50) { - struct nv50_program *vp = nv50->vertprog; + struct nouveau_channel *chan = nv50->screen->base.channel; + uint32_t pntc[8], mode; struct nv50_program *fp = nv50->fragprog; unsigned i, c; + unsigned m = (nv50->state.interpolant_ctrl >> 8) & 0xff; + + if (!nv50->rast->pipe.point_quad_rasterization) { + if (nv50->state.point_sprite) { + BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8); + for (i = 0; i < 8; ++i) + OUT_RING(chan, 0); - memset(pntc, 0, 8 * sizeof(uint32_t)); + nv50->state.point_sprite = FALSE; + } + return; + } else { + nv50->state.point_sprite = TRUE; + } - if (nv50->geomprog) - vp = nv50->geomprog; + memset(pntc, 0, sizeof(pntc)); for (i = 0; i < fp->in_nr; i++) { - unsigned j, n = util_bitcount(fp->in[i].mask); + unsigned n = util_bitcount(fp->in[i].mask); if (fp->in[i].sn != TGSI_SEMANTIC_GENERIC) { m += n; continue; } - - for (j = 0; j < vp->out_nr; ++j) - if (vp->out[j].sn == fp->in[i].sn && vp->out[j].si == fp->in[i].si) - break; - - if (j < vp->out_nr) { - uint32_t en = nv50->rasterizer->pipe.sprite_coord_enable; - - if (!(en & (1 << vp->out[j].si))) { - m += n; - continue; - } + if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) { + m += n; + continue; } - /* this is either PointCoord or replaced by sprite coords */ - for (c = 0; c < 4; c++) { - if (!(fp->in[i].mask & (1 << c))) - continue; - pntc[m / 8] |= (c + 1) << ((m % 8) * 4); - ++m; + for (c = 0; c < 4; ++c) { + if (fp->in[i].mask & (1 << c)) { + pntc[m / 8] |= (c + 1) << ((m % 8) * 4); + ++m; + } } } - if (nv50->rasterizer->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) - return 0; - return (1 << 4); + + if (nv50->rast->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) + mode = 0x00; + else + mode = 0x10; + + BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1); + OUT_RING (chan, mode); + + BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8); + OUT_RINGp (chan, pntc, 8); } static int -nv50_vec4_map(uint32_t *map32, int mid, uint32_t lin[4], +nv50_vec4_map(uint8_t *map, int mid, uint32_t lin[4], struct nv50_varying *in, struct nv50_varying *out) { int c; uint8_t mv = out->mask, mf = in->mask, oid = out->hw; - uint8_t *map = (uint8_t *)map32; for (c = 0; c < 4; ++c) { if (mf & 1) { @@ -465,140 +309,112 @@ nv50_vec4_map(uint32_t *map32, int mid, uint32_t lin[4], return mid; } -struct nouveau_stateobj * +void nv50_fp_linkage_validate(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nv50_program *vp; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog; struct nv50_program *fp = nv50->fragprog; - struct nouveau_stateobj *so; struct nv50_varying dummy; int i, n, c, m; - - uint32_t map[16], lin[4], pntc[8]; - + uint32_t primid = 0; + uint32_t psiz = 0x000; uint32_t interp = fp->fp.interp; uint32_t colors = fp->fp.colors; - uint32_t clip = 0x04; - uint32_t psiz = 0x000; - uint32_t primid = 0; - uint32_t sysval = 0; + uint32_t lin[4]; + uint8_t map[64]; - if (nv50->geomprog) { - vp = nv50->geomprog; - memset(map, 0x80, sizeof(map)); - } else { - vp = nv50->vertprog; - memset(map, 0x40, sizeof(map)); - } - memset(lin, 0, sizeof(lin)); + memset(lin, 0x00, sizeof(lin)); + + /* XXX: in buggy-endian mode, is the first element of map (u32)0x000000xx + * or is it the first byte ? + */ + memset(map, nv50->gmtyprog ? 0x80 : 0x40, sizeof(map)); - dummy.linear = 0; dummy.mask = 0xf; /* map all components of HPOS */ + dummy.linear = 0; m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]); - if (vp->vp.clpd < 0x40) { - for (c = 0; c < vp->vp.clpd_nr; ++c) { - map[m / 4] |= (vp->vp.clpd + c) << ((m % 4) * 8); - ++m; - } - clip |= vp->vp.clpd_nr << 8; - } + for (c = 0; c < vp->vp.clpd_nr; ++c) + map[m++] |= vp->vp.clpd + c; colors |= m << 8; /* adjust BFC0 id */ - /* if light_twoside is active, it seems FFC0_ID == BFC0_ID is bad */ - if (nv50->rasterizer->pipe.light_twoside) { + /* if light_twoside is active, FFC0_ID == BFC0_ID is invalid */ + if (nv50->rast->pipe.light_twoside) { for (i = 0; i < 2; ++i) m = nv50_vec4_map(map, m, lin, - &fp->in[fp->vp.bfc[i]], - &vp->out[vp->vp.bfc[i]]); + &fp->in[fp->vp.bfc[i]], &vp->out[vp->vp.bfc[i]]); } - colors += m - 4; /* adjust FFC0 id */ - interp |= m << 8; /* set mid where 'normal' FP inputs start */ + interp |= m << 8; /* set map id where 'normal' FP inputs start */ dummy.mask = 0x0; - for (i = 0; i < fp->in_nr; i++) { + for (i = 0; i < fp->in_nr; ++i) { for (n = 0; n < vp->out_nr; ++n) if (vp->out[n].sn == fp->in[i].sn && vp->out[n].si == fp->in[i].si) break; - m = nv50_vec4_map(map, m, lin, &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy); - } + } /* PrimitiveID either is replaced by the system value, or * written by the geometry shader into an output register */ if (fp->gp.primid < 0x40) { - i = (m % 4) * 8; - map[m / 4] = (map[m / 4] & ~(0xff << i)) | (vp->gp.primid << i); - primid = m++; + primid = m; + map[m++] = vp->gp.primid; } - if (nv50->rasterizer->pipe.point_size_per_vertex) { - i = (m % 4) * 8; - map[m / 4] = (map[m / 4] & ~(0xff << i)) | (vp->vp.psiz << i); - psiz = (m++ << 4) | 1; + if (nv50->rast->pipe.point_size_per_vertex) { + psiz = (m << 4) | 1; + map[m++] = vp->vp.psiz; } - /* now fill the stateobj (at most 28 so_data) */ - so = so_new(10, 54, 0); - n = (m + 3) / 4; assert(m <= 64); - if (vp->type == PIPE_SHADER_GEOMETRY) { - so_method(so, tesla, NV50TCL_GP_RESULT_MAP_SIZE, 1); - so_data (so, m); - so_method(so, tesla, NV50TCL_GP_RESULT_MAP(0), n); - so_datap (so, map, n); + + if (unlikely(nv50->gmtyprog)) { + BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1); + OUT_RING (chan, m); + BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n); + OUT_RINGp (chan, map, n); } else { - so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1); - so_data (so, vp->vp.attrs[2]); + BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1); + OUT_RING (chan, vp->vp.attrs[2]); - so_method(so, tesla, NV50TCL_MAP_SEMANTIC_4, 1); - so_data (so, primid); + BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1); + OUT_RING (chan, primid); - so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1); - so_data (so, m); - so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), n); - so_datap (so, map, n); + BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1); + OUT_RING (chan, m); + BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n); + OUT_RINGp (chan, map, n); } - so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4); - so_data (so, colors); - so_data (so, clip); - so_data (so, sysval); - so_data (so, psiz); - - so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 1); - so_data (so, interp); - - so_method(so, tesla, NV50TCL_NOPERSPECTIVE_BITMAP(0), 4); - so_datap (so, lin, 4); + BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4); + OUT_RING (chan, colors); + OUT_RING (chan, (vp->vp.clpd_nr << 8) | 4); + OUT_RING (chan, 0); + OUT_RING (chan, psiz); - if (nv50->rasterizer->pipe.point_quad_rasterization) { - so_method(so, tesla, NV50TCL_POINT_SPRITE_CTRL, 1); - so_data (so, - nv50_pntc_replace(nv50, pntc, (interp >> 8) & 0xff)); + BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1); + OUT_RING (chan, interp); - so_method(so, tesla, NV50TCL_POINT_COORD_REPLACE_MAP(0), 8); - so_datap (so, pntc, 8); - } + nv50->state.interpolant_ctrl = interp; - so_method(so, tesla, NV50TCL_GP_ENABLE, 1); - so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0); + BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4); + OUT_RINGp (chan, lin, 4); - return so; + BEGIN_RING(chan, RING_3D(GP_ENABLE), 1); + OUT_RING (chan, nv50->gmtyprog ? 1 : 0); } static int -nv50_vp_gp_mapping(uint32_t *map32, int m, +nv50_vp_gp_mapping(uint8_t *map, int m, struct nv50_program *vp, struct nv50_program *gp) { - uint8_t *map = (uint8_t *)map32; int i, j, c; for (i = 0; i < gp->in_nr; ++i) { @@ -625,34 +441,29 @@ nv50_vp_gp_mapping(uint32_t *map32, int m, return m; } -struct nouveau_stateobj * +void nv50_gp_linkage_validate(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so; + struct nouveau_channel *chan = nv50->screen->base.channel; struct nv50_program *vp = nv50->vertprog; - struct nv50_program *gp = nv50->geomprog; - uint32_t map[16]; + struct nv50_program *gp = nv50->gmtyprog; int m = 0; + int n; + uint8_t map[64]; if (!gp) - return NULL; + return; memset(map, 0, sizeof(map)); m = nv50_vp_gp_mapping(map, m, vp, gp); - so = so_new(3, 24 - 3, 0); - - so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1); - so_data (so, vp->vp.attrs[2] | gp->vp.attrs[2]); - - assert(m <= 32); - so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1); - so_data (so, m); + n = (m + 3) / 4; - m = (m + 3) / 4; - so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m); - so_datap (so, map, m); + BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1); + OUT_RING (chan, vp->vp.attrs[2] | gp->vp.attrs[2]); - return so; + BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1); + OUT_RING (chan, m); + BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n); + OUT_RINGp (chan, map, n); } diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index ba2c3e8c281..3d6423b2238 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Ben Skeggs + * Copyright 2010 Christoph Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -20,873 +20,851 @@ * SOFTWARE. */ -#include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "util/u_transfer.h" #include "tgsi/tgsi_parse.h" +#include "nv50_stateobj.h" #include "nv50_context.h" -#include "nv50_texture.h" -#include "nouveau/nouveau_stateobj.h" +#include "nv50_3d.xml.h" +#include "nv50_texture.xml.h" + +#include "nouveau/nouveau_gldefs.h" static INLINE uint32_t nv50_colormask(unsigned mask) { - uint32_t cmask = 0; + uint32_t ret = 0; - if (mask & PIPE_MASK_R) - cmask |= 0x0001; - if (mask & PIPE_MASK_G) - cmask |= 0x0010; - if (mask & PIPE_MASK_B) - cmask |= 0x0100; - if (mask & PIPE_MASK_A) - cmask |= 0x1000; + if (mask & PIPE_MASK_R) + ret |= 0x0001; + if (mask & PIPE_MASK_G) + ret |= 0x0010; + if (mask & PIPE_MASK_B) + ret |= 0x0100; + if (mask & PIPE_MASK_A) + ret |= 0x1000; - return cmask; + return ret; } +#define NV50_BLEND_FACTOR_CASE(a, b) \ + case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b + static INLINE uint32_t -nv50_blend_func(unsigned factor) -{ - switch (factor) { - case PIPE_BLENDFACTOR_ZERO: - return NV50TCL_BLEND_FUNC_SRC_RGB_ZERO; - case PIPE_BLENDFACTOR_ONE: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE; - case PIPE_BLENDFACTOR_SRC_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR; - case PIPE_BLENDFACTOR_SRC_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA; - case PIPE_BLENDFACTOR_DST_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA; - case PIPE_BLENDFACTOR_DST_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_DST_COLOR; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - return NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE; - case PIPE_BLENDFACTOR_CONST_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR; - case PIPE_BLENDFACTOR_CONST_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA; - case PIPE_BLENDFACTOR_SRC1_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_COLOR; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_COLOR; - case PIPE_BLENDFACTOR_SRC1_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_ALPHA; - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_ALPHA; - default: - return NV50TCL_BLEND_FUNC_SRC_RGB_ZERO; - } +nv50_blend_fac(unsigned factor) +{ + switch (factor) { + NV50_BLEND_FACTOR_CASE(ONE, ONE); + NV50_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR); + NV50_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA); + NV50_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA); + NV50_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR); + NV50_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE); + NV50_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR); + NV50_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA); + NV50_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR); + NV50_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA); + NV50_BLEND_FACTOR_CASE(ZERO, ZERO); + NV50_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR); + NV50_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA); + NV50_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA); + NV50_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR); + NV50_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR); + NV50_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA); + NV50_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR); + NV50_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA); + default: + return NV50_3D_BLEND_FACTOR_ZERO; + } } static void * nv50_blend_state_create(struct pipe_context *pipe, - const struct pipe_blend_state *cso) -{ - struct nouveau_stateobj *so = so_new(5, 24, 0); - struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; - struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj); - unsigned i, blend_enabled = 0; - - /*XXX ignored: - * - dither - */ - - so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); - if (cso->independent_blend_enable) { - for (i = 0; i < 8; ++i) { - so_data(so, cso->rt[i].blend_enable); - if (cso->rt[i].blend_enable) - blend_enabled = 1; - } - } else - if (cso->rt[0].blend_enable) { - blend_enabled = 1; - for (i = 0; i < 8; i++) - so_data(so, 1); - } else { - for (i = 0; i < 8; i++) - so_data(so, 0); - } - if (blend_enabled) { - so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5); - so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); - so_data (so, nv50_blend_func(cso->rt[0].rgb_src_factor)); - so_data (so, nv50_blend_func(cso->rt[0].rgb_dst_factor)); - so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); - so_data (so, nv50_blend_func(cso->rt[0].alpha_src_factor)); - so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); - so_data (so, nv50_blend_func(cso->rt[0].alpha_dst_factor)); - } - - if (cso->logicop_enable == 0 ) { - so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 1); - so_data (so, 0); - } else { - so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 2); - so_data (so, 1); - so_data (so, nvgl_logicop_func(cso->logicop_func)); - } - - so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8); - if (cso->independent_blend_enable) - for (i = 0; i < 8; ++i) - so_data(so, nv50_colormask(cso->rt[i].colormask)); - else { - uint32_t cmask = nv50_colormask(cso->rt[0].colormask); - for (i = 0; i < 8; i++) - so_data(so, cmask); - } - - bso->pipe = *cso; - so_ref(so, &bso->so); - so_ref(NULL, &so); - return (void *)bso; + const struct pipe_blend_state *cso) +{ + struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj); + int i; + boolean emit_common_func = cso->rt[0].blend_enable; + + if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) { + SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); + SB_DATA (so, cso->independent_blend_enable); + } + + so->pipe = *cso; + + SB_BEGIN_3D(so, BLEND_ENABLE(0), 8); + if (cso->independent_blend_enable) { + for (i = 0; i < 8; ++i) { + SB_DATA(so, cso->rt[i].blend_enable); + if (cso->rt[i].blend_enable) + emit_common_func = TRUE; + } + + if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) { + emit_common_func = FALSE; + + for (i = 0; i < 8; ++i) { + if (!cso->rt[i].blend_enable) + continue; + SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6); + SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor)); + SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor)); + } + } + } else { + for (i = 0; i < 8; ++i) + SB_DATA(so, cso->rt[0].blend_enable); + } + + if (emit_common_func) { + SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); + SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); + SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor)); + SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor)); + SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); + SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor)); + SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); + SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor)); + } + + if (cso->logicop_enable) { + SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); + SB_DATA (so, 1); + SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); + } else { + SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1); + SB_DATA (so, 0); + } + + SB_BEGIN_3D(so, COLOR_MASK(0), 8); + if (cso->independent_blend_enable) { + for (i = 0; i < 8; ++i) + SB_DATA(so, nv50_colormask(cso->rt[i].colormask)); + } else { + uint32_t cmask = nv50_colormask(cso->rt[0].colormask); + for (i = 0; i < 8; ++i) + SB_DATA(so, cmask); + } + + assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); + return so; } static void nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->blend = hwcso; - nv50->dirty |= NV50_NEW_BLEND; + nv50->blend = hwcso; + nv50->dirty |= NV50_NEW_BLEND; } static void nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv50_blend_stateobj *bso = hwcso; - - so_ref(NULL, &bso->so); - FREE(bso); + FREE(hwcso); } -static INLINE unsigned -wrap_mode(unsigned wrap) -{ - switch (wrap) { - case PIPE_TEX_WRAP_REPEAT: - return NV50TSC_1_0_WRAPS_REPEAT; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - return NV50TSC_1_0_WRAPS_MIRROR_REPEAT; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - return NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER; - case PIPE_TEX_WRAP_CLAMP: - return NV50TSC_1_0_WRAPS_CLAMP; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: - return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER; - case PIPE_TEX_WRAP_MIRROR_CLAMP: - return NV50TSC_1_0_WRAPS_MIRROR_CLAMP; - default: - NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); - return NV50TSC_1_0_WRAPS_REPEAT; - } -} static void * -nv50_sampler_state_create(struct pipe_context *pipe, - const struct pipe_sampler_state *cso) -{ - struct nv50_sampler_stateobj *sso = CALLOC(1, sizeof(*sso)); - unsigned *tsc = sso->tsc; - float limit; - - tsc[0] = (0x00026000 | - (wrap_mode(cso->wrap_s) << 0) | - (wrap_mode(cso->wrap_t) << 3) | - (wrap_mode(cso->wrap_r) << 6)); - - switch (cso->mag_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - tsc[1] |= NV50TSC_1_1_MAGF_LINEAR; - break; - case PIPE_TEX_FILTER_NEAREST: - default: - tsc[1] |= NV50TSC_1_1_MAGF_NEAREST; - break; - } - - switch (cso->min_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - tsc[1] |= NV50TSC_1_1_MINF_LINEAR; - break; - case PIPE_TEX_FILTER_NEAREST: - default: - tsc[1] |= NV50TSC_1_1_MINF_NEAREST; - break; - } - - switch (cso->min_mip_filter) { - case PIPE_TEX_MIPFILTER_LINEAR: - tsc[1] |= NV50TSC_1_1_MIPF_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NEAREST: - tsc[1] |= NV50TSC_1_1_MIPF_NEAREST; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - tsc[1] |= NV50TSC_1_1_MIPF_NONE; - break; - } - - if (cso->max_anisotropy >= 16) - tsc[0] |= (7 << 20); - else - if (cso->max_anisotropy >= 12) - tsc[0] |= (6 << 20); - else { - tsc[0] |= (cso->max_anisotropy >> 1) << 20; - - if (cso->max_anisotropy >= 4) - tsc[1] |= NV50TSC_1_1_UNKN_ANISO_35; - else - if (cso->max_anisotropy >= 2) - tsc[1] |= NV50TSC_1_1_UNKN_ANISO_15; - } - - if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - /* XXX: must be deactivated for non-shadow textures */ - tsc[0] |= (1 << 9); - tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10; - } - - limit = CLAMP(cso->lod_bias, -16.0, 15.0); - tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 12; - - tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) | - ((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8); - - tsc[4] = fui(cso->border_color[0]); - tsc[5] = fui(cso->border_color[1]); - tsc[6] = fui(cso->border_color[2]); - tsc[7] = fui(cso->border_color[3]); - - sso->normalized = cso->normalized_coords; - return (void *)sso; -} - -/* type == 0 for VPs, 1 for GPs, 2 for FPs, which is how the - * relevant tesla methods are indexed (NV50TCL_BIND_TSC etc.) - */ -static INLINE void -nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type, - unsigned nr, void **sampler) +nv50_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv50_rasterizer_stateobj *so; + + so = CALLOC_STRUCT(nv50_rasterizer_stateobj); + if (!so) + return NULL; + so->pipe = *cso; + +#ifndef NV50_SCISSORS_CLIPPING + SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1); + SB_DATA (so, cso->scissor); +#endif + + SB_BEGIN_3D(so, SHADE_MODEL, 1); + SB_DATA (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT : + NV50_3D_SHADE_MODEL_SMOOTH); + SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1); + SB_DATA (so, !cso->flatshade_first); + SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1); + SB_DATA (so, cso->light_twoside); + + SB_BEGIN_3D(so, LINE_WIDTH, 1); + SB_DATA (so, fui(cso->line_width)); + SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1); + SB_DATA (so, cso->line_smooth); + + SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1); + if (cso->line_stipple_enable) { + SB_DATA (so, 1); + SB_BEGIN_3D(so, LINE_STIPPLE, 1); + SB_DATA (so, (cso->line_stipple_pattern << 8) | + cso->line_stipple_factor); + } else { + SB_DATA (so, 0); + } + + if (!cso->point_size_per_vertex) { + SB_BEGIN_3D(so, POINT_SIZE, 1); + SB_DATA (so, fui(cso->point_size)); + } + SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1); + SB_DATA (so, cso->point_quad_rasterization); + SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1); + SB_DATA (so, cso->point_smooth); + + SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3); + SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); + SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); + SB_DATA (so, cso->poly_smooth); + + SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); + SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); + SB_DATA (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW : + NV50_3D_FRONT_FACE_CW); + switch (cso->cull_face) { + case PIPE_FACE_FRONT_AND_BACK: + SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK); + break; + case PIPE_FACE_FRONT: + SB_DATA(so, NV50_3D_CULL_FACE_FRONT); + break; + case PIPE_FACE_BACK: + default: + SB_DATA(so, NV50_3D_CULL_FACE_BACK); + break; + } + + SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1); + SB_DATA (so, cso->poly_stipple_enable); + SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); + SB_DATA (so, cso->offset_point); + SB_DATA (so, cso->offset_line); + SB_DATA (so, cso->offset_tri); + + if (cso->offset_point || cso->offset_line || cso->offset_tri) { + SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); + SB_DATA (so, fui(cso->offset_scale)); + SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); + SB_DATA (so, fui(cso->offset_units * 2.0f)); + } + + assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); + return (void *)so; +} + +static void +nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - memcpy(nv50->sampler[type], sampler, nr * sizeof(void *)); + nv50->rast = hwcso; + nv50->dirty |= NV50_NEW_RASTERIZER; +} - nv50->sampler_nr[type] = nr; - nv50->dirty |= NV50_NEW_SAMPLER; +static void +nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + FREE(hwcso); +} + +static void * +nv50_zsa_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj); + + so->pipe = *cso; + + SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1); + SB_DATA (so, cso->depth.writemask); + SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1); + if (cso->depth.enabled) { + SB_DATA (so, 1); + SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1); + SB_DATA (so, nvgl_comparison_op(cso->depth.func)); + } else { + SB_DATA (so, 0); + } + + if (cso->stencil[0].enabled) { + SB_BEGIN_3D(so, STENCIL_ENABLE, 5); + SB_DATA (so, 1); + SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op)); + SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); + SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); + SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func)); + SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2); + SB_DATA (so, cso->stencil[0].writemask); + SB_DATA (so, cso->stencil[0].valuemask); + } else { + SB_BEGIN_3D(so, STENCIL_ENABLE, 1); + SB_DATA (so, 0); + } + + if (cso->stencil[1].enabled) { + assert(cso->stencil[0].enabled); + SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5); + SB_DATA (so, 1); + SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op)); + SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); + SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); + SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func)); + SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2); + SB_DATA (so, cso->stencil[1].writemask); + SB_DATA (so, cso->stencil[1].valuemask); + } else { + SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1); + SB_DATA (so, 0); + } + + SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1); + if (cso->alpha.enabled) { + SB_DATA (so, 1); + SB_BEGIN_3D(so, ALPHA_TEST_REF, 2); + SB_DATA (so, fui(cso->alpha.ref_value)); + SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); + } else { + SB_DATA (so, 0); + } + + assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); + return (void *)so; } static void -nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s) +nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso) { - nv50_sampler_state_bind(pipe, 0, nr, s); + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->zsa = hwcso; + nv50->dirty |= NV50_NEW_ZSA; } static void -nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s) +nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso) { - nv50_sampler_state_bind(pipe, 2, nr, s); + FREE(hwcso); +} + +/* ====================== SAMPLERS AND TEXTURES ================================ + */ + +#define NV50_TSC_WRAP_CASE(n) \ + case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n + +static INLINE unsigned +nv50_tsc_wrap_mode(unsigned wrap) +{ + switch (wrap) { + NV50_TSC_WRAP_CASE(REPEAT); + NV50_TSC_WRAP_CASE(MIRROR_REPEAT); + NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE); + NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER); + NV50_TSC_WRAP_CASE(CLAMP); + NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE); + NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER); + NV50_TSC_WRAP_CASE(MIRROR_CLAMP); + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + return NV50_TSC_WRAP_REPEAT; + } +} + +static void * +nv50_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + struct nv50_tsc_entry *so = CALLOC_STRUCT(nv50_tsc_entry); + float f[2]; + + so->id = -1; + + so->tsc[0] = (0x00026000 | + (nv50_tsc_wrap_mode(cso->wrap_s) << 0) | + (nv50_tsc_wrap_mode(cso->wrap_t) << 3) | + (nv50_tsc_wrap_mode(cso->wrap_r) << 6)); + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + so->tsc[1] |= NV50_TSC_1_MINF_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + so->tsc[1] |= NV50_TSC_1_MINF_NEAREST; + break; + } + + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_LINEAR: + so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NEAREST: + so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + so->tsc[1] |= NV50_TSC_1_MIPF_NONE; + break; + } + + if (cso->max_anisotropy >= 16) + so->tsc[0] |= (7 << 20); + else + if (cso->max_anisotropy >= 12) + so->tsc[0] |= (6 << 20); + else { + so->tsc[0] |= (cso->max_anisotropy >> 1) << 20; + + if (cso->max_anisotropy >= 4) + so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35; + else + if (cso->max_anisotropy >= 2) + so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15; + } + + if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + /* NOTE: must be deactivated for non-shadow textures */ + so->tsc[0] |= (1 << 9); + so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10; + } + + f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f); + so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12; + + f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f); + f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f); + so->tsc[2] |= + (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff); + + so->tsc[4] = fui(cso->border_color[0]); + so->tsc[5] = fui(cso->border_color[1]); + so->tsc[6] = fui(cso->border_color[2]); + so->tsc[7] = fui(cso->border_color[3]); + + return (void *)so; } static void nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { - FREE(hwcso); + unsigned s, i; + + for (s = 0; s < 5; ++s) + for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i) + if (nv50_context(pipe)->samplers[s][i] == hwcso) + nv50_context(pipe)->samplers[s][i] = NULL; + + nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso)); + + FREE(hwcso); } static INLINE void -nv50_set_sampler_views(struct pipe_context *pipe, unsigned p, - unsigned nr, - struct pipe_sampler_view **views) +nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s, + unsigned nr, void **hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); - unsigned i; + unsigned i; + + for (i = 0; i < nr; ++i) { + struct nv50_tsc_entry *old = nv50->samplers[s][i]; - for (i = 0; i < nr; i++) - pipe_sampler_view_reference(&nv50->sampler_views[p][i], - views[i]); + nv50->samplers[s][i] = nv50_tsc_entry(hwcso[i]); + if (old) + nv50_screen_tsc_unlock(nv50->screen, old); + } + for (; i < nv50->num_samplers[s]; ++i) + if (nv50->samplers[s][i]) + nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]); - for (i = nr; i < nv50->sampler_view_nr[p]; i++) - pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL); + nv50->num_samplers[s] = nr; - nv50->sampler_view_nr[p] = nr; - nv50->dirty |= NV50_NEW_TEXTURE; + nv50->dirty |= NV50_NEW_SAMPLERS; } static void -nv50_set_vp_sampler_views(struct pipe_context *pipe, - unsigned nr, - struct pipe_sampler_view **views) +nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) { - nv50_set_sampler_views(pipe, 0, nr, views); + nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s); } static void -nv50_set_fp_sampler_views(struct pipe_context *pipe, - unsigned nr, - struct pipe_sampler_view **views) +nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) { - nv50_set_sampler_views(pipe, 2, nr, views); + nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s); } static void -nv50_sampler_view_destroy(struct pipe_context *pipe, - struct pipe_sampler_view *view) +nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) { - pipe_resource_reference(&view->texture, NULL); - FREE(nv50_sampler_view(view)); + nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s); } -static struct pipe_sampler_view * -nv50_create_sampler_view(struct pipe_context *pipe, - struct pipe_resource *texture, - const struct pipe_sampler_view *templ) +/* NOTE: only called when not referenced anywhere, won't be bound */ +static void +nv50_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) { - struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view); + pipe_resource_reference(&view->texture, NULL); - view->pipe = *templ; - view->pipe.reference.count = 1; - view->pipe.texture = NULL; - pipe_resource_reference(&view->pipe.texture, texture); - view->pipe.context = pipe; + nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view)); - if (!nv50_tex_construct(view)) { - nv50_sampler_view_destroy(pipe, &view->pipe); - return NULL; - } - return &view->pipe; + FREE(nv50_tic_entry(view)); } +static INLINE void +nv50_stage_set_sampler_views(struct nv50_context *nv50, int s, + unsigned nr, + struct pipe_sampler_view **views) +{ + unsigned i; + + for (i = 0; i < nr; ++i) { + struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]); + if (old) + nv50_screen_tic_unlock(nv50->screen, old); -static void * -nv50_rasterizer_state_create(struct pipe_context *pipe, - const struct pipe_rasterizer_state *cso) -{ - struct nouveau_stateobj *so = so_new(16, 22, 0); - struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; - struct nv50_rasterizer_stateobj *rso = - CALLOC_STRUCT(nv50_rasterizer_stateobj); - - /*XXX: ignored - * - light_twoside - * - point_smooth - * - multisample - * - point_sprite / sprite_coord_mode - */ - - so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1); - so_data (so, cso->scissor); - - so_method(so, tesla, NV50TCL_SHADE_MODEL, 1); - so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT : - NV50TCL_SHADE_MODEL_SMOOTH); - so_method(so, tesla, NV50TCL_PROVOKING_VERTEX_LAST, 1); - so_data (so, cso->flatshade_first ? 0 : 1); - - so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1); - so_data (so, cso->light_twoside); - - so_method(so, tesla, NV50TCL_LINE_WIDTH, 1); - so_data (so, fui(cso->line_width)); - so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1); - so_data (so, cso->line_smooth ? 1 : 0); - if (cso->line_stipple_enable) { - so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1); - so_data (so, 1); - so_method(so, tesla, NV50TCL_LINE_STIPPLE_PATTERN, 1); - so_data (so, (cso->line_stipple_pattern << 8) | - cso->line_stipple_factor); - } else { - so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1); - so_data (so, 0); - } - - so_method(so, tesla, NV50TCL_POINT_SIZE, 1); - so_data (so, fui(cso->point_size)); - - so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1); - so_data (so, cso->point_quad_rasterization ? 1 : 0); - - so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3); - so_data(so, nvgl_polygon_mode(cso->fill_front)); - so_data(so, nvgl_polygon_mode(cso->fill_back)); - so_data(so, cso->poly_smooth ? 1 : 0); - - so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3); - so_data (so, cso->cull_face != PIPE_FACE_NONE); - if (cso->front_ccw) { - so_data(so, NV50TCL_FRONT_FACE_CCW); - } - else { - so_data(so, NV50TCL_FRONT_FACE_CW); - } - switch (cso->cull_face) { - case PIPE_FACE_FRONT: - so_data(so, NV50TCL_CULL_FACE_FRONT); - break; - case PIPE_FACE_BACK: - so_data(so, NV50TCL_CULL_FACE_BACK); - break; - case PIPE_FACE_FRONT_AND_BACK: - so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); - break; - default: - so_data(so, NV50TCL_CULL_FACE_BACK); - break; - } - - so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1); - so_data (so, cso->poly_stipple_enable ? 1 : 0); - - so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3); - so_data(so, cso->offset_point); - so_data(so, cso->offset_line); - so_data(so, cso->offset_tri); - - if (cso->offset_point || - cso->offset_line || - cso->offset_tri) { - so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1); - so_data (so, fui(cso->offset_scale)); - so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1); - so_data (so, fui(cso->offset_units * 2.0f)); - } - - rso->pipe = *cso; - so_ref(so, &rso->so); - so_ref(NULL, &so); - return (void *)rso; + pipe_sampler_view_reference(&nv50->textures[s][i], views[i]); + } + + for (i = nr; i < nv50->num_textures[s]; ++i) { + struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]); + if (!old) + continue; + nv50_screen_tic_unlock(nv50->screen, old); + + pipe_sampler_view_reference(&nv50->textures[s][i], NULL); + } + + nv50->num_textures[s] = nr; + + nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES); + + nv50->dirty |= NV50_NEW_TEXTURES; } static void -nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +nv50_vp_set_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) { - struct nv50_context *nv50 = nv50_context(pipe); - - nv50->rasterizer = hwcso; - nv50->dirty |= NV50_NEW_RASTERIZER; + nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views); } static void -nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +nv50_fp_set_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) { - struct nv50_rasterizer_stateobj *rso = hwcso; - - so_ref(NULL, &rso->so); - FREE(rso); + nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views); } -static void * -nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *cso) -{ - struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; - struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj); - struct nouveau_stateobj *so = so_new(9, 21, 0); - - so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1); - so_data (so, cso->depth.writemask ? 1 : 0); - if (cso->depth.enabled) { - so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); - so_data (so, 1); - so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1); - so_data (so, nvgl_comparison_op(cso->depth.func)); - } else { - so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); - so_data (so, 0); - } - - if (cso->stencil[0].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5); - so_data (so, 1); - so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); - so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); - so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); - so_data (so, nvgl_comparison_op(cso->stencil[0].func)); - so_method(so, tesla, NV50TCL_STENCIL_FRONT_MASK, 2); - so_data (so, cso->stencil[0].writemask); - so_data (so, cso->stencil[0].valuemask); - } else { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1); - so_data (so, 0); - } - - if (cso->stencil[1].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5); - so_data (so, 1); - so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op)); - so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); - so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); - so_data (so, nvgl_comparison_op(cso->stencil[1].func)); - so_method(so, tesla, NV50TCL_STENCIL_BACK_MASK, 2); - so_data (so, cso->stencil[1].writemask); - so_data (so, cso->stencil[1].valuemask); - } else { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1); - so_data (so, 0); - } - - if (cso->alpha.enabled) { - so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1); - so_data (so, 1); - so_method(so, tesla, NV50TCL_ALPHA_TEST_REF, 2); - so_data (so, fui(cso->alpha.ref_value)); - so_data (so, nvgl_comparison_op(cso->alpha.func)); - } else { - so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1); - so_data (so, 0); - } - - zsa->pipe = *cso; - so_ref(so, &zsa->so); - so_ref(NULL, &so); - return (void *)zsa; +static void +nv50_gp_set_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) +{ + nv50_stage_set_sampler_views(nv50_context(pipe), 1, nr, views); } -static void -nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +/* ============================= SHADERS ======================================= + */ + +static void * +nv50_sp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso, unsigned type) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_program *prog; - nv50->zsa = hwcso; - nv50->dirty |= NV50_NEW_ZSA; + prog = CALLOC_STRUCT(nv50_program); + if (!prog) + return NULL; + + prog->type = type; + prog->pipe.tokens = tgsi_dup_tokens(cso->tokens); + + return (void *)prog; } static void -nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv50_zsa_stateobj *zsa = hwcso; + struct nv50_program *prog = (struct nv50_program *)hwcso; + + nv50_program_destroy(nv50_context(pipe), prog); - so_ref(NULL, &zsa->so); - FREE(zsa); + FREE((void *)prog->pipe.tokens); + FREE(prog); } static void * nv50_vp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *cso) + const struct pipe_shader_state *cso) { - struct nv50_program *p = CALLOC_STRUCT(nv50_program); - - p->pipe.tokens = tgsi_dup_tokens(cso->tokens); - p->type = PIPE_SHADER_VERTEX; - return (void *)p; + return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX); } static void nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); - - nv50->vertprog = hwcso; - nv50->dirty |= NV50_NEW_VERTPROG; -} - -static void -nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso) -{ - struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_program *p = hwcso; + struct nv50_context *nv50 = nv50_context(pipe); - nv50_program_destroy(nv50, p); - FREE((void *)p->pipe.tokens); - FREE(p); + nv50->vertprog = hwcso; + nv50->dirty |= NV50_NEW_VERTPROG; } static void * nv50_fp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *cso) + const struct pipe_shader_state *cso) { - struct nv50_program *p = CALLOC_STRUCT(nv50_program); - - p->pipe.tokens = tgsi_dup_tokens(cso->tokens); - p->type = PIPE_SHADER_FRAGMENT; - return (void *)p; + return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT); } static void nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->fragprog = hwcso; - nv50->dirty |= NV50_NEW_FRAGPROG; -} - -static void -nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso) -{ - struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_program *p = hwcso; - - nv50_program_destroy(nv50, p); - FREE((void *)p->pipe.tokens); - FREE(p); + nv50->fragprog = hwcso; + nv50->dirty |= NV50_NEW_FRAGPROG; } static void * nv50_gp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *cso) + const struct pipe_shader_state *cso) { - struct nv50_program *p = CALLOC_STRUCT(nv50_program); - - p->pipe.tokens = tgsi_dup_tokens(cso->tokens); - p->type = PIPE_SHADER_GEOMETRY; - return (void *)p; + return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY); } static void nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->geomprog = hwcso; - nv50->dirty |= NV50_NEW_GEOMPROG; + nv50->gmtyprog = hwcso; + nv50->dirty |= NV50_NEW_GMTYPROG; } static void -nv50_gp_state_delete(struct pipe_context *pipe, void *hwcso) +nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + struct pipe_resource *res) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_program *p = hwcso; + struct nv50_context *nv50 = nv50_context(pipe); + + if (nv50->constbuf[shader][index]) + nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT, + nv04_resource(nv50->constbuf[shader][index])); + + pipe_resource_reference(&nv50->constbuf[shader][index], res); - nv50_program_destroy(nv50, p); - FREE((void *)p->pipe.tokens); - FREE(p); + nv50->constbuf_dirty[shader] |= 1 << index; + + nv50->dirty |= NV50_NEW_CONSTBUF; } +/* ============================================================================= + */ + static void nv50_set_blend_color(struct pipe_context *pipe, - const struct pipe_blend_color *bcol) + const struct pipe_blend_color *bcol) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->blend_colour = *bcol; - nv50->dirty |= NV50_NEW_BLEND_COLOUR; + nv50->blend_colour = *bcol; + nv50->dirty |= NV50_NEW_BLEND_COLOUR; } - static void +static void nv50_set_stencil_ref(struct pipe_context *pipe, - const struct pipe_stencil_ref *sr) + const struct pipe_stencil_ref *sr) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->stencil_ref = *sr; - nv50->dirty |= NV50_NEW_STENCIL_REF; + nv50->stencil_ref = *sr; + nv50->dirty |= NV50_NEW_STENCIL_REF; } static void nv50_set_clip_state(struct pipe_context *pipe, - const struct pipe_clip_state *clip) + const struct pipe_clip_state *clip) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); + const unsigned size = clip->nr * sizeof(clip->ucp[0]); - nv50->clip.depth_clamp = clip->depth_clamp; - nv50->dirty |= NV50_NEW_CLIP; -} + memcpy(&nv50->clip.ucp[0][0], &clip->ucp[0][0], size); + nv50->clip.nr = clip->nr; -static void -nv50_set_sample_mask(struct pipe_context *pipe, - unsigned sample_mask) -{ + nv50->clip.depth_clamp = clip->depth_clamp; + + nv50->dirty |= NV50_NEW_CLIP; } static void -nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_resource *buf ) +nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) { - struct nv50_context *nv50 = nv50_context(pipe); - - if (shader == PIPE_SHADER_VERTEX) { - nv50->dirty |= NV50_NEW_VERTPROG_CB; - } else - if (shader == PIPE_SHADER_FRAGMENT) { - nv50->dirty |= NV50_NEW_FRAGPROG_CB; - } else { - assert(shader == PIPE_SHADER_GEOMETRY); - nv50->dirty |= NV50_NEW_GEOMPROG_CB; - } + struct nv50_context *nv50 = nv50_context(pipe); - pipe_resource_reference(&nv50->constbuf[shader], buf); + nv50->sample_mask = sample_mask; + nv50->dirty |= NV50_NEW_SAMPLE_MASK; } + static void nv50_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) + const struct pipe_framebuffer_state *fb) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->framebuffer = *fb; - nv50->dirty |= NV50_NEW_FRAMEBUFFER; + nv50->framebuffer = *fb; + nv50->dirty |= NV50_NEW_FRAMEBUFFER; } static void nv50_set_polygon_stipple(struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple) + const struct pipe_poly_stipple *stipple) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->stipple = *stipple; - nv50->dirty |= NV50_NEW_STIPPLE; + nv50->stipple = *stipple; + nv50->dirty |= NV50_NEW_STIPPLE; } static void nv50_set_scissor_state(struct pipe_context *pipe, - const struct pipe_scissor_state *s) + const struct pipe_scissor_state *scissor) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->scissor = *s; - nv50->dirty |= NV50_NEW_SCISSOR; + nv50->scissor = *scissor; + nv50->dirty |= NV50_NEW_SCISSOR; } static void nv50_set_viewport_state(struct pipe_context *pipe, - const struct pipe_viewport_state *vpt) + const struct pipe_viewport_state *vpt) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->viewport = *vpt; - nv50->dirty |= NV50_NEW_VIEWPORT; + nv50->viewport = *vpt; + nv50->dirty |= NV50_NEW_VIEWPORT; } static void -nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_buffer *vb) +nv50_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *vb) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); + unsigned i; - util_copy_vertex_buffers(nv50->vtxbuf, - &nv50->vtxbuf_nr, - vb, count); + for (i = 0; i < count; ++i) + pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer); + for (; i < nv50->num_vtxbufs; ++i) + pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL); - nv50->dirty |= NV50_NEW_ARRAYS; -} + memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count); + nv50->num_vtxbufs = count; -static void -nv50_set_index_buffer(struct pipe_context *pipe, - const struct pipe_index_buffer *ib) -{ - struct nv50_context *nv50 = nv50_context(pipe); - - if (ib) - memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); - else - memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf)); - - /* TODO make this more like a state */ -} - -static void * -nv50_vtxelts_state_create(struct pipe_context *pipe, - unsigned num_elements, - const struct pipe_vertex_element *elements) -{ - struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj); - - assert(num_elements < 16); /* not doing fallbacks yet */ - cso->num_elements = num_elements; - memcpy(cso->pipe, elements, num_elements * sizeof(*elements)); + nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX); - nv50_vtxelt_construct(cso); - - return (void *)cso; + nv50->dirty |= NV50_NEW_ARRAYS; } static void -nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso) +nv50_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) { - FREE(hwcso); + struct nv50_context *nv50 = nv50_context(pipe); + + if (ib) + memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); + else + nv50->idxbuf.buffer = NULL; } static void -nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso) +nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->vtxelt = hwcso; - nv50->dirty |= NV50_NEW_ARRAYS; + nv50->vertex = hwcso; + nv50->dirty |= NV50_NEW_VERTEX; } void nv50_init_state_functions(struct nv50_context *nv50) { - nv50->pipe.create_blend_state = nv50_blend_state_create; - nv50->pipe.bind_blend_state = nv50_blend_state_bind; - nv50->pipe.delete_blend_state = nv50_blend_state_delete; - - nv50->pipe.create_sampler_state = nv50_sampler_state_create; - nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; - nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind; - nv50->pipe.bind_vertex_sampler_states = nv50_vp_sampler_state_bind; - nv50->pipe.set_fragment_sampler_views = nv50_set_fp_sampler_views; - nv50->pipe.set_vertex_sampler_views = nv50_set_vp_sampler_views; - nv50->pipe.create_sampler_view = nv50_create_sampler_view; - nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy; - - nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create; - nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind; - nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete; - - nv50->pipe.create_depth_stencil_alpha_state = - nv50_depth_stencil_alpha_state_create; - nv50->pipe.bind_depth_stencil_alpha_state = - nv50_depth_stencil_alpha_state_bind; - nv50->pipe.delete_depth_stencil_alpha_state = - nv50_depth_stencil_alpha_state_delete; - - nv50->pipe.create_vs_state = nv50_vp_state_create; - nv50->pipe.bind_vs_state = nv50_vp_state_bind; - nv50->pipe.delete_vs_state = nv50_vp_state_delete; - - nv50->pipe.create_fs_state = nv50_fp_state_create; - nv50->pipe.bind_fs_state = nv50_fp_state_bind; - nv50->pipe.delete_fs_state = nv50_fp_state_delete; - - nv50->pipe.create_gs_state = nv50_gp_state_create; - nv50->pipe.bind_gs_state = nv50_gp_state_bind; - nv50->pipe.delete_gs_state = nv50_gp_state_delete; - - nv50->pipe.set_blend_color = nv50_set_blend_color; - nv50->pipe.set_stencil_ref = nv50_set_stencil_ref; - nv50->pipe.set_clip_state = nv50_set_clip_state; - nv50->pipe.set_sample_mask = nv50_set_sample_mask; - nv50->pipe.set_constant_buffer = nv50_set_constant_buffer; - nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state; - nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple; - nv50->pipe.set_scissor_state = nv50_set_scissor_state; - nv50->pipe.set_viewport_state = nv50_set_viewport_state; - - nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create; - nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete; - nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind; - - nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; - nv50->pipe.set_index_buffer = nv50_set_index_buffer; - nv50->pipe.redefine_user_buffer = u_default_redefine_user_buffer; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->create_blend_state = nv50_blend_state_create; + pipe->bind_blend_state = nv50_blend_state_bind; + pipe->delete_blend_state = nv50_blend_state_delete; + + pipe->create_rasterizer_state = nv50_rasterizer_state_create; + pipe->bind_rasterizer_state = nv50_rasterizer_state_bind; + pipe->delete_rasterizer_state = nv50_rasterizer_state_delete; + + pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create; + pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind; + pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete; + + pipe->create_sampler_state = nv50_sampler_state_create; + pipe->delete_sampler_state = nv50_sampler_state_delete; + pipe->bind_vertex_sampler_states = nv50_vp_sampler_states_bind; + pipe->bind_fragment_sampler_states = nv50_fp_sampler_states_bind; + pipe->bind_geometry_sampler_states = nv50_gp_sampler_states_bind; + + pipe->create_sampler_view = nv50_create_sampler_view; + pipe->sampler_view_destroy = nv50_sampler_view_destroy; + pipe->set_vertex_sampler_views = nv50_vp_set_sampler_views; + pipe->set_fragment_sampler_views = nv50_fp_set_sampler_views; + pipe->set_geometry_sampler_views = nv50_gp_set_sampler_views; + + pipe->create_vs_state = nv50_vp_state_create; + pipe->create_fs_state = nv50_fp_state_create; + pipe->create_gs_state = nv50_gp_state_create; + pipe->bind_vs_state = nv50_vp_state_bind; + pipe->bind_fs_state = nv50_fp_state_bind; + pipe->bind_gs_state = nv50_gp_state_bind; + pipe->delete_vs_state = nv50_sp_state_delete; + pipe->delete_fs_state = nv50_sp_state_delete; + pipe->delete_gs_state = nv50_sp_state_delete; + + pipe->set_blend_color = nv50_set_blend_color; + pipe->set_stencil_ref = nv50_set_stencil_ref; + pipe->set_clip_state = nv50_set_clip_state; + pipe->set_sample_mask = nv50_set_sample_mask; + pipe->set_constant_buffer = nv50_set_constant_buffer; + pipe->set_framebuffer_state = nv50_set_framebuffer_state; + pipe->set_polygon_stipple = nv50_set_polygon_stipple; + pipe->set_scissor_state = nv50_set_scissor_state; + pipe->set_viewport_state = nv50_set_viewport_state; + + pipe->create_vertex_elements_state = nv50_vertex_state_create; + pipe->delete_vertex_elements_state = nv50_vertex_state_delete; + pipe->bind_vertex_elements_state = nv50_vertex_state_bind; + + pipe->set_vertex_buffers = nv50_set_vertex_buffers; + pipe->set_index_buffer = nv50_set_index_buffer; } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index ae02143e352..bf46296e7ef 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -1,449 +1,314 @@ -/* - * Copyright 2008 Ben Skeggs - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "util/u_format.h" #include "nv50_context.h" -#include "nv50_resource.h" -#include "nouveau/nouveau_stateobj.h" +#include "os/os_time.h" -static struct nouveau_stateobj * -validate_fb(struct nv50_context *nv50) +static void +nv50_validate_fb(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(32, 79, 18); - struct pipe_framebuffer_state *fb = &nv50->framebuffer; - unsigned i, w = 0, h = 0, gw = 0; - - /* Set nr of active RTs and select RT for each colour output. - * FP result 0 always goes to RT[0], bits 4 - 6 are ignored. - * Ambiguous assignment results in no rendering (no DATA_ERROR). - */ - so_method(so, tesla, NV50TCL_RT_CONTROL, 1); - so_data (so, fb->nr_cbufs | - (0 << 4) | (1 << 7) | (2 << 10) | (3 << 13) | - (4 << 16) | (5 << 19) | (6 << 22) | (7 << 25)); - - for (i = 0; i < fb->nr_cbufs; i++) { - struct pipe_resource *pt = fb->cbufs[i]->texture; - struct nouveau_bo *bo = nv50_miptree(pt)->base.bo; - - if (!gw) { - w = fb->cbufs[i]->width; - h = fb->cbufs[i]->height; - gw = 1; - } else { - assert(w == fb->cbufs[i]->width); - assert(h == fb->cbufs[i]->height); - } - - assert(nv50_format_table[fb->cbufs[i]->format].rt); - - so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2); - so_data (so, fb->cbufs[i]->width); - so_data (so, fb->cbufs[i]->height); - - so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); - so_reloc (so, bo, ((struct nv50_surface *)fb->cbufs[i])->offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0); - so_reloc (so, bo, ((struct nv50_surface *)fb->cbufs[i])->offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0); - so_data (so, nv50_format_table[fb->cbufs[i]->format].rt); - so_data (so, nv50_miptree(pt)-> - level[fb->cbufs[i]->u.tex.level].tile_mode << 4); - so_data(so, 0x00000000); - - so_method(so, tesla, NV50TCL_RT_ARRAY_MODE, 1); - so_data (so, 1); - } - - if (fb->zsbuf) { - struct pipe_resource *pt = fb->zsbuf->texture; - struct nouveau_bo *bo = nv50_miptree(pt)->base.bo; - - if (!gw) { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - gw = 1; - } else { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } - - assert(nv50_format_table[fb->zsbuf->format].rt); - - so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5); - so_reloc (so, bo, ((struct nv50_surface *)(fb->zsbuf))->offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0); - so_reloc (so, bo, ((struct nv50_surface *)(fb->zsbuf))->offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0); - so_data (so, nv50_format_table[fb->zsbuf->format].rt); - so_data (so, nv50_miptree(pt)-> - level[fb->zsbuf->u.tex.level].tile_mode << 4); - so_data (so, 0x00000000); - - so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1); - so_data (so, 1); - so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3); - so_data (so, fb->zsbuf->width); - so_data (so, fb->zsbuf->height); - so_data (so, 0x00010001); - } else { - so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1); - so_data (so, 0); - } - - so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2); - so_data (so, w << 16); - so_data (so, h << 16); - /* set window lower left corner */ - so_method(so, tesla, NV50TCL_WINDOW_OFFSET_X, 2); - so_data (so, 0); - so_data (so, 0); - /* set screen scissor rectangle */ - so_method(so, tesla, NV50TCL_SCREEN_SCISSOR_HORIZ, 2); - so_data (so, w << 16); - so_data (so, h << 16); - - return so; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct pipe_framebuffer_state *fb = &nv50->framebuffer; + unsigned i; + boolean serialize = FALSE; + + nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME); + + BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); + OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs); + BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2); + OUT_RING (chan, fb->width << 16); + OUT_RING (chan, fb->height << 16); + + MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs); + + for (i = 0; i < fb->nr_cbufs; ++i) { + struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture); + struct nv50_surface *sf = nv50_surface(fb->cbufs[i]); + struct nouveau_bo *bo = mt->base.bo; + uint32_t offset = sf->offset; + + BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5); + OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RING (chan, nv50_format_table[sf->base.format].rt); + OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); + OUT_RING (chan, mt->layer_stride >> 2); + BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2); + OUT_RING (chan, sf->width); + OUT_RING (chan, sf->height); + BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); + OUT_RING (chan, sf->depth); + + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) + serialize = TRUE; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + } + + if (fb->zsbuf) { + struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture); + struct nv50_surface *sf = nv50_surface(fb->zsbuf); + struct nouveau_bo *bo = mt->base.bo; + int unk = mt->base.base.target == PIPE_TEXTURE_2D; + uint32_t offset = sf->offset; + + MARK_RING (chan, 12, 2); + BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5); + OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RING (chan, nv50_format_table[fb->zsbuf->format].rt); + OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); + OUT_RING (chan, mt->layer_stride >> 2); + BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); + OUT_RING (chan, sf->width); + OUT_RING (chan, sf->height); + OUT_RING (chan, (unk << 16) | sf->depth); + + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) + serialize = TRUE; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + } else { + BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); + OUT_RING (chan, fb->width << 16); + OUT_RING (chan, fb->height << 16); + + if (serialize) { + BEGIN_RING(chan, RING_3D(SERIALIZE), 1); + OUT_RING (chan, 0); + } } static void -nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so, - unsigned p) +nv50_validate_blend_colour(struct nv50_context *nv50) { - struct nouveau_grobj *eng2d = nv50->screen->eng2d; - unsigned i, j, dw = nv50->sampler_nr[p] * 8; - - if (!dw) - return; - nv50_so_init_sifc(nv50, so, nv50->screen->tsc, NOUVEAU_BO_VRAM, - p * (32 * 8 * 4), dw * 4); - - so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), dw); - - for (i = 0; i < nv50->sampler_nr[p]; ++i) { - if (nv50->sampler[p][i]) - so_datap(so, nv50->sampler[p][i]->tsc, 8); - else { - for (j = 0; j < 8; ++j) /* you get punished */ - so_data(so, 0); /* ... for leaving holes */ - } - } -} + struct nouveau_channel *chan = nv50->screen->base.channel; -static struct nouveau_stateobj * -validate_blend(struct nv50_context *nv50) -{ - struct nouveau_stateobj *so = NULL; - so_ref(nv50->blend->so, &so); - return so; + BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4); + OUT_RINGf (chan, nv50->blend_colour.color[0]); + OUT_RINGf (chan, nv50->blend_colour.color[1]); + OUT_RINGf (chan, nv50->blend_colour.color[2]); + OUT_RINGf (chan, nv50->blend_colour.color[3]); } -static struct nouveau_stateobj * -validate_zsa(struct nv50_context *nv50) +static void +nv50_validate_stencil_ref(struct nv50_context *nv50) { - struct nouveau_stateobj *so = NULL; - so_ref(nv50->zsa->so, &so); - return so; -} + struct nouveau_channel *chan = nv50->screen->base.channel; -static struct nouveau_stateobj * -validate_rast(struct nv50_context *nv50) -{ - struct nouveau_stateobj *so = NULL; - so_ref(nv50->rasterizer->so, &so); - return so; + BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1); + OUT_RING (chan, nv50->stencil_ref.ref_value[0]); + BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1); + OUT_RING (chan, nv50->stencil_ref.ref_value[1]); } -static struct nouveau_stateobj * -validate_blend_colour(struct nv50_context *nv50) +static void +nv50_validate_stipple(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(1, 4, 0); - - so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4); - so_data (so, fui(nv50->blend_colour.color[0])); - so_data (so, fui(nv50->blend_colour.color[1])); - so_data (so, fui(nv50->blend_colour.color[2])); - so_data (so, fui(nv50->blend_colour.color[3])); - return so; -} + struct nouveau_channel *chan = nv50->screen->base.channel; + unsigned i; -static struct nouveau_stateobj * -validate_stencil_ref(struct nv50_context *nv50) -{ - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(2, 2, 0); - - so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1); - so_data (so, nv50->stencil_ref.ref_value[0]); - so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1); - so_data (so, nv50->stencil_ref.ref_value[1]); - return so; + BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32); + for (i = 0; i < 32; ++i) + OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i])); } -static struct nouveau_stateobj * -validate_stipple(struct nv50_context *nv50) +static void +nv50_validate_scissor(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(1, 32, 0); - int i; - - so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32); - for (i = 0; i < 32; i++) - so_data(so, util_bswap32(nv50->stipple.stipple[i])); - return so; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct pipe_scissor_state *s = &nv50->scissor; +#ifdef NV50_SCISSORS_CLIPPING + struct pipe_viewport_state *vp = &nv50->viewport; + int minx, maxx, miny, maxy; + + if (!(nv50->dirty & + (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) && + nv50->state.scissor == nv50->rast->pipe.scissor) + return; + nv50->state.scissor = nv50->rast->pipe.scissor; + + if (nv50->state.scissor) { + minx = s->minx; + maxx = s->maxx; + miny = s->miny; + maxy = s->maxy; + } else { + minx = 0; + maxx = nv50->framebuffer.width; + miny = 0; + maxy = nv50->framebuffer.height; + } + + minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0]))); + maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0]))); + miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1]))); + maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1]))); + + BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); + OUT_RING (chan, (maxx << 16) | minx); + OUT_RING (chan, (maxy << 16) | miny); +#else + BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); + OUT_RING (chan, (s->maxx << 16) | s->minx); + OUT_RING (chan, (s->maxy << 16) | s->miny); +#endif } -static struct nouveau_stateobj * -validate_scissor(struct nv50_context *nv50) +static void +nv50_validate_viewport(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct pipe_scissor_state *s = &nv50->scissor; - struct nouveau_stateobj *so; - - so = so_new(1, 2, 0); - so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2); - so_data (so, (s->maxx << 16) | s->minx); - so_data (so, (s->maxy << 16) | s->miny); - return so; + struct nouveau_channel *chan = nv50->screen->base.channel; + float zmin, zmax; + + BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3); + OUT_RINGf (chan, nv50->viewport.translate[0]); + OUT_RINGf (chan, nv50->viewport.translate[1]); + OUT_RINGf (chan, nv50->viewport.translate[2]); + BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3); + OUT_RINGf (chan, nv50->viewport.scale[0]); + OUT_RINGf (chan, nv50->viewport.scale[1]); + OUT_RINGf (chan, nv50->viewport.scale[2]); + + zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]); + zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]); + +#ifdef NV50_SCISSORS_CLIPPING + BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); + OUT_RINGf (chan, zmin); + OUT_RINGf (chan, zmax); +#endif } -static struct nouveau_stateobj * -validate_viewport(struct nv50_context *nv50) +static void +nv50_validate_clip(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(3, 7, 0); - - so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3); - so_data (so, fui(nv50->viewport.translate[0])); - so_data (so, fui(nv50->viewport.translate[1])); - so_data (so, fui(nv50->viewport.translate[2])); - so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3); - so_data (so, fui(nv50->viewport.scale[0])); - so_data (so, fui(nv50->viewport.scale[1])); - so_data (so, fui(nv50->viewport.scale[2])); - - /* no idea what 0f90 does */ - so_method(so, tesla, 0x0f90, 1); - so_data (so, 0); - - return so; + struct nouveau_channel *chan = nv50->screen->base.channel; + uint32_t clip; + + if (nv50->clip.depth_clamp) { + clip = + NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | + NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | + NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; + } else { + clip = 0; + } + +#ifndef NV50_SCISSORS_CLIPPING + clip |= + NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 | + NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; +#endif + + BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1); + OUT_RING (chan, clip); + + if (nv50->clip.nr) { + BEGIN_RING(chan, RING_3D(CB_ADDR), 1); + OUT_RING (chan, (0 << 8) | NV50_CB_AUX); + BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nv50->clip.nr * 4); + OUT_RINGp (chan, &nv50->clip.ucp[0][0], nv50->clip.nr * 4); + } + + BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1); + OUT_RING (chan, (1 << nv50->clip.nr) - 1); } -static struct nouveau_stateobj * -validate_sampler(struct nv50_context *nv50) +static void +nv50_validate_blend(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so; - unsigned nr = 0, i; + struct nouveau_channel *chan = nv50->screen->base.channel; - for (i = 0; i < 3; ++i) - nr += nv50->sampler_nr[i]; - - so = so_new(1 + 5 * 3, 1 + 19 * 3 + nr * 8, 3 * 2); - - nv50_validate_samplers(nv50, so, 0); /* VP */ - nv50_validate_samplers(nv50, so, 2); /* FP */ - - so_method(so, tesla, 0x1334, 1); /* flush TSC */ - so_data (so, 0); - - return so; + WAIT_RING(chan, nv50->blend->size); + OUT_RINGp(chan, nv50->blend->state, nv50->blend->size); } -static struct nouveau_stateobj * -validate_vtxbuf(struct nv50_context *nv50) +static void +nv50_validate_zsa(struct nv50_context *nv50) { - struct nouveau_stateobj *so = NULL; - so_ref(nv50->state.vtxbuf, &so); - return so; -} + struct nouveau_channel *chan = nv50->screen->base.channel; -static struct nouveau_stateobj * -validate_vtxattr(struct nv50_context *nv50) -{ - struct nouveau_stateobj *so = NULL; - so_ref(nv50->state.vtxattr, &so); - return so; + WAIT_RING(chan, nv50->zsa->size); + OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size); } -static struct nouveau_stateobj * -validate_clip(struct nv50_context *nv50) +static void +nv50_validate_rasterizer(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(1, 1, 0); - uint32_t vvcc; - - /* 0x0000 = remove whole primitive only (xyz) - * 0x1018 = remove whole primitive only (xy), clamp z - * 0x1080 = clip primitive (xyz) - * 0x1098 = clip primitive (xy), clamp z - */ - vvcc = nv50->clip.depth_clamp ? 0x1098 : 0x1080; - - so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1); - so_data (so, vvcc); + struct nouveau_channel *chan = nv50->screen->base.channel; - return so; + WAIT_RING(chan, nv50->rast->size); + OUT_RINGp(chan, nv50->rast->state, nv50->rast->size); } -struct state_validate { - struct nouveau_stateobj *(*func)(struct nv50_context *nv50); - unsigned states; +static struct state_validate { + void (*func)(struct nv50_context *); + uint32_t states; } validate_list[] = { - { validate_fb , NV50_NEW_FRAMEBUFFER }, - { validate_blend , NV50_NEW_BLEND }, - { validate_zsa , NV50_NEW_ZSA }, - { nv50_vertprog_validate , NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB }, - { nv50_fragprog_validate , NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB }, - { nv50_geomprog_validate , NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB }, - { nv50_fp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG | - NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER }, - { nv50_gp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG }, - { validate_rast , NV50_NEW_RASTERIZER }, - { validate_blend_colour , NV50_NEW_BLEND_COLOUR }, - { validate_stencil_ref , NV50_NEW_STENCIL_REF }, - { validate_stipple , NV50_NEW_STIPPLE }, - { validate_scissor , NV50_NEW_SCISSOR }, - { validate_viewport , NV50_NEW_VIEWPORT }, - { validate_sampler , NV50_NEW_SAMPLER }, - { nv50_tex_validate , NV50_NEW_TEXTURE | NV50_NEW_SAMPLER }, - { nv50_vbo_validate , NV50_NEW_ARRAYS }, - { validate_vtxbuf , NV50_NEW_ARRAYS }, - { validate_vtxattr , NV50_NEW_ARRAYS }, - { validate_clip , NV50_NEW_CLIP }, - { NULL , 0 } + { nv50_validate_fb, NV50_NEW_FRAMEBUFFER }, + { nv50_validate_blend, NV50_NEW_BLEND }, + { nv50_validate_zsa, NV50_NEW_ZSA }, + { nv50_validate_rasterizer, NV50_NEW_RASTERIZER }, + { nv50_validate_blend_colour, NV50_NEW_BLEND_COLOUR }, + { nv50_validate_stencil_ref, NV50_NEW_STENCIL_REF }, + { nv50_validate_stipple, NV50_NEW_STIPPLE }, +#ifdef NV50_SCISSORS_CLIPPING + { nv50_validate_scissor, NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | + NV50_NEW_RASTERIZER | + NV50_NEW_FRAMEBUFFER }, +#else + { nv50_validate_scissor, NV50_NEW_SCISSOR }, +#endif + { nv50_validate_viewport, NV50_NEW_VIEWPORT }, + { nv50_validate_clip, NV50_NEW_CLIP }, + { nv50_vertprog_validate, NV50_NEW_VERTPROG }, + { nv50_gmtyprog_validate, NV50_NEW_GMTYPROG }, + { nv50_fragprog_validate, NV50_NEW_FRAGPROG }, + { nv50_fp_linkage_validate, NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | + NV50_NEW_GMTYPROG }, + { nv50_gp_linkage_validate, NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG }, + { nv50_sprite_coords_validate, NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER | + NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG }, + { nv50_constbufs_validate, NV50_NEW_CONSTBUF }, + { nv50_validate_textures, NV50_NEW_TEXTURES }, + { nv50_validate_samplers, NV50_NEW_SAMPLERS }, + { nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS } }; #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0])) boolean -nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords) -{ - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned nr_relocs = 128, nr_dwords = wait_dwords + 128 + 4; - int ret, i; - - for (i = 0; i < validate_list_len; i++) { - struct state_validate *validate = &validate_list[i]; - struct nouveau_stateobj *so; - - if (!(nv50->dirty & validate->states)) - continue; - - so = validate->func(nv50); - if (!so) - continue; - - nr_dwords += (so->total + so->cur); - nr_relocs += so->cur_reloc; - - so_ref(so, &nv50->state.hw[i]); - so_ref(NULL, &so); - nv50->state.hw_dirty |= (1 << i); - } - nv50->dirty = 0; - - if (nv50->screen->cur_ctx != nv50) { - for (i = 0; i < validate_list_len; i++) { - if (!nv50->state.hw[i] || - (nv50->state.hw_dirty & (1 << i))) - continue; - - nr_dwords += (nv50->state.hw[i]->total + - nv50->state.hw[i]->cur); - nr_relocs += nv50->state.hw[i]->cur_reloc; - nv50->state.hw_dirty |= (1 << i); - } - - nv50->screen->cur_ctx = nv50; - } - - ret = MARK_RING(chan, nr_dwords, nr_relocs); - if (ret) { - debug_printf("MARK_RING(%d, %d) failed: %d\n", - nr_dwords, nr_relocs, ret); - return FALSE; - } - - while (nv50->state.hw_dirty) { - i = ffs(nv50->state.hw_dirty) - 1; - nv50->state.hw_dirty &= ~(1 << i); - - so_emit(chan, nv50->state.hw[i]); - } - - /* Yes, really, we need to do this. If a buffer that is referenced - * on the hardware isn't part of changed state above, without doing - * this the kernel is given no clue that the buffer is being used - * still. This can cause all sorts of fun issues. - */ - nv50_tex_relocs(nv50); - so_emit_reloc_markers(chan, nv50->state.hw[0]); /* fb */ - so_emit_reloc_markers(chan, nv50->state.hw[3]); /* vp */ - so_emit_reloc_markers(chan, nv50->state.hw[4]); /* fp */ - so_emit_reloc_markers(chan, nv50->state.hw[17]); /* vb */ - nv50_screen_relocs(nv50->screen); - - /* No idea.. */ - BEGIN_RING(chan, tesla, 0x142c, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, tesla, 0x142c, 1); - OUT_RING (chan, 0); - return TRUE; -} - -void nv50_so_init_sifc(struct nv50_context *nv50, - struct nouveau_stateobj *so, - struct nouveau_bo *bo, unsigned reloc, - unsigned offset, unsigned size) +nv50_state_validate(struct nv50_context *nv50) { - struct nouveau_grobj *eng2d = nv50->screen->eng2d; - - reloc |= NOUVEAU_BO_WR; - - so_method(so, eng2d, NV50_2D_DST_FORMAT, 2); - so_data (so, NV50_2D_DST_FORMAT_R8_UNORM); - so_data (so, 1); - so_method(so, eng2d, NV50_2D_DST_PITCH, 5); - so_data (so, 262144); - so_data (so, 65536); - so_data (so, 1); - so_reloc (so, bo, offset, reloc | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, bo, offset, reloc | NOUVEAU_BO_LOW, 0, 0); - so_method(so, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2); - so_data (so, 0); - so_data (so, NV50_2D_SIFC_FORMAT_R8_UNORM); - so_method(so, eng2d, NV50_2D_SIFC_WIDTH, 10); - so_data (so, size); - so_data (so, 1); - so_data (so, 0); - so_data (so, 1); - so_data (so, 0); - so_data (so, 1); - so_data (so, 0); - so_data (so, 0); - so_data (so, 0); - so_data (so, 0); + unsigned i; +#if 0 + if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */ + nv50->dirty = 0xffffffff; +#endif + nv50->screen->cur_ctx = nv50; + + if (nv50->dirty) { + for (i = 0; i < validate_list_len; ++i) { + struct state_validate *validate = &validate_list[i]; + + if (nv50->dirty & validate->states) + validate->func(nv50); + } + nv50->dirty = 0; + } + + nv50_bufctx_emit_relocs(nv50); + + return TRUE; } diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h new file mode 100644 index 00000000000..f4e458b0c05 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_stateobj.h @@ -0,0 +1,76 @@ + +#ifndef __NV50_STATEOBJ_H__ +#define __NV50_STATEOBJ_H__ + +#include "pipe/p_state.h" + +#define NV50_SCISSORS_CLIPPING + +#define SB_BEGIN_3D(so, m, s) \ + (so)->state[(so)->size++] = \ + ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m + +#define SB_BEGIN_3D_(so, m, s) \ + (so)->state[(so)->size++] = \ + ((s) << 18) | (NV50_SUBCH_3D << 13) | m + +#define SB_DATA(so, u) (so)->state[(so)->size++] = (u) + +struct nv50_blend_stateobj { + struct pipe_blend_state pipe; + int size; + uint32_t state[78]; +}; + +struct nv50_tsc_entry { + int id; + uint32_t tsc[8]; +}; + +static INLINE struct nv50_tsc_entry * +nv50_tsc_entry(void *hwcso) +{ + return (struct nv50_tsc_entry *)hwcso; +} + +struct nv50_tic_entry { + struct pipe_sampler_view pipe; + int id; + uint32_t tic[8]; +}; + +static INLINE struct nv50_tic_entry * +nv50_tic_entry(struct pipe_sampler_view *view) +{ + return (struct nv50_tic_entry *)view; +} + +struct nv50_rasterizer_stateobj { + struct pipe_rasterizer_state pipe; + int size; + uint32_t state[40]; +}; + +struct nv50_zsa_stateobj { + struct pipe_depth_stencil_alpha_state pipe; + int size; + uint32_t state[29]; +}; + +struct nv50_vertex_element { + struct pipe_vertex_element pipe; + uint32_t state; +}; + +struct nv50_vertex_stateobj { + struct translate *translate; + unsigned num_elements; + uint32_t instance_elts; + uint32_t instance_bufs; + boolean need_conversion; + unsigned vertex_size; + unsigned packet_vertex_limit; + struct nv50_vertex_element element[1]; +}; + +#endif diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index a99df76cee3..dc9e2880f0f 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -20,306 +20,362 @@ * SOFTWARE. */ -#define __NOUVEAU_PUSH_H__ #include <stdint.h> -#include "nouveau/nv04_pushbuf.h" -#include "nv50_context.h" -#include "nv50_resource.h" + #include "pipe/p_defines.h" + #include "util/u_inlines.h" #include "util/u_pack_color.h" - #include "util/u_format.h" +#include "nv50_context.h" +#include "nv50_resource.h" + +#include "nv50_defs.xml.h" + /* return TRUE for formats that can be converted among each other by NV50_2D */ static INLINE boolean nv50_2d_format_faithful(enum pipe_format format) { - switch (format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_B8G8R8X8_SRGB: - case PIPE_FORMAT_B5G6R5_UNORM: - case PIPE_FORMAT_B5G5R5A1_UNORM: - case PIPE_FORMAT_B10G10R10A2_UNORM: - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R32G32B32A32_FLOAT: - case PIPE_FORMAT_R32G32B32_FLOAT: - return TRUE; - default: - return FALSE; - } + switch (format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_SRGB: + case PIPE_FORMAT_B5G6R5_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + return TRUE; + default: + return FALSE; + } } static INLINE uint8_t nv50_2d_format(enum pipe_format format) { - uint8_t id = nv50_format_table[format].rt; - - /* Hardware values for color formats range from 0xc0 to 0xff, - * but the 2D engine doesn't support all of them. - */ - if ((id >= 0xc0) && (0xff0843e080608409ULL & (1ULL << (id - 0xc0)))) - return id; - - switch (util_format_get_blocksize(format)) { - case 1: - return NV50_2D_DST_FORMAT_R8_UNORM; - case 2: - return NV50_2D_DST_FORMAT_R16_UNORM; - case 4: - return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM; - default: - return 0; - } + uint8_t id = nv50_format_table[format].rt; + + /* Hardware values for color formats range from 0xc0 to 0xff, + * but the 2D engine doesn't support all of them. + */ + if ((id >= 0xc0) && (0xff0843e080608409ULL & (1ULL << (id - 0xc0)))) + return id; + + switch (util_format_get_blocksize(format)) { + case 1: + return NV50_SURFACE_FORMAT_R8_UNORM; + case 2: + return NV50_SURFACE_FORMAT_R16_UNORM; + case 4: + return NV50_SURFACE_FORMAT_A8R8G8B8_UNORM; + default: + return 0; + } } static int -nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) +nv50_2d_texture_set(struct nouveau_channel *chan, int dst, + struct nv50_miptree *mt, unsigned level, unsigned layer) { - struct nv50_miptree *mt = nv50_miptree(ps->texture); - struct nouveau_channel *chan = screen->eng2d->channel; - struct nouveau_grobj *eng2d = screen->eng2d; - struct nouveau_bo *bo = nv50_miptree(ps->texture)->base.bo; - int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; - int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); - - format = nv50_2d_format(ps->format); - if (!format) { - NOUVEAU_ERR("invalid/unsupported surface format: %s\n", - util_format_name(ps->format)); - return 1; - } - - if (!nouveau_bo_tile_layout(bo)) { - BEGIN_RING(chan, eng2d, mthd, 2); - OUT_RING (chan, format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, mthd + 0x14, 5); - OUT_RING (chan, mt->level[ps->u.tex.level].pitch); - OUT_RING (chan, ps->width); - OUT_RING (chan, ps->height); - OUT_RELOCh(chan, bo, ((struct nv50_surface *)ps)->offset, flags); - OUT_RELOCl(chan, bo, ((struct nv50_surface *)ps)->offset, flags); - } else { - BEGIN_RING(chan, eng2d, mthd, 5); - OUT_RING (chan, format); - OUT_RING (chan, 0); - OUT_RING (chan, mt->level[ps->u.tex.level].tile_mode << 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, mthd + 0x18, 4); - OUT_RING (chan, ps->width); - OUT_RING (chan, ps->height); - OUT_RELOCh(chan, bo, ((struct nv50_surface *)ps)->offset, flags); - OUT_RELOCl(chan, bo, ((struct nv50_surface *)ps)->offset, flags); - } - + struct nouveau_bo *bo = mt->base.bo; + uint32_t width, height, depth; + uint32_t format; + uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + uint32_t offset = mt->level[level].offset; + + format = nv50_2d_format(mt->base.base.format); + if (!format) { + NOUVEAU_ERR("invalid/unsupported surface format: %s\n", + util_format_name(mt->base.base.format)); + return 1; + } + + width = u_minify(mt->base.base.width0, level); + height = u_minify(mt->base.base.height0, level); + + offset = mt->level[level].offset; + if (!mt->layout_3d) { + offset += mt->layer_stride * layer; + depth = 1; + layer = 0; + } else { + depth = u_minify(mt->base.base.depth0, level); + } + + if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) { + BEGIN_RING(chan, RING_2D_(mthd), 2); + OUT_RING (chan, format); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5); + OUT_RING (chan, mt->level[level].pitch); + OUT_RING (chan, width); + OUT_RING (chan, height); + OUT_RELOCh(chan, bo, offset, flags); + OUT_RELOCl(chan, bo, offset, flags); + } else { + BEGIN_RING(chan, RING_2D_(mthd), 5); + OUT_RING (chan, format); + OUT_RING (chan, 0); + OUT_RING (chan, mt->level[level].tile_mode << 4); + OUT_RING (chan, depth); + OUT_RING (chan, layer); + BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4); + OUT_RING (chan, width); + OUT_RING (chan, height); + OUT_RELOCh(chan, bo, offset, flags); + OUT_RELOCl(chan, bo, offset, flags); + } + #if 0 - if (dst) { - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - } + if (dst) { + BEGIN_RING(chan, RING_2D_(NV50_2D_CLIP_X), 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, width); + OUT_RING (chan, height); + } #endif - - return 0; + return 0; } -int -nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, - int dx, int dy, struct pipe_surface *src, int sx, int sy, - int w, int h) +static int +nv50_2d_texture_do_copy(struct nouveau_channel *chan, + struct nv50_miptree *dst, unsigned dst_level, + unsigned dx, unsigned dy, unsigned dz, + struct nv50_miptree *src, unsigned src_level, + unsigned sx, unsigned sy, unsigned sz, + unsigned w, unsigned h) { - struct nouveau_channel *chan = screen->eng2d->channel; - struct nouveau_grobj *eng2d = screen->eng2d; - int ret; - - ret = MARK_RING(chan, 2*16 + 32, 4); - if (ret) - return ret; - - ret = nv50_surface_set(screen, dst, 1); - if (ret) - return ret; - - ret = nv50_surface_set(screen, src, 0); - if (ret) - return ret; - - BEGIN_RING(chan, eng2d, 0x088c, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, w); - OUT_RING (chan, h); - BEGIN_RING(chan, eng2d, 0x08c0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, 0x08d0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx); - OUT_RING (chan, 0); - OUT_RING (chan, sy); - - return 0; + int ret; + + ret = MARK_RING(chan, 2 * 16 + 32, 4); + if (ret) + return ret; + + ret = nv50_2d_texture_set(chan, 1, dst, dst_level, dz); + if (ret) + return ret; + + ret = nv50_2d_texture_set(chan, 0, src, src_level, sz); + if (ret) + return ret; + + /* 0/1 = CENTER/CORNER, 10/00 = POINT/BILINEAR */ + BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, w); + OUT_RING (chan, h); + BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4); + OUT_RING (chan, 0); + OUT_RING (chan, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); + + return 0; } static void -nv50_surface_copy(struct pipe_context *pipe, - struct pipe_resource *dest, unsigned dst_level, - unsigned destx, unsigned desty, unsigned destz, - struct pipe_resource *src, unsigned src_level, - const struct pipe_box *src_box) +nv50_resource_copy_region(struct pipe_context *pipe, + struct pipe_resource *dst, unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_screen *screen = nv50->screen; - struct pipe_surface *ps_dst, *ps_src, surf_tmpl; - - - assert((src->format == dest->format) || - (nv50_2d_format_faithful(src->format) && - nv50_2d_format_faithful(dest->format))); - assert(src_box->depth == 1); - - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - surf_tmpl.format = src->format; - surf_tmpl.usage = 0; /* no bind flag - not a surface */ - surf_tmpl.u.tex.level = src_level; - surf_tmpl.u.tex.first_layer = src_box->z; - surf_tmpl.u.tex.last_layer = src_box->z; - /* XXX really need surfaces here? */ - ps_src = nv50_miptree_surface_new(pipe, src, &surf_tmpl); - surf_tmpl.format = dest->format; - surf_tmpl.usage = 0; /* no bind flag - not a surface */ - surf_tmpl.u.tex.level = dst_level; - surf_tmpl.u.tex.first_layer = destz; - surf_tmpl.u.tex.last_layer = destz; - ps_dst = nv50_miptree_surface_new(pipe, dest, &surf_tmpl); - - nv50_surface_do_copy(screen, ps_dst, destx, desty, ps_src, src_box->x, - src_box->y, src_box->width, src_box->height); - - nv50_miptree_surface_del(pipe, ps_src); - nv50_miptree_surface_del(pipe, ps_dst); + struct nv50_screen *screen = nv50_context(pipe)->screen; + int ret; + unsigned dst_layer = dstz, src_layer = src_box->z; + + assert((src->format == dst->format) || + (nv50_2d_format_faithful(src->format) && + nv50_2d_format_faithful(dst->format))); + + for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) { + ret = nv50_2d_texture_do_copy(screen->base.channel, + nv50_miptree(dst), dst_level, + dstx, dsty, dst_layer, + nv50_miptree(src), src_level, + src_box->x, src_box->y, src_layer, + src_box->width, src_box->height); + if (ret) + return; + } } static void nv50_clear_render_target(struct pipe_context *pipe, - struct pipe_surface *dst, - const float *rgba, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height) + struct pipe_surface *dst, + const float *rgba, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *tesla = screen->tesla; - struct nv50_miptree *mt = nv50_miptree(dst->texture); - struct nouveau_bo *bo = mt->base.bo; - - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4); - OUT_RINGf (chan, rgba[0]); - OUT_RINGf (chan, rgba[1]); - OUT_RINGf (chan, rgba[2]); - OUT_RINGf (chan, rgba[3]); - - if (MARK_RING(chan, 18, 2)) - return; - - BEGIN_RING(chan, tesla, NV50TCL_RT_CONTROL, 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5); - OUT_RELOCh(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, nv50_format_table[dst->format].rt); - OUT_RING (chan, mt->level[dst->u.tex.level].tile_mode << 4); - OUT_RING (chan, 0); - BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); - BEGIN_RING(chan, tesla, NV50TCL_RT_ARRAY_MODE, 1); - OUT_RING (chan, 1); - - /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */ - - BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2); - OUT_RING (chan, (width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); - - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1); - OUT_RING (chan, 0x3c); - - nv50->dirty |= NV50_NEW_FRAMEBUFFER; + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_screen *screen = nv50->screen; + struct nouveau_channel *chan = screen->base.channel; + struct nv50_miptree *mt = nv50_miptree(dst->texture); + struct nv50_surface *sf = nv50_surface(dst); + struct nouveau_bo *bo = mt->base.bo; + + BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4); + OUT_RINGf (chan, rgba[0]); + OUT_RINGf (chan, rgba[1]); + OUT_RINGf (chan, rgba[2]); + OUT_RINGf (chan, rgba[3]); + + if (MARK_RING(chan, 18, 2)) + return; + + BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 5); + OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, nv50_format_table[dst->format].rt); + OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2); + OUT_RING (chan, sf->width); + OUT_RING (chan, sf->height); + BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); + OUT_RING (chan, 1); + + /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */ + + BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); + OUT_RING (chan, (width << 16) | dstx); + OUT_RING (chan, (height << 16) | dsty); + + BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); + OUT_RING (chan, 0x3c); + + nv50->dirty |= NV50_NEW_FRAMEBUFFER; } static void nv50_clear_depth_stencil(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned clear_flags, - double depth, - unsigned stencil, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height) + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_screen *screen = nv50->screen; + struct nouveau_channel *chan = screen->base.channel; + struct nv50_miptree *mt = nv50_miptree(dst->texture); + struct nv50_surface *sf = nv50_surface(dst); + struct nouveau_bo *bo = mt->base.bo; + uint32_t mode = 0; + + if (clear_flags & PIPE_CLEAR_DEPTH) { + BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); + OUT_RINGf (chan, depth); + mode |= NV50_3D_CLEAR_BUFFERS_Z; + } + + if (clear_flags & PIPE_CLEAR_STENCIL) { + BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1); + OUT_RING (chan, stencil & 0xff); + mode |= NV50_3D_CLEAR_BUFFERS_S; + } + + if (MARK_RING(chan, 17, 2)) + return; + + BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5); + OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, nv50_format_table[dst->format].rt); + OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); + OUT_RING (chan, sf->width); + OUT_RING (chan, sf->height); + OUT_RING (chan, (1 << 16) | 1); + + BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); + OUT_RING (chan, (width << 16) | dstx); + OUT_RING (chan, (height << 16) | dsty); + + BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); + OUT_RING (chan, mode); + + nv50->dirty |= NV50_NEW_FRAMEBUFFER; +} + +void +nv50_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *tesla = screen->tesla; - struct nv50_miptree *mt = nv50_miptree(dst->texture); - struct nouveau_bo *bo = mt->base.bo; - uint32_t mode = 0; - - if (clear_flags & PIPE_CLEAR_DEPTH) { - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1); - OUT_RINGf (chan, depth); - mode |= NV50TCL_CLEAR_BUFFERS_Z; - } - - if (clear_flags & PIPE_CLEAR_STENCIL) { - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1); - OUT_RING (chan, stencil & 0xff); - mode |= NV50TCL_CLEAR_BUFFERS_S; - } - - if (MARK_RING(chan, 17, 2)) - return; - - BEGIN_RING(chan, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5); - OUT_RELOCh(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, nv50_format_table[dst->format].rt); - OUT_RING (chan, mt->level[dst->u.tex.level].tile_mode << 4); - OUT_RING (chan, 0); - BEGIN_RING(chan, tesla, NV50TCL_ZETA_ENABLE, 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, tesla, NV50TCL_ZETA_HORIZ, 3); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); - OUT_RING (chan, (1 << 16) | 1); - - BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2); - OUT_RING (chan, (width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); - - BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1); - OUT_RING (chan, mode); - - nv50->dirty |= NV50_NEW_FRAMEBUFFER; + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct pipe_framebuffer_state *fb = &nv50->framebuffer; + unsigned i; + const unsigned dirty = nv50->dirty; + uint32_t mode = 0; + + /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */ + nv50->dirty &= NV50_NEW_FRAMEBUFFER; + if (!nv50_state_validate(nv50)) + return; + + if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { + BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4); + OUT_RINGf (chan, rgba[0]); + OUT_RINGf (chan, rgba[1]); + OUT_RINGf (chan, rgba[2]); + OUT_RINGf (chan, rgba[3]); + mode = + NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G | + NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A; + } + + if (buffers & PIPE_CLEAR_DEPTH) { + BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); + OUT_RING (chan, fui(depth)); + mode |= NV50_3D_CLEAR_BUFFERS_Z; + } + + if (buffers & PIPE_CLEAR_STENCIL) { + BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1); + OUT_RING (chan, stencil & 0xff); + mode |= NV50_3D_CLEAR_BUFFERS_S; + } + + BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); + OUT_RING (chan, mode); + + for (i = 1; i < fb->nr_cbufs; i++) { + BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); + OUT_RING (chan, (i << 6) | 0x3c); + } + + nv50->dirty = dirty & ~NV50_NEW_FRAMEBUFFER; } void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.resource_copy_region = nv50_surface_copy; - nv50->pipe.clear_render_target = nv50_clear_render_target; - nv50->pipe.clear_depth_stencil = nv50_clear_depth_stencil; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->resource_copy_region = nv50_resource_copy_region; + pipe->clear_render_target = nv50_clear_render_target; + pipe->clear_depth_stencil = nv50_clear_depth_stencil; } diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 9243f9edced..4456553a868 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -21,217 +21,282 @@ */ #include "nv50_context.h" -#include "nv50_texture.h" #include "nv50_resource.h" - -#include "nouveau/nouveau_stateobj.h" -#include "nouveau/nouveau_reloc.h" +#include "nv50_texture.xml.h" +#include "nv50_defs.xml.h" #include "util/u_format.h" static INLINE uint32_t nv50_tic_swizzle(uint32_t tc, unsigned swz) { - switch (swz) { - case PIPE_SWIZZLE_RED: - return (tc & NV50TIC_0_0_MAPR_MASK) >> NV50TIC_0_0_MAPR_SHIFT; - case PIPE_SWIZZLE_GREEN: - return (tc & NV50TIC_0_0_MAPG_MASK) >> NV50TIC_0_0_MAPG_SHIFT; - case PIPE_SWIZZLE_BLUE: - return (tc & NV50TIC_0_0_MAPB_MASK) >> NV50TIC_0_0_MAPB_SHIFT; - case PIPE_SWIZZLE_ALPHA: - return (tc & NV50TIC_0_0_MAPA_MASK) >> NV50TIC_0_0_MAPA_SHIFT; - case PIPE_SWIZZLE_ONE: - return 7; - case PIPE_SWIZZLE_ZERO: - default: - return 0; - } + switch (swz) { + case PIPE_SWIZZLE_RED: + return (tc & NV50_TIC_0_MAPR__MASK) >> NV50_TIC_0_MAPR__SHIFT; + case PIPE_SWIZZLE_GREEN: + return (tc & NV50_TIC_0_MAPG__MASK) >> NV50_TIC_0_MAPG__SHIFT; + case PIPE_SWIZZLE_BLUE: + return (tc & NV50_TIC_0_MAPB__MASK) >> NV50_TIC_0_MAPB__SHIFT; + case PIPE_SWIZZLE_ALPHA: + return (tc & NV50_TIC_0_MAPA__MASK) >> NV50_TIC_0_MAPA__SHIFT; + case PIPE_SWIZZLE_ONE: + return NV50_TIC_MAP_ONE; + case PIPE_SWIZZLE_ZERO: + default: + return NV50_TIC_MAP_ZERO; + } } -boolean -nv50_tex_construct(struct nv50_sampler_view *view) +struct pipe_sampler_view * +nv50_create_sampler_view(struct pipe_context *pipe, + struct pipe_resource *texture, + const struct pipe_sampler_view *templ) { - const struct util_format_description *desc; - struct nv50_miptree *mt = nv50_miptree(view->pipe.texture); - uint32_t swz[4], *tic = view->tic; - - tic[0] = nv50_format_table[view->pipe.format].tic; - - swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r); - swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g); - swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b); - swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a); - view->tic[0] = (tic[0] & ~NV50TIC_0_0_SWIZZLE_MASK) | - (swz[0] << NV50TIC_0_0_MAPR_SHIFT) | - (swz[1] << NV50TIC_0_0_MAPG_SHIFT) | - (swz[2] << NV50TIC_0_0_MAPB_SHIFT) | - (swz[3] << NV50TIC_0_0_MAPA_SHIFT); - - tic[2] = 0x50001000; - tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) | - ((mt->base.bo->tile_mode & 0xf0) << 21); - - desc = util_format_description(mt->base.base.format); - if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) - tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB; - - switch (mt->base.base.target) { - case PIPE_TEXTURE_1D: - tic[2] |= NV50TIC_0_2_TARGET_1D; - break; - case PIPE_TEXTURE_2D: - tic[2] |= NV50TIC_0_2_TARGET_2D; - break; - case PIPE_TEXTURE_RECT: - tic[2] |= NV50TIC_0_2_TARGET_RECT; - break; - case PIPE_TEXTURE_3D: - tic[2] |= NV50TIC_0_2_TARGET_3D; - break; - case PIPE_TEXTURE_CUBE: - tic[2] |= NV50TIC_0_2_TARGET_CUBE; - break; - default: - NOUVEAU_ERR("invalid texture target: %d\n", - mt->base.base.target); - return FALSE; - } - - tic[3] = 0x00300000; - - tic[4] = (1 << 31) | mt->base.base.width0; - tic[5] = (mt->base.base.last_level << 28) | - (mt->base.base.depth0 << 16) | mt->base.base.height0; - - tic[6] = 0x03000000; - - tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; - - return TRUE; + const struct util_format_description *desc; + uint32_t *tic; + uint32_t swz[4]; + uint32_t depth; + struct nv50_tic_entry *view; + struct nv50_miptree *mt = nv50_miptree(texture); + + view = MALLOC_STRUCT(nv50_tic_entry); + if (!view) + return NULL; + + view->pipe = *templ; + view->pipe.reference.count = 1; + view->pipe.texture = NULL; + view->pipe.context = pipe; + + view->id = -1; + + pipe_resource_reference(&view->pipe.texture, texture); + + tic = &view->tic[0]; + + desc = util_format_description(mt->base.base.format); + + /* TIC[0] */ + + tic[0] = nv50_format_table[view->pipe.format].tic; + + swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r); + swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g); + swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b); + swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a); + tic[0] = (tic[0] & ~NV50_TIC_0_SWIZZLE__MASK) | + (swz[0] << NV50_TIC_0_MAPR__SHIFT) | + (swz[1] << NV50_TIC_0_MAPG__SHIFT) | + (swz[2] << NV50_TIC_0_MAPB__SHIFT) | + (swz[3] << NV50_TIC_0_MAPA__SHIFT); + + /* tic[1] = mt->base.bo->offset; */ + tic[2] = /* mt->base.bo->offset >> 32 */ 0; + + tic[2] |= 0x10001000 | /* NV50_TIC_2_NO_BORDER */ 0x40000000; + + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) + tic[2] |= NV50_TIC_2_COLORSPACE_SRGB; + + if (mt->base.base.target != PIPE_TEXTURE_RECT) + tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; + + tic[2] |= + ((mt->base.bo->tile_mode & 0x0f) << (22 - 0)) | + ((mt->base.bo->tile_mode & 0xf0) << (25 - 4)); + + depth = MAX2(mt->base.base.array_size, mt->base.base.depth0); + + switch (mt->base.base.target) { + case PIPE_TEXTURE_1D: + tic[2] |= NV50_TIC_2_TARGET_1D; + break; + case PIPE_TEXTURE_2D: + tic[2] |= NV50_TIC_2_TARGET_2D; + break; + case PIPE_TEXTURE_RECT: + tic[2] |= NV50_TIC_2_TARGET_RECT; + break; + case PIPE_TEXTURE_3D: + tic[2] |= NV50_TIC_2_TARGET_3D; + break; + case PIPE_TEXTURE_CUBE: + depth /= 6; + if (depth > 1) + tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY; + else + tic[2] |= NV50_TIC_2_TARGET_CUBE; + break; + case PIPE_TEXTURE_1D_ARRAY: + tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY; + break; + case PIPE_TEXTURE_2D_ARRAY: + tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY; + break; + case PIPE_BUFFER: + tic[2] |= NV50_TIC_2_TARGET_BUFFER | /* NV50_TIC_2_LINEAR */ (1 << 18); + default: + NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target); + return FALSE; + } + + if (mt->base.base.target == PIPE_BUFFER) + tic[3] = mt->base.base.width0; + else + tic[3] = 0x00300000; + + tic[4] = (1 << 31) | mt->base.base.width0; + + tic[5] = mt->base.base.height0 & 0xffff; + tic[5] |= depth << 16; + tic[5] |= mt->base.base.last_level << 28; + + tic[6] = 0x03000000; + + tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; + + return &view->pipe; } -static int -nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so, - unsigned p) +static boolean +nv50_validate_tic(struct nv50_context *nv50, int s) { - struct nouveau_grobj *eng2d = nv50->screen->eng2d; - struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned unit, j; - - const unsigned rll = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW; - const unsigned rlh = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH - | NOUVEAU_BO_OR; - - nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM, - p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4); - - for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) { - struct nv50_sampler_view *view = - nv50_sampler_view(nv50->sampler_views[p][unit]); - - so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8); - if (view) { - uint32_t tic2 = view->tic[2]; - struct nv50_miptree *mt = - nv50_miptree(view->pipe.texture); - - tic2 &= ~NV50TIC_0_2_NORMALIZED_COORDS; - if (nv50->sampler[p][unit]->normalized) - tic2 |= NV50TIC_0_2_NORMALIZED_COORDS; - view->tic[2] = tic2; - - so_data (so, view->tic[0]); - so_reloc (so, mt->base.bo, 0, rll, 0, 0); - so_reloc (so, mt->base.bo, 0, rlh, tic2, tic2); - so_datap (so, &view->tic[3], 5); - - /* Set TEX insn $t src binding $unit in program type p - * to TIC, TSC entry (32 * p + unit), mark valid (1). - */ - so_method(so, tesla, NV50TCL_BIND_TIC(p), 1); - so_data (so, ((32 * p + unit) << 9) | (unit << 1) | 1); - } else { - for (j = 0; j < 8; ++j) - so_data(so, 0); - so_method(so, tesla, NV50TCL_BIND_TIC(p), 1); - so_data (so, (unit << 1) | 0); - } - } - - for (; unit < nv50->state.sampler_view_nr[p]; unit++) { - /* Make other bindings invalid. */ - so_method(so, tesla, NV50TCL_BIND_TIC(p), 1); - so_data (so, (unit << 1) | 0); - } - - nv50->state.sampler_view_nr[p] = nv50->sampler_view_nr[p]; - return TRUE; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_bo *txc = nv50->screen->txc; + unsigned i; + boolean need_flush = FALSE; + + for (i = 0; i < nv50->num_textures[s]; ++i) { + struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]); + struct nv04_resource *res; + + if (!tic) { + BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); + OUT_RING (chan, (i << 1) | 0); + continue; + } + res = &nv50_miptree(tic->pipe.texture)->base; + + if (tic->id < 0) { + tic->id = nv50_screen_tic_alloc(nv50->screen, tic); + + MARK_RING (chan, 24 + 8, 4); + BEGIN_RING(chan, RING_2D(DST_FORMAT), 2); + OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_2D(DST_PITCH), 5); + OUT_RING (chan, 262144); + OUT_RING (chan, 65536); + OUT_RING (chan, 1); + OUT_RELOCh(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2); + OUT_RING (chan, 0); + OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); + BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10); + OUT_RING (chan, 32); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, tic->id * 32); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), 8); + OUT_RING (chan, tic->tic[0]); + OUT_RELOCl(chan, res->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOC (chan, res->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]); + OUT_RINGp (chan, &tic->tic[3], 5); + + need_flush = TRUE; + } else + if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { + BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); + OUT_RING (chan, 0x20); //(tic->id << 4) | 1); + } + + nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); + + res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; + + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); + OUT_RING (chan, (tic->id << 9) | (i << 1) | 1); + } + for (; i < nv50->state.num_textures[s]; ++i) { + BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); + OUT_RING (chan, (i << 1) | 0); + } + nv50->state.num_textures[s] = nv50->num_textures[s]; + + return need_flush; } -static void -nv50_emit_texture_relocs(struct nv50_context *nv50, int prog) +void nv50_validate_textures(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_bo *tic = nv50->screen->tic; - int unit; - - for (unit = 0; unit < nv50->sampler_view_nr[prog]; unit++) { - struct nv50_sampler_view *view; - struct nv50_miptree *mt; - const unsigned base = ((prog * 32) + unit) * 32; - - view = nv50_sampler_view(nv50->sampler_views[prog][unit]); - if (!view) - continue; - mt = nv50_miptree(view->pipe.texture); - - nouveau_reloc_emit(chan, tic, base + 4, NULL, mt->base.bo, 0, 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); - nouveau_reloc_emit(chan, tic, base + 8, NULL, mt->base.bo, 0, 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, view->tic[2], view->tic[2]); - } + boolean need_flush; + + need_flush = nv50_validate_tic(nv50, 0); + need_flush |= nv50_validate_tic(nv50, 2); + + if (need_flush) { + BEGIN_RING(nv50->screen->base.channel, RING_3D(TIC_FLUSH), 1); + OUT_RING (nv50->screen->base.channel, 0); + } } -void -nv50_tex_relocs(struct nv50_context *nv50) +static boolean +nv50_validate_tsc(struct nv50_context *nv50, int s) { - nv50_emit_texture_relocs(nv50, 2); /* FP */ - nv50_emit_texture_relocs(nv50, 0); /* VP */ + struct nouveau_channel *chan = nv50->screen->base.channel; + unsigned i; + boolean need_flush = FALSE; + + for (i = 0; i < nv50->num_samplers[s]; ++i) { + struct nv50_tsc_entry *tsc = nv50_tsc_entry(nv50->samplers[s][i]); + + if (!tsc) { + BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); + OUT_RING (chan, (i << 4) | 0); + continue; + } + if (tsc->id < 0) { + tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc); + + nv50_sifc_linear_u8(&nv50->base, nv50->screen->txc, + 65536 + tsc->id * 32, + NOUVEAU_BO_VRAM, 32, tsc->tsc); + need_flush = TRUE; + } + nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); + + BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); + OUT_RING (chan, (tsc->id << 12) | (i << 4) | 1); + } + for (; i < nv50->state.num_samplers[s]; ++i) { + BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); + OUT_RING (chan, (i << 4) | 0); + } + nv50->state.num_samplers[s] = nv50->num_samplers[s]; + + return need_flush; } -struct nouveau_stateobj * -nv50_tex_validate(struct nv50_context *nv50) +void nv50_validate_samplers(struct nv50_context *nv50) { - struct nouveau_stateobj *so; - struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned p, m = 0, d = 0, r = 0; - - for (p = 0; p < 3; ++p) { - unsigned nr = MAX2(nv50->sampler_view_nr[p], - nv50->state.sampler_view_nr[p]); - m += nr; - d += nr; - r += nv50->sampler_view_nr[p]; - } - m = m * 2 + 3 * 4 + 1; - d = d * 9 + 3 * 19 + 1; - r = r * 2 + 3 * 2; - - so = so_new(m, d, r); - - if (nv50_validate_textures(nv50, so, 0) == FALSE || - nv50_validate_textures(nv50, so, 2) == FALSE) { - so_ref(NULL, &so); - - NOUVEAU_ERR("failed tex validate\n"); - return NULL; - } - - so_method(so, tesla, 0x1330, 1); /* flush TIC */ - so_data (so, 0); - - return so; + boolean need_flush; + + need_flush = nv50_validate_tsc(nv50, 0); + need_flush |= nv50_validate_tsc(nv50, 2); + + if (need_flush) { + BEGIN_RING(nv50->screen->base.channel, RING_3D(TSC_FLUSH), 1); + OUT_RING (nv50->screen->base.channel, 0); + } } diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h deleted file mode 100644 index b4939943e8a..00000000000 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef __NV50_TEXTURE_H__ -#define __NV50_TEXTURE_H__ - -/* It'd be really nice to have these in nouveau_class.h generated by - * renouveau like the rest of the object header - but not sure it can - * handle non-object stuff nicely - need to look into it. - */ - -/* Texture image control block */ -#define NV50TIC_0_0_SWIZZLE_MASK 0x3ffc0000 -#define NV50TIC_0_0_MAPA_MASK 0x38000000 -#define NV50TIC_0_0_MAPA_SHIFT 27 -#define NV50TIC_0_0_MAPA_ZERO 0x00000000 -#define NV50TIC_0_0_MAPA_C0 0x10000000 -#define NV50TIC_0_0_MAPA_C1 0x18000000 -#define NV50TIC_0_0_MAPA_C2 0x20000000 -#define NV50TIC_0_0_MAPA_C3 0x28000000 -#define NV50TIC_0_0_MAPA_ONE 0x38000000 -#define NV50TIC_0_0_MAPB_MASK 0x07000000 -#define NV50TIC_0_0_MAPB_SHIFT 24 -#define NV50TIC_0_0_MAPB_ZERO 0x00000000 -#define NV50TIC_0_0_MAPB_C0 0x02000000 -#define NV50TIC_0_0_MAPB_C1 0x03000000 -#define NV50TIC_0_0_MAPB_C2 0x04000000 -#define NV50TIC_0_0_MAPB_C3 0x05000000 -#define NV50TIC_0_0_MAPB_ONE 0x07000000 -#define NV50TIC_0_0_MAPG_MASK 0x00e00000 -#define NV50TIC_0_0_MAPG_SHIFT 21 -#define NV50TIC_0_0_MAPG_ZERO 0x00000000 -#define NV50TIC_0_0_MAPG_C0 0x00400000 -#define NV50TIC_0_0_MAPG_C1 0x00600000 -#define NV50TIC_0_0_MAPG_C2 0x00800000 -#define NV50TIC_0_0_MAPG_C3 0x00a00000 -#define NV50TIC_0_0_MAPG_ONE 0x00e00000 -#define NV50TIC_0_0_MAPR_MASK 0x001c0000 -#define NV50TIC_0_0_MAPR_SHIFT 18 -#define NV50TIC_0_0_MAPR_ZERO 0x00000000 -#define NV50TIC_0_0_MAPR_C0 0x00080000 -#define NV50TIC_0_0_MAPR_C1 0x000c0000 -#define NV50TIC_0_0_MAPR_C2 0x00100000 -#define NV50TIC_0_0_MAPR_C3 0x00140000 -#define NV50TIC_0_0_MAPR_ONE 0x001c0000 -#define NV50TIC_0_0_TYPEA_MASK 0x00038000 -#define NV50TIC_0_0_TYPEA_UNORM 0x00010000 -#define NV50TIC_0_0_TYPEA_SNORM 0x00008000 -#define NV50TIC_0_0_TYPEA_SINT 0x00018000 -#define NV50TIC_0_0_TYPEA_UINT 0x00020000 -#define NV50TIC_0_0_TYPEA_SSCALED 0x00028000 -#define NV50TIC_0_0_TYPEA_USCALED 0x00030000 -#define NV50TIC_0_0_TYPEA_FLOAT 0x00038000 -#define NV50TIC_0_0_TYPEB_MASK 0x00007000 -#define NV50TIC_0_0_TYPEB_UNORM 0x00002000 -#define NV50TIC_0_0_TYPEB_SNORM 0x00001000 -#define NV50TIC_0_0_TYPEB_SINT 0x00003000 -#define NV50TIC_0_0_TYPEB_UINT 0x00004000 -#define NV50TIC_0_0_TYPEB_SSCALED 0x00005000 -#define NV50TIC_0_0_TYPEB_USCALED 0x00006000 -#define NV50TIC_0_0_TYPEB_FLOAT 0x00007000 -#define NV50TIC_0_0_TYPEG_MASK 0x00000e00 -#define NV50TIC_0_0_TYPEG_UNORM 0x00000400 -#define NV50TIC_0_0_TYPEG_SNORM 0x00000200 -#define NV50TIC_0_0_TYPEG_SINT 0x00000600 -#define NV50TIC_0_0_TYPEG_UINT 0x00000800 -#define NV50TIC_0_0_TYPEG_SSCALED 0x00000a00 -#define NV50TIC_0_0_TYPEG_USCALED 0x00000c00 -#define NV50TIC_0_0_TYPEG_FLOAT 0x00000e00 -#define NV50TIC_0_0_TYPER_MASK 0x000001c0 -#define NV50TIC_0_0_TYPER_UNORM 0x00000080 -#define NV50TIC_0_0_TYPER_SNORM 0x00000040 -#define NV50TIC_0_0_TYPER_SINT 0x000000c0 -#define NV50TIC_0_0_TYPER_UINT 0x00000100 -#define NV50TIC_0_0_TYPER_SSCALED 0x00000140 -#define NV50TIC_0_0_TYPER_USCALED 0x00000180 -#define NV50TIC_0_0_TYPER_FLOAT 0x000001c0 -#define NV50TIC_0_0_FMT_MASK 0x0000003f -#define NV50TIC_0_0_FMT_32_32_32_32 0x00000001 -#define NV50TIC_0_0_FMT_16_16_16_16 0x00000003 -#define NV50TIC_0_0_FMT_32_32 0x00000004 -#define NV50TIC_0_0_FMT_8_8_8_8 0x00000008 -#define NV50TIC_0_0_FMT_2_10_10_10 0x00000009 -#define NV50TIC_0_0_FMT_16_16 0x0000000c -#define NV50TIC_0_0_FMT_32 0x0000000f -#define NV50TIC_0_0_FMT_4_4_4_4 0x00000012 -/* #define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 */ -#define NV50TIC_0_0_FMT_1_5_5_5 0x00000014 -#define NV50TIC_0_0_FMT_5_6_5 0x00000015 -#define NV50TIC_0_0_FMT_8_8 0x00000018 -#define NV50TIC_0_0_FMT_16 0x0000001b -#define NV50TIC_0_0_FMT_8 0x0000001d -#define NV50TIC_0_0_FMT_5_9_9_9 0x00000020 -#define NV50TIC_0_0_FMT_10_11_11 0x00000021 -#define NV50TIC_0_0_FMT_DXT1 0x00000024 -#define NV50TIC_0_0_FMT_DXT3 0x00000025 -#define NV50TIC_0_0_FMT_DXT5 0x00000026 -#define NV50TIC_0_0_FMT_RGTC1 0x00000027 -#define NV50TIC_0_0_FMT_RGTC2 0x00000028 -#define NV50TIC_0_0_FMT_24_8 0x00000029 -#define NV50TIC_0_0_FMT_8_24 0x0000002a -#define NV50TIC_0_0_FMT_32_DEPTH 0x0000002f -#define NV50TIC_0_0_FMT_32_8 0x00000030 -#define NV50TIC_0_0_FMT_16_DEPTH 0x0000003a - -#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff -#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0 - -#define NV50TIC_0_2_COLORSPACE_SRGB 0x00000400 -#define NV50TIC_0_2_TARGET_1D 0x00000000 -#define NV50TIC_0_2_TARGET_2D 0x00004000 -#define NV50TIC_0_2_TARGET_3D 0x00008000 -#define NV50TIC_0_2_TARGET_CUBE 0x0000c000 -#define NV50TIC_0_2_TARGET_1D_ARRAY 0x00010000 -#define NV50TIC_0_2_TARGET_2D_ARRAY 0x00014000 -#define NV50TIC_0_2_TARGET_BUFFER 0x00018000 -#define NV50TIC_0_2_TARGET_RECT 0x0001c000 -/* #define NV50TIC_0_0_TILE_MODE_LINEAR 0x00040000 */ -#define NV50TIC_0_2_TILE_MODE_Y_MASK 0x01c00000 -#define NV50TIC_0_2_TILE_MODE_Y_SHIFT 22 -#define NV50TIC_0_2_TILE_MODE_Z_MASK 0x0e000000 -#define NV50TIC_0_2_TILE_MODE_Z_SHIFT 25 -#define NV50TIC_0_2_NORMALIZED_COORDS 0x80000000 - -#define NV50TIC_0_3_UNKNOWN_MASK 0xffffffff - -#define NV50TIC_0_4_WIDTH_MASK 0x0000ffff -#define NV50TIC_0_4_WIDTH_SHIFT 0 - -#define NV50TIC_0_5_LAST_LEVEL_MASK 0xf0000000 -#define NV50TIC_0_5_LAST_LEVEL_SHIFT 28 -#define NV50TIC_0_5_DEPTH_MASK 0x0fff0000 -#define NV50TIC_0_5_DEPTH_SHIFT 16 -#define NV50TIC_0_5_HEIGHT_MASK 0x0000ffff -#define NV50TIC_0_5_HEIGHT_SHIFT 0 -#define NV50TIC_0_6_UNKNOWN_MASK 0xffffffff - -#define NV50TIC_0_7_BASE_LEVEL_MASK 0x0000000f -#define NV50TIC_0_7_BASE_LEVEL_SHIFT 0 -#define NV50TIC_0_7_MAX_LEVEL_MASK 0x000000f0 -#define NV50TIC_0_7_MAX_LEVEL_SHIFT 4 - -/* Texture sampler control block */ -#define NV50TSC_1_0_WRAPS_MASK 0x00000007 -#define NV50TSC_1_0_WRAPS_REPEAT 0x00000000 -#define NV50TSC_1_0_WRAPS_MIRROR_REPEAT 0x00000001 -#define NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE 0x00000002 -#define NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER 0x00000003 -#define NV50TSC_1_0_WRAPS_CLAMP 0x00000004 -#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE 0x00000005 -#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER 0x00000006 -#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP 0x00000007 -#define NV50TSC_1_0_WRAPT_MASK 0x00000038 -#define NV50TSC_1_0_WRAPT_REPEAT 0x00000000 -#define NV50TSC_1_0_WRAPT_MIRROR_REPEAT 0x00000008 -#define NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE 0x00000010 -#define NV50TSC_1_0_WRAPT_CLAMP_TO_BORDER 0x00000018 -#define NV50TSC_1_0_WRAPT_CLAMP 0x00000020 -#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP_TO_EDGE 0x00000028 -#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP_TO_BORDER 0x00000030 -#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP 0x00000038 -#define NV50TSC_1_0_WRAPR_MASK 0x000001c0 -#define NV50TSC_1_0_WRAPR_REPEAT 0x00000000 -#define NV50TSC_1_0_WRAPR_MIRROR_REPEAT 0x00000040 -#define NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE 0x00000080 -#define NV50TSC_1_0_WRAPR_CLAMP_TO_BORDER 0x000000c0 -#define NV50TSC_1_0_WRAPR_CLAMP 0x00000100 -#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE 0x00000140 -#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER 0x00000180 -#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP 0x000001c0 -#define NV50TSC_1_0_MAX_ANISOTROPY_MASK 0x00700000 - -#define NV50TSC_1_1_MAGF_MASK 0x00000003 -#define NV50TSC_1_1_MAGF_NEAREST 0x00000001 -#define NV50TSC_1_1_MAGF_LINEAR 0x00000002 -#define NV50TSC_1_1_MINF_MASK 0x00000030 -#define NV50TSC_1_1_MINF_NEAREST 0x00000010 -#define NV50TSC_1_1_MINF_LINEAR 0x00000020 -#define NV50TSC_1_1_MIPF_MASK 0x000000c0 -#define NV50TSC_1_1_MIPF_NONE 0x00000040 -#define NV50TSC_1_1_MIPF_NEAREST 0x00000080 -#define NV50TSC_1_1_MIPF_LINEAR 0x000000c0 -#define NV50TSC_1_1_LOD_BIAS_MASK 0x01fff000 -#define NV50TSC_1_1_UNKN_ANISO_15 0x10000000 -#define NV50TSC_1_1_UNKN_ANISO_35 0x18000000 - -#define NV50TSC_1_2_MIN_LOD_MASK 0x00000f00 -#define NV50TSC_1_2_MAX_LOD_MASK 0x00f00000 - -#define NV50TSC_1_3_UNKNOWN_MASK 0xffffffff - -#define NV50TSC_1_4_BORDER_COLOR_RED_MASK 0xffffffff - -#define NV50TSC_1_5_BORDER_COLOR_GREEN_MASK 0xffffffff - -#define NV50TSC_1_6_BORDER_COLOR_BLUE_MASK 0xffffffff - -#define NV50TSC_1_7_BORDER_COLOR_ALPHA_MASK 0xffffffff - -#endif diff --git a/src/gallium/drivers/nv50/nv50_texture.xml.h b/src/gallium/drivers/nv50/nv50_texture.xml.h new file mode 100644 index 00000000000..9f83206516f --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_texture.xml.h @@ -0,0 +1,259 @@ +#ifndef NV50_TEXTURE_XML +#define NV50_TEXTURE_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://0x04.net/cgit/index.cgi/rules-ng-ng +git clone git://0x04.net/rules-ng-ng + +The rules-ng-ng source files this header was generated from are: +- nv50_texture.xml ( 6871 bytes, from 2010-10-03 13:18:37) +- copyright.xml ( 6498 bytes, from 2010-10-03 13:18:37) + +Copyright (C) 2006-2010 by the following authors: +- Artur Huillet <[email protected]> (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. <[email protected]> (koala_br) +- Carlos Martin <[email protected]> (carlosmn) +- Christoph Bumiller <[email protected]> (calim, chrisbmr) +- Dawid Gajownik <[email protected]> (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov <[email protected]> (lumag) +- EdB <[email protected]> (edb_) +- Erik Waling <[email protected]> (erikwaling) +- Francisco Jerez <[email protected]> (curro, curro_, currojerez) +- imirkin <[email protected]> (imirkin) +- jb17bsome <[email protected]> (jb17bsome) +- Jeremy Kolb <[email protected]> (kjeremy) +- Laurent Carlier <[email protected]> (lordheavy) +- Luca Barbieri <[email protected]> (lb, lb1) +- Maarten Maathuis <[email protected]> (stillunknown) +- Marcin Kościelnicki <[email protected]> (mwk, koriakin) +- Mark Carey <[email protected]> (careym) +- Matthieu Castet <[email protected]> (mat-c) +- nvidiaman <[email protected]> (nvidiaman) +- Patrice Mandin <[email protected]> (pmandin, pmdata) +- Pekka Paalanen <[email protected]> (pq, ppaalanen) +- Peter Popov <[email protected]> (ironpeter) +- Richard Hughes <[email protected]> (hughsient) +- Rudi Cilibrasi <[email protected]> (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet <[email protected]> (leroutier) +- Stephane Marchesin <[email protected]> (marcheu) +- sturmflut <[email protected]> (sturmflut) +- Sylvain Munaut <[email protected]> +- Victor Stinner <[email protected]> (haypo) +- Wladmir van der Laan <[email protected]> (miathan6) +- Younes Manton <[email protected]> (ymanton) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#define NV50_TIC_MAP_ZERO 0x00000000 +#define NV50_TIC_MAP_C0 0x00000002 +#define NV50_TIC_MAP_C1 0x00000003 +#define NV50_TIC_MAP_C2 0x00000004 +#define NV50_TIC_MAP_C3 0x00000005 +#define NV50_TIC_MAP_ONE 0x00000007 +#define NV50_TIC_TYPE_SNORM 0x00000001 +#define NV50_TIC_TYPE_UNORM 0x00000002 +#define NV50_TIC_TYPE_SINT 0x00000003 +#define NV50_TIC_TYPE_UINT 0x00000004 +#define NV50_TIC_TYPE_SSCALED 0x00000005 +#define NV50_TIC_TYPE_USCALED 0x00000006 +#define NV50_TIC_TYPE_FLOAT 0x00000007 +#define NV50_TSC_WRAP_REPEAT 0x00000000 +#define NV50_TSC_WRAP_MIRROR_REPEAT 0x00000001 +#define NV50_TSC_WRAP_CLAMP_TO_EDGE 0x00000002 +#define NV50_TSC_WRAP_CLAMP_TO_BORDER 0x00000003 +#define NV50_TSC_WRAP_CLAMP 0x00000004 +#define NV50_TSC_WRAP_MIRROR_CLAMP_TO_EDGE 0x00000005 +#define NV50_TSC_WRAP_MIRROR_CLAMP_TO_BORDER 0x00000006 +#define NV50_TSC_WRAP_MIRROR_CLAMP 0x00000007 +#define NV50_TIC__SIZE 0x00000020 +#define NV50_TIC_0 0x00000000 +#define NV50_TIC_0_MAPA__MASK 0x38000000 +#define NV50_TIC_0_MAPA__SHIFT 27 +#define NV50_TIC_0_MAPB__MASK 0x07000000 +#define NV50_TIC_0_MAPB__SHIFT 24 +#define NV50_TIC_0_MAPG__MASK 0x00e00000 +#define NV50_TIC_0_MAPG__SHIFT 21 +#define NV50_TIC_0_MAPR__MASK 0x001c0000 +#define NV50_TIC_0_MAPR__SHIFT 18 +#define NV50_TIC_0_TYPE3__MASK 0x00038000 +#define NV50_TIC_0_TYPE3__SHIFT 15 +#define NV50_TIC_0_TYPE2__MASK 0x00007000 +#define NV50_TIC_0_TYPE2__SHIFT 12 +#define NV50_TIC_0_TYPE1__MASK 0x00000e00 +#define NV50_TIC_0_TYPE1__SHIFT 9 +#define NV50_TIC_0_TYPE0__MASK 0x000001c0 +#define NV50_TIC_0_TYPE0__SHIFT 6 +#define NV50_TIC_0_SWIZZLE__MASK 0x3ffc0000 +#define NV50_TIC_0_FMT__MASK 0x0000003f +#define NV50_TIC_0_FMT__SHIFT 0 +#define NV50_TIC_0_FMT_32_32_32_32 0x00000001 +#define NV50_TIC_0_FMT_16_16_16_16 0x00000003 +#define NV50_TIC_0_FMT_32_32 0x00000004 +#define NV50_TIC_0_FMT_32_8 0x00000005 +#define NV50_TIC_0_FMT_8_8_8_8 0x00000008 +#define NV50_TIC_0_FMT_2_10_10_10 0x00000009 +#define NV50_TIC_0_FMT_16_16 0x0000000c +#define NV50_TIC_0_FMT_8_24 0x0000000d +#define NV50_TIC_0_FMT_24_8 0x0000000e +#define NV50_TIC_0_FMT_32 0x0000000f +#define NV50_TIC_0_FMT_4_4_4_4 0x00000012 +#define NV50_TIC_0_FMT_5_5_5_1 0x00000013 +#define NV50_TIC_0_FMT_1_5_5_5 0x00000014 +#define NV50_TIC_0_FMT_5_6_5 0x00000015 +#define NV50_TIC_0_FMT_6_5_5 0x00000016 +#define NV50_TIC_0_FMT_8_8 0x00000018 +#define NV50_TIC_0_FMT_16 0x0000001b +#define NV50_TIC_0_FMT_8 0x0000001d +#define NV50_TIC_0_FMT_4_4 0x0000001e +#define NV50_TIC_0_FMT_UNK1F 0x0000001f +#define NV50_TIC_0_FMT_E5_9_9_9 0x00000020 +#define NV50_TIC_0_FMT_10_11_11 0x00000021 +#define NV50_TIC_0_FMT_C1_C2_C1_C0 0x00000022 +#define NV50_TIC_0_FMT_C2_C1_C0_C1 0x00000023 +#define NV50_TIC_0_FMT_DXT1 0x00000024 +#define NV50_TIC_0_FMT_DXT3 0x00000025 +#define NV50_TIC_0_FMT_DXT5 0x00000026 +#define NV50_TIC_0_FMT_RGTC1 0x00000027 +#define NV50_TIC_0_FMT_RGTC2 0x00000028 +#define NV50_TIC_0_FMT_24_8_ZETA 0x00000029 +#define NV50_TIC_0_FMT_8_24_ZETA 0x0000002a +#define NV50_TIC_0_FMT_UNK2C_ZETA 0x0000002c +#define NV50_TIC_0_FMT_UNK2D_ZETA 0x0000002d +#define NV50_TIC_0_FMT_UNK2E_ZETA 0x0000002e +#define NV50_TIC_0_FMT_32_ZETA 0x0000002f +#define NV50_TIC_0_FMT_32_8_ZETA 0x00000030 +#define NV50_TIC_0_FMT_16_ZETA 0x0000003a + +#define NV50_TIC_1 0x00000004 +#define NV50_TIC_1_OFFSET_LOW__MASK 0xffffffff +#define NV50_TIC_1_OFFSET_LOW__SHIFT 0 + +#define NV50_TIC_2 0x00000008 +#define NV50_TIC_2_OFFSET_HIGH__MASK 0x000000ff +#define NV50_TIC_2_OFFSET_HIGH__SHIFT 0 +#define NV50_TIC_2_COLORSPACE_SRGB 0x00000400 +#define NV50_TIC_2_TARGET__MASK 0x0003c000 +#define NV50_TIC_2_TARGET__SHIFT 14 +#define NV50_TIC_2_TARGET_1D 0x00000000 +#define NV50_TIC_2_TARGET_2D 0x00004000 +#define NV50_TIC_2_TARGET_3D 0x00008000 +#define NV50_TIC_2_TARGET_CUBE 0x0000c000 +#define NV50_TIC_2_TARGET_1D_ARRAY 0x00010000 +#define NV50_TIC_2_TARGET_2D_ARRAY 0x00014000 +#define NV50_TIC_2_TARGET_BUFFER 0x00018000 +#define NV50_TIC_2_TARGET_RECT 0x0001c000 +#define NV50_TIC_2_TARGET_CUBE_ARRAY 0x00020000 +#define NV50_TIC_2_TILE_MODE_LINEAR 0x00040000 +#define NV50_TIC_2_TILE_MODE_Y__MASK 0x01c00000 +#define NV50_TIC_2_TILE_MODE_Y__SHIFT 22 +#define NV50_TIC_2_TILE_MODE_Z__MASK 0x0e000000 +#define NV50_TIC_2_TILE_MODE_Z__SHIFT 25 +#define NV50_TIC_2_2D_UNK0258__MASK 0x30000000 +#define NV50_TIC_2_2D_UNK0258__SHIFT 28 +#define NV50_TIC_2_NORMALIZED_COORDS 0x80000000 + +#define NV50_TIC_3 0x0000000c +#define NV50_TIC_3_PITCH__MASK 0xffffffff +#define NV50_TIC_3_PITCH__SHIFT 0 + +#define NV50_TIC_4 0x00000010 +#define NV50_TIC_4_WIDTH__MASK 0xffffffff +#define NV50_TIC_4_WIDTH__SHIFT 0 + +#define NV50_TIC_5 0x00000014 +#define NV50_TIC_5_LAST_LEVEL__MASK 0xf0000000 +#define NV50_TIC_5_LAST_LEVEL__SHIFT 28 +#define NV50_TIC_5_DEPTH__MASK 0x0fff0000 +#define NV50_TIC_5_DEPTH__SHIFT 16 +#define NV50_TIC_5_HEIGHT__MASK 0x0000ffff +#define NV50_TIC_5_HEIGHT__SHIFT 0 + +#define NV50_TIC_7 0x0000001c +#define NV50_TIC_7_BASE_LEVEL__MASK 0x0000000f +#define NV50_TIC_7_BASE_LEVEL__SHIFT 0 +#define NV50_TIC_7_MAX_LEVEL__MASK 0x000000f0 +#define NV50_TIC_7_MAX_LEVEL__SHIFT 4 + +#define NV50_TSC__SIZE 0x00000020 +#define NV50_TSC_0 0x00000000 +#define NV50_TSC_0_WRAPS__MASK 0x00000007 +#define NV50_TSC_0_WRAPS__SHIFT 0 +#define NV50_TSC_0_WRAPT__MASK 0x00000038 +#define NV50_TSC_0_WRAPT__SHIFT 3 +#define NV50_TSC_0_WRAPR__MASK 0x000001c0 +#define NV50_TSC_0_WRAPR__SHIFT 6 +#define NV50_TSC_0_SHADOW_COMPARE_ENABLE 0x00000200 +#define NV50_TSC_0_SHADOW_COMPARE_FUNC__MASK 0x00001c00 +#define NV50_TSC_0_SHADOW_COMPARE_FUNC__SHIFT 10 +#define NV50_TSC_0_ANISOTROPY_MASK__MASK 0x00700000 +#define NV50_TSC_0_ANISOTROPY_MASK__SHIFT 20 + +#define NV50_TSC_1 0x00000004 +#define NV50_TSC_1_UNKN_ANISO_15 0x10000000 +#define NV50_TSC_1_UNKN_ANISO_35 0x18000000 +#define NV50_TSC_1_MAGF__MASK 0x00000003 +#define NV50_TSC_1_MAGF__SHIFT 0 +#define NV50_TSC_1_MAGF_NEAREST 0x00000001 +#define NV50_TSC_1_MAGF_LINEAR 0x00000002 +#define NV50_TSC_1_MINF__MASK 0x00000030 +#define NV50_TSC_1_MINF__SHIFT 4 +#define NV50_TSC_1_MINF_NEAREST 0x00000010 +#define NV50_TSC_1_MINF_LINEAR 0x00000020 +#define NV50_TSC_1_MIPF__MASK 0x000000c0 +#define NV50_TSC_1_MIPF__SHIFT 6 +#define NV50_TSC_1_MIPF_NONE 0x00000040 +#define NV50_TSC_1_MIPF_NEAREST 0x00000080 +#define NV50_TSC_1_MIPF_LINEAR 0x000000c0 +#define NV50_TSC_1_LOD_BIAS__MASK 0x01fff000 +#define NV50_TSC_1_LOD_BIAS__SHIFT 12 + +#define NV50_TSC_2 0x00000008 +#define NV50_TSC_2_MIN_LOD__MASK 0x00000f00 +#define NV50_TSC_2_MIN_LOD__SHIFT 8 +#define NV50_TSC_2_MAX_LOD__MASK 0x00f00000 +#define NV50_TSC_2_MAX_LOD__SHIFT 20 + +#define NV50_TSC_4 0x00000010 +#define NV50_TSC_4_BORDER_COLOR_RED__MASK 0xffffffff +#define NV50_TSC_4_BORDER_COLOR_RED__SHIFT 0 + +#define NV50_TSC_5 0x00000014 +#define NV50_TSC_5_BORDER_COLOR_GREEN__MASK 0xffffffff +#define NV50_TSC_5_BORDER_COLOR_GREEN__SHIFT 0 + +#define NV50_TSC_6 0x00000018 +#define NV50_TSC_6_BORDER_COLOR_BLUE__MASK 0xffffffff +#define NV50_TSC_6_BORDER_COLOR_BLUE__SHIFT 0 + +#define NV50_TSC_7 0x0000001c +#define NV50_TSC_7_BORDER_COLOR_ALPHA__MASK 0xffffffff +#define NV50_TSC_7_BORDER_COLOR_ALPHA__SHIFT 0 + + +#endif /* NV50_TEXTURE_XML */ diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index ce9300ad8fd..54b78e850ed 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -476,6 +476,7 @@ bld_loop_end(struct bld_context *bld, struct nv_basic_block *bb) stk = (struct bld_value_stack *)phi->target; phi->target = NULL; + /* start with s == 1, src[0] is from outside the loop */ for (s = 1, n = 0; n < bb->num_in; ++n) { if (bb->in_kind[n] != CFG_EDGE_BACK) continue; @@ -487,8 +488,11 @@ bld_loop_end(struct bld_context *bld, struct nv_basic_block *bb) for (i = 0; i < 4; ++i) if (phi->src[i] && phi->src[i]->value == val) break; - if (i == 4) + if (i == 4) { + /* skip values we do not want to replace */ + for (; phi->src[s] && phi->src[s]->value != phi->def[0]; ++s); nv_reference(bld->pc, &phi->src[s++], val); + } } bld->pc->current_block = save; @@ -1102,9 +1106,8 @@ emit_fetch(struct bld_context *bld, const struct tgsi_full_instruction *insn, switch (src->Register.File) { case TGSI_FILE_CONSTANT: - dim_idx = src->Dimension.Index ? src->Dimension.Index + 2 : 1; - assert(dim_idx < 14); - assert(dim_idx == 1); /* for now */ + dim_idx = src->Dimension.Index; + assert(dim_idx < 15); res = new_value(bld->pc, NV_FILE_MEM_C(dim_idx), type); SET_TYPE(res, type); @@ -1468,7 +1471,7 @@ bld_tex(struct bld_context *bld, struct nv_value *dst0[4], uint opcode = translate_opcode(insn->Instruction.Opcode); int arg, dim, c; const int tic = insn->Src[1].Register.Index; - const int tsc = 0; + const int tsc = tic; const int cube = (insn->Texture.Texture == TGSI_TEXTURE_CUBE) ? 1 : 0; get_tex_dim(insn, &dim, &arg); @@ -1717,6 +1720,10 @@ bld_instruction(struct bld_context *bld, { struct nv_basic_block *b = new_basic_block(bld->pc); + if (bld->pc->current_block->exit && + !bld->pc->current_block->exit->is_terminator) + bld_flow(bld, NV_OP_BRA, NV_CC_TR, NULL, b, FALSE); + --bld->cond_lvl; nvbb_attach_block(bld->pc->current_block, b, bld->out_kind); nvbb_attach_block(bld->cond_bb[bld->cond_lvl], b, CFG_EDGE_FORWARD); @@ -1923,6 +1930,7 @@ bld_instruction(struct bld_context *bld, dst0[c] = bld_insn_2(bld, NV_OP_XOR, temp, temp); dst0[c]->insn->cc = NV_CC_EQ; nv_reference(bld->pc, &dst0[c]->insn->flags_src, src1); + dst0[c] = bld_insn_2(bld, NV_OP_SELECT, dst0[c], temp); } break; case TGSI_OPCODE_SUB: diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index bf5af4ddc65..74869774595 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -1,351 +1,347 @@ -#include "pipe/p_context.h" -#include "util/u_inlines.h" #include "util/u_format.h" -#include "util/u_math.h" #include "nv50_context.h" #include "nv50_transfer.h" -#include "nv50_resource.h" + +#include "nv50_defs.xml.h" struct nv50_transfer { - struct pipe_transfer base; - struct nouveau_bo *bo; - int map_refcnt; - unsigned level_offset; - unsigned level_tiling; - int level_pitch; - int level_width; - int level_height; - int level_depth; - int level_x; - int level_y; - int level_z; - unsigned nblocksx; - unsigned nblocksy; + struct pipe_transfer base; + struct nv50_m2mf_rect rect[2]; + uint32_t nblocksx; + uint32_t nblocksy; }; static void -nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, - struct nouveau_bo *src_bo, unsigned src_offset, - int src_pitch, unsigned src_tile_mode, - int sx, int sy, int sz, int sw, int sh, int sd, - struct nouveau_bo *dst_bo, unsigned dst_offset, - int dst_pitch, unsigned dst_tile_mode, - int dx, int dy, int dz, int dw, int dh, int dd, - int cpp, int width, int height, - unsigned src_reloc, unsigned dst_reloc) +nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, + const struct nv50_m2mf_rect *dst, + const struct nv50_m2mf_rect *src, + uint32_t nblocksx, uint32_t nblocksy) { - struct nv50_screen *screen = nv50_screen(pscreen); - struct nouveau_channel *chan = screen->m2mf->channel; - struct nouveau_grobj *m2mf = screen->m2mf; - - src_reloc |= NOUVEAU_BO_RD; - dst_reloc |= NOUVEAU_BO_WR; - - WAIT_RING (chan, 14); - - if (!nouveau_bo_tile_layout(src_bo)) { - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, m2mf, - NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1); - OUT_RING (chan, src_pitch); - src_offset += (sy * src_pitch) + (sx * cpp); - } else { - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 6); - OUT_RING (chan, 0); - OUT_RING (chan, src_tile_mode << 4); - OUT_RING (chan, sw * cpp); - OUT_RING (chan, sh); - OUT_RING (chan, sd); - OUT_RING (chan, sz); /* copying only 1 zslice per call */ - } - - if (!nouveau_bo_tile_layout(dst_bo)) { - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, m2mf, - NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1); - OUT_RING (chan, dst_pitch); - dst_offset += (dy * dst_pitch) + (dx * cpp); - } else { - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 6); - OUT_RING (chan, 0); - OUT_RING (chan, dst_tile_mode << 4); - OUT_RING (chan, dw * cpp); - OUT_RING (chan, dh); - OUT_RING (chan, dd); - OUT_RING (chan, dz); /* copying only 1 zslice per call */ - } - - while (height) { - int line_count = height > 2047 ? 2047 : height; - - MARK_RING (chan, 15, 4); /* flush on lack of space or relocs */ - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2); - OUT_RELOCh(chan, src_bo, src_offset, src_reloc); - OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc); - BEGIN_RING(chan, m2mf, - NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2); - OUT_RELOCl(chan, src_bo, src_offset, src_reloc); - OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc); - if (nouveau_bo_tile_layout(src_bo)) { - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1); - OUT_RING (chan, (sy << 16) | (sx * cpp)); - } else { - src_offset += (line_count * src_pitch); - } - if (nouveau_bo_tile_layout(dst_bo)) { - BEGIN_RING(chan, m2mf, - NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1); - OUT_RING (chan, (dy << 16) | (dx * cpp)); - } else { - dst_offset += (line_count * dst_pitch); - } - BEGIN_RING(chan, m2mf, - NV04_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4); - OUT_RING (chan, width * cpp); - OUT_RING (chan, line_count); - OUT_RING (chan, 0x00000101); - OUT_RING (chan, 0); - FIRE_RING (chan); - - height -= line_count; - sy += line_count; - dy += line_count; - } + struct nouveau_channel *chan = nouveau_screen(pscreen)->channel; + const int cpp = dst->cpp; + uint32_t src_ofst = src->base; + uint32_t dst_ofst = dst->base; + uint32_t height = nblocksy; + uint32_t sy = src->y; + uint32_t dy = dst->y; + + assert(dst->cpp == src->cpp); + + if (nouveau_bo_tile_layout(src->bo)) { + BEGIN_RING(chan, RING_MF(LINEAR_IN), 6); + OUT_RING (chan, 0); + OUT_RING (chan, src->tile_mode << 4); + OUT_RING (chan, src->width * cpp); + OUT_RING (chan, src->height); + OUT_RING (chan, src->depth); + OUT_RING (chan, src->z); + } else { + src_ofst += src->y * src->pitch + src->x * cpp; + + BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_IN), 1); + OUT_RING (chan, src->pitch); + } + + if (nouveau_bo_tile_layout(dst->bo)) { + BEGIN_RING(chan, RING_MF(LINEAR_OUT), 6); + OUT_RING (chan, 0); + OUT_RING (chan, dst->tile_mode << 4); + OUT_RING (chan, dst->width * cpp); + OUT_RING (chan, dst->height); + OUT_RING (chan, dst->depth); + OUT_RING (chan, dst->z); + } else { + dst_ofst += dst->y * dst->pitch + dst->x * cpp; + + BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_OUT), 1); + OUT_RING (chan, dst->pitch); + } + + while (height) { + int line_count = height > 2047 ? 2047 : height; + + MARK_RING (chan, 17, 4); + + BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2); + OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD); + OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR); + + BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2); + OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR); + + if (nouveau_bo_tile_layout(src->bo)) { + BEGIN_RING(chan, RING_MF(TILING_POSITION_IN), 1); + OUT_RING (chan, (sy << 16) | (src->x * cpp)); + } else { + src_ofst += line_count * src->pitch; + } + if (nouveau_bo_tile_layout(dst->bo)) { + BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT), 1); + OUT_RING (chan, (dy << 16) | (dst->x * cpp)); + } else { + dst_ofst += line_count * dst->pitch; + } + + BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4); + OUT_RING (chan, nblocksx * cpp); + OUT_RING (chan, line_count); + OUT_RING (chan, (1 << 8) | (1 << 0)); + OUT_RING (chan, 0); + + height -= line_count; + sy += line_count; + dy += line_count; + } } -struct pipe_transfer * -nv50_miptree_transfer_new(struct pipe_context *pcontext, - struct pipe_resource *pt, - unsigned level, - unsigned usage, - const struct pipe_box *box) +void +nv50_sifc_linear_u8(struct nouveau_context *nv, + struct nouveau_bo *dst, unsigned offset, unsigned domain, + unsigned size, void *data) { - struct pipe_screen *pscreen = pcontext->screen; - struct nouveau_device *dev = nouveau_screen(pscreen)->device; - struct nv50_miptree *mt = nv50_miptree(pt); - struct nv50_miptree_level *lvl = &mt->level[level]; - struct nv50_transfer *tx; - unsigned nx, ny, image = 0, boxz = 0; - int ret; - - /* XXX can't unify these here? */ - if (pt->target == PIPE_TEXTURE_CUBE) - image = box->z; - else if (pt->target == PIPE_TEXTURE_3D) - boxz = box->z; - - tx = CALLOC_STRUCT(nv50_transfer); - if (!tx) - return NULL; - - /* Don't handle 3D transfers yet. - */ - assert(box->depth == 1); - - - pipe_resource_reference(&tx->base.resource, pt); - tx->base.level = level; - tx->base.usage = usage; - tx->base.box = *box; - tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level)); - tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level)); - tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format); - tx->base.usage = usage; - - tx->level_pitch = lvl->pitch; - tx->level_width = u_minify(mt->base.base.width0, level); - tx->level_height = u_minify(mt->base.base.height0, level); - tx->level_depth = u_minify(mt->base.base.depth0, level); - tx->level_offset = lvl->image_offset[image]; - tx->level_tiling = lvl->tile_mode; - tx->level_z = boxz; - tx->level_x = util_format_get_nblocksx(pt->format, box->x); - tx->level_y = util_format_get_nblocksy(pt->format, box->y); - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, - tx->nblocksy * tx->base.stride, &tx->bo); - if (ret) { - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - nx = util_format_get_nblocksx(pt->format, box->width); - ny = util_format_get_nblocksy(pt->format, box->height); - - nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset, - tx->level_pitch, tx->level_tiling, - box->x, box->y, boxz, - tx->nblocksx, tx->nblocksy, - tx->level_depth, - tx->bo, 0, - tx->base.stride, tx->bo->tile_mode, - 0, 0, 0, - tx->nblocksx, tx->nblocksy, 1, - util_format_get_blocksize(pt->format), nx, ny, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, - NOUVEAU_BO_GART); - } - - return &tx->base; + struct nouveau_channel *chan = nv->screen->channel; + uint32_t *src = (uint32_t *)data; + unsigned count = (size + 3) / 4; + unsigned xcoord = offset & 0xff; + + offset &= ~0xff; + + MARK_RING (chan, 23, 4); + BEGIN_RING(chan, RING_2D(DST_FORMAT), 2); + OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_2D(DST_PITCH), 5); + OUT_RING (chan, 262144); + OUT_RING (chan, 65536); + OUT_RING (chan, 1); + OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR); + BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2); + OUT_RING (chan, 0); + OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); + BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10); + OUT_RING (chan, size); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, xcoord); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + + while (count) { + unsigned nr = AVAIL_RING(chan); + + if (nr < 9) { + FIRE_RING(chan); + nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR); + continue; + } + nr = MIN2(count, nr - 1); + nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); + + BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), nr); + OUT_RINGp (chan, src, nr); + + src += nr; + count -= nr; + } } void -nv50_miptree_transfer_del(struct pipe_context *pcontext, - struct pipe_transfer *ptx) +nv50_m2mf_copy_linear(struct nouveau_context *nv, + struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, + struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, + unsigned size) { - struct nv50_transfer *tx = (struct nv50_transfer *)ptx; - struct nv50_miptree *mt = nv50_miptree(ptx->resource); - struct pipe_resource *pt = ptx->resource; - - unsigned nx = util_format_get_nblocksx(pt->format, tx->base.box.width); - unsigned ny = util_format_get_nblocksy(pt->format, tx->base.box.height); - - if (ptx->usage & PIPE_TRANSFER_WRITE) { - struct pipe_screen *pscreen = pcontext->screen; - - nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, - tx->base.stride, tx->bo->tile_mode, - 0, 0, 0, - tx->nblocksx, tx->nblocksy, 1, - mt->base.bo, tx->level_offset, - tx->level_pitch, tx->level_tiling, - tx->level_x, tx->level_y, tx->level_z, - tx->nblocksx, tx->nblocksy, - tx->level_depth, - util_format_get_blocksize(pt->format), nx, ny, - NOUVEAU_BO_GART, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART); - } - - nouveau_bo_ref(NULL, &tx->bo); - pipe_resource_reference(&ptx->resource, NULL); - FREE(ptx); + struct nouveau_channel *chan = nv->screen->channel; + + BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1); + OUT_RING (chan, 1); + + while (size) { + unsigned bytes = MIN2(size, 1 << 17); + + MARK_RING (chan, 11, 4); + BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2); + OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD); + OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR); + BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2); + OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR); + BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4); + OUT_RING (chan, bytes); + OUT_RING (chan, 1); + OUT_RING (chan, (1 << 8) | (1 << 0)); + OUT_RING (chan, 0); + + srcoff += bytes; + dstoff += bytes; + size -= bytes; + } } -void * -nv50_miptree_transfer_map(struct pipe_context *pcontext, - struct pipe_transfer *ptx) +struct pipe_transfer * +nv50_miptree_transfer_new(struct pipe_context *pctx, + struct pipe_resource *res, + unsigned level, + unsigned usage, + const struct pipe_box *box) { - struct nv50_transfer *tx = (struct nv50_transfer *)ptx; - unsigned flags = 0; - int ret; - - if (tx->map_refcnt++) - return tx->bo->map; - - if (ptx->usage & PIPE_TRANSFER_WRITE) - flags |= NOUVEAU_BO_WR; - if (ptx->usage & PIPE_TRANSFER_READ) - flags |= NOUVEAU_BO_RD; - - ret = nouveau_bo_map(tx->bo, flags); - if (ret) { - tx->map_refcnt = 0; - return NULL; - } - return tx->bo->map; + struct nv50_context *nv50 = nv50_context(pctx); + struct pipe_screen *pscreen = pctx->screen; + struct nouveau_device *dev = nv50->screen->base.device; + struct nv50_miptree *mt = nv50_miptree(res); + struct nv50_miptree_level *lvl = &mt->level[level]; + struct nv50_transfer *tx; + uint32_t size; + uint32_t w, h, d, z, layer; + int ret; + + if (mt->layout_3d) { + z = box->z; + d = u_minify(res->depth0, level); + layer = 0; + } else { + z = 0; + d = 1; + layer = box->z; + } + + tx = CALLOC_STRUCT(nv50_transfer); + if (!tx) + return NULL; + + pipe_resource_reference(&tx->base.resource, res); + + tx->base.level = level; + tx->base.usage = usage; + tx->base.box = *box; + + tx->nblocksx = util_format_get_nblocksx(res->format, box->width); + tx->nblocksy = util_format_get_nblocksy(res->format, box->height); + + tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format); + tx->base.layer_stride = tx->nblocksy * tx->base.stride; + + w = u_minify(res->width0, level); + h = u_minify(res->height0, level); + + tx->rect[0].cpp = tx->rect[1].cpp = util_format_get_blocksize(res->format); + + tx->rect[0].bo = mt->base.bo; + tx->rect[0].base = lvl->offset + layer * mt->layer_stride; + tx->rect[0].tile_mode = lvl->tile_mode; + tx->rect[0].x = util_format_get_nblocksx(res->format, box->x); + tx->rect[0].y = util_format_get_nblocksy(res->format, box->y); + tx->rect[0].z = z; + tx->rect[0].width = util_format_get_nblocksx(res->format, w); + tx->rect[0].height = util_format_get_nblocksy(res->format, h); + tx->rect[0].depth = d; + tx->rect[0].pitch = lvl->pitch; + tx->rect[0].domain = NOUVEAU_BO_VRAM; + + size = tx->base.layer_stride; + + ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, + size * tx->base.box.depth, &tx->rect[1].bo); + if (ret) { + FREE(tx); + return NULL; + } + + tx->rect[1].width = tx->nblocksx; + tx->rect[1].height = tx->nblocksy; + tx->rect[1].depth = 1; + tx->rect[1].pitch = tx->base.stride; + tx->rect[1].domain = NOUVEAU_BO_GART; + + if (usage & PIPE_TRANSFER_READ) { + unsigned base = tx->rect[0].base; + unsigned i; + for (i = 0; i < box->depth; ++i) { + nv50_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0], + tx->nblocksx, tx->nblocksy); + if (mt->layout_3d) + tx->rect[0].z++; + else + tx->rect[0].base += mt->layer_stride; + tx->rect[1].base += size; + } + tx->rect[0].z = z; + tx->rect[0].base = base; + tx->rect[1].base = 0; + } + + return &tx->base; } void -nv50_miptree_transfer_unmap(struct pipe_context *pcontext, - struct pipe_transfer *ptx) +nv50_miptree_transfer_del(struct pipe_context *pctx, + struct pipe_transfer *transfer) { - struct nv50_transfer *tx = (struct nv50_transfer *)ptx; - - if (--tx->map_refcnt) - return; - nouveau_bo_unmap(tx->bo); + struct pipe_screen *pscreen = pctx->screen; + struct nv50_transfer *tx = (struct nv50_transfer *)transfer; + struct nv50_miptree *mt = nv50_miptree(tx->base.resource); + unsigned i; + + if (tx->base.usage & PIPE_TRANSFER_WRITE) { + for (i = 0; i < tx->base.box.depth; ++i) { + nv50_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1], + tx->nblocksx, tx->nblocksy); + if (mt->layout_3d) + tx->rect[0].z++; + else + tx->rect[0].base += mt->layer_stride; + tx->rect[1].base += tx->nblocksy * tx->base.stride; + } + } + + nouveau_bo_ref(NULL, &tx->rect[1].bo); + pipe_resource_reference(&transfer->resource, NULL); + + FREE(tx); } +void * +nv50_miptree_transfer_map(struct pipe_context *pctx, + struct pipe_transfer *transfer) +{ + struct nv50_transfer *tx = (struct nv50_transfer *)transfer; + int ret; + unsigned flags = 0; + + if (tx->rect[1].bo->map) + return tx->rect[1].bo->map; + + if (transfer->usage & PIPE_TRANSFER_READ) + flags = NOUVEAU_BO_RD; + if (transfer->usage & PIPE_TRANSFER_WRITE) + flags |= NOUVEAU_BO_WR; + + ret = nouveau_bo_map(tx->rect[1].bo, flags); + if (ret) + return NULL; + return tx->rect[1].bo->map; +} void -nv50_upload_sifc(struct nv50_context *nv50, - struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc, - unsigned dst_format, int dst_w, int dst_h, int dst_pitch, - void *src, unsigned src_format, int src_pitch, - int x, int y, int w, int h, int cpp) +nv50_miptree_transfer_unmap(struct pipe_context *pctx, + struct pipe_transfer *transfer) { - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *eng2d = nv50->screen->eng2d; - unsigned line_dwords = (w * cpp + 3) / 4; - - reloc |= NOUVEAU_BO_WR; - - MARK_RING (chan, 32, 2); /* flush on lack of space or relocs */ - - if (nouveau_bo_tile_layout(bo)) { - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5); - OUT_RING (chan, dst_format); - OUT_RING (chan, 0); - OUT_RING (chan, bo->tile_mode << 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - } else { - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); - OUT_RING (chan, dst_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 1); - OUT_RING (chan, dst_pitch); - } - - BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 4); - OUT_RING (chan, dst_w); - OUT_RING (chan, dst_h); - OUT_RELOCh(chan, bo, dst_offset, reloc); - OUT_RELOCl(chan, bo, dst_offset, reloc); - - /* NV50_2D_OPERATION_SRCCOPY assumed already set */ - - BEGIN_RING(chan, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, src_format); - BEGIN_RING(chan, eng2d, NV50_2D_SIFC_WIDTH, 10); - OUT_RING (chan, w); - OUT_RING (chan, h); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, x); - OUT_RING (chan, 0); - OUT_RING (chan, y); - - while (h--) { - const uint32_t *p = src; - unsigned count = line_dwords; - - while (count) { - unsigned nr = MIN2(count, 1792); - - if (AVAIL_RING(chan) <= nr) { - FIRE_RING (chan); - - BEGIN_RING(chan, eng2d, - NV50_2D_DST_ADDRESS_HIGH, 2); - OUT_RELOCh(chan, bo, dst_offset, reloc); - OUT_RELOCl(chan, bo, dst_offset, reloc); - } - assert(AVAIL_RING(chan) > nr); - - BEGIN_RING(chan, eng2d, - NV50_2D_SIFC_DATA | (2 << 29), nr); - OUT_RINGp (chan, p, nr); - - p += nr; - count -= nr; - } - - src = (uint8_t *) src + src_pitch; - } + struct nv50_transfer *tx = (struct nv50_transfer *)transfer; + + nouveau_bo_unmap(tx->rect[1].bo); } + diff --git a/src/gallium/drivers/nv50/nv50_transfer.h b/src/gallium/drivers/nv50/nv50_transfer.h index 6699bf546ea..d3259ef4a5d 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.h +++ b/src/gallium/drivers/nv50/nv50_transfer.h @@ -1,31 +1,38 @@ -#ifndef NV50_TRANSFER_H -#define NV50_TRANSFER_H +#ifndef __NV50_TRANSFER_H__ +#define __NV50_TRANSFER_H__ #include "pipe/p_state.h" - struct pipe_transfer * nv50_miptree_transfer_new(struct pipe_context *pcontext, - struct pipe_resource *pt, - unsigned level, - unsigned usage, - const struct pipe_box *box); + struct pipe_resource *pt, + unsigned level, + unsigned usage, + const struct pipe_box *box); void nv50_miptree_transfer_del(struct pipe_context *pcontext, - struct pipe_transfer *ptx); + struct pipe_transfer *ptx); void * nv50_miptree_transfer_map(struct pipe_context *pcontext, - struct pipe_transfer *ptx); + struct pipe_transfer *ptx); void nv50_miptree_transfer_unmap(struct pipe_context *pcontext, - struct pipe_transfer *ptx); + struct pipe_transfer *ptx); -extern void -nv50_upload_sifc(struct nv50_context *nv50, - struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc, - unsigned dst_format, int dst_w, int dst_h, int dst_pitch, - void *src, unsigned src_format, int src_pitch, - int x, int y, int w, int h, int cpp); +struct nv50_m2mf_rect { + struct nouveau_bo *bo; + uint32_t base; + unsigned domain; + uint32_t pitch; + uint32_t width; + uint32_t x; + uint32_t height; + uint32_t y; + uint16_t depth; + uint16_t z; + uint16_t tile_mode; + uint16_t cpp; +}; #endif diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 53f319acf46..4f0a5018459 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Ben Skeggs + * Copyright 2010 Christoph Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -24,540 +24,696 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" #include "util/u_format.h" -#include "util/u_split_prim.h" +#include "translate/translate.h" #include "nv50_context.h" #include "nv50_resource.h" -struct instance { - struct nouveau_bo *bo; - unsigned delta; - unsigned stride; - unsigned step; - unsigned divisor; -}; +#include "nv50_3d.xml.h" -static void -instance_init(struct nv50_context *nv50, struct instance *a, unsigned first) +void +nv50_vertex_state_delete(struct pipe_context *pipe, + void *hwcso) { - int i; - - for (i = 0; i < nv50->vtxelt->num_elements; i++) { - struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; - struct pipe_vertex_buffer *vb; - - a[i].divisor = ve->instance_divisor; - if (a[i].divisor) { - vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - - a[i].bo = nv50_resource(vb->buffer)->bo; - a[i].stride = vb->stride; - a[i].step = first % a[i].divisor; - a[i].delta = vb->buffer_offset + ve->src_offset + - (first * a[i].stride); - } - } + struct nv50_vertex_stateobj *so = hwcso; + + if (so->translate) + so->translate->release(so->translate); + FREE(hwcso); } -static void -instance_step(struct nv50_context *nv50, struct instance *a) +void * +nv50_vertex_state_create(struct pipe_context *pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) { - struct nouveau_channel *chan = nv50->screen->tesla->channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - int i; - - for (i = 0; i < nv50->vtxelt->num_elements; i++) { - if (!a[i].divisor) - continue; - - BEGIN_RING(chan, tesla, - NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2); - OUT_RELOCh(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD | - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART); - OUT_RELOCl(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD | - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART); - if (++a[i].step == a[i].divisor) { - a[i].step = 0; - a[i].delta += a[i].stride; - } - } + struct nv50_vertex_stateobj *so; + struct translate_key transkey; + unsigned i; + + assert(num_elements); + + so = MALLOC(sizeof(*so) + + (num_elements - 1) * sizeof(struct nv50_vertex_element)); + if (!so) + return NULL; + so->num_elements = num_elements; + so->instance_elts = 0; + so->instance_bufs = 0; + so->need_conversion = FALSE; + + transkey.nr_elements = 0; + transkey.output_stride = 0; + + for (i = 0; i < num_elements; ++i) { + const struct pipe_vertex_element *ve = &elements[i]; + const unsigned vbi = ve->vertex_buffer_index; + enum pipe_format fmt = ve->src_format; + + so->element[i].pipe = elements[i]; + so->element[i].state = nv50_format_table[fmt].vtx; + + if (!so->element[i].state) { + switch (util_format_get_nr_components(fmt)) { + case 1: fmt = PIPE_FORMAT_R32_FLOAT; break; + case 2: fmt = PIPE_FORMAT_R32G32_FLOAT; break; + case 3: fmt = PIPE_FORMAT_R32G32B32_FLOAT; break; + case 4: fmt = PIPE_FORMAT_R32G32B32A32_FLOAT; break; + default: + assert(0); + return NULL; + } + so->element[i].state = nv50_format_table[fmt].vtx; + so->need_conversion = TRUE; + } + so->element[i].state |= i; + + if (1) { + unsigned j = transkey.nr_elements++; + + transkey.element[j].type = TRANSLATE_ELEMENT_NORMAL; + transkey.element[j].input_format = ve->src_format; + transkey.element[j].input_buffer = vbi; + transkey.element[j].input_offset = ve->src_offset; + transkey.element[j].instance_divisor = ve->instance_divisor; + + transkey.element[j].output_format = fmt; + transkey.element[j].output_offset = transkey.output_stride; + transkey.output_stride += (util_format_get_stride(fmt, 1) + 3) & ~3; + + if (unlikely(ve->instance_divisor)) { + so->instance_elts |= 1 << i; + so->instance_bufs |= 1 << vbi; + } + } + } + + so->translate = translate_create(&transkey); + so->vertex_size = transkey.output_stride / 4; + so->packet_vertex_limit = NV04_PFIFO_MAX_PACKET_LEN / + MAX2(so->vertex_size, 1); + + return so; } +#define NV50_3D_VERTEX_ATTRIB_INACTIVE \ + NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT | \ + NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 | \ + NV50_3D_VERTEX_ARRAY_ATTRIB_CONST + static void -nv50_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, unsigned start, unsigned count, - unsigned startInstance, unsigned instanceCount) +nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, + struct pipe_vertex_element *ve, unsigned attr) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->tesla->channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct instance a[16]; - unsigned prim = nv50_prim(mode); - - instance_init(nv50, a, startInstance); - if (!nv50_state_validate(nv50, 10 + 16*3)) - return; - - if (nv50->vbo_fifo) { - nv50_push_elements_instanced(pipe, NULL, 0, 0, mode, start, - count, startInstance, - instanceCount); - return; - } - - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); - OUT_RING (chan, NV50_CB_AUX | (24 << 8)); - OUT_RING (chan, startInstance); - while (instanceCount--) { - if (AVAIL_RING(chan) < (7 + 16*3)) { - FIRE_RING(chan); - if (!nv50_state_validate(nv50, 7 + 16*3)) { - assert(0); - return; - } - } - instance_step(nv50, a); - - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); - OUT_RING (chan, prim); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); - OUT_RING (chan, start); - OUT_RING (chan, count); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); - OUT_RING (chan, 0); - - prim |= (1 << 28); - } + const void *data; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv04_resource *res = nv04_resource(vb->buffer); + float v[4]; + const unsigned nc = util_format_get_nr_components(ve->src_format); + + data = nouveau_resource_map_offset(&nv50->base, res, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_RD); + + util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); + + switch (nc) { + case 4: + BEGIN_RING(chan, RING_3D(VTX_ATTR_4F_X(attr)), 4); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + OUT_RINGf (chan, v[2]); + OUT_RINGf (chan, v[3]); + break; + case 3: + BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(attr)), 3); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + OUT_RINGf (chan, v[2]); + break; + case 2: + BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(attr)), 2); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + break; + case 1: + if (attr == nv50->vertprog->vp.edgeflag) { + BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); + OUT_RING (chan, v[0] ? 1 : 0); + } + BEGIN_RING(chan, RING_3D(VTX_ATTR_1F(attr)), 1); + OUT_RINGf (chan, v[0]); + break; + default: + assert(0); + break; + } } -struct inline_ctx { - struct nv50_context *nv50; - void *map; -}; +static INLINE void +nv50_vbuf_range(struct nv50_context *nv50, int vbi, + uint32_t *base, uint32_t *size) +{ + if (unlikely(nv50->vertex->instance_bufs & (1 << vbi))) { + /* TODO: use min and max instance divisor to get a proper range */ + *base = 0; + *size = nv50->vtxbuf[vbi].buffer->width0; + } else { + assert(nv50->vbo_max_index != ~0); + *base = nv50->vbo_min_index * nv50->vtxbuf[vbi].stride; + *size = (nv50->vbo_max_index - + nv50->vbo_min_index + 1) * nv50->vtxbuf[vbi].stride; + } +} static void -inline_elt08(void *priv, unsigned start, unsigned count) +nv50_prevalidate_vbufs(struct nv50_context *nv50) { - struct inline_ctx *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; - uint8_t *map = (uint8_t *)ctx->map + start; - - if (count & 1) { - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, map[0]); - map++; - count &= ~1; - } - - count >>= 1; - if (!count) - return; - - BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count); - while (count--) { - OUT_RING(chan, (map[1] << 16) | map[0]); - map += 2; - } + struct pipe_vertex_buffer *vb; + struct nv04_resource *buf; + int i; + uint32_t base, size; + + nv50->vbo_fifo = nv50->vbo_user = 0; + + nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX); + + for (i = 0; i < nv50->num_vtxbufs; ++i) { + vb = &nv50->vtxbuf[i]; + if (!vb->stride) + continue; + buf = nv04_resource(vb->buffer); + + /* NOTE: user buffers with temporary storage count as mapped by GPU */ + if (!nouveau_resource_mapped_by_gpu(vb->buffer)) { + if (nv50->vbo_push_hint) { + nv50->vbo_fifo = ~0; + continue; + } else { + if (buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY) { + nv50->vbo_user |= 1 << i; + assert(vb->stride > vb->buffer_offset); + nv50_vbuf_range(nv50, i, &base, &size); + nouveau_user_buffer_upload(buf, base, size); + } else { + nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART); + } + nv50->base.vbo_dirty = TRUE; + } + } + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); + nouveau_buffer_adjust_score(&nv50->base, buf, 1); + } } static void -inline_elt16(void *priv, unsigned start, unsigned count) +nv50_update_user_vbufs(struct nv50_context *nv50) { - struct inline_ctx *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; - uint16_t *map = (uint16_t *)ctx->map + start; - - if (count & 1) { - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, map[0]); - count &= ~1; - map++; - } - - count >>= 1; - if (!count) - return; - - BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count); - while (count--) { - OUT_RING(chan, (map[1] << 16) | map[0]); - map += 2; - } + struct nouveau_channel *chan = nv50->screen->base.channel; + uint32_t base, offset, size; + int i; + uint32_t written = 0; + + for (i = 0; i < nv50->vertex->num_elements; ++i) { + struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe; + const int b = ve->vertex_buffer_index; + struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b]; + struct nv04_resource *buf = nv04_resource(vb->buffer); + + if (!(nv50->vbo_user & (1 << b))) + continue; + + if (!vb->stride) { + nv50_emit_vtxattr(nv50, vb, ve, i); + continue; + } + nv50_vbuf_range(nv50, b, &base, &size); + + if (!(written & (1 << b))) { + written |= 1 << b; + nouveau_user_buffer_upload(buf, base, size); + } + offset = vb->buffer_offset + ve->src_offset; + + MARK_RING (chan, 6, 4); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2); + OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD); + OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2); + OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); + OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); + } + nv50->base.vbo_dirty = TRUE; } -static void -inline_elt32(void *priv, unsigned start, unsigned count) +static INLINE void +nv50_release_user_vbufs(struct nv50_context *nv50) { - struct inline_ctx *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; + uint32_t vbo_user = nv50->vbo_user; - BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, count); - OUT_RINGp (chan, (uint32_t *)ctx->map + start, count); + while (vbo_user) { + int i = ffs(vbo_user) - 1; + vbo_user &= ~(1 << i); + + nouveau_buffer_release_gpu_storage(nv04_resource(nv50->vtxbuf[i].buffer)); + } } -static void -inline_edgeflag(void *priv, boolean enabled) +void +nv50_vertex_arrays_validate(struct nv50_context *nv50) { - struct inline_ctx *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_vertex_stateobj *vertex = nv50->vertex; + struct pipe_vertex_buffer *vb; + struct nv50_vertex_element *ve; + unsigned i; + + if (unlikely(vertex->need_conversion)) { + nv50->vbo_fifo = ~0; + nv50->vbo_user = 0; + } else { + nv50_prevalidate_vbufs(nv50); + } + + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements); + for (i = 0; i < vertex->num_elements; ++i) { + ve = &vertex->element[i]; + vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index]; + + if (likely(vb->stride) || nv50->vbo_fifo) { + OUT_RING(chan, ve->state); + } else { + OUT_RING(chan, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST); + nv50->vbo_fifo &= ~(1 << i); + } + } + + for (i = 0; i < vertex->num_elements; ++i) { + struct nv04_resource *res; + unsigned size, offset; + + ve = &vertex->element[i]; + vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index]; + + if (unlikely(ve->pipe.instance_divisor)) { + if (!(nv50->state.instance_elts & (1 << i))) { + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + OUT_RING (chan, 1); + } + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1); + OUT_RING (chan, ve->pipe.instance_divisor); + } else + if (unlikely(nv50->state.instance_elts & (1 << i))) { + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + OUT_RING (chan, 0); + } + + res = nv04_resource(vb->buffer); + + if (nv50->vbo_fifo || unlikely(vb->stride == 0)) { + if (!nv50->vbo_fifo) + nv50_emit_vtxattr(nv50, vb, &ve->pipe, i); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); + OUT_RING (chan, 0); + continue; + } + + size = vb->buffer->width0; + offset = ve->pipe.src_offset + vb->buffer_offset; + + MARK_RING (chan, 8, 4); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); + OUT_RING (chan, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2); + OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD); + OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2); + OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD); + OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD); + } + for (; i < nv50->state.num_vtxelts; ++i) { + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(i)), 1); + OUT_RING (chan, NV50_3D_VERTEX_ATTRIB_INACTIVE); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); + OUT_RING (chan, 0); + } + + nv50->state.num_vtxelts = vertex->num_elements; + nv50->state.instance_elts = vertex->instance_elts; +} + +#define NV50_PRIM_GL_CASE(n) \ + case PIPE_PRIM_##n: return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n - BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, enabled ? 1 : 0); +static INLINE unsigned +nv50_prim_gl(unsigned prim) +{ + switch (prim) { + NV50_PRIM_GL_CASE(POINTS); + NV50_PRIM_GL_CASE(LINES); + NV50_PRIM_GL_CASE(LINE_LOOP); + NV50_PRIM_GL_CASE(LINE_STRIP); + NV50_PRIM_GL_CASE(TRIANGLES); + NV50_PRIM_GL_CASE(TRIANGLE_STRIP); + NV50_PRIM_GL_CASE(TRIANGLE_FAN); + NV50_PRIM_GL_CASE(QUADS); + NV50_PRIM_GL_CASE(QUAD_STRIP); + NV50_PRIM_GL_CASE(POLYGON); + NV50_PRIM_GL_CASE(LINES_ADJACENCY); + NV50_PRIM_GL_CASE(LINE_STRIP_ADJACENCY); + NV50_PRIM_GL_CASE(TRIANGLES_ADJACENCY); + NV50_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY); + default: + return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS; + break; + } } static void -nv50_draw_elements_inline(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, unsigned indexSize, - unsigned mode, unsigned start, unsigned count, - unsigned startInstance, unsigned instanceCount) +nv50_draw_vbo_flush_notify(struct nouveau_channel *chan) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->tesla->channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct pipe_transfer *transfer; - struct instance a[16]; - struct inline_ctx ctx; - struct util_split_prim s; - boolean nzi = FALSE; - unsigned overhead; - - overhead = 16*3; /* potential instance adjustments */ - overhead += 4; /* Begin()/End() */ - overhead += 4; /* potential edgeflag disable/reenable */ - overhead += 3; /* potentially 3 VTX_ELT_U16/U32 packet headers */ - - s.priv = &ctx; - if (indexSize == 1) - s.emit = inline_elt08; - else - if (indexSize == 2) - s.emit = inline_elt16; - else - s.emit = inline_elt32; - s.edge = inline_edgeflag; - - ctx.nv50 = nv50; - ctx.map = pipe_buffer_map(pipe, indexBuffer, PIPE_TRANSFER_READ, &transfer); - assert(ctx.map); - if (!ctx.map) - return; - - instance_init(nv50, a, startInstance); - if (!nv50_state_validate(nv50, overhead + 6 + 3)) - return; - - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); - OUT_RING (chan, NV50_CB_AUX | (24 << 8)); - OUT_RING (chan, startInstance); - while (instanceCount--) { - unsigned max_verts; - boolean done; - - util_split_prim_init(&s, mode, start, count); - do { - if (AVAIL_RING(chan) < (overhead + 6)) { - FIRE_RING(chan); - if (!nv50_state_validate(nv50, (overhead + 6))) { - assert(0); - return; - } - } - - max_verts = AVAIL_RING(chan) - overhead; - if (max_verts > 2047) - max_verts = 2047; - if (indexSize != 4) - max_verts <<= 1; - instance_step(nv50, a); - - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); - OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1<<28) : 0)); - done = util_split_prim_next(&s, max_verts); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); - OUT_RING (chan, 0); - } while (!done); - - nzi = TRUE; - } - - pipe_buffer_unmap(pipe, transfer); + struct nv50_context *nv50 = chan->user_private; + + nouveau_fence_update(&nv50->screen->base, TRUE); + + nv50_bufctx_emit_relocs(nv50); } static void -nv50_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count, - unsigned startInstance, unsigned instanceCount) +nv50_draw_arrays(struct nv50_context *nv50, + unsigned mode, unsigned start, unsigned count, + unsigned instance_count) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->tesla->channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct instance a[16]; - unsigned prim = nv50_prim(mode); - - instance_init(nv50, a, startInstance); - if (!nv50_state_validate(nv50, 13 + 16*3)) - return; - - if (nv50->vbo_fifo) { - nv50_push_elements_instanced(pipe, indexBuffer, indexSize, - indexBias, mode, start, count, - startInstance, instanceCount); - return; - } - - /* indices are uint32 internally, so large indexBias means negative */ - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_BASE, 1); - OUT_RING (chan, indexBias); - - if (!nv50_resource_mapped_by_gpu(indexBuffer) || indexSize == 1) { - nv50_draw_elements_inline(pipe, indexBuffer, indexSize, - mode, start, count, startInstance, - instanceCount); - return; - } - - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); - OUT_RING (chan, NV50_CB_AUX | (24 << 8)); - OUT_RING (chan, startInstance); - while (instanceCount--) { - if (AVAIL_RING(chan) < (7 + 16*3)) { - FIRE_RING(chan); - if (!nv50_state_validate(nv50, 10 + 16*3)) { - assert(0); - return; - } - } - instance_step(nv50, a); - - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); - OUT_RING (chan, prim); - if (indexSize == 4) { - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0); - OUT_RING (chan, count); - nouveau_pushbuf_submit(chan, - nv50_resource(indexBuffer)->bo, - start << 2, count << 2); - } else - if (indexSize == 2) { - unsigned vb_start = (start & ~1); - unsigned vb_end = (start + count + 1) & ~1; - unsigned dwords = (vb_end - vb_start) >> 1; - - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1); - OUT_RING (chan, ((start & 1) << 31) | count); - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0); - OUT_RING (chan, dwords); - nouveau_pushbuf_submit(chan, - nv50_resource(indexBuffer)->bo, - vb_start << 1, dwords << 2); - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1); - OUT_RING (chan, 0); - } - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); - OUT_RING (chan, 0); - - prim |= (1 << 28); - } + struct nouveau_channel *chan = nv50->screen->base.channel; + unsigned prim; + + chan->flush_notify = nv50_draw_vbo_flush_notify; + chan->user_private = nv50; + + prim = nv50_prim_gl(mode); + + while (instance_count--) { + BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); + OUT_RING (chan, prim); + BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2); + OUT_RING (chan, start); + OUT_RING (chan, count); + BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); + OUT_RING (chan, 0); + + prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; + } + + chan->flush_notify = nv50_default_flush_notify; } -void -nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +static void +nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map, + unsigned start, unsigned count) { - struct nv50_context *nv50 = nv50_context(pipe); - - if (info->indexed && nv50->idxbuf.buffer) { - unsigned offset; - - assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0); - offset = nv50->idxbuf.offset / nv50->idxbuf.index_size; - - nv50_draw_elements_instanced(pipe, - nv50->idxbuf.buffer, - nv50->idxbuf.index_size, - info->index_bias, - info->mode, - info->start + offset, - info->count, - info->start_instance, - info->instance_count); - } - else { - nv50_draw_arrays_instanced(pipe, - info->mode, - info->start, - info->count, - info->start_instance, - info->instance_count); - } + map += start; + + if (count & 3) { + unsigned i; + BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3); + for (i = 0; i < (count & 3); ++i) + OUT_RING(chan, *map++); + count &= ~3; + } + while (count) { + unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4; + + BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr); + for (i = 0; i < nr; ++i) { + OUT_RING(chan, + (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]); + map += 4; + } + count -= nr * 4; + } } -static INLINE boolean -nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, - struct nouveau_stateobj **pso, - struct pipe_vertex_element *ve, - struct pipe_vertex_buffer *vb) - +static void +nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map, + unsigned start, unsigned count) { - struct nouveau_stateobj *so; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo; - float v[4]; - int ret; - unsigned nr_components = util_format_get_nr_components(ve->src_format); - - ret = nouveau_bo_map(bo, NOUVEAU_BO_RD); - if (ret) - return FALSE; - - util_format_read_4f(ve->src_format, v, 0, (uint8_t *)bo->map + - (vb->buffer_offset + ve->src_offset), 0, - 0, 0, 1, 1); - so = *pso; - if (!so) - *pso = so = so_new(nv50->vtxelt->num_elements, - nv50->vtxelt->num_elements * 4, 0); - - switch (nr_components) { - case 4: - so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4); - so_data (so, fui(v[0])); - so_data (so, fui(v[1])); - so_data (so, fui(v[2])); - so_data (so, fui(v[3])); - break; - case 3: - so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 3); - so_data (so, fui(v[0])); - so_data (so, fui(v[1])); - so_data (so, fui(v[2])); - break; - case 2: - so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 2); - so_data (so, fui(v[0])); - so_data (so, fui(v[1])); - break; - case 1: - if (attrib == nv50->vertprog->vp.edgeflag) { - so_method(so, tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - so_data (so, v[0] ? 1 : 0); - } - so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1); - so_data (so, fui(v[0])); - break; - default: - nouveau_bo_unmap(bo); - return FALSE; - } - - nouveau_bo_unmap(bo); - return TRUE; + map += start; + + if (count & 1) { + count &= ~1; + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (chan, *map++); + } + while (count) { + unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2; + + BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr); + for (i = 0; i < nr; ++i) { + OUT_RING(chan, (map[1] << 16) | map[0]); + map += 2; + } + count -= nr * 2; + } } -void -nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso) +static void +nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, + unsigned start, unsigned count) { - unsigned i; + map += start; + + while (count) { + const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN); - for (i = 0; i < cso->num_elements; ++i) - cso->hw[i] = nv50_format_table[cso->pipe[i].src_format].vtx; + BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr); + OUT_RINGp (chan, map, nr); + + map += nr; + count -= nr; + } } -struct nouveau_stateobj * -nv50_vbo_validate(struct nv50_context *nv50) +static void +nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map, + unsigned start, unsigned count) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *vtxbuf, *vtxfmt, *vtxattr; - unsigned i, n_ve; - - /* don't validate if Gallium took away our buffers */ - if (nv50->vtxbuf_nr == 0) - return NULL; - - nv50->vbo_fifo = 0; - if (nv50->screen->force_push || - nv50->vertprog->vp.edgeflag < 16) - nv50->vbo_fifo = 0xffff; - - for (i = 0; i < nv50->vtxbuf_nr; i++) { - if (nv50->vtxbuf[i].stride && - !nv50_resource_mapped_by_gpu(nv50->vtxbuf[i].buffer)) - nv50->vbo_fifo = 0xffff; - } - - n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr); - - vtxattr = NULL; - vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4); - vtxfmt = so_new(1, n_ve, 0); - so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve); - - for (i = 0; i < nv50->vtxelt->num_elements; i++) { - struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; - struct pipe_vertex_buffer *vb = - &nv50->vtxbuf[ve->vertex_buffer_index]; - struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo; - uint32_t hw = nv50->vtxelt->hw[i]; - - if (!vb->stride && - nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) { - so_data(vtxfmt, hw | (1 << 4)); - - so_method(vtxbuf, tesla, - NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); - so_data (vtxbuf, 0); - - nv50->vbo_fifo &= ~(1 << i); - continue; - } - - if (nv50->vbo_fifo) { - so_data (vtxfmt, hw | (ve->instance_divisor ? (1 << 4) : i)); - so_method(vtxbuf, tesla, - NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); - so_data (vtxbuf, 0); - continue; - } - - so_data(vtxfmt, hw | i); - - so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3); - so_data (vtxbuf, 0x20000000 | - (ve->instance_divisor ? 0 : vb->stride)); - so_reloc (vtxbuf, bo, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | - NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (vtxbuf, bo, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | - NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - - /* vertex array limits */ - so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2); - so_reloc (vtxbuf, bo, vb->buffer->width0 - 1, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, 0, 0); - so_reloc (vtxbuf, bo, vb->buffer->width0 - 1, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); - } - for (; i < n_ve; ++i) { - so_data (vtxfmt, 0x7e080010); - - so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); - so_data (vtxbuf, 0); - } - nv50->state.vtxelt_nr = nv50->vtxelt->num_elements; - - so_ref (vtxbuf, &nv50->state.vtxbuf); - so_ref (vtxattr, &nv50->state.vtxattr); - so_ref (NULL, &vtxbuf); - so_ref (NULL, &vtxattr); - return vtxfmt; + map += start; + + if (count & 1) { + count--; + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (chan, *map++); + } + while (count) { + unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2; + + BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr); + for (i = 0; i < nr; ++i) { + OUT_RING(chan, (map[1] << 16) | map[0]); + map += 2; + } + count -= nr * 2; + } } +static void +nv50_draw_elements(struct nv50_context *nv50, boolean shorten, + unsigned mode, unsigned start, unsigned count, + unsigned instance_count, int32_t index_bias) +{ + struct nouveau_channel *chan = nv50->screen->base.channel; + void *data; + unsigned prim; + const unsigned index_size = nv50->idxbuf.index_size; + + chan->flush_notify = nv50_draw_vbo_flush_notify; + chan->user_private = nv50; + + prim = nv50_prim_gl(mode); + + if (index_bias != nv50->state.index_bias) { + BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1); + OUT_RING (chan, index_bias); + nv50->state.index_bias = index_bias; + } + + if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) { + struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); + + start += nv50->idxbuf.offset >> (index_size >> 1); + + nouveau_buffer_adjust_score(&nv50->base, res, 1); + + while (instance_count--) { + BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); + OUT_RING (chan, mode); + + switch (index_size) { + case 4: + { + WAIT_RING (chan, 2); + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32) | 0x30000, 0); + OUT_RING (chan, count); + nouveau_pushbuf_submit(chan, res->bo, res->offset + start * 4, + count * 4); + } + break; + case 2: + { + unsigned pb_start = (start & ~1); + unsigned pb_words = (((start + count + 1) & ~1) - pb_start) >> 1; + + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1); + OUT_RING (chan, (start << 31) | count); + WAIT_RING (chan, 2); + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16) | 0x30000, 0); + OUT_RING (chan, pb_words); + nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start * 2, + pb_words * 4); + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1); + OUT_RING (chan, 0); + break; + } + case 1: + { + unsigned pb_start = (start & ~3); + unsigned pb_words = (((start + count + 3) & ~3) - pb_start) >> 1; + + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1); + OUT_RING (chan, (start << 30) | count); + WAIT_RING (chan, 2); + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8) | 0x30000, 0); + OUT_RING (chan, pb_words); + nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start, + pb_words * 4); + BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1); + OUT_RING (chan, 0); + break; + } + default: + assert(0); + return; + } + BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); + OUT_RING (chan, 0); + + nv50_resource_fence(res, NOUVEAU_BO_RD); + + mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; + } + } else { + data = nouveau_resource_map_offset(&nv50->base, + nv04_resource(nv50->idxbuf.buffer), + nv50->idxbuf.offset, NOUVEAU_BO_RD); + if (!data) + return; + + while (instance_count--) { + BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); + OUT_RING (chan, prim); + switch (index_size) { + case 1: + nv50_draw_elements_inline_u08(chan, data, start, count); + break; + case 2: + nv50_draw_elements_inline_u16(chan, data, start, count); + break; + case 4: + if (shorten) + nv50_draw_elements_inline_u32_short(chan, data, start, count); + else + nv50_draw_elements_inline_u32(chan, data, start, count); + break; + default: + assert(0); + return; + } + BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); + OUT_RING (chan, 0); + + prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; + } + } + + chan->flush_notify = nv50_default_flush_notify; +} +void +nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + + /* For picking only a few vertices from a large user buffer, push is better, + * if index count is larger and we expect repeated vertices, suggest upload. + */ + nv50->vbo_push_hint = /* the 64 is heuristic */ + !(info->indexed && + ((info->max_index - info->min_index + 64) < info->count)); + + nv50->vbo_min_index = info->min_index; + nv50->vbo_max_index = info->max_index; + + if (nv50->vbo_push_hint != !!nv50->vbo_fifo) + nv50->dirty |= NV50_NEW_ARRAYS; + + if (nv50->vbo_user && !(nv50->dirty & (NV50_NEW_VERTEX | NV50_NEW_ARRAYS))) + nv50_update_user_vbufs(nv50); + + nv50_state_validate(nv50); + + if (nv50->vbo_fifo) { + nv50_push_vbo(nv50, info); + return; + } + + if (nv50->state.instance_base != info->start_instance) { + nv50->state.instance_base = info->start_instance; + /* NOTE: this does not affect the shader input, should it ? */ + BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1); + OUT_RING (chan, info->start_instance); + } + + if (nv50->base.vbo_dirty) { + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); + OUT_RING (chan, 0); + nv50->base.vbo_dirty = FALSE; + } + + if (!info->indexed) { + nv50_draw_arrays(nv50, + info->mode, info->start, info->count, + info->instance_count); + } else { + boolean shorten = info->max_index <= 65535; + + assert(nv50->idxbuf.buffer); + + if (info->primitive_restart != nv50->state.prim_restart) { + if (info->primitive_restart) { + BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2); + OUT_RING (chan, 1); + OUT_RING (chan, info->restart_index); + + if (info->restart_index > 65535) + shorten = FALSE; + } else { + BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 1); + OUT_RING (chan, 0); + } + nv50->state.prim_restart = info->primitive_restart; + } else + if (info->primitive_restart) { + BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1); + OUT_RING (chan, info->restart_index); + + if (info->restart_index > 65535) + shorten = FALSE; + } + + nv50_draw_elements(nv50, shorten, + info->mode, info->start, info->count, + info->instance_count, info->index_bias); + } + + nv50_release_user_vbufs(nv50); +} diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h new file mode 100644 index 00000000000..afa2a00c7a2 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -0,0 +1,106 @@ + +#ifndef __NV50_WINSYS_H__ +#define __NV50_WINSYS_H__ + +#include <stdint.h> +#include <unistd.h> + +#include "pipe/p_defines.h" + +#include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_grobj.h" +#include "nouveau/nouveau_device.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" +#include "nouveau/nouveau_reloc.h" +#include "nouveau/nouveau_notifier.h" + +#include "nouveau/nouveau_buffer.h" + +#ifndef NV04_PFIFO_MAX_PACKET_LEN +#define NV04_PFIFO_MAX_PACKET_LEN 2047 +#endif + +#define NV50_SUBCH_3D 5 +#define NV50_SUBCH_2D 6 +#define NV50_SUBCH_MF 7 + +#define NV50_MF_(n) NV50_M2MF_##n + +#define RING_3D(n) ((NV50_SUBCH_3D << 13) | NV50_3D_##n) +#define RING_2D(n) ((NV50_SUBCH_2D << 13) | NV50_2D_##n) +#define RING_MF(n) ((NV50_SUBCH_MF << 13) | NV50_MF_(n)) + +#define RING_3D_(m) ((NV50_SUBCH_3D << 13) | (m)) +#define RING_2D_(m) ((NV50_SUBCH_2D << 13) | (m)) +#define RING_MF_(m) ((NV50_SUBCH_MF << 13) | (m)) + +#define RING_GR(gr, m) (((gr)->subc << 13) | (m)) + +int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); + +static inline uint32_t +nouveau_bo_tile_layout(struct nouveau_bo *bo) +{ + return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK; +} + +static INLINE void +nouveau_bo_validate(struct nouveau_channel *chan, + struct nouveau_bo *bo, unsigned flags) +{ + nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0); +} + +/* incremental methods */ +static INLINE void +BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size) +{ + WAIT_RING(chan, size + 1); + OUT_RING (chan, (size << 18) | mthd); +} + +/* non-incremental */ +static INLINE void +BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size) +{ + WAIT_RING(chan, size + 1); + OUT_RING (chan, (0x2 << 29) | (size << 18) | mthd); +} + +static INLINE int +OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res, + unsigned delta, unsigned flags) +{ + return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags); +} + +static INLINE int +OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, + unsigned delta, unsigned flags) +{ + if (flags & NOUVEAU_BO_WR) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); +} + +static INLINE void +BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s) +{ + struct nouveau_subchannel *subc = &gr->channel->subc[s]; + + assert(s < 8); + if (subc->gr) { + assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT); + subc->gr->bound = NOUVEAU_GROBJ_UNBOUND; + } + subc->gr = gr; + subc->gr->subc = s; + subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; + + BEGIN_RING(chan, RING_GR(gr, 0x0000), 1); + OUT_RING (chan, gr->handle); +} + +#endif diff --git a/src/gallium/drivers/nvc0/Makefile b/src/gallium/drivers/nvc0/Makefile index 54f1ab7fa93..e1cd188eec5 100644 --- a/src/gallium/drivers/nvc0/Makefile +++ b/src/gallium/drivers/nvc0/Makefile @@ -4,7 +4,6 @@ include $(TOP)/configs/current LIBNAME = nvc0 C_SOURCES = \ - nvc0_buffer.c \ nvc0_context.c \ nvc0_draw.c \ nvc0_formats.c \ @@ -27,8 +26,6 @@ C_SOURCES = \ nvc0_pc_regalloc.c \ nvc0_push.c \ nvc0_push2.c \ - nvc0_fence.c \ - nvc0_mm.c \ nvc0_query.c LIBRARY_INCLUDES = \ diff --git a/src/gallium/drivers/nvc0/nvc0_buffer.c b/src/gallium/drivers/nvc0/nvc0_buffer.c deleted file mode 100644 index aa949bdfa36..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_buffer.c +++ /dev/null @@ -1,494 +0,0 @@ - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#define NOUVEAU_NVC0 -#include "nouveau/nouveau_screen.h" -#include "nouveau/nouveau_winsys.h" -#undef NOUVEAU_NVC0 - -#include "nvc0_context.h" -#include "nvc0_resource.h" - -struct nvc0_transfer { - struct pipe_transfer base; -}; - -static INLINE struct nvc0_transfer * -nvc0_transfer(struct pipe_transfer *transfer) -{ - return (struct nvc0_transfer *)transfer; -} - -static INLINE boolean -nvc0_buffer_allocate(struct nvc0_screen *screen, struct nvc0_resource *buf, - unsigned domain) -{ - if (domain == NOUVEAU_BO_VRAM) { - buf->mm = nvc0_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo, - &buf->offset); - if (!buf->bo) - return nvc0_buffer_allocate(screen, buf, NOUVEAU_BO_GART); - } else - if (domain == NOUVEAU_BO_GART) { - buf->mm = nvc0_mm_allocate(screen->mm_GART, buf->base.width0, &buf->bo, - &buf->offset); - if (!buf->bo) - return FALSE; - } - if (domain != NOUVEAU_BO_GART) { - if (!buf->data) { - buf->data = MALLOC(buf->base.width0); - if (!buf->data) - return FALSE; - } - } - buf->domain = domain; - return TRUE; -} - -static INLINE void -release_allocation(struct nvc0_mm_allocation **mm, struct nvc0_fence *fence) -{ - if (fence && fence->state != NVC0_FENCE_STATE_SIGNALLED) { - nvc0_fence_sched_release(fence, *mm); - } else { - nvc0_mm_free(*mm); - } - (*mm) = NULL; -} - -INLINE void -nvc0_buffer_release_gpu_storage(struct nvc0_resource *buf) -{ - nouveau_bo_ref(NULL, &buf->bo); - - if (buf->mm) - release_allocation(&buf->mm, buf->fence); - - buf->domain = 0; -} - -static INLINE boolean -nvc0_buffer_reallocate(struct nvc0_screen *screen, struct nvc0_resource *buf, - unsigned domain) -{ - nvc0_buffer_release_gpu_storage(buf); - - return nvc0_buffer_allocate(screen, buf, domain); -} - -static void -nvc0_buffer_destroy(struct pipe_screen *pscreen, - struct pipe_resource *presource) -{ - struct nvc0_resource *res = nvc0_resource(presource); - - nvc0_buffer_release_gpu_storage(res); - - if (res->data && !(res->status & NVC0_BUFFER_STATUS_USER_MEMORY)) - FREE(res->data); - - FREE(res); -} - -/* Maybe just migrate to GART right away if we actually need to do this. */ -boolean -nvc0_buffer_download(struct nvc0_context *nvc0, struct nvc0_resource *buf, - unsigned start, unsigned size) -{ - struct nvc0_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - assert(buf->domain == NOUVEAU_BO_VRAM); - - mm = nvc0_mm_allocate(nvc0->screen->mm_GART, size, &bounce, &offset); - if (!bounce) - return FALSE; - - nvc0_m2mf_copy_linear(nvc0, bounce, offset, NOUVEAU_BO_GART, - buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, - size); - - if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD)) - return FALSE; - memcpy(buf->data + start, bounce->map, size); - nouveau_bo_unmap(bounce); - - buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING; - - nouveau_bo_ref(NULL, &bounce); - if (mm) - nvc0_mm_free(mm); - return TRUE; -} - -static boolean -nvc0_buffer_upload(struct nvc0_context *nvc0, struct nvc0_resource *buf, - unsigned start, unsigned size) -{ - struct nvc0_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - if (size <= 192) { - nvc0_m2mf_push_linear(nvc0, buf->bo, buf->domain, buf->offset + start, - size, buf->data + start); - return TRUE; - } - - mm = nvc0_mm_allocate(nvc0->screen->mm_GART, size, &bounce, &offset); - if (!bounce) - return FALSE; - - nouveau_bo_map_range(bounce, offset, size, - NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); - memcpy(bounce->map, buf->data + start, size); - nouveau_bo_unmap(bounce); - - nvc0_m2mf_copy_linear(nvc0, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, - bounce, offset, NOUVEAU_BO_GART, size); - - nouveau_bo_ref(NULL, &bounce); - if (mm) - release_allocation(&mm, nvc0->screen->fence.current); - - if (start == 0 && size == buf->base.width0) - buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING; - return TRUE; -} - -static struct pipe_transfer * -nvc0_buffer_transfer_get(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box) -{ - struct nvc0_resource *buf = nvc0_resource(resource); - struct nvc0_transfer *xfr = CALLOC_STRUCT(nvc0_transfer); - if (!xfr) - return NULL; - - xfr->base.resource = resource; - xfr->base.box.x = box->x; - xfr->base.box.width = box->width; - xfr->base.usage = usage; - - if (buf->domain == NOUVEAU_BO_VRAM) { - if (usage & PIPE_TRANSFER_READ) { - if (buf->status & NVC0_BUFFER_STATUS_GPU_WRITING) - nvc0_buffer_download(nvc0_context(pipe), buf, 0, buf->base.width0); - } - } - - return &xfr->base; -} - -static void -nvc0_buffer_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct nvc0_resource *buf = nvc0_resource(transfer->resource); - struct nvc0_transfer *xfr = nvc0_transfer(transfer); - - if (xfr->base.usage & PIPE_TRANSFER_WRITE) { - /* writing is worse */ - nvc0_buffer_adjust_score(nvc0_context(pipe), buf, -5000); - - if (buf->domain == NOUVEAU_BO_VRAM) { - nvc0_buffer_upload(nvc0_context(pipe), buf, - transfer->box.x, transfer->box.width); - } - - if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | - PIPE_BIND_INDEX_BUFFER))) - nvc0_context(pipe)->vbo_dirty = TRUE; - } - - FREE(xfr); -} - -static INLINE boolean -nvc0_buffer_sync(struct nvc0_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) { - if (!buf->fence_wr) - return TRUE; - if (!nvc0_fence_wait(buf->fence_wr)) - return FALSE; - } else { - if (!buf->fence) - return TRUE; - if (!nvc0_fence_wait(buf->fence)) - return FALSE; - - nvc0_fence_reference(&buf->fence, NULL); - } - nvc0_fence_reference(&buf->fence_wr, NULL); - - return TRUE; -} - -static INLINE boolean -nvc0_buffer_busy(struct nvc0_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) - return (buf->fence_wr && !nvc0_fence_signalled(buf->fence_wr)); - else - return (buf->fence && !nvc0_fence_signalled(buf->fence)); -} - -static void * -nvc0_buffer_transfer_map(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct nvc0_transfer *xfr = nvc0_transfer(transfer); - struct nvc0_resource *buf = nvc0_resource(transfer->resource); - struct nouveau_bo *bo = buf->bo; - uint8_t *map; - int ret; - uint32_t offset = xfr->base.box.x; - uint32_t flags; - - nvc0_buffer_adjust_score(nvc0_context(pipe), buf, -250); - - if (buf->domain != NOUVEAU_BO_GART) - return buf->data + offset; - - if (buf->mm) - flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR; - else - flags = nouveau_screen_transfer_flags(xfr->base.usage); - - offset += buf->offset; - - ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags); - if (ret) - return NULL; - map = bo->map; - - /* Unmap right now. Since multiple buffers can share a single nouveau_bo, - * not doing so might make future maps fail or trigger "reloc while mapped" - * errors. For now, mappings to userspace are guaranteed to be persistent. - */ - nouveau_bo_unmap(bo); - - if (buf->mm) { - if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) { - if (nvc0_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE)) - return NULL; - } else - if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { - nvc0_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE); - } - } - return map; -} - - - -static void -nvc0_buffer_transfer_flush_region(struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct nvc0_resource *res = nvc0_resource(transfer->resource); - struct nouveau_bo *bo = res->bo; - unsigned offset = res->offset + transfer->box.x + box->x; - - /* not using non-snoop system memory yet, no need for cflush */ - if (1) - return; - - /* XXX: maybe need to upload for VRAM buffers here */ - - nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width); -} - -static void -nvc0_buffer_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - /* we've called nouveau_bo_unmap right after map */ -} - -const struct u_resource_vtbl nvc0_buffer_vtbl = -{ - u_default_resource_get_handle, /* get_handle */ - nvc0_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - nvc0_buffer_transfer_get, /* get_transfer */ - nvc0_buffer_transfer_destroy, /* transfer_destroy */ - nvc0_buffer_transfer_map, /* transfer_map */ - nvc0_buffer_transfer_flush_region, /* transfer_flush_region */ - nvc0_buffer_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ -}; - -struct pipe_resource * -nvc0_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ) -{ - struct nvc0_screen *screen = nvc0_screen(pscreen); - struct nvc0_resource *buffer; - boolean ret; - - buffer = CALLOC_STRUCT(nvc0_resource); - if (!buffer) - return NULL; - - buffer->base = *templ; - buffer->vtbl = &nvc0_buffer_vtbl; - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = pscreen; - - if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) - ret = nvc0_buffer_allocate(screen, buffer, 0); - else - ret = nvc0_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); - - if (ret == FALSE) - goto fail; - - return &buffer->base; - -fail: - FREE(buffer); - return NULL; -} - - -struct pipe_resource * -nvc0_user_buffer_create(struct pipe_screen *pscreen, - void *ptr, - unsigned bytes, - unsigned bind) -{ - struct nvc0_resource *buffer; - - buffer = CALLOC_STRUCT(nvc0_resource); - if (!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->vtbl = &nvc0_buffer_vtbl; - buffer->base.screen = pscreen; - buffer->base.format = PIPE_FORMAT_R8_UNORM; - buffer->base.usage = PIPE_USAGE_IMMUTABLE; - buffer->base.bind = bind; - buffer->base.width0 = bytes; - buffer->base.height0 = 1; - buffer->base.depth0 = 1; - - buffer->data = ptr; - buffer->status = NVC0_BUFFER_STATUS_USER_MEMORY; - - return &buffer->base; -} - -/* Like download, but for GART buffers. Merge ? */ -static INLINE boolean -nvc0_buffer_data_fetch(struct nvc0_resource *buf, - struct nouveau_bo *bo, unsigned offset, unsigned size) -{ - if (!buf->data) { - buf->data = MALLOC(size); - if (!buf->data) - return FALSE; - } - if (nouveau_bo_map_range(bo, offset, size, NOUVEAU_BO_RD)) - return FALSE; - memcpy(buf->data, bo->map, size); - nouveau_bo_unmap(bo); - - return TRUE; -} - -/* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */ -boolean -nvc0_buffer_migrate(struct nvc0_context *nvc0, - struct nvc0_resource *buf, const unsigned new_domain) -{ - struct nvc0_screen *screen = nvc0_screen(buf->base.screen); - struct nouveau_bo *bo; - const unsigned old_domain = buf->domain; - unsigned size = buf->base.width0; - unsigned offset; - int ret; - - assert(new_domain != old_domain); - - if (new_domain == NOUVEAU_BO_GART && old_domain == 0) { - if (!nvc0_buffer_allocate(screen, buf, new_domain)) - return FALSE; - ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR | - NOUVEAU_BO_NOSYNC); - if (ret) - return ret; - memcpy(buf->bo->map, buf->data, size); - nouveau_bo_unmap(buf->bo); - FREE(buf->data); - } else - if (old_domain != 0 && new_domain != 0) { - struct nvc0_mm_allocation *mm = buf->mm; - - if (new_domain == NOUVEAU_BO_VRAM) { - /* keep a system memory copy of our data in case we hit a fallback */ - if (!nvc0_buffer_data_fetch(buf, buf->bo, buf->offset, size)) - return FALSE; - debug_printf("migrating %u KiB to VRAM\n", size / 1024); - } - - offset = buf->offset; - bo = buf->bo; - buf->bo = NULL; - buf->mm = NULL; - nvc0_buffer_allocate(screen, buf, new_domain); - - nvc0_m2mf_copy_linear(nvc0, buf->bo, buf->offset, new_domain, - bo, offset, old_domain, buf->base.width0); - - nouveau_bo_ref(NULL, &bo); - if (mm) - release_allocation(&mm, screen->fence.current); - } else - if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { - if (!nvc0_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) - return FALSE; - if (!nvc0_buffer_upload(nvc0, buf, 0, buf->base.width0)) - return FALSE; - } else - return FALSE; - - assert(buf->domain == new_domain); - return TRUE; -} - -/* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART. - * We'd like to only allocate @size bytes here, but then we'd have to rebase - * the vertex indices ... - */ -boolean -nvc0_user_buffer_upload(struct nvc0_resource *buf, unsigned base, unsigned size) -{ - struct nvc0_screen *screen = nvc0_screen(buf->base.screen); - int ret; - - assert(buf->status & NVC0_BUFFER_STATUS_USER_MEMORY); - - buf->base.width0 = base + size; - if (!nvc0_buffer_reallocate(screen, buf, NOUVEAU_BO_GART)) - return FALSE; - - ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size, - NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); - if (ret) - return FALSE; - memcpy(buf->bo->map, buf->data + base, size); - nouveau_bo_unmap(buf->bo); - - return TRUE; -} diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index f02de4d044a..d6de979b132 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -48,8 +48,8 @@ nvc0_flush(struct pipe_context *pipe, unsigned flags, } if (fence) - nvc0_fence_reference((struct nvc0_fence **)fence, - nvc0->screen->fence.current); + nouveau_fence_ref(nvc0->screen->base.fence.current, + (struct nouveau_fence **)fence); if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME)) FIRE_RING(chan); @@ -62,8 +62,10 @@ nvc0_destroy(struct pipe_context *pipe) draw_destroy(nvc0->draw); - if (nvc0->screen->cur_ctx == nvc0) + if (nvc0->screen->cur_ctx == nvc0) { + nvc0->screen->base.channel->user_private = NULL; nvc0->screen->cur_ctx = NULL; + } FREE(nvc0); } @@ -73,9 +75,11 @@ nvc0_default_flush_notify(struct nouveau_channel *chan) { struct nvc0_context *nvc0 = chan->user_private; - nvc0_screen_fence_update(nvc0->screen, TRUE); + if (!nvc0) + return; - nvc0_screen_fence_next(nvc0->screen); + nouveau_fence_update(&nvc0->screen->base, TRUE); + nouveau_fence_next(&nvc0->screen->base); } struct pipe_context * @@ -84,46 +88,54 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nvc0_screen *screen = nvc0_screen(pscreen); struct nvc0_context *nvc0; + struct pipe_context *pipe; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; + pipe = &nvc0->base.pipe; + nvc0->screen = screen; + nvc0->base.screen = &screen->base; + nvc0->base.copy_data = nvc0_m2mf_copy_linear; + nvc0->base.push_data = nvc0_m2mf_push_linear; - nvc0->pipe.winsys = pipe_winsys; - nvc0->pipe.screen = pscreen; - nvc0->pipe.priv = priv; + pipe->winsys = pipe_winsys; + pipe->screen = pscreen; + pipe->priv = priv; - nvc0->pipe.destroy = nvc0_destroy; + pipe->destroy = nvc0_destroy; - nvc0->pipe.draw_vbo = nvc0_draw_vbo; - nvc0->pipe.clear = nvc0_clear; + pipe->draw_vbo = nvc0_draw_vbo; + pipe->clear = nvc0_clear; - nvc0->pipe.flush = nvc0_flush; + pipe->flush = nvc0_flush; + if (!screen->cur_ctx) + screen->cur_ctx = nvc0; screen->base.channel->user_private = nvc0; screen->base.channel->flush_notify = nvc0_default_flush_notify; nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); nvc0_init_state_functions(nvc0); - nvc0_init_resource_functions(&nvc0->pipe); + nvc0_init_resource_functions(pipe); - nvc0->draw = draw_create(&nvc0->pipe); + nvc0->draw = draw_create(pipe); assert(nvc0->draw); draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0)); - return &nvc0->pipe; + return pipe; } struct resident { - struct nvc0_resource *res; + struct nv04_resource *res; uint32_t flags; }; void nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx, - struct nvc0_resource *resource, uint32_t flags) + struct nv04_resource *resource, uint32_t flags) { struct resident rsd = { resource, flags }; @@ -138,7 +150,7 @@ nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx, void nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx, - struct nvc0_resource *resource) + struct nv04_resource *resource) { struct resident *rsd, *top; unsigned i; diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 1ce5554f7b7..114e664fc58 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -19,6 +19,8 @@ #include "nvc0_program.h" #include "nvc0_resource.h" +#include "nouveau/nouveau_context.h" + #include "nvc0_3ddefs.xml.h" #include "nvc0_3d.xml.h" #include "nvc0_2d.xml.h" @@ -64,7 +66,7 @@ #define NVC0_BUFCTX_COUNT 4 struct nvc0_context { - struct pipe_context pipe; + struct nouveau_context base; struct nvc0_screen *screen; @@ -123,7 +125,6 @@ struct nvc0_context { unsigned sample_mask; - boolean vbo_dirty; boolean vbo_push_hint; struct nvc0_transform_feedback_state *tfb; @@ -161,9 +162,9 @@ void nvc0_default_flush_notify(struct nouveau_channel *); void nvc0_bufctx_emit_relocs(struct nvc0_context *); void nvc0_bufctx_add_resident(struct nvc0_context *, int ctx, - struct nvc0_resource *, uint32_t flags); + struct nv04_resource *, uint32_t flags); void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx, - struct nvc0_resource *); + struct nv04_resource *); static INLINE void nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx) { @@ -211,11 +212,11 @@ nvc0_create_sampler_view(struct pipe_context *, /* nvc0_transfer.c */ void -nvc0_m2mf_push_linear(struct nvc0_context *nvc0, - struct nouveau_bo *dst, unsigned domain, int offset, +nvc0_m2mf_push_linear(struct nouveau_context *nv, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nvc0_m2mf_copy_linear(struct nvc0_context *nvc0, +nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nvc0/nvc0_fence.c b/src/gallium/drivers/nvc0/nvc0_fence.c deleted file mode 100644 index f2d4b1451bf..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_fence.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2010 Christoph Bumiller - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "nvc0_fence.h" -#include "nvc0_context.h" -#include "nvc0_screen.h" - -#ifdef PIPE_OS_UNIX -#include <sched.h> -#endif - -boolean -nvc0_screen_fence_new(struct nvc0_screen *screen, struct nvc0_fence **fence, - boolean emit) -{ - *fence = CALLOC_STRUCT(nvc0_fence); - if (!*fence) - return FALSE; - - (*fence)->screen = screen; - (*fence)->ref = 1; - - if (emit) - nvc0_fence_emit(*fence); - - return TRUE; -} - -void -nvc0_fence_emit(struct nvc0_fence *fence) -{ - struct nvc0_screen *screen = fence->screen; - struct nouveau_channel *chan = screen->base.channel; - - fence->sequence = ++screen->fence.sequence; - - assert(fence->state == NVC0_FENCE_STATE_AVAILABLE); - - MARK_RING (chan, 5, 2); - BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RING (chan, fence->sequence); - OUT_RING (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | - (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT)); - - ++fence->ref; - - if (screen->fence.tail) - screen->fence.tail->next = fence; - else - screen->fence.head = fence; - - screen->fence.tail = fence; - - fence->state = NVC0_FENCE_STATE_EMITTED; -} - -static void -nvc0_fence_trigger_release_buffers(struct nvc0_fence *fence); - -void -nvc0_fence_del(struct nvc0_fence *fence) -{ - struct nvc0_fence *it; - struct nvc0_screen *screen = fence->screen; - - if (fence->state == NVC0_FENCE_STATE_EMITTED || - fence->state == NVC0_FENCE_STATE_FLUSHED) { - if (fence == screen->fence.head) { - screen->fence.head = fence->next; - if (!screen->fence.head) - screen->fence.tail = NULL; - } else { - for (it = screen->fence.head; it && it->next != fence; it = it->next); - it->next = fence->next; - if (screen->fence.tail == fence) - screen->fence.tail = it; - } - } - - if (fence->buffers) { - debug_printf("WARNING: deleting fence with buffers " - "still hooked to it !\n"); - nvc0_fence_trigger_release_buffers(fence); - } - - FREE(fence); -} - -static void -nvc0_fence_trigger_release_buffers(struct nvc0_fence *fence) -{ - struct nvc0_mm_allocation *alloc = fence->buffers; - - while (alloc) { - struct nvc0_mm_allocation *next = alloc->next; - nvc0_mm_free(alloc); - alloc = next; - }; - fence->buffers = NULL; -} - -void -nvc0_screen_fence_update(struct nvc0_screen *screen, boolean flushed) -{ - struct nvc0_fence *fence; - struct nvc0_fence *next = NULL; - uint32_t sequence = screen->fence.map[0]; - - if (screen->fence.sequence_ack == sequence) - return; - screen->fence.sequence_ack = sequence; - - for (fence = screen->fence.head; fence; fence = next) { - next = fence->next; - sequence = fence->sequence; - - fence->state = NVC0_FENCE_STATE_SIGNALLED; - - if (fence->buffers) - nvc0_fence_trigger_release_buffers(fence); - - nvc0_fence_reference(&fence, NULL); - - if (sequence == screen->fence.sequence_ack) - break; - } - screen->fence.head = next; - if (!next) - screen->fence.tail = NULL; - - if (flushed) { - for (fence = next; fence; fence = fence->next) - fence->state = NVC0_FENCE_STATE_FLUSHED; - } -} - -boolean -nvc0_fence_signalled(struct nvc0_fence *fence) -{ - struct nvc0_screen *screen = fence->screen; - - if (fence->state >= NVC0_FENCE_STATE_EMITTED) - nvc0_screen_fence_update(screen, FALSE); - - return fence->state == NVC0_FENCE_STATE_SIGNALLED; -} - -#define NVC0_FENCE_MAX_SPINS (1 << 31) - -boolean -nvc0_fence_wait(struct nvc0_fence *fence) -{ - struct nvc0_screen *screen = fence->screen; - uint32_t spins = 0; - - if (fence->state < NVC0_FENCE_STATE_EMITTED) { - nvc0_fence_emit(fence); - - if (fence == screen->fence.current) - nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); - } - if (fence->state < NVC0_FENCE_STATE_FLUSHED) - FIRE_RING(screen->base.channel); - - do { - nvc0_screen_fence_update(screen, FALSE); - - if (fence->state == NVC0_FENCE_STATE_SIGNALLED) - return TRUE; - spins++; -#ifdef PIPE_OS_UNIX - if (!(spins % 8)) /* donate a few cycles */ - sched_yield(); -#endif - } while (spins < NVC0_FENCE_MAX_SPINS); - - debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n", - fence->sequence, - screen->fence.sequence_ack, screen->fence.sequence); - - return FALSE; -} - -void -nvc0_screen_fence_next(struct nvc0_screen *screen) -{ - nvc0_fence_emit(screen->fence.current); - nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); -} diff --git a/src/gallium/drivers/nvc0/nvc0_fence.h b/src/gallium/drivers/nvc0/nvc0_fence.h deleted file mode 100644 index 3d8c3f8ba60..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_fence.h +++ /dev/null @@ -1,49 +0,0 @@ - -#ifndef __NVC0_FENCE_H__ -#define __NVC0_FENCE_H__ - -#include "util/u_inlines.h" -#include "util/u_double_list.h" - -#define NVC0_FENCE_STATE_AVAILABLE 0 -#define NVC0_FENCE_STATE_EMITTED 1 -#define NVC0_FENCE_STATE_FLUSHED 2 -#define NVC0_FENCE_STATE_SIGNALLED 3 - -struct nvc0_mm_allocation; - -struct nvc0_fence { - struct nvc0_fence *next; - struct nvc0_screen *screen; - int state; - int ref; - uint32_t sequence; - struct nvc0_mm_allocation *buffers; -}; - -void nvc0_fence_emit(struct nvc0_fence *); -void nvc0_fence_del(struct nvc0_fence *); - -boolean nvc0_fence_wait(struct nvc0_fence *); -boolean nvc0_fence_signalled(struct nvc0_fence *); - -static INLINE void -nvc0_fence_reference(struct nvc0_fence **ref, struct nvc0_fence *fence) -{ - if (*ref) { - if (--(*ref)->ref == 0) - nvc0_fence_del(*ref); - } - if (fence) - ++fence->ref; - - *ref = fence; -} - -static INLINE struct nvc0_fence * -nvc0_fence(struct pipe_fence_handle *fence) -{ - return (struct nvc0_fence *)fence; -} - -#endif // __NVC0_FENCE_H__ diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index fcbb7da41a3..68544c90d29 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -227,10 +227,10 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) for (i = 0; i < nvc0->num_vtxbufs; ++i) { uint8_t *data; struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i]; - struct nvc0_resource *res = nvc0_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer); - data = nvc0_resource_map_offset(nvc0, res, - vb->buffer_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nvc0->base, res, + vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nvc0->vertex->instance_bufs & (1 << i)))) data += info->index_bias * vb->stride; @@ -239,9 +239,9 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nvc0_resource_map_offset(nvc0, - nvc0_resource(nvc0->idxbuf.buffer), - nvc0->idxbuf.offset, NOUVEAU_BO_RD); + ctx.idxbuf = nouveau_resource_map_offset(&nvc0->base, + nv04_resource(nvc0->idxbuf.buffer), + nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) return; index_size = nvc0->idxbuf.index_size; @@ -284,8 +284,8 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) - nvc0_resource_unmap(nvc0_resource(nvc0->idxbuf.buffer)); + nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer)); for (i = 0; i < nvc0->num_vtxbufs; ++i) - nvc0_resource_unmap(nvc0_resource(nvc0->vtxbuf[i].buffer)); + nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer)); } diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c index e5e43c0e7a5..ead015b6b84 100644 --- a/src/gallium/drivers/nvc0/nvc0_query.c +++ b/src/gallium/drivers/nvc0/nvc0_query.c @@ -41,7 +41,7 @@ struct nvc0_query { uint32_t offset; /* base + i * 16 */ boolean ready; boolean is64bit; - struct nvc0_mm_allocation *mm; + struct nouveau_mm_allocation *mm; }; #define NVC0_QUERY_ALLOC_SPACE 128 @@ -62,13 +62,13 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size) nouveau_bo_ref(NULL, &q->bo); if (q->mm) { if (q->ready) - nvc0_mm_free(q->mm); + nouveau_mm_free(q->mm); else - nvc0_fence_sched_release(screen->fence.current, q->mm); + nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm); } } if (size) { - q->mm = nvc0_mm_allocate(screen->mm_GART, size, &q->bo, &q->base); + q->mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, &q->base); if (!q->bo) return FALSE; q->offset = q->base; @@ -330,10 +330,12 @@ nvc0_render_condition(struct pipe_context *pipe, void nvc0_init_query_functions(struct nvc0_context *nvc0) { - nvc0->pipe.create_query = nvc0_query_create; - nvc0->pipe.destroy_query = nvc0_query_destroy; - nvc0->pipe.begin_query = nvc0_query_begin; - nvc0->pipe.end_query = nvc0_query_end; - nvc0->pipe.get_query_result = nvc0_query_result; - nvc0->pipe.render_condition = nvc0_render_condition; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->create_query = nvc0_query_create; + pipe->destroy_query = nvc0_query_destroy; + pipe->begin_query = nvc0_query_begin; + pipe->end_query = nvc0_query_end; + pipe->get_query_result = nvc0_query_result; + pipe->render_condition = nvc0_render_condition; } diff --git a/src/gallium/drivers/nvc0/nvc0_resource.c b/src/gallium/drivers/nvc0/nvc0_resource.c index 7e42cedd163..fb5a496b84b 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.c +++ b/src/gallium/drivers/nvc0/nvc0_resource.c @@ -8,7 +8,7 @@ nvc0_resource_is_referenced(struct pipe_context *pipe, struct pipe_resource *resource, unsigned face, int layer) { - struct nvc0_resource *res = nvc0_resource(resource); + struct nv04_resource *res = nv04_resource(resource); unsigned flags = 0; #ifdef NOUVEAU_USERSPACE_MM @@ -29,7 +29,7 @@ nvc0_resource_create(struct pipe_screen *screen, { switch (templ->target) { case PIPE_BUFFER: - return nvc0_buffer_create(screen, templ); + return nouveau_buffer_create(screen, templ); default: return nvc0_miptree_create(screen, templ); } @@ -67,5 +67,5 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen) pscreen->resource_from_handle = nvc0_resource_from_handle; pscreen->resource_get_handle = u_resource_get_handle_vtbl; pscreen->resource_destroy = u_resource_destroy_vtbl; - pscreen->user_buffer_create = nvc0_user_buffer_create; + pscreen->user_buffer_create = nouveau_user_buffer_create; } diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h index 599823c0dc9..7821db51b72 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.h +++ b/src/gallium/drivers/nvc0/nvc0_resource.h @@ -6,115 +6,15 @@ #include "util/u_double_list.h" #define NOUVEAU_NVC0 #include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_fence.h" +#include "nouveau/nouveau_buffer.h" #undef NOUVEAU_NVC0 -#include "nvc0_fence.h" - -struct pipe_resource; -struct nouveau_bo; -struct nvc0_context; - -#define NVC0_BUFFER_SCORE_MIN -25000 -#define NVC0_BUFFER_SCORE_MAX 25000 -#define NVC0_BUFFER_SCORE_VRAM_THRESHOLD 20000 - -/* DIRTY: buffer was (or will be after the next flush) written to by GPU and - * resource->data has not been updated to reflect modified VRAM contents - * - * USER_MEMORY: resource->data is a pointer to client memory and may change - * between GL calls - */ -#define NVC0_BUFFER_STATUS_GPU_READING (1 << 0) -#define NVC0_BUFFER_STATUS_GPU_WRITING (1 << 1) -#define NVC0_BUFFER_STATUS_USER_MEMORY (1 << 7) - -/* Resources, if mapped into the GPU's address space, are guaranteed to - * have constant virtual addresses. - * The address of a resource will lie within the nouveau_bo referenced, - * and this bo should be added to the memory manager's validation list. - */ -struct nvc0_resource { - struct pipe_resource base; - const struct u_resource_vtbl *vtbl; - - uint8_t *data; - struct nouveau_bo *bo; - uint32_t offset; - - uint8_t status; - uint8_t domain; - - int16_t score; /* low if mapped very often, if high can move to VRAM */ - - struct nvc0_fence *fence; - struct nvc0_fence *fence_wr; - - struct nvc0_mm_allocation *mm; -}; - void -nvc0_buffer_release_gpu_storage(struct nvc0_resource *); - -boolean -nvc0_buffer_download(struct nvc0_context *, struct nvc0_resource *, - unsigned start, unsigned size); - -boolean -nvc0_buffer_migrate(struct nvc0_context *, - struct nvc0_resource *, unsigned domain); - -static INLINE void -nvc0_buffer_adjust_score(struct nvc0_context *nvc0, struct nvc0_resource *res, - int16_t score) -{ - if (score < 0) { - if (res->score > NVC0_BUFFER_SCORE_MIN) - res->score += score; - } else - if (score > 0){ - if (res->score < NVC0_BUFFER_SCORE_MAX) - res->score += score; - if (res->domain == NOUVEAU_BO_GART && - res->score > NVC0_BUFFER_SCORE_VRAM_THRESHOLD) - nvc0_buffer_migrate(nvc0, res, NOUVEAU_BO_VRAM); - } -} - -/* XXX: wait for fence (atm only using this for vertex push) */ -static INLINE void * -nvc0_resource_map_offset(struct nvc0_context *nvc0, - struct nvc0_resource *res, uint32_t offset, - uint32_t flags) -{ - void *map; - - nvc0_buffer_adjust_score(nvc0, res, -250); - - if ((res->domain == NOUVEAU_BO_VRAM) && - (res->status & NVC0_BUFFER_STATUS_GPU_WRITING)) - nvc0_buffer_download(nvc0, res, 0, res->base.width0); - - if ((res->domain != NOUVEAU_BO_GART) || - (res->status & NVC0_BUFFER_STATUS_USER_MEMORY)) - return res->data + offset; - - if (res->mm) - flags |= NOUVEAU_BO_NOSYNC; - - if (nouveau_bo_map_range(res->bo, res->offset + offset, - res->base.width0, flags)) - return NULL; - - map = res->bo->map; - nouveau_bo_unmap(res->bo); - return map; -} +nvc0_init_resource_functions(struct pipe_context *pcontext); -static INLINE void -nvc0_resource_unmap(struct nvc0_resource *res) -{ - /* no-op */ -} +void +nvc0_screen_init_resource_functions(struct pipe_screen *pscreen); #define NVC0_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) @@ -137,7 +37,7 @@ struct nvc0_miptree_level { #define NVC0_MAX_TEXTURE_LEVELS 16 struct nvc0_miptree { - struct nvc0_resource base; + struct nv04_resource base; struct nvc0_miptree_level level[NVC0_MAX_TEXTURE_LEVELS]; uint32_t total_size; uint32_t layer_stride; @@ -150,25 +50,6 @@ nvc0_miptree(struct pipe_resource *pt) return (struct nvc0_miptree *)pt; } -static INLINE struct nvc0_resource * -nvc0_resource(struct pipe_resource *resource) -{ - return (struct nvc0_resource *)resource; -} - -/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */ -static INLINE boolean -nvc0_resource_mapped_by_gpu(struct pipe_resource *resource) -{ - return nvc0_resource(resource)->domain != 0; -} - -void -nvc0_init_resource_functions(struct pipe_context *pcontext); - -void -nvc0_screen_init_resource_functions(struct pipe_screen *pscreen); - /* Internal functions: */ struct pipe_resource * @@ -180,17 +61,6 @@ nvc0_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *whandle); -struct pipe_resource * -nvc0_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ); - -struct pipe_resource * -nvc0_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, - unsigned usage); - - struct pipe_surface * nvc0_miptree_surface_new(struct pipe_context *, struct pipe_resource *, @@ -199,7 +69,4 @@ nvc0_miptree_surface_new(struct pipe_context *, void nvc0_miptree_surface_del(struct pipe_context *, struct pipe_surface *); -boolean -nvc0_user_buffer_upload(struct nvc0_resource *, unsigned base, unsigned size); - #endif diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index f7f1fd09a12..923bb83e8a3 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -23,7 +23,6 @@ #include "util/u_format_s3tc.h" #include "pipe/p_screen.h" -#include "nvc0_fence.h" #include "nvc0_context.h" #include "nvc0_screen.h" @@ -200,8 +199,8 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) { struct nvc0_screen *screen = nvc0_screen(pscreen); - nvc0_fence_wait(screen->fence.current); - nvc0_fence_reference(&screen->fence.current, NULL); + nouveau_fence_wait(screen->base.fence.current); + nouveau_fence_ref(NULL, &screen->base.fence.current); nouveau_bo_ref(NULL, &screen->text); nouveau_bo_ref(NULL, &screen->tls); @@ -214,9 +213,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) if (screen->tic.entries) FREE(screen->tic.entries); - nvc0_mm_destroy(screen->mm_GART); - nvc0_mm_destroy(screen->mm_VRAM); - nvc0_mm_destroy(screen->mm_VRAM_fe0); + nouveau_mm_destroy(screen->mm_VRAM_fe0); nouveau_grobj_free(&screen->fermi); nouveau_grobj_free(&screen->eng2d); @@ -246,30 +243,6 @@ nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos, } static void -nvc0_screen_fence_reference(struct pipe_screen *pscreen, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ - nvc0_fence_reference((struct nvc0_fence **)ptr, nvc0_fence(fence)); -} - -static int -nvc0_screen_fence_signalled(struct pipe_screen *pscreen, - struct pipe_fence_handle *fence, - unsigned flags) -{ - return !(nvc0_fence_signalled(nvc0_fence(fence))); -} - -static int -nvc0_screen_fence_finish(struct pipe_screen *pscreen, - struct pipe_fence_handle *fence, - unsigned flags) -{ - return nvc0_fence_wait((struct nvc0_fence *)fence) != TRUE; -} - -static void nvc0_magic_3d_init(struct nouveau_channel *chan) { BEGIN_RING(chan, RING_3D_(0x10cc), 1); @@ -342,6 +315,28 @@ nvc0_magic_3d_init(struct nouveau_channel *chan) OUT_RING (chan, 0); } +static void +nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence) +{ + struct nvc0_screen *screen = nvc0_screen(pscreen); + struct nouveau_channel *chan = screen->base.channel; + + MARK_RING (chan, 5, 2); + BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); + OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); + OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); + OUT_RING (chan, sequence); + OUT_RING (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | + (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT)); +} + +static u32 +nvc0_screen_fence_update(struct pipe_screen *pscreen) +{ + struct nvc0_screen *screen = nvc0_screen(pscreen); + return screen->fence.map[0]; +} + #define FAIL_SCREEN_INIT(str, err) \ do { \ NOUVEAU_ERR(str, err); \ @@ -363,6 +358,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; + screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; + ret = nouveau_screen_init(&screen->base, dev); if (ret) { nvc0_screen_destroy(pscreen); @@ -377,15 +374,9 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->get_param = nvc0_screen_get_param; pscreen->get_shader_param = nvc0_screen_get_shader_param; pscreen->get_paramf = nvc0_screen_get_paramf; - pscreen->fence_reference = nvc0_screen_fence_reference; - pscreen->fence_signalled = nvc0_screen_fence_signalled; - pscreen->fence_finish = nvc0_screen_fence_finish; nvc0_screen_init_resource_functions(pscreen); - screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; - screen->base.index_buffer_flags = 0; - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); if (ret) @@ -393,6 +384,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); screen->fence.map = screen->fence.bo->map; nouveau_bo_unmap(screen->fence.bo); + screen->base.fence.emit = nvc0_screen_fence_emit; + screen->base.fence.update = nvc0_screen_fence_update; for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) { ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, @@ -619,12 +612,9 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tic.entries = CALLOC(4096, sizeof(void *)); screen->tsc.entries = screen->tic.entries + 2048; - screen->mm_GART = nvc0_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0x000); - screen->mm_VRAM = nvc0_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); - screen->mm_VRAM_fe0 = nvc0_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); + screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); - nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); + nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); return pscreen; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h index d952ff1f9b1..d8b8c5e3dc8 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nvc0/nvc0_screen.h @@ -3,6 +3,7 @@ #define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" +#include "nouveau/nouveau_mm.h" #undef NOUVEAU_NVC0 #include "nvc0_winsys.h" #include "nvc0_stateobj.h" @@ -10,9 +11,7 @@ #define NVC0_TIC_MAX_ENTRIES 2048 #define NVC0_TSC_MAX_ENTRIES 2048 -struct nvc0_mman; struct nvc0_context; -struct nvc0_fence; #define NVC0_SCRATCH_SIZE (2 << 20) #define NVC0_SCRATCH_NR_BUFFERS 2 @@ -53,18 +52,11 @@ struct nvc0_screen { } tsc; struct { - uint32_t *map; - struct nvc0_fence *head; - struct nvc0_fence *tail; - struct nvc0_fence *current; - uint32_t sequence; - uint32_t sequence_ack; struct nouveau_bo *bo; + uint32_t *map; } fence; - struct nvc0_mman *mm_GART; - struct nvc0_mman *mm_VRAM; - struct nvc0_mman *mm_VRAM_fe0; + struct nouveau_mman *mm_VRAM_fe0; struct nouveau_grobj *fermi; struct nouveau_grobj *eng2d; @@ -77,54 +69,26 @@ nvc0_screen(struct pipe_screen *screen) return (struct nvc0_screen *)screen; } -/* Since a resource can be migrated, we need to decouple allocations from - * them. This struct is linked with fences for delayed freeing of allocs. - */ -struct nvc0_mm_allocation { - struct nvc0_mm_allocation *next; - void *priv; - uint32_t offset; -}; - -static INLINE void -nvc0_fence_sched_release(struct nvc0_fence *nf, struct nvc0_mm_allocation *mm) -{ - mm->next = nf->buffers; - nf->buffers = mm; -} - -extern struct nvc0_mman * -nvc0_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type); - -extern void -nvc0_mm_destroy(struct nvc0_mman *); - -extern struct nvc0_mm_allocation * -nvc0_mm_allocate(struct nvc0_mman *, - uint32_t size, struct nouveau_bo **, uint32_t *offset); -extern void -nvc0_mm_free(struct nvc0_mm_allocation *); - void nvc0_screen_make_buffers_resident(struct nvc0_screen *); int nvc0_screen_tic_alloc(struct nvc0_screen *, void *); int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *); static INLINE void -nvc0_resource_fence(struct nvc0_resource *res, uint32_t flags) +nvc0_resource_fence(struct nv04_resource *res, uint32_t flags) { struct nvc0_screen *screen = nvc0_screen(res->base.screen); if (res->mm) { - nvc0_fence_reference(&res->fence, screen->fence.current); + nouveau_fence_ref(screen->base.fence.current, &res->fence); if (flags & NOUVEAU_BO_WR) - nvc0_fence_reference(&res->fence_wr, screen->fence.current); + nouveau_fence_ref(screen->base.fence.current, &res->fence_wr); } } static INLINE void -nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags) +nvc0_resource_validate(struct nv04_resource *res, uint32_t flags) { struct nvc0_screen *screen = nvc0_screen(res->base.screen); @@ -132,30 +96,14 @@ nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags) nouveau_bo_validate(screen->base.channel, res->bo, flags); if (flags & NOUVEAU_BO_WR) - res->status |= NVC0_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; if (flags & NOUVEAU_BO_RD) - res->status |= NVC0_BUFFER_STATUS_GPU_READING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_resource_fence(res, flags); } } - -boolean -nvc0_screen_fence_new(struct nvc0_screen *, struct nvc0_fence **, boolean emit); -void -nvc0_screen_fence_next(struct nvc0_screen *); -void -nvc0_screen_fence_update(struct nvc0_screen *, boolean flushed); - -static INLINE boolean -nvc0_screen_fence_emit(struct nvc0_screen *screen) -{ - nvc0_fence_emit(screen->fence.current); - - return nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); -} - struct nvc0_format { uint32_t rt; uint32_t tic; diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 357f8b80deb..79b5f3d81cc 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -59,11 +59,11 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) prog->code_base = prog->res->start; - nvc0_m2mf_push_linear(nvc0, nvc0->screen->text, NOUVEAU_BO_VRAM, - prog->code_base, NVC0_SHADER_HEADER_SIZE, prog->hdr); - nvc0_m2mf_push_linear(nvc0, nvc0->screen->text, NOUVEAU_BO_VRAM, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base, + NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr); + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base + NVC0_SHADER_HEADER_SIZE, - prog->code_size, prog->code); + NOUVEAU_BO_VRAM, prog->code_size, prog->code); BEGIN_RING(nvc0->screen->base.channel, RING_3D(MEM_BARRIER), 1); OUT_RING (nvc0->screen->base.channel, 0x1111); @@ -217,7 +217,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0) for (b = 0; b < nvc0->num_tfbbufs; ++b) { uint8_t idx, var[128]; int i, n; - struct nvc0_resource *buf = nvc0_resource(nvc0->tfbbuf[b]); + struct nv04_resource *buf = nv04_resource(nvc0->tfbbuf[b]); BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 5); OUT_RING (chan, 1); diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index aa437195764..ee4680efeca 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -666,8 +666,7 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, if (nvc0->constbuf[shader][index]) nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT, - nvc0_resource( - nvc0->constbuf[shader][index])); + nv04_resource(nvc0->constbuf[shader][index])); pipe_resource_reference(&nvc0->constbuf[shader][index], res); @@ -877,62 +876,64 @@ nvc0_set_transform_feedback_buffers(struct pipe_context *pipe, void nvc0_init_state_functions(struct nvc0_context *nvc0) { - nvc0->pipe.create_blend_state = nvc0_blend_state_create; - nvc0->pipe.bind_blend_state = nvc0_blend_state_bind; - nvc0->pipe.delete_blend_state = nvc0_blend_state_delete; - - nvc0->pipe.create_rasterizer_state = nvc0_rasterizer_state_create; - nvc0->pipe.bind_rasterizer_state = nvc0_rasterizer_state_bind; - nvc0->pipe.delete_rasterizer_state = nvc0_rasterizer_state_delete; - - nvc0->pipe.create_depth_stencil_alpha_state = nvc0_zsa_state_create; - nvc0->pipe.bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; - nvc0->pipe.delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; - - nvc0->pipe.create_sampler_state = nvc0_sampler_state_create; - nvc0->pipe.delete_sampler_state = nvc0_sampler_state_delete; - nvc0->pipe.bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; - nvc0->pipe.bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; - nvc0->pipe.bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; - - nvc0->pipe.create_sampler_view = nvc0_create_sampler_view; - nvc0->pipe.sampler_view_destroy = nvc0_sampler_view_destroy; - nvc0->pipe.set_vertex_sampler_views = nvc0_vp_set_sampler_views; - nvc0->pipe.set_fragment_sampler_views = nvc0_fp_set_sampler_views; - nvc0->pipe.set_geometry_sampler_views = nvc0_gp_set_sampler_views; - - nvc0->pipe.create_vs_state = nvc0_vp_state_create; - nvc0->pipe.create_fs_state = nvc0_fp_state_create; - nvc0->pipe.create_gs_state = nvc0_gp_state_create; - nvc0->pipe.bind_vs_state = nvc0_vp_state_bind; - nvc0->pipe.bind_fs_state = nvc0_fp_state_bind; - nvc0->pipe.bind_gs_state = nvc0_gp_state_bind; - nvc0->pipe.delete_vs_state = nvc0_sp_state_delete; - nvc0->pipe.delete_fs_state = nvc0_sp_state_delete; - nvc0->pipe.delete_gs_state = nvc0_sp_state_delete; - - nvc0->pipe.set_blend_color = nvc0_set_blend_color; - nvc0->pipe.set_stencil_ref = nvc0_set_stencil_ref; - nvc0->pipe.set_clip_state = nvc0_set_clip_state; - nvc0->pipe.set_sample_mask = nvc0_set_sample_mask; - nvc0->pipe.set_constant_buffer = nvc0_set_constant_buffer; - nvc0->pipe.set_framebuffer_state = nvc0_set_framebuffer_state; - nvc0->pipe.set_polygon_stipple = nvc0_set_polygon_stipple; - nvc0->pipe.set_scissor_state = nvc0_set_scissor_state; - nvc0->pipe.set_viewport_state = nvc0_set_viewport_state; - - nvc0->pipe.create_vertex_elements_state = nvc0_vertex_state_create; - nvc0->pipe.delete_vertex_elements_state = nvc0_vertex_state_delete; - nvc0->pipe.bind_vertex_elements_state = nvc0_vertex_state_bind; - - nvc0->pipe.set_vertex_buffers = nvc0_set_vertex_buffers; - nvc0->pipe.set_index_buffer = nvc0_set_index_buffer; - - nvc0->pipe.create_stream_output_state = nvc0_tfb_state_create; - nvc0->pipe.delete_stream_output_state = nvc0_tfb_state_delete; - nvc0->pipe.bind_stream_output_state = nvc0_tfb_state_bind; - nvc0->pipe.set_stream_output_buffers = nvc0_set_transform_feedback_buffers; - - nvc0->pipe.redefine_user_buffer = u_default_redefine_user_buffer; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->create_blend_state = nvc0_blend_state_create; + pipe->bind_blend_state = nvc0_blend_state_bind; + pipe->delete_blend_state = nvc0_blend_state_delete; + + pipe->create_rasterizer_state = nvc0_rasterizer_state_create; + pipe->bind_rasterizer_state = nvc0_rasterizer_state_bind; + pipe->delete_rasterizer_state = nvc0_rasterizer_state_delete; + + pipe->create_depth_stencil_alpha_state = nvc0_zsa_state_create; + pipe->bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; + pipe->delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; + + pipe->create_sampler_state = nvc0_sampler_state_create; + pipe->delete_sampler_state = nvc0_sampler_state_delete; + pipe->bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; + pipe->bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; + pipe->bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; + + pipe->create_sampler_view = nvc0_create_sampler_view; + pipe->sampler_view_destroy = nvc0_sampler_view_destroy; + pipe->set_vertex_sampler_views = nvc0_vp_set_sampler_views; + pipe->set_fragment_sampler_views = nvc0_fp_set_sampler_views; + pipe->set_geometry_sampler_views = nvc0_gp_set_sampler_views; + + pipe->create_vs_state = nvc0_vp_state_create; + pipe->create_fs_state = nvc0_fp_state_create; + pipe->create_gs_state = nvc0_gp_state_create; + pipe->bind_vs_state = nvc0_vp_state_bind; + pipe->bind_fs_state = nvc0_fp_state_bind; + pipe->bind_gs_state = nvc0_gp_state_bind; + pipe->delete_vs_state = nvc0_sp_state_delete; + pipe->delete_fs_state = nvc0_sp_state_delete; + pipe->delete_gs_state = nvc0_sp_state_delete; + + pipe->set_blend_color = nvc0_set_blend_color; + pipe->set_stencil_ref = nvc0_set_stencil_ref; + pipe->set_clip_state = nvc0_set_clip_state; + pipe->set_sample_mask = nvc0_set_sample_mask; + pipe->set_constant_buffer = nvc0_set_constant_buffer; + pipe->set_framebuffer_state = nvc0_set_framebuffer_state; + pipe->set_polygon_stipple = nvc0_set_polygon_stipple; + pipe->set_scissor_state = nvc0_set_scissor_state; + pipe->set_viewport_state = nvc0_set_viewport_state; + + pipe->create_vertex_elements_state = nvc0_vertex_state_create; + pipe->delete_vertex_elements_state = nvc0_vertex_state_delete; + pipe->bind_vertex_elements_state = nvc0_vertex_state_bind; + + pipe->set_vertex_buffers = nvc0_set_vertex_buffers; + pipe->set_index_buffer = nvc0_set_index_buffer; + + pipe->create_stream_output_state = nvc0_tfb_state_create; + pipe->delete_stream_output_state = nvc0_tfb_state_delete; + pipe->bind_stream_output_state = nvc0_tfb_state_bind; + pipe->set_stream_output_buffers = nvc0_set_transform_feedback_buffers; + + pipe->redefine_user_buffer = u_default_redefine_user_buffer; } diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 70c418fad9b..ab8119a3bbb 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -87,10 +87,10 @@ nvc0_validate_fb(struct nvc0_context *nvc0) OUT_RING (chan, sf->depth); OUT_RING (chan, mt->layer_stride >> 2); - if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING) + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) serialize = TRUE; - mt->base.status |= NVC0_BUFFER_STATUS_GPU_WRITING; - mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); @@ -117,10 +117,10 @@ nvc0_validate_fb(struct nvc0_context *nvc0) OUT_RING (chan, sf->height); OUT_RING (chan, (unk << 16) | sf->depth); - if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING) + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) serialize = TRUE; - mt->base.status |= NVC0_BUFFER_STATUS_GPU_WRITING; - mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); @@ -323,7 +323,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) unsigned s; for (s = 0; s < 5; ++s) { - struct nvc0_resource *res; + struct nv04_resource *res; int i; while (nvc0->constbuf_dirty[s]) { @@ -334,7 +334,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) i = ffs(nvc0->constbuf_dirty[s]) - 1; nvc0->constbuf_dirty[s] &= ~(1 << i); - res = nvc0_resource(nvc0->constbuf[s][i]); + res = nv04_resource(nvc0->constbuf[s][i]); if (!res) { BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); OUT_RING (chan, (i << 4) | 0); @@ -343,7 +343,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) continue; } - if (!nvc0_resource_mapped_by_gpu(&res->base)) { + if (!nouveau_resource_mapped_by_gpu(&res->base)) { if (i == 0) { base = s << 16; bo = nvc0->screen->uniforms; diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 8898bc733a3..a4b2b948123 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -367,9 +367,11 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, void nvc0_init_surface_functions(struct nvc0_context *nvc0) { - nvc0->pipe.resource_copy_region = nvc0_resource_copy_region; - nvc0->pipe.clear_render_target = nvc0_clear_render_target; - nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->resource_copy_region = nvc0_resource_copy_region; + pipe->clear_render_target = nvc0_clear_render_target; + pipe->clear_depth_stencil = nvc0_clear_depth_stencil; } diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index 968558a5869..6822e597b36 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -167,7 +167,7 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) for (i = 0; i < nvc0->num_textures[s]; ++i) { struct nvc0_tic_entry *tic = nvc0_tic_entry(nvc0->textures[s][i]); - struct nvc0_resource *res; + struct nv04_resource *res; if (!tic) { BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); @@ -197,14 +197,14 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) need_flush = TRUE; } else - if (res->status & NVC0_BUFFER_STATUS_GPU_WRITING) { + if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); OUT_RING (chan, (tic->id << 4) | 1); } nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); - res->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING; - res->status |= NVC0_BUFFER_STATUS_GPU_READING; + res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); @@ -252,8 +252,9 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) if (tsc->id < 0) { tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); - nvc0_m2mf_push_linear(nvc0, nvc0->screen->txc, NOUVEAU_BO_VRAM, - 65536 + tsc->id * 32, 32, tsc->tsc); + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc, + 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, + 32, tsc->tsc); need_flush = TRUE; } nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index b279bdc6e7d..a38bdb8f0a6 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -104,11 +104,11 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nvc0_m2mf_push_linear(struct nvc0_context *nvc0, - struct nouveau_bo *dst, unsigned domain, int offset, +nvc0_m2mf_push_linear(struct nouveau_context *nv, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; @@ -143,12 +143,12 @@ nvc0_m2mf_push_linear(struct nvc0_context *nvc0, } void -nvc0_m2mf_copy_linear(struct nvc0_context *nvc0, +nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; while (size) { unsigned bytes = MIN2(size, 1 << 17); diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 2db43d8704b..e7e7ce7dc22 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -131,13 +131,13 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, { const void *data; struct nouveau_channel *chan = nvc0->screen->base.channel; - struct nvc0_resource *res = nvc0_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer); float v[4]; int i; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nvc0_resource_map_offset(nvc0, res, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nvc0->base, res, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_RD); util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); @@ -167,7 +167,7 @@ static void nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) { struct pipe_vertex_buffer *vb; - struct nvc0_resource *buf; + struct nv04_resource *buf; int i; uint32_t base, size; @@ -179,27 +179,27 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) vb = &nvc0->vtxbuf[i]; if (!vb->stride) continue; - buf = nvc0_resource(vb->buffer); + buf = nv04_resource(vb->buffer); /* NOTE: user buffers with temporary storage count as mapped by GPU */ - if (!nvc0_resource_mapped_by_gpu(vb->buffer)) { + if (!nouveau_resource_mapped_by_gpu(vb->buffer)) { if (nvc0->vbo_push_hint) { nvc0->vbo_fifo = ~0; continue; } else { - if (buf->status & NVC0_BUFFER_STATUS_USER_MEMORY) { + if (buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY) { nvc0->vbo_user |= 1 << i; assert(vb->stride > vb->buffer_offset); nvc0_vbuf_range(nvc0, i, &base, &size); - nvc0_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } else { - nvc0_buffer_migrate(nvc0, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART); } - nvc0->vbo_dirty = TRUE; + nvc0->base.vbo_dirty = TRUE; } } nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nvc0_buffer_adjust_score(nvc0, buf, 1); + nouveau_buffer_adjust_score(&nvc0->base, buf, 1); } } @@ -215,7 +215,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe; const int b = ve->vertex_buffer_index; struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b]; - struct nvc0_resource *buf = nvc0_resource(vb->buffer); + struct nv04_resource *buf = nv04_resource(vb->buffer); if (!(nvc0->vbo_user & (1 << b))) continue; @@ -228,7 +228,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) if (!(written & (1 << b))) { written |= 1 << b; - nvc0_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } offset = vb->buffer_offset + ve->src_offset; @@ -240,7 +240,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } - nvc0->vbo_dirty = TRUE; + nvc0->base.vbo_dirty = TRUE; } static INLINE void @@ -252,7 +252,7 @@ nvc0_release_user_vbufs(struct nvc0_context *nvc0) int i = ffs(vbo_user) - 1; vbo_user &= ~(1 << i); - nvc0_buffer_release_gpu_storage(nvc0_resource(nvc0->vtxbuf[i].buffer)); + nouveau_buffer_release_gpu_storage(nv04_resource(nvc0->vtxbuf[i].buffer)); } } @@ -286,7 +286,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) } for (i = 0; i < vertex->num_elements; ++i) { - struct nvc0_resource *res; + struct nv04_resource *res; unsigned size, offset; ve = &vertex->element[i]; @@ -303,7 +303,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); } - res = nvc0_resource(vb->buffer); + res = nv04_resource(vb->buffer); if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) { if (!nvc0->vbo_fifo) @@ -371,7 +371,7 @@ nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan) { struct nvc0_context *nvc0 = chan->user_private; - nvc0_screen_fence_update(nvc0->screen, TRUE); + nouveau_fence_update(&nvc0->screen->base, TRUE); nvc0_bufctx_emit_relocs(nvc0); } @@ -513,12 +513,12 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, nvc0->state.index_bias = index_bias; } - if (nvc0_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) { - struct nvc0_resource *res = nvc0_resource(nvc0->idxbuf.buffer); + if (nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) { + struct nv04_resource *res = nv04_resource(nvc0->idxbuf.buffer); unsigned offset = nvc0->idxbuf.offset; unsigned limit = nvc0->idxbuf.buffer->width0 - 1; - nvc0_buffer_adjust_score(nvc0, res, 1); + nouveau_buffer_adjust_score(&nvc0->base, res, 1); while (instance_count--) { MARK_RING (chan, 11, 4); @@ -539,8 +539,9 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nvc0_resource_map_offset(nvc0, nvc0_resource(nvc0->idxbuf.buffer), - nvc0->idxbuf.offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nvc0->base, + nv04_resource(nvc0->idxbuf.buffer), + nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!data) return; @@ -609,10 +610,10 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) OUT_RING (chan, info->start_instance); } - if (nvc0->vbo_dirty) { + if (nvc0->base.vbo_dirty) { BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); - nvc0->vbo_dirty = FALSE; + nvc0->base.vbo_dirty = FALSE; } if (!info->indexed) { diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h index 45f71967eff..6519ce8e19f 100644 --- a/src/gallium/drivers/nvc0/nvc0_winsys.h +++ b/src/gallium/drivers/nvc0/nvc0_winsys.h @@ -84,18 +84,18 @@ IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data) } static INLINE int -OUT_RESRCh(struct nouveau_channel *chan, struct nvc0_resource *res, +OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags); } static INLINE int -OUT_RESRCl(struct nouveau_channel *chan, struct nvc0_resource *res, +OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { if (flags & NOUVEAU_BO_WR) - res->status |= NVC0_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); } diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 2238aa1ad0e..dad912b2aee 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -18,6 +18,7 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_gldefs.h" +#include "nouveau/nouveau_resource.h" #include "nv30-40_3d.xml.h" #include "nvfx_state.h" diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 7d3d022d973..16b53a0b2a5 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -424,10 +424,10 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, */ if (force_tiling == -1) { struct r600_screen *rscreen = (struct r600_screen *)screen; - if (r600_get_minor_version(rscreen->radeon) >= 9) - force_tiling = debug_get_bool_option("R600_TILING", TRUE); - else - force_tiling = debug_get_bool_option("R600_TILING", FALSE); + /* reenable when 2D tiling is fixed better */ + /*if (r600_get_minor_version(rscreen->radeon) >= 9) + force_tiling = debug_get_bool_option("R600_TILING", TRUE);*/ + force_tiling = debug_get_bool_option("R600_TILING", FALSE); } if (force_tiling && permit_hardware_blit(screen, templ)) { diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index 3aefb5b3bb5..4a5d5413d8c 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -544,6 +544,7 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe, rb_pipe->curr.nr_cbufs = 0; memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs)); + rb_pipe->curr.zsbuf = NULL; /* unwrap the input state */ if (_state) { @@ -556,6 +557,8 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe, rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture); } unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf); + if (_state->zsbuf) + rb_pipe->curr.zsbuf = rbug_resource(_state->zsbuf->texture); state = &unwrapped_state; } diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 3d6b5b5c81d..3441db685ce 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -171,6 +171,18 @@ typedef unsigned char boolean; # define __FUNCTION__ "<unknown>" # endif #endif +#ifndef __func__ +# if (__STDC_VERSION__ >= 199901L) || \ + (defined(__SUNPRO_C) && defined(__C99FEATURES__)) + /* __func__ is part of C99 */ +# elif defined(_MSC_VER) +# if _MSC_VER >= 1300 +# define __func__ __FUNCTION__ +# else +# define __func__ "<unknown>" +# endif +# endif +#endif |