From 26add9288c88108e3485ffc57c51ea9bdc0ee719 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 17:23:12 +1100 Subject: nouveau: match gallium code reorginisation. That was... fun.. --- src/gallium/drivers/nv40/Makefile | 29 + src/gallium/drivers/nv40/nv40_clear.c | 12 + src/gallium/drivers/nv40/nv40_context.c | 312 +++++++++++ src/gallium/drivers/nv40/nv40_context.h | 153 ++++++ src/gallium/drivers/nv40/nv40_dma.h | 66 +++ src/gallium/drivers/nv40/nv40_draw.c | 62 +++ src/gallium/drivers/nv40/nv40_fragprog.c | 842 +++++++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_fragtex.c | 151 ++++++ src/gallium/drivers/nv40/nv40_miptree.c | 104 ++++ src/gallium/drivers/nv40/nv40_query.c | 113 ++++ src/gallium/drivers/nv40/nv40_shader.h | 554 +++++++++++++++++++ src/gallium/drivers/nv40/nv40_state.c | 823 ++++++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_state.h | 80 +++ src/gallium/drivers/nv40/nv40_state_emit.c | 77 +++ src/gallium/drivers/nv40/nv40_surface.c | 137 +++++ src/gallium/drivers/nv40/nv40_vbo.c | 424 +++++++++++++++ src/gallium/drivers/nv40/nv40_vertprog.c | 790 +++++++++++++++++++++++++++ 17 files changed, 4729 insertions(+) create mode 100644 src/gallium/drivers/nv40/Makefile create mode 100644 src/gallium/drivers/nv40/nv40_clear.c create mode 100644 src/gallium/drivers/nv40/nv40_context.c create mode 100644 src/gallium/drivers/nv40/nv40_context.h create mode 100644 src/gallium/drivers/nv40/nv40_dma.h create mode 100644 src/gallium/drivers/nv40/nv40_draw.c create mode 100644 src/gallium/drivers/nv40/nv40_fragprog.c create mode 100644 src/gallium/drivers/nv40/nv40_fragtex.c create mode 100644 src/gallium/drivers/nv40/nv40_miptree.c create mode 100644 src/gallium/drivers/nv40/nv40_query.c create mode 100644 src/gallium/drivers/nv40/nv40_shader.h create mode 100644 src/gallium/drivers/nv40/nv40_state.c create mode 100644 src/gallium/drivers/nv40/nv40_state.h create mode 100644 src/gallium/drivers/nv40/nv40_state_emit.c create mode 100644 src/gallium/drivers/nv40/nv40_surface.c create mode 100644 src/gallium/drivers/nv40/nv40_vbo.c create mode 100644 src/gallium/drivers/nv40/nv40_vertprog.c (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile new file mode 100644 index 0000000000..2a9de4a2dc --- /dev/null +++ b/src/gallium/drivers/nv40/Makefile @@ -0,0 +1,29 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv40 + +DRIVER_SOURCES = \ + nv40_clear.c \ + nv40_context.c \ + nv40_draw.c \ + nv40_fragprog.c \ + nv40_fragtex.c \ + nv40_miptree.c \ + nv40_query.c \ + nv40_state.c \ + nv40_state_emit.c \ + nv40_surface.c \ + nv40_vbo.c \ + nv40_vertprog.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c new file mode 100644 index 0000000000..2c4e8f01fd --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -0,0 +1,12 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv40_context.h" + +void +nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +} diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c new file mode 100644 index 0000000000..8b5cc693de --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -0,0 +1,312 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" + +#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf +#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 +#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 + +static const char * +nv40_get_name(struct pipe_context *pipe) +{ + struct nv40_context *nv40 = nv40_context(pipe); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv40->chipset); + return buffer; +} + +static const char * +nv40_get_vendor(struct pipe_context *pipe) +{ + return "nouveau"; +} + +static int +nv40_get_param(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 16; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 4; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + 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; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv40_get_paramf(struct pipe_context *pipe, int 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 16.0; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static void +nv40_flush(struct pipe_context *pipe, unsigned flags) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_winsys *nvws = nv40->nvws; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(curie, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(curie, 0x1fd8, 1); + OUT_RING (1); + } + + if (flags & PIPE_FLUSH_WAIT) { + nvws->notifier_reset(nv40->hw->sync, 0); + BEGIN_RING(curie, 0x104, 1); + OUT_RING (0); + BEGIN_RING(curie, 0x100, 1); + OUT_RING (0); + } + + FIRE_RING(); + + if (flags & PIPE_FLUSH_WAIT) + nvws->notifier_wait(nv40->hw->sync, 0, 0, 2000); +} + +static void +nv40_channel_takedown(struct nv40_channel_context *cnv40) +{ + struct nouveau_winsys *nvws = cnv40->nvws; + + nvws->res_free(&cnv40->vp_exec_heap); + nvws->res_free(&cnv40->vp_data_heap); + nvws->res_free(&cnv40->query_heap); + nvws->notifier_free(&cnv40->query); + nvws->notifier_free(&cnv40->sync); + nvws->grobj_free(&cnv40->curie); + free(cnv40); +} + +static struct nv40_channel_context * +nv40_channel_init(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv40_channel_context *cnv40 = NULL; + struct nouveau_stateobj *so; + unsigned curie_class = 0; + int ret; + + switch (chipset & 0xf0) { + case 0x40: + if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV40TCL; + else + if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + case 0x60: + if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + default: + break; + } + + if (!curie_class) { + NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset); + return NULL; + } + + cnv40 = CALLOC(1, sizeof(struct nv40_channel_context)); + if (!cnv40) + return NULL; + cnv40->chipset = chipset; + cnv40->nvws = nvws; + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &cnv40->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv40_channel_takedown(cnv40); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &cnv40->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv40_channel_takedown(cnv40); + return NULL; + } + + ret = nvws->res_init(&cnv40->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv40_channel_takedown(cnv40); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&cnv40->vp_exec_heap, 0, 512) || + nvws->res_init(&cnv40->vp_data_heap, 0, 256)) { + nv40_channel_takedown(cnv40); + return NULL; + } + + /* 3D object */ + ret = nvws->grobj_alloc(nvws, curie_class, &cnv40->curie); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Static curie initialisation */ + so = so_new(128, 0); + so_method(so, cnv40->curie, NV40TCL_DMA_NOTIFY, 1); + so_data (so, cnv40->sync->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_TEXTURE0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_COLOR1, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_COLOR0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_VTXBUF0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_FENCE, 2); + so_data (so, 0); + so_data (so, cnv40->query->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_UNK01AC, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_COLOR2, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + + so_method(so, cnv40->curie, 0x1ea4, 3); + so_data (so, 0x00000010); + so_data (so, 0x01000100); + so_data (so, 0xff800006); + + /* vtxprog output routing */ + so_method(so, cnv40->curie, 0x1fc4, 1); + so_data (so, 0x06144321); + so_method(so, cnv40->curie, 0x1fc8, 2); + so_data (so, 0xedcba987); + so_data (so, 0x00000021); + so_method(so, cnv40->curie, 0x1fd0, 1); + so_data (so, 0x00171615); + so_method(so, cnv40->curie, 0x1fd4, 1); + so_data (so, 0x001b1a19); + + so_method(so, cnv40->curie, 0x1ef8, 1); + so_data (so, 0x0020ffff); + so_method(so, cnv40->curie, 0x1d64, 1); + so_data (so, 0x00d30000); + so_method(so, cnv40->curie, 0x1e94, 1); + so_data (so, 0x00000001); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws->channel, 0); + + return cnv40; +} + +static void +nv40_destroy(struct pipe_context *pipe) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + if (nv40->draw) + draw_destroy(nv40->draw); + + if (nv40->hw) { + if (--nv40->hw->refcount == 0) + nv40_channel_takedown(nv40->hw); + } + + free(nv40); +} + +struct pipe_context * +nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv40_context *nv40; + + nv40 = CALLOC(1, sizeof(struct nv40_context)); + if (!nv40) + return NULL; + + nv40->hw = nv40_channel_init(ws, nvws, chipset); + if (!nv40->hw) { + nv40_destroy(&nv40->pipe); + return NULL; + } + + nv40->chipset = chipset; + nv40->nvws = nvws; + + nv40->pipe.winsys = ws; + nv40->pipe.destroy = nv40_destroy; + nv40->pipe.get_name = nv40_get_name; + nv40->pipe.get_vendor = nv40_get_vendor; + nv40->pipe.get_param = nv40_get_param; + nv40->pipe.get_paramf = nv40_get_paramf; + nv40->pipe.draw_arrays = nv40_draw_arrays; + nv40->pipe.draw_elements = nv40_draw_elements; + nv40->pipe.clear = nv40_clear; + nv40->pipe.flush = nv40_flush; + + nv40_init_query_functions(nv40); + nv40_init_surface_functions(nv40); + nv40_init_state_functions(nv40); + nv40_init_miptree_functions(nv40); + + nv40->draw = draw_create(); + assert(nv40->draw); + draw_set_rasterize_stage(nv40->draw, nv40_draw_render_stage(nv40)); + + return &nv40->pipe; +} + diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h new file mode 100644 index 0000000000..f511759e3b --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -0,0 +1,153 @@ +#ifndef __NV40_CONTEXT_H__ +#define __NV40_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv40_channel_context *ctx = nv40->hw +#include "nouveau/nouveau_push.h" +#include "nouveau/nouveau_stateobj.h" + +#include "nv40_state.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +#define NV40_NEW_BLEND (1 << 0) +#define NV40_NEW_RAST (1 << 1) +#define NV40_NEW_ZSA (1 << 2) +#define NV40_NEW_SAMPLER (1 << 3) +#define NV40_NEW_FB (1 << 4) +#define NV40_NEW_STIPPLE (1 << 5) +#define NV40_NEW_SCISSOR (1 << 6) +#define NV40_NEW_VIEWPORT (1 << 7) +#define NV40_NEW_BCOL (1 << 8) +#define NV40_NEW_VERTPROG (1 << 9) +#define NV40_NEW_FRAGPROG (1 << 10) +#define NV40_NEW_ARRAYS (1 << 11) + +struct nv40_channel_context { + struct nouveau_winsys *nvws; + unsigned refcount; + + unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *curie; + struct nouveau_notifier *sync; + + /* Query object resources */ + struct nouveau_notifier *query; + struct nouveau_resource *query_heap; + + /* Vtxprog resources */ + struct nouveau_resource *vp_exec_heap; + struct nouveau_resource *vp_data_heap; +}; + +struct nv40_context { + struct pipe_context pipe; + struct nouveau_winsys *nvws; + + struct nv40_channel_context *hw; + struct draw_context *draw; + + int chipset; + + uint32_t dirty; + + struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned dirty_samplers; + unsigned fp_samplers; + unsigned vp_samplers; + + struct nouveau_stateobj *so_framebuffer; + struct nouveau_stateobj *so_fragtex[16]; + struct nouveau_stateobj *so_vtxbuf; + struct nouveau_stateobj *so_blend; + struct nouveau_stateobj *so_rast; + struct nouveau_stateobj *so_zsa; + struct nouveau_stateobj *so_bcol; + struct nouveau_stateobj *so_scissor; + struct nouveau_stateobj *so_viewport; + struct nouveau_stateobj *so_stipple; + + struct { + struct nv40_vertex_program *active; + + struct nv40_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv40_fragment_program *active; + + struct nv40_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; +}; + +static INLINE struct nv40_context * +nv40_context(struct pipe_context *pipe) +{ + return (struct nv40_context *)pipe; +} + +extern void nv40_init_state_functions(struct nv40_context *nv40); +extern void nv40_init_surface_functions(struct nv40_context *nv40); +extern void nv40_init_miptree_functions(struct nv40_context *nv40); +extern void nv40_init_query_functions(struct nv40_context *nv40); + +/* nv40_draw.c */ +extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); + +/* nv40_vertprog.c */ +extern void nv40_vertprog_translate(struct nv40_context *, + struct nv40_vertex_program *); +extern void nv40_vertprog_bind(struct nv40_context *, + struct nv40_vertex_program *); +extern void nv40_vertprog_destroy(struct nv40_context *, + struct nv40_vertex_program *); + +/* nv40_fragprog.c */ +extern void nv40_fragprog_translate(struct nv40_context *, + struct nv40_fragment_program *); +extern void nv40_fragprog_bind(struct nv40_context *, + struct nv40_fragment_program *); +extern void nv40_fragprog_destroy(struct nv40_context *, + struct nv40_fragment_program *); + +/* nv40_fragtex.c */ +extern void nv40_fragtex_bind(struct nv40_context *); + +/* nv40_state.c and friends */ +extern void nv40_emit_hw_state(struct nv40_context *nv40); +extern void nv40_state_tex_update(struct nv40_context *nv40); + +/* nv40_vbo.c */ +extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv40_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count); + +/* nv40_clear.c */ +extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +#endif diff --git a/src/gallium/drivers/nv40/nv40_dma.h b/src/gallium/drivers/nv40/nv40_dma.h new file mode 100644 index 0000000000..1fb8267768 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_dma.h @@ -0,0 +1,66 @@ +#ifndef __NV40_DMA_H__ +#define __NV40_DMA_H__ + +#include "pipe/nouveau/nouveau_winsys.h" + +#define OUT_RING(data) do { \ + (*nv40->nvws->channel->pushbuf->cur++) = (data); \ +} while(0) + +#define OUT_RINGp(src,size) do { \ + memcpy(nv40->nvws->channel->pushbuf->cur, (src), (size) * 4); \ + nv40->nvws->channel->pushbuf->cur += (size); \ +} while(0) + +#define OUT_RINGf(data) do { \ + union { float v; uint32_t u; } c; \ + c.v = (data); \ + OUT_RING(c.u); \ +} while(0) + +#define BEGIN_RING(obj,mthd,size) do { \ + if (nv40->nvws->channel->pushbuf->remaining < ((size) + 1)) \ + nv40->nvws->push_flush(nv40->nvws->channel, ((size) + 1)); \ + OUT_RING((nv40->obj->subc << 13) | ((size) << 18) | (mthd)); \ + nv40->nvws->channel->pushbuf->remaining -= ((size) + 1); \ +} while(0) + +#define BEGIN_RING_NI(obj,mthd,size) do { \ + BEGIN_RING(obj, (mthd) | 0x40000000, (size)); \ +} while(0) + +#define FIRE_RING() do { \ + nv40->nvws->push_flush(nv40->nvws->channel, 0); \ +} while(0) + +#define OUT_RELOC(bo,data,flags,vor,tor) do { \ + nv40->nvws->push_reloc(nv40->nvws->channel, \ + nv40->nvws->channel->pushbuf->cur, \ + (struct nouveau_bo *)(bo), \ + (data), (flags), (vor), (tor)); \ + OUT_RING(0); \ +} while(0) + +/* Raw data + flags depending on FB/TT buffer */ +#define OUT_RELOCd(bo,data,flags,vor,tor) do { \ + OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \ +} while(0) + +/* FB/TT object handle */ +#define OUT_RELOCo(bo,flags) do { \ + OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ + nv40->nvws->channel->vram->handle, \ + nv40->nvws->channel->gart->handle); \ +} while(0) + +/* Low 32-bits of offset */ +#define OUT_RELOCl(bo,delta,flags) do { \ + OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ +} while(0) + +/* High 32-bits of offset */ +#define OUT_RELOCh(bo,delta,flags) do { \ + OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \ +} while(0) + +#endif diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c new file mode 100644 index 0000000000..a39bb85e99 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -0,0 +1,62 @@ +#include "draw/draw_private.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" + +struct nv40_draw_stage { + struct draw_stage draw; + struct nv40_context *nv40; +}; + +static void +nv40_draw_point(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_line(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_tri(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_flush(struct draw_stage *draw, unsigned flags) +{ +} + +static void +nv40_draw_reset_stipple_counter(struct draw_stage *draw) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_destroy(struct draw_stage *draw) +{ + free(draw); +} + +struct draw_stage * +nv40_draw_render_stage(struct nv40_context *nv40) +{ + struct nv40_draw_stage *nv40draw = CALLOC_STRUCT(nv40_draw_stage); + + nv40draw->nv40 = nv40; + nv40draw->draw.draw = nv40->draw; + nv40draw->draw.point = nv40_draw_point; + nv40draw->draw.line = nv40_draw_line; + nv40draw->draw.tri = nv40_draw_tri; + nv40draw->draw.flush = nv40_draw_flush; + nv40draw->draw.reset_stipple_counter = nv40_draw_reset_stipple_counter; + nv40draw->draw.destroy = nv40_draw_destroy; + + return &nv40draw->draw; +} + diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c new file mode 100644 index 0000000000..07a418c1e9 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -0,0 +1,842 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv40_context.h" + +#define SWZ_X 0 +#define SWZ_Y 1 +#define SWZ_Z 2 +#define SWZ_W 3 +#define MASK_X 1 +#define MASK_Y 2 +#define MASK_Z 4 +#define MASK_W 8 +#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) +#define DEF_SCALE NV40_FP_OP_DST_SCALE_1X +#define DEF_CTEST NV40_FP_OP_COND_TR +#include "nv40_shader.h" + +#define swz(s,x,y,z,w) nv40_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv40_sr_neg((s)) +#define abs(s) nv40_sr_abs((s)) +#define scale(s,v) nv40_sr_scale((s), NV40_FP_OP_DST_SCALE_##v) + +#define MAX_CONSTS 128 +#define MAX_IMM 32 +struct nv40_fpc { + struct nv40_fragment_program *fp; + + uint attrib_map[PIPE_MAX_SHADER_INPUTS]; + + int high_temp; + int temp_temp_count; + int num_regs; + + uint depth_id; + uint colour_id; + + unsigned inst_offset; + + struct { + int pipe; + float vals[4]; + } consts[MAX_CONSTS]; + int nr_consts; + + struct nv40_sreg imm[MAX_IMM]; + unsigned nr_imm; +}; + +static INLINE struct nv40_sreg +temp(struct nv40_fpc *fpc) +{ + int idx; + + idx = fpc->temp_temp_count++; + idx += fpc->high_temp + 1; + return nv40_sr(NV40SR_TEMP, idx); +} + +static INLINE struct nv40_sreg +constant(struct nv40_fpc *fpc, int pipe, float vals[4]) +{ + int idx; + + if (fpc->nr_consts == MAX_CONSTS) + assert(0); + idx = fpc->nr_consts++; + + fpc->consts[idx].pipe = pipe; + if (pipe == -1) + memcpy(fpc->consts[idx].vals, vals, 4 * sizeof(float)); + return nv40_sr(NV40SR_CONST, idx); +} + +#define arith(cc,s,o,d,m,s0,s1,s2) \ + nv40_fp_arith((cc), (s), NV40_FP_OP_OPCODE_##o, \ + (d), (m), (s0), (s1), (s2)) +#define tex(cc,s,o,u,d,m,s0,s1,s2) \ + nv40_fp_tex((cc), (s), NV40_FP_OP_OPCODE_##o, (u), \ + (d), (m), (s0), none, none) + +static void +grow_insns(struct nv40_fpc *fpc, int size) +{ + struct nv40_fragment_program *fp = fpc->fp; + + fp->insn_len += size; + fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len); +} + +static void +emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src) +{ + struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; + uint32_t sr = 0; + + switch (src.type) { + case NV40SR_INPUT: + sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT); + hw[0] |= (src.index << NV40_FP_OP_INPUT_SRC_SHIFT); + break; + case NV40SR_OUTPUT: + sr |= NV40_FP_REG_SRC_HALF; + /* fall-through */ + case NV40SR_TEMP: + sr |= (NV40_FP_REG_TYPE_TEMP << NV40_FP_REG_TYPE_SHIFT); + sr |= (src.index << NV40_FP_REG_SRC_SHIFT); + break; + case NV40SR_CONST: + grow_insns(fpc, 4); + hw = &fp->insn[fpc->inst_offset]; + if (fpc->consts[src.index].pipe >= 0) { + struct nv40_fragment_program_data *fpd; + + fp->consts = realloc(fp->consts, ++fp->nr_consts * + sizeof(*fpd)); + fpd = &fp->consts[fp->nr_consts - 1]; + fpd->offset = fpc->inst_offset + 4; + fpd->index = fpc->consts[src.index].pipe; + memset(&fp->insn[fpd->offset], 0, sizeof(uint32_t) * 4); + } else { + memcpy(&fp->insn[fpc->inst_offset + 4], + fpc->consts[src.index].vals, + sizeof(uint32_t) * 4); + } + + sr |= (NV40_FP_REG_TYPE_CONST << NV40_FP_REG_TYPE_SHIFT); + break; + case NV40SR_NONE: + sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT); + break; + default: + assert(0); + } + + if (src.negate) + sr |= NV40_FP_REG_NEGATE; + + if (src.abs) + hw[1] |= (1 << (29 + pos)); + + sr |= ((src.swz[0] << NV40_FP_REG_SWZ_X_SHIFT) | + (src.swz[1] << NV40_FP_REG_SWZ_Y_SHIFT) | + (src.swz[2] << NV40_FP_REG_SWZ_Z_SHIFT) | + (src.swz[3] << NV40_FP_REG_SWZ_W_SHIFT)); + + hw[pos + 1] |= sr; +} + +static void +emit_dst(struct nv40_fpc *fpc, struct nv40_sreg dst) +{ + struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; + + switch (dst.type) { + case NV40SR_TEMP: + if (fpc->num_regs < (dst.index + 1)) + fpc->num_regs = dst.index + 1; + break; + case NV40SR_OUTPUT: + if (dst.index == 1) { + fp->fp_control |= 0xe; + } else { + hw[0] |= NV40_FP_OP_OUT_REG_HALF; + } + break; + case NV40SR_NONE: + hw[0] |= (1 << 30); + break; + default: + assert(0); + } + + hw[0] |= (dst.index << NV40_FP_OP_OUT_REG_SHIFT); +} + +static void +nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op, + struct nv40_sreg dst, int mask, + struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2) +{ + struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw; + + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + hw = &fp->insn[fpc->inst_offset]; + memset(hw, 0, sizeof(uint32_t) * 4); + + if (op == NV40_FP_OP_OPCODE_KIL) + fp->fp_control |= NV40TCL_FP_CONTROL_KIL; + hw[0] |= (op << NV40_FP_OP_OPCODE_SHIFT); + hw[0] |= (mask << NV40_FP_OP_OUTMASK_SHIFT); + hw[2] |= (dst.dst_scale << NV40_FP_OP_DST_SCALE_SHIFT); + + if (sat) + hw[0] |= NV40_FP_OP_OUT_SAT; + + if (dst.cc_update) + hw[0] |= NV40_FP_OP_COND_WRITE_ENABLE; + hw[1] |= (dst.cc_test << NV40_FP_OP_COND_SHIFT); + hw[1] |= ((dst.cc_swz[0] << NV40_FP_OP_COND_SWZ_X_SHIFT) | + (dst.cc_swz[1] << NV40_FP_OP_COND_SWZ_Y_SHIFT) | + (dst.cc_swz[2] << NV40_FP_OP_COND_SWZ_Z_SHIFT) | + (dst.cc_swz[3] << NV40_FP_OP_COND_SWZ_W_SHIFT)); + + emit_dst(fpc, dst); + emit_src(fpc, 0, s0); + emit_src(fpc, 1, s1); + emit_src(fpc, 2, s2); +} + +static void +nv40_fp_tex(struct nv40_fpc *fpc, int sat, int op, int unit, + struct nv40_sreg dst, int mask, + struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2) +{ + struct nv40_fragment_program *fp = fpc->fp; + + nv40_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2); + + fp->insn[fpc->inst_offset] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT); + fp->samplers |= (1 << unit); +} + +static INLINE struct nv40_sreg +tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc) +{ + struct nv40_sreg src; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + src = nv40_sr(NV40SR_INPUT, + fpc->attrib_map[fsrc->SrcRegister.Index]); + break; + case TGSI_FILE_CONSTANT: + src = constant(fpc, fsrc->SrcRegister.Index, NULL); + break; + case TGSI_FILE_IMMEDIATE: + assert(fsrc->SrcRegister.Index < fpc->nr_imm); + src = fpc->imm[fsrc->SrcRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + src = nv40_sr(NV40SR_TEMP, fsrc->SrcRegister.Index + 1); + if (fpc->high_temp < src.index) + fpc->high_temp = src.index; + break; + /* This is clearly insane, but gallium hands us shaders like this. + * Luckily fragprog results are just temp regs.. + */ + case TGSI_FILE_OUTPUT: + if (fsrc->SrcRegister.Index == fpc->colour_id) + return nv40_sr(NV40SR_OUTPUT, 0); + else + return nv40_sr(NV40SR_OUTPUT, 1); + break; + default: + NOUVEAU_ERR("bad src file\n"); + break; + } + + src.abs = fsrc->SrcRegisterExtMod.Absolute; + src.negate = fsrc->SrcRegister.Negate; + src.swz[0] = fsrc->SrcRegister.SwizzleX; + src.swz[1] = fsrc->SrcRegister.SwizzleY; + src.swz[2] = fsrc->SrcRegister.SwizzleZ; + src.swz[3] = fsrc->SrcRegister.SwizzleW; + return src; +} + +static INLINE struct nv40_sreg +tgsi_dst(struct nv40_fpc *fpc, const struct tgsi_full_dst_register *fdst) { + int idx; + + switch (fdst->DstRegister.File) { + case TGSI_FILE_OUTPUT: + if (fdst->DstRegister.Index == fpc->colour_id) + return nv40_sr(NV40SR_OUTPUT, 0); + else + return nv40_sr(NV40SR_OUTPUT, 1); + break; + case TGSI_FILE_TEMPORARY: + idx = fdst->DstRegister.Index + 1; + if (fpc->high_temp < idx) + fpc->high_temp = idx; + return nv40_sr(NV40SR_TEMP, idx); + case TGSI_FILE_NULL: + return nv40_sr(NV40SR_NONE, 0); + default: + NOUVEAU_ERR("bad dst file %d\n", fdst->DstRegister.File); + return nv40_sr(NV40SR_NONE, 0); + } +} + +static INLINE int +tgsi_mask(uint tgsi) +{ + int mask = 0; + + if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; + if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; + if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; + if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; + return mask; +} + +static boolean +src_native_swz(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc, + struct nv40_sreg *src) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg tgsi = tgsi_src(fpc, fsrc); + uint mask = 0, zero_mask = 0, one_mask = 0, neg_mask = 0; + uint neg[4] = { fsrc->SrcRegisterExtSwz.NegateX, + fsrc->SrcRegisterExtSwz.NegateY, + fsrc->SrcRegisterExtSwz.NegateZ, + fsrc->SrcRegisterExtSwz.NegateW }; + uint c; + + for (c = 0; c < 4; c++) { + switch (tgsi_util_get_full_src_register_extswizzle(fsrc, c)) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + mask |= (1 << c); + break; + case TGSI_EXTSWIZZLE_ZERO: + zero_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + case TGSI_EXTSWIZZLE_ONE: + one_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + default: + assert(0); + } + + if (!tgsi.negate && neg[c]) + neg_mask |= (1 << c); + } + + if (mask == MASK_ALL && !neg_mask) + return TRUE; + + *src = temp(fpc); + + if (mask) + arith(fpc, 0, MOV, *src, mask, tgsi, none, none); + + if (zero_mask) + arith(fpc, 0, SFL, *src, zero_mask, *src, none, none); + + if (one_mask) + arith(fpc, 0, STR, *src, one_mask, *src, none, none); + + if (neg_mask) { + struct nv40_sreg one = temp(fpc); + arith(fpc, 0, STR, one, neg_mask, one, none, none); + arith(fpc, 0, MUL, *src, neg_mask, *src, neg(one), none); + } + + return FALSE; +} + +static boolean +nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, + const struct tgsi_full_instruction *finst) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg src[3], dst, tmp; + int mask, sat, unit; + int ai = -1, ci = -1; + int i; + + if (finst->Instruction.Opcode == TGSI_OPCODE_END) + return TRUE; + + fpc->temp_temp_count = 0; + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) { + src[i] = tgsi_src(fpc, fsrc); + } + } + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + if (!src_native_swz(fpc, fsrc, &src[i])) + continue; + break; + default: + break; + } + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + if (ai == -1 || ai == fsrc->SrcRegister.Index) { + ai = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + NOUVEAU_MSG("extra src attr %d\n", + fsrc->SrcRegister.Index); + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_CONSTANT: + case TGSI_FILE_IMMEDIATE: + if (ci == -1 || ci == fsrc->SrcRegister.Index) { + ci = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_TEMPORARY: + /* handled above */ + break; + case TGSI_FILE_SAMPLER: + unit = fsrc->SrcRegister.Index; + break; + case TGSI_FILE_OUTPUT: + break; + default: + NOUVEAU_ERR("bad src file\n"); + return FALSE; + } + } + + dst = tgsi_dst(fpc, &finst->FullDstRegisters[0]); + mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + sat = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE); + + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + arith(fpc, sat, MOV, dst, mask, abs(src[0]), none, none); + break; + case TGSI_OPCODE_ADD: + arith(fpc, sat, ADD, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_CMP: + tmp = temp(fpc); + arith(fpc, sat, MOV, dst, mask, src[2], none, none); + tmp.cc_update = 1; + arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none); + dst.cc_test = NV40_VP_INST_COND_LT; + arith(fpc, sat, MOV, dst, mask, src[1], none, none); + break; + case TGSI_OPCODE_COS: + arith(fpc, sat, COS, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_DP3: + arith(fpc, sat, DP3, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DP4: + arith(fpc, sat, DP4, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DPH: + tmp = temp(fpc); + arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[1], none); + arith(fpc, sat, ADD, dst, mask, swz(tmp, X, X, X, X), + swz(src[1], W, W, W, W), none); + break; + case TGSI_OPCODE_DST: + arith(fpc, sat, DST, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_EX2: + arith(fpc, sat, EX2, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FLR: + arith(fpc, sat, FLR, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FRC: + arith(fpc, sat, FRC, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_KIL: + arith(fpc, 0, KIL, none, 0, none, none, none); + break; + case TGSI_OPCODE_KILP: + dst = nv40_sr(NV40SR_NONE, 0); + dst.cc_update = 1; + arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none); + dst.cc_update = 0; dst.cc_test = NV40_FP_OP_COND_LT; + arith(fpc, 0, KIL, dst, 0, none, none, none); + break; + case TGSI_OPCODE_LG2: + arith(fpc, sat, LG2, dst, mask, src[0], none, none); + break; +// case TGSI_OPCODE_LIT: + case TGSI_OPCODE_LRP: + tmp = temp(fpc); + arith(fpc, 0, MAD, tmp, mask, neg(src[0]), src[2], src[2]); + arith(fpc, sat, MAD, dst, mask, src[0], src[1], tmp); + break; + case TGSI_OPCODE_MAD: + arith(fpc, sat, MAD, dst, mask, src[0], src[1], src[2]); + break; + case TGSI_OPCODE_MAX: + arith(fpc, sat, MAX, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MIN: + arith(fpc, sat, MIN, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MOV: + arith(fpc, sat, MOV, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_MUL: + arith(fpc, sat, MUL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_POW: + tmp = temp(fpc); + arith(fpc, 0, LG2, tmp, MASK_X, + swz(src[0], X, X, X, X), none, none); + arith(fpc, 0, MUL, tmp, MASK_X, swz(tmp, X, X, X, X), + swz(src[1], X, X, X, X), none); + arith(fpc, sat, EX2, dst, mask, + swz(tmp, X, X, X, X), none, none); + break; + case TGSI_OPCODE_RCP: + arith(fpc, sat, RCP, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_RET: + assert(0); + break; + case TGSI_OPCODE_RFL: + tmp = temp(fpc); + arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[0], none); + arith(fpc, 0, DP3, tmp, MASK_Y, src[0], src[1], none); + arith(fpc, 0, DIV, scale(tmp, 2X), MASK_Z, + swz(tmp, Y, Y, Y, Y), swz(tmp, X, X, X, X), none); + arith(fpc, sat, MAD, dst, mask, + swz(tmp, Z, Z, Z, Z), src[0], neg(src[1])); + break; + case TGSI_OPCODE_RSQ: + tmp = temp(fpc); + arith(fpc, 0, LG2, scale(tmp, INV_2X), MASK_X, + abs(swz(src[0], X, X, X, X)), none, none); + arith(fpc, sat, EX2, dst, mask, + neg(swz(tmp, X, X, X, X)), none, none); + break; + case TGSI_OPCODE_SCS: + if (mask & MASK_X) { + arith(fpc, sat, COS, dst, MASK_X, + swz(src[0], X, X, X, X), none, none); + } + if (mask & MASK_Y) { + arith(fpc, sat, SIN, dst, MASK_Y, + swz(src[0], X, X, X, X), none, none); + } + break; + case TGSI_OPCODE_SIN: + arith(fpc, sat, SIN, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_SGE: + arith(fpc, sat, SGE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SLT: + arith(fpc, sat, SLT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SUB: + arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); + break; + case TGSI_OPCODE_TEX: + if (finst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide == + TGSI_EXTSWIZZLE_W) { + tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); + } else + tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_TXB: + tex(fpc, sat, TXB, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_XPD: + tmp = temp(fpc); + arith(fpc, 0, MUL, tmp, mask, + swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); + arith(fpc, sat, MAD, dst, (mask & ~MASK_W), + swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), + neg(tmp)); + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); + return FALSE; + } + + return TRUE; +} + +static boolean +nv40_fragprog_parse_decl_attrib(struct nv40_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV40_FP_OP_INPUT_SRC_POSITION; + break; + case TGSI_SEMANTIC_COLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV40_FP_OP_INPUT_SRC_COL0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV40_FP_OP_INPUT_SRC_COL1; + } else { + NOUVEAU_ERR("bad colour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_FOG: + hw = NV40_FP_OP_INPUT_SRC_FOGC; + break; + case TGSI_SEMANTIC_GENERIC: + if (fdec->Semantic.SemanticIndex <= 7) { + hw = NV40_FP_OP_INPUT_SRC_TC(fdec->Semantic. + SemanticIndex); + } else { + NOUVEAU_ERR("bad generic semantic index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad input semantic\n"); + return FALSE; + } + + fpc->attrib_map[fdec->u.DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + fpc->depth_id = fdec->u.DeclarationRange.First; + break; + case TGSI_SEMANTIC_COLOR: + fpc->colour_id = fdec->u.DeclarationRange.First; + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + return TRUE; +} + +void +nv40_fragprog_translate(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + struct tgsi_parse_context parse; + struct nv40_fpc *fpc = NULL; + + fpc = CALLOC(1, sizeof(struct nv40_fpc)); + if (!fpc) + return; + fpc->fp = fp; + fpc->high_temp = -1; + fpc->num_regs = 2; + + tgsi_parse_init(&parse, fp->pipe->tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + fdec = &parse.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_INPUT: + if (!nv40_fragprog_parse_decl_attrib(fpc, fdec)) + goto out_err; + break; + case TGSI_FILE_OUTPUT: + if (!nv40_fragprog_parse_decl_output(fpc, fdec)) + goto out_err; + break; + default: + break; + } + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm; + float vals[4]; + + imm = &parse.FullToken.FullImmediate; + assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); + assert(fpc->nr_imm < MAX_IMM); + + vals[0] = imm->u.ImmediateFloat32[0].Float; + vals[1] = imm->u.ImmediateFloat32[1].Float; + vals[2] = imm->u.ImmediateFloat32[2].Float; + vals[3] = imm->u.ImmediateFloat32[3].Float; + fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals); + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + + finst = &parse.FullToken.FullInstruction; + if (!nv40_fragprog_parse_instruction(fpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + fp->fp_control |= fpc->num_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT; + + /* Terminate final instruction */ + fp->insn[fpc->inst_offset] |= 0x00000001; + + /* Append NOP + END instruction, may or may not be necessary. */ + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + fp->insn[fpc->inst_offset + 0] = 0x00000001; + fp->insn[fpc->inst_offset + 1] = 0x00000000; + fp->insn[fpc->inst_offset + 2] = 0x00000000; + fp->insn[fpc->inst_offset + 3] = 0x00000000; + + fp->translated = TRUE; + fp->on_hw = FALSE; +out_err: + tgsi_parse_free(&parse); + free(fpc); +} + +void +nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) +{ + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_stateobj *so; + int i; + + if (!fp->translated) { + nv40_fragprog_translate(nv40, fp); + if (!fp->translated) + assert(0); + } + + if (fp->nr_consts) { + float *map = ws->buffer_map(ws, nv40->fragprog.constant_buf, + PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < fp->nr_consts; i++) { + struct nv40_fragment_program_data *fpd = &fp->consts[i]; + uint32_t *p = &fp->insn[fpd->offset]; + uint32_t *cb = (uint32_t *)&map[fpd->index * 4]; + + if (!memcmp(p, cb, 4 * sizeof(float))) + continue; + memcpy(p, cb, 4 * sizeof(float)); + fp->on_hw = 0; + } + ws->buffer_unmap(ws, nv40->fragprog.constant_buf); + } + + if (!fp->on_hw) { + const uint32_t le = 1; + uint32_t *map; + + if (!fp->buffer) + fp->buffer = ws->buffer_create(ws, 0x100, 0, + fp->insn_len * 4); + map = ws->buffer_map(ws, fp->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); + +#if 0 + for (i = 0; i < fp->insn_len; i++) { + NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); + } +#endif + + if ((*(const uint8_t *)&le)) { + for (i = 0; i < fp->insn_len; i++) { + map[i] = fp->insn[i]; + } + } else { + /* Weird swapping for big-endian chips */ + for (i = 0; i < fp->insn_len; i++) { + map[i] = ((fp->insn[i] & 0xffff) << 16) | + ((fp->insn[i] >> 16) & 0xffff); + } + } + + ws->buffer_unmap(ws, fp->buffer); + fp->on_hw = TRUE; + } + + so = so_new(4, 1); + so_method(so, nv40->hw->curie, NV40TCL_FP_ADDRESS, 1); + so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); + so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); + so_data (so, fp->fp_control); + + so_emit(nv40->nvws, so); + so_ref(so, &fp->so); + so_ref(NULL, &so); + + nv40->fragprog.active = fp; +} + +void +nv40_fragprog_destroy(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + if (fp->insn_len) + free(fp->insn); +} + diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c new file mode 100644 index 0000000000..5af5fbe746 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -0,0 +1,151 @@ +#include "nv40_context.h" + +#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ +{ \ + TRUE, \ + PIPE_FORMAT_##m, \ + NV40TCL_TEX_FORMAT_FORMAT_##tf, \ + (NV40TCL_TEX_SWIZZLE_S0_X_##ts0x | NV40TCL_TEX_SWIZZLE_S0_Y_##ts0y | \ + NV40TCL_TEX_SWIZZLE_S0_Z_##ts0z | NV40TCL_TEX_SWIZZLE_S0_W_##ts0w | \ + NV40TCL_TEX_SWIZZLE_S1_X_##ts1x | NV40TCL_TEX_SWIZZLE_S1_Y_##ts1y | \ + NV40TCL_TEX_SWIZZLE_S1_Z_##ts1z | NV40TCL_TEX_SWIZZLE_S1_W_##ts1w), \ +} + +struct nv40_texture_format { + boolean defined; + uint pipe; + int format; + int swizzle; +}; + +static struct nv40_texture_format +nv40_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W), + _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W), + _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W), + _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W), + _(U_L8 , L8 , S1, S1, S1, ONE, X, X, X, X), + _(U_A8 , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), + _(U_I8 , L8 , S1, S1, S1, S1, X, X, X, X), + _(U_A8_L8 , A8L8 , S1, S1, S1, S1, X, X, X, Y), + _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X), + _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X), +// _(RGB_DXT1 , 0x86, S1, S1, S1, ONE, X, Y, Z, W, 0x00, 0x00), +// _(RGBA_DXT1 , 0x86, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), +// _(RGBA_DXT3 , 0x87, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), +// _(RGBA_DXT5 , 0x88, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), + {}, +}; + +static struct nv40_texture_format * +nv40_fragtex_format(uint pipe_format) +{ + struct nv40_texture_format *tf = nv40_texture_formats; + + while (tf->defined) { + if (tf->pipe == pipe_format) + return tf; + tf++; + } + + return NULL; +} + + +static void +nv40_fragtex_build(struct nv40_context *nv40, int unit) +{ + struct nv40_sampler_state *ps = nv40->tex_sampler[unit]; + struct nv40_miptree *nv40mt = nv40->tex_miptree[unit]; + struct pipe_texture *pt = &nv40mt->base; + struct nv40_texture_format *tf; + struct nouveau_stateobj *so; + uint32_t txf, txs, txp; + int swizzled = 0; /*XXX: implement in region code? */ + unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + tf = nv40_fragtex_format(pt->format); + if (!tf) + assert(0); + + txf = ps->fmt; + txf |= tf->format | 0x8000; + txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT); + + if (1) /* XXX */ + txf |= NV40TCL_TEX_FORMAT_NO_BORDER; + + switch (pt->target) { + case PIPE_TEXTURE_CUBE: + txf |= NV40TCL_TEX_FORMAT_CUBIC; + /* fall-through */ + case PIPE_TEXTURE_2D: + txf |= NV40TCL_TEX_FORMAT_DIMS_2D; + break; + case PIPE_TEXTURE_3D: + txf |= NV40TCL_TEX_FORMAT_DIMS_3D; + break; + case PIPE_TEXTURE_1D: + txf |= NV40TCL_TEX_FORMAT_DIMS_1D; + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return; + } + + if (swizzled) { + txp = 0; + } else { + txp = nv40mt->level[0].pitch; + txf |= NV40TCL_TEX_FORMAT_LINEAR; + } + + txs = tf->swizzle; + + so = so_new(16, 2); + so_method(so, nv40->hw->curie, NV40TCL_TEX_OFFSET(unit), 8); + so_reloc (so, nv40mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); + so_reloc (so, nv40mt->buffer, txf, tex_flags | NOUVEAU_BO_OR, + NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1); + so_data (so, ps->wrap); + so_data (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en); + so_data (so, txs); + so_data (so, ps->filt | 0x2000 /*voodoo*/); + so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | + pt->height[0]); + so_data (so, ps->bcol); + so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); + so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); + + so_emit(nv40->nvws, so); + so_ref (so, &nv40->so_fragtex[unit]); + so_ref (NULL, &so); +} + +void +nv40_fragtex_bind(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog.active; + unsigned samplers, unit; + + samplers = nv40->fp_samplers & ~fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + so_ref(NULL, &nv40->so_fragtex[unit]); + BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1); + OUT_RING (0); + } + + samplers = nv40->dirty_samplers & fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + nv40_fragtex_build(nv40, unit); + } + + nv40->fp_samplers = fp->samplers; +} + diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c new file mode 100644 index 0000000000..92e6b3a43d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -0,0 +1,104 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv40_context.h" + +static void +nv40_miptree_layout(struct nv40_miptree *nv40mt) +{ + struct pipe_texture *pt = &nv40mt->base; + boolean swizzled = FALSE; + uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint offset = 0; + int nr_faces, l, f; + + if (pt->target == PIPE_TEXTURE_CUBE) { + nr_faces = 6; + } else + if (pt->target == PIPE_TEXTURE_3D) { + nr_faces = pt->depth[0]; + } else { + nr_faces = 1; + } + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + nv40mt->level[l].pitch = pt->width[l] * pt->cpp; + else + nv40mt->level[l].pitch = pt->width[0] * pt->cpp; + nv40mt->level[l].pitch = (nv40mt->level[l].pitch + 63) & ~63; + + nv40mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + depth = MAX2(1, depth >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv40mt->level[l].image_offset[f] = offset; + offset += nv40mt->level[l].pitch * pt->height[l]; + } + } + + nv40mt->total_size = offset; +} + +static struct pipe_texture * +nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = pipe->winsys; + struct nv40_miptree *mt; + + mt = MALLOC(sizeof(struct nv40_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + nv40_miptree_layout(mt); + + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->total_size); + if (!mt->buffer) { + free(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = pipe->winsys; + struct pipe_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv40_miptree *nv40mt = (struct nv40_miptree *)mt; + int l; + + pipe_buffer_reference(ws, &nv40mt->buffer, NULL); + for (l = 0; l <= mt->last_level; l++) { + if (nv40mt->level[l].image_offset) + free(nv40mt->level[l].image_offset); + } + free(nv40mt); + } +} + +void +nv40_init_miptree_functions(struct nv40_context *nv40) +{ + nv40->pipe.texture_create = nv40_miptree_create; + nv40->pipe.texture_release = nv40_miptree_release; +} + diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c new file mode 100644 index 0000000000..8bca2788b9 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -0,0 +1,113 @@ +#include "pipe/p_context.h" + +#include "nv40_context.h" + +struct nv40_query { + struct nouveau_resource *object; + unsigned type; + boolean ready; + uint64_t result; +}; + +static INLINE struct nv40_query * +nv40_query(struct pipe_query *pipe) +{ + return (struct nv40_query *)pipe; +} + +static struct pipe_query * +nv40_query_create(struct pipe_context *pipe, unsigned query_type) +{ + struct nv40_query *q; + + q = CALLOC(1, sizeof(struct nv40_query)); + q->type = query_type; + + return (struct pipe_query *)q; +} + +static void +nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + + if (q->object) + nv40->nvws->res_free(&q->object); + free(q); +} + +static void +nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + + assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); + + if (nv40->nvws->res_alloc(nv40->hw->query_heap, 1, NULL, &q->object)) + assert(0); + nv40->nvws->notifier_reset(nv40->hw->query, q->object->start); + + BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1); + OUT_RING (1); + BEGIN_RING(curie, NV40TCL_QUERY_UNK17CC, 1); + OUT_RING (1); + + q->ready = FALSE; +} + +static void +nv40_query_end(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + + BEGIN_RING(curie, NV40TCL_QUERY_GET, 1); + OUT_RING ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) | + ((q->object->start * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT)); + FIRE_RING(); +} + +static boolean +nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq, + boolean wait, uint64 *result) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + struct nouveau_winsys *nvws = nv40->nvws; + + assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER); + + if (!q->ready) { + unsigned status; + + status = nvws->notifier_status(nv40->hw->query, + q->object->start); + if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { + if (wait == FALSE) + return FALSE; + nvws->notifier_wait(nv40->hw->query, q->object->start, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0); + } + + q->result = nvws->notifier_retval(nv40->hw->query, + q->object->start); + q->ready = TRUE; + nvws->res_free(&q->object); + } + + *result = q->result; + return TRUE; +} + +void +nv40_init_query_functions(struct nv40_context *nv40) +{ + nv40->pipe.create_query = nv40_query_create; + nv40->pipe.destroy_query = nv40_query_destroy; + nv40->pipe.begin_query = nv40_query_begin; + nv40->pipe.end_query = nv40_query_end; + nv40->pipe.get_query_result = nv40_query_result; +} diff --git a/src/gallium/drivers/nv40/nv40_shader.h b/src/gallium/drivers/nv40/nv40_shader.h new file mode 100644 index 0000000000..5909c70713 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_shader.h @@ -0,0 +1,554 @@ +#ifndef __NV40_SHADER_H__ +#define __NV40_SHADER_H__ + +/* Vertex programs instruction set + * + * The NV40 instruction set is very similar to NV30. Most fields are in + * a slightly different position in the instruction however. + * + * Merged instructions + * In some cases it is possible to put two instructions into one opcode + * slot. The rules for when this is OK is not entirely clear to me yet. + * + * There are separate writemasks and dest temp register fields for each + * grouping of instructions. There is however only one field with the + * ID of a result register. Writing to temp/result regs is selected by + * setting VEC_RESULT/SCA_RESULT. + * + * Temporary registers + * The source/dest temp register fields have been extended by 1 bit, to + * give a total of 32 temporary registers. + * + * Relative Addressing + * NV40 can use an address register to index into vertex attribute regs. + * This is done by putting the offset value into INPUT_SRC and setting + * the INDEX_INPUT flag. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * There is a second condition code register on NV40, it's use is enabled + * by setting the COND_REG_SELECT_1 flag. + * + * Texture lookup + * TODO + */ + +/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */ +#define NV40_VP_INST_VEC_RESULT (1 << 30) +/* uncertain.. */ +#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29) +/* use address reg as index into attribs */ +#define NV40_VP_INST_INDEX_INPUT (1 << 27) +#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25) +#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV40_VP_INST_SRC2_ABS (1 << 23) +#define NV40_VP_INST_SRC1_ABS (1 << 22) +#define NV40_VP_INST_SRC0_ABS (1 << 21) +#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15 +#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15) +#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13) +#define NV40_VP_INST_COND_SHIFT 10 +#define NV40_VP_INST_COND_MASK (0x7 << 10) +# define NV40_VP_INST_COND_FL 0 +# define NV40_VP_INST_COND_LT 1 +# define NV40_VP_INST_COND_EQ 2 +# define NV40_VP_INST_COND_LE 3 +# define NV40_VP_INST_COND_GT 4 +# define NV40_VP_INST_COND_NE 5 +# define NV40_VP_INST_COND_GE 6 +# define NV40_VP_INST_COND_TR 7 +#define NV40_VP_INST_COND_SWZ_X_SHIFT 8 +#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8) +#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6 +#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6) +#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4 +#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4) +#define NV40_VP_INST_COND_SWZ_W_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2) +#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2) +#define NV40_VP_INST_ADDR_SWZ_SHIFT 0 +#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0) +#define NV40_VP_INST0_KNOWN ( \ + NV40_VP_INST_INDEX_INPUT | \ + NV40_VP_INST_COND_REG_SELECT_1 | \ + NV40_VP_INST_ADDR_REG_SELECT_1 | \ + NV40_VP_INST_SRC2_ABS | \ + NV40_VP_INST_SRC1_ABS | \ + NV40_VP_INST_SRC0_ABS | \ + NV40_VP_INST_VEC_DEST_TEMP_MASK | \ + NV40_VP_INST_COND_TEST_ENABLE | \ + NV40_VP_INST_COND_MASK | \ + NV40_VP_INST_COND_SWZ_ALL_MASK | \ + NV40_VP_INST_ADDR_SWZ_MASK) + +/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */ +#define NV40_VP_INST_VEC_OPCODE_SHIFT 22 +#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22) +# define NV40_VP_INST_OP_NOP 0x00 +# define NV40_VP_INST_OP_MOV 0x01 +# define NV40_VP_INST_OP_MUL 0x02 +# define NV40_VP_INST_OP_ADD 0x03 +# define NV40_VP_INST_OP_MAD 0x04 +# define NV40_VP_INST_OP_DP3 0x05 +# define NV40_VP_INST_OP_DPH 0x06 +# define NV40_VP_INST_OP_DP4 0x07 +# define NV40_VP_INST_OP_DST 0x08 +# define NV40_VP_INST_OP_MIN 0x09 +# define NV40_VP_INST_OP_MAX 0x0A +# define NV40_VP_INST_OP_SLT 0x0B +# define NV40_VP_INST_OP_SGE 0x0C +# define NV40_VP_INST_OP_ARL 0x0D +# define NV40_VP_INST_OP_FRC 0x0E +# define NV40_VP_INST_OP_FLR 0x0F +# define NV40_VP_INST_OP_SEQ 0x10 +# define NV40_VP_INST_OP_SFL 0x11 +# define NV40_VP_INST_OP_SGT 0x12 +# define NV40_VP_INST_OP_SLE 0x13 +# define NV40_VP_INST_OP_SNE 0x14 +# define NV40_VP_INST_OP_STR 0x15 +# define NV40_VP_INST_OP_SSG 0x16 +# define NV40_VP_INST_OP_ARR 0x17 +# define NV40_VP_INST_OP_ARA 0x18 +# define NV40_VP_INST_OP_TXL 0x19 +#define NV40_VP_INST_SCA_OPCODE_SHIFT 27 +#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27) +# define NV40_VP_INST_OP_NOP 0x00 +# define NV40_VP_INST_OP_MOV 0x01 +# define NV40_VP_INST_OP_RCP 0x02 +# define NV40_VP_INST_OP_RCC 0x03 +# define NV40_VP_INST_OP_RSQ 0x04 +# define NV40_VP_INST_OP_EXP 0x05 +# define NV40_VP_INST_OP_LOG 0x06 +# define NV40_VP_INST_OP_LIT 0x07 +# define NV40_VP_INST_OP_BRA 0x09 +# define NV40_VP_INST_OP_CAL 0x0B +# define NV40_VP_INST_OP_RET 0x0C +# define NV40_VP_INST_OP_LG2 0x0D +# define NV40_VP_INST_OP_EX2 0x0E +# define NV40_VP_INST_OP_SIN 0x0F +# define NV40_VP_INST_OP_COS 0x10 +# define NV40_VP_INST_OP_PUSHA 0x13 +# define NV40_VP_INST_OP_POPA 0x14 +#define NV40_VP_INST_CONST_SRC_SHIFT 12 +#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12) +#define NV40_VP_INST_INPUT_SRC_SHIFT 8 +#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8) +# define NV40_VP_INST_IN_POS 0 +# define NV40_VP_INST_IN_WEIGHT 1 +# define NV40_VP_INST_IN_NORMAL 2 +# define NV40_VP_INST_IN_COL0 3 +# define NV40_VP_INST_IN_COL1 4 +# define NV40_VP_INST_IN_FOGC 5 +# define NV40_VP_INST_IN_TC0 8 +# define NV40_VP_INST_IN_TC(n) (8+n) +#define NV40_VP_INST_SRC0H_SHIFT 0 +#define NV40_VP_INST_SRC0H_MASK (0xFF << 0) +#define NV40_VP_INST1_KNOWN ( \ + NV40_VP_INST_VEC_OPCODE_MASK | \ + NV40_VP_INST_SCA_OPCODE_MASK | \ + NV40_VP_INST_CONST_SRC_MASK | \ + NV40_VP_INST_INPUT_SRC_MASK | \ + NV40_VP_INST_SRC0H_MASK \ + ) + +/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */ +#define NV40_VP_INST_SRC0L_SHIFT 23 +#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23) +#define NV40_VP_INST_SRC1_SHIFT 6 +#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6) +#define NV40_VP_INST_SRC2H_SHIFT 0 +#define NV40_VP_INST_SRC2H_MASK (0x3F << 0) +#define NV40_VP_INST_IADDRH_SHIFT 0 +#define NV40_VP_INST_IADDRH_MASK (0x1F << 0) + +/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */ +#define NV40_VP_INST_IADDRL_SHIFT 29 +#define NV40_VP_INST_IADDRL_MASK (7 << 29) +#define NV40_VP_INST_SRC2L_SHIFT 21 +#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21) +#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17 +#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17) +# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20) +# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19) +# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18) +# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17) +#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13 +#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13) +# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16) +# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15) +# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14) +# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13) +#define NV40_VP_INST_SCA_RESULT (1 << 12) +#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7 +#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7) +#define NV40_VP_INST_DEST_SHIFT 2 +#define NV40_VP_INST_DEST_MASK (31 << 2) +# define NV40_VP_INST_DEST_POS 0 +# define NV40_VP_INST_DEST_COL0 1 +# define NV40_VP_INST_DEST_COL1 2 +# define NV40_VP_INST_DEST_BFC0 3 +# define NV40_VP_INST_DEST_BFC1 4 +# define NV40_VP_INST_DEST_FOGC 5 +# define NV40_VP_INST_DEST_PSZ 6 +# define NV40_VP_INST_DEST_TC0 7 +# define NV40_VP_INST_DEST_TC(n) (7+n) +# define NV40_VP_INST_DEST_TEMP 0x1F +#define NV40_VP_INST_INDEX_CONST (1 << 1) +#define NV40_VP_INST_LAST (1 << 0) +#define NV40_VP_INST3_KNOWN ( \ + NV40_VP_INST_SRC2L_MASK |\ + NV40_VP_INST_SCA_WRITEMASK_MASK |\ + NV40_VP_INST_VEC_WRITEMASK_MASK |\ + NV40_VP_INST_SCA_DEST_TEMP_MASK |\ + NV40_VP_INST_DEST_MASK |\ + NV40_VP_INST_INDEX_CONST) + +/* Useful to split the source selection regs into their pieces */ +#define NV40_VP_SRC0_HIGH_SHIFT 9 +#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00 +#define NV40_VP_SRC0_LOW_MASK 0x000001FF +#define NV40_VP_SRC2_HIGH_SHIFT 11 +#define NV40_VP_SRC2_HIGH_MASK 0x0001F800 +#define NV40_VP_SRC2_LOW_MASK 0x000007FF + +/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */ +#define NV40_VP_SRC_NEGATE (1 << 16) +#define NV40_VP_SRC_SWZ_X_SHIFT 14 +#define NV40_VP_SRC_SWZ_X_MASK (3 << 14) +#define NV40_VP_SRC_SWZ_Y_SHIFT 12 +#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12) +#define NV40_VP_SRC_SWZ_Z_SHIFT 10 +#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10) +#define NV40_VP_SRC_SWZ_W_SHIFT 8 +#define NV40_VP_SRC_SWZ_W_MASK (3 << 8) +#define NV40_VP_SRC_SWZ_ALL_SHIFT 8 +#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8) +#define NV40_VP_SRC_TEMP_SRC_SHIFT 2 +#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2) +#define NV40_VP_SRC_REG_TYPE_SHIFT 0 +#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0) +# define NV40_VP_SRC_REG_TYPE_UNK0 0 +# define NV40_VP_SRC_REG_TYPE_TEMP 1 +# define NV40_VP_SRC_REG_TYPE_INPUT 2 +# define NV40_VP_SRC_REG_TYPE_CONST 3 + + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, + * NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and + * SWIZZLE_ONE. + * + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as + * SWIZZLE_ZERO is implemented simply by not writing to the relevant components + * of the destination. + * + * Looping + * Loops appear to be fairly expensive on NV40 at least, the proprietary + * driver goes to a lot of effort to avoid using the native looping + * instructions. If the total number of *executed* instructions between + * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop. + * The maximum loop count is 255. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + * DP2 - MUL + ADD + * NRM + */ + +//== Opcode / Destination selection == +#define NV40_FP_OP_PROGRAM_END (1 << 0) +#define NV40_FP_OP_OUT_REG_SHIFT 1 +#define NV40_FP_OP_OUT_REG_MASK (63 << 1) +/* Needs to be set when writing outputs to get expected result.. */ +#define NV40_FP_OP_OUT_REG_HALF (1 << 7) +#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV40_FP_OP_OUTMASK_SHIFT 9 +#define NV40_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV40_FP_OP_OUT_X (1 << 9) +# define NV40_FP_OP_OUT_Y (1 <<10) +# define NV40_FP_OP_OUT_Z (1 <<11) +# define NV40_FP_OP_OUT_W (1 <<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV40_FP_OP_INPUT_SRC_SHIFT 13 +#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV40_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV40_FP_OP_INPUT_SRC_COL0 0x1 +# define NV40_FP_OP_INPUT_SRC_COL1 0x2 +# define NV40_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV40_FP_OP_INPUT_SRC_TC0 0x4 +# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +# define NV40_FP_OP_INPUT_SRC_FACING 0xE +#define NV40_FP_OP_TEX_UNIT_SHIFT 17 +#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17) +#define NV40_FP_OP_PRECISION_SHIFT 22 +#define NV40_FP_OP_PRECISION_MASK (3 << 22) +# define NV40_FP_PRECISION_FP32 0 +# define NV40_FP_PRECISION_FP16 1 +# define NV40_FP_PRECISION_FX12 2 +#define NV40_FP_OP_OPCODE_SHIFT 24 +#define NV40_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV40_FP_OP_OPCODE_NOP 0x00 +# define NV40_FP_OP_OPCODE_MOV 0x01 +# define NV40_FP_OP_OPCODE_MUL 0x02 +# define NV40_FP_OP_OPCODE_ADD 0x03 +# define NV40_FP_OP_OPCODE_MAD 0x04 +# define NV40_FP_OP_OPCODE_DP3 0x05 +# define NV40_FP_OP_OPCODE_DP4 0x06 +# define NV40_FP_OP_OPCODE_DST 0x07 +# define NV40_FP_OP_OPCODE_MIN 0x08 +# define NV40_FP_OP_OPCODE_MAX 0x09 +# define NV40_FP_OP_OPCODE_SLT 0x0A +# define NV40_FP_OP_OPCODE_SGE 0x0B +# define NV40_FP_OP_OPCODE_SLE 0x0C +# define NV40_FP_OP_OPCODE_SGT 0x0D +# define NV40_FP_OP_OPCODE_SNE 0x0E +# define NV40_FP_OP_OPCODE_SEQ 0x0F +# define NV40_FP_OP_OPCODE_FRC 0x10 +# define NV40_FP_OP_OPCODE_FLR 0x11 +# define NV40_FP_OP_OPCODE_KIL 0x12 +# define NV40_FP_OP_OPCODE_PK4B 0x13 +# define NV40_FP_OP_OPCODE_UP4B 0x14 +/* DDX/DDY can only write to XY */ +# define NV40_FP_OP_OPCODE_DDX 0x15 +# define NV40_FP_OP_OPCODE_DDY 0x16 +# define NV40_FP_OP_OPCODE_TEX 0x17 +# define NV40_FP_OP_OPCODE_TXP 0x18 +# define NV40_FP_OP_OPCODE_TXD 0x19 +# define NV40_FP_OP_OPCODE_RCP 0x1A +# define NV40_FP_OP_OPCODE_EX2 0x1C +# define NV40_FP_OP_OPCODE_LG2 0x1D +# define NV40_FP_OP_OPCODE_STR 0x20 +# define NV40_FP_OP_OPCODE_SFL 0x21 +# define NV40_FP_OP_OPCODE_COS 0x22 +# define NV40_FP_OP_OPCODE_SIN 0x23 +# define NV40_FP_OP_OPCODE_PK2H 0x24 +# define NV40_FP_OP_OPCODE_UP2H 0x25 +# define NV40_FP_OP_OPCODE_PK4UB 0x27 +# define NV40_FP_OP_OPCODE_UP4UB 0x28 +# define NV40_FP_OP_OPCODE_PK2US 0x29 +# define NV40_FP_OP_OPCODE_UP2US 0x2A +# define NV40_FP_OP_OPCODE_DP2A 0x2E +# define NV40_FP_OP_OPCODE_TXL 0x2F +# define NV40_FP_OP_OPCODE_TXB 0x31 +# define NV40_FP_OP_OPCODE_DIV 0x3A +# define NV40_FP_OP_OPCODE_UNK_LIT 0x3C +/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/ +# define NV40_FP_OP_BRA_OPCODE_BRK 0x0 +# define NV40_FP_OP_BRA_OPCODE_CAL 0x1 +# define NV40_FP_OP_BRA_OPCODE_IF 0x2 +# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3 +# define NV40_FP_OP_BRA_OPCODE_REP 0x4 +# define NV40_FP_OP_BRA_OPCODE_RET 0x5 +#define NV40_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV40_FP_OP_OUT_ABS (1 << 29) +#define NV40_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV40_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV40_FP_OP_COND_SHIFT 18 +#define NV40_FP_OP_COND_MASK (0x07 << 18) +# define NV40_FP_OP_COND_FL 0 +# define NV40_FP_OP_COND_LT 1 +# define NV40_FP_OP_COND_EQ 2 +# define NV40_FP_OP_COND_LE 3 +# define NV40_FP_OP_COND_GT 4 +# define NV40_FP_OP_COND_NE 5 +# define NV40_FP_OP_COND_GE 6 +# define NV40_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31) +#define NV40_FP_OP_DST_SCALE_SHIFT 28 +#define NV40_FP_OP_DST_SCALE_MASK (3 << 28) +#define NV40_FP_OP_DST_SCALE_1X 0 +#define NV40_FP_OP_DST_SCALE_2X 1 +#define NV40_FP_OP_DST_SCALE_4X 2 +#define NV40_FP_OP_DST_SCALE_8X 3 +#define NV40_FP_OP_DST_SCALE_INV_2X 5 +#define NV40_FP_OP_DST_SCALE_INV_4X 6 +#define NV40_FP_OP_DST_SCALE_INV_8X 7 + +/* SRC1 LOOP */ +#define NV40_FP_OP_LOOP_INCR_SHIFT 19 +#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19) +#define NV40_FP_OP_LOOP_INDEX_SHIFT 10 +#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10) +#define NV40_FP_OP_LOOP_COUNT_SHIFT 2 +#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2) + +/* SRC1 IF */ +#define NV40_FP_OP_ELSE_ID_SHIFT 2 +#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2) + +/* SRC1 CAL */ +#define NV40_FP_OP_IADDR_SHIFT 2 +#define NV40_FP_OP_IADDR_MASK (0xFF << 2) + +/* SRC1 REP + * I have no idea why there are 3 count values here.. but they + * have always been filled with the same value in my tests so + * far.. + */ +#define NV40_FP_OP_REP_COUNT1_SHIFT 2 +#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2) +#define NV40_FP_OP_REP_COUNT2_SHIFT 10 +#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10) +#define NV40_FP_OP_REP_COUNT3_SHIFT 19 +#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19) + +/* SRC2 REP/IF */ +#define NV40_FP_OP_END_ID_SHIFT 2 +#define NV40_FP_OP_END_ID_MASK (0xFF << 2) + +// SRC2 high-order +#define NV40_FP_OP_INDEX_INPUT (1 << 30) +#define NV40_FP_OP_ADDR_INDEX_SHIFT 19 +#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19) + +//== Register selection == +#define NV40_FP_REG_TYPE_SHIFT 0 +#define NV40_FP_REG_TYPE_MASK (3 << 0) +# define NV40_FP_REG_TYPE_TEMP 0 +# define NV40_FP_REG_TYPE_INPUT 1 +# define NV40_FP_REG_TYPE_CONST 2 +#define NV40_FP_REG_SRC_SHIFT 2 +#define NV40_FP_REG_SRC_MASK (63 << 2) +#define NV40_FP_REG_SRC_HALF (1 << 8) +#define NV40_FP_REG_SWZ_ALL_SHIFT 9 +#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV40_FP_REG_SWZ_X_SHIFT 9 +#define NV40_FP_REG_SWZ_X_MASK (3 << 9) +#define NV40_FP_REG_SWZ_Y_SHIFT 11 +#define NV40_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV40_FP_REG_SWZ_Z_SHIFT 13 +#define NV40_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV40_FP_REG_SWZ_W_SHIFT 15 +#define NV40_FP_REG_SWZ_W_MASK (3 << 15) +# define NV40_FP_SWIZZLE_X 0 +# define NV40_FP_SWIZZLE_Y 1 +# define NV40_FP_SWIZZLE_Z 2 +# define NV40_FP_SWIZZLE_W 3 +#define NV40_FP_REG_NEGATE (1 << 17) + +#define NV40SR_NONE 0 +#define NV40SR_OUTPUT 1 +#define NV40SR_INPUT 2 +#define NV40SR_TEMP 3 +#define NV40SR_CONST 4 + +struct nv40_sreg { + int type; + int index; + + int dst_scale; + + int negate; + int abs; + int swz[4]; + + int cc_update; + int cc_update_reg; + int cc_test; + int cc_test_reg; + int cc_swz[4]; +}; + +static INLINE struct nv40_sreg +nv40_sr(int type, int index) +{ + struct nv40_sreg temp = { + .type = type, + .index = index, + .dst_scale = DEF_SCALE, + .abs = 0, + .negate = 0, + .swz = { 0, 1, 2, 3 }, + .cc_update = 0, + .cc_update_reg = 0, + .cc_test = DEF_CTEST, + .cc_test_reg = 0, + .cc_swz = { 0, 1, 2, 3 }, + }; + return temp; +} + +static INLINE struct nv40_sreg +nv40_sr_swz(struct nv40_sreg src, int x, int y, int z, int w) +{ + struct nv40_sreg dst = src; + + dst.swz[SWZ_X] = src.swz[x]; + dst.swz[SWZ_Y] = src.swz[y]; + dst.swz[SWZ_Z] = src.swz[z]; + dst.swz[SWZ_W] = src.swz[w]; + return dst; +} + +static INLINE struct nv40_sreg +nv40_sr_neg(struct nv40_sreg src) +{ + src.negate = !src.negate; + return src; +} + +static INLINE struct nv40_sreg +nv40_sr_abs(struct nv40_sreg src) +{ + src.abs = 1; + return src; +} + +static INLINE struct nv40_sreg +nv40_sr_scale(struct nv40_sreg src, int scale) +{ + src.dst_scale = scale; + return src; +} + +#endif diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c new file mode 100644 index 0000000000..713f31dbb1 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -0,0 +1,823 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_state.h" + +static void * +nv40_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_stateobj *so = so_new(16, 0); + + if (cso->blend_enable) { + so_method(so, curie, NV40TCL_BLEND_ENABLE, 3); + so_data (so, 1); + so_data (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) | + nvgl_blend_func(cso->rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rgb_dst_factor)); + so_method(so, curie, NV40TCL_BLEND_EQUATION, 1); + so_data (so, nvgl_blend_eqn(cso->alpha_func) << 16 | + nvgl_blend_eqn(cso->rgb_func)); + } else { + so_method(so, curie, NV40TCL_BLEND_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, curie, NV40TCL_COLOR_MASK, 1); + so_data (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + + if (cso->logicop_enable) { + so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2); + so_data (so, 1); + so_data (so, nvgl_logicop_func(cso->logicop_func)); + } else { + so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); + so_data (so, cso->dither ? 1 : 0); + + return (void *)so; +} + +static void +nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + so_ref(hwcso, &nv40->so_blend); + nv40->dirty |= NV40_NEW_BLEND; +} + +static void +nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nouveau_stateobj *so = hwcso; + + so_ref(NULL, &so); +} + + +static INLINE unsigned +wrap_mode(unsigned wrap) { + unsigned ret; + + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + ret = NV40TCL_TEX_WRAP_S_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV40TCL_TEX_WRAP_S_CLAMP; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP; + break; + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + ret = NV40TCL_TEX_WRAP_S_REPEAT; + break; + } + + return ret >> NV40TCL_TEX_WRAP_S_SHIFT; +} + +static void * +nv40_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + struct nv40_sampler_state *ps; + uint32_t filter = 0; + + ps = MALLOC(sizeof(struct nv40_sampler_state)); + + ps->fmt = 0; + if (!cso->normalized_coords) + ps->fmt |= NV40TCL_TEX_FORMAT_RECT; + + ps->wrap = ((wrap_mode(cso->wrap_s) << NV40TCL_TEX_WRAP_S_SHIFT) | + (wrap_mode(cso->wrap_t) << NV40TCL_TEX_WRAP_T_SHIFT) | + (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT)); + + ps->en = 0; + if (cso->max_anisotropy >= 2.0) { + /* no idea, binary driver sets it, works without it.. meh.. */ + ps->wrap |= (1 << 5); + + if (cso->max_anisotropy >= 16.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X; + } else + if (cso->max_anisotropy >= 12.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X; + } else + if (cso->max_anisotropy >= 10.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X; + } else + if (cso->max_anisotropy >= 8.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X; + } else + if (cso->max_anisotropy >= 6.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X; + } else + if (cso->max_anisotropy >= 4.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X; + } else { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X; + } + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV40TCL_TEX_FILTER_MAG_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV40TCL_TEX_FILTER_MAG_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV40TCL_TEX_FILTER_MIN_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV40TCL_TEX_FILTER_MIN_NEAREST; + break; + } + break; + } + + ps->filt = filter; + + { + float limit; + + limit = CLAMP(cso->lod_bias, -16.0, 15.0); + ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff; + + limit = CLAMP(cso->max_lod, 0.0, 15.0); + ps->en |= (int)(limit * 256.0) << 7; + + limit = CLAMP(cso->min_lod, 0.0, 15.0); + ps->en |= (int)(limit * 256.0) << 19; + } + + + if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + switch (cso->compare_func) { + case PIPE_FUNC_NEVER: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NEVER; + break; + case PIPE_FUNC_GREATER: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GREATER; + break; + case PIPE_FUNC_EQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_EQUAL; + break; + case PIPE_FUNC_GEQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GEQUAL; + break; + case PIPE_FUNC_LESS: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LESS; + break; + case PIPE_FUNC_NOTEQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NOTEQUAL; + break; + case PIPE_FUNC_LEQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LEQUAL; + break; + case PIPE_FUNC_ALWAYS: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_ALWAYS; + break; + default: + break; + } + } + + ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | + (float_to_ubyte(cso->border_color[0]) << 16) | + (float_to_ubyte(cso->border_color[1]) << 8) | + (float_to_ubyte(cso->border_color[2]) << 0)); + + return (void *)ps; +} + +static void +nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, + void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_sampler_state *ps = hwcso; + + nv40->tex_sampler[unit] = ps; + nv40->dirty_samplers |= (1 << unit); +} + +static void +nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void +nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit, + struct pipe_texture *miptree) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree; + nv40->dirty_samplers |= (1 << unit); +} + +static void * +nv40_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(32, 0); + + /*XXX: ignored: + * light_twoside + * offset_cw/ccw -nohw + * scissor + * point_smooth -nohw + * multisample + * offset_units / offset_scale + */ + + so_method(so, nv40->hw->curie, NV40TCL_SHADE_MODEL, 1); + so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT : + NV40TCL_SHADE_MODEL_SMOOTH); + + so_method(so, nv40->hw->curie, NV40TCL_LINE_WIDTH, 2); + so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff); + so_data (so, cso->line_smooth ? 1 : 0); + so_method(so, nv40->hw->curie, NV40TCL_LINE_STIPPLE_ENABLE, 2); + so_data (so, cso->line_stipple_enable ? 1 : 0); + so_data (so, (cso->line_stipple_pattern << 16) | + cso->line_stipple_factor); + + so_method(so, nv40->hw->curie, NV40TCL_POINT_SIZE, 1); + so_data (so, fui(cso->point_size)); + + so_method(so, nv40->hw->curie, NV40TCL_POLYGON_MODE_FRONT, 6); + if (cso->front_winding == PIPE_WINDING_CCW) { + so_data(so, nvgl_polygon_mode(cso->fill_ccw)); + so_data(so, nvgl_polygon_mode(cso->fill_cw)); + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + so_data(so, NV40TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_CW: + so_data(so, NV40TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, 0); + break; + } + so_data(so, NV40TCL_FRONT_FACE_CCW); + } else { + so_data(so, nvgl_polygon_mode(cso->fill_cw)); + so_data(so, nvgl_polygon_mode(cso->fill_ccw)); + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + so_data(so, NV40TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_CW: + so_data(so, NV40TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, 0); + break; + } + so_data(so, NV40TCL_FRONT_FACE_CW); + } + so_data(so, cso->poly_smooth ? 1 : 0); + so_data(so, cso->cull_mode != PIPE_WINDING_NONE ? 1 : 0); + + so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, cso->poly_stipple_enable ? 1 : 0); + + so_method(so, nv40->hw->curie, NV40TCL_POINT_SPRITE, 1); + if (cso->point_sprite) { + unsigned psctl = (1 << 0), i; + + for (i = 0; i < 8; i++) { + if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) + psctl |= (1 << (8 + i)); + } + + so_data(so, psctl); + } else { + so_data(so, 0); + } + + return (void *)so; +} + +static void +nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + so_ref(hwcso, &nv40->so_rast); + nv40->dirty |= NV40_NEW_RAST; +} + +static void +nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nouveau_stateobj *so = hwcso; + + so_ref(NULL, &so); +} + +static void * +nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(32, 0); + + so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); + so_data (so, nvgl_comparison_op(cso->depth.func)); + so_data (so, cso->depth.writemask ? 1 : 0); + so_data (so, cso->depth.enabled ? 1 : 0); + + so_method(so, nv40->hw->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + so_data (so, cso->alpha.enabled ? 1 : 0); + so_data (so, nvgl_comparison_op(cso->alpha.func)); + so_data (so, float_to_ubyte(cso->alpha.ref)); + + if (cso->stencil[0].enabled) { + so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_data (so, cso->stencil[0].enabled ? 1 : 0); + so_data (so, cso->stencil[0].write_mask); + so_data (so, nvgl_comparison_op(cso->stencil[0].func)); + so_data (so, cso->stencil[0].ref_value); + so_data (so, cso->stencil[0].value_mask); + 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)); + } else { + so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_data (so, 0); + } + + if (cso->stencil[1].enabled) { + so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_data (so, cso->stencil[1].enabled ? 1 : 0); + so_data (so, cso->stencil[1].write_mask); + so_data (so, nvgl_comparison_op(cso->stencil[1].func)); + so_data (so, cso->stencil[1].ref_value); + so_data (so, cso->stencil[1].value_mask); + 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)); + } else { + so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_data (so, 0); + } + + return (void *)so; +} + +static void +nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + so_ref(hwcso, &nv40->so_zsa); + nv40->dirty |= NV40_NEW_ZSA; +} + +static void +nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nouveau_stateobj *so = hwcso; + + so_ref(NULL, &so); +} + +static void * +nv40_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv40_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nv40_vertex_program)); + vp->pipe = cso; + + return (void *)vp; +} + +static void +nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + nv40->vertprog.current = vp; + nv40->dirty |= NV40_NEW_VERTPROG; +} + +static void +nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + nv40_vertprog_destroy(nv40, vp); + free(vp); +} + +static void * +nv40_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv40_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv40_fragment_program)); + fp->pipe = cso; + + return (void *)fp; +} + +static void +nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_fragment_program *fp = hwcso; + + nv40->fragprog.current = fp; + nv40->dirty |= NV40_NEW_FRAGPROG; +} + +static void +nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_fragment_program *fp = hwcso; + + nv40_fragprog_destroy(nv40, fp); + free(fp); +} + +static void +nv40_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(2, 0); + + so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); + so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | + (float_to_ubyte(bcol->color[0]) << 16) | + (float_to_ubyte(bcol->color[1]) << 8) | + (float_to_ubyte(bcol->color[2]) << 0))); + + so_ref(so, &nv40->so_bcol); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_BCOL; +} + +static void +nv40_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +static void +nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv40->vertprog.constant_buf = buf->buffer; + nv40->dirty |= NV40_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv40->fragprog.constant_buf = buf->buffer; + nv40->dirty |= NV40_NEW_FRAGPROG; + } +} + +static void +nv40_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct pipe_surface *rt[4], *zeta; + uint32_t rt_enable, rt_format, w, h; + int i, colour_format = 0, zeta_format = 0; + struct nouveau_stateobj *so = so_new(64, 10); + unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; + + rt_enable = 0; + for (i = 0; i < 4; i++) { + if (!fb->cbufs[i]) + continue; + + if (colour_format) { + assert(w == fb->cbufs[i]->width); + assert(h == fb->cbufs[i]->height); + assert(colour_format == fb->cbufs[i]->format); + } else { + w = fb->cbufs[i]->width; + h = fb->cbufs[i]->height; + colour_format = fb->cbufs[i]->format; + rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i); + rt[i] = fb->cbufs[i]; + } + } + + if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 | + NV40TCL_RT_ENABLE_COLOR3)) + rt_enable |= NV40TCL_RT_ENABLE_MRT; + + if (fb->zsbuf) { + if (colour_format) { + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); + } else { + w = fb->zsbuf->width; + h = fb->zsbuf->height; + } + + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + switch (zeta_format) { + case PIPE_FORMAT_Z16_UNORM: + rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16; + break; + case PIPE_FORMAT_Z24S8_UNORM: + case 0: + rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8; + break; + default: + assert(0); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1); + so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR0_PITCH, 2); + so_data (so, rt[0]->pitch * rt[0]->cpp); + so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR1, 1); + so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR1_OFFSET, 2); + so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_data (so, rt[1]->pitch * rt[1]->cpp); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR2, 1); + so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR2_OFFSET, 1); + so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_COLOR2_PITCH, 1); + so_data (so, rt[2]->pitch * rt[2]->cpp); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR3, 1); + so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR3_OFFSET, 1); + so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_COLOR3_PITCH, 1); + so_data (so, rt[3]->pitch * rt[3]->cpp); + } + + if (zeta_format) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_ZETA, 1); + so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_ZETA_OFFSET, 1); + so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_data (so, zeta->pitch * zeta->cpp); + } + + so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_data (so, rt_enable); + so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_data (so, rt_format); + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_data (so, ((w - 1) << 16) | 0); + so_data (so, ((h - 1) << 16) | 0); + + so_ref(so, &nv40->so_framebuffer); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_FB; +} + +static void +nv40_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(33, 0); + unsigned i; + + so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, stipple->stipple[i]); + + so_ref(so, &nv40->so_stipple); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_STIPPLE; +} + +static void +nv40_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(3, 0); + + so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + so_data (so, ((s->maxx - s->minx) << 16) | s->minx); + so_data (so, ((s->maxy - s->miny) << 16) | s->miny); + + so_ref(so, &nv40->so_scissor); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_SCISSOR; +} + +static void +nv40_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(9, 0); + + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + + so_ref(so, &nv40->so_viewport); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_VIEWPORT; +} + +static void +nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_buffer *vb) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->vtxbuf[index] = *vb; + + nv40->dirty |= NV40_NEW_ARRAYS; +} + +static void +nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_element *ve) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->vtxelt[index] = *ve; + + nv40->dirty |= NV40_NEW_ARRAYS; +} + +void +nv40_init_state_functions(struct nv40_context *nv40) +{ + nv40->pipe.create_blend_state = nv40_blend_state_create; + nv40->pipe.bind_blend_state = nv40_blend_state_bind; + nv40->pipe.delete_blend_state = nv40_blend_state_delete; + + nv40->pipe.create_sampler_state = nv40_sampler_state_create; + nv40->pipe.bind_sampler_state = nv40_sampler_state_bind; + nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; + nv40->pipe.set_sampler_texture = nv40_set_sampler_texture; + + nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create; + nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind; + nv40->pipe.delete_rasterizer_state = nv40_rasterizer_state_delete; + + nv40->pipe.create_depth_stencil_alpha_state = + nv40_depth_stencil_alpha_state_create; + nv40->pipe.bind_depth_stencil_alpha_state = + nv40_depth_stencil_alpha_state_bind; + nv40->pipe.delete_depth_stencil_alpha_state = + nv40_depth_stencil_alpha_state_delete; + + nv40->pipe.create_vs_state = nv40_vp_state_create; + nv40->pipe.bind_vs_state = nv40_vp_state_bind; + nv40->pipe.delete_vs_state = nv40_vp_state_delete; + + nv40->pipe.create_fs_state = nv40_fp_state_create; + nv40->pipe.bind_fs_state = nv40_fp_state_bind; + nv40->pipe.delete_fs_state = nv40_fp_state_delete; + + nv40->pipe.set_blend_color = nv40_set_blend_color; + nv40->pipe.set_clip_state = nv40_set_clip_state; + nv40->pipe.set_constant_buffer = nv40_set_constant_buffer; + nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state; + nv40->pipe.set_polygon_stipple = nv40_set_polygon_stipple; + nv40->pipe.set_scissor_state = nv40_set_scissor_state; + nv40->pipe.set_viewport_state = nv40_set_viewport_state; + + nv40->pipe.set_vertex_buffer = nv40_set_vertex_buffer; + nv40->pipe.set_vertex_element = nv40_set_vertex_element; +} + diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h new file mode 100644 index 0000000000..e82ab9de98 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -0,0 +1,80 @@ +#ifndef __NV40_STATE_H__ +#define __NV40_STATE_H__ + +#include "pipe/p_state.h" + +struct nv40_sampler_state { + uint32_t fmt; + uint32_t wrap; + uint32_t en; + uint32_t filt; + uint32_t bcol; +}; + +struct nv40_vertex_program_exec { + uint32_t data[4]; + boolean has_branch_offset; + int const_index; +}; + +struct nv40_vertex_program_data { + int index; /* immediates == -1 */ + float value[4]; +}; + +struct nv40_vertex_program { + const struct pipe_shader_state *pipe; + + boolean translated; + struct nv40_vertex_program_exec *insns; + unsigned nr_insns; + struct nv40_vertex_program_data *consts; + unsigned nr_consts; + + struct nouveau_resource *exec; + unsigned exec_start; + struct nouveau_resource *data; + unsigned data_start; + unsigned data_start_min; + + uint32_t ir; + uint32_t or; +}; + +struct nv40_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv40_fragment_program { + const struct pipe_shader_state *pipe; + + boolean translated; + boolean on_hw; + unsigned samplers; + + uint32_t *insn; + int insn_len; + + struct nv40_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + struct nouveau_stateobj *so; +}; + +struct nv40_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +#endif diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c new file mode 100644 index 0000000000..a10c995548 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -0,0 +1,77 @@ +#include "nv40_context.h" +#include "nv40_state.h" + +/* Emit relocs for every referenced buffer. + * + * This is to ensure the bufmgr has an accurate idea of how + * the buffer is used. These relocs appear in the push buffer as + * NOPs, and will only be turned into state changes if a buffer + * actually moves. + */ +static void +nv40_state_emit_dummy_relocs(struct nv40_context *nv40) +{ + unsigned i; + + so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); + for (i = 0; i < 16; i++) { + if (!(nv40->fp_samplers & (1 << i))) + continue; + so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); + } + so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); +} + +void +nv40_emit_hw_state(struct nv40_context *nv40) +{ + if (nv40->dirty & NV40_NEW_FB) + so_emit(nv40->nvws, nv40->so_framebuffer); + + if (nv40->dirty & NV40_NEW_BLEND) + so_emit(nv40->nvws, nv40->so_blend); + + if (nv40->dirty & NV40_NEW_RAST) + so_emit(nv40->nvws, nv40->so_rast); + + if (nv40->dirty & NV40_NEW_ZSA) + so_emit(nv40->nvws, nv40->so_zsa); + + if (nv40->dirty & NV40_NEW_BCOL) + so_emit(nv40->nvws, nv40->so_bcol); + + if (nv40->dirty & NV40_NEW_SCISSOR) + so_emit(nv40->nvws, nv40->so_scissor); + + if (nv40->dirty & NV40_NEW_VIEWPORT) + so_emit(nv40->nvws, nv40->so_viewport); + + if (nv40->dirty & NV40_NEW_STIPPLE) + so_emit(nv40->nvws, nv40->so_stipple); + + if (nv40->dirty & NV40_NEW_FRAGPROG) { + nv40_fragprog_bind(nv40, nv40->fragprog.current); + /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */ + } + + if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { + nv40_fragtex_bind(nv40); + + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); + nv40->dirty &= ~NV40_NEW_FRAGPROG; + } + + if (nv40->dirty & NV40_NEW_VERTPROG) { + nv40_vertprog_bind(nv40, nv40->vertprog.current); + nv40->dirty &= ~NV40_NEW_VERTPROG; + } + + nv40->dirty_samplers = 0; + nv40->dirty = 0; + + nv40_state_emit_dummy_relocs(nv40); +} + diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c new file mode 100644 index 0000000000..9726ab4e4d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -0,0 +1,137 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "nv40_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static boolean +nv40_surface_format_supported(struct pipe_context *pipe, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static struct pipe_surface * +nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = pipe->winsys; + struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv40mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv40mt->level[level].image_offset[face]; + } else + if (pt->target == PIPE_TEXTURE_3D) { + ps->offset = nv40mt->level[level].image_offset[zslice]; + } else { + ps->offset = nv40mt->level[level].image_offset[0]; + } + + return ps; +} + +static void +nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_winsys *nvws = nv40->nvws; + + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); +} + +static void +nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_winsys *nvws = nv40->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv40_init_surface_functions(struct nv40_context *nv40) +{ + nv40->pipe.is_format_supported = nv40_surface_format_supported; + nv40->pipe.get_tex_surface = nv40_get_tex_surface; + nv40->pipe.surface_copy = nv40_surface_copy; + nv40->pipe.surface_fill = nv40_surface_fill; +} diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c new file mode 100644 index 0000000000..fa827ef0c5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -0,0 +1,424 @@ +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" + +static INLINE int +nv40_vbo_ncomp(uint format) +{ + int ncomp = 0; + + if (pf_size_x(format)) ncomp++; + if (pf_size_y(format)) ncomp++; + if (pf_size_z(format)) ncomp++; + if (pf_size_w(format)) ncomp++; + + return ncomp; +} + +static INLINE int +nv40_vbo_type(uint format) +{ + switch (pf_type(format)) { + case PIPE_FORMAT_TYPE_FLOAT: + return NV40TCL_VTXFMT_TYPE_FLOAT; + case PIPE_FORMAT_TYPE_UNORM: + return NV40TCL_VTXFMT_TYPE_UBYTE; + default: + NOUVEAU_ERR("Unknown format 0x%08x\n", format); + return NV40TCL_VTXFMT_TYPE_FLOAT; + } +} + +static boolean +nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, + struct pipe_vertex_element *ve, + struct pipe_vertex_buffer *vb) +{ + struct pipe_winsys *ws = nv40->pipe.winsys; + int type, ncomp; + void *map; + + type = nv40_vbo_type(ve->src_format); + ncomp = nv40_vbo_ncomp(ve->src_format); + + map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + map += vb->buffer_offset + ve->src_offset; + + switch (type) { + case NV40TCL_VTXFMT_TYPE_FLOAT: + { + float *v = map; + + BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(attrib), 4); + switch (ncomp) { + case 4: + OUT_RINGf(v[0]); + OUT_RINGf(v[1]); + OUT_RINGf(v[2]); + OUT_RINGf(v[3]); + break; + case 3: + OUT_RINGf(v[0]); + OUT_RINGf(v[1]); + OUT_RINGf(v[2]); + OUT_RINGf(1.0); + break; + case 2: + OUT_RINGf(v[0]); + OUT_RINGf(v[1]); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + break; + case 1: + OUT_RINGf(v[0]); + OUT_RINGf(0.0); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + break; + default: + ws->buffer_unmap(ws, vb->buffer); + return FALSE; + } + } + break; + default: + ws->buffer_unmap(ws, vb->buffer); + return FALSE; + } + + ws->buffer_unmap(ws, vb->buffer); + + return TRUE; +} + +static void +nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, + unsigned ib_format) +{ + struct nv40_vertex_program *vp = nv40->vertprog.active; + struct nouveau_stateobj *vtxbuf, *vtxfmt; + unsigned inputs, hw, num_hw; + unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + inputs = vp->ir; + for (hw = 0; hw < 16 && inputs; hw++) { + if (inputs & (1 << hw)) { + num_hw = hw; + inputs &= ~(1 << hw); + } + } + num_hw++; + + vtxbuf = so_new(20, 18); + so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + vtxfmt = so_new(17, 0); + so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw); + + inputs = vp->ir; + for (hw = 0; hw < num_hw; hw++) { + struct pipe_vertex_element *ve; + struct pipe_vertex_buffer *vb; + + if (!(inputs & (1 << hw))) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + ve = &nv40->vtxelt[hw]; + vb = &nv40->vtxbuf[ve->vertex_buffer_index]; + + if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, + vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + 0, NV40TCL_VTXBUF_ADDRESS_DMA1); + so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) | + (nv40_vbo_ncomp(ve->src_format) << + NV40TCL_VTXFMT_SIZE_SHIFT) | + nv40_vbo_type(ve->src_format))); + } + + if (ib) { + so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); + so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, + 0, NV40TCL_IDXBUF_FORMAT_DMA1); + } + + so_emit(nv40->nvws, vtxfmt); + so_emit(nv40->nvws, vtxbuf); + so_ref (vtxbuf, &nv40->so_vtxbuf); + so_ref (NULL, &vtxbuf); + so_ref (NULL, &vtxfmt); +} + +static boolean +nv40_vbo_validate_state(struct nv40_context *nv40, + struct pipe_buffer *ib, unsigned ib_format) +{ + unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS; + + nv40_emit_hw_state(nv40); + if (vdn || ib) { + nv40_vbo_arrays_update(nv40, ib, ib_format); + nv40->dirty &= ~NV40_NEW_ARRAYS; + } + + so_emit_reloc_markers(nv40->nvws, nv40->so_vtxbuf); + + BEGIN_RING(curie, 0x1710, 1); + OUT_RING (0); /* vtx cache flush */ + + return TRUE; +} + +boolean +nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, + unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + unsigned nr; + boolean ret; + + ret = nv40_vbo_validate_state(nv40, NULL, 0); + if (!ret) { + NOUVEAU_ERR("state validate failed\n"); + return FALSE; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (count & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } + + nr = count >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + pipe->flush(pipe, 0); + return TRUE; +} + +static INLINE void +nv40_draw_elements_u08(struct nv40_context *nv40, void *ib, + unsigned start, unsigned count) +{ + uint8_t *elts = (uint8_t *)ib + start; + int push, i; + + if (count & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; count--; + } + + while (count) { + push = MIN2(count, 2047 * 2); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + count -= push; + elts += push; + } +} + +static INLINE void +nv40_draw_elements_u16(struct nv40_context *nv40, void *ib, + unsigned start, unsigned count) +{ + uint16_t *elts = (uint16_t *)ib + start; + int push, i; + + if (count & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; count--; + } + + while (count) { + push = MIN2(count, 2047 * 2); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + count -= push; + elts += push; + } +} + +static INLINE void +nv40_draw_elements_u32(struct nv40_context *nv40, void *ib, + unsigned start, unsigned count) +{ + uint32_t *elts = (uint32_t *)ib + start; + int push; + + while (count) { + push = MIN2(count, 2047); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); + + count -= push; + elts += push; + } +} + +static boolean +nv40_draw_elements_inline(struct pipe_context *pipe, + struct pipe_buffer *ib, unsigned ib_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + boolean ret; + void *map; + + ret = nv40_vbo_validate_state(nv40, NULL, 0); + if (!ret) { + NOUVEAU_ERR("state validate failed\n"); + return FALSE; + } + + map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); + if (!ib) { + NOUVEAU_ERR("failed mapping ib\n"); + return FALSE; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + switch (ib_size) { + case 1: + nv40_draw_elements_u08(nv40, map, start, count); + break; + case 2: + nv40_draw_elements_u16(nv40, map, start, count); + break; + case 4: + nv40_draw_elements_u32(nv40, map, start, count); + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + break; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + ws->buffer_unmap(ws, ib); + + return TRUE; +} + +static boolean +nv40_draw_elements_vbo(struct pipe_context *pipe, + struct pipe_buffer *ib, unsigned ib_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + unsigned nr, type; + boolean ret; + + switch (ib_size) { + case 2: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + return FALSE; + } + + ret = nv40_vbo_validate_state(nv40, ib, type); + if (!ret) { + NOUVEAU_ERR("failed state validation\n"); + return FALSE; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (count & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } + + nr = count >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + return TRUE; +} + +boolean +nv40_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + /* 0x4497 doesn't support real index buffers, and there doesn't appear + * to be support on any chipset for 8-bit indices. + */ + if (nv40->hw->curie->grclass == NV44TCL || indexSize == 1) { + nv40_draw_elements_inline(pipe, indexBuffer, indexSize, + mode, start, count); + } else { + nv40_draw_elements_vbo(pipe, indexBuffer, indexSize, + mode, start, count); + } + + pipe->flush(pipe, 0); + return TRUE; +} + + diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c new file mode 100644 index 0000000000..9f4738b830 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -0,0 +1,790 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" + +#include "nv40_context.h" +#include "nv40_state.h" + +/* TODO (at least...): + * 1. Indexed consts + ARL + * 2. Arb. swz/negation + * 3. NV_vp11, NV_vp2, NV_vp3 features + * - extra arith opcodes + * - branching + * - texture sampling + * - indexed attribs + * - indexed results + * 4. bugs + */ + +#define SWZ_X 0 +#define SWZ_Y 1 +#define SWZ_Z 2 +#define SWZ_W 3 +#define MASK_X 8 +#define MASK_Y 4 +#define MASK_Z 2 +#define MASK_W 1 +#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) +#define DEF_SCALE 0 +#define DEF_CTEST 0 +#include "nv40_shader.h" + +#define swz(s,x,y,z,w) nv40_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv40_sr_neg((s)) +#define abs(s) nv40_sr_abs((s)) + +struct nv40_vpc { + struct nv40_vertex_program *vp; + + struct nv40_vertex_program_exec *vpi; + + unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; + + int high_temp; + int temp_temp_count; + + struct nv40_sreg *imm; + unsigned nr_imm; +}; + +static struct nv40_sreg +temp(struct nv40_vpc *vpc) +{ + int idx; + + idx = vpc->temp_temp_count++; + idx += vpc->high_temp + 1; + return nv40_sr(NV40SR_TEMP, idx); +} + +static struct nv40_sreg +constant(struct nv40_vpc *vpc, int pipe, float x, float y, float z, float w) +{ + struct nv40_vertex_program *vp = vpc->vp; + struct nv40_vertex_program_data *vpd; + int idx; + + if (pipe >= 0) { + for (idx = 0; idx < vp->nr_consts; idx++) { + if (vp->consts[idx].index == pipe) + return nv40_sr(NV40SR_CONST, idx); + } + } + + idx = vp->nr_consts++; + vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts); + vpd = &vp->consts[idx]; + + vpd->index = pipe; + vpd->value[0] = x; + vpd->value[1] = y; + vpd->value[2] = z; + vpd->value[3] = w; + return nv40_sr(NV40SR_CONST, idx); +} + +#define arith(cc,s,o,d,m,s0,s1,s2) \ + nv40_vp_arith((cc), (s), NV40_VP_INST_##o, (d), (m), (s0), (s1), (s2)) + +static void +emit_src(struct nv40_vpc *vpc, uint32_t *hw, int pos, struct nv40_sreg src) +{ + struct nv40_vertex_program *vp = vpc->vp; + uint32_t sr = 0; + + switch (src.type) { + case NV40SR_TEMP: + sr |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT); + sr |= (src.index << NV40_VP_SRC_TEMP_SRC_SHIFT); + break; + case NV40SR_INPUT: + sr |= (NV40_VP_SRC_REG_TYPE_INPUT << + NV40_VP_SRC_REG_TYPE_SHIFT); + vp->ir |= (1 << src.index); + hw[1] |= (src.index << NV40_VP_INST_INPUT_SRC_SHIFT); + break; + case NV40SR_CONST: + sr |= (NV40_VP_SRC_REG_TYPE_CONST << + NV40_VP_SRC_REG_TYPE_SHIFT); + assert(vpc->vpi->const_index == -1 || + vpc->vpi->const_index == src.index); + vpc->vpi->const_index = src.index; + break; + case NV40SR_NONE: + sr |= (NV40_VP_SRC_REG_TYPE_INPUT << + NV40_VP_SRC_REG_TYPE_SHIFT); + break; + default: + assert(0); + } + + if (src.negate) + sr |= NV40_VP_SRC_NEGATE; + + if (src.abs) + hw[0] |= (1 << (21 + pos)); + + sr |= ((src.swz[0] << NV40_VP_SRC_SWZ_X_SHIFT) | + (src.swz[1] << NV40_VP_SRC_SWZ_Y_SHIFT) | + (src.swz[2] << NV40_VP_SRC_SWZ_Z_SHIFT) | + (src.swz[3] << NV40_VP_SRC_SWZ_W_SHIFT)); + + switch (pos) { + case 0: + hw[1] |= ((sr & NV40_VP_SRC0_HIGH_MASK) >> + NV40_VP_SRC0_HIGH_SHIFT) << NV40_VP_INST_SRC0H_SHIFT; + hw[2] |= (sr & NV40_VP_SRC0_LOW_MASK) << + NV40_VP_INST_SRC0L_SHIFT; + break; + case 1: + hw[2] |= sr << NV40_VP_INST_SRC1_SHIFT; + break; + case 2: + hw[2] |= ((sr & NV40_VP_SRC2_HIGH_MASK) >> + NV40_VP_SRC2_HIGH_SHIFT) << NV40_VP_INST_SRC2H_SHIFT; + hw[3] |= (sr & NV40_VP_SRC2_LOW_MASK) << + NV40_VP_INST_SRC2L_SHIFT; + break; + default: + assert(0); + } +} + +static void +emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst) +{ + struct nv40_vertex_program *vp = vpc->vp; + + switch (dst.type) { + case NV40SR_TEMP: + hw[3] |= NV40_VP_INST_DEST_MASK; + if (slot == 0) { + hw[0] |= (dst.index << + NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + } else { + hw[3] |= (dst.index << + NV40_VP_INST_SCA_DEST_TEMP_SHIFT); + } + break; + case NV40SR_OUTPUT: + switch (dst.index) { + case NV40_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break; + case NV40_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break; + case NV40_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break; + case NV40_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break; + case NV40_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break; + case NV40_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break; + case NV40_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break; + case NV40_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break; + case NV40_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break; + case NV40_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break; + case NV40_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break; + case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break; + case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break; + case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break; + default: + break; + } + + hw[3] |= (dst.index << NV40_VP_INST_DEST_SHIFT); + if (slot == 0) { + hw[0] |= NV40_VP_INST_VEC_RESULT; + hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); + } else { + hw[3] |= NV40_VP_INST_SCA_RESULT; + hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK; + } + break; + default: + assert(0); + } +} + +static void +nv40_vp_arith(struct nv40_vpc *vpc, int slot, int op, + struct nv40_sreg dst, int mask, + struct nv40_sreg s0, struct nv40_sreg s1, + struct nv40_sreg s2) +{ + struct nv40_vertex_program *vp = vpc->vp; + uint32_t *hw; + + vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi)); + vpc->vpi = &vp->insns[vp->nr_insns - 1]; + memset(vpc->vpi, 0, sizeof(*vpc->vpi)); + vpc->vpi->const_index = -1; + + hw = vpc->vpi->data; + + hw[0] |= (NV40_VP_INST_COND_TR << NV40_VP_INST_COND_SHIFT); + hw[0] |= ((0 << NV40_VP_INST_COND_SWZ_X_SHIFT) | + (1 << NV40_VP_INST_COND_SWZ_Y_SHIFT) | + (2 << NV40_VP_INST_COND_SWZ_Z_SHIFT) | + (3 << NV40_VP_INST_COND_SWZ_W_SHIFT)); + + if (slot == 0) { + hw[1] |= (op << NV40_VP_INST_VEC_OPCODE_SHIFT); + hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK; + hw[3] |= (mask << NV40_VP_INST_VEC_WRITEMASK_SHIFT); + } else { + hw[1] |= (op << NV40_VP_INST_SCA_OPCODE_SHIFT); + hw[0] |= (NV40_VP_INST_VEC_DEST_TEMP_MASK | (1 << 20)); + hw[3] |= (mask << NV40_VP_INST_SCA_WRITEMASK_SHIFT); + } + + emit_dst(vpc, hw, slot, dst); + emit_src(vpc, hw, 0, s0); + emit_src(vpc, hw, 1, s1); + emit_src(vpc, hw, 2, s2); +} + +static INLINE struct nv40_sreg +tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) { + struct nv40_sreg src; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + src = nv40_sr(NV40SR_INPUT, fsrc->SrcRegister.Index); + break; + case TGSI_FILE_CONSTANT: + src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0); + break; + case TGSI_FILE_IMMEDIATE: + src = vpc->imm[fsrc->SrcRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + if (vpc->high_temp < fsrc->SrcRegister.Index) + vpc->high_temp = fsrc->SrcRegister.Index; + src = nv40_sr(NV40SR_TEMP, fsrc->SrcRegister.Index); + break; + default: + NOUVEAU_ERR("bad src file\n"); + break; + } + + src.abs = fsrc->SrcRegisterExtMod.Absolute; + src.negate = fsrc->SrcRegister.Negate; + src.swz[0] = fsrc->SrcRegister.SwizzleX; + src.swz[1] = fsrc->SrcRegister.SwizzleY; + src.swz[2] = fsrc->SrcRegister.SwizzleZ; + src.swz[3] = fsrc->SrcRegister.SwizzleW; + return src; +} + +static INLINE struct nv40_sreg +tgsi_dst(struct nv40_vpc *vpc, const struct tgsi_full_dst_register *fdst) { + struct nv40_sreg dst; + + switch (fdst->DstRegister.File) { + case TGSI_FILE_OUTPUT: + dst = nv40_sr(NV40SR_OUTPUT, + vpc->output_map[fdst->DstRegister.Index]); + + break; + case TGSI_FILE_TEMPORARY: + dst = nv40_sr(NV40SR_TEMP, fdst->DstRegister.Index); + if (vpc->high_temp < dst.index) + vpc->high_temp = dst.index; + break; + default: + NOUVEAU_ERR("bad dst file\n"); + break; + } + + return dst; +} + +static INLINE int +tgsi_mask(uint tgsi) +{ + int mask = 0; + + if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; + if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; + if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; + if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; + return mask; +} + +static boolean +nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, + const struct tgsi_full_instruction *finst) +{ + struct nv40_sreg src[3], dst, tmp; + struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + int mask; + int ai = -1, ci = -1; + int i; + + if (finst->Instruction.Opcode == TGSI_OPCODE_END) + return TRUE; + + vpc->temp_temp_count = 0; + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) { + src[i] = tgsi_src(vpc, fsrc); + } + } + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + if (ai == -1 || ai == fsrc->SrcRegister.Index) { + ai = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + /*XXX: index comparison is broken now that consts come from + * two different register files. + */ + case TGSI_FILE_CONSTANT: + case TGSI_FILE_IMMEDIATE: + if (ci == -1 || ci == fsrc->SrcRegister.Index) { + ci = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + case TGSI_FILE_TEMPORARY: + /* handled above */ + break; + default: + NOUVEAU_ERR("bad src file\n"); + return FALSE; + } + } + + dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); + mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); + break; + case TGSI_OPCODE_ADD: + arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]); + break; + case TGSI_OPCODE_ARL: + arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_DP3: + arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DP4: + arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DPH: + arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DST: + arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_EX2: + arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_EXP: + arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_FLR: + arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FRC: + arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_LG2: + arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_LIT: + arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_LOG: + arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_MAD: + arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]); + break; + case TGSI_OPCODE_MAX: + arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MIN: + arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MOV: + arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_MUL: + arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_POW: + tmp = temp(vpc); + arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none, + swz(src[0], X, X, X, X)); + arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X), + swz(src[1], X, X, X, X), none); + arith(vpc, 1, OP_EX2, dst, mask, none, none, + swz(tmp, X, X, X, X)); + break; + case TGSI_OPCODE_RCP: + arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_RET: + break; + case TGSI_OPCODE_RSQ: + arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_SGE: + arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SLT: + arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SUB: + arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1])); + break; + case TGSI_OPCODE_XPD: + tmp = temp(vpc); + arith(vpc, 0, OP_MUL, tmp, mask, + swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); + arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W), + swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), + neg(tmp)); + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); + return FALSE; + } + + return TRUE; +} + +static boolean +nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, + const struct tgsi_full_declaration *fdec) +{ + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV40_VP_INST_DEST_POS; + break; + case TGSI_SEMANTIC_COLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV40_VP_INST_DEST_COL0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV40_VP_INST_DEST_COL1; + } else { + NOUVEAU_ERR("bad colour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_BCOLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV40_VP_INST_DEST_BFC0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV40_VP_INST_DEST_BFC1; + } else { + NOUVEAU_ERR("bad bcolour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_FOG: + hw = NV40_VP_INST_DEST_FOGC; + break; + case TGSI_SEMANTIC_PSIZE: + hw = NV40_VP_INST_DEST_PSZ; + break; + case TGSI_SEMANTIC_GENERIC: + if (fdec->Semantic.SemanticIndex <= 7) { + hw = NV40_VP_INST_DEST_TC(fdec->Semantic.SemanticIndex); + } else { + NOUVEAU_ERR("bad generic semantic index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + vpc->output_map[fdec->u.DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv40_vertprog_prepare(struct nv40_vpc *vpc) +{ + struct tgsi_parse_context p; + int nr_imm = 0; + + tgsi_parse_init(&p, vpc->vp->pipe->tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; + + tgsi_parse_token(&p); + switch(tok->Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + nr_imm++; + break; + default: + break; + } + } + tgsi_parse_free(&p); + + if (nr_imm) { + vpc->imm = CALLOC(nr_imm, sizeof(struct nv40_sreg)); + assert(vpc->imm); + } + + return TRUE; +} + +void +nv40_vertprog_translate(struct nv40_context *nv40, + struct nv40_vertex_program *vp) +{ + struct tgsi_parse_context parse; + struct nv40_vpc *vpc = NULL; + + vpc = CALLOC(1, sizeof(struct nv40_vpc)); + if (!vpc) + return; + vpc->vp = vp; + vpc->high_temp = -1; + + if (!nv40_vertprog_prepare(vpc)) { + free(vpc); + return; + } + + tgsi_parse_init(&parse, vp->pipe->tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + fdec = &parse.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_OUTPUT: + if (!nv40_vertprog_parse_decl_output(vpc, fdec)) + goto out_err; + break; + default: + break; + } + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + const struct tgsi_full_immediate *imm; + + imm = &parse.FullToken.FullImmediate; + assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); +// assert(imm->Immediate.Size == 4); + vpc->imm[vpc->nr_imm++] = + constant(vpc, -1, + imm->u.ImmediateFloat32[0].Float, + imm->u.ImmediateFloat32[1].Float, + imm->u.ImmediateFloat32[2].Float, + imm->u.ImmediateFloat32[3].Float); + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + finst = &parse.FullToken.FullInstruction; + if (!nv40_vertprog_parse_instruction(vpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + vp->insns[vp->nr_insns - 1].data[3] |= NV40_VP_INST_LAST; + vp->translated = TRUE; +out_err: + tgsi_parse_free(&parse); + free(vpc); +} + +void +nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) +{ + struct nouveau_winsys *nvws = nv40->nvws; + struct pipe_winsys *ws = nv40->pipe.winsys; + boolean upload_code = FALSE, upload_data = FALSE; + int i; + + /* Translate TGSI shader into hw bytecode */ + if (!vp->translated) { + nv40_vertprog_translate(nv40, vp); + if (!vp->translated) + assert(0); + } + + /* Allocate hw vtxprog exec slots */ + if (!vp->exec) { + struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + uint vplen = vp->nr_insns; + + if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { + while (heap->next && heap->size < vplen) { + struct nv40_vertex_program *evict; + + evict = heap->next->priv; + nvws->res_free(&evict->exec); + } + + if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) + assert(0); + } + + upload_code = TRUE; + } + + /* Allocate hw vtxprog const slots */ + if (vp->nr_consts && !vp->data) { + struct nouveau_resource *heap = nv40->hw->vp_data_heap; + + if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { + while (heap->next && heap->size < vp->nr_consts) { + struct nv40_vertex_program *evict; + + evict = heap->next->priv; + nvws->res_free(&evict->data); + } + + if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) + assert(0); + } + + /*XXX: handle this some day */ + assert(vp->data->start >= vp->data_start_min); + + upload_data = TRUE; + if (vp->data_start != vp->data->start) + upload_code = TRUE; + } + + /* If exec or data segments moved we need to patch the program to + * fixup offsets and register IDs. + */ + if (vp->exec_start != vp->exec->start) { + for (i = 0; i < vp->nr_insns; i++) { + struct nv40_vertex_program_exec *vpi = &vp->insns[i]; + + if (vpi->has_branch_offset) { + assert(0); + } + } + + vp->exec_start = vp->exec->start; + } + + if (vp->nr_consts && vp->data_start != vp->data->start) { + for (i = 0; i < vp->nr_insns; i++) { + struct nv40_vertex_program_exec *vpi = &vp->insns[i]; + + if (vpi->const_index >= 0) { + vpi->data[1] &= ~NV40_VP_INST_CONST_SRC_MASK; + vpi->data[1] |= + (vpi->const_index + vp->data->start) << + NV40_VP_INST_CONST_SRC_SHIFT; + + } + } + + vp->data_start = vp->data->start; + } + + /* Update + Upload constant values */ + if (vp->nr_consts) { + float *map = NULL; + + if (nv40->vertprog.constant_buf) { + map = ws->buffer_map(ws, nv40->vertprog.constant_buf, + PIPE_BUFFER_USAGE_CPU_READ); + } + + for (i = 0; i < vp->nr_consts; i++) { + struct nv40_vertex_program_data *vpd = &vp->consts[i]; + + if (vpd->index >= 0) { + if (!upload_data && + !memcmp(vpd->value, &map[vpd->index * 4], + 4 * sizeof(float))) + continue; + memcpy(vpd->value, &map[vpd->index * 4], + 4 * sizeof(float)); + } + + BEGIN_RING(curie, NV40TCL_VP_UPLOAD_CONST_ID, 5); + OUT_RING (i + vp->data->start); + OUT_RINGp ((uint32_t *)vpd->value, 4); + } + + if (map) { + ws->buffer_unmap(ws, nv40->vertprog.constant_buf); + } + } + + /* Upload vtxprog */ + if (upload_code) { +#if 0 + for (i = 0; i < vp->nr_insns; i++) { + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[0]); + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[1]); + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[2]); + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[3]); + } +#endif + BEGIN_RING(curie, NV40TCL_VP_UPLOAD_FROM_ID, 1); + OUT_RING (vp->exec->start); + for (i = 0; i < vp->nr_insns; i++) { + BEGIN_RING(curie, NV40TCL_VP_UPLOAD_INST(0), 4); + OUT_RINGp (vp->insns[i].data, 4); + } + } + + BEGIN_RING(curie, NV40TCL_VP_START_FROM_ID, 1); + OUT_RING (vp->exec->start); + BEGIN_RING(curie, NV40TCL_VP_ATTRIB_EN, 2); + OUT_RING (vp->ir); + OUT_RING (vp->or); + + nv40->vertprog.active = vp; +} + +void +nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) +{ + if (vp->nr_consts) + free(vp->consts); + if (vp->nr_insns) + free(vp->insns); +} + -- cgit v1.2.3 From 5e091b573aa0a0c45f8ff34429f2a9d4198bb80a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 21:27:53 +1100 Subject: nv40: ensure scissor gets disabled where necessary Fixes progs/demos/lodbias. Makes a complete mess of things, but now there's a motivation to finish this off :) --- src/gallium/drivers/nv40/nv40_context.h | 19 ++++++++- src/gallium/drivers/nv40/nv40_state.c | 23 +++++------ src/gallium/drivers/nv40/nv40_state_emit.c | 65 +++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index f511759e3b..c4523112db 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -54,6 +54,11 @@ struct nv40_channel_context { struct nouveau_resource *vp_data_heap; }; +struct nv40_rasterizer_state { + struct pipe_rasterizer_state pipe; + struct nouveau_stateobj *so; +}; + struct nv40_context { struct pipe_context pipe; struct nouveau_winsys *nvws; @@ -63,7 +68,8 @@ struct nv40_context { int chipset; - uint32_t dirty; + unsigned dirty; + unsigned hw_dirty; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; @@ -71,14 +77,23 @@ struct nv40_context { unsigned fp_samplers; unsigned vp_samplers; + struct { + struct pipe_scissor_state scissor; + } pipe_state; + + struct { + unsigned scissor_enabled; + struct nouveau_stateobj *scissor; + } state; + struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; struct nouveau_stateobj *so_blend; + struct nv40_rasterizer_state *rasterizer; struct nouveau_stateobj *so_rast; struct nouveau_stateobj *so_zsa; struct nouveau_stateobj *so_bcol; - struct nouveau_stateobj *so_scissor; struct nouveau_stateobj *so_viewport; struct nouveau_stateobj *so_stipple; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 713f31dbb1..bb9b6b139f 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -278,12 +278,12 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_rasterizer_state *rsso = MALLOC(sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); /*XXX: ignored: * light_twoside * offset_cw/ccw -nohw - * scissor * point_smooth -nohw * multisample * offset_units / offset_scale @@ -362,24 +362,29 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, 0); } - return (void *)so; + rsso->so = so; + rsso->pipe = *cso; + return (void *)rsso; } static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_rasterizer_state *rsso = hwcso; - so_ref(hwcso, &nv40->so_rast); + so_ref(rsso->so, &nv40->so_rast); + nv40->rasterizer = rsso; nv40->dirty |= NV40_NEW_RAST; } static void nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nouveau_stateobj *so = hwcso; + struct nv40_rasterizer_state *rsso = hwcso; - so_ref(NULL, &so); + so_ref(NULL, &rsso->so); + free(rsso); } static void * @@ -723,14 +728,8 @@ nv40_set_scissor_state(struct pipe_context *pipe, const struct pipe_scissor_state *s) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); - so_data (so, ((s->maxx - s->minx) << 16) | s->minx); - so_data (so, ((s->maxy - s->miny) << 16) | s->miny); - - so_ref(so, &nv40->so_scissor); - so_ref(NULL, &so); + nv40->pipe_state.scissor = *s; nv40->dirty |= NV40_NEW_SCISSOR; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a10c995548..74306fe22b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -22,9 +22,68 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40) so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); } +static boolean +nv40_state_scissor_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_scissor_state *s = &nv40->pipe_state.scissor; + struct nouveau_stateobj *so; + + if (nv40->state.scissor && + (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) + return FALSE; + + so = so_new(3, 0); + so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + if (rast->scissor) { + so_data (so, ((s->maxx - s->minx) << 16) | s->minx); + so_data (so, ((s->maxy - s->miny) << 16) | s->miny); + } else { + so_data (so, 4096 << 16); + so_data (so, 4096 << 16); + } + + so_ref(so, &nv40->state.scissor); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_atom { + boolean (*validate)(struct nv40_context *nv40); + struct { + unsigned pipe; + unsigned hw; + } dirty; +}; + +static struct nv40_state_atom states[] = { + { + .validate = nv40_state_scissor_validate, + .dirty = { + .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, + .hw = NV40_NEW_SCISSOR, + } + } +}; + +static void +nv40_state_validate(struct nv40_context *nv40) +{ + unsigned i; + + for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) { + if (nv40->dirty & states[i].dirty.pipe) { + if (states[i].validate(nv40)) + nv40->hw_dirty |= states[i].dirty.hw; + } + } +} + void nv40_emit_hw_state(struct nv40_context *nv40) { + nv40_state_validate(nv40); + if (nv40->dirty & NV40_NEW_FB) so_emit(nv40->nvws, nv40->so_framebuffer); @@ -40,8 +99,10 @@ nv40_emit_hw_state(struct nv40_context *nv40) if (nv40->dirty & NV40_NEW_BCOL) so_emit(nv40->nvws, nv40->so_bcol); - if (nv40->dirty & NV40_NEW_SCISSOR) - so_emit(nv40->nvws, nv40->so_scissor); + if (nv40->hw_dirty & NV40_NEW_SCISSOR) { + so_emit(nv40->nvws, nv40->state.scissor); + nv40->hw_dirty &= ~NV40_NEW_SCISSOR; + } if (nv40->dirty & NV40_NEW_VIEWPORT) so_emit(nv40->nvws, nv40->so_viewport); -- cgit v1.2.3 From 12e0aa7b1d587b7c30897762d2f8f368a4a7d453 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 14:12:58 +1100 Subject: nv40: similar changes to polygon stipple as were done for scissor --- src/gallium/drivers/nv40/nv40_context.h | 18 ++++++++--- src/gallium/drivers/nv40/nv40_state.c | 9 +----- src/gallium/drivers/nv40/nv40_state_emit.c | 52 ++++++++++++++++++++++++++---- 3 files changed, 61 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index c4523112db..7d5806f5f7 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -59,6 +59,18 @@ struct nv40_rasterizer_state { struct nouveau_stateobj *so; }; +struct nv40_state { + struct { + unsigned enabled; + struct nouveau_stateobj *so; + } scissor; + + struct { + unsigned enabled; + struct nouveau_stateobj *so; + } stipple; +}; + struct nv40_context { struct pipe_context pipe; struct nouveau_winsys *nvws; @@ -79,12 +91,10 @@ struct nv40_context { struct { struct pipe_scissor_state scissor; + unsigned stipple[32]; } pipe_state; - struct { - unsigned scissor_enabled; - struct nouveau_stateobj *scissor; - } state; + struct nv40_state state; struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index bb9b6b139f..a36efd37f6 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -711,15 +711,8 @@ nv40_set_polygon_stipple(struct pipe_context *pipe, const struct pipe_poly_stipple *stipple) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(33, 0); - unsigned i; - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); - for (i = 0; i < 32; i++) - so_data(so, stipple->stipple[i]); - - so_ref(so, &nv40->so_stipple); - so_ref(NULL, &so); + memcpy(nv40->pipe_state.stipple, stipple->stipple, 4 * 32); nv40->dirty |= NV40_NEW_STIPPLE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 74306fe22b..244c6838f3 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -29,8 +29,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40) struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; - if (nv40->state.scissor && - (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) + if (nv40->state.scissor.so && + (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) return FALSE; so = so_new(3, 0); @@ -43,7 +43,38 @@ nv40_state_scissor_validate(struct nv40_context *nv40) so_data (so, 4096 << 16); } - so_ref(so, &nv40->state.scissor); + so_ref(so, &nv40->state.scissor.so); + so_ref(NULL, &so); + return TRUE; +} + +static boolean +nv40_state_stipple_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_stateobj *so; + + if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 && + nv40->state.stipple.enabled == 0)) + return FALSE; + + if (rast->poly_stipple_enable) { + unsigned i; + + so = so_new(35, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 1); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, nv40->pipe_state.stipple[i]); + } else { + so = so_new(2, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &nv40->state.stipple.so); so_ref(NULL, &so); return TRUE; } @@ -63,6 +94,13 @@ static struct nv40_state_atom states[] = { .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, .hw = NV40_NEW_SCISSOR, } + }, + { + .validate = nv40_state_stipple_validate, + .dirty = { + .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, + .hw = NV40_NEW_STIPPLE, + } } }; @@ -100,15 +138,17 @@ nv40_emit_hw_state(struct nv40_context *nv40) so_emit(nv40->nvws, nv40->so_bcol); if (nv40->hw_dirty & NV40_NEW_SCISSOR) { - so_emit(nv40->nvws, nv40->state.scissor); + so_emit(nv40->nvws, nv40->state.scissor.so); nv40->hw_dirty &= ~NV40_NEW_SCISSOR; } if (nv40->dirty & NV40_NEW_VIEWPORT) so_emit(nv40->nvws, nv40->so_viewport); - if (nv40->dirty & NV40_NEW_STIPPLE) - so_emit(nv40->nvws, nv40->so_stipple); + if (nv40->hw_dirty & NV40_NEW_STIPPLE) { + so_emit(nv40->nvws, nv40->state.stipple.so); + nv40->hw_dirty &= ~NV40_NEW_STIPPLE; + } if (nv40->dirty & NV40_NEW_FRAGPROG) { nv40_fragprog_bind(nv40, nv40->fragprog.current); -- cgit v1.2.3 From 037570fa5a6cf83d3aaaa6cdacc10eb0b5da45bf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 15:17:39 +1100 Subject: nv40: obey polygon offset state Almost sure this isn't entirely correct. However, I'm not sure what gallium expects yet, and this fixes some bugs, so it'll do for now. --- src/gallium/drivers/nv40/nv40_state.c | 39 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index a36efd37f6..fec8f946c3 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -280,31 +280,30 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = MALLOC(sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *curie = nv40->hw->curie; /*XXX: ignored: * light_twoside - * offset_cw/ccw -nohw * point_smooth -nohw * multisample - * offset_units / offset_scale */ - so_method(so, nv40->hw->curie, NV40TCL_SHADE_MODEL, 1); + so_method(so, curie, NV40TCL_SHADE_MODEL, 1); so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT : NV40TCL_SHADE_MODEL_SMOOTH); - so_method(so, nv40->hw->curie, NV40TCL_LINE_WIDTH, 2); + so_method(so, curie, NV40TCL_LINE_WIDTH, 2); so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff); so_data (so, cso->line_smooth ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_LINE_STIPPLE_ENABLE, 2); + so_method(so, curie, NV40TCL_LINE_STIPPLE_ENABLE, 2); so_data (so, cso->line_stipple_enable ? 1 : 0); so_data (so, (cso->line_stipple_pattern << 16) | cso->line_stipple_factor); - so_method(so, nv40->hw->curie, NV40TCL_POINT_SIZE, 1); + so_method(so, curie, NV40TCL_POINT_SIZE, 1); so_data (so, fui(cso->point_size)); - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_MODE_FRONT, 6); + so_method(so, curie, NV40TCL_POLYGON_MODE_FRONT, 6); if (cso->front_winding == PIPE_WINDING_CCW) { so_data(so, nvgl_polygon_mode(cso->fill_ccw)); so_data(so, nvgl_polygon_mode(cso->fill_cw)); @@ -345,10 +344,32 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, cso->poly_smooth ? 1 : 0); so_data(so, cso->cull_mode != PIPE_WINDING_NONE ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_POINT_SPRITE, 1); + so_method(so, curie, 0x0a60, 3); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) + so_data(so, 1); + else + so_data(so, 0); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) + so_data(so, 1); + else + so_data(so, 0); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) + so_data(so, 1); + else + so_data(so, 0); + if (cso->offset_cw || cso->offset_ccw) { + so_method(so, curie, NV40TCL_POLYGON_OFFSET_FACTOR, 2); + so_data (so, fui(cso->offset_scale)); + so_data (so, fui(cso->offset_units * 2)); + } + + so_method(so, curie, NV40TCL_POINT_SPRITE, 1); if (cso->point_sprite) { unsigned psctl = (1 << 0), i; -- cgit v1.2.3 From f911235f64d610e57da88487133d0483c7a094e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 15:31:55 +1100 Subject: nouveau: header update --- src/gallium/drivers/nv40/nv40_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index fec8f946c3..d7379e9090 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -347,7 +347,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); - so_method(so, curie, 0x0a60, 3); + so_method(so, curie, NV40TCL_POLYGON_OFFSET_POINT_ENABLE, 3); if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) so_data(so, 1); -- cgit v1.2.3 From 112ba3355a3fa53768efb9a9fb0eeb677bd28d47 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 16:26:33 +1100 Subject: nv40: until gallium is fixed we'll need a fallback for user clip planes --- src/gallium/drivers/nv40/nv40_context.h | 13 +++++++++++ src/gallium/drivers/nv40/nv40_state.c | 4 ++++ src/gallium/drivers/nv40/nv40_state_emit.c | 37 ++++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 7d5806f5f7..e9ed7ea3fb 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -34,6 +34,9 @@ #define NV40_NEW_VERTPROG (1 << 9) #define NV40_NEW_FRAGPROG (1 << 10) #define NV40_NEW_ARRAYS (1 << 11) +#define NV40_NEW_UCP (1 << 12) + +#define NV40_FALLBACK_TNL (1 << 0) struct nv40_channel_context { struct nouveau_winsys *nvws; @@ -92,9 +95,11 @@ struct nv40_context { struct { struct pipe_scissor_state scissor; unsigned stipple[32]; + struct pipe_clip_state clip; } pipe_state; struct nv40_state state; + unsigned fallback; struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; @@ -131,6 +136,14 @@ nv40_context(struct pipe_context *pipe) return (struct nv40_context *)pipe; } +struct nv40_state_entry { + boolean (*validate)(struct nv40_context *nv40); + struct { + unsigned pipe; + unsigned hw; + } dirty; +}; + extern void nv40_init_state_functions(struct nv40_context *nv40); extern void nv40_init_surface_functions(struct nv40_context *nv40); extern void nv40_init_miptree_functions(struct nv40_context *nv40); diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index d7379e9090..c203b00240 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -561,6 +561,10 @@ static void nv40_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) { + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->pipe_state.clip = *clip; + nv40->dirty |= NV40_NEW_UCP; } static void diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 244c6838f3..ce52a3863e 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -79,15 +79,15 @@ nv40_state_stipple_validate(struct nv40_context *nv40) return TRUE; } -struct nv40_state_atom { - boolean (*validate)(struct nv40_context *nv40); - struct { - unsigned pipe; - unsigned hw; - } dirty; -}; +static boolean +nv40_state_clip_validate(struct nv40_context *nv40) +{ + if (nv40->pipe_state.clip.nr) + nv40->fallback |= NV40_FALLBACK_TNL; + return FALSE; +} -static struct nv40_state_atom states[] = { +static struct nv40_state_entry states[] = { { .validate = nv40_state_scissor_validate, .dirty = { @@ -101,13 +101,23 @@ static struct nv40_state_atom states[] = { .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, .hw = NV40_NEW_STIPPLE, } + }, + { + .validate = nv40_state_clip_validate, + .dirty = { + .pipe = NV40_NEW_UCP, + .hw = 0, + } } }; static void nv40_state_validate(struct nv40_context *nv40) { - unsigned i; + unsigned i, last_fallback; + + last_fallback = nv40->fallback; + nv40->fallback = 0; for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) { if (nv40->dirty & states[i].dirty.pipe) { @@ -115,6 +125,15 @@ nv40_state_validate(struct nv40_context *nv40) nv40->hw_dirty |= states[i].dirty.hw; } } + + if (nv40->fallback & NV40_FALLBACK_TNL && + !(last_fallback & NV40_FALLBACK_TNL)) { + NOUVEAU_ERR("XXX: hwtnl->swtnl\n"); + } else + if (last_fallback & NV40_FALLBACK_TNL && + !(nv40->fallback & NV40_FALLBACK_TNL)) { + NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); + } } void -- cgit v1.2.3 From 56045da083d6530a56a2a7585e3121df0b07bac4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 16:38:27 +1100 Subject: nv40: move some things around --- src/gallium/drivers/nv40/Makefile | 3 + src/gallium/drivers/nv40/nv40_context.h | 3 + src/gallium/drivers/nv40/nv40_state_clip.c | 18 +++++ src/gallium/drivers/nv40/nv40_state_emit.c | 99 ++++----------------------- src/gallium/drivers/nv40/nv40_state_scissor.c | 35 ++++++++++ src/gallium/drivers/nv40/nv40_state_stipple.c | 40 +++++++++++ 6 files changed, 114 insertions(+), 84 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_state_clip.c create mode 100644 src/gallium/drivers/nv40/nv40_state_scissor.c create mode 100644 src/gallium/drivers/nv40/nv40_state_stipple.c (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 2a9de4a2dc..12b8eef259 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -13,6 +13,9 @@ DRIVER_SOURCES = \ nv40_query.c \ nv40_state.c \ nv40_state_emit.c \ + nv40_state_clip.c \ + nv40_state_scissor.c \ + nv40_state_stipple.c \ nv40_surface.c \ nv40_vbo.c \ nv40_vertprog.c diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index e9ed7ea3fb..432204b825 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -174,6 +174,9 @@ extern void nv40_fragtex_bind(struct nv40_context *); /* nv40_state.c and friends */ extern void nv40_emit_hw_state(struct nv40_context *nv40); extern void nv40_state_tex_update(struct nv40_context *nv40); +extern struct nv40_state_entry nv40_state_clip; +extern struct nv40_state_entry nv40_state_scissor; +extern struct nv40_state_entry nv40_state_stipple; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c new file mode 100644 index 0000000000..19f1c3b36d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -0,0 +1,18 @@ +#include "nv40_context.h" + +static boolean +nv40_state_clip_validate(struct nv40_context *nv40) +{ + if (nv40->pipe_state.clip.nr) + nv40->fallback |= NV40_FALLBACK_TNL; + + return FALSE; +} + +struct nv40_state_entry nv40_state_clip = { + .validate = nv40_state_clip_validate, + .dirty = { + .pipe = NV40_NEW_UCP, + .hw = 0 + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index ce52a3863e..b5d0d68d6b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -22,63 +22,6 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40) so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); } -static boolean -nv40_state_scissor_validate(struct nv40_context *nv40) -{ - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct pipe_scissor_state *s = &nv40->pipe_state.scissor; - struct nouveau_stateobj *so; - - if (nv40->state.scissor.so && - (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) - return FALSE; - - so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); - if (rast->scissor) { - so_data (so, ((s->maxx - s->minx) << 16) | s->minx); - so_data (so, ((s->maxy - s->miny) << 16) | s->miny); - } else { - so_data (so, 4096 << 16); - so_data (so, 4096 << 16); - } - - so_ref(so, &nv40->state.scissor.so); - so_ref(NULL, &so); - return TRUE; -} - -static boolean -nv40_state_stipple_validate(struct nv40_context *nv40) -{ - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct nouveau_grobj *curie = nv40->hw->curie; - struct nouveau_stateobj *so; - - if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 && - nv40->state.stipple.enabled == 0)) - return FALSE; - - if (rast->poly_stipple_enable) { - unsigned i; - - so = so_new(35, 0); - so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); - so_data (so, 1); - so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); - for (i = 0; i < 32; i++) - so_data(so, nv40->pipe_state.stipple[i]); - } else { - so = so_new(2, 0); - so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); - so_data (so, 0); - } - - so_ref(so, &nv40->state.stipple.so); - so_ref(NULL, &so); - return TRUE; -} - static boolean nv40_state_clip_validate(struct nv40_context *nv40) { @@ -87,43 +30,31 @@ nv40_state_clip_validate(struct nv40_context *nv40) return FALSE; } -static struct nv40_state_entry states[] = { - { - .validate = nv40_state_scissor_validate, - .dirty = { - .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, - .hw = NV40_NEW_SCISSOR, - } - }, - { - .validate = nv40_state_stipple_validate, - .dirty = { - .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, - .hw = NV40_NEW_STIPPLE, - } - }, - { - .validate = nv40_state_clip_validate, - .dirty = { - .pipe = NV40_NEW_UCP, - .hw = 0, - } - } +static struct nv40_state_entry *render_states[] = { + &nv40_state_clip, + &nv40_state_scissor, + &nv40_state_stipple, + NULL }; static void nv40_state_validate(struct nv40_context *nv40) { - unsigned i, last_fallback; + struct nv40_state_entry **states = render_states; + unsigned last_fallback; last_fallback = nv40->fallback; nv40->fallback = 0; - for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) { - if (nv40->dirty & states[i].dirty.pipe) { - if (states[i].validate(nv40)) - nv40->hw_dirty |= states[i].dirty.hw; + while (*states) { + struct nv40_state_entry *e = *states; + + if (nv40->dirty & e->dirty.pipe) { + if (e->validate(nv40)) + nv40->hw_dirty |= e->dirty.hw; } + + states++; } if (nv40->fallback & NV40_FALLBACK_TNL && diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c new file mode 100644 index 0000000000..556b820e58 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -0,0 +1,35 @@ +#include "nv40_context.h" + +static boolean +nv40_state_scissor_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_scissor_state *s = &nv40->pipe_state.scissor; + struct nouveau_stateobj *so; + + if (nv40->state.scissor.so && + (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) + return FALSE; + + so = so_new(3, 0); + so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + if (rast->scissor) { + so_data (so, ((s->maxx - s->minx) << 16) | s->minx); + so_data (so, ((s->maxy - s->miny) << 16) | s->miny); + } else { + so_data (so, 4096 << 16); + so_data (so, 4096 << 16); + } + + so_ref(so, &nv40->state.scissor.so); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_scissor = { + .validate = nv40_state_scissor_validate, + .dirty = { + .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, + .hw = NV40_NEW_SCISSOR + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c new file mode 100644 index 0000000000..52462a0b50 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -0,0 +1,40 @@ +#include "nv40_context.h" + +static boolean +nv40_state_stipple_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_stateobj *so; + + if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 && + nv40->state.stipple.enabled == 0)) + return FALSE; + + if (rast->poly_stipple_enable) { + unsigned i; + + so = so_new(35, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 1); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, nv40->pipe_state.stipple[i]); + } else { + so = so_new(2, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &nv40->state.stipple.so); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_stipple = { + .validate = nv40_state_stipple_validate, + .dirty = { + .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, + .hw = NV40_NEW_STIPPLE + } +}; -- cgit v1.2.3 From 4a9cb97bbf6961cc4106c4c54e59296a74e889e9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 17:07:59 +1100 Subject: nv40: get fragprog onto new state mechanism --- src/gallium/drivers/nv40/nv40_context.h | 17 ++-- src/gallium/drivers/nv40/nv40_fragprog.c | 127 +++++++++++++++++------------ src/gallium/drivers/nv40/nv40_fragtex.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 5 +- src/gallium/drivers/nv40/nv40_state.h | 1 - src/gallium/drivers/nv40/nv40_state_emit.c | 26 +++--- 6 files changed, 97 insertions(+), 81 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 432204b825..ce0933fea4 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -37,6 +37,7 @@ #define NV40_NEW_UCP (1 << 12) #define NV40_FALLBACK_TNL (1 << 0) +#define NV40_FALLBACK_RAST (1 << 1) struct nv40_channel_context { struct nouveau_winsys *nvws; @@ -72,6 +73,8 @@ struct nv40_state { unsigned enabled; struct nouveau_stateobj *so; } stipple; + + struct nouveau_stateobj *fragprog; }; struct nv40_context { @@ -96,6 +99,8 @@ struct nv40_context { struct pipe_scissor_state scissor; unsigned stipple[32]; struct pipe_clip_state clip; + struct nv40_fragment_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; } pipe_state; struct nv40_state state; @@ -119,13 +124,6 @@ struct nv40_context { struct pipe_buffer *constant_buf; } vertprog; - struct { - struct nv40_fragment_program *active; - - struct nv40_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -161,10 +159,6 @@ extern void nv40_vertprog_destroy(struct nv40_context *, struct nv40_vertex_program *); /* nv40_fragprog.c */ -extern void nv40_fragprog_translate(struct nv40_context *, - struct nv40_fragment_program *); -extern void nv40_fragprog_bind(struct nv40_context *, - struct nv40_fragment_program *); extern void nv40_fragprog_destroy(struct nv40_context *, struct nv40_fragment_program *); @@ -177,6 +171,7 @@ extern void nv40_state_tex_update(struct nv40_context *nv40); extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; +extern struct nv40_state_entry nv40_state_fragprog; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 07a418c1e9..bfc75eb462 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -668,7 +668,7 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, return TRUE; } -void +static void nv40_fragprog_translate(struct nv40_context *nv40, struct nv40_fragment_program *fp) { @@ -750,72 +750,66 @@ nv40_fragprog_translate(struct nv40_context *nv40, fp->insn[fpc->inst_offset + 3] = 0x00000000; fp->translated = TRUE; - fp->on_hw = FALSE; out_err: tgsi_parse_free(&parse); free(fpc); } -void -nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) +static void +nv40_fragprog_upload(struct nv40_context *nv40, + struct nv40_fragment_program *fp) { struct pipe_winsys *ws = nv40->pipe.winsys; - struct nouveau_stateobj *so; + const uint32_t le = 1; + uint32_t *map; int i; - if (!fp->translated) { - nv40_fragprog_translate(nv40, fp); - if (!fp->translated) - assert(0); - } + map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - if (fp->nr_consts) { - float *map = ws->buffer_map(ws, nv40->fragprog.constant_buf, - PIPE_BUFFER_USAGE_CPU_READ); - for (i = 0; i < fp->nr_consts; i++) { - struct nv40_fragment_program_data *fpd = &fp->consts[i]; - uint32_t *p = &fp->insn[fpd->offset]; - uint32_t *cb = (uint32_t *)&map[fpd->index * 4]; +#if 0 + for (i = 0; i < fp->insn_len; i++) { + NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); + } +#endif - if (!memcmp(p, cb, 4 * sizeof(float))) - continue; - memcpy(p, cb, 4 * sizeof(float)); - fp->on_hw = 0; + if ((*(const uint8_t *)&le)) { + for (i = 0; i < fp->insn_len; i++) { + map[i] = fp->insn[i]; + } + } else { + /* Weird swapping for big-endian chips */ + for (i = 0; i < fp->insn_len; i++) { + map[i] = ((fp->insn[i] & 0xffff) << 16) | + ((fp->insn[i] >> 16) & 0xffff); } - ws->buffer_unmap(ws, nv40->fragprog.constant_buf); } - if (!fp->on_hw) { - const uint32_t le = 1; - uint32_t *map; - - if (!fp->buffer) - fp->buffer = ws->buffer_create(ws, 0x100, 0, - fp->insn_len * 4); - map = ws->buffer_map(ws, fp->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE); + ws->buffer_unmap(ws, fp->buffer); +} -#if 0 - for (i = 0; i < fp->insn_len; i++) { - NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); - } -#endif +static boolean +nv40_fragprog_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct pipe_buffer *constbuf = + nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_stateobj *so; + unsigned new_program = FALSE; + int i; - if ((*(const uint8_t *)&le)) { - for (i = 0; i < fp->insn_len; i++) { - map[i] = fp->insn[i]; - } - } else { - /* Weird swapping for big-endian chips */ - for (i = 0; i < fp->insn_len; i++) { - map[i] = ((fp->insn[i] & 0xffff) << 16) | - ((fp->insn[i] >> 16) & 0xffff); - } - } + if (fp->translated) + goto update_constants; - ws->buffer_unmap(ws, fp->buffer); - fp->on_hw = TRUE; + nv40_fragprog_translate(nv40, fp); + if (!fp->translated) { + nv40->fallback |= NV40_FALLBACK_RAST; + return FALSE; } + new_program = TRUE; + + fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); + nv40_fragprog_upload(nv40, fp); so = so_new(4, 1); so_method(so, nv40->hw->curie, NV40TCL_FP_ADDRESS, 1); @@ -824,12 +818,33 @@ nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); - - so_emit(nv40->nvws, so); so_ref(so, &fp->so); so_ref(NULL, &so); - nv40->fragprog.active = fp; +update_constants: + if (fp->nr_consts) { + boolean new_consts = FALSE; + float *map; + + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < fp->nr_consts; i++) { + struct nv40_fragment_program_data *fpd = &fp->consts[i]; + uint32_t *p = &fp->insn[fpd->offset]; + uint32_t *cb = (uint32_t *)&map[fpd->index * 4]; + + if (!memcmp(p, cb, 4 * sizeof(float))) + continue; + memcpy(p, cb, 4 * sizeof(float)); + new_consts = TRUE; + } + ws->buffer_unmap(ws, constbuf); + + if (new_consts) + nv40_fragprog_upload(nv40, fp); + } + + so_ref(fp->so, &nv40->state.fragprog); + return new_program; } void @@ -840,3 +855,11 @@ nv40_fragprog_destroy(struct nv40_context *nv40, free(fp->insn); } +struct nv40_state_entry nv40_state_fragprog = { + .validate = nv40_fragprog_validate, + .dirty = { + .pipe = NV40_NEW_FRAGPROG, + .hw = NV40_NEW_FRAGPROG + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 5af5fbe746..811f3098ba 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -125,7 +125,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) void nv40_fragtex_bind(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->fragprog.active; + struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; unsigned samplers, unit; samplers = nv40->fp_samplers & ~fp->samplers; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index c203b00240..2886c6b0dc 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -523,9 +523,8 @@ static void nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_fragment_program *fp = hwcso; - nv40->fragprog.current = fp; + nv40->pipe_state.fragprog = hwcso; nv40->dirty |= NV40_NEW_FRAGPROG; } @@ -578,7 +577,7 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->fragprog.constant_buf = buf->buffer; + nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index e82ab9de98..2701294a07 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -50,7 +50,6 @@ struct nv40_fragment_program { const struct pipe_shader_state *pipe; boolean translated; - boolean on_hw; unsigned samplers; uint32_t *insn; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index b5d0d68d6b..e10e178432 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -19,21 +19,14 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40) continue; so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); } - so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); -} - -static boolean -nv40_state_clip_validate(struct nv40_context *nv40) -{ - if (nv40->pipe_state.clip.nr) - nv40->fallback |= NV40_FALLBACK_TNL; - return FALSE; + so_emit_reloc_markers(nv40->nvws, nv40->state.fragprog); } static struct nv40_state_entry *render_states[] = { &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, + &nv40_state_fragprog, NULL }; @@ -65,6 +58,15 @@ nv40_state_validate(struct nv40_context *nv40) !(nv40->fallback & NV40_FALLBACK_TNL)) { NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); } + + if (nv40->fallback & NV40_FALLBACK_RAST && + !(last_fallback & NV40_FALLBACK_RAST)) { + NOUVEAU_ERR("XXX: hwrast->swrast\n"); + } else + if (last_fallback & NV40_FALLBACK_RAST && + !(nv40->fallback & NV40_FALLBACK_RAST)) { + NOUVEAU_ERR("XXX: swrast->hwrast\n"); + } } void @@ -100,10 +102,8 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->hw_dirty &= ~NV40_NEW_STIPPLE; } - if (nv40->dirty & NV40_NEW_FRAGPROG) { - nv40_fragprog_bind(nv40, nv40->fragprog.current); - /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */ - } + if (nv40->hw_dirty & NV40_NEW_FRAGPROG) + so_emit(nv40->nvws, nv40->state.fragprog); if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); -- cgit v1.2.3 From 9a5dd26fe22c37b85787130a2b724e6e8ef4f553 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 17:36:24 +1100 Subject: nv40: and vertprog.. --- src/gallium/drivers/nv40/nv40_context.h | 14 ++------ src/gallium/drivers/nv40/nv40_fragprog.c | 10 +++--- src/gallium/drivers/nv40/nv40_state.c | 5 ++- src/gallium/drivers/nv40/nv40_state.h | 1 + src/gallium/drivers/nv40/nv40_state_emit.c | 3 +- src/gallium/drivers/nv40/nv40_vbo.c | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 57 +++++++++++++++++++++--------- 7 files changed, 55 insertions(+), 37 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index ce0933fea4..28a0274d77 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -75,6 +75,7 @@ struct nv40_state { } stipple; struct nouveau_stateobj *fragprog; + struct nouveau_stateobj *vertprog; }; struct nv40_context { @@ -99,6 +100,7 @@ struct nv40_context { struct pipe_scissor_state scissor; unsigned stipple[32]; struct pipe_clip_state clip; + struct nv40_vertex_program *vertprog; struct nv40_fragment_program *fragprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; } pipe_state; @@ -117,13 +119,6 @@ struct nv40_context { struct nouveau_stateobj *so_viewport; struct nouveau_stateobj *so_stipple; - struct { - struct nv40_vertex_program *active; - - struct nv40_vertex_program *current; - struct pipe_buffer *constant_buf; - } vertprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -151,10 +146,6 @@ extern void nv40_init_query_functions(struct nv40_context *nv40); extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); /* nv40_vertprog.c */ -extern void nv40_vertprog_translate(struct nv40_context *, - struct nv40_vertex_program *); -extern void nv40_vertprog_bind(struct nv40_context *, - struct nv40_vertex_program *); extern void nv40_vertprog_destroy(struct nv40_context *, struct nv40_vertex_program *); @@ -172,6 +163,7 @@ extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; extern struct nv40_state_entry nv40_state_fragprog; +extern struct nv40_state_entry nv40_state_vertprog; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index bfc75eb462..77ac8ab2c6 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -795,7 +795,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; - unsigned new_program = FALSE; int i; if (fp->translated) @@ -806,7 +805,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->fallback |= NV40_FALLBACK_RAST; return FALSE; } - new_program = TRUE; fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv40_fragprog_upload(nv40, fp); @@ -843,8 +841,12 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - so_ref(fp->so, &nv40->state.fragprog); - return new_program; + if (fp->so != nv40->state.fragprog) { + so_ref(fp->so, &nv40->state.fragprog); + return TRUE; + } + + return FALSE; } void diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 2886c6b0dc..8ffbb131f7 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -491,9 +491,8 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_vertex_program *vp = hwcso; - nv40->vertprog.current = vp; + nv40->pipe_state.vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; } @@ -573,7 +572,7 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv40->vertprog.constant_buf = buf->buffer; + nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 2701294a07..e5217fe91c 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -39,6 +39,7 @@ struct nv40_vertex_program { uint32_t ir; uint32_t or; + struct nouveau_stateobj *so; }; struct nv40_fragment_program_data { diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e10e178432..e702b10323 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -27,6 +27,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, + &nv40_state_vertprog, NULL }; @@ -116,7 +117,7 @@ nv40_emit_hw_state(struct nv40_context *nv40) } if (nv40->dirty & NV40_NEW_VERTPROG) { - nv40_vertprog_bind(nv40, nv40->vertprog.current); + so_emit(nv40->nvws, nv40->state.vertprog); nv40->dirty &= ~NV40_NEW_VERTPROG; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index fa827ef0c5..3bfcb264db 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -101,7 +101,7 @@ static void nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned ib_format) { - struct nv40_vertex_program *vp = nv40->vertprog.active; + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt; unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 9f4738b830..4a15e51eb3 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -558,7 +558,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) return TRUE; } -void +static void nv40_vertprog_translate(struct nv40_context *nv40, struct nv40_vertex_program *vp) { @@ -631,24 +631,32 @@ out_err: free(vpc); } -void -nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) +static boolean +nv40_vertprog_validate(struct nv40_context *nv40) { + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct pipe_buffer *constbuf = + nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; boolean upload_code = FALSE, upload_data = FALSE; int i; /* Translate TGSI shader into hw bytecode */ + if (vp->translated) + goto check_gpu_resources; + + nv40_vertprog_translate(nv40, vp); if (!vp->translated) { - nv40_vertprog_translate(nv40, vp); - if (!vp->translated) - assert(0); + nv40->fallback |= NV40_FALLBACK_TNL; + return FALSE; } +check_gpu_resources: /* Allocate hw vtxprog exec slots */ if (!vp->exec) { struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + struct nouveau_stateobj *so; uint vplen = vp->nr_insns; if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { @@ -663,6 +671,15 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) assert(0); } + so = so_new(5, 0); + so_method(so, nv40->hw->curie, NV40TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + so_method(so, nv40->hw->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_data (so, vp->ir); + so_data (so, vp->or); + so_ref(so, &vp->so); + so_ref(NULL, &so); + upload_code = TRUE; } @@ -725,8 +742,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) if (vp->nr_consts) { float *map = NULL; - if (nv40->vertprog.constant_buf) { - map = ws->buffer_map(ws, nv40->vertprog.constant_buf, + if (constbuf) { + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); } @@ -747,9 +764,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) OUT_RINGp ((uint32_t *)vpd->value, 4); } - if (map) { - ws->buffer_unmap(ws, nv40->vertprog.constant_buf); - } + if (constbuf) + ws->buffer_unmap(ws, constbuf); } /* Upload vtxprog */ @@ -770,13 +786,12 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) } } - BEGIN_RING(curie, NV40TCL_VP_START_FROM_ID, 1); - OUT_RING (vp->exec->start); - BEGIN_RING(curie, NV40TCL_VP_ATTRIB_EN, 2); - OUT_RING (vp->ir); - OUT_RING (vp->or); + if (vp->so != nv40->state.vertprog) { + so_ref(vp->so, &nv40->state.vertprog); + return TRUE; + } - nv40->vertprog.active = vp; + return FALSE; } void @@ -788,3 +803,11 @@ nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) free(vp->insns); } +struct nv40_state_entry nv40_state_vertprog = { + .validate = nv40_vertprog_validate, + .dirty = { + .pipe = NV40_NEW_VERTPROG, + .hw = NV40_NEW_VERTPROG + } +}; + -- cgit v1.2.3 From c0f9cab905f3f54cc01bf947665f8a731b8cb347 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 18:23:12 +1100 Subject: nouveau: cleanups + fixes --- src/gallium/drivers/nv40/nv40_state_emit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e702b10323..e8230111bb 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -103,8 +103,10 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->hw_dirty &= ~NV40_NEW_STIPPLE; } - if (nv40->hw_dirty & NV40_NEW_FRAGPROG) + if (nv40->hw_dirty & NV40_NEW_FRAGPROG) { so_emit(nv40->nvws, nv40->state.fragprog); + nv40->hw_dirty &= ~NV40_NEW_FRAGPROG; + } if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); @@ -116,9 +118,9 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->dirty &= ~NV40_NEW_FRAGPROG; } - if (nv40->dirty & NV40_NEW_VERTPROG) { + if (nv40->hw_dirty & NV40_NEW_VERTPROG) { so_emit(nv40->nvws, nv40->state.vertprog); - nv40->dirty &= ~NV40_NEW_VERTPROG; + nv40->hw_dirty &= ~NV40_NEW_VERTPROG; } nv40->dirty_samplers = 0; -- cgit v1.2.3 From 46c3d0918dd7a47f69c21e4eb1a3fd2a2fbe6223 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 16:21:28 +1100 Subject: nv40: keep track of generated context state vs current channel state --- src/gallium/drivers/nv40/nv40_context.h | 26 ++++++----- src/gallium/drivers/nv40/nv40_fragprog.c | 6 +-- src/gallium/drivers/nv40/nv40_state_emit.c | 67 ++++++++++----------------- src/gallium/drivers/nv40/nv40_state_scissor.c | 8 ++-- src/gallium/drivers/nv40/nv40_state_stipple.c | 8 ++-- src/gallium/drivers/nv40/nv40_vertprog.c | 6 +-- 6 files changed, 53 insertions(+), 68 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 28a0274d77..2dd137ead0 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -22,6 +22,15 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +enum nv40_state_index { + NV40_STATE_CLIP = 1ULL, + NV40_STATE_SCISSOR = 2ULL, + NV40_STATE_STIPPLE = 3ULL, + NV40_STATE_FRAGPROG = 4ULL, + NV40_STATE_VERTPROG = 5ULL, + NV40_STATE_MAX = 6ULL +}; + #define NV40_NEW_BLEND (1 << 0) #define NV40_NEW_RAST (1 << 1) #define NV40_NEW_ZSA (1 << 2) @@ -56,6 +65,9 @@ struct nv40_channel_context { /* Vtxprog resources */ struct nouveau_resource *vp_exec_heap; struct nouveau_resource *vp_data_heap; + + /* Current 3D state of channel */ + struct nouveau_stateobj *state[NV40_STATE_MAX]; }; struct nv40_rasterizer_state { @@ -64,18 +76,10 @@ struct nv40_rasterizer_state { }; struct nv40_state { - struct { - unsigned enabled; - struct nouveau_stateobj *so; - } scissor; - - struct { - unsigned enabled; - struct nouveau_stateobj *so; - } stipple; + unsigned scissor_enabled; + unsigned stipple_enabled; - struct nouveau_stateobj *fragprog; - struct nouveau_stateobj *vertprog; + struct nouveau_stateobj *hw[NV40_STATE_MAX]; }; struct nv40_context { diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 77ac8ab2c6..db2613ef8b 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -841,8 +841,8 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - if (fp->so != nv40->state.fragprog) { - so_ref(fp->so, &nv40->state.fragprog); + if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { + so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]); return TRUE; } @@ -861,7 +861,7 @@ struct nv40_state_entry nv40_state_fragprog = { .validate = nv40_fragprog_validate, .dirty = { .pipe = NV40_NEW_FRAGPROG, - .hw = NV40_NEW_FRAGPROG + .hw = NV40_STATE_FRAGPROG } }; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e8230111bb..58beb72389 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -1,27 +1,6 @@ #include "nv40_context.h" #include "nv40_state.h" -/* Emit relocs for every referenced buffer. - * - * This is to ensure the bufmgr has an accurate idea of how - * the buffer is used. These relocs appear in the push buffer as - * NOPs, and will only be turned into state changes if a buffer - * actually moves. - */ -static void -nv40_state_emit_dummy_relocs(struct nv40_context *nv40) -{ - unsigned i; - - so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); - for (i = 0; i < 16; i++) { - if (!(nv40->fp_samplers & (1 << i))) - continue; - so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); - } - so_emit_reloc_markers(nv40->nvws, nv40->state.fragprog); -} - static struct nv40_state_entry *render_states[] = { &nv40_state_clip, &nv40_state_scissor, @@ -45,7 +24,7 @@ nv40_state_validate(struct nv40_context *nv40) if (nv40->dirty & e->dirty.pipe) { if (e->validate(nv40)) - nv40->hw_dirty |= e->dirty.hw; + nv40->hw_dirty |= (1 << e->dirty.hw); } states++; @@ -70,6 +49,28 @@ nv40_state_validate(struct nv40_context *nv40) } } +static void +nv40_state_emit(struct nv40_context *nv40) +{ + unsigned i; + + while (nv40->hw_dirty) { + unsigned idx = ffs(nv40->hw_dirty) - 1; + nv40->hw_dirty &= ~(1 << idx); + + so_ref (nv40->state.hw[idx], &nv40->hw->state[idx]); + so_emit(nv40->nvws, nv40->hw->state[idx]); + } + + so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); + for (i = 0; i < 16; i++) { + if (!(nv40->fp_samplers & (1 << i))) + continue; + so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); + } + so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]); +} + void nv40_emit_hw_state(struct nv40_context *nv40) { @@ -90,24 +91,9 @@ nv40_emit_hw_state(struct nv40_context *nv40) if (nv40->dirty & NV40_NEW_BCOL) so_emit(nv40->nvws, nv40->so_bcol); - if (nv40->hw_dirty & NV40_NEW_SCISSOR) { - so_emit(nv40->nvws, nv40->state.scissor.so); - nv40->hw_dirty &= ~NV40_NEW_SCISSOR; - } - if (nv40->dirty & NV40_NEW_VIEWPORT) so_emit(nv40->nvws, nv40->so_viewport); - if (nv40->hw_dirty & NV40_NEW_STIPPLE) { - so_emit(nv40->nvws, nv40->state.stipple.so); - nv40->hw_dirty &= ~NV40_NEW_STIPPLE; - } - - if (nv40->hw_dirty & NV40_NEW_FRAGPROG) { - so_emit(nv40->nvws, nv40->state.fragprog); - nv40->hw_dirty &= ~NV40_NEW_FRAGPROG; - } - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); @@ -118,14 +104,9 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->dirty &= ~NV40_NEW_FRAGPROG; } - if (nv40->hw_dirty & NV40_NEW_VERTPROG) { - so_emit(nv40->nvws, nv40->state.vertprog); - nv40->hw_dirty &= ~NV40_NEW_VERTPROG; - } + nv40_state_emit(nv40); nv40->dirty_samplers = 0; nv40->dirty = 0; - - nv40_state_emit_dummy_relocs(nv40); } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 556b820e58..dc7b6d3a9d 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -7,8 +7,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40) struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; - if (nv40->state.scissor.so && - (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) + if (nv40->state.hw[NV40_STATE_SCISSOR] && + (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) return FALSE; so = so_new(3, 0); @@ -21,7 +21,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40) so_data (so, 4096 << 16); } - so_ref(so, &nv40->state.scissor.so); + so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]); so_ref(NULL, &so); return TRUE; } @@ -30,6 +30,6 @@ struct nv40_state_entry nv40_state_scissor = { .validate = nv40_state_scissor_validate, .dirty = { .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, - .hw = NV40_NEW_SCISSOR + .hw = NV40_STATE_SCISSOR } }; diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 52462a0b50..1b0b194432 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -7,8 +7,8 @@ nv40_state_stipple_validate(struct nv40_context *nv40) struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; - if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 && - nv40->state.stipple.enabled == 0)) + if (nv40->state.hw[NV40_STATE_STIPPLE] && + (rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0)) return FALSE; if (rast->poly_stipple_enable) { @@ -26,7 +26,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40) so_data (so, 0); } - so_ref(so, &nv40->state.stipple.so); + so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]); so_ref(NULL, &so); return TRUE; } @@ -35,6 +35,6 @@ struct nv40_state_entry nv40_state_stipple = { .validate = nv40_state_stipple_validate, .dirty = { .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, - .hw = NV40_NEW_STIPPLE + .hw = NV40_STATE_STIPPLE, } }; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 4a15e51eb3..8a2d233697 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -786,8 +786,8 @@ check_gpu_resources: } } - if (vp->so != nv40->state.vertprog) { - so_ref(vp->so, &nv40->state.vertprog); + if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) { + so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]); return TRUE; } @@ -807,7 +807,7 @@ struct nv40_state_entry nv40_state_vertprog = { .validate = nv40_vertprog_validate, .dirty = { .pipe = NV40_NEW_VERTPROG, - .hw = NV40_NEW_VERTPROG + .hw = NV40_STATE_VERTPROG, } }; -- cgit v1.2.3 From 9cd10d7618a226fe46395b08beb19e420bc14a4f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 17:14:41 +1100 Subject: nv40: almost there.. --- src/gallium/drivers/nv40/Makefile | 6 ++- src/gallium/drivers/nv40/nv40_context.h | 66 +++++++++++++++++++----- src/gallium/drivers/nv40/nv40_state.c | 62 +++++++++------------- src/gallium/drivers/nv40/nv40_state_blend.c | 41 +++++++++++++++ src/gallium/drivers/nv40/nv40_state_emit.c | 20 ++----- src/gallium/drivers/nv40/nv40_state_rasterizer.c | 17 ++++++ src/gallium/drivers/nv40/nv40_state_scissor.c | 2 +- src/gallium/drivers/nv40/nv40_state_stipple.c | 2 +- src/gallium/drivers/nv40/nv40_state_viewport.c | 30 +++++++++++ src/gallium/drivers/nv40/nv40_state_zsa.c | 17 ++++++ 10 files changed, 194 insertions(+), 69 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_state_blend.c create mode 100644 src/gallium/drivers/nv40/nv40_state_rasterizer.c create mode 100644 src/gallium/drivers/nv40/nv40_state_viewport.c create mode 100644 src/gallium/drivers/nv40/nv40_state_zsa.c (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 12b8eef259..82295cbefc 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -12,10 +12,14 @@ DRIVER_SOURCES = \ nv40_miptree.c \ nv40_query.c \ nv40_state.c \ - nv40_state_emit.c \ + nv40_state_blend.c \ nv40_state_clip.c \ + nv40_state_emit.c \ + nv40_state_rasterizer.c \ nv40_state_scissor.c \ nv40_state_stipple.c \ + nv40_state_viewport.c \ + nv40_state_zsa.c \ nv40_surface.c \ nv40_vbo.c \ nv40_vertprog.c diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 2dd137ead0..d71fe11a4a 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -23,12 +23,38 @@ fprintf(stderr, "nouveau: "fmt, ##args); enum nv40_state_index { - NV40_STATE_CLIP = 1ULL, - NV40_STATE_SCISSOR = 2ULL, - NV40_STATE_STIPPLE = 3ULL, - NV40_STATE_FRAGPROG = 4ULL, - NV40_STATE_VERTPROG = 5ULL, - NV40_STATE_MAX = 6ULL + NV40_STATE_FB = 0, + NV40_STATE_VIEWPORT = 1, + NV40_STATE_BLEND = 2, + NV40_STATE_RAST = 3, + NV40_STATE_ZSA = 4, + NV40_STATE_BCOL = 5, + NV40_STATE_CLIP = 6, + NV40_STATE_SCISSOR = 7, + NV40_STATE_STIPPLE = 8, + NV40_STATE_FRAGPROG = 9, + NV40_STATE_VERTPROG = 10, + NV40_STATE_FRAGTEX0 = 11, + NV40_STATE_FRAGTEX1 = 12, + NV40_STATE_FRAGTEX2 = 13, + NV40_STATE_FRAGTEX3 = 14, + NV40_STATE_FRAGTEX4 = 15, + NV40_STATE_FRAGTEX5 = 16, + NV40_STATE_FRAGTEX6 = 17, + NV40_STATE_FRAGTEX7 = 18, + NV40_STATE_FRAGTEX8 = 19, + NV40_STATE_FRAGTEX9 = 20, + NV40_STATE_FRAGTEX10 = 21, + NV40_STATE_FRAGTEX11 = 22, + NV40_STATE_FRAGTEX12 = 23, + NV40_STATE_FRAGTEX13 = 24, + NV40_STATE_FRAGTEX14 = 25, + NV40_STATE_FRAGTEX15 = 26, + NV40_STATE_VERTTEX0 = 27, + NV40_STATE_VERTTEX1 = 28, + NV40_STATE_VERTTEX2 = 29, + NV40_STATE_VERTTEX3 = 30, + NV40_STATE_MAX = 31 }; #define NV40_NEW_BLEND (1 << 0) @@ -75,6 +101,17 @@ struct nv40_rasterizer_state { struct nouveau_stateobj *so; }; +struct nv40_zsa_state { + struct pipe_depth_stencil_alpha_state pipe; + struct nouveau_stateobj *so; +}; + +struct nv40_blend_state { + struct pipe_blend_state pipe; + struct nouveau_stateobj *so; +}; + + struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; @@ -107,6 +144,11 @@ struct nv40_context { struct nv40_vertex_program *vertprog; struct nv40_fragment_program *fragprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct nv40_rasterizer_state *rasterizer; + struct nv40_zsa_state *zsa; + struct nv40_blend_state *blend; + struct pipe_blend_color blend_colour; + struct pipe_viewport_state viewport; } pipe_state; struct nv40_state state; @@ -115,13 +157,6 @@ struct nv40_context { struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; - struct nouveau_stateobj *so_blend; - struct nv40_rasterizer_state *rasterizer; - struct nouveau_stateobj *so_rast; - struct nouveau_stateobj *so_zsa; - struct nouveau_stateobj *so_bcol; - struct nouveau_stateobj *so_viewport; - struct nouveau_stateobj *so_stipple; struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; @@ -164,10 +199,15 @@ extern void nv40_fragtex_bind(struct nv40_context *); extern void nv40_emit_hw_state(struct nv40_context *nv40); extern void nv40_state_tex_update(struct nv40_context *nv40); extern struct nv40_state_entry nv40_state_clip; +extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; extern struct nv40_state_entry nv40_state_fragprog; extern struct nv40_state_entry nv40_state_vertprog; +extern struct nv40_state_entry nv40_state_blend; +extern struct nv40_state_entry nv40_state_blend_colour; +extern struct nv40_state_entry nv40_state_zsa; +extern struct nv40_state_entry nv40_state_viewport; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 8ffbb131f7..41631ef2dd 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -11,6 +11,7 @@ nv40_blend_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_grobj *curie = nv40->hw->curie; + struct nv40_blend_state *bso = MALLOC(sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); if (cso->blend_enable) { @@ -46,7 +47,9 @@ nv40_blend_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); so_data (so, cso->dither ? 1 : 0); - return (void *)so; + bso->so = so; + bso->pipe = *cso; + return (void *)bso; } static void @@ -54,16 +57,17 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - so_ref(hwcso, &nv40->so_blend); + nv40->pipe_state.blend = hwcso; nv40->dirty |= NV40_NEW_BLEND; } static void nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nouveau_stateobj *so = hwcso; + struct nv40_blend_state *bso = hwcso; - so_ref(NULL, &so); + so_ref(NULL, &bso->so); + FREE(bso); } @@ -260,7 +264,7 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, static void nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void @@ -392,10 +396,8 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_rasterizer_state *rsso = hwcso; - so_ref(rsso->so, &nv40->so_rast); - nv40->rasterizer = rsso; + nv40->pipe_state.rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; } @@ -405,7 +407,7 @@ nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_rasterizer_state *rsso = hwcso; so_ref(NULL, &rsso->so); - free(rsso); + FREE(rsso); } static void * @@ -413,6 +415,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_zsa_state *zsaso = MALLOC(sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); @@ -455,7 +458,9 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - return (void *)so; + zsaso->so = so; + zsaso->pipe = *cso; + return (void *)zsaso; } static void @@ -463,16 +468,17 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - so_ref(hwcso, &nv40->so_zsa); + nv40->pipe_state.zsa = hwcso; nv40->dirty |= NV40_NEW_ZSA; } static void nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nouveau_stateobj *so = hwcso; + struct nv40_zsa_state *zsaso = hwcso; - so_ref(NULL, &so); + so_ref(NULL, &zsaso->so); + FREE(zsaso); } static void * @@ -503,7 +509,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_vertex_program *vp = hwcso; nv40_vertprog_destroy(nv40, vp); - free(vp); + FREE(vp); } static void * @@ -534,7 +540,7 @@ nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_fragment_program *fp = hwcso; nv40_fragprog_destroy(nv40, fp); - free(fp); + FREE(fp); } static void @@ -542,16 +548,8 @@ nv40_set_blend_color(struct pipe_context *pipe, const struct pipe_blend_color *bcol) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(2, 0); - - so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); - so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | - (float_to_ubyte(bcol->color[0]) << 16) | - (float_to_ubyte(bcol->color[1]) << 8) | - (float_to_ubyte(bcol->color[2]) << 0))); - so_ref(so, &nv40->so_bcol); - so_ref(NULL, &so); + nv40->pipe_state.blend_colour = *bcol; nv40->dirty |= NV40_NEW_BCOL; } @@ -754,20 +752,8 @@ nv40_set_viewport_state(struct pipe_context *pipe, const struct pipe_viewport_state *vpt) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(9, 0); - - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(vpt->translate[0])); - so_data (so, fui(vpt->translate[1])); - so_data (so, fui(vpt->translate[2])); - so_data (so, fui(vpt->translate[3])); - so_data (so, fui(vpt->scale[0])); - so_data (so, fui(vpt->scale[1])); - so_data (so, fui(vpt->scale[2])); - so_data (so, fui(vpt->scale[3])); - - so_ref(so, &nv40->so_viewport); - so_ref(NULL, &so); + + nv40->pipe_state.viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c new file mode 100644 index 0000000000..b12f8b03dd --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -0,0 +1,41 @@ +#include "nv40_context.h" + +static boolean +nv40_state_blend_validate(struct nv40_context *nv40) +{ + so_ref(nv40->pipe_state.blend->so, &nv40->state.hw[NV40_STATE_BLEND]); + return TRUE; +} + +struct nv40_state_entry nv40_state_blend = { + .validate = nv40_state_blend_validate, + .dirty = { + .pipe = NV40_NEW_BLEND, + .hw = NV40_STATE_BLEND + } +}; + +static boolean +nv40_state_blend_colour_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *so = so_new(2, 0); + struct pipe_blend_color *bcol = &nv40->pipe_state.blend_colour; + + so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); + so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | + (float_to_ubyte(bcol->color[0]) << 16) | + (float_to_ubyte(bcol->color[1]) << 8) | + (float_to_ubyte(bcol->color[2]) << 0))); + + so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_blend_colour = { + .validate = nv40_state_blend_colour_validate, + .dirty = { + .pipe = NV40_NEW_BCOL, + .hw = NV40_STATE_BCOL + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 58beb72389..65d7e2978a 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -2,11 +2,16 @@ #include "nv40_state.h" static struct nv40_state_entry *render_states[] = { + &nv40_state_rasterizer, &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, &nv40_state_vertprog, + &nv40_state_blend, + &nv40_state_blend_colour, + &nv40_state_zsa, + &nv40_state_viewport, NULL }; @@ -79,21 +84,6 @@ nv40_emit_hw_state(struct nv40_context *nv40) if (nv40->dirty & NV40_NEW_FB) so_emit(nv40->nvws, nv40->so_framebuffer); - if (nv40->dirty & NV40_NEW_BLEND) - so_emit(nv40->nvws, nv40->so_blend); - - if (nv40->dirty & NV40_NEW_RAST) - so_emit(nv40->nvws, nv40->so_rast); - - if (nv40->dirty & NV40_NEW_ZSA) - so_emit(nv40->nvws, nv40->so_zsa); - - if (nv40->dirty & NV40_NEW_BCOL) - so_emit(nv40->nvws, nv40->so_bcol); - - if (nv40->dirty & NV40_NEW_VIEWPORT) - so_emit(nv40->nvws, nv40->so_viewport); - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c new file mode 100644 index 0000000000..59b35d1d50 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_rasterizer.c @@ -0,0 +1,17 @@ +#include "nv40_context.h" + +static boolean +nv40_state_rasterizer_validate(struct nv40_context *nv40) +{ + so_ref(nv40->pipe_state.rasterizer->so, + &nv40->state.hw[NV40_STATE_RAST]); + return TRUE; +} + +struct nv40_state_entry nv40_state_rasterizer = { + .validate = nv40_state_rasterizer_validate, + .dirty = { + .pipe = NV40_NEW_RAST, + .hw = NV40_STATE_RAST + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index dc7b6d3a9d..2871fa2516 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -3,7 +3,7 @@ static boolean nv40_state_scissor_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 1b0b194432..bd163582a3 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -3,7 +3,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c new file mode 100644 index 0000000000..79fcc31a8b --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -0,0 +1,30 @@ +#include "nv40_context.h" + +static boolean +nv40_state_viewport_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *so = so_new(9, 0); + struct pipe_viewport_state *vpt = &nv40->pipe_state.viewport; + + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + + so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_viewport = { + .validate = nv40_state_viewport_validate, + .dirty = { + .pipe = NV40_NEW_VIEWPORT, + .hw = NV40_STATE_VIEWPORT + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c new file mode 100644 index 0000000000..061a3555cb --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_zsa.c @@ -0,0 +1,17 @@ +#include "nv40_context.h" + +static boolean +nv40_state_zsa_validate(struct nv40_context *nv40) +{ + so_ref(nv40->pipe_state.zsa->so, + &nv40->state.hw[NV40_STATE_ZSA]); + return TRUE; +} + +struct nv40_state_entry nv40_state_zsa = { + .validate = nv40_state_zsa_validate, + .dirty = { + .pipe = NV40_NEW_ZSA, + .hw = NV40_STATE_ZSA + } +}; -- cgit v1.2.3 From 759fa5fcc8038af4845a6d9c57b75933ef26559c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 17:22:40 +1100 Subject: nv40: fb state --- src/gallium/drivers/nv40/Makefile | 1 + src/gallium/drivers/nv40/nv40_context.h | 3 +- src/gallium/drivers/nv40/nv40_state.c | 140 +------------------------- src/gallium/drivers/nv40/nv40_state_emit.c | 6 +- src/gallium/drivers/nv40/nv40_state_fb.c | 156 +++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 144 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_state_fb.c (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 82295cbefc..fd002b54e7 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -15,6 +15,7 @@ DRIVER_SOURCES = \ nv40_state_blend.c \ nv40_state_clip.c \ nv40_state_emit.c \ + nv40_state_fb.c \ nv40_state_rasterizer.c \ nv40_state_scissor.c \ nv40_state_stipple.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index d71fe11a4a..69062a8a20 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -149,12 +149,12 @@ struct nv40_context { struct nv40_blend_state *blend; struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; } pipe_state; struct nv40_state state; unsigned fallback; - struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; @@ -208,6 +208,7 @@ extern struct nv40_state_entry nv40_state_blend; extern struct nv40_state_entry nv40_state_blend_colour; extern struct nv40_state_entry nv40_state_zsa; extern struct nv40_state_entry nv40_state_viewport; +extern struct nv40_state_entry nv40_state_framebuffer; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 41631ef2dd..84818d6729 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -584,146 +584,8 @@ nv40_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct nv40_context *nv40 = nv40_context(pipe); - struct pipe_surface *rt[4], *zeta; - uint32_t rt_enable, rt_format, w, h; - int i, colour_format = 0, zeta_format = 0; - struct nouveau_stateobj *so = so_new(64, 10); - unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; - - rt_enable = 0; - for (i = 0; i < 4; i++) { - if (!fb->cbufs[i]) - continue; - - if (colour_format) { - assert(w == fb->cbufs[i]->width); - assert(h == fb->cbufs[i]->height); - assert(colour_format == fb->cbufs[i]->format); - } else { - w = fb->cbufs[i]->width; - h = fb->cbufs[i]->height; - colour_format = fb->cbufs[i]->format; - rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i); - rt[i] = fb->cbufs[i]; - } - } - - if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 | - NV40TCL_RT_ENABLE_COLOR3)) - rt_enable |= NV40TCL_RT_ENABLE_MRT; - - if (fb->zsbuf) { - if (colour_format) { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } else { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - } - - zeta_format = fb->zsbuf->format; - zeta = fb->zsbuf; - } - - rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR; - - switch (colour_format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case 0: - rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8; - break; - case PIPE_FORMAT_R5G6B5_UNORM: - rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5; - break; - default: - assert(0); - } - - switch (zeta_format) { - case PIPE_FORMAT_Z16_UNORM: - rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16; - break; - case PIPE_FORMAT_Z24S8_UNORM: - case 0: - rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8; - break; - default: - assert(0); - } - - if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1); - so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, - nv40->nvws->channel->vram->handle, - nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR0_PITCH, 2); - so_data (so, rt[0]->pitch * rt[0]->cpp); - so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | - NOUVEAU_BO_LOW, 0, 0); - } - - if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR1, 1); - so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, - nv40->nvws->channel->vram->handle, - nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR1_OFFSET, 2); - so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | - NOUVEAU_BO_LOW, 0, 0); - so_data (so, rt[1]->pitch * rt[1]->cpp); - } - - if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR2, 1); - so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, - nv40->nvws->channel->vram->handle, - nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR2_OFFSET, 1); - so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_COLOR2_PITCH, 1); - so_data (so, rt[2]->pitch * rt[2]->cpp); - } - - if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR3, 1); - so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, - nv40->nvws->channel->vram->handle, - nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR3_OFFSET, 1); - so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_COLOR3_PITCH, 1); - so_data (so, rt[3]->pitch * rt[3]->cpp); - } - - if (zeta_format) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_ZETA, 1); - so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, - nv40->nvws->channel->vram->handle, - nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_OFFSET, 1); - so_reloc (so, zeta->buffer, zeta->offset, rt_flags | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); - so_data (so, zeta->pitch * zeta->cpp); - } - so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); - so_data (so, rt_enable); - so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3); - so_data (so, (w << 16) | 0); - so_data (so, (h << 16) | 0); - so_data (so, rt_format); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); - so_data (so, (w << 16) | 0); - so_data (so, (h << 16) | 0); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); - so_data (so, ((w - 1) << 16) | 0); - so_data (so, ((h - 1) << 16) | 0); - - so_ref(so, &nv40->so_framebuffer); - so_ref(NULL, &so); + nv40->pipe_state.framebuffer = *fb; nv40->dirty |= NV40_NEW_FB; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 65d7e2978a..a9ca71c5e9 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -2,6 +2,7 @@ #include "nv40_state.h" static struct nv40_state_entry *render_states[] = { + &nv40_state_framebuffer, &nv40_state_rasterizer, &nv40_state_clip, &nv40_state_scissor, @@ -67,7 +68,7 @@ nv40_state_emit(struct nv40_context *nv40) so_emit(nv40->nvws, nv40->hw->state[idx]); } - so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); + so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FB]); for (i = 0; i < 16; i++) { if (!(nv40->fp_samplers & (1 << i))) continue; @@ -81,9 +82,6 @@ nv40_emit_hw_state(struct nv40_context *nv40) { nv40_state_validate(nv40); - if (nv40->dirty & NV40_NEW_FB) - so_emit(nv40->nvws, nv40->so_framebuffer); - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c new file mode 100644 index 0000000000..d3032f1be5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -0,0 +1,156 @@ +#include "nv40_context.h" + +static boolean +nv40_state_framebuffer_validate(struct nv40_context *nv40) +{ + struct pipe_framebuffer_state *fb = &nv40->pipe_state.framebuffer; + struct pipe_surface *rt[4], *zeta; + uint32_t rt_enable, rt_format, w, h; + int i, colour_format = 0, zeta_format = 0; + struct nouveau_stateobj *so = so_new(64, 10); + unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; + + rt_enable = 0; + for (i = 0; i < 4; i++) { + if (!fb->cbufs[i]) + continue; + + if (colour_format) { + assert(w == fb->cbufs[i]->width); + assert(h == fb->cbufs[i]->height); + assert(colour_format == fb->cbufs[i]->format); + } else { + w = fb->cbufs[i]->width; + h = fb->cbufs[i]->height; + colour_format = fb->cbufs[i]->format; + rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i); + rt[i] = fb->cbufs[i]; + } + } + + if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 | + NV40TCL_RT_ENABLE_COLOR3)) + rt_enable |= NV40TCL_RT_ENABLE_MRT; + + if (fb->zsbuf) { + if (colour_format) { + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); + } else { + w = fb->zsbuf->width; + h = fb->zsbuf->height; + } + + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + switch (zeta_format) { + case PIPE_FORMAT_Z16_UNORM: + rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16; + break; + case PIPE_FORMAT_Z24S8_UNORM: + case 0: + rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8; + break; + default: + assert(0); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1); + so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR0_PITCH, 2); + so_data (so, rt[0]->pitch * rt[0]->cpp); + so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR1, 1); + so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR1_OFFSET, 2); + so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_data (so, rt[1]->pitch * rt[1]->cpp); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR2, 1); + so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR2_OFFSET, 1); + so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_COLOR2_PITCH, 1); + so_data (so, rt[2]->pitch * rt[2]->cpp); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR3, 1); + so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_COLOR3_OFFSET, 1); + so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_COLOR3_PITCH, 1); + so_data (so, rt[3]->pitch * rt[3]->cpp); + } + + if (zeta_format) { + so_method(so, nv40->hw->curie, NV40TCL_DMA_ZETA, 1); + so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->hw->curie, NV40TCL_ZETA_OFFSET, 1); + so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_data (so, zeta->pitch * zeta->cpp); + } + + so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_data (so, rt_enable); + so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_data (so, rt_format); + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_data (so, ((w - 1) << 16) | 0); + so_data (so, ((h - 1) << 16) | 0); + + so_ref(so, &nv40->state.hw[NV40_STATE_FB]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_framebuffer = { + .validate = nv40_state_framebuffer_validate, + .dirty = { + .pipe = NV40_NEW_FB, + .hw = NV40_STATE_FB + } +}; -- cgit v1.2.3 From 73e0e567dea3cf4e1591acb3e894eecef812f367 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 12:36:48 +1100 Subject: nouveau: fix build --- src/gallium/drivers/nv40/nv40_miptree.c | 38 +++++++++++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_surface.c | 31 --------------------------- 2 files changed, 38 insertions(+), 31 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 92e6b3a43d..5e1c7ade31 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -63,6 +63,7 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) if (!mt) return NULL; mt->base = *pt; + mt->base.refcount = 1; nv40_miptree_layout(mt); mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, @@ -95,10 +96,47 @@ nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) } } +static void +nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +{ +} + +static struct pipe_surface * +nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = pipe->winsys; + struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv40mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv40mt->level[level].image_offset[face]; + } else + if (pt->target == PIPE_TEXTURE_3D) { + ps->offset = nv40mt->level[level].image_offset[zslice]; + } else { + ps->offset = nv40mt->level[level].image_offset[0]; + } + + return ps; +} + void nv40_init_miptree_functions(struct nv40_context *nv40) { nv40->pipe.texture_create = nv40_miptree_create; nv40->pipe.texture_release = nv40_miptree_release; + nv40->pipe.texture_update = nv40_miptree_update; + nv40->pipe.get_tex_surface = nv40_miptree_surface; } diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 9726ab4e4d..df5d7abdbf 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -73,36 +73,6 @@ nv40_surface_format_supported(struct pipe_context *pipe, return FALSE; } -static struct pipe_surface * -nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = pipe->winsys; - struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; - struct pipe_surface *ps; - - ps = ws->surface_alloc(ws); - if (!ps) - return NULL; - pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = nv40mt->level[level].pitch / ps->cpp; - - if (pt->target == PIPE_TEXTURE_CUBE) { - ps->offset = nv40mt->level[level].image_offset[face]; - } else - if (pt->target == PIPE_TEXTURE_3D) { - ps->offset = nv40mt->level[level].image_offset[zslice]; - } else { - ps->offset = nv40mt->level[level].image_offset[0]; - } - - return ps; -} - static void nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -131,7 +101,6 @@ void nv40_init_surface_functions(struct nv40_context *nv40) { nv40->pipe.is_format_supported = nv40_surface_format_supported; - nv40->pipe.get_tex_surface = nv40_get_tex_surface; nv40->pipe.surface_copy = nv40_surface_copy; nv40->pipe.surface_fill = nv40_surface_fill; } -- cgit v1.2.3 From 5b2ff28a2fd3bb0ca9df569edcaf80e8141ccaa1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 13:32:51 +1100 Subject: nv40: rework fragment texture state --- src/gallium/drivers/nv40/nv40_context.h | 2 +- src/gallium/drivers/nv40/nv40_fragtex.c | 36 +++++++++++++++++++++--------- src/gallium/drivers/nv40/nv40_state.c | 2 ++ src/gallium/drivers/nv40/nv40_state_emit.c | 22 +++++++----------- 4 files changed, 36 insertions(+), 26 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 69062a8a20..cbc798fbd6 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -155,7 +155,6 @@ struct nv40_context { struct nv40_state state; unsigned fallback; - struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; @@ -209,6 +208,7 @@ extern struct nv40_state_entry nv40_state_blend_colour; extern struct nv40_state_entry nv40_state_zsa; extern struct nv40_state_entry nv40_state_viewport; extern struct nv40_state_entry nv40_state_framebuffer; +extern struct nv40_state_entry nv40_state_fragtex; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 811f3098ba..826d4a9478 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -52,7 +52,7 @@ nv40_fragtex_format(uint pipe_format) } -static void +static struct nouveau_stateobj * nv40_fragtex_build(struct nv40_context *nv40, int unit) { struct nv40_sampler_state *ps = nv40->tex_sampler[unit]; @@ -90,7 +90,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) break; default: NOUVEAU_ERR("Unknown target %d\n", pt->target); - return; + return NULL; } if (swizzled) { @@ -117,15 +117,14 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); - so_emit(nv40->nvws, so); - so_ref (so, &nv40->so_fragtex[unit]); - so_ref (NULL, &so); + return so; } -void -nv40_fragtex_bind(struct nv40_context *nv40) +static boolean +nv40_fragtex_validate(struct nv40_context *nv40) { struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nouveau_stateobj *so; unsigned samplers, unit; samplers = nv40->fp_samplers & ~fp->samplers; @@ -133,9 +132,12 @@ nv40_fragtex_bind(struct nv40_context *nv40) unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - so_ref(NULL, &nv40->so_fragtex[unit]); - BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1); - OUT_RING (0); + so = so_new(2, 0); + so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); + so_data (so, 0); + so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); + so_ref(NULL, &so); + nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } samplers = nv40->dirty_samplers & fp->samplers; @@ -143,9 +145,21 @@ nv40_fragtex_bind(struct nv40_context *nv40) unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - nv40_fragtex_build(nv40, unit); + so = nv40_fragtex_build(nv40, unit); + so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); + so_ref(NULL, &so); + nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } nv40->fp_samplers = fp->samplers; + return FALSE; } +struct nv40_state_entry nv40_state_fragtex = { + .validate = nv40_fragtex_validate, + .dirty = { + .pipe = NV40_NEW_SAMPLER | NV40_NEW_FRAGPROG, + .hw = 0 + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 84818d6729..74cbabb023 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -259,6 +259,7 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, nv40->tex_sampler[unit] = ps; nv40->dirty_samplers |= (1 << unit); + nv40->dirty |= NV40_NEW_SAMPLER; } static void @@ -275,6 +276,7 @@ nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit, nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree; nv40->dirty_samplers |= (1 << unit); + nv40->dirty |= NV40_NEW_SAMPLER; } static void * diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a9ca71c5e9..6d87b7b52b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -8,6 +8,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, + &nv40_state_fragtex, &nv40_state_vertprog, &nv40_state_blend, &nv40_state_blend_colour, @@ -35,6 +36,7 @@ nv40_state_validate(struct nv40_context *nv40) states++; } + nv40->dirty = 0; if (nv40->fallback & NV40_FALLBACK_TNL && !(last_fallback & NV40_FALLBACK_TNL)) { @@ -72,7 +74,8 @@ nv40_state_emit(struct nv40_context *nv40) for (i = 0; i < 16; i++) { if (!(nv40->fp_samplers & (1 << i))) continue; - so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); + so_emit_reloc_markers(nv40->nvws, + nv40->state.hw[NV40_STATE_FRAGTEX0+i]); } so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]); } @@ -81,20 +84,11 @@ void nv40_emit_hw_state(struct nv40_context *nv40) { nv40_state_validate(nv40); - - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { - nv40_fragtex_bind(nv40); - - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (2); - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (1); - nv40->dirty &= ~NV40_NEW_FRAGPROG; - } - nv40_state_emit(nv40); - nv40->dirty_samplers = 0; - nv40->dirty = 0; + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); } -- cgit v1.2.3 From c2e36bdd1a58ba6f58c4e72db1f7f64e8bd05901 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 13:55:18 +1100 Subject: nv40: move hw_dirty --- src/gallium/drivers/nv40/nv40_context.h | 5 ++--- src/gallium/drivers/nv40/nv40_fragtex.c | 9 +++++---- src/gallium/drivers/nv40/nv40_state_emit.c | 24 ++++++++++++------------ 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index cbc798fbd6..c533b9e0ef 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -115,7 +115,9 @@ struct nv40_blend_state { struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; + unsigned fp_samplers; + unsigned dirty; struct nouveau_stateobj *hw[NV40_STATE_MAX]; }; @@ -129,13 +131,10 @@ struct nv40_context { int chipset; unsigned dirty; - unsigned hw_dirty; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned dirty_samplers; - unsigned fp_samplers; - unsigned vp_samplers; struct { struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 826d4a9478..3d27a9bf13 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -124,10 +124,11 @@ static boolean nv40_fragtex_validate(struct nv40_context *nv40) { struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_state *state = &nv40->state; struct nouveau_stateobj *so; unsigned samplers, unit; - samplers = nv40->fp_samplers & ~fp->samplers; + samplers = state->fp_samplers & ~fp->samplers; while (samplers) { unit = ffs(samplers) - 1; samplers &= ~(1 << unit); @@ -137,7 +138,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); so_ref(NULL, &so); - nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } samplers = nv40->dirty_samplers & fp->samplers; @@ -148,10 +149,10 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); so_ref(NULL, &so); - nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } - nv40->fp_samplers = fp->samplers; + nv40->state.fp_samplers = fp->samplers; return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 6d87b7b52b..af09ed47d6 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -31,7 +31,7 @@ nv40_state_validate(struct nv40_context *nv40) if (nv40->dirty & e->dirty.pipe) { if (e->validate(nv40)) - nv40->hw_dirty |= (1 << e->dirty.hw); + nv40->state.dirty |= (1 << e->dirty.hw); } states++; @@ -60,24 +60,24 @@ nv40_state_validate(struct nv40_context *nv40) static void nv40_state_emit(struct nv40_context *nv40) { - unsigned i; + struct nv40_state *state = &nv40->state; + unsigned i, samplers; - while (nv40->hw_dirty) { - unsigned idx = ffs(nv40->hw_dirty) - 1; - nv40->hw_dirty &= ~(1 << idx); + while (state->dirty) { + unsigned idx = ffs(state->dirty) - 1; - so_ref (nv40->state.hw[idx], &nv40->hw->state[idx]); + so_ref (state->hw[idx], &nv40->hw->state[idx]); so_emit(nv40->nvws, nv40->hw->state[idx]); + state->dirty &= ~(1 << idx); } - so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FB]); - for (i = 0; i < 16; i++) { - if (!(nv40->fp_samplers & (1 << i))) - continue; + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); + for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { so_emit_reloc_markers(nv40->nvws, - nv40->state.hw[NV40_STATE_FRAGTEX0+i]); + state->hw[NV40_STATE_FRAGTEX0+i]); + samplers &= ~(1 << i); } - so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]); + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); } void -- cgit v1.2.3 From 7b938431d0ab5ccce1e7e2b1c38e1dcbdc6001e8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 14:46:48 +1100 Subject: nv40: stateobj start out with 0 refcount --- src/gallium/drivers/nv40/nv40_fragprog.c | 1 - src/gallium/drivers/nv40/nv40_fragtex.c | 2 -- src/gallium/drivers/nv40/nv40_state.c | 12 ++++++------ src/gallium/drivers/nv40/nv40_state_blend.c | 1 - src/gallium/drivers/nv40/nv40_state_fb.c | 1 - src/gallium/drivers/nv40/nv40_state_scissor.c | 1 - src/gallium/drivers/nv40/nv40_state_stipple.c | 1 - src/gallium/drivers/nv40/nv40_state_viewport.c | 1 - src/gallium/drivers/nv40/nv40_vbo.c | 1 - src/gallium/drivers/nv40/nv40_vertprog.c | 1 - 10 files changed, 6 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index db2613ef8b..a4a1ea01e0 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -817,7 +817,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); so_ref(so, &fp->so); - so_ref(NULL, &so); update_constants: if (fp->nr_consts) { diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 3d27a9bf13..c8a8120f30 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -137,7 +137,6 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - so_ref(NULL, &so); state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } @@ -148,7 +147,6 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - so_ref(NULL, &so); state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 74cbabb023..107e60f179 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -11,7 +11,7 @@ nv40_blend_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_grobj *curie = nv40->hw->curie; - struct nv40_blend_state *bso = MALLOC(sizeof(*bso)); + struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); if (cso->blend_enable) { @@ -47,7 +47,7 @@ nv40_blend_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); so_data (so, cso->dither ? 1 : 0); - bso->so = so; + so_ref(so, &bso->so); bso->pipe = *cso; return (void *)bso; } @@ -284,7 +284,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_rasterizer_state *rsso = MALLOC(sizeof(*rsso)); + struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); struct nouveau_grobj *curie = nv40->hw->curie; @@ -389,7 +389,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, 0); } - rsso->so = so; + so_ref(so, &rsso->so); rsso->pipe = *cso; return (void *)rsso; } @@ -417,7 +417,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_zsa_state *zsaso = MALLOC(sizeof(*zsaso)); + struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); @@ -460,7 +460,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - zsaso->so = so; + so_ref(so, &zsaso->so); zsaso->pipe = *cso; return (void *)zsaso; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index b12f8b03dd..81b927a67a 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -28,7 +28,6 @@ nv40_state_blend_colour_validate(struct nv40_context *nv40) (float_to_ubyte(bcol->color[2]) << 0))); so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index d3032f1be5..c3bf4d43a3 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -143,7 +143,6 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_data (so, ((h - 1) << 16) | 0); so_ref(so, &nv40->state.hw[NV40_STATE_FB]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 2871fa2516..ee797094d3 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -22,7 +22,6 @@ nv40_state_scissor_validate(struct nv40_context *nv40) } so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index bd163582a3..aad4d179ac 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -27,7 +27,6 @@ nv40_state_stipple_validate(struct nv40_context *nv40) } so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 79fcc31a8b..68820d3133 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -17,7 +17,6 @@ nv40_state_viewport_validate(struct nv40_context *nv40) so_data (so, fui(vpt->scale[3])); so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 3bfcb264db..5abe4c9af1 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -159,7 +159,6 @@ nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, so_emit(nv40->nvws, vtxfmt); so_emit(nv40->nvws, vtxbuf); so_ref (vtxbuf, &nv40->so_vtxbuf); - so_ref (NULL, &vtxbuf); so_ref (NULL, &vtxfmt); } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 8a2d233697..c482964adc 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -678,7 +678,6 @@ check_gpu_resources: so_data (so, vp->ir); so_data (so, vp->or); so_ref(so, &vp->so); - so_ref(NULL, &so); upload_code = TRUE; } -- cgit v1.2.3 From 14de997d5df48512c751c627ab19d486691f591d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 12:26:48 +1100 Subject: nv40: dump meaningful names for surface formats --- src/gallium/drivers/nv40/nv40_fragtex.c | 3 +++ src/gallium/drivers/nv40/nv40_vbo.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index c8a8120f30..7adee8858d 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -41,6 +41,7 @@ static struct nv40_texture_format * nv40_fragtex_format(uint pipe_format) { struct nv40_texture_format *tf = nv40_texture_formats; + char fs[128]; while (tf->defined) { if (tf->pipe == pipe_format) @@ -48,6 +49,8 @@ nv40_fragtex_format(uint pipe_format) tf++; } + pf_sprint_name(fs, pipe_format); + NOUVEAU_ERR("unknown texture format %s\n", fs); return NULL; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 5abe4c9af1..753c2fe64b 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -30,9 +30,13 @@ nv40_vbo_type(uint format) case PIPE_FORMAT_TYPE_UNORM: return NV40TCL_VTXFMT_TYPE_UBYTE; default: - NOUVEAU_ERR("Unknown format 0x%08x\n", format); + { + char fs[128]; + pf_sprint_name(fs, format); + NOUVEAU_ERR("Unknown format %s\n", fs); return NV40TCL_VTXFMT_TYPE_FLOAT; } + } } static boolean -- cgit v1.2.3 From 4058a9012764ce3bc7b90d03c4d79d020540f8e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 13:29:16 +1100 Subject: nv40: construct vbo state the same way as the rest --- src/gallium/drivers/nv40/nv40_context.h | 11 +- src/gallium/drivers/nv40/nv40_fragtex.c | 4 +- src/gallium/drivers/nv40/nv40_state.c | 2 - src/gallium/drivers/nv40/nv40_state_emit.c | 10 +- src/gallium/drivers/nv40/nv40_vbo.c | 246 ++++++++++++++--------------- 5 files changed, 137 insertions(+), 136 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index c533b9e0ef..110d9d7ab7 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -54,7 +54,9 @@ enum nv40_state_index { NV40_STATE_VERTTEX1 = 28, NV40_STATE_VERTTEX2 = 29, NV40_STATE_VERTTEX3 = 30, - NV40_STATE_MAX = 31 + NV40_STATE_VTXBUF = 31, + NV40_STATE_VTXFMT = 32, + NV40_STATE_MAX = 33 }; #define NV40_NEW_BLEND (1 << 0) @@ -117,7 +119,7 @@ struct nv40_state { unsigned stipple_enabled; unsigned fp_samplers; - unsigned dirty; + uint64_t dirty; struct nouveau_stateobj *hw[NV40_STATE_MAX]; }; @@ -149,13 +151,13 @@ struct nv40_context { struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; } pipe_state; struct nv40_state state; unsigned fallback; - struct nouveau_stateobj *so_vtxbuf; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -208,6 +210,7 @@ extern struct nv40_state_entry nv40_state_zsa; extern struct nv40_state_entry nv40_state_viewport; extern struct nv40_state_entry nv40_state_framebuffer; extern struct nv40_state_entry nv40_state_fragtex; +extern struct nv40_state_entry nv40_state_vbo; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 7adee8858d..ed47d707b2 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -140,7 +140,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); } samplers = nv40->dirty_samplers & fp->samplers; @@ -150,7 +150,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); } nv40->state.fp_samplers = fp->samplers; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 107e60f179..e6f2754dc5 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -628,7 +628,6 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, struct nv40_context *nv40 = nv40_context(pipe); nv40->vtxbuf[index] = *vb; - nv40->dirty |= NV40_NEW_ARRAYS; } @@ -639,7 +638,6 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, struct nv40_context *nv40 = nv40_context(pipe); nv40->vtxelt[index] = *ve; - nv40->dirty |= NV40_NEW_ARRAYS; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index af09ed47d6..bb2ce0f722 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -14,6 +14,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_blend_colour, &nv40_state_zsa, &nv40_state_viewport, + &nv40_state_vbo, NULL }; @@ -31,7 +32,7 @@ nv40_state_validate(struct nv40_context *nv40) if (nv40->dirty & e->dirty.pipe) { if (e->validate(nv40)) - nv40->state.dirty |= (1 << e->dirty.hw); + nv40->state.dirty |= (1ULL << e->dirty.hw); } states++; @@ -64,20 +65,21 @@ nv40_state_emit(struct nv40_context *nv40) unsigned i, samplers; while (state->dirty) { - unsigned idx = ffs(state->dirty) - 1; + unsigned idx = ffsll(state->dirty) - 1; so_ref (state->hw[idx], &nv40->hw->state[idx]); so_emit(nv40->nvws, nv40->hw->state[idx]); - state->dirty &= ~(1 << idx); + state->dirty &= ~(1ULL << idx); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGTEX0+i]); - samplers &= ~(1 << i); + samplers &= ~(1ULL << i); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); } void diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 753c2fe64b..b5faf06291 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -39,6 +39,43 @@ nv40_vbo_type(uint format) } } +static boolean +nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, + unsigned ib_size) +{ + unsigned type; + + if (!ib) { + nv40->pipe_state.idxbuf = NULL; + nv40->pipe_state.idxbuf_format = 0xdeadbeef; + return FALSE; + } + + /* No support for 8bit indices, no support at all on 0x4497 chips */ + if (nv40->hw->curie->grclass == NV44TCL || ib_size == 1) + return FALSE; + + switch (ib_size) { + case 2: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; + break; + default: + return FALSE; + } + + if (ib != nv40->pipe_state.idxbuf || + type != nv40->pipe_state.idxbuf_format) { + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->pipe_state.idxbuf = ib; + nv40->pipe_state.idxbuf_format = type; + } + + return TRUE; +} + static boolean nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, struct pipe_vertex_element *ve, @@ -101,104 +138,15 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, return TRUE; } -static void -nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, - unsigned ib_format) -{ - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; - struct nouveau_stateobj *vtxbuf, *vtxfmt; - unsigned inputs, hw, num_hw; - unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; - - inputs = vp->ir; - for (hw = 0; hw < 16 && inputs; hw++) { - if (inputs & (1 << hw)) { - num_hw = hw; - inputs &= ~(1 << hw); - } - } - num_hw++; - - vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); - vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw); - - inputs = vp->ir; - for (hw = 0; hw < num_hw; hw++) { - struct pipe_vertex_element *ve; - struct pipe_vertex_buffer *vb; - - if (!(inputs & (1 << hw))) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; - } - - ve = &nv40->vtxelt[hw]; - vb = &nv40->vtxbuf[ve->vertex_buffer_index]; - - if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; - } - - so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, - vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, - 0, NV40TCL_VTXBUF_ADDRESS_DMA1); - so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) | - (nv40_vbo_ncomp(ve->src_format) << - NV40TCL_VTXFMT_SIZE_SHIFT) | - nv40_vbo_type(ve->src_format))); - } - - if (ib) { - so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2); - so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); - so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, - 0, NV40TCL_IDXBUF_FORMAT_DMA1); - } - - so_emit(nv40->nvws, vtxfmt); - so_emit(nv40->nvws, vtxbuf); - so_ref (vtxbuf, &nv40->so_vtxbuf); - so_ref (NULL, &vtxfmt); -} - -static boolean -nv40_vbo_validate_state(struct nv40_context *nv40, - struct pipe_buffer *ib, unsigned ib_format) -{ - unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS; - - nv40_emit_hw_state(nv40); - if (vdn || ib) { - nv40_vbo_arrays_update(nv40, ib, ib_format); - nv40->dirty &= ~NV40_NEW_ARRAYS; - } - - so_emit_reloc_markers(nv40->nvws, nv40->so_vtxbuf); - - BEGIN_RING(curie, 0x1710, 1); - OUT_RING (0); /* vtx cache flush */ - - return TRUE; -} - boolean nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); unsigned nr; - boolean ret; - ret = nv40_vbo_validate_state(nv40, NULL, 0); - if (!ret) { - NOUVEAU_ERR("state validate failed\n"); - return FALSE; - } + nv40_vbo_set_idxbuf(nv40, NULL, 0); + nv40_emit_hw_state(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -305,14 +253,9 @@ nv40_draw_elements_inline(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct pipe_winsys *ws = pipe->winsys; - boolean ret; void *map; - ret = nv40_vbo_validate_state(nv40, NULL, 0); - if (!ret) { - NOUVEAU_ERR("state validate failed\n"); - return FALSE; - } + nv40_emit_hw_state(nv40); map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { @@ -348,30 +291,12 @@ nv40_draw_elements_inline(struct pipe_context *pipe, static boolean nv40_draw_elements_vbo(struct pipe_context *pipe, - struct pipe_buffer *ib, unsigned ib_size, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); - unsigned nr, type; - boolean ret; - - switch (ib_size) { - case 2: - type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; - break; - case 4: - type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; - break; - default: - NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); - return FALSE; - } + unsigned nr; - ret = nv40_vbo_validate_state(nv40, ib, type); - if (!ret) { - NOUVEAU_ERR("failed state validation\n"); - return FALSE; - } + nv40_emit_hw_state(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -409,19 +334,92 @@ nv40_draw_elements(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - /* 0x4497 doesn't support real index buffers, and there doesn't appear - * to be support on any chipset for 8-bit indices. - */ - if (nv40->hw->curie->grclass == NV44TCL || indexSize == 1) { + if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) { + nv40_draw_elements_vbo(pipe, mode, start, count); + } else { nv40_draw_elements_inline(pipe, indexBuffer, indexSize, mode, start, count); - } else { - nv40_draw_elements_vbo(pipe, indexBuffer, indexSize, - mode, start, count); } pipe->flush(pipe, 0); return TRUE; } +static boolean +nv40_vbo_validate(struct nv40_context *nv40) +{ + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nouveau_stateobj *vtxbuf, *vtxfmt; + struct pipe_buffer *ib = nv40->pipe_state.idxbuf; + unsigned ib_format = nv40->pipe_state.idxbuf_format; + unsigned inputs, hw, num_hw; + unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + inputs = vp->ir; + for (hw = 0; hw < 16 && inputs; hw++) { + if (inputs & (1 << hw)) { + num_hw = hw; + inputs &= ~(1 << hw); + } + } + num_hw++; + + vtxbuf = so_new(20, 18); + so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + vtxfmt = so_new(17, 0); + so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw); + + inputs = vp->ir; + for (hw = 0; hw < num_hw; hw++) { + struct pipe_vertex_element *ve; + struct pipe_vertex_buffer *vb; + + if (!(inputs & (1 << hw))) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + ve = &nv40->vtxelt[hw]; + vb = &nv40->vtxbuf[ve->vertex_buffer_index]; + + if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, + vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + 0, NV40TCL_VTXBUF_ADDRESS_DMA1); + so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) | + (nv40_vbo_ncomp(ve->src_format) << + NV40TCL_VTXFMT_SIZE_SHIFT) | + nv40_vbo_type(ve->src_format))); + } + + if (ib) { + so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); + so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, + 0, NV40TCL_IDXBUF_FORMAT_DMA1); + } + + so_method(vtxbuf, nv40->hw->curie, 0x1710, 1); + so_data (vtxbuf, 0); + + so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]); + nv40->state.dirty |= (1ULL << NV40_STATE_VTXBUF); + so_ref(vtxfmt, &nv40->state.hw[NV40_STATE_VTXFMT]); + nv40->state.dirty |= (1ULL << NV40_STATE_VTXFMT); + return FALSE; +} + +struct nv40_state_entry nv40_state_vbo = { + .validate = nv40_vbo_validate, + .dirty = { + .pipe = NV40_NEW_ARRAYS, + .hw = 0, + } +}; -- cgit v1.2.3 From 026e2fd3c6eb87a010a9c90341e8a77b09376b5b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 13:33:08 +1100 Subject: nv40: remove pipe_state struct now. --- src/gallium/drivers/nv40/nv40_context.h | 41 +++++++++++------------- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +-- src/gallium/drivers/nv40/nv40_fragtex.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 26 +++++++-------- src/gallium/drivers/nv40/nv40_state_blend.c | 4 +-- src/gallium/drivers/nv40/nv40_state_clip.c | 2 +- src/gallium/drivers/nv40/nv40_state_fb.c | 2 +- src/gallium/drivers/nv40/nv40_state_rasterizer.c | 2 +- src/gallium/drivers/nv40/nv40_state_scissor.c | 4 +-- src/gallium/drivers/nv40/nv40_state_stipple.c | 4 +-- src/gallium/drivers/nv40/nv40_state_viewport.c | 2 +- src/gallium/drivers/nv40/nv40_state_zsa.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 18 +++++------ src/gallium/drivers/nv40/nv40_vertprog.c | 4 +-- 14 files changed, 57 insertions(+), 60 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 110d9d7ab7..16cc053ad9 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -132,32 +132,29 @@ struct nv40_context { int chipset; - unsigned dirty; + /* HW state derived from pipe states */ + struct nv40_state state; + unsigned fallback; + /* Context state */ + unsigned dirty; + struct pipe_scissor_state scissor; + unsigned stipple[32]; + struct pipe_clip_state clip; + struct nv40_vertex_program *vertprog; + struct nv40_fragment_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct nv40_rasterizer_state *rasterizer; + struct nv40_zsa_state *zsa; + struct nv40_blend_state *blend; + struct pipe_blend_color blend_colour; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned dirty_samplers; - - struct { - struct pipe_scissor_state scissor; - unsigned stipple[32]; - struct pipe_clip_state clip; - struct nv40_vertex_program *vertprog; - struct nv40_fragment_program *fragprog; - struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; - struct nv40_rasterizer_state *rasterizer; - struct nv40_zsa_state *zsa; - struct nv40_blend_state *blend; - struct pipe_blend_color blend_colour; - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state framebuffer; - struct pipe_buffer *idxbuf; - unsigned idxbuf_format; - } pipe_state; - - struct nv40_state state; - unsigned fallback; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index a4a1ea01e0..2a8abb32a3 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -790,9 +790,9 @@ nv40_fragprog_upload(struct nv40_context *nv40, static boolean nv40_fragprog_validate(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_fragment_program *fp = nv40->fragprog; struct pipe_buffer *constbuf = - nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; + nv40->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; int i; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index ed47d707b2..6be8378c08 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -126,7 +126,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) static boolean nv40_fragtex_validate(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_fragment_program *fp = nv40->fragprog; struct nv40_state *state = &nv40->state; struct nouveau_stateobj *so; unsigned samplers, unit; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index e6f2754dc5..24335fbc44 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -57,7 +57,7 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.blend = hwcso; + nv40->blend = hwcso; nv40->dirty |= NV40_NEW_BLEND; } @@ -399,7 +399,7 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.rasterizer = hwcso; + nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; } @@ -470,7 +470,7 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.zsa = hwcso; + nv40->zsa = hwcso; nv40->dirty |= NV40_NEW_ZSA; } @@ -500,7 +500,7 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.vertprog = hwcso; + nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; } @@ -531,7 +531,7 @@ nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.fragprog = hwcso; + nv40->fragprog = hwcso; nv40->dirty |= NV40_NEW_FRAGPROG; } @@ -551,7 +551,7 @@ nv40_set_blend_color(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.blend_colour = *bcol; + nv40->blend_colour = *bcol; nv40->dirty |= NV40_NEW_BCOL; } @@ -561,7 +561,7 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.clip = *clip; + nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; } @@ -572,11 +572,11 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX] = buf->buffer; + nv40->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; + nv40->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } @@ -587,7 +587,7 @@ nv40_set_framebuffer_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.framebuffer = *fb; + nv40->framebuffer = *fb; nv40->dirty |= NV40_NEW_FB; } @@ -597,7 +597,7 @@ nv40_set_polygon_stipple(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - memcpy(nv40->pipe_state.stipple, stipple->stipple, 4 * 32); + memcpy(nv40->stipple, stipple->stipple, 4 * 32); nv40->dirty |= NV40_NEW_STIPPLE; } @@ -607,7 +607,7 @@ nv40_set_scissor_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.scissor = *s; + nv40->scissor = *s; nv40->dirty |= NV40_NEW_SCISSOR; } @@ -617,7 +617,7 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.viewport = *vpt; + nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index 81b927a67a..dd09830aa3 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -3,7 +3,7 @@ static boolean nv40_state_blend_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.blend->so, &nv40->state.hw[NV40_STATE_BLEND]); + so_ref(nv40->blend->so, &nv40->state.hw[NV40_STATE_BLEND]); return TRUE; } @@ -19,7 +19,7 @@ static boolean nv40_state_blend_colour_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(2, 0); - struct pipe_blend_color *bcol = &nv40->pipe_state.blend_colour; + struct pipe_blend_color *bcol = &nv40->blend_colour; so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c index 19f1c3b36d..93e690161f 100644 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -3,7 +3,7 @@ static boolean nv40_state_clip_validate(struct nv40_context *nv40) { - if (nv40->pipe_state.clip.nr) + if (nv40->clip.nr) nv40->fallback |= NV40_FALLBACK_TNL; return FALSE; diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index c3bf4d43a3..3d0ab92003 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -3,7 +3,7 @@ static boolean nv40_state_framebuffer_validate(struct nv40_context *nv40) { - struct pipe_framebuffer_state *fb = &nv40->pipe_state.framebuffer; + struct pipe_framebuffer_state *fb = &nv40->framebuffer; struct pipe_surface *rt[4], *zeta; uint32_t rt_enable, rt_format, w, h; int i, colour_format = 0, zeta_format = 0; diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c index 59b35d1d50..9ecda5990f 100644 --- a/src/gallium/drivers/nv40/nv40_state_rasterizer.c +++ b/src/gallium/drivers/nv40/nv40_state_rasterizer.c @@ -3,7 +3,7 @@ static boolean nv40_state_rasterizer_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.rasterizer->so, + so_ref(nv40->rasterizer->so, &nv40->state.hw[NV40_STATE_RAST]); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index ee797094d3..09ffc49f96 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -3,8 +3,8 @@ static boolean nv40_state_scissor_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; - struct pipe_scissor_state *s = &nv40->pipe_state.scissor; + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_scissor_state *s = &nv40->scissor; struct nouveau_stateobj *so; if (nv40->state.hw[NV40_STATE_SCISSOR] && diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index aad4d179ac..001c396d74 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -3,7 +3,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; @@ -19,7 +19,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40) so_data (so, 1); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); for (i = 0; i < 32; i++) - so_data(so, nv40->pipe_state.stipple[i]); + so_data(so, nv40->stipple[i]); } else { so = so_new(2, 0); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 68820d3133..9616be5052 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -4,7 +4,7 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(9, 0); - struct pipe_viewport_state *vpt = &nv40->pipe_state.viewport; + struct pipe_viewport_state *vpt = &nv40->viewport; so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c index 061a3555cb..fb760677c8 100644 --- a/src/gallium/drivers/nv40/nv40_state_zsa.c +++ b/src/gallium/drivers/nv40/nv40_state_zsa.c @@ -3,7 +3,7 @@ static boolean nv40_state_zsa_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.zsa->so, + so_ref(nv40->zsa->so, &nv40->state.hw[NV40_STATE_ZSA]); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index b5faf06291..1653ebf2a7 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -46,8 +46,8 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned type; if (!ib) { - nv40->pipe_state.idxbuf = NULL; - nv40->pipe_state.idxbuf_format = 0xdeadbeef; + nv40->idxbuf = NULL; + nv40->idxbuf_format = 0xdeadbeef; return FALSE; } @@ -66,11 +66,11 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, return FALSE; } - if (ib != nv40->pipe_state.idxbuf || - type != nv40->pipe_state.idxbuf_format) { + if (ib != nv40->idxbuf || + type != nv40->idxbuf_format) { nv40->dirty |= NV40_NEW_ARRAYS; - nv40->pipe_state.idxbuf = ib; - nv40->pipe_state.idxbuf_format = type; + nv40->idxbuf = ib; + nv40->idxbuf_format = type; } return TRUE; @@ -348,10 +348,10 @@ nv40_draw_elements(struct pipe_context *pipe, static boolean nv40_vbo_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nv40_vertex_program *vp = nv40->vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt; - struct pipe_buffer *ib = nv40->pipe_state.idxbuf; - unsigned ib_format = nv40->pipe_state.idxbuf_format; + struct pipe_buffer *ib = nv40->idxbuf; + unsigned ib_format = nv40->idxbuf_format; unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index c482964adc..d3ed57b199 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -634,9 +634,9 @@ out_err: static boolean nv40_vertprog_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nv40_vertex_program *vp = nv40->vertprog; struct pipe_buffer *constbuf = - nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX]; + nv40->constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; boolean upload_code = FALSE, upload_data = FALSE; -- cgit v1.2.3 From 84cc07dc89c0ebce4ad55b4b3684d4420a202683 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 15:03:57 +1100 Subject: nouveau: implement pipe_screen Untested on NV3x/NV5x. Quite possibly broken. --- src/gallium/drivers/nv40/Makefile | 1 + src/gallium/drivers/nv40/nv40_context.c | 85 ++---------------- src/gallium/drivers/nv40/nv40_context.h | 2 + src/gallium/drivers/nv40/nv40_miptree.c | 25 ++++-- src/gallium/drivers/nv40/nv40_screen.c | 151 ++++++++++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_screen.h | 20 +++++ src/gallium/drivers/nv40/nv40_surface.c | 41 --------- 7 files changed, 195 insertions(+), 130 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_screen.c create mode 100644 src/gallium/drivers/nv40/nv40_screen.h (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index fd002b54e7..3369a21574 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -11,6 +11,7 @@ DRIVER_SOURCES = \ nv40_fragtex.c \ nv40_miptree.c \ nv40_query.c \ + nv40_screen.c \ nv40_state.c \ nv40_state_blend.c \ nv40_state_clip.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 8b5cc693de..a7f64c6e9e 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -4,85 +4,12 @@ #include "pipe/p_util.h" #include "nv40_context.h" +#include "nv40_screen.h" #define NV4X_GRCLASS4097_CHIPSETS 0x00000baf #define NV4X_GRCLASS4497_CHIPSETS 0x00005450 #define NV6X_GRCLASS4497_CHIPSETS 0x00000088 -static const char * -nv40_get_name(struct pipe_context *pipe) -{ - struct nv40_context *nv40 = nv40_context(pipe); - static char buffer[128]; - - snprintf(buffer, sizeof(buffer), "NV%02X", nv40->chipset); - return buffer; -} - -static const char * -nv40_get_vendor(struct pipe_context *pipe) -{ - return "nouveau"; -} - -static int -nv40_get_param(struct pipe_context *pipe, int param) -{ - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 16; - case PIPE_CAP_NPOT_TEXTURES: - return 1; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; - case PIPE_CAP_GLSL: - return 0; - case PIPE_CAP_S3TC: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; - case PIPE_CAP_POINT_SPRITE: - return 1; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 4; - case PIPE_CAP_OCCLUSION_QUERY: - return 1; - 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; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv40_get_paramf(struct pipe_context *pipe, int 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 16.0; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} - static void nv40_flush(struct pipe_context *pipe, unsigned flags) { @@ -269,10 +196,11 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv40_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) { + struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; + unsigned chipset = nv40_screen(pscreen)->chipset; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) @@ -288,11 +216,8 @@ nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, nv40->nvws = nvws; nv40->pipe.winsys = ws; + nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; - nv40->pipe.get_name = nv40_get_name; - nv40->pipe.get_vendor = nv40_get_vendor; - nv40->pipe.get_param = nv40_get_param; - nv40->pipe.get_paramf = nv40_get_paramf; nv40->pipe.draw_arrays = nv40_draw_arrays; nv40->pipe.draw_elements = nv40_draw_elements; nv40->pipe.clear = nv40_clear; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 16cc053ad9..3ddfbd43f6 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -178,6 +178,8 @@ extern void nv40_init_surface_functions(struct nv40_context *nv40); extern void nv40_init_miptree_functions(struct nv40_context *nv40); extern void nv40_init_query_functions(struct nv40_context *nv40); +extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen); + /* nv40_draw.c */ extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 5e1c7ade31..94ba05b710 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -54,9 +54,9 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) } static struct pipe_texture * -nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) +nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *mt; mt = MALLOC(sizeof(struct nv40_miptree)); @@ -64,6 +64,8 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) return NULL; mt->base = *pt; mt->base.refcount = 1; + mt->base.screen = pscreen; + nv40_miptree_layout(mt); mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, @@ -77,9 +79,9 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) } static void -nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct pipe_texture *mt = *pt; *pt = NULL; @@ -102,10 +104,10 @@ nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) } static struct pipe_surface * -nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, +nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; @@ -134,9 +136,14 @@ nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, void nv40_init_miptree_functions(struct nv40_context *nv40) { - nv40->pipe.texture_create = nv40_miptree_create; - nv40->pipe.texture_release = nv40_miptree_release; nv40->pipe.texture_update = nv40_miptree_update; - nv40->pipe.get_tex_surface = nv40_miptree_surface; +} + +void +nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv40_miptree_create; + pscreen->texture_release = nv40_miptree_release; + pscreen->get_tex_surface = nv40_miptree_surface; } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c new file mode 100644 index 0000000000..1941598c64 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -0,0 +1,151 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_screen.h" + +static const char * +nv40_screen_get_name(struct pipe_screen *pscreen) +{ + struct nv40_screen *screen = nv40_screen(pscreen); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset); + return buffer; +} + +static const char * +nv40_screen_get_vendor(struct pipe_screen *pscreen) +{ + return "nouveau"; +} + +static int +nv40_screen_get_param(struct pipe_screen *pscreen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 16; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 4; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + 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; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv40_screen_get_paramf(struct pipe_screen *pscreen, int 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 16.0; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv40_screen_surface_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void +nv40_screen_destroy(struct pipe_screen *pscreen) +{ + FREE(pscreen); +} + +struct pipe_screen * +nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) +{ + struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); + + if (!screen) + return NULL; + + screen->chipset = chipset; + + screen->pipe.winsys = ws; + screen->pipe.destroy = nv40_screen_destroy; + + screen->pipe.get_name = nv40_screen_get_name; + screen->pipe.get_vendor = nv40_screen_get_vendor; + screen->pipe.get_param = nv40_screen_get_param; + screen->pipe.get_paramf = nv40_screen_get_paramf; + + screen->pipe.is_format_supported = nv40_screen_surface_format_supported; + + nv40_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h new file mode 100644 index 0000000000..b30a6c5ad5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -0,0 +1,20 @@ +#ifndef __NV40_SCREEN_H__ +#define __NV40_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv40_screen { + struct pipe_screen pipe; + unsigned chipset; +}; + +static INLINE struct nv40_screen * +nv40_screen(struct pipe_screen *screen) +{ + return (struct nv40_screen *)screen; +} + +extern struct pipe_screen * +nv40_screen_create(struct pipe_winsys *winsys, unsigned chipset); + +#endif diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index df5d7abdbf..e8a6011696 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -33,46 +33,6 @@ #include "pipe/p_inlines.h" #include "util/p_tile.h" -static boolean -nv40_surface_format_supported(struct pipe_context *pipe, - enum pipe_format format, uint type) -{ - switch (type) { - case PIPE_SURFACE: - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - break; - case PIPE_TEXTURE: - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: - case PIPE_FORMAT_U_A8_L8: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - } - break; - default: - assert(0); - }; - - return FALSE; -} - static void nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -100,7 +60,6 @@ nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, void nv40_init_surface_functions(struct nv40_context *nv40) { - nv40->pipe.is_format_supported = nv40_surface_format_supported; nv40->pipe.surface_copy = nv40_surface_copy; nv40->pipe.surface_fill = nv40_surface_fill; } -- cgit v1.2.3 From baaae562f02563c5966b857c61b3eae7341950e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 22:54:40 +1100 Subject: nouveau: hand nouveau_winsys in with pipe_screen init --- src/gallium/drivers/nv40/nv40_context.c | 3 ++- src/gallium/drivers/nv40/nv40_screen.c | 4 +++- src/gallium/drivers/nv40/nv40_screen.h | 5 ++--- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index a7f64c6e9e..679c2ddc6b 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -196,11 +196,12 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) +nv40_create(struct pipe_screen *pscreen) { struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; unsigned chipset = nv40_screen(pscreen)->chipset; + struct nouveau_winsys *nvws = nv40_screen(pscreen)->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 1941598c64..66e84b6890 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -125,7 +125,8 @@ nv40_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); @@ -133,6 +134,7 @@ nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) return NULL; screen->chipset = chipset; + screen->nvws = nvws; screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index b30a6c5ad5..88b8fed26c 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -5,6 +5,8 @@ struct nv40_screen { struct pipe_screen pipe; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv40_screen(struct pipe_screen *screen) return (struct nv40_screen *)screen; } -extern struct pipe_screen * -nv40_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif -- cgit v1.2.3 From 17f6db9d0197657cd753249ef60355c6fd983032 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 23:08:01 +1100 Subject: nv40: move "channel context" stuff into nv40_screen --- src/gallium/drivers/nv40/nv40_context.c | 168 +------------------------ src/gallium/drivers/nv40/nv40_context.h | 29 +---- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +- src/gallium/drivers/nv40/nv40_fragtex.c | 6 +- src/gallium/drivers/nv40/nv40_query.c | 10 +- src/gallium/drivers/nv40/nv40_screen.c | 128 ++++++++++++++++++- src/gallium/drivers/nv40/nv40_screen.h | 15 +++ src/gallium/drivers/nv40/nv40_state.c | 16 +-- src/gallium/drivers/nv40/nv40_state_blend.c | 2 +- src/gallium/drivers/nv40/nv40_state_emit.c | 4 +- src/gallium/drivers/nv40/nv40_state_fb.c | 34 ++--- src/gallium/drivers/nv40/nv40_state_scissor.c | 2 +- src/gallium/drivers/nv40/nv40_state_stipple.c | 2 +- src/gallium/drivers/nv40/nv40_state_viewport.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 10 +- src/gallium/drivers/nv40/nv40_vertprog.c | 8 +- 16 files changed, 203 insertions(+), 237 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 679c2ddc6b..084829ce28 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -6,10 +6,6 @@ #include "nv40_context.h" #include "nv40_screen.h" -#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf -#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 -#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 - static void nv40_flush(struct pipe_context *pipe, unsigned flags) { @@ -24,7 +20,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) } if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv40->hw->sync, 0); + nvws->notifier_reset(nv40->screen->sync, 0); BEGIN_RING(curie, 0x104, 1); OUT_RING (0); BEGIN_RING(curie, 0x100, 1); @@ -34,149 +30,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) FIRE_RING(); if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv40->hw->sync, 0, 0, 2000); -} - -static void -nv40_channel_takedown(struct nv40_channel_context *cnv40) -{ - struct nouveau_winsys *nvws = cnv40->nvws; - - nvws->res_free(&cnv40->vp_exec_heap); - nvws->res_free(&cnv40->vp_data_heap); - nvws->res_free(&cnv40->query_heap); - nvws->notifier_free(&cnv40->query); - nvws->notifier_free(&cnv40->sync); - nvws->grobj_free(&cnv40->curie); - free(cnv40); -} - -static struct nv40_channel_context * -nv40_channel_init(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) -{ - struct nv40_channel_context *cnv40 = NULL; - struct nouveau_stateobj *so; - unsigned curie_class = 0; - int ret; - - switch (chipset & 0xf0) { - case 0x40: - if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) - curie_class = NV40TCL; - else - if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) - curie_class = NV44TCL; - break; - case 0x60: - if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) - curie_class = NV44TCL; - break; - default: - break; - } - - if (!curie_class) { - NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset); - return NULL; - } - - cnv40 = CALLOC(1, sizeof(struct nv40_channel_context)); - if (!cnv40) - return NULL; - cnv40->chipset = chipset; - cnv40->nvws = nvws; - - /* Notifier for sync purposes */ - ret = nvws->notifier_alloc(nvws, 1, &cnv40->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - /* Query objects */ - ret = nvws->notifier_alloc(nvws, 32, &cnv40->query); - if (ret) { - NOUVEAU_ERR("Error initialising query objects: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - ret = nvws->res_init(&cnv40->query_heap, 0, 32); - if (ret) { - NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - /* Vtxprog resources */ - if (nvws->res_init(&cnv40->vp_exec_heap, 0, 512) || - nvws->res_init(&cnv40->vp_data_heap, 0, 256)) { - nv40_channel_takedown(cnv40); - return NULL; - } - - /* 3D object */ - ret = nvws->grobj_alloc(nvws, curie_class, &cnv40->curie); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* Static curie initialisation */ - so = so_new(128, 0); - so_method(so, cnv40->curie, NV40TCL_DMA_NOTIFY, 1); - so_data (so, cnv40->sync->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_TEXTURE0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->gart->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR1, 1); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_VTXBUF0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->gart->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_FENCE, 2); - so_data (so, 0); - so_data (so, cnv40->query->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_UNK01AC, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR2, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - - so_method(so, cnv40->curie, 0x1ea4, 3); - so_data (so, 0x00000010); - so_data (so, 0x01000100); - so_data (so, 0xff800006); - - /* vtxprog output routing */ - so_method(so, cnv40->curie, 0x1fc4, 1); - so_data (so, 0x06144321); - so_method(so, cnv40->curie, 0x1fc8, 2); - so_data (so, 0xedcba987); - so_data (so, 0x00000021); - so_method(so, cnv40->curie, 0x1fd0, 1); - so_data (so, 0x00171615); - so_method(so, cnv40->curie, 0x1fd4, 1); - so_data (so, 0x001b1a19); - - so_method(so, cnv40->curie, 0x1ef8, 1); - so_data (so, 0x0020ffff); - so_method(so, cnv40->curie, 0x1d64, 1); - so_data (so, 0x00d30000); - so_method(so, cnv40->curie, 0x1e94, 1); - so_data (so, 0x00000001); - - so_emit(nvws, so); - so_ref(NULL, &so); - nvws->push_flush(nvws->channel, 0); - - return cnv40; + nvws->notifier_wait(nv40->screen->sync, 0, 0, 2000); } static void @@ -186,32 +40,22 @@ nv40_destroy(struct pipe_context *pipe) if (nv40->draw) draw_destroy(nv40->draw); - - if (nv40->hw) { - if (--nv40->hw->refcount == 0) - nv40_channel_takedown(nv40->hw); - } - free(nv40); } struct pipe_context * nv40_create(struct pipe_screen *pscreen) { + struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; - unsigned chipset = nv40_screen(pscreen)->chipset; - struct nouveau_winsys *nvws = nv40_screen(pscreen)->nvws; + unsigned chipset = screen->chipset; + struct nouveau_winsys *nvws = screen->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) return NULL; - - nv40->hw = nv40_channel_init(ws, nvws, chipset); - if (!nv40->hw) { - nv40_destroy(&nv40->pipe); - return NULL; - } + nv40->screen = screen; nv40->chipset = chipset; nv40->nvws = nvws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 3ddfbd43f6..3b669594dc 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -11,7 +11,7 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv40_channel_context *ctx = nv40->hw + struct nv40_screen *ctx = nv40->screen #include "nouveau/nouveau_push.h" #include "nouveau/nouveau_stateobj.h" @@ -59,6 +59,8 @@ enum nv40_state_index { NV40_STATE_MAX = 33 }; +#include "nv40_screen.h" + #define NV40_NEW_BLEND (1 << 0) #define NV40_NEW_RAST (1 << 1) #define NV40_NEW_ZSA (1 << 2) @@ -76,28 +78,6 @@ enum nv40_state_index { #define NV40_FALLBACK_TNL (1 << 0) #define NV40_FALLBACK_RAST (1 << 1) -struct nv40_channel_context { - struct nouveau_winsys *nvws; - unsigned refcount; - - unsigned chipset; - - /* HW graphics objects */ - struct nouveau_grobj *curie; - struct nouveau_notifier *sync; - - /* Query object resources */ - struct nouveau_notifier *query; - struct nouveau_resource *query_heap; - - /* Vtxprog resources */ - struct nouveau_resource *vp_exec_heap; - struct nouveau_resource *vp_data_heap; - - /* Current 3D state of channel */ - struct nouveau_stateobj *state[NV40_STATE_MAX]; -}; - struct nv40_rasterizer_state { struct pipe_rasterizer_state pipe; struct nouveau_stateobj *so; @@ -125,9 +105,10 @@ struct nv40_state { struct nv40_context { struct pipe_context pipe; + struct nouveau_winsys *nvws; + struct nv40_screen *screen; - struct nv40_channel_context *hw; struct draw_context *draw; int chipset; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 2a8abb32a3..3c4ea7e99e 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -810,11 +810,11 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40_fragprog_upload(nv40, fp); so = so_new(4, 1); - so_method(so, nv40->hw->curie, NV40TCL_FP_ADDRESS, 1); + so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1); so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); - so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); + so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); so_ref(so, &fp->so); diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 6be8378c08..436f954cec 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -106,7 +106,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) txs = tf->swizzle; so = so_new(16, 2); - so_method(so, nv40->hw->curie, NV40TCL_TEX_OFFSET(unit), 8); + so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8); so_reloc (so, nv40mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); so_reloc (so, nv40mt->buffer, txf, tex_flags | NOUVEAU_BO_OR, NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1); @@ -117,7 +117,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | pt->height[0]); so_data (so, ps->bcol); - so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); + so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1); so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); return so; @@ -137,7 +137,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) samplers &= ~(1 << unit); so = so_new(2, 0); - so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); + so_method(so, nv40->screen->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 8bca2788b9..0317845624 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -45,9 +45,9 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); - if (nv40->nvws->res_alloc(nv40->hw->query_heap, 1, NULL, &q->object)) + if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object)) assert(0); - nv40->nvws->notifier_reset(nv40->hw->query, q->object->start); + nv40->nvws->notifier_reset(nv40->screen->query, q->object->start); BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1); OUT_RING (1); @@ -82,17 +82,17 @@ nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq, if (!q->ready) { unsigned status; - status = nvws->notifier_status(nv40->hw->query, + status = nvws->notifier_status(nv40->screen->query, q->object->start); if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { if (wait == FALSE) return FALSE; - nvws->notifier_wait(nv40->hw->query, q->object->start, + nvws->notifier_wait(nv40->screen->query, q->object->start, NV_NOTIFY_STATE_STATUS_COMPLETED, 0); } - q->result = nvws->notifier_retval(nv40->hw->query, + q->result = nvws->notifier_retval(nv40->screen->query, q->object->start); q->ready = TRUE; nvws->res_free(&q->object); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 66e84b6890..268ca83ce0 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -4,6 +4,10 @@ #include "nv40_context.h" #include "nv40_screen.h" +#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf +#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 +#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 + static const char * nv40_screen_get_name(struct pipe_screen *pscreen) { @@ -121,6 +125,16 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, static void nv40_screen_destroy(struct pipe_screen *pscreen) { + struct nv40_screen *screen = nv40_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->res_free(&screen->vp_exec_heap); + nvws->res_free(&screen->vp_data_heap); + nvws->res_free(&screen->query_heap); + nvws->notifier_free(&screen->query); + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->curie); + FREE(pscreen); } @@ -129,13 +143,125 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); + struct nouveau_stateobj *so; + unsigned curie_class; + int ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; + /* 3D object */ + switch (chipset & 0xf0) { + case 0x40: + if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV40TCL; + else + if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + case 0x60: + if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + default: + break; + } + + if (!curie_class) { + NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, curie_class, &screen->curie); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &screen->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->res_init(&screen->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&screen->vp_exec_heap, 0, 512) || + nvws->res_init(&screen->vp_data_heap, 0, 256)) { + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static curie initialisation */ + so = so_new(128, 0); + so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2); + so_data (so, 0); + so_data (so, screen->query->handle); + so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + + so_method(so, screen->curie, 0x1ea4, 3); + so_data (so, 0x00000010); + so_data (so, 0x01000100); + so_data (so, 0xff800006); + + /* vtxprog output routing */ + so_method(so, screen->curie, 0x1fc4, 1); + so_data (so, 0x06144321); + so_method(so, screen->curie, 0x1fc8, 2); + so_data (so, 0xedcba987); + so_data (so, 0x00000021); + so_method(so, screen->curie, 0x1fd0, 1); + so_data (so, 0x00171615); + so_method(so, screen->curie, 0x1fd4, 1); + so_data (so, 0x001b1a19); + + so_method(so, screen->curie, 0x1ef8, 1); + so_data (so, 0x0020ffff); + so_method(so, screen->curie, 0x1d64, 1); + so_data (so, 0x00d30000); + so_method(so, screen->curie, 0x1e94, 1); + so_data (so, 0x00000001); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws->channel, 0); + screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 88b8fed26c..9f9668dbb6 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -8,6 +8,21 @@ struct nv40_screen { struct nouveau_winsys *nvws; unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *curie; + struct nouveau_notifier *sync; + + /* Query object resources */ + struct nouveau_notifier *query; + struct nouveau_resource *query_heap; + + /* Vtxprog resources */ + struct nouveau_resource *vp_exec_heap; + struct nouveau_resource *vp_data_heap; + + /* Current 3D state of channel */ + struct nouveau_stateobj *state[NV40_STATE_MAX]; }; static INLINE struct nv40_screen * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 24335fbc44..caa2f9df0c 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -10,7 +10,7 @@ nv40_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); @@ -286,7 +286,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; /*XXX: ignored: * light_twoside @@ -420,18 +420,18 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); - so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); + so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3); so_data (so, nvgl_comparison_op(cso->depth.func)); so_data (so, cso->depth.writemask ? 1 : 0); so_data (so, cso->depth.enabled ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); so_data (so, cso->alpha.enabled ? 1 : 0); so_data (so, nvgl_comparison_op(cso->alpha.func)); so_data (so, float_to_ubyte(cso->alpha.ref)); if (cso->stencil[0].enabled) { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); so_data (so, cso->stencil[0].enabled ? 1 : 0); so_data (so, cso->stencil[0].write_mask); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); @@ -441,12 +441,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); } else { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); so_data (so, cso->stencil[1].enabled ? 1 : 0); so_data (so, cso->stencil[1].write_mask); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); @@ -456,7 +456,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); } else { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); so_data (so, 0); } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index dd09830aa3..95e6d7394f 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -21,7 +21,7 @@ nv40_state_blend_colour_validate(struct nv40_context *nv40) struct nouveau_stateobj *so = so_new(2, 0); struct pipe_blend_color *bcol = &nv40->blend_colour; - so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); + so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1); so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | (float_to_ubyte(bcol->color[0]) << 16) | (float_to_ubyte(bcol->color[1]) << 8) | diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index bb2ce0f722..221503617c 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -67,8 +67,8 @@ nv40_state_emit(struct nv40_context *nv40) while (state->dirty) { unsigned idx = ffsll(state->dirty) - 1; - so_ref (state->hw[idx], &nv40->hw->state[idx]); - so_emit(nv40->nvws, nv40->hw->state[idx]); + so_ref (state->hw[idx], &nv40->screen->state[idx]); + so_emit(nv40->nvws, nv40->screen->state[idx]); state->dirty &= ~(1ULL << idx); } diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 3d0ab92003..71795ab182 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -72,73 +72,73 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) } if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR0, 1); so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR0_PITCH, 2); + so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2); so_data (so, rt[0]->pitch * rt[0]->cpp); so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR1, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR1, 1); so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR1_OFFSET, 2); + so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2); so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_data (so, rt[1]->pitch * rt[1]->cpp); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR2, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR2, 1); so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR2_OFFSET, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR2_OFFSET, 1); so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_COLOR2_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1); so_data (so, rt[2]->pitch * rt[2]->cpp); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR3, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR3, 1); so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR3_OFFSET, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR3_OFFSET, 1); so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_COLOR3_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1); so_data (so, rt[3]->pitch * rt[3]->cpp); } if (zeta_format) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_ZETA, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_ZETA, 1); so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_OFFSET, 1); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_OFFSET, 1); so_reloc (so, zeta->buffer, zeta->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1); so_data (so, zeta->pitch * zeta->cpp); } - so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1); so_data (so, rt_enable); - so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3); + so_method(so, nv40->screen->curie, NV40TCL_RT_HORIZ, 3); so_data (so, (w << 16) | 0); so_data (so, (h << 16) | 0); so_data (so, rt_format); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_HORIZ, 2); so_data (so, (w << 16) | 0); so_data (so, (h << 16) | 0); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); so_data (so, ((w - 1) << 16) | 0); so_data (so, ((h - 1) << 16) | 0); diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 09ffc49f96..9e9eadc511 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -12,7 +12,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40) return FALSE; so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2); if (rast->scissor) { so_data (so, ((s->maxx - s->minx) << 16) | s->minx); so_data (so, ((s->maxy - s->miny) << 16) | s->miny); diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 001c396d74..b51024ad9b 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -4,7 +4,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; struct nouveau_stateobj *so; if (nv40->state.hw[NV40_STATE_STIPPLE] && diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9616be5052..3a32533907 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -6,7 +6,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) struct nouveau_stateobj *so = so_new(9, 0); struct pipe_viewport_state *vpt = &nv40->viewport; - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); so_data (so, fui(vpt->translate[1])); so_data (so, fui(vpt->translate[2])); diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 1653ebf2a7..bedc8c6d4e 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -52,7 +52,7 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, } /* No support for 8bit indices, no support at all on 0x4497 chips */ - if (nv40->hw->curie->grclass == NV44TCL || ib_size == 1) + if (nv40->screen->curie->grclass == NV44TCL || ib_size == 1) return FALSE; switch (ib_size) { @@ -365,9 +365,9 @@ nv40_vbo_validate(struct nv40_context *nv40) num_hw++; vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, nv40->screen->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, nv40->screen->curie, NV40TCL_VTXFMT(0), num_hw); inputs = vp->ir; for (hw = 0; hw < num_hw; hw++) { @@ -399,13 +399,13 @@ nv40_vbo_validate(struct nv40_context *nv40) } if (ib) { - so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_method(vtxbuf, nv40->screen->curie, NV40TCL_IDXBUF_ADDRESS, 2); so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, 0, NV40TCL_IDXBUF_FORMAT_DMA1); } - so_method(vtxbuf, nv40->hw->curie, 0x1710, 1); + so_method(vtxbuf, nv40->screen->curie, 0x1710, 1); so_data (vtxbuf, 0); so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index d3ed57b199..5b7a343e55 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -655,7 +655,7 @@ nv40_vertprog_validate(struct nv40_context *nv40) check_gpu_resources: /* Allocate hw vtxprog exec slots */ if (!vp->exec) { - struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + struct nouveau_resource *heap = nv40->screen->vp_exec_heap; struct nouveau_stateobj *so; uint vplen = vp->nr_insns; @@ -672,9 +672,9 @@ check_gpu_resources: } so = so_new(5, 0); - so_method(so, nv40->hw->curie, NV40TCL_VP_START_FROM_ID, 1); + so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - so_method(so, nv40->hw->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2); so_data (so, vp->ir); so_data (so, vp->or); so_ref(so, &vp->so); @@ -684,7 +684,7 @@ check_gpu_resources: /* Allocate hw vtxprog const slots */ if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv40->hw->vp_data_heap; + struct nouveau_resource *heap = nv40->screen->vp_data_heap; if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { while (heap->next && heap->size < vp->nr_consts) { -- cgit v1.2.3 From b560ed2444383b9634786fe742b8cb6f5cdfc781 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 14:56:42 +1100 Subject: nouveau: enable multi-context/single-channel support for nv40 --- src/gallium/drivers/nv40/nv40_context.c | 3 ++- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_screen.h | 2 ++ src/gallium/drivers/nv40/nv40_state_emit.c | 10 ++++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 084829ce28..203c843a01 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -44,7 +44,7 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_screen *pscreen) +nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; @@ -56,6 +56,7 @@ nv40_create(struct pipe_screen *pscreen) if (!nv40) return NULL; nv40->screen = screen; + nv40->pctx_id = pctx_id; nv40->chipset = chipset; nv40->nvws = nvws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 3b669594dc..e118776306 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -108,6 +108,7 @@ struct nv40_context { struct nouveau_winsys *nvws; struct nv40_screen *screen; + unsigned pctx_id; struct draw_context *draw; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 9f9668dbb6..3ea78aadfd 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -9,6 +9,8 @@ struct nv40_screen { struct nouveau_winsys *nvws; unsigned chipset; + unsigned cur_pctx; + /* HW graphics objects */ struct nouveau_grobj *curie; struct nouveau_notifier *sync; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 221503617c..a95e2472e2 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -62,8 +62,18 @@ static void nv40_state_emit(struct nv40_context *nv40) { struct nv40_state *state = &nv40->state; + struct nv40_screen *screen = nv40->screen; unsigned i, samplers; + if (nv40->pctx_id != screen->cur_pctx) { + for (i = 0; i < NV40_STATE_MAX; i++) { + if (screen->state[i] != state->hw[i] && state->hw[i]) + state->dirty |= (1ULL << i); + } + + screen->cur_pctx = nv40->pctx_id; + } + while (state->dirty) { unsigned idx = ffsll(state->dirty) - 1; -- cgit v1.2.3 From 59d4b7cc626704dbbd9c817019ec2dd9183322ad Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 15:28:24 +1100 Subject: nv40: fix segv when app "skips" texture units. --- src/gallium/drivers/nv40/nv40_state_emit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a95e2472e2..9f268640e0 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -67,7 +67,7 @@ nv40_state_emit(struct nv40_context *nv40) if (nv40->pctx_id != screen->cur_pctx) { for (i = 0; i < NV40_STATE_MAX; i++) { - if (screen->state[i] != state->hw[i] && state->hw[i]) + if (state->hw[i] && screen->state[i] != state->hw[i]) state->dirty |= (1ULL << i); } @@ -84,6 +84,8 @@ nv40_state_emit(struct nv40_context *nv40) so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { + if (!(samplers & (1 << i))) + continue; so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGTEX0+i]); samplers &= ~(1ULL << i); -- cgit v1.2.3 From 57b8711aebdce9bc21bf3311c50dbfb0f9ad6d42 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 16:48:15 +1100 Subject: nv40: nuke debug --- src/gallium/drivers/nv40/nv40_fragprog.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 3c4ea7e99e..d981a02a63 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -416,8 +416,6 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, ai = fsrc->SrcRegister.Index; src[i] = tgsi_src(fpc, fsrc); } else { - NOUVEAU_MSG("extra src attr %d\n", - fsrc->SrcRegister.Index); src[i] = temp(fpc); arith(fpc, 0, MOV, src[i], MASK_ALL, tgsi_src(fpc, fsrc), none, none); -- cgit v1.2.3 From 1de15ad83e5a6902ac57212a3df63bb9b829bc20 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 3 Mar 2008 00:01:44 +1100 Subject: nv40: re-do vtxbuf format code --- src/gallium/drivers/nv40/nv40_vbo.c | 79 +++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 29 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index bedc8c6d4e..f16afc23b8 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -9,34 +9,53 @@ #include "nouveau/nouveau_pushbuf.h" static INLINE int -nv40_vbo_ncomp(uint format) +nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { - int ncomp = 0; - - if (pf_size_x(format)) ncomp++; - if (pf_size_y(format)) ncomp++; - if (pf_size_z(format)) ncomp++; - if (pf_size_w(format)) ncomp++; - - return ncomp; -} - -static INLINE int -nv40_vbo_type(uint format) -{ - switch (pf_type(format)) { - case PIPE_FORMAT_TYPE_FLOAT: - return NV40TCL_VTXFMT_TYPE_FLOAT; - case PIPE_FORMAT_TYPE_UNORM: - return NV40TCL_VTXFMT_TYPE_UBYTE; + char fs[128]; + + switch (pipe) { + case PIPE_FORMAT_R32_FLOAT: + case PIPE_FORMAT_R32G32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + *fmt = NV40TCL_VTXFMT_TYPE_FLOAT; + break; + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R8G8B8_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + *fmt = NV40TCL_VTXFMT_TYPE_UBYTE; + break; default: - { - char fs[128]; - pf_sprint_name(fs, format); + pf_sprint_name(fs, pipe); NOUVEAU_ERR("Unknown format %s\n", fs); - return NV40TCL_VTXFMT_TYPE_FLOAT; + return 1; } + + switch (pipe) { + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R32_FLOAT: + *ncomp = 1; + break; + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R32G32_FLOAT: + *ncomp = 2; + break; + case PIPE_FORMAT_R8G8B8_UNORM: + case PIPE_FORMAT_R32G32B32_FLOAT: + *ncomp = 3; + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + *ncomp = 4; + break; + default: + pf_sprint_name(fs, pipe); + NOUVEAU_ERR("Unknown format %s\n", fs); + return 1; } + + return 0; } static boolean @@ -82,11 +101,11 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, struct pipe_vertex_buffer *vb) { struct pipe_winsys *ws = nv40->pipe.winsys; - int type, ncomp; + unsigned type, ncomp; void *map; - type = nv40_vbo_type(ve->src_format); - ncomp = nv40_vbo_ncomp(ve->src_format); + if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) + return FALSE; map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); map += vb->buffer_offset + ve->src_offset; @@ -373,6 +392,7 @@ nv40_vbo_validate(struct nv40_context *nv40) for (hw = 0; hw < num_hw; hw++) { struct pipe_vertex_element *ve; struct pipe_vertex_buffer *vb; + unsigned type, ncomp; if (!(inputs & (1 << hw))) { so_data(vtxbuf, 0); @@ -389,13 +409,14 @@ nv40_vbo_validate(struct nv40_context *nv40) continue; } + if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) + assert(0); + so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, 0, NV40TCL_VTXBUF_ADDRESS_DMA1); so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) | - (nv40_vbo_ncomp(ve->src_format) << - NV40TCL_VTXFMT_SIZE_SHIFT) | - nv40_vbo_type(ve->src_format))); + (ncomp << NV40TCL_VTXFMT_SIZE_SHIFT) | type)); } if (ib) { -- cgit v1.2.3 From 9a4938d7033101122b627786273ff37229b5558a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 12:36:35 +1100 Subject: nouveau: match interface changes --- src/gallium/drivers/nv40/nv40_context.h | 2 ++ src/gallium/drivers/nv40/nv40_fragprog.c | 11 ++++---- src/gallium/drivers/nv40/nv40_state.c | 47 +++++++++++++++++++++++--------- src/gallium/drivers/nv40/nv40_state.h | 4 +-- src/gallium/drivers/nv40/nv40_vertprog.c | 4 +-- 5 files changed, 45 insertions(+), 23 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index e118776306..100c678187 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -136,6 +136,8 @@ struct nv40_context { unsigned idxbuf_format; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + unsigned nr_textures; unsigned dirty_samplers; struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index d981a02a63..953f9cd908 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -580,15 +580,14 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); break; case TGSI_OPCODE_TEX: - if (finst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide == - TGSI_EXTSWIZZLE_W) { - tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); - } else - tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); + tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); break; case TGSI_OPCODE_TXB: tex(fpc, sat, TXB, unit, dst, mask, src[0], none, none); break; + case TGSI_OPCODE_TXP: + tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); + break; case TGSI_OPCODE_XPD: tmp = temp(fpc); arith(fpc, 0, MUL, tmp, mask, @@ -680,7 +679,7 @@ nv40_fragprog_translate(struct nv40_context *nv40, fpc->high_temp = -1; fpc->num_regs = 2; - tgsi_parse_init(&parse, fp->pipe->tokens); + tgsi_parse_init(&parse, fp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index caa2f9df0c..321d5de041 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "nv40_context.h" #include "nv40_state.h" @@ -251,14 +252,22 @@ nv40_sampler_state_create(struct pipe_context *pipe, } static void -nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, - void *hwcso) +nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_sampler_state *ps = hwcso; + unsigned unit; - nv40->tex_sampler[unit] = ps; - nv40->dirty_samplers |= (1 << unit); + for (unit = 0; unit < nr; unit++) { + nv40->tex_sampler[unit] = sampler[unit]; + nv40->dirty_samplers |= (1 << unit); + } + + for (unit = nr; unit < nv40->nr_samplers; unit++) { + nv40->tex_sampler[unit] = NULL; + nv40->dirty_samplers |= (1 << unit); + } + + nv40->nr_samplers = nr; nv40->dirty |= NV40_NEW_SAMPLER; } @@ -269,13 +278,25 @@ nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso) } static void -nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit, - struct pipe_texture *miptree) +nv40_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) { struct nv40_context *nv40 = nv40_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + pipe_texture_reference((struct pipe_texture **) + &nv40->tex_miptree[unit], miptree[unit]); + nv40->dirty_samplers |= (1 << unit); + } + + for (unit = nr; unit < nv40->nr_textures; unit++) { + pipe_texture_reference((struct pipe_texture **) + &nv40->tex_miptree[unit], NULL); + nv40->dirty_samplers |= (1 << unit); + } - nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree; - nv40->dirty_samplers |= (1 << unit); + nv40->nr_textures = nr; nv40->dirty |= NV40_NEW_SAMPLER; } @@ -490,7 +511,7 @@ nv40_vp_state_create(struct pipe_context *pipe, struct nv40_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv40_vertex_program)); - vp->pipe = cso; + vp->pipe = *cso; return (void *)vp; } @@ -521,7 +542,7 @@ nv40_fp_state_create(struct pipe_context *pipe, struct nv40_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv40_fragment_program)); - fp->pipe = cso; + fp->pipe = *cso; return (void *)fp; } @@ -649,9 +670,9 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.delete_blend_state = nv40_blend_state_delete; nv40->pipe.create_sampler_state = nv40_sampler_state_create; - nv40->pipe.bind_sampler_state = nv40_sampler_state_bind; + nv40->pipe.bind_sampler_states = nv40_sampler_state_bind; nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; - nv40->pipe.set_sampler_texture = nv40_set_sampler_texture; + nv40->pipe.set_sampler_textures = nv40_set_sampler_texture; nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create; nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index e5217fe91c..a02ea0c878 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -23,7 +23,7 @@ struct nv40_vertex_program_data { }; struct nv40_vertex_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; boolean translated; struct nv40_vertex_program_exec *insns; @@ -48,7 +48,7 @@ struct nv40_fragment_program_data { }; struct nv40_fragment_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; boolean translated; unsigned samplers; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 5b7a343e55..3d730c1a32 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -535,7 +535,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) struct tgsi_parse_context p; int nr_imm = 0; - tgsi_parse_init(&p, vpc->vp->pipe->tokens); + tgsi_parse_init(&p, vpc->vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&p)) { const union tgsi_full_token *tok = &p.FullToken; @@ -576,7 +576,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, return; } - tgsi_parse_init(&parse, vp->pipe->tokens); + tgsi_parse_init(&parse, vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); -- cgit v1.2.3 From e1cf3f00e546f814effd25e9ccd072c941366444 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 18:29:56 +1100 Subject: nv40: simple swtnl path (half broken, but getting there) --- src/gallium/drivers/nv40/nv40_context.c | 6 +- src/gallium/drivers/nv40/nv40_context.h | 25 +- src/gallium/drivers/nv40/nv40_draw.c | 334 +++++++++++++++++++++++-- src/gallium/drivers/nv40/nv40_fragprog.c | 3 +- src/gallium/drivers/nv40/nv40_shader.h | 2 + src/gallium/drivers/nv40/nv40_state.c | 27 +- src/gallium/drivers/nv40/nv40_state.h | 4 + src/gallium/drivers/nv40/nv40_state_clip.c | 8 +- src/gallium/drivers/nv40/nv40_state_emit.c | 130 +++++++--- src/gallium/drivers/nv40/nv40_state_viewport.c | 45 +++- src/gallium/drivers/nv40/nv40_vbo.c | 22 +- src/gallium/drivers/nv40/nv40_vertprog.c | 16 +- 12 files changed, 531 insertions(+), 91 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 203c843a01..58627443b8 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -74,8 +74,12 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40_init_state_functions(nv40); nv40_init_miptree_functions(nv40); + /* Create, configure, and install fallback swtnl path */ nv40->draw = draw_create(); - assert(nv40->draw); + draw_wide_point_threshold(nv40->draw, 9999999.0); + draw_wide_line_threshold(nv40->draw, 9999999.0); + draw_enable_line_stipple(nv40->draw, FALSE); + draw_enable_point_sprites(nv40->draw, FALSE); draw_set_rasterize_stage(nv40->draw, nv40_draw_render_stage(nv40)); return &nv40->pipe; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 100c678187..02ca20b801 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -116,7 +116,20 @@ struct nv40_context { /* HW state derived from pipe states */ struct nv40_state state; - unsigned fallback; + struct { + struct nv40_vertex_program *vertprog; + + unsigned nr_attribs; + unsigned hw[PIPE_MAX_SHADER_INPUTS]; + unsigned draw[PIPE_MAX_SHADER_INPUTS]; + unsigned emit[PIPE_MAX_SHADER_INPUTS]; + } swtnl; + + enum { + HW, SWTNL, SWRAST + } render_mode; + unsigned fallback_swtnl; + unsigned fallback_swrast; /* Context state */ unsigned dirty; @@ -166,6 +179,10 @@ extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv40_draw.c */ extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); +extern boolean nv40_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, + unsigned ib_size, unsigned mode, + unsigned start, unsigned count); /* nv40_vertprog.c */ extern void nv40_vertprog_destroy(struct nv40_context *, @@ -179,8 +196,9 @@ extern void nv40_fragprog_destroy(struct nv40_context *, extern void nv40_fragtex_bind(struct nv40_context *); /* nv40_state.c and friends */ -extern void nv40_emit_hw_state(struct nv40_context *nv40); -extern void nv40_state_tex_update(struct nv40_context *nv40); +extern boolean nv40_state_validate(struct nv40_context *nv40); +extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40); +extern void nv40_state_emit(struct nv40_context *nv40); extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; @@ -194,6 +212,7 @@ extern struct nv40_state_entry nv40_state_viewport; extern struct nv40_state_entry nv40_state_framebuffer; extern struct nv40_state_entry nv40_state_fragtex; extern struct nv40_state_entry nv40_state_vbo; +extern struct nv40_state_entry nv40_state_vtxfmt; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index a39bb85e99..ce0e0bc6f2 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -1,62 +1,350 @@ -#include "draw/draw_private.h" #include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" +#include "draw/draw_private.h" #include "nv40_context.h" +#define NV40_SHADER_NO_FUCKEDNESS +#include "nv40_shader.h" + +/* Simple, but crappy, swtnl path, hopefully we wont need to hit this very + * often at all. Uses "quadro style" vertex submission + a fixed vertex + * layout to avoid the need to generate a vertex program or vtxfmt. + */ -struct nv40_draw_stage { - struct draw_stage draw; +struct nv40_render_stage { + struct draw_stage stage; struct nv40_context *nv40; + unsigned prim; }; +static INLINE struct nv40_render_stage * +nv40_render_stage(struct draw_stage *stage) +{ + return (struct nv40_render_stage *)stage; +} + +static INLINE void +nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) +{ + unsigned i; + + for (i = 0; i < nv40->swtnl.nr_attribs; i++) { + unsigned idx = nv40->swtnl.draw[i]; + unsigned hw = nv40->swtnl.hw[i]; + + switch (nv40->swtnl.emit[i]) { + case EMIT_OMIT: + break; + case EMIT_1F: + BEGIN_RING(curie, 0x1e40 + (hw * 4), 1); + OUT_RING (fui(v->data[idx][0])); + break; + case EMIT_2F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_2F_X(hw), 2); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + break; + case EMIT_3F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_3F_X(hw), 3); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + OUT_RING (fui(v->data[idx][2])); + break; + case EMIT_4F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(hw), 4); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + OUT_RING (fui(v->data[idx][2])); + OUT_RING (fui(v->data[idx][3])); + break; + case EMIT_4UB: + BEGIN_RING(curie, 0x1940 + (hw * 4), 1); + OUT_RING (pack_ub4(float_to_ubyte(v->data[idx][0]), + float_to_ubyte(v->data[idx][1]), + float_to_ubyte(v->data[idx][2]), + float_to_ubyte(v->data[idx][3]))); + break; + default: + assert(0); + break; + } + } +} + +static INLINE void +nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, + unsigned mode, unsigned count) +{ + struct nv40_render_stage *rs = nv40_render_stage(stage); + struct nv40_context *nv40 = rs->nv40; + struct nouveau_pushbuf *pb = nv40->nvws->channel->pushbuf; + unsigned i; + + /* Ensure there's room for 4xfloat32 + potentially 3 begin/end */ + if (pb->remaining < ((count * 20) + 6)) { + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + NOUVEAU_ERR("AIII, missed flush\n"); + assert(0); + } + FIRE_RING(); + nv40_state_emit(nv40); + } + + /* Switch primitive modes if necessary */ + if (rs->prim != mode) { + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (mode); + rs->prim = mode; + } + + /* Emit vertex data */ + for (i = 0; i < count; i++) + nv40_render_vertex(nv40, prim->v[i]); + + /* If it's likely we'll need to empty the push buffer soon, finish + * off the primitive now. + */ + if (pb->remaining < ((count * 20) + 6)) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + rs->prim = NV40TCL_BEGIN_END_STOP; + } +} + static void -nv40_draw_point(struct draw_stage *draw, struct prim_header *prim) +nv40_render_point(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_POINTS, 1); } static void -nv40_draw_line(struct draw_stage *draw, struct prim_header *prim) +nv40_render_line(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_LINES, 2); } static void -nv40_draw_tri(struct draw_stage *draw, struct prim_header *prim) +nv40_render_tri(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_TRIANGLES, 3); } static void -nv40_draw_flush(struct draw_stage *draw, unsigned flags) +nv40_render_flush(struct draw_stage *draw, unsigned flags) { + struct nv40_render_stage *rs = nv40_render_stage(draw); + struct nv40_context *nv40 = rs->nv40; + + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + rs->prim = NV40TCL_BEGIN_END_STOP; + } } static void -nv40_draw_reset_stipple_counter(struct draw_stage *draw) +nv40_render_reset_stipple_counter(struct draw_stage *draw) { - NOUVEAU_ERR("\n"); } static void -nv40_draw_destroy(struct draw_stage *draw) +nv40_render_destroy(struct draw_stage *draw) { free(draw); } +static INLINE void +emit_mov(struct nv40_vertex_program *vp, + unsigned dst, unsigned src, unsigned vor, unsigned mask) +{ + struct nv40_vertex_program_exec *inst; + + vp->insns = realloc(vp->insns, + sizeof(struct nv40_vertex_program_exec) * + ++vp->nr_insns); + inst = &vp->insns[vp->nr_insns - 1]; + + inst->data[0] = 0x401f9c6c; + inst->data[1] = 0x0040000d | (src << 8); + inst->data[2] = 0x8106c083; + inst->data[3] = 0x6041ff80 | (dst << 2) | (mask << 13); + inst->const_index = -1; + inst->has_branch_offset = FALSE; + + vp->ir |= (1 << src); + if (vor != ~0) + vp->or |= (1 << vor); +} + +static struct nv40_vertex_program * +create_drawvp(struct nv40_context *nv40) +{ + struct nv40_vertex_program *vp = CALLOC_STRUCT(nv40_vertex_program); + unsigned i; + + emit_mov(vp, NV40_VP_INST_DEST_POS, 0, ~0, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_COL0, 3, 0, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_COL1, 4, 1, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_BFC0, 3, 2, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_BFC1, 4, 3, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_FOGC, 5, 4, 0x8); + for (i = 0; i < 8; i++) + emit_mov(vp, NV40_VP_INST_DEST_TC(i), 8 + i, 14 + i, 0xf); + + vp->insns[vp->nr_insns - 1].data[3] |= 1; + vp->translated = TRUE; + return vp; +} + struct draw_stage * nv40_draw_render_stage(struct nv40_context *nv40) { - struct nv40_draw_stage *nv40draw = CALLOC_STRUCT(nv40_draw_stage); + struct nv40_render_stage *render = CALLOC_STRUCT(nv40_render_stage); + + if (!nv40->swtnl.vertprog) + nv40->swtnl.vertprog = create_drawvp(nv40); + + render->nv40 = nv40; + render->stage.draw = nv40->draw; + render->stage.point = nv40_render_point; + render->stage.line = nv40_render_line; + render->stage.tri = nv40_render_tri; + render->stage.flush = nv40_render_flush; + render->stage.reset_stipple_counter = nv40_render_reset_stipple_counter; + render->stage.destroy = nv40_render_destroy; + + return &render->stage; +} + +boolean +nv40_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, unsigned idxbuf_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + unsigned i; + void *map; + + if (!nv40_state_validate_swtnl(nv40)) + return FALSE; + nv40_state_emit(nv40); - nv40draw->nv40 = nv40; - nv40draw->draw.draw = nv40->draw; - nv40draw->draw.point = nv40_draw_point; - nv40draw->draw.line = nv40_draw_line; - nv40draw->draw.tri = nv40_draw_tri; - nv40draw->draw.flush = nv40_draw_flush; - nv40draw->draw.reset_stipple_counter = nv40_draw_reset_stipple_counter; - nv40draw->draw.destroy = nv40_draw_destroy; + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (!nv40->vtxbuf[i].buffer) + continue; + map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(nv40->draw, i, map); + } - return &nv40draw->draw; + if (idxbuf) { + map = ws->buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map); + } else { + draw_set_mapped_element_buffer(nv40->draw, 0, NULL); + } + + if (nv40->constbuf[PIPE_SHADER_VERTEX]) { + map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_constant_buffer(nv40->draw, map); + } + + draw_arrays(nv40->draw, mode, start, count); + + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (!nv40->vtxbuf[i].buffer) + continue; + ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); + } + + if (idxbuf) + ws->buffer_unmap(ws, idxbuf); + + if (nv40->constbuf[PIPE_SHADER_VERTEX]) + ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); + + draw_flush(nv40->draw); + pipe->flush(pipe, 0); + + return TRUE; } +static INLINE void +emit_attrib(struct nv40_context *nv40, unsigned hw, unsigned emit, + unsigned semantic, unsigned index) +{ + unsigned draw_out = draw_find_vs_output(nv40->draw, semantic, index); + unsigned a = nv40->swtnl.nr_attribs++; + + nv40->swtnl.hw[a] = hw; + nv40->swtnl.emit[a] = emit; + nv40->swtnl.draw[a] = draw_out; +} + +static boolean +nv40_state_vtxfmt_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog; + unsigned colour = 0, texcoords = 0, fog = 0, i; + + /* Determine needed fragprog inputs */ + for (i = 0; i < fp->info.num_inputs; i++) { + switch (fp->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + break; + case TGSI_SEMANTIC_COLOR: + colour |= (1 << fp->info.input_semantic_index[i]); + break; + case TGSI_SEMANTIC_GENERIC: + texcoords |= (1 << fp->info.input_semantic_index[i]); + break; + case TGSI_SEMANTIC_FOG: + fog = 1; + break; + default: + assert(0); + } + } + + nv40->swtnl.nr_attribs = 0; + + /* Map draw vtxprog output to hw attribute IDs */ + for (i = 0; i < 2; i++) { + if (!(colour & (1 << i))) + continue; + emit_attrib(nv40, 3 + i, EMIT_4UB, TGSI_SEMANTIC_COLOR, i); + } + + for (i = 0; i < 8; i++) { + if (!(texcoords & (1 << i))) + continue; + emit_attrib(nv40, 8 + i, EMIT_4F, TGSI_SEMANTIC_GENERIC, i); + } + + if (fog) { + emit_attrib(nv40, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0); + } + + emit_attrib(nv40, 0, EMIT_4F, TGSI_SEMANTIC_POSITION, 0); + + return FALSE; +} + +struct nv40_state_entry nv40_state_vtxfmt = { + .validate = nv40_state_vtxfmt_validate, + .dirty = { + .pipe = NV40_NEW_ARRAYS | NV40_NEW_FRAGPROG, + .hw = 0 + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 953f9cd908..82dbcd3eef 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -797,9 +797,10 @@ nv40_fragprog_validate(struct nv40_context *nv40) if (fp->translated) goto update_constants; + nv40->fallback_swrast &= ~NV40_NEW_FRAGPROG; nv40_fragprog_translate(nv40, fp); if (!fp->translated) { - nv40->fallback |= NV40_FALLBACK_RAST; + nv40->fallback_swrast |= NV40_NEW_FRAGPROG; return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_shader.h b/src/gallium/drivers/nv40/nv40_shader.h index 5909c70713..854dccf548 100644 --- a/src/gallium/drivers/nv40/nv40_shader.h +++ b/src/gallium/drivers/nv40/nv40_shader.h @@ -476,6 +476,7 @@ # define NV40_FP_SWIZZLE_W 3 #define NV40_FP_REG_NEGATE (1 << 17) +#ifndef NV40_SHADER_NO_FUCKEDNESS #define NV40SR_NONE 0 #define NV40SR_OUTPUT 1 #define NV40SR_INPUT 2 @@ -550,5 +551,6 @@ nv40_sr_scale(struct nv40_sreg src, int scale) src.dst_scale = scale; return src; } +#endif #endif diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 321d5de041..3eafbece30 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -3,6 +3,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "draw/draw_context.h" + #include "nv40_context.h" #include "nv40_state.h" @@ -345,7 +347,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: - so_data(so, 0); + so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CCW); @@ -363,13 +365,13 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: - so_data(so, 0); + so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CW); } so_data(so, cso->poly_smooth ? 1 : 0); - so_data(so, cso->cull_mode != PIPE_WINDING_NONE ? 1 : 0); + so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); @@ -419,6 +421,9 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_rasterizer_state *rsso = hwcso; + + draw_set_rasterizer_state(nv40->draw, &rsso->pipe); nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; @@ -508,10 +513,12 @@ static void * nv40_vp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { + struct nv40_context *nv40 = nv40_context(pipe); struct nv40_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv40_vertex_program)); vp->pipe = *cso; + vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe); return (void *)vp; } @@ -520,6 +527,9 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL); nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; @@ -531,6 +541,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_context *nv40 = nv40_context(pipe); struct nv40_vertex_program *vp = hwcso; + draw_delete_vertex_shader(nv40->draw, vp->draw); nv40_vertprog_destroy(nv40, vp); FREE(vp); } @@ -544,6 +555,8 @@ nv40_fp_state_create(struct pipe_context *pipe, fp = CALLOC(1, sizeof(struct nv40_fragment_program)); fp->pipe = *cso; + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + return (void *)fp; } @@ -582,6 +595,8 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_clip_state(nv40->draw, clip); + nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; } @@ -638,6 +653,8 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_viewport_state(nv40->draw, vpt); + nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } @@ -648,6 +665,8 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_vertex_buffer(nv40->draw, index, vb); + nv40->vtxbuf[index] = *vb; nv40->dirty |= NV40_NEW_ARRAYS; } @@ -658,6 +677,8 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_vertex_element(nv40->draw, index, ve); + nv40->vtxelt[index] = *ve; nv40->dirty |= NV40_NEW_ARRAYS; } diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index a02ea0c878..ab2866eb7a 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -2,6 +2,7 @@ #define __NV40_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" struct nv40_sampler_state { uint32_t fmt; @@ -25,6 +26,8 @@ struct nv40_vertex_program_data { struct nv40_vertex_program { struct pipe_shader_state pipe; + struct draw_vertex_shader *draw; + boolean translated; struct nv40_vertex_program_exec *insns; unsigned nr_insns; @@ -49,6 +52,7 @@ struct nv40_fragment_program_data { struct nv40_fragment_program { struct pipe_shader_state pipe; + struct tgsi_shader_info info; boolean translated; unsigned samplers; diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c index 93e690161f..c52390f9ed 100644 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -3,8 +3,12 @@ static boolean nv40_state_clip_validate(struct nv40_context *nv40) { - if (nv40->clip.nr) - nv40->fallback |= NV40_FALLBACK_TNL; + + if (nv40->render_mode == HW) { + nv40->fallback_swtnl &= ~NV40_NEW_UCP; + if (nv40->clip.nr) + nv40->fallback_swtnl |= NV40_NEW_UCP; + } return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 9f268640e0..056238cc83 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -1,5 +1,6 @@ #include "nv40_context.h" #include "nv40_state.h" +#include "draw/draw_context.h" static struct nv40_state_entry *render_states[] = { &nv40_state_framebuffer, @@ -18,15 +19,27 @@ static struct nv40_state_entry *render_states[] = { NULL }; +static struct nv40_state_entry *swtnl_states[] = { + &nv40_state_framebuffer, + &nv40_state_rasterizer, + &nv40_state_clip, + &nv40_state_scissor, + &nv40_state_stipple, + &nv40_state_fragprog, + &nv40_state_fragtex, + &nv40_state_vertprog, + &nv40_state_blend, + &nv40_state_blend_colour, + &nv40_state_zsa, + &nv40_state_viewport, + &nv40_state_vtxfmt, + NULL +}; + static void -nv40_state_validate(struct nv40_context *nv40) +nv40_state_do_validate(struct nv40_context *nv40, + struct nv40_state_entry **states) { - struct nv40_state_entry **states = render_states; - unsigned last_fallback; - - last_fallback = nv40->fallback; - nv40->fallback = 0; - while (*states) { struct nv40_state_entry *e = *states; @@ -38,32 +51,15 @@ nv40_state_validate(struct nv40_context *nv40) states++; } nv40->dirty = 0; - - if (nv40->fallback & NV40_FALLBACK_TNL && - !(last_fallback & NV40_FALLBACK_TNL)) { - NOUVEAU_ERR("XXX: hwtnl->swtnl\n"); - } else - if (last_fallback & NV40_FALLBACK_TNL && - !(nv40->fallback & NV40_FALLBACK_TNL)) { - NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); - } - - if (nv40->fallback & NV40_FALLBACK_RAST && - !(last_fallback & NV40_FALLBACK_RAST)) { - NOUVEAU_ERR("XXX: hwrast->swrast\n"); - } else - if (last_fallback & NV40_FALLBACK_RAST && - !(nv40->fallback & NV40_FALLBACK_RAST)) { - NOUVEAU_ERR("XXX: swrast->hwrast\n"); - } } -static void +void nv40_state_emit(struct nv40_context *nv40) { struct nv40_state *state = &nv40->state; struct nv40_screen *screen = nv40->screen; unsigned i, samplers; + uint64 states; if (nv40->pctx_id != screen->cur_pctx) { for (i = 0; i < NV40_STATE_MAX; i++) { @@ -74,14 +70,24 @@ nv40_state_emit(struct nv40_context *nv40) screen->cur_pctx = nv40->pctx_id; } - while (state->dirty) { - unsigned idx = ffsll(state->dirty) - 1; + for (i = 0, states = state->dirty; states; i++) { + if (!(states & (1ULL << i))) + continue; + so_ref (state->hw[i], &nv40->screen->state[i]); + so_emit(nv40->nvws, nv40->screen->state[i]); + states &= ~(1ULL << i); + } - so_ref (state->hw[idx], &nv40->screen->state[idx]); - so_emit(nv40->nvws, nv40->screen->state[idx]); - state->dirty &= ~(1ULL << idx); + if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) | + (1ULL << NV40_STATE_FRAGTEX0))) { + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); } + state->dirty = 0; + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) @@ -91,18 +97,62 @@ nv40_state_emit(struct nv40_context *nv40) samplers &= ~(1ULL << i); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); - so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); + if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW) + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); } -void -nv40_emit_hw_state(struct nv40_context *nv40) +boolean +nv40_state_validate(struct nv40_context *nv40) { - nv40_state_validate(nv40); - nv40_state_emit(nv40); + boolean was_sw = nv40->fallback_swtnl ? TRUE : FALSE; + + if (nv40->render_mode != HW) { + /* Don't even bother trying to go back to hw if none + * of the states that caused swtnl previously have changed. + */ + if ((nv40->fallback_swtnl & nv40->dirty) + != nv40->fallback_swtnl) + return FALSE; + + /* Attempt to go to hwtnl again */ + nv40->pipe.flush(&nv40->pipe, 0); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS | + NV40_NEW_UCP); + nv40->render_mode = HW; + } + + nv40_state_do_validate(nv40, render_states); + if (nv40->fallback_swtnl || nv40->fallback_swrast) + return FALSE; + + if (was_sw) + NOUVEAU_ERR("swtnl->hw\n"); + + return TRUE; +} + +boolean +nv40_state_validate_swtnl(struct nv40_context *nv40) +{ + /* Setup for swtnl */ + if (nv40->render_mode == HW) { + NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); + nv40->pipe.flush(&nv40->pipe, 0); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS | + NV40_NEW_UCP); + nv40->render_mode = SWTNL; + } + + nv40_state_do_validate(nv40, swtnl_states); + if (nv40->fallback_swrast) { + NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast); + return FALSE; + } - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (2); - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (1); + return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 3a32533907..9e5c7a72a7 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -3,18 +3,43 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { - struct nouveau_stateobj *so = so_new(9, 0); + struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; - so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(vpt->translate[0])); - so_data (so, fui(vpt->translate[1])); - so_data (so, fui(vpt->translate[2])); - so_data (so, fui(vpt->translate[3])); - so_data (so, fui(vpt->scale[0])); - so_data (so, fui(vpt->scale[1])); - so_data (so, fui(vpt->scale[2])); - so_data (so, fui(vpt->scale[3])); + if (nv40->render_mode == HW) { + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 1); + } else { + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(0.0)); + /* Not entirely certain what this is yet. The DDX uses this + * value also as it fixes rendering when you pass + * pre-transformed vertices to the GPU. My best gusss is that + * this bypasses some culling/clipping stage. Might be worth + * noting that points/lines are uneffected by whatever this + * value fixes, only filled polygons are effected. + */ + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 0x110); + } so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); return TRUE; diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index f16afc23b8..fad423fdf8 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -8,6 +8,8 @@ #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" +#define FORCE_SWTNL 0 + static INLINE int nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { @@ -165,7 +167,11 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned nr; nv40_vbo_set_idxbuf(nv40, NULL, 0); - nv40_emit_hw_state(nv40); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + nv40_state_emit(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -274,7 +280,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - nv40_emit_hw_state(nv40); + nv40_state_emit(nv40); map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { @@ -315,7 +321,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); unsigned nr; - nv40_emit_hw_state(nv40); + nv40_state_emit(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -352,8 +358,16 @@ nv40_draw_elements(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); + boolean idxbuf; + + idxbuf = nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + nv40_state_emit(nv40); - if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) { + if (idxbuf) { nv40_draw_elements_vbo(pipe, mode, start, count); } else { nv40_draw_elements_inline(pipe, indexBuffer, indexSize, diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 3d730c1a32..9f1ee575ce 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -634,21 +634,29 @@ out_err: static boolean nv40_vertprog_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->vertprog; - struct pipe_buffer *constbuf = - nv40->constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; + struct nv40_vertex_program *vp; + struct pipe_buffer *constbuf; boolean upload_code = FALSE, upload_data = FALSE; int i; + if (nv40->render_mode == HW) { + vp = nv40->vertprog; + constbuf = nv40->constbuf[PIPE_SHADER_VERTEX]; + } else { + vp = nv40->swtnl.vertprog; + constbuf = NULL; + } + /* Translate TGSI shader into hw bytecode */ if (vp->translated) goto check_gpu_resources; + nv40->fallback_swtnl &= ~NV40_NEW_VERTPROG; nv40_vertprog_translate(nv40, vp); if (!vp->translated) { - nv40->fallback |= NV40_FALLBACK_TNL; + nv40->fallback_swtnl |= NV40_NEW_VERTPROG; return FALSE; } -- cgit v1.2.3 From 767cd2ed6e97ae09526b15728495f361d5e22cb2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 17 Mar 2008 13:49:03 +1100 Subject: nv40: workaround main swtnl breakage Not sure where the real bug is here yet, but for now this gives us correct rendering in far more cases than previously. --- src/gallium/drivers/nv40/nv40_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index ce0e0bc6f2..eb4f2395c4 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -335,7 +335,7 @@ nv40_state_vtxfmt_validate(struct nv40_context *nv40) emit_attrib(nv40, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0); } - emit_attrib(nv40, 0, EMIT_4F, TGSI_SEMANTIC_POSITION, 0); + emit_attrib(nv40, 0, EMIT_3F, TGSI_SEMANTIC_POSITION, 0); return FALSE; } -- cgit v1.2.3 From 6b3269900101a4e4745f95028bfc0c7cfced12a8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 17 Mar 2008 23:05:46 +1100 Subject: nv40: a few more fp opcodes --- src/gallium/drivers/nv40/nv40_fragprog.c | 50 ++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 82dbcd3eef..4fb28a01ea 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -468,6 +468,34 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, case TGSI_OPCODE_COS: arith(fpc, sat, COS, dst, mask, src[0], none, none); break; + case TGSI_OPCODE_DDX: + if (mask & (MASK_Z | MASK_W)) { + tmp = temp(fpc); + arith(fpc, sat, DDX, tmp, MASK_X | MASK_Y, + swz(src[0], Z, W, Z, W), none, none); + arith(fpc, 0, MOV, tmp, MASK_Z | MASK_W, + swz(tmp, X, Y, X, Y), none, none); + arith(fpc, sat, DDX, tmp, MASK_X | MASK_Y, src[0], + none, none); + arith(fpc, 0, MOV, dst, mask, tmp, none, none); + } else { + arith(fpc, sat, DDX, dst, mask, src[0], none, none); + } + break; + case TGSI_OPCODE_DDY: + if (mask & (MASK_Z | MASK_W)) { + tmp = temp(fpc); + arith(fpc, sat, DDY, tmp, MASK_X | MASK_Y, + swz(src[0], Z, W, Z, W), none, none); + arith(fpc, 0, MOV, tmp, MASK_Z | MASK_W, + swz(tmp, X, Y, X, Y), none, none); + arith(fpc, sat, DDY, tmp, MASK_X | MASK_Y, src[0], + none, none); + arith(fpc, 0, MOV, dst, mask, tmp, none, none); + } else { + arith(fpc, sat, DDY, dst, mask, src[0], none, none); + } + break; case TGSI_OPCODE_DP3: arith(fpc, sat, DP3, dst, mask, src[0], src[1], none); break; @@ -567,15 +595,33 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, swz(src[0], X, X, X, X), none, none); } break; - case TGSI_OPCODE_SIN: - arith(fpc, sat, SIN, dst, mask, src[0], none, none); + case TGSI_OPCODE_SEQ: + arith(fpc, sat, SEQ, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SFL: + arith(fpc, sat, SFL, dst, mask, src[0], src[1], none); break; case TGSI_OPCODE_SGE: arith(fpc, sat, SGE, dst, mask, src[0], src[1], none); break; + case TGSI_OPCODE_SGT: + arith(fpc, sat, SGT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SIN: + arith(fpc, sat, SIN, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_SLE: + arith(fpc, sat, SLE, dst, mask, src[0], src[1], none); + break; case TGSI_OPCODE_SLT: arith(fpc, sat, SLT, dst, mask, src[0], src[1], none); break; + case TGSI_OPCODE_SNE: + arith(fpc, sat, SNE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_STR: + arith(fpc, sat, STR, dst, mask, src[0], src[1], none); + break; case TGSI_OPCODE_SUB: arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); break; -- cgit v1.2.3 From 9575e35807c89c0b8a745671bc2dcd54d96379ff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Mar 2008 00:06:15 +1100 Subject: nouveau: pass nvws to nvws->push_* functions, rather than nouveau_channel* --- src/gallium/drivers/nv40/nv40_dma.h | 66 ---------------------------------- src/gallium/drivers/nv40/nv40_screen.c | 2 +- 2 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 src/gallium/drivers/nv40/nv40_dma.h (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_dma.h b/src/gallium/drivers/nv40/nv40_dma.h deleted file mode 100644 index 1fb8267768..0000000000 --- a/src/gallium/drivers/nv40/nv40_dma.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __NV40_DMA_H__ -#define __NV40_DMA_H__ - -#include "pipe/nouveau/nouveau_winsys.h" - -#define OUT_RING(data) do { \ - (*nv40->nvws->channel->pushbuf->cur++) = (data); \ -} while(0) - -#define OUT_RINGp(src,size) do { \ - memcpy(nv40->nvws->channel->pushbuf->cur, (src), (size) * 4); \ - nv40->nvws->channel->pushbuf->cur += (size); \ -} while(0) - -#define OUT_RINGf(data) do { \ - union { float v; uint32_t u; } c; \ - c.v = (data); \ - OUT_RING(c.u); \ -} while(0) - -#define BEGIN_RING(obj,mthd,size) do { \ - if (nv40->nvws->channel->pushbuf->remaining < ((size) + 1)) \ - nv40->nvws->push_flush(nv40->nvws->channel, ((size) + 1)); \ - OUT_RING((nv40->obj->subc << 13) | ((size) << 18) | (mthd)); \ - nv40->nvws->channel->pushbuf->remaining -= ((size) + 1); \ -} while(0) - -#define BEGIN_RING_NI(obj,mthd,size) do { \ - BEGIN_RING(obj, (mthd) | 0x40000000, (size)); \ -} while(0) - -#define FIRE_RING() do { \ - nv40->nvws->push_flush(nv40->nvws->channel, 0); \ -} while(0) - -#define OUT_RELOC(bo,data,flags,vor,tor) do { \ - nv40->nvws->push_reloc(nv40->nvws->channel, \ - nv40->nvws->channel->pushbuf->cur, \ - (struct nouveau_bo *)(bo), \ - (data), (flags), (vor), (tor)); \ - OUT_RING(0); \ -} while(0) - -/* Raw data + flags depending on FB/TT buffer */ -#define OUT_RELOCd(bo,data,flags,vor,tor) do { \ - OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \ -} while(0) - -/* FB/TT object handle */ -#define OUT_RELOCo(bo,flags) do { \ - OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ - nv40->nvws->channel->vram->handle, \ - nv40->nvws->channel->gart->handle); \ -} while(0) - -/* Low 32-bits of offset */ -#define OUT_RELOCl(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ -} while(0) - -/* High 32-bits of offset */ -#define OUT_RELOCh(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \ -} while(0) - -#endif diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 268ca83ce0..bf30fbeca1 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -260,7 +260,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so_emit(nvws, so); so_ref(NULL, &so); - nvws->push_flush(nvws->channel, 0); + nvws->push_flush(nvws, 0); screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; -- cgit v1.2.3 From 176df85568992a5d99aab7f0b1e382d41459aa13 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Mar 2008 21:52:19 +1100 Subject: nv40: "implement" noise opcodes in fragprog For the moment, we do what NVIDIA does and return 0 unconditionally. This isn't correct, but it's an implementation at least. --- src/gallium/drivers/nv40/nv40_fragprog.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4fb28a01ea..33aac37d56 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -554,6 +554,12 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, case TGSI_OPCODE_MUL: arith(fpc, sat, MUL, dst, mask, src[0], src[1], none); break; + case TGSI_OPCODE_NOISE1: + case TGSI_OPCODE_NOISE2: + case TGSI_OPCODE_NOISE3: + case TGSI_OPCODE_NOISE4: + arith(fpc, sat, SFL, dst, mask, none, none, none); + break; case TGSI_OPCODE_POW: tmp = temp(fpc); arith(fpc, 0, LG2, tmp, MASK_X, -- cgit v1.2.3 From 1d9049c4df24d47446218f4032b891b817af0d00 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 00:18:18 +1100 Subject: nouveau: match gallium API changes --- src/gallium/drivers/nv40/nv40_miptree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 94ba05b710..0dff9b3ad6 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -99,7 +99,8 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) } static void -nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, + uint face, uint levels) { } -- cgit v1.2.3 From 95e8cad9a38181052790b34837daa6717e0c5171 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 12:57:05 +1100 Subject: nv40: use new pipe_framebuffer width/height fields --- src/gallium/drivers/nv40/nv40_state_fb.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 71795ab182..107b440028 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -5,10 +5,12 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) { struct pipe_framebuffer_state *fb = &nv40->framebuffer; struct pipe_surface *rt[4], *zeta; - uint32_t rt_enable, rt_format, w, h; + uint32_t rt_enable, rt_format; int i, colour_format = 0, zeta_format = 0; struct nouveau_stateobj *so = so_new(64, 10); unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; + unsigned w = fb->width; + unsigned h = fb->height; rt_enable = 0; for (i = 0; i < 4; i++) { @@ -16,12 +18,8 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) continue; if (colour_format) { - assert(w == fb->cbufs[i]->width); - assert(h == fb->cbufs[i]->height); assert(colour_format == fb->cbufs[i]->format); } else { - w = fb->cbufs[i]->width; - h = fb->cbufs[i]->height; colour_format = fb->cbufs[i]->format; rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i); rt[i] = fb->cbufs[i]; @@ -33,14 +31,6 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) rt_enable |= NV40TCL_RT_ENABLE_MRT; if (fb->zsbuf) { - if (colour_format) { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } else { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - } - zeta_format = fb->zsbuf->format; zeta = fb->zsbuf; } -- cgit v1.2.3 From ebde8d3a1276f5c72d39936efabe72b5325f8e98 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 21:17:57 +1100 Subject: nv40: use num_cbufs --- src/gallium/drivers/nv40/nv40_state_fb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 107b440028..93b79377c9 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -13,10 +13,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) unsigned h = fb->height; rt_enable = 0; - for (i = 0; i < 4; i++) { - if (!fb->cbufs[i]) - continue; - + for (i = 0; i < fb->num_cbufs; i++) { if (colour_format) { assert(colour_format == fb->cbufs[i]->format); } else { -- cgit v1.2.3 From 32162871396f65e8afdd90c602b1ccd01233c2e2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 21:58:17 +1100 Subject: nv40: align each level to 64 pixels --- src/gallium/drivers/nv40/nv40_miptree.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 0dff9b3ad6..01b3952fe6 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -12,7 +12,7 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; uint offset = 0; - int nr_faces, l, f; + int nr_faces, l, f, pitch; if (pt->target == PIPE_TEXTURE_CUBE) { nr_faces = 6; @@ -22,18 +22,18 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) } else { nr_faces = 1; } - + + pitch = pt->width[0]; for (l = 0; l <= pt->last_level; l++) { pt->width[l] = width; pt->height[l] = height; pt->depth[l] = depth; if (swizzled) - nv40mt->level[l].pitch = pt->width[l] * pt->cpp; - else - nv40mt->level[l].pitch = pt->width[0] * pt->cpp; - nv40mt->level[l].pitch = (nv40mt->level[l].pitch + 63) & ~63; + pitch = pt->width[l]; + pitch = (pitch + 63) & ~63; + nv40mt->level[l].pitch = pitch * pt->cpp; nv40mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); @@ -49,6 +49,7 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) offset += nv40mt->level[l].pitch * pt->height[l]; } } + NOUVEAU_ERR("\n"); nv40mt->total_size = offset; } -- cgit v1.2.3 From 46b8dd9c16755e97ae547c0a1823e338f7a7c791 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:01:22 +1100 Subject: nv40: s/free/FREE/ --- src/gallium/drivers/nv40/nv40_context.c | 2 +- src/gallium/drivers/nv40/nv40_draw.c | 2 +- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- src/gallium/drivers/nv40/nv40_miptree.c | 6 +++--- src/gallium/drivers/nv40/nv40_query.c | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 58627443b8..7fcf8b8619 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -40,7 +40,7 @@ nv40_destroy(struct pipe_context *pipe) if (nv40->draw) draw_destroy(nv40->draw); - free(nv40); + FREE(nv40); } struct pipe_context * diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index eb4f2395c4..7c5e0df5b8 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -158,7 +158,7 @@ nv40_render_reset_stipple_counter(struct draw_stage *draw) static void nv40_render_destroy(struct draw_stage *draw) { - free(draw); + FREE(draw); } static INLINE void diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 33aac37d56..2d82f86ef5 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -801,7 +801,7 @@ nv40_fragprog_translate(struct nv40_context *nv40, fp->translated = TRUE; out_err: tgsi_parse_free(&parse); - free(fpc); + FREE(fpc); } static void @@ -903,7 +903,7 @@ nv40_fragprog_destroy(struct nv40_context *nv40, struct nv40_fragment_program *fp) { if (fp->insn_len) - free(fp->insn); + FREE(fp->insn); } struct nv40_state_entry nv40_state_fragprog = { diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 01b3952fe6..215b91fcd0 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -72,7 +72,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); if (!mt->buffer) { - free(mt); + FREE(mt); return NULL; } @@ -93,9 +93,9 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) pipe_buffer_reference(ws, &nv40mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv40mt->level[l].image_offset) - free(nv40mt->level[l].image_offset); + FREE(nv40mt->level[l].image_offset); } - free(nv40mt); + FREE(nv40mt); } } diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 0317845624..a0a3072406 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -34,7 +34,7 @@ nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) if (q->object) nv40->nvws->res_free(&q->object); - free(q); + FREE(q); } static void diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 9f1ee575ce..385c8aa078 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -572,7 +572,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, vpc->high_temp = -1; if (!nv40_vertprog_prepare(vpc)) { - free(vpc); + FREE(vpc); return; } @@ -628,7 +628,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, vp->translated = TRUE; out_err: tgsi_parse_free(&parse); - free(vpc); + FREE(vpc); } static boolean @@ -805,9 +805,9 @@ void nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) { if (vp->nr_consts) - free(vp->consts); + FREE(vp->consts); if (vp->nr_insns) - free(vp->insns); + FREE(vp->insns); } struct nv40_state_entry nv40_state_vertprog = { -- cgit v1.2.3 From 0c91f5991dee7827ea915214a2a6973c2d6a7257 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:02:49 +1100 Subject: nv40: oops --- src/gallium/drivers/nv40/nv40_miptree.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 215b91fcd0..502edc1629 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -49,7 +49,6 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) offset += nv40mt->level[l].pitch * pt->height[l]; } } - NOUVEAU_ERR("\n"); nv40mt->total_size = offset; } -- cgit v1.2.3 From 308d7b171179f40b767b6590f71f969473ade25c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:09:29 +1100 Subject: nv40: swtnl fallback on unsupported array format --- src/gallium/drivers/nv40/nv40_vbo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index fad423fdf8..4a5b811939 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -423,8 +423,12 @@ nv40_vbo_validate(struct nv40_context *nv40) continue; } - if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) - assert(0); + if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) { + nv40->fallback_swtnl |= NV40_NEW_ARRAYS; + so_ref(NULL, &vtxbuf); + so_ref(NULL, &vtxfmt); + return FALSE; + } so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, -- cgit v1.2.3 From 19b57690ad251e2b0714abe3a20893722bd99d54 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:23:19 +1100 Subject: nv40: call semi-magic 0x1d88 method --- src/gallium/drivers/nv40/nv40_state_fb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 93b79377c9..88baf61ffb 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -128,6 +128,8 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); so_data (so, ((w - 1) << 16) | 0); so_data (so, ((h - 1) << 16) | 0); + so_method(so, nv40->screen->curie, 0x1d88, 1); + so_data (so, (1 << 12) | h); so_ref(so, &nv40->state.hw[NV40_STATE_FB]); return TRUE; -- cgit v1.2.3 From 3a0dd2e6d162fad6f98f337ee4f6b5dada1e37f3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 23:03:25 +1100 Subject: nv40: ensure vb relocs don't end up on list for swtnl Avoids bo code bailing out because of mapped buffers being validated. --- src/gallium/drivers/nv40/nv40_draw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 7c5e0df5b8..d05e5ad193 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -236,6 +236,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, if (!nv40_state_validate_swtnl(nv40)) return FALSE; + nv40->dirty &= ~(1ULL << NV40_STATE_VTXBUF); nv40_state_emit(nv40); for (i = 0; i < PIPE_ATTRIB_MAX; i++) { -- cgit v1.2.3 From 3be8785e08128bc2821c0cdff97f7adbb46c745b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 23:09:01 +1100 Subject: nv40: add 16-bit SSCALED vb formats --- src/gallium/drivers/nv40/nv40_vbo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 4a5b811939..4fae10f74b 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -28,6 +28,12 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) case PIPE_FORMAT_R8G8B8A8_UNORM: *fmt = NV40TCL_VTXFMT_TYPE_UBYTE; break; + case PIPE_FORMAT_R16_SSCALED: + case PIPE_FORMAT_R16G16_SSCALED: + case PIPE_FORMAT_R16G16B16_SSCALED: + case PIPE_FORMAT_R16G16B16A16_SSCALED: + *fmt = 5; + break; default: pf_sprint_name(fs, pipe); NOUVEAU_ERR("Unknown format %s\n", fs); @@ -37,18 +43,22 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) switch (pipe) { case PIPE_FORMAT_R8_UNORM: case PIPE_FORMAT_R32_FLOAT: + case PIPE_FORMAT_R16_SSCALED: *ncomp = 1; break; case PIPE_FORMAT_R8G8_UNORM: case PIPE_FORMAT_R32G32_FLOAT: + case PIPE_FORMAT_R16G16_SSCALED: *ncomp = 2; break; case PIPE_FORMAT_R8G8B8_UNORM: case PIPE_FORMAT_R32G32B32_FLOAT: + case PIPE_FORMAT_R16G16B16_SSCALED: *ncomp = 3; break; case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R16G16B16A16_SSCALED: *ncomp = 4; break; default: -- cgit v1.2.3 From 75b85fd33abe143d9cca6f8405f0a4243b6a5ddb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 23:24:16 +1100 Subject: nv40: fix bug in query code --- src/gallium/drivers/nv40/nv40_query.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index a0a3072406..15961591b9 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -45,6 +45,15 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); + /* Happens when end_query() is called, then another begin_query() + * without querying the result in-between. For now we'll wait for + * the existing query to notify completion, but it could be better. + */ + if (q->object) { + uint64 tmp; + pipe->get_query_result(pipe, pq, 1, &tmp); + } + if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object)) assert(0); nv40->nvws->notifier_reset(nv40->screen->query, q->object->start); -- cgit v1.2.3 From 62a8e7685f0567052f50a2b9aaa64054e5dfa0c6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 14:29:35 +1100 Subject: nv40: add dxtn formats (disabled) --- src/gallium/drivers/nv40/nv40_fragtex.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.c | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 436f954cec..980705f94a 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -30,10 +30,10 @@ nv40_texture_formats[] = { _(U_A8_L8 , A8L8 , S1, S1, S1, S1, X, X, X, Y), _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X), _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X), -// _(RGB_DXT1 , 0x86, S1, S1, S1, ONE, X, Y, Z, W, 0x00, 0x00), -// _(RGBA_DXT1 , 0x86, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), -// _(RGBA_DXT3 , 0x87, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), -// _(RGBA_DXT5 , 0x88, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), + _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W), + _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W), + _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W), + _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W), {}, }; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index bf30fbeca1..75b965bb9d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -110,6 +110,12 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_U_A8_L8: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_Z24S8_UNORM: +#if 0 /* state tracker not up to the task just yet. */ + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: +#endif return TRUE; default: break; -- cgit v1.2.3 From 01cb2cd93efe7ad94d7fd36aa5a776c2e3ab4c7d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 16:11:03 +1100 Subject: nv40: workaround fp result.data[0] clobberage Temporary, the fp reg handling will get reworked at some point in the near future. But before that, there's a few bugs to find. --- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 2d82f86ef5..4e42536698 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -58,7 +58,7 @@ temp(struct nv40_fpc *fpc) int idx; idx = fpc->temp_temp_count++; - idx += fpc->high_temp + 1; + idx += fpc->high_temp + 2; return nv40_sr(NV40SR_TEMP, idx); } @@ -817,7 +817,9 @@ nv40_fragprog_upload(struct nv40_context *nv40, #if 0 for (i = 0; i < fp->insn_len; i++) { + fflush(stdout); fflush(stderr); NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); + fflush(stdout); fflush(stderr); } #endif -- cgit v1.2.3 From ba223e91df8f372a983e99c453947e4340d7d884 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 16:26:42 +1100 Subject: nv40: fp: fix multiple refs to a single const withing an instruction --- src/gallium/drivers/nv40/nv40_fragprog.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4e42536698..4cdbf962ab 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -41,6 +41,7 @@ struct nv40_fpc { uint colour_id; unsigned inst_offset; + unsigned have_const; struct { int pipe; @@ -113,7 +114,11 @@ emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src) sr |= (src.index << NV40_FP_REG_SRC_SHIFT); break; case NV40SR_CONST: - grow_insns(fpc, 4); + if (!fpc->have_const) { + grow_insns(fpc, 4); + fpc->have_const = 1; + } + hw = &fp->insn[fpc->inst_offset]; if (fpc->consts[src.index].pipe >= 0) { struct nv40_fragment_program_data *fpd; @@ -190,6 +195,7 @@ nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op, uint32_t *hw; fpc->inst_offset = fp->insn_len; + fpc->have_const = 0; grow_insns(fpc, 4); hw = &fp->insn[fpc->inst_offset]; memset(hw, 0, sizeof(uint32_t) * 4); -- cgit v1.2.3 From 3158035154915ae11bebca045e3f0ce3b0e264ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 16:31:31 +1100 Subject: nv40: catch fp extra-const cases where both const and immd have same idx --- src/gallium/drivers/nv40/nv40_fragprog.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4cdbf962ab..c854ae89f7 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -384,7 +384,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); struct nv40_sreg src[3], dst, tmp; int mask, sat, unit; - int ai = -1, ci = -1; + int ai = -1, ci = -1, ii = -1; int i; if (finst->Instruction.Opcode == TGSI_OPCODE_END) @@ -428,8 +428,8 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, } break; case TGSI_FILE_CONSTANT: - case TGSI_FILE_IMMEDIATE: - if (ci == -1 || ci == fsrc->SrcRegister.Index) { + if ((ci == -1 && ii == -1) || + ci == fsrc->SrcRegister.Index) { ci = fsrc->SrcRegister.Index; src[i] = tgsi_src(fpc, fsrc); } else { @@ -438,6 +438,17 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, tgsi_src(fpc, fsrc), none, none); } break; + case TGSI_FILE_IMMEDIATE: + if ((ci == -1 && ii == -1) || + ii == fsrc->SrcRegister.Index) { + ii = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; case TGSI_FILE_TEMPORARY: /* handled above */ break; -- cgit v1.2.3 From 4dfcf912964f7c14c877abde04255a3896fb903d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 18:11:49 +1100 Subject: nv40: remove some badness from fp temp/result allocation Should hopefully be OK now (on the fragprog size) for MRT. The hack from a commit 01cb2cd93efe7ad94d7fd36aa5a776c2e3ab4c7d is no longer needed. --- src/gallium/drivers/nv40/nv40_fragprog.c | 158 +++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 51 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index c854ae89f7..6d8a29ed9c 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -33,12 +33,12 @@ struct nv40_fpc { uint attrib_map[PIPE_MAX_SHADER_INPUTS]; - int high_temp; - int temp_temp_count; - int num_regs; + unsigned r_temps; + unsigned r_temps_discard; + struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS]; + struct nv40_sreg *r_temp; - uint depth_id; - uint colour_id; + int num_regs; unsigned inst_offset; unsigned have_const; @@ -56,13 +56,26 @@ struct nv40_fpc { static INLINE struct nv40_sreg temp(struct nv40_fpc *fpc) { - int idx; + int idx = ffs(~fpc->r_temps) - 1; - idx = fpc->temp_temp_count++; - idx += fpc->high_temp + 2; + if (idx < 0) { + NOUVEAU_ERR("out of temps!!\n"); + assert(0); + return nv40_sr(NV40SR_TEMP, 0); + } + + fpc->r_temps |= (1 << idx); + fpc->r_temps_discard |= (1 << idx); return nv40_sr(NV40SR_TEMP, idx); } +static INLINE void +release_temps(struct nv40_fpc *fpc) +{ + fpc->r_temps &= ~fpc->r_temps_discard; + fpc->r_temps_discard = 0; +} + static INLINE struct nv40_sreg constant(struct nv40_fpc *fpc, int pipe, float vals[4]) { @@ -254,18 +267,11 @@ tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc) src = fpc->imm[fsrc->SrcRegister.Index]; break; case TGSI_FILE_TEMPORARY: - src = nv40_sr(NV40SR_TEMP, fsrc->SrcRegister.Index + 1); - if (fpc->high_temp < src.index) - fpc->high_temp = src.index; + src = fpc->r_temp[fsrc->SrcRegister.Index]; break; - /* This is clearly insane, but gallium hands us shaders like this. - * Luckily fragprog results are just temp regs.. - */ + /* NV40 fragprog result regs are just temps, so this is simple */ case TGSI_FILE_OUTPUT: - if (fsrc->SrcRegister.Index == fpc->colour_id) - return nv40_sr(NV40SR_OUTPUT, 0); - else - return nv40_sr(NV40SR_OUTPUT, 1); + src = fpc->r_result[fsrc->SrcRegister.Index]; break; default: NOUVEAU_ERR("bad src file\n"); @@ -283,20 +289,11 @@ tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc) static INLINE struct nv40_sreg tgsi_dst(struct nv40_fpc *fpc, const struct tgsi_full_dst_register *fdst) { - int idx; - switch (fdst->DstRegister.File) { case TGSI_FILE_OUTPUT: - if (fdst->DstRegister.Index == fpc->colour_id) - return nv40_sr(NV40SR_OUTPUT, 0); - else - return nv40_sr(NV40SR_OUTPUT, 1); - break; + return fpc->r_result[fdst->DstRegister.Index]; case TGSI_FILE_TEMPORARY: - idx = fdst->DstRegister.Index + 1; - if (fpc->high_temp < idx) - fpc->high_temp = idx; - return nv40_sr(NV40SR_TEMP, idx); + return fpc->r_temp[fdst->DstRegister.Index]; case TGSI_FILE_NULL: return nv40_sr(NV40SR_NONE, 0); default: @@ -390,7 +387,6 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, if (finst->Instruction.Opcode == TGSI_OPCODE_END) return TRUE; - fpc->temp_temp_count = 0; for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *fsrc; @@ -670,6 +666,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, return FALSE; } + release_temps(fpc); return TRUE; } @@ -719,45 +716,50 @@ static boolean nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, const struct tgsi_full_declaration *fdec) { + unsigned idx = fdec->u.DeclarationRange.First; + unsigned hw; + switch (fdec->Semantic.SemanticName) { case TGSI_SEMANTIC_POSITION: - fpc->depth_id = fdec->u.DeclarationRange.First; + hw = 1; break; case TGSI_SEMANTIC_COLOR: - fpc->colour_id = fdec->u.DeclarationRange.First; + switch (idx) { + case 0: hw = 0; break; + case 1: hw = 2; break; + case 2: hw = 3; break; + case 3: hw = 4; break; + default: + NOUVEAU_ERR("bad rcol index\n"); + return FALSE; + } break; default: NOUVEAU_ERR("bad output semantic\n"); return FALSE; } + fpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw); + fpc->r_temps |= (1 << hw); return TRUE; } -static void -nv40_fragprog_translate(struct nv40_context *nv40, - struct nv40_fragment_program *fp) +static boolean +nv40_fragprog_prepare(struct nv40_fpc *fpc) { - struct tgsi_parse_context parse; - struct nv40_fpc *fpc = NULL; + struct tgsi_parse_context p; + int high_temp = -1, i; - fpc = CALLOC(1, sizeof(struct nv40_fpc)); - if (!fpc) - return; - fpc->fp = fp; - fpc->high_temp = -1; - fpc->num_regs = 2; + tgsi_parse_init(&p, fpc->fp->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; - tgsi_parse_init(&parse, fp->pipe.tokens); - - while (!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { + tgsi_parse_token(&p); + switch(tok->Token.Type) { case TGSI_TOKEN_TYPE_DECLARATION: { const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; + fdec = &p.FullToken.FullDeclaration; switch (fdec->Declaration.File) { case TGSI_FILE_INPUT: if (!nv40_fragprog_parse_decl_attrib(fpc, fdec)) @@ -767,6 +769,12 @@ nv40_fragprog_translate(struct nv40_context *nv40, if (!nv40_fragprog_parse_decl_output(fpc, fdec)) goto out_err; break; + case TGSI_FILE_TEMPORARY: + if (fdec->u.DeclarationRange.Last > high_temp) { + high_temp = + fdec->u.DeclarationRange.Last; + } + break; default: break; } @@ -777,7 +785,7 @@ nv40_fragprog_translate(struct nv40_context *nv40, struct tgsi_full_immediate *imm; float vals[4]; - imm = &parse.FullToken.FullImmediate; + imm = &p.FullToken.FullImmediate; assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); assert(fpc->nr_imm < MAX_IMM); @@ -788,6 +796,52 @@ nv40_fragprog_translate(struct nv40_context *nv40, fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals); } break; + default: + break; + } + } + tgsi_parse_free(&p); + + if (++high_temp) { + fpc->r_temp = CALLOC(high_temp, sizeof(struct nv40_sreg)); + for (i = 0; i < high_temp; i++) + fpc->r_temp[i] = temp(fpc); + fpc->r_temps_discard = 0; + } + + return TRUE; + +out_err: + if (fpc->r_temp) + FREE(fpc->r_temp); + tgsi_parse_free(&p); + return FALSE; +} + +static void +nv40_fragprog_translate(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + struct tgsi_parse_context parse; + struct nv40_fpc *fpc = NULL; + + fpc = CALLOC(1, sizeof(struct nv40_fpc)); + if (!fpc) + return; + fpc->fp = fp; + fpc->num_regs = 2; + + if (!nv40_fragprog_prepare(fpc)) { + FREE(fpc); + return; + } + + tgsi_parse_init(&parse, fp->pipe.tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { case TGSI_TOKEN_TYPE_INSTRUCTION: { const struct tgsi_full_instruction *finst; @@ -818,6 +872,8 @@ nv40_fragprog_translate(struct nv40_context *nv40, fp->translated = TRUE; out_err: tgsi_parse_free(&parse); + if (fpc->r_temp) + FREE(fpc->r_temp); FREE(fpc); } -- cgit v1.2.3 From e1ad8c232ba31985a6f9e5b76279f2f131312d1d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 18:20:04 +1100 Subject: nv40: fix fp depth write --- src/gallium/drivers/nv40/nv40_fragprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 6d8a29ed9c..87bca41cf6 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -724,7 +724,7 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, hw = 1; break; case TGSI_SEMANTIC_COLOR: - switch (idx) { + switch (fdec->Semantic.SemanticIndex) { case 0: hw = 0; break; case 1: hw = 2; break; case 2: hw = 3; break; -- cgit v1.2.3 From 17491ea27ffa6b48e31c0ad6ad6f795dd000c476 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 19:08:59 +1100 Subject: nv40: vp reg changes similar to recent fp changes --- src/gallium/drivers/nv40/nv40_vertprog.c | 106 +++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 20 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 385c8aa078..e5ce894375 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -42,10 +42,11 @@ struct nv40_vpc { struct nv40_vertex_program_exec *vpi; - unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; - - int high_temp; - int temp_temp_count; + unsigned r_temps; + unsigned r_temps_discard; + struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS]; + struct nv40_sreg *r_address; + struct nv40_sreg *r_temp; struct nv40_sreg *imm; unsigned nr_imm; @@ -54,13 +55,26 @@ struct nv40_vpc { static struct nv40_sreg temp(struct nv40_vpc *vpc) { - int idx; + int idx = ffs(~vpc->r_temps) - 1; + + if (idx < 0) { + NOUVEAU_ERR("out of temps!!\n"); + assert(0); + return nv40_sr(NV40SR_TEMP, 0); + } - idx = vpc->temp_temp_count++; - idx += vpc->high_temp + 1; + vpc->r_temps |= (1 << idx); + vpc->r_temps_discard |= (1 << idx); return nv40_sr(NV40SR_TEMP, idx); } +static INLINE void +release_temps(struct nv40_vpc *vpc) +{ + vpc->r_temps &= ~vpc->r_temps_discard; + vpc->r_temps_discard = 0; +} + static struct nv40_sreg constant(struct nv40_vpc *vpc, int pipe, float x, float y, float z, float w) { @@ -257,9 +271,7 @@ tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) { src = vpc->imm[fsrc->SrcRegister.Index]; break; case TGSI_FILE_TEMPORARY: - if (vpc->high_temp < fsrc->SrcRegister.Index) - vpc->high_temp = fsrc->SrcRegister.Index; - src = nv40_sr(NV40SR_TEMP, fsrc->SrcRegister.Index); + src = vpc->r_temp[fsrc->SrcRegister.Index]; break; default: NOUVEAU_ERR("bad src file\n"); @@ -281,14 +293,13 @@ tgsi_dst(struct nv40_vpc *vpc, const struct tgsi_full_dst_register *fdst) { switch (fdst->DstRegister.File) { case TGSI_FILE_OUTPUT: - dst = nv40_sr(NV40SR_OUTPUT, - vpc->output_map[fdst->DstRegister.Index]); - + dst = vpc->r_result[fdst->DstRegister.Index]; break; case TGSI_FILE_TEMPORARY: - dst = nv40_sr(NV40SR_TEMP, fdst->DstRegister.Index); - if (vpc->high_temp < dst.index) - vpc->high_temp = dst.index; + dst = vpc->r_temp[fdst->DstRegister.Index]; + break; + case TGSI_FILE_ADDRESS: + dst = vpc->r_address[fdst->DstRegister.Index]; break; default: NOUVEAU_ERR("bad dst file\n"); @@ -323,7 +334,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, if (finst->Instruction.Opcode == TGSI_OPCODE_END) return TRUE; - vpc->temp_temp_count = 0; for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *fsrc; @@ -471,6 +481,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, return FALSE; } + release_temps(vpc); return TRUE; } @@ -478,6 +489,7 @@ static boolean nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, const struct tgsi_full_declaration *fdec) { + unsigned idx = fdec->u.DeclarationRange.First; int hw; switch (fdec->Semantic.SemanticName) { @@ -525,7 +537,7 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, return FALSE; } - vpc->output_map[fdec->u.DeclarationRange.First] = hw; + vpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw); return TRUE; } @@ -533,7 +545,7 @@ static boolean nv40_vertprog_prepare(struct nv40_vpc *vpc) { struct tgsi_parse_context p; - int nr_imm = 0; + int high_temp = -1, high_addr = -1, nr_imm = 0, i; tgsi_parse_init(&p, vpc->vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&p)) { @@ -544,6 +556,48 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) case TGSI_TOKEN_TYPE_IMMEDIATE: nr_imm++; break; + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + + fdec = &p.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_TEMPORARY: + if (fdec->u.DeclarationRange.Last > high_temp) { + high_temp = + fdec->u.DeclarationRange.Last; + } + break; +#if 0 /* this would be nice.. except gallium doesn't track it */ + case TGSI_FILE_ADDRESS: + if (fdec->u.DeclarationRange.Last > high_addr) { + high_addr = + fdec->u.DeclarationRange.Last; + } + break; +#endif + default: + break; + } + } + break; +#if 1 /* yay, parse instructions looking for address regs instead */ + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + const struct tgsi_full_dst_register *fdst; + + finst = &p.FullToken.FullInstruction; + fdst = &finst->FullDstRegisters[0]; + + if (fdst->DstRegister.File == TGSI_FILE_ADDRESS) { + if (fdst->DstRegister.Index > high_addr) + high_addr = fdst->DstRegister.Index; + } + + } + break; +#endif default: break; } @@ -555,6 +609,19 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) assert(vpc->imm); } + if (++high_temp) { + vpc->r_temp = CALLOC(high_temp, sizeof(struct nv40_sreg)); + for (i = 0; i < high_temp; i++) + vpc->r_temp[i] = temp(vpc); + } + + if (++high_addr) { + vpc->r_address = CALLOC(high_addr, sizeof(struct nv40_sreg)); + for (i = 0; i < high_addr; i++) + vpc->r_address[i] = temp(vpc); + } + + vpc->r_temps_discard = 0; return TRUE; } @@ -569,7 +636,6 @@ nv40_vertprog_translate(struct nv40_context *nv40, if (!vpc) return; vpc->vp = vp; - vpc->high_temp = -1; if (!nv40_vertprog_prepare(vpc)) { FREE(vpc); -- cgit v1.2.3 From 799d3bce06e998e51ad8df6bcadeb41bd061801e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:41:40 +1100 Subject: nv40: respect rasterizer cso bypass_clipping flag --- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_state_viewport.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 02ca20b801..b50f6f8fef 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -97,6 +97,7 @@ struct nv40_blend_state { struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; + unsigned viewport_bypass; unsigned fp_samplers; uint64_t dirty; diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9e5c7a72a7..1b6248e5b8 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -5,8 +5,20 @@ nv40_state_viewport_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; + unsigned bypass; - if (nv40->render_mode == HW) { + if (nv40->render_mode == HW && !nv40->rasterizer->pipe.bypass_clipping) + bypass = 0; + else + bypass = 1; + + if (nv40->state.hw[NV40_STATE_VIEWPORT] && + (bypass || !(nv40->dirty & NV40_NEW_VIEWPORT)) && + nv40->state.viewport_bypass == bypass) + return FALSE; + nv40->state.viewport_bypass = bypass; + + if (!bypass) { so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); @@ -48,7 +60,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) struct nv40_state_entry nv40_state_viewport = { .validate = nv40_state_viewport_validate, .dirty = { - .pipe = NV40_NEW_VIEWPORT, + .pipe = NV40_NEW_VIEWPORT | NV40_NEW_RAST, .hw = NV40_STATE_VIEWPORT } }; -- cgit v1.2.3 From 5ce37d42b3268102caf8225be4ca18418bfab7c4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:45:38 +1100 Subject: nv40: maintain pipe_surface status field --- src/gallium/drivers/nv40/nv40_clear.c | 1 + src/gallium/drivers/nv40/nv40_state_emit.c | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c index 2c4e8f01fd..59efd620e3 100644 --- a/src/gallium/drivers/nv40/nv40_clear.c +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -9,4 +9,5 @@ nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + ps->status = PIPE_SURFACE_STATUS_CLEAR; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 056238cc83..a9a9abc922 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -40,6 +40,14 @@ static void nv40_state_do_validate(struct nv40_context *nv40, struct nv40_state_entry **states) { + const struct pipe_framebuffer_state *fb = &nv40->framebuffer; + unsigned i; + + for (i = 0; i < fb->num_cbufs; i++) + fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; + if (fb->zsbuf) + fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; + while (*states) { struct nv40_state_entry *e = *states; -- cgit v1.2.3 From ce64778ed1f436d81178862dc0032dfd16b4b7de Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 25 Mar 2008 12:57:36 +1100 Subject: nv40: respect do_flip in surface_copy() --- src/gallium/drivers/nv40/nv40_surface.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index e8a6011696..c0d135eb36 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -42,8 +42,20 @@ nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_winsys *nvws = nv40->nvws; - nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, - width, height); + if (do_flip) { + /*XXX: This dodgyness will do for now for correctness. But, + * need to investigate whether the 2D engine is able to + * manage a flip (perhaps SIFM?), if not, use the 3D engine + */ + desty += height; + while (height--) { + nvws->surface_copy(nvws, dest, destx, desty--, src, + srcx, srcy++, width, 1); + } + } else { + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); + } } static void -- cgit v1.2.3 From 3017999d9bee8f9d2ef170c1bb6926aab8e08393 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 19:00:07 +1000 Subject: nv40: vp const/immd fix --- src/gallium/drivers/nv40/nv40_vertprog.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index e5ce894375..41885b9d4a 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -328,7 +328,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, struct nv40_sreg src[3], dst, tmp; struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); int mask; - int ai = -1, ci = -1; + int ai = -1, ci = -1, ii = -1; int i; if (finst->Instruction.Opcode == TGSI_OPCODE_END) @@ -358,12 +358,9 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, tgsi_src(vpc, fsrc), none, none); } break; - /*XXX: index comparison is broken now that consts come from - * two different register files. - */ case TGSI_FILE_CONSTANT: - case TGSI_FILE_IMMEDIATE: - if (ci == -1 || ci == fsrc->SrcRegister.Index) { + if ((ci == -1 && ii == -1) || + ci == fsrc->SrcRegister.Index) { ci = fsrc->SrcRegister.Index; src[i] = tgsi_src(vpc, fsrc); } else { @@ -372,6 +369,17 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, tgsi_src(vpc, fsrc), none, none); } break; + case TGSI_FILE_IMMEDIATE: + if ((ci == -1 && ii == -1) || + ii == fsrc->SrcRegister.Index) { + ii = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; case TGSI_FILE_TEMPORARY: /* handled above */ break; -- cgit v1.2.3 From 68395f6726183a0776e324b900e429449ede2b22 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 19:08:59 +1000 Subject: nv40: vp 1/0/- swz --- src/gallium/drivers/nv40/nv40_vertprog.c | 74 +++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 41885b9d4a..40ef7174a4 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -4,13 +4,13 @@ #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" #include "nv40_context.h" #include "nv40_state.h" /* TODO (at least...): * 1. Indexed consts + ARL - * 2. Arb. swz/negation * 3. NV_vp11, NV_vp2, NV_vp3 features * - extra arith opcodes * - branching @@ -321,6 +321,66 @@ tgsi_mask(uint tgsi) return mask; } +static boolean +src_native_swz(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc, + struct nv40_sreg *src) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg tgsi = tgsi_src(vpc, fsrc); + uint mask = 0, zero_mask = 0, one_mask = 0, neg_mask = 0; + uint neg[4] = { fsrc->SrcRegisterExtSwz.NegateX, + fsrc->SrcRegisterExtSwz.NegateY, + fsrc->SrcRegisterExtSwz.NegateZ, + fsrc->SrcRegisterExtSwz.NegateW }; + uint c; + + for (c = 0; c < 4; c++) { + switch (tgsi_util_get_full_src_register_extswizzle(fsrc, c)) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + mask |= tgsi_mask(1 << c); + break; + case TGSI_EXTSWIZZLE_ZERO: + zero_mask |= tgsi_mask(1 << c); + tgsi.swz[c] = SWZ_X; + break; + case TGSI_EXTSWIZZLE_ONE: + one_mask |= tgsi_mask(1 << c); + tgsi.swz[c] = SWZ_X; + break; + default: + assert(0); + } + + if (!tgsi.negate && neg[c]) + neg_mask |= tgsi_mask(1 << c); + } + + if (mask == MASK_ALL && !neg_mask) + return TRUE; + + *src = temp(vpc); + + if (mask) + arith(vpc, 0, OP_MOV, *src, mask, tgsi, none, none); + + if (zero_mask) + arith(vpc, 0, OP_SFL, *src, zero_mask, *src, none, none); + + if (one_mask) + arith(vpc, 0, OP_STR, *src, one_mask, *src, none, none); + + if (neg_mask) { + struct nv40_sreg one = temp(vpc); + arith(vpc, 0, OP_STR, one, neg_mask, one, none, none); + arith(vpc, 0, OP_MUL, *src, neg_mask, *src, neg(one), none); + } + + return FALSE; +} + static boolean nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, const struct tgsi_full_instruction *finst) @@ -347,6 +407,18 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc; fsrc = &finst->FullSrcRegisters[i]; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + if (!src_native_swz(vpc, fsrc, &src[i])) + continue; + break; + default: + break; + } + switch (fsrc->SrcRegister.File) { case TGSI_FILE_INPUT: if (ai == -1 || ai == fsrc->SrcRegister.Index) { -- cgit v1.2.3 From bbefb541ad94382debb0f7a8daa636729799a31a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 20:32:22 +1000 Subject: nouveau: adapt to recent gallium changes --- src/gallium/drivers/nv40/nv40_context.c | 17 +++-------------- src/gallium/drivers/nv40/nv40_draw.c | 4 ++-- src/gallium/drivers/nv40/nv40_query.c | 2 +- src/gallium/drivers/nv40/nv40_screen.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 20 ++++++++++---------- src/gallium/drivers/nv40/nv40_state_emit.c | 4 ++-- src/gallium/drivers/nv40/nv40_vbo.c | 4 ++-- 7 files changed, 21 insertions(+), 32 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 7fcf8b8619..f9c93f7a2d 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -7,10 +7,10 @@ #include "nv40_screen.h" static void -nv40_flush(struct pipe_context *pipe, unsigned flags) +nv40_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_winsys *nvws = nv40->nvws; if (flags & PIPE_FLUSH_TEXTURE_CACHE) { BEGIN_RING(curie, 0x1fd8, 1); @@ -19,18 +19,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) OUT_RING (1); } - if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv40->screen->sync, 0); - BEGIN_RING(curie, 0x104, 1); - OUT_RING (0); - BEGIN_RING(curie, 0x100, 1); - OUT_RING (0); - } - - FIRE_RING(); - - if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv40->screen->sync, 0, 0, 2000); + FIRE_RING(fence); } static void diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index d05e5ad193..9cd8fa6a49 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -89,7 +89,7 @@ nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, NOUVEAU_ERR("AIII, missed flush\n"); assert(0); } - FIRE_RING(); + FIRE_RING(NULL); nv40_state_emit(nv40); } @@ -275,7 +275,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); draw_flush(nv40->draw); - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 15961591b9..57f39cfab0 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -75,7 +75,7 @@ nv40_query_end(struct pipe_context *pipe, struct pipe_query *pq) BEGIN_RING(curie, NV40TCL_QUERY_GET, 1); OUT_RING ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) | ((q->object->start * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT)); - FIRE_RING(); + FIRE_RING(NULL); } static boolean diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 75b965bb9d..e98005f749 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -266,7 +266,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so_emit(nvws, so); so_ref(NULL, &so); - nvws->push_flush(nvws, 0); + nvws->push_flush(nvws, 0, NULL); screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 3eafbece30..1417c95e75 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -660,26 +660,26 @@ nv40_set_viewport_state(struct pipe_context *pipe, } static void -nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_buffer *vb) +nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_buffer(nv40->draw, index, vb); + draw_set_vertex_buffers(nv40->draw, count, vb); - nv40->vtxbuf[index] = *vb; + memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count); nv40->dirty |= NV40_NEW_ARRAYS; } static void -nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_element *ve) +nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_element(nv40->draw, index, ve); + draw_set_vertex_elements(nv40->draw, count, ve); - nv40->vtxelt[index] = *ve; + memcpy(nv40->vtxelt, ve, sizeof(*ve) * count); nv40->dirty |= NV40_NEW_ARRAYS; } @@ -722,7 +722,7 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.set_scissor_state = nv40_set_scissor_state; nv40->pipe.set_viewport_state = nv40_set_viewport_state; - nv40->pipe.set_vertex_buffer = nv40_set_vertex_buffer; - nv40->pipe.set_vertex_element = nv40_set_vertex_element; + nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers; + nv40->pipe.set_vertex_elements = nv40_set_vertex_elements; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a9a9abc922..74feb6d4bf 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -123,7 +123,7 @@ nv40_state_validate(struct nv40_context *nv40) return FALSE; /* Attempt to go to hwtnl again */ - nv40->pipe.flush(&nv40->pipe, 0); + nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | NV40_NEW_ARRAYS | @@ -147,7 +147,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) /* Setup for swtnl */ if (nv40->render_mode == HW) { NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); - nv40->pipe.flush(&nv40->pipe, 0); + nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | NV40_NEW_ARRAYS | diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 4fae10f74b..b66bf26afb 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -209,7 +209,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (0); - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } @@ -384,7 +384,7 @@ nv40_draw_elements(struct pipe_context *pipe, mode, start, count); } - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } -- cgit v1.2.3 From 833b1fb152851ba0d4fa2a5ba4702ee98d9bc217 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 05:13:06 +1000 Subject: nv40: mark fp dirty even when only consts updated Fixes arbfplight "sticking". --- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 87bca41cf6..4b7667e038 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -919,6 +919,7 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; + boolean new_consts = FALSE; int i; if (fp->translated) @@ -945,7 +946,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) update_constants: if (fp->nr_consts) { - boolean new_consts = FALSE; float *map; map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); @@ -965,7 +965,7 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { + if (new_consts || fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]); return TRUE; } -- cgit v1.2.3 From 6806519a0b2a8af0c950f71705b02e13876d460f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 06:35:43 +1000 Subject: nv40: track current scissor enable/disable state Not sure how this was forgotten :) Anyhow, fixes gearbox/bzflag/xmoto, probably other things that use scissored clears / hit the nasty clear-with-quad path. --- src/gallium/drivers/nv40/nv40_state_scissor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 9e9eadc511..285239ef41 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -10,10 +10,11 @@ nv40_state_scissor_validate(struct nv40_context *nv40) if (nv40->state.hw[NV40_STATE_SCISSOR] && (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) return FALSE; + nv40->state.scissor_enabled = rast->scissor; so = so_new(3, 0); so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2); - if (rast->scissor) { + if (nv40->state.scissor_enabled) { so_data (so, ((s->maxx - s->minx) << 16) | s->minx); so_data (so, ((s->maxy - s->miny) << 16) | s->miny); } else { -- cgit v1.2.3 From 169faae6db9a289c5a2d9430d85c36ac36abd218 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 09:00:25 +1000 Subject: nv40: support vp clip distance regs, unused currently. --- src/gallium/drivers/nv40/nv40_state.h | 1 + src/gallium/drivers/nv40/nv40_vertprog.c | 106 ++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index ab2866eb7a..e018464c9f 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -42,6 +42,7 @@ struct nv40_vertex_program { uint32_t ir; uint32_t or; + uint32_t clip_ctrl; struct nouveau_stateobj *so; }; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 40ef7174a4..5906280e5e 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -37,6 +37,8 @@ #define neg(s) nv40_sr_neg((s)) #define abs(s) nv40_sr_abs((s)) +#define NV40_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n)) + struct nv40_vpc { struct nv40_vertex_program *vp; @@ -200,6 +202,36 @@ emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst) case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break; case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break; case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break; + case NV40_VP_INST_DEST_CLIP(0): + vp->or |= (1 << 6); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE0; + dst.index = NV40_VP_INST_DEST_FOGC; + break; + case NV40_VP_INST_DEST_CLIP(1): + vp->or |= (1 << 7); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE1; + dst.index = NV40_VP_INST_DEST_FOGC; + break; + case NV40_VP_INST_DEST_CLIP(2): + vp->or |= (1 << 8); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE2; + dst.index = NV40_VP_INST_DEST_FOGC; + break; + case NV40_VP_INST_DEST_CLIP(3): + vp->or |= (1 << 9); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE3; + dst.index = NV40_VP_INST_DEST_PSZ; + break; + case NV40_VP_INST_DEST_CLIP(4): + vp->or |= (1 << 10); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE4; + dst.index = NV40_VP_INST_DEST_PSZ; + break; + case NV40_VP_INST_DEST_CLIP(5): + vp->or |= (1 << 11); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE5; + dst.index = NV40_VP_INST_DEST_PSZ; + break; default: break; } @@ -391,6 +423,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, int ai = -1, ci = -1, ii = -1; int i; + struct { + struct nv40_sreg dst; + unsigned c, m; + } clip; + if (finst->Instruction.Opcode == TGSI_OPCODE_END) return TRUE; @@ -464,6 +501,51 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + /* If writing to clip distance regs, need to modify instruction to + * change which component is written to. On NV40 the clip regs + * are the unused components (yzw) of FOGC/PSZ + */ + clip.dst = none; + if (dst.type == NV40SR_OUTPUT && + dst.index >= NV40_VP_INST_DEST_CLIP(0) && + dst.index <= NV40_VP_INST_DEST_CLIP(5)) { + unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0); + unsigned c[] = { SWZ_Y, SWZ_Z, SWZ_W, SWZ_Y, SWZ_Z, SWZ_W }; + unsigned m[] = + { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W }; + + /* Some instructions we can get away with swizzling and/or + * changing the writemask. Others, we'll use a temp reg. + */ + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_DST: + case TGSI_OPCODE_EXP: + case TGSI_OPCODE_LIT: + case TGSI_OPCODE_LOG: + case TGSI_OPCODE_XPD: + clip.dst = dst; + clip.c = c[n]; + clip.m = m[n]; + dst = temp(vpc); + break; + case TGSI_OPCODE_DP3: + case TGSI_OPCODE_DP4: + case TGSI_OPCODE_DPH: + case TGSI_OPCODE_POW: + case TGSI_OPCODE_RCP: + case TGSI_OPCODE_RSQ: + mask = m[n]; + break; + default: + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + src[i] = nv40_sr_swz(src[i], + c[n], c[n], c[n], c[n]); + } + mask = m[n]; + break; + } + } + switch (finst->Instruction.Opcode) { case TGSI_OPCODE_ABS: arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); @@ -561,6 +643,12 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, return FALSE; } + if (clip.dst.type != NV40SR_NONE) { + arith(vpc, 0, OP_MOV, clip.dst, clip.m, + nv40_sr_swz(dst, clip.c, clip.c, clip.c, clip.c), + none, none); + } + release_temps(vpc); return TRUE; } @@ -612,6 +700,15 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, return FALSE; } break; +#if 0 + case TGSI_SEMANTIC_CLIP: + if (fdec->Semantic.SemanticIndex >= 6) { + NOUVEAU_ERR("bad clip distance index\n"); + return FALSE; + } + hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex); + break; +#endif default: NOUVEAU_ERR("bad output semantic\n"); return FALSE; @@ -782,6 +879,7 @@ nv40_vertprog_validate(struct nv40_context *nv40) { struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_grobj *curie = nv40->screen->curie; struct nv40_vertex_program *vp; struct pipe_buffer *constbuf; boolean upload_code = FALSE, upload_data = FALSE; @@ -825,12 +923,14 @@ check_gpu_resources: assert(0); } - so = so_new(5, 0); - so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1); + so = so_new(7, 0); + so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2); so_data (so, vp->ir); so_data (so, vp->or); + so_method(so, curie, NV40TCL_CLIP_PLANE_ENABLE, 1); + so_data (so, vp->clip_ctrl); so_ref(so, &vp->so); upload_code = TRUE; -- cgit v1.2.3 From 4ad9dd6179787a46ecb223ab0e59e6b25b9368af Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 09:29:22 +1000 Subject: nouveau: update object header --- src/gallium/drivers/nv40/nv40_vbo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index b66bf26afb..bc53924a67 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -32,7 +32,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) case PIPE_FORMAT_R16G16_SSCALED: case PIPE_FORMAT_R16G16B16_SSCALED: case PIPE_FORMAT_R16G16B16A16_SSCALED: - *fmt = 5; + *fmt = NV40TCL_VTXFMT_TYPE_USHORT; break; default: pf_sprint_name(fs, pipe); -- cgit v1.2.3 From e616d3f3e2178e34e4e7d769b38b0dff4ad615fe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 09:37:57 +1000 Subject: nv40: fix slight thinko --- src/gallium/drivers/nv40/nv40_vertprog.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 5906280e5e..08d3f387e0 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -425,7 +425,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, struct { struct nv40_sreg dst; - unsigned c, m; + unsigned m; } clip; if (finst->Instruction.Opcode == TGSI_OPCODE_END) @@ -503,14 +503,13 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, /* If writing to clip distance regs, need to modify instruction to * change which component is written to. On NV40 the clip regs - * are the unused components (yzw) of FOGC/PSZ + * are the unused components (yzw) of FOGC/PSZ. */ clip.dst = none; if (dst.type == NV40SR_OUTPUT && dst.index >= NV40_VP_INST_DEST_CLIP(0) && dst.index <= NV40_VP_INST_DEST_CLIP(5)) { unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0); - unsigned c[] = { SWZ_Y, SWZ_Z, SWZ_W, SWZ_Y, SWZ_Z, SWZ_W }; unsigned m[] = { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W }; @@ -524,7 +523,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, case TGSI_OPCODE_LOG: case TGSI_OPCODE_XPD: clip.dst = dst; - clip.c = c[n]; clip.m = m[n]; dst = temp(vpc); break; @@ -537,10 +535,8 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, mask = m[n]; break; default: - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { - src[i] = nv40_sr_swz(src[i], - c[n], c[n], c[n], c[n]); - } + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) + src[i] = swz(src[i], X, X, X, X); mask = m[n]; break; } @@ -645,8 +641,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, if (clip.dst.type != NV40SR_NONE) { arith(vpc, 0, OP_MOV, clip.dst, clip.m, - nv40_sr_swz(dst, clip.c, clip.c, clip.c, clip.c), - none, none); + swz(dst, X, X, X, X), none, none); } release_temps(vpc); -- cgit v1.2.3 From bdf5b23bfd222ade9b3599ebd0f8932a5179431e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Apr 2008 12:54:37 +1000 Subject: nv40: shorten zsa state lines --- src/gallium/drivers/nv40/nv40_state.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 1417c95e75..89f4078b72 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -445,19 +445,20 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *curie = nv40->screen->curie; - so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3); + so_method(so, curie, NV40TCL_DEPTH_FUNC, 3); so_data (so, nvgl_comparison_op(cso->depth.func)); so_data (so, cso->depth.writemask ? 1 : 0); so_data (so, cso->depth.enabled ? 1 : 0); - so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3); so_data (so, cso->alpha.enabled ? 1 : 0); so_data (so, nvgl_comparison_op(cso->alpha.func)); so_data (so, float_to_ubyte(cso->alpha.ref)); if (cso->stencil[0].enabled) { - so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); so_data (so, cso->stencil[0].enabled ? 1 : 0); so_data (so, cso->stencil[0].write_mask); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); @@ -467,12 +468,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); } else { - so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8); so_data (so, cso->stencil[1].enabled ? 1 : 0); so_data (so, cso->stencil[1].write_mask); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); @@ -482,7 +483,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); } else { - so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1); so_data (so, 0); } -- cgit v1.2.3 From ae87909d0d261d0f4e888f6a167e6329eb129a87 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Apr 2008 13:04:06 +1000 Subject: nv40: only update draw module state when using swtnl --- src/gallium/drivers/nv40/nv40_context.h | 6 ++++-- src/gallium/drivers/nv40/nv40_state.c | 22 ++++++++++------------ src/gallium/drivers/nv40/nv40_state_emit.c | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index b50f6f8fef..525eef8d63 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -133,7 +133,7 @@ struct nv40_context { unsigned fallback_swrast; /* Context state */ - unsigned dirty; + unsigned dirty, draw_dirty; struct pipe_scissor_state scissor; unsigned stipple[32]; struct pipe_clip_state clip; @@ -153,8 +153,10 @@ struct nv40_context { unsigned nr_samplers; unsigned nr_textures; unsigned dirty_samplers; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + unsigned vtxbuf_nr; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; + unsigned vtxelt_nr; }; static INLINE struct nv40_context * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 89f4078b72..5dc2991212 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -423,10 +423,9 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = hwcso; - draw_set_rasterizer_state(nv40->draw, &rsso->pipe); - nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; + nv40->draw_dirty |= NV40_NEW_RAST; } static void @@ -530,10 +529,9 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) struct nv40_context *nv40 = nv40_context(pipe); struct nv40_vertex_program *vp = hwcso; - draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL); - nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; + nv40->draw_dirty |= NV40_NEW_VERTPROG; } static void @@ -596,10 +594,9 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_clip_state(nv40->draw, clip); - nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; + nv40->draw_dirty |= NV40_NEW_UCP; } static void @@ -654,10 +651,9 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_viewport_state(nv40->draw, vpt); - nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; + nv40->draw_dirty |= NV40_NEW_VIEWPORT; } static void @@ -666,10 +662,11 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_buffers(nv40->draw, count, vb); - memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count); + nv40->vtxbuf_nr = count; + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; } static void @@ -678,10 +675,11 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_elements(nv40->draw, count, ve); - memcpy(nv40->vtxelt, ve, sizeof(*ve) * count); + nv40->vtxelt_nr = count; + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; } void diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 74feb6d4bf..722b9f31e6 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -144,6 +144,8 @@ nv40_state_validate(struct nv40_context *nv40) boolean nv40_state_validate_swtnl(struct nv40_context *nv40) { + struct draw_context *draw = nv40->draw; + /* Setup for swtnl */ if (nv40->render_mode == HW) { NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); @@ -155,12 +157,30 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) nv40->render_mode = SWTNL; } + if (nv40->draw_dirty & NV40_NEW_VERTPROG) + draw_bind_vertex_shader(draw, nv40->vertprog->draw); + + if (nv40->draw_dirty & NV40_NEW_RAST) + draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe); + + if (nv40->draw_dirty & NV40_NEW_UCP) + draw_set_clip_state(draw, &nv40->clip); + + if (nv40->draw_dirty & NV40_NEW_VIEWPORT) + draw_set_viewport_state(draw, &nv40->viewport); + + if (nv40->draw_dirty & NV40_NEW_ARRAYS) { + draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf); + draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt); + } + nv40_state_do_validate(nv40, swtnl_states); if (nv40->fallback_swrast) { NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast); return FALSE; } + nv40->draw_dirty = 0; return TRUE; } -- cgit v1.2.3 From 73322bba5c7102f0e100c9a07273a7a87705cf55 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 Mar 2008 23:51:24 +1100 Subject: nv40: need to resubmit buffers if pushbuf gets flushed during draw --- src/gallium/drivers/nv40/nv40_vbo.c | 120 +++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 44 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index bc53924a67..33d3efb58d 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -7,6 +7,7 @@ #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" +#include "nouveau/nouveau_util.h" #define FORCE_SWTNL 0 @@ -170,44 +171,60 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, } boolean -nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, - unsigned count) +nv40_draw_arrays(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); - unsigned nr; + struct nouveau_channel *chan = nv40->nvws->channel; + unsigned restart; nv40_vbo_set_idxbuf(nv40, NULL, 0); if (FORCE_SWTNL || !nv40_state_validate(nv40)) { return nv40_draw_elements_swtnl(pipe, NULL, 0, mode, start, count); } - nv40_state_emit(nv40); - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); + while (count) { + unsigned vc, nr; - nr = (count & 0xff); - if (nr) { - BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1); - OUT_RING (((nr - 1) << 24) | start); - start += nr; - } + nv40_state_emit(nv40); - nr = count >> 8; - while (nr) { - unsigned push = nr > 2047 ? 2047 : nr; + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); + continue; + } - nr -= push; + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); - BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push); - while (push--) { - OUT_RING(((0x100 - 1) << 24) | start); - start += 0x100; + nr = (vc & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; } - } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (0); + nr = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + count -= vc; + start = restart; + } pipe->flush(pipe, 0, NULL); return TRUE; @@ -329,35 +346,50 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); - unsigned nr; + struct nouveau_channel *chan = nv40->nvws->channel; + unsigned restart; - nv40_state_emit(nv40); + while (count) { + unsigned nr, vc; - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); + nv40_state_emit(nv40); - nr = (count & 0xff); - if (nr) { - BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1); - OUT_RING (((nr - 1) << 24) | start); - start += nr; - } + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); + continue; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (vc & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } - nr = count >> 8; - while (nr) { - unsigned push = nr > 2047 ? 2047 : nr; + nr = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; - nr -= push; + nr -= push; - BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push); - while (push--) { - OUT_RING(((0x100 - 1) << 24) | start); - start += 0x100; + BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } } - } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (0); + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + count -= vc; + start = restart; + } return TRUE; } -- cgit v1.2.3 From 7e9b83ac0ac59298f1b983e6a9aed3a8f2ccb147 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 29 Mar 2008 00:30:04 +1100 Subject: nv40: convert the inline idxbuf paths also --- src/gallium/drivers/nv40/nv40_vbo.c | 159 +++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 48 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 33d3efb58d..8cc977a19a 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -232,69 +232,139 @@ nv40_draw_arrays(struct pipe_context *pipe, static INLINE void nv40_draw_elements_u08(struct nv40_context *nv40, void *ib, - unsigned start, unsigned count) + unsigned mode, unsigned start, unsigned count) { - uint8_t *elts = (uint8_t *)ib + start; - int push, i; - - if (count & 1) { - BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); - OUT_RING (elts[0]); - elts++; count--; - } + struct nouveau_channel *chan = nv40->nvws->channel; while (count) { - push = MIN2(count, 2047 * 2); + uint8_t *elts = (uint8_t *)ib + start; + unsigned vc, push, restart; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + if (vc & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; vc--; + } + + while (vc) { + unsigned i; + + push = MIN2(vc, 2047 * 2); - BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); - for (i = 0; i < push; i+=2) - OUT_RING((elts[i+1] << 16) | elts[i]); + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); - count -= push; - elts += push; + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; } } static INLINE void nv40_draw_elements_u16(struct nv40_context *nv40, void *ib, - unsigned start, unsigned count) + unsigned mode, unsigned start, unsigned count) { - uint16_t *elts = (uint16_t *)ib + start; - int push, i; - - if (count & 1) { - BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); - OUT_RING (elts[0]); - elts++; count--; - } + struct nouveau_channel *chan = nv40->nvws->channel; while (count) { - push = MIN2(count, 2047 * 2); + uint16_t *elts = (uint16_t *)ib + start; + unsigned vc, push, restart; - BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); - for (i = 0; i < push; i+=2) - OUT_RING((elts[i+1] << 16) | elts[i]); + nv40_state_emit(nv40); - count -= push; - elts += push; + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + if (vc & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; vc--; + } + + while (vc) { + unsigned i; + + push = MIN2(vc, 2047 * 2); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; } } static INLINE void nv40_draw_elements_u32(struct nv40_context *nv40, void *ib, - unsigned start, unsigned count) + unsigned mode, unsigned start, unsigned count) { - uint32_t *elts = (uint32_t *)ib + start; - int push; + struct nouveau_channel *chan = nv40->nvws->channel; while (count) { - push = MIN2(count, 2047); + uint32_t *elts = (uint32_t *)ib + start; + unsigned vc, push, restart; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + while (vc) { + push = MIN2(vc, 2047); - BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push); - OUT_RINGp (elts, push); + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); - count -= push; - elts += push; + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; } } @@ -315,29 +385,22 @@ nv40_draw_elements_inline(struct pipe_context *pipe, return FALSE; } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); - switch (ib_size) { case 1: - nv40_draw_elements_u08(nv40, map, start, count); + nv40_draw_elements_u08(nv40, map, mode, start, count); break; case 2: - nv40_draw_elements_u16(nv40, map, start, count); + nv40_draw_elements_u16(nv40, map, mode, start, count); break; case 4: - nv40_draw_elements_u32(nv40, map, start, count); + nv40_draw_elements_u32(nv40, map, mode, start, count); break; default: NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); break; } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (0); - ws->buffer_unmap(ws, ib); - return TRUE; } -- cgit v1.2.3 From 6fbc50e013f1ac7684d8d63d9433f6dd72b4c1cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Apr 2008 08:21:56 +1000 Subject: nv40: static attribs -> stateobj --- src/gallium/drivers/nv40/nv40_context.h | 3 +- src/gallium/drivers/nv40/nv40_state_emit.c | 3 +- src/gallium/drivers/nv40/nv40_vbo.c | 62 ++++++++++++++++-------------- 3 files changed, 38 insertions(+), 30 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 525eef8d63..a1b5c88a06 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -56,7 +56,8 @@ enum nv40_state_index { NV40_STATE_VERTTEX3 = 30, NV40_STATE_VTXBUF = 31, NV40_STATE_VTXFMT = 32, - NV40_STATE_MAX = 33 + NV40_STATE_VTXATTR = 33, + NV40_STATE_MAX = 34 }; #include "nv40_screen.h" diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 722b9f31e6..c742e4f421 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -82,7 +82,8 @@ nv40_state_emit(struct nv40_context *nv40) if (!(states & (1ULL << i))) continue; so_ref (state->hw[i], &nv40->screen->state[i]); - so_emit(nv40->nvws, nv40->screen->state[i]); + if (state->hw[i]) + so_emit(nv40->nvws, nv40->screen->state[i]); states &= ~(1ULL << i); } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 8cc977a19a..e5ee5f3c47 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -109,11 +109,12 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, } static boolean -nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, - struct pipe_vertex_element *ve, +nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, + int attrib, struct pipe_vertex_element *ve, struct pipe_vertex_buffer *vb) { struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_grobj *curie = nv40->screen->curie; unsigned type, ncomp; void *map; @@ -128,31 +129,28 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, { float *v = map; - BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(attrib), 4); switch (ncomp) { case 4: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(v[2]); - OUT_RINGf(v[3]); + so_method(so, curie, NV40TCL_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: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(v[2]); - OUT_RINGf(1.0); + so_method(so, curie, NV40TCL_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: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(0.0); - OUT_RINGf(1.0); + so_method(so, curie, NV40TCL_VTX_ATTR_2F_X(attrib), 2); + so_data (so, fui(v[0])); + so_data (so, fui(v[1])); break; case 1: - OUT_RINGf(v[0]); - OUT_RINGf(0.0); - OUT_RINGf(0.0); - OUT_RINGf(1.0); + so_method(so, curie, 0x1e40 + (attrib * 4), 1); + so_data (so, fui(v[0])); break; default: ws->buffer_unmap(ws, vb->buffer); @@ -487,7 +485,8 @@ static boolean nv40_vbo_validate(struct nv40_context *nv40) { struct nv40_vertex_program *vp = nv40->vertprog; - struct nouveau_stateobj *vtxbuf, *vtxfmt; + struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL; + struct nouveau_grobj *curie = nv40->screen->curie; struct pipe_buffer *ib = nv40->idxbuf; unsigned ib_format = nv40->idxbuf_format; unsigned inputs, hw, num_hw; @@ -503,9 +502,9 @@ nv40_vbo_validate(struct nv40_context *nv40) num_hw++; vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->screen->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->screen->curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), num_hw); inputs = vp->ir; for (hw = 0; hw < num_hw; hw++) { @@ -522,10 +521,15 @@ nv40_vbo_validate(struct nv40_context *nv40) ve = &nv40->vtxelt[hw]; vb = &nv40->vtxbuf[ve->vertex_buffer_index]; - if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; + if (!vb->pitch) { + if (!sattr) + sattr = so_new(16 * 5, 0); + + if (nv40_vbo_static_attrib(nv40, sattr, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } } if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) { @@ -543,19 +547,21 @@ nv40_vbo_validate(struct nv40_context *nv40) } if (ib) { - so_method(vtxbuf, nv40->screen->curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_method(vtxbuf, curie, NV40TCL_IDXBUF_ADDRESS, 2); so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, 0, NV40TCL_IDXBUF_FORMAT_DMA1); } - so_method(vtxbuf, nv40->screen->curie, 0x1710, 1); + so_method(vtxbuf, curie, 0x1710, 1); so_data (vtxbuf, 0); so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]); nv40->state.dirty |= (1ULL << NV40_STATE_VTXBUF); so_ref(vtxfmt, &nv40->state.hw[NV40_STATE_VTXFMT]); nv40->state.dirty |= (1ULL << NV40_STATE_VTXFMT); + so_ref(sattr, &nv40->state.hw[NV40_STATE_VTXATTR]); + nv40->state.dirty |= (1ULL << NV40_STATE_VTXATTR); return FALSE; } -- cgit v1.2.3 From 0b57662fa6feb3d4571e4a3bc3a2243547595816 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Apr 2008 09:39:00 +1000 Subject: nv40: remove redundant state_emit() calls --- src/gallium/drivers/nv40/nv40_vbo.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index e5ee5f3c47..8c446936ea 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -375,8 +375,6 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - nv40_state_emit(nv40); - map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); @@ -468,7 +466,6 @@ nv40_draw_elements(struct pipe_context *pipe, return nv40_draw_elements_swtnl(pipe, NULL, 0, mode, start, count); } - nv40_state_emit(nv40); if (idxbuf) { nv40_draw_elements_vbo(pipe, mode, start, count); -- cgit v1.2.3 From fbb6cc7842ec8a59b60018233275babc4deb6765 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 12:39:45 +1000 Subject: nouveau: in some cases don't create the buffer in local mem initially. --- src/gallium/drivers/nv40/nv40_miptree.c | 4 +++- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 502edc1629..1b19217223 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -68,7 +68,9 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) nv40_miptree_layout(mt); - mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->buffer = ws->buffer_create(ws, 256, + PIPE_BUFFER_USAGE_PIXEL | + NOUVEAU_BUFFER_USAGE_TEXTURE, mt->total_size); if (!mt->buffer) { FREE(mt); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index e98005f749..a408d7262f 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -27,6 +27,8 @@ nv40_screen_get_vendor(struct pipe_screen *pscreen) static int nv40_screen_get_param(struct pipe_screen *pscreen, int param) { + struct nv40_screen *screen = nv40_screen(pscreen); + switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return 16; @@ -54,6 +56,12 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case NOUVEAU_CAP_HW_VTXBUF: + return 1; + case NOUVEAU_CAP_HW_IDXBUF: + if (screen->curie->grclass == NV40TCL) + return 1; + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; -- cgit v1.2.3 From a45a12e757a8f4d41daea2a3f632d4772ff69e38 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 13:02:37 +1000 Subject: nv40: have test for hw idxbuf in single place --- src/gallium/drivers/nv40/nv40_vbo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 8c446936ea..ec88470b31 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -75,6 +75,7 @@ static boolean nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned ib_size) { + struct pipe_screen *pscreen = &nv40->screen->pipe; unsigned type; if (!ib) { @@ -83,8 +84,7 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, return FALSE; } - /* No support for 8bit indices, no support at all on 0x4497 chips */ - if (nv40->screen->curie->grclass == NV44TCL || ib_size == 1) + if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1) return FALSE; switch (ib_size) { -- cgit v1.2.3 From 2946a5a012f494bad280a0ecf082d81ed4e89c3b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 20:32:06 +1000 Subject: nv40: kill some warnings --- src/gallium/drivers/nv40/nv40_state.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 5dc2991212..997beca883 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -421,7 +421,6 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_rasterizer_state *rsso = hwcso; nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; @@ -527,7 +526,6 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_vertex_program *vp = hwcso; nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; -- cgit v1.2.3 From 2655f6901289bcfe3835cf28d7b9eefa242045b8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Apr 2008 20:10:40 +1000 Subject: nv40: implement user clip planes It turns out the user planes handed to the driver are already in clip space. Hence, we no longer need to transform incoming vertices before computing the clip distance, and no longer need to change the interface provided by gallium. Yay :) The clip state change handling could be better, but this works. --- src/gallium/drivers/nv40/Makefile | 1 - src/gallium/drivers/nv40/nv40_context.h | 4 - src/gallium/drivers/nv40/nv40_draw.c | 2 +- src/gallium/drivers/nv40/nv40_state.h | 3 + src/gallium/drivers/nv40/nv40_state_clip.c | 22 ---- src/gallium/drivers/nv40/nv40_state_emit.c | 8 +- src/gallium/drivers/nv40/nv40_vertprog.c | 159 +++++++++++++++-------------- 7 files changed, 87 insertions(+), 112 deletions(-) delete mode 100644 src/gallium/drivers/nv40/nv40_state_clip.c (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 3369a21574..9c8eadf7e4 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -14,7 +14,6 @@ DRIVER_SOURCES = \ nv40_screen.c \ nv40_state.c \ nv40_state_blend.c \ - nv40_state_clip.c \ nv40_state_emit.c \ nv40_state_fb.c \ nv40_state_rasterizer.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index a1b5c88a06..436351b6bc 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -76,9 +76,6 @@ enum nv40_state_index { #define NV40_NEW_ARRAYS (1 << 11) #define NV40_NEW_UCP (1 << 12) -#define NV40_FALLBACK_TNL (1 << 0) -#define NV40_FALLBACK_RAST (1 << 1) - struct nv40_rasterizer_state { struct pipe_rasterizer_state pipe; struct nouveau_stateobj *so; @@ -203,7 +200,6 @@ extern void nv40_fragtex_bind(struct nv40_context *); extern boolean nv40_state_validate(struct nv40_context *nv40); extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40); extern void nv40_state_emit(struct nv40_context *nv40); -extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 9cd8fa6a49..7f008aca3a 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -236,7 +236,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, if (!nv40_state_validate_swtnl(nv40)) return FALSE; - nv40->dirty &= ~(1ULL << NV40_STATE_VTXBUF); + nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF); nv40_state_emit(nv40); for (i = 0; i < PIPE_ATTRIB_MAX; i++) { diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index e018464c9f..2b4225deb2 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -29,6 +29,9 @@ struct nv40_vertex_program { struct draw_vertex_shader *draw; boolean translated; + + struct pipe_clip_state ucp; + struct nv40_vertex_program_exec *insns; unsigned nr_insns; struct nv40_vertex_program_data *consts; diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c deleted file mode 100644 index c52390f9ed..0000000000 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "nv40_context.h" - -static boolean -nv40_state_clip_validate(struct nv40_context *nv40) -{ - - if (nv40->render_mode == HW) { - nv40->fallback_swtnl &= ~NV40_NEW_UCP; - if (nv40->clip.nr) - nv40->fallback_swtnl |= NV40_NEW_UCP; - } - - return FALSE; -} - -struct nv40_state_entry nv40_state_clip = { - .validate = nv40_state_clip_validate, - .dirty = { - .pipe = NV40_NEW_UCP, - .hw = 0 - } -}; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index c742e4f421..864dfc2e0c 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -5,7 +5,6 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_framebuffer, &nv40_state_rasterizer, - &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, @@ -22,7 +21,6 @@ static struct nv40_state_entry *render_states[] = { static struct nv40_state_entry *swtnl_states[] = { &nv40_state_framebuffer, &nv40_state_rasterizer, - &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, @@ -127,8 +125,7 @@ nv40_state_validate(struct nv40_context *nv40) nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | - NV40_NEW_ARRAYS | - NV40_NEW_UCP); + NV40_NEW_ARRAYS); nv40->render_mode = HW; } @@ -153,8 +150,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | - NV40_NEW_ARRAYS | - NV40_NEW_UCP); + NV40_NEW_ARRAYS); nv40->render_mode = SWTNL; } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 08d3f387e0..e10250528e 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -52,6 +52,8 @@ struct nv40_vpc { struct nv40_sreg *imm; unsigned nr_imm; + + unsigned hpos_idx; }; static struct nv40_sreg @@ -423,11 +425,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, int ai = -1, ci = -1, ii = -1; int i; - struct { - struct nv40_sreg dst; - unsigned m; - } clip; - if (finst->Instruction.Opcode == TGSI_OPCODE_END) return TRUE; @@ -501,47 +498,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); - /* If writing to clip distance regs, need to modify instruction to - * change which component is written to. On NV40 the clip regs - * are the unused components (yzw) of FOGC/PSZ. - */ - clip.dst = none; - if (dst.type == NV40SR_OUTPUT && - dst.index >= NV40_VP_INST_DEST_CLIP(0) && - dst.index <= NV40_VP_INST_DEST_CLIP(5)) { - unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0); - unsigned m[] = - { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W }; - - /* Some instructions we can get away with swizzling and/or - * changing the writemask. Others, we'll use a temp reg. - */ - switch (finst->Instruction.Opcode) { - case TGSI_OPCODE_DST: - case TGSI_OPCODE_EXP: - case TGSI_OPCODE_LIT: - case TGSI_OPCODE_LOG: - case TGSI_OPCODE_XPD: - clip.dst = dst; - clip.m = m[n]; - dst = temp(vpc); - break; - case TGSI_OPCODE_DP3: - case TGSI_OPCODE_DP4: - case TGSI_OPCODE_DPH: - case TGSI_OPCODE_POW: - case TGSI_OPCODE_RCP: - case TGSI_OPCODE_RSQ: - mask = m[n]; - break; - default: - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) - src[i] = swz(src[i], X, X, X, X); - mask = m[n]; - break; - } - } - switch (finst->Instruction.Opcode) { case TGSI_OPCODE_ABS: arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); @@ -639,11 +595,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, return FALSE; } - if (clip.dst.type != NV40SR_NONE) { - arith(vpc, 0, OP_MOV, clip.dst, clip.m, - swz(dst, X, X, X, X), none, none); - } - release_temps(vpc); return TRUE; } @@ -658,6 +609,7 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, switch (fdec->Semantic.SemanticName) { case TGSI_SEMANTIC_POSITION: hw = NV40_VP_INST_DEST_POS; + vpc->hpos_idx = idx; break; case TGSI_SEMANTIC_COLOR: if (fdec->Semantic.SemanticIndex == 0) { @@ -695,15 +647,6 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, return FALSE; } break; -#if 0 - case TGSI_SEMANTIC_CLIP: - if (fdec->Semantic.SemanticIndex >= 6) { - NOUVEAU_ERR("bad clip distance index\n"); - return FALSE; - } - hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex); - break; -#endif default: NOUVEAU_ERR("bad output semantic\n"); return FALSE; @@ -748,6 +691,10 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) } break; #endif + case TGSI_FILE_OUTPUT: + if (!nv40_vertprog_parse_decl_output(vpc, fdec)) + return FALSE; + break; default: break; } @@ -803,6 +750,8 @@ nv40_vertprog_translate(struct nv40_context *nv40, { struct tgsi_parse_context parse; struct nv40_vpc *vpc = NULL; + struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + int i; vpc = CALLOC(1, sizeof(struct nv40_vpc)); if (!vpc) @@ -814,26 +763,21 @@ nv40_vertprog_translate(struct nv40_context *nv40, return; } + /* Redirect post-transform vertex position to a temp if user clip + * planes are enabled. We need to append code the the vtxprog + * to handle clip planes later. + */ + if (vp->ucp.nr) { + vpc->r_result[vpc->hpos_idx] = temp(vpc); + vpc->r_temps_discard = 0; + } + tgsi_parse_init(&parse, vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - { - const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; - switch (fdec->Declaration.File) { - case TGSI_FILE_OUTPUT: - if (!nv40_vertprog_parse_decl_output(vpc, fdec)) - goto out_err; - break; - default: - break; - } - } - break; case TGSI_TOKEN_TYPE_IMMEDIATE: { const struct tgsi_full_immediate *imm; @@ -862,6 +806,39 @@ nv40_vertprog_translate(struct nv40_context *nv40, } } + /* Write out HPOS if it was redirected to a temp earlier */ + if (vpc->r_result[vpc->hpos_idx].type != NV40SR_OUTPUT) { + struct nv40_sreg hpos = nv40_sr(NV40SR_OUTPUT, + NV40_VP_INST_DEST_POS); + struct nv40_sreg htmp = vpc->r_result[vpc->hpos_idx]; + + arith(vpc, 0, OP_MOV, hpos, MASK_ALL, htmp, none, none); + } + + /* Insert code to handle user clip planes */ + for (i = 0; i < vp->ucp.nr; i++) { + struct nv40_sreg cdst = nv40_sr(NV40SR_OUTPUT, + NV40_VP_INST_DEST_CLIP(i)); + struct nv40_sreg ceqn = constant(vpc, -1, + nv40->clip.ucp[i][0], + nv40->clip.ucp[i][1], + nv40->clip.ucp[i][2], + nv40->clip.ucp[i][3]); + struct nv40_sreg htmp = vpc->r_result[vpc->hpos_idx]; + unsigned mask; + + switch (i) { + case 0: case 3: mask = MASK_Y; break; + case 1: case 4: mask = MASK_Z; break; + case 2: case 5: mask = MASK_W; break; + default: + NOUVEAU_ERR("invalid clip dist #%d\n", i); + goto out_err; + } + + arith(vpc, 0, OP_DP4, cdst, mask, htmp, ceqn, none); + } + vp->insns[vp->nr_insns - 1].data[3] |= NV40_VP_INST_LAST; vp->translated = TRUE; out_err: @@ -883,6 +860,12 @@ nv40_vertprog_validate(struct nv40_context *nv40) if (nv40->render_mode == HW) { vp = nv40->vertprog; constbuf = nv40->constbuf[PIPE_SHADER_VERTEX]; + + if ((nv40->dirty & NV40_NEW_UCP) || + memcmp(&nv40->clip, &vp->ucp, sizeof(vp->ucp))) { + nv40_vertprog_destroy(nv40, vp); + memcpy(&vp->ucp, &nv40->clip, sizeof(vp->ucp)); + } } else { vp = nv40->swtnl.vertprog; constbuf = NULL; @@ -1045,16 +1028,36 @@ check_gpu_resources: void nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) { - if (vp->nr_consts) - FREE(vp->consts); - if (vp->nr_insns) + struct nouveau_winsys *nvws = nv40->screen->nvws; + + vp->translated = FALSE; + + if (vp->nr_insns) { FREE(vp->insns); + vp->insns = NULL; + vp->nr_insns = 0; + } + + if (vp->nr_consts) { + FREE(vp->consts); + vp->consts = NULL; + vp->nr_consts = 0; + } + + nvws->res_free(&vp->exec); + vp->exec_start = 0; + nvws->res_free(&vp->data); + vp->data_start = 0; + vp->data_start_min = 0; + + vp->ir = vp->or = vp->clip_ctrl = 0; + so_ref(NULL, &vp->so); } struct nv40_state_entry nv40_state_vertprog = { .validate = nv40_vertprog_validate, .dirty = { - .pipe = NV40_NEW_VERTPROG, + .pipe = NV40_NEW_VERTPROG | NV40_NEW_UCP, .hw = NV40_STATE_VERTPROG, } }; -- cgit v1.2.3 From bdfcce47921cdd808740ee26e6781837351bad98 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 9 Apr 2008 13:58:51 +1000 Subject: nv40: use vb/ve counts rather than shader inputs for related loops --- src/gallium/drivers/nv40/nv40_draw.c | 9 ++------- src/gallium/drivers/nv40/nv40_vbo.c | 25 ++++--------------------- 2 files changed, 6 insertions(+), 28 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 7f008aca3a..dd5cc8fc99 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -239,9 +239,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF); nv40_state_emit(nv40); - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { - if (!nv40->vtxbuf[i].buffer) - continue; + for (i = 0; i < nv40->vtxbuf_nr; i++) { map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(nv40->draw, i, map); @@ -262,11 +260,8 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, draw_arrays(nv40->draw, mode, start, count); - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { - if (!nv40->vtxbuf[i].buffer) - continue; + for (i = 0; i < nv40->vtxbuf_nr; i++) ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); - } if (idxbuf) ws->buffer_unmap(ws, idxbuf); diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index ec88470b31..06374184b1 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -481,40 +481,23 @@ nv40_draw_elements(struct pipe_context *pipe, static boolean nv40_vbo_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL; struct nouveau_grobj *curie = nv40->screen->curie; struct pipe_buffer *ib = nv40->idxbuf; unsigned ib_format = nv40->idxbuf_format; - unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; - - inputs = vp->ir; - for (hw = 0; hw < 16 && inputs; hw++) { - if (inputs & (1 << hw)) { - num_hw = hw; - inputs &= ~(1 << hw); - } - } - num_hw++; + int hw; vtxbuf = so_new(20, 18); - so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr); vtxfmt = so_new(17, 0); - so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr); - inputs = vp->ir; - for (hw = 0; hw < num_hw; hw++) { + for (hw = 0; hw < nv40->vtxelt_nr; hw++) { struct pipe_vertex_element *ve; struct pipe_vertex_buffer *vb; unsigned type, ncomp; - if (!(inputs & (1 << hw))) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; - } - ve = &nv40->vtxelt[hw]; vb = &nv40->vtxbuf[ve->vertex_buffer_index]; -- cgit v1.2.3 From 7d2085bd7d9378703bfff3d974536ff5e9fd9b30 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 15 Apr 2008 13:25:28 +1000 Subject: nouveau: PIPE_ATTRIB_MAX -> PIPE_MAX_ATTRIBS --- src/gallium/drivers/nv40/nv40_context.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 436351b6bc..2f10540ff0 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -151,9 +151,9 @@ struct nv40_context { unsigned nr_samplers; unsigned nr_textures; unsigned dirty_samplers; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; - struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; unsigned vtxelt_nr; }; -- cgit v1.2.3 From a3265958994ce4107da2a3954c04b496e29cd8aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 23 Apr 2008 12:41:42 +1000 Subject: nouveau: fix build --- src/gallium/drivers/nv40/nv40_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index dd5cc8fc99..a9a939af0c 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -3,7 +3,7 @@ #include "draw/draw_context.h" #include "draw/draw_vertex.h" -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "nv40_context.h" #define NV40_SHADER_NO_FUCKEDNESS -- cgit v1.2.3 From 2193578851b3b5a99c078b28187cf3158f4218f6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 27 Apr 2008 18:12:14 +1000 Subject: nouveau: stub set_edgeflags for all nv pipe drivers --- src/gallium/drivers/nv40/nv40_context.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f9c93f7a2d..f1d4f3c76f 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -32,6 +32,11 @@ nv40_destroy(struct pipe_context *pipe) FREE(nv40); } +static void +nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + struct pipe_context * nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -53,6 +58,7 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->pipe.winsys = ws; nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; + nv40->pipe.set_edgeflags = nv40_set_edgeflags; nv40->pipe.draw_arrays = nv40_draw_arrays; nv40->pipe.draw_elements = nv40_draw_elements; nv40->pipe.clear = nv40_clear; -- cgit v1.2.3 From 58b1bcaa094ed07a54bd7e4cdbddbcdcf1f629a7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 28 Apr 2008 15:42:19 +1000 Subject: nv40: do full swtnl fallback when edge flags present. This isn't necessary, with some effort we can do this on the hw. However, until I encounter something "real" that uses them there's not a lot of point. --- src/gallium/drivers/nv40/nv40_context.c | 6 ------ src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_state.c | 11 +++++++++++ src/gallium/drivers/nv40/nv40_state_emit.c | 1 + src/gallium/drivers/nv40/nv40_vbo.c | 5 +++++ 5 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f1d4f3c76f..f9c93f7a2d 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -32,11 +32,6 @@ nv40_destroy(struct pipe_context *pipe) FREE(nv40); } -static void -nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) -{ -} - struct pipe_context * nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -58,7 +53,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->pipe.winsys = ws; nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; - nv40->pipe.set_edgeflags = nv40_set_edgeflags; nv40->pipe.draw_arrays = nv40_draw_arrays; nv40->pipe.draw_elements = nv40_draw_elements; nv40->pipe.clear = nv40_clear; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 2f10540ff0..24e8cd2337 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -155,6 +155,7 @@ struct nv40_context { unsigned vtxbuf_nr; struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; unsigned vtxelt_nr; + const unsigned *edgeflags; }; static INLINE struct nv40_context * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 997beca883..2d921d2b8a 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -680,6 +680,16 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, nv40->draw_dirty |= NV40_NEW_ARRAYS; } +static void +nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->edgeflags = bitfield; + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; +} + void nv40_init_state_functions(struct nv40_context *nv40) { @@ -719,6 +729,7 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.set_scissor_state = nv40_set_scissor_state; nv40->pipe.set_viewport_state = nv40_set_viewport_state; + nv40->pipe.set_edgeflags = nv40_set_edgeflags; nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers; nv40->pipe.set_vertex_elements = nv40_set_vertex_elements; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 864dfc2e0c..ab88dc416e 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -167,6 +167,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) draw_set_viewport_state(draw, &nv40->viewport); if (nv40->draw_dirty & NV40_NEW_ARRAYS) { + draw_set_edgeflags(draw, nv40->edgeflags); draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf); draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt); } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 06374184b1..e5f9bd5668 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -488,6 +488,11 @@ nv40_vbo_validate(struct nv40_context *nv40) unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; int hw; + if (nv40->edgeflags) { + nv40->fallback_swtnl |= NV40_NEW_ARRAYS; + return FALSE; + } + vtxbuf = so_new(20, 18); so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr); vtxfmt = so_new(17, 0); -- cgit v1.2.3 From 480ab1b7893290505efba925ea95d3b173aa97d4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 29 Apr 2008 08:56:41 +1000 Subject: nv40: enable DXTn formats GL state tracker capable enough for progs/tests/texcompress2 at least. --- src/gallium/drivers/nv40/nv40_screen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index a408d7262f..c64c3b1c39 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -39,7 +39,7 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_GLSL: return 0; case PIPE_CAP_S3TC: - return 0; + return 1; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: @@ -118,12 +118,10 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_U_A8_L8: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_Z24S8_UNORM: -#if 0 /* state tracker not up to the task just yet. */ case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: -#endif return TRUE; default: break; -- cgit v1.2.3 From 612f44266cba78c4e5677a2f992581fdaa17f4e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 May 2008 19:45:21 +1000 Subject: nouveau: bitmap texcoord bias has been removed --- src/gallium/drivers/nv40/nv40_screen.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index c64c3b1c39..7f68539a85 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -82,8 +82,6 @@ nv40_screen_get_paramf(struct pipe_screen *pscreen, int param) return 16.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; -- cgit v1.2.3 From 1ef08564d2a201a422db772a6bb23d1129888304 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:16:35 +1000 Subject: nouveau: remove chipset fields in all nv pipe driver context/screen structs. --- src/gallium/drivers/nv40/nv40_context.c | 2 -- src/gallium/drivers/nv40/nv40_context.h | 2 -- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.h | 1 - 4 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f9c93f7a2d..d9d9accea8 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -38,7 +38,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); @@ -47,7 +46,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->screen = screen; nv40->pctx_id = pctx_id; - nv40->chipset = chipset; nv40->nvws = nvws; nv40->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 24e8cd2337..77b3da0ab9 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -111,8 +111,6 @@ struct nv40_context { struct draw_context *draw; - int chipset; - /* HW state derived from pipe states */ struct nv40_state state; struct { diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 7f68539a85..1bf0931e4d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -12,9 +12,10 @@ static const char * nv40_screen_get_name(struct pipe_screen *pscreen) { struct nv40_screen *screen = nv40_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; static char buffer[128]; - snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -149,17 +150,16 @@ nv40_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); struct nouveau_stateobj *so; unsigned curie_class; + unsigned chipset = nvws->channel->device; int ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 3ea78aadfd..c04a1275a0 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -7,7 +7,6 @@ struct nv40_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; unsigned cur_pctx; -- cgit v1.2.3 From 9a01ee4424718e0c3015c1f0477cae63ee63d96b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 14 May 2008 18:35:37 +1000 Subject: nv40: fix typo in one of the previous commits --- src/gallium/drivers/nv40/nv40_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 1bf0931e4d..0336b84e5f 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -155,7 +155,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); struct nouveau_stateobj *so; unsigned curie_class; - unsigned chipset = nvws->channel->device; + unsigned chipset = nvws->channel->device->chipset; int ret; if (!screen) -- cgit v1.2.3 From f5599a7a3c4a6335ce79fdbd82e18f08bb0ac8e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 25 May 2008 14:25:15 +1000 Subject: nouveau: remove final PIPE_FORMAT_U_* usage --- src/gallium/drivers/nv40/nv40_fragtex.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 980705f94a..c79ea8becb 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -24,10 +24,10 @@ nv40_texture_formats[] = { _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W), _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W), _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W), - _(U_L8 , L8 , S1, S1, S1, ONE, X, X, X, X), - _(U_A8 , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), - _(U_I8 , L8 , S1, S1, S1, S1, X, X, X, X), - _(U_A8_L8 , A8L8 , S1, S1, S1, S1, X, X, X, Y), + _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X), + _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), + _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X), + _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y), _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X), _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X), _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W), diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 0336b84e5f..5164053393 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -111,10 +111,10 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: - case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_A8L8_UNORM: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_Z24S8_UNORM: case PIPE_FORMAT_DXT1_RGB: -- cgit v1.2.3 From fa4b2439d4f240a5e573d4ea198b829791d614f4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 27 May 2008 01:22:22 +1000 Subject: nouveau: very quick port to tex-surface changes. probably the last match-gallium-upstream merge for a bit, some cleanup+nv50 work coming RSN... --- src/gallium/drivers/nv40/nv40_context.c | 1 - src/gallium/drivers/nv40/nv40_context.h | 1 - src/gallium/drivers/nv40/nv40_miptree.c | 20 ++++++++------------ src/gallium/drivers/nv40/nv40_screen.c | 25 +++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 14 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index d9d9accea8..a40f14895f 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -59,7 +59,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40_init_query_functions(nv40); nv40_init_surface_functions(nv40); nv40_init_state_functions(nv40); - nv40_init_miptree_functions(nv40); /* Create, configure, and install fallback swtnl path */ nv40->draw = draw_create(); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 77b3da0ab9..d8d1891dff 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -172,7 +172,6 @@ struct nv40_state_entry { extern void nv40_init_state_functions(struct nv40_context *nv40); extern void nv40_init_surface_functions(struct nv40_context *nv40); -extern void nv40_init_miptree_functions(struct nv40_context *nv40); extern void nv40_init_query_functions(struct nv40_context *nv40); extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen); diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 1b19217223..23da6e36a3 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -100,15 +100,10 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) } } -static void -nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) -{ -} - static struct pipe_surface * -nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; @@ -136,10 +131,10 @@ nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, return ps; } -void -nv40_init_miptree_functions(struct nv40_context *nv40) +static void +nv40_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) { - nv40->pipe.texture_update = nv40_miptree_update; } void @@ -147,6 +142,7 @@ nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv40_miptree_create; pscreen->texture_release = nv40_miptree_release; - pscreen->get_tex_surface = nv40_miptree_surface; + pscreen->get_tex_surface = nv40_miptree_surface_new; + pscreen->tex_surface_release = nv40_miptree_surface_del; } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 5164053393..ed0215b486 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -133,6 +133,28 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, return FALSE; } +static void * +nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + static void nv40_screen_destroy(struct pipe_screen *pscreen) { @@ -282,6 +304,9 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) screen->pipe.is_format_supported = nv40_screen_surface_format_supported; + screen->pipe.surface_map = nv40_surface_map; + screen->pipe.surface_unmap = nv40_surface_unmap; + nv40_screen_init_miptree_functions(&screen->pipe); return &screen->pipe; -- cgit v1.2.3 From 996b549fdbfe772ee56a51858e81e93bccaae5c5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 11:04:55 +1000 Subject: nv40: a couple of memory leaks --- src/gallium/drivers/nv40/nv40_state_viewport.c | 3 ++- src/gallium/drivers/nv40/nv40_vertprog.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 1b6248e5b8..869a55b405 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -3,8 +3,8 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { - struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; + struct nouveau_stateobj *so; unsigned bypass; if (nv40->render_mode == HW && !nv40->rasterizer->pipe.bypass_clipping) @@ -18,6 +18,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) return FALSE; nv40->state.viewport_bypass = bypass; + so = so_new(11, 0); if (!bypass) { so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index e10250528e..eb14869bfe 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -843,6 +843,12 @@ nv40_vertprog_translate(struct nv40_context *nv40, vp->translated = TRUE; out_err: tgsi_parse_free(&parse); + if (vpc->r_temp) + FREE(vpc->r_temp); + if (vpc->r_address) + FREE(vpc->r_address); + if (vpc->imm) + FREE(vpc->imm); FREE(vpc); } -- cgit v1.2.3 From 8c26a521ee80f5d8a1d0aabd0910233aad400322 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 21 Jun 2008 22:59:05 +0200 Subject: Update for extra vertex attributes --- src/gallium/drivers/nv40/nv40_draw.c | 4 ++-- src/gallium/drivers/nv40/nv40_vbo.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index a9a939af0c..1d78324dda 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -39,7 +39,7 @@ nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) case EMIT_OMIT: break; case EMIT_1F: - BEGIN_RING(curie, 0x1e40 + (hw * 4), 1); + BEGIN_RING(curie, NV40TCL_VTX_ATTR_1F(hw), 1); OUT_RING (fui(v->data[idx][0])); break; case EMIT_2F: @@ -61,7 +61,7 @@ nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) OUT_RING (fui(v->data[idx][3])); break; case EMIT_4UB: - BEGIN_RING(curie, 0x1940 + (hw * 4), 1); + BEGIN_RING(curie, NV40TCL_VTX_ATTR_4UB(hw), 1); OUT_RING (pack_ub4(float_to_ubyte(v->data[idx][0]), float_to_ubyte(v->data[idx][1]), float_to_ubyte(v->data[idx][2]), diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index e5f9bd5668..93669e6192 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -149,7 +149,7 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, so_data (so, fui(v[1])); break; case 1: - so_method(so, curie, 0x1e40 + (attrib * 4), 1); + so_method(so, curie, NV40TCL_VTX_ATTR_1F(attrib), 1); so_data (so, fui(v[0])); break; default: -- cgit v1.2.3 From 5a01060eb95cb2cb168cb7224ecc805020584c91 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 00:14:21 +1000 Subject: nouveau: update for interface changes + hack around gallium x86_64 bustage --- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_draw.c | 4 +++- src/gallium/drivers/nv40/nv40_fragprog.c | 8 ++++---- src/gallium/drivers/nv40/nv40_state.c | 5 +++-- src/gallium/drivers/nv40/nv40_vertprog.c | 10 +++++----- 5 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index d8d1891dff..8e60a81e68 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -136,6 +136,7 @@ struct nv40_context { struct nv40_vertex_program *vertprog; struct nv40_fragment_program *fragprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + unsigned constbuf_nr[PIPE_SHADER_TYPES]; struct nv40_rasterizer_state *rasterizer; struct nv40_zsa_state *zsa; struct nv40_blend_state *blend; diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 1d78324dda..2cf58e2950 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -253,9 +253,11 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, } if (nv40->constbuf[PIPE_SHADER_VERTEX]) { + const unsigned nr = nv40->constbuf_nr[PIPE_SHADER_VERTEX]; + map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(nv40->draw, map); + draw_set_mapped_constant_buffer(nv40->draw, map, nr); } draw_arrays(nv40->draw, mode, start, count); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4b7667e038..428348c338 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -708,7 +708,7 @@ nv40_fragprog_parse_decl_attrib(struct nv40_fpc *fpc, return FALSE; } - fpc->attrib_map[fdec->u.DeclarationRange.First] = hw; + fpc->attrib_map[fdec->DeclarationRange.First] = hw; return TRUE; } @@ -716,7 +716,7 @@ static boolean nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, const struct tgsi_full_declaration *fdec) { - unsigned idx = fdec->u.DeclarationRange.First; + unsigned idx = fdec->DeclarationRange.First; unsigned hw; switch (fdec->Semantic.SemanticName) { @@ -770,9 +770,9 @@ nv40_fragprog_prepare(struct nv40_fpc *fpc) goto out_err; break; case TGSI_FILE_TEMPORARY: - if (fdec->u.DeclarationRange.Last > high_temp) { + if (fdec->DeclarationRange.Last > high_temp) { high_temp = - fdec->u.DeclarationRange.Last; + fdec->DeclarationRange.Last; } break; default: diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 2d921d2b8a..afcf336a65 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -603,12 +603,13 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, { struct nv40_context *nv40 = nv40_context(pipe); + nv40->constbuf[shader] = buf->buffer; + nv40->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); + if (shader == PIPE_SHADER_VERTEX) { - nv40->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index eb14869bfe..1e486a66ef 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -603,7 +603,7 @@ static boolean nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, const struct tgsi_full_declaration *fdec) { - unsigned idx = fdec->u.DeclarationRange.First; + unsigned idx = fdec->DeclarationRange.First; int hw; switch (fdec->Semantic.SemanticName) { @@ -678,16 +678,16 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) fdec = &p.FullToken.FullDeclaration; switch (fdec->Declaration.File) { case TGSI_FILE_TEMPORARY: - if (fdec->u.DeclarationRange.Last > high_temp) { + if (fdec->DeclarationRange.Last > high_temp) { high_temp = - fdec->u.DeclarationRange.Last; + fdec->DeclarationRange.Last; } break; #if 0 /* this would be nice.. except gallium doesn't track it */ case TGSI_FILE_ADDRESS: - if (fdec->u.DeclarationRange.Last > high_addr) { + if (fdec->DeclarationRange.Last > high_addr) { high_addr = - fdec->u.DeclarationRange.Last; + fdec->DeclarationRange.Last; } break; #endif -- cgit v1.2.3 From b6478021d572d9ec30212d6e6992496ee4cf347d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 13:26:04 +1000 Subject: nouveau: adapt to cpp->pf_block changes --- src/gallium/drivers/nv40/nv40_miptree.c | 29 ++++++++++++++++++++++------- src/gallium/drivers/nv40/nv40_state_fb.c | 10 +++++----- src/gallium/drivers/nv40/nv40_surface.c | 2 +- 3 files changed, 28 insertions(+), 13 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 23da6e36a3..38e1a5f04c 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -28,19 +28,20 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) pt->width[l] = width; pt->height[l] = height; pt->depth[l] = depth; + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (swizzled) - pitch = pt->width[l]; - pitch = (pitch + 63) & ~63; + pitch = pt->nblocksx[l]; + pitch = align_int(pitch, 64); - nv40mt->level[l].pitch = pitch * pt->cpp; + nv40mt->level[l].pitch = pitch * pt->block.size; nv40mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); depth = MAX2(1, depth >> 1); - } for (f = 0; f < nr_faces; f++) { @@ -109,15 +110,20 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; - ps = ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; + pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = nv40mt->level[level].pitch / ps->cpp; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv40mt->level[level].pitch; + ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv40mt->level[level].image_offset[face]; @@ -135,6 +141,15 @@ static void nv40_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { + struct pipe_surface *ps = *psurface; + + *psurface = NULL; + if (--ps->refcount > 0) + return; + + pipe_texture_reference(&ps->texture, NULL); + pipe_buffer_reference(pscreen->winsys, &ps->buffer, NULL); + FREE(ps); } void diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 88baf61ffb..0e4e60eaa7 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -64,7 +64,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2); - so_data (so, rt[0]->pitch * rt[0]->cpp); + so_data (so, rt[0]->stride); so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); } @@ -77,7 +77,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2); so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_data (so, rt[1]->pitch * rt[1]->cpp); + so_data (so, rt[1]->stride); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { @@ -89,7 +89,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1); - so_data (so, rt[2]->pitch * rt[2]->cpp); + so_data (so, rt[2]->stride); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { @@ -101,7 +101,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1); - so_data (so, rt[3]->pitch * rt[3]->cpp); + so_data (so, rt[3]->stride); } if (zeta_format) { @@ -113,7 +113,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_reloc (so, zeta->buffer, zeta->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1); - so_data (so, zeta->pitch * zeta->cpp); + so_data (so, zeta->stride); } so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1); diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index c0d135eb36..0916555d56 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -34,7 +34,7 @@ #include "util/p_tile.h" static void -nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, +nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) -- cgit v1.2.3 From 39793a262f055adf49e6bbd7b74728f744074e8e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 23 Jul 2008 14:14:55 +1000 Subject: nouveau: is_format_supported() interface changes --- src/gallium/drivers/nv40/nv40_screen.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index ed0215b486..3872c0a0c9 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -91,10 +91,11 @@ nv40_screen_get_paramf(struct pipe_screen *pscreen, int param) static boolean nv40_screen_surface_format_supported(struct pipe_screen *pscreen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -104,8 +105,7 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: @@ -125,10 +125,7 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - default: - assert(0); - }; + } return FALSE; } -- cgit v1.2.3 From a8da04cb861b8f9caf3acd33f52f64621f0c15e2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 23 Jul 2008 23:35:23 -0400 Subject: nv all: Copy shader tokens on create, free on delete. Must copy token stream on shader create, client is allowed to free their copy after creating the state object. --- src/gallium/drivers/nv40/nv40_state.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index afcf336a65..5d2c3ab881 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -5,6 +5,8 @@ #include "draw/draw_context.h" +#include "tgsi/util/tgsi_parse.h" + #include "nv40_context.h" #include "nv40_state.h" @@ -516,7 +518,7 @@ nv40_vp_state_create(struct pipe_context *pipe, struct nv40_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv40_vertex_program)); - vp->pipe = *cso; + vp->pipe.tokens = tgsi_dup_tokens(cso->tokens); vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe); return (void *)vp; @@ -540,6 +542,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) draw_delete_vertex_shader(nv40->draw, vp->draw); nv40_vertprog_destroy(nv40, vp); + FREE((void*)vp->pipe.tokens); FREE(vp); } @@ -550,7 +553,7 @@ nv40_fp_state_create(struct pipe_context *pipe, struct nv40_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv40_fragment_program)); - fp->pipe = *cso; + fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); tgsi_scan_shader(fp->pipe.tokens, &fp->info); @@ -573,6 +576,7 @@ nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_fragment_program *fp = hwcso; nv40_fragprog_destroy(nv40, fp); + FREE((void*)fp->pipe.tokens); FREE(fp); } -- cgit v1.2.3 From a55ced56760f90fe84794b23c557050403d514b2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 3 Aug 2008 17:20:48 -0400 Subject: nv40: Support for PIPE_FORMAT_R16_SNORM. --- src/gallium/drivers/nv40/nv40_fragtex.c | 36 ++++++++++++++++++--------------- src/gallium/drivers/nv40/nv40_screen.c | 3 ++- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index c79ea8becb..2d45c2545c 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -1,6 +1,6 @@ #include "nv40_context.h" -#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ +#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \ { \ TRUE, \ PIPE_FORMAT_##m, \ @@ -9,6 +9,8 @@ NV40TCL_TEX_SWIZZLE_S0_Z_##ts0z | NV40TCL_TEX_SWIZZLE_S0_W_##ts0w | \ NV40TCL_TEX_SWIZZLE_S1_X_##ts1x | NV40TCL_TEX_SWIZZLE_S1_Y_##ts1y | \ NV40TCL_TEX_SWIZZLE_S1_Z_##ts1z | NV40TCL_TEX_SWIZZLE_S1_W_##ts1w), \ + ((NV40TCL_TEX_FILTER_SIGNED_RED*sx) | (NV40TCL_TEX_FILTER_SIGNED_GREEN*sy) | \ + (NV40TCL_TEX_FILTER_SIGNED_BLUE*sz) | (NV40TCL_TEX_FILTER_SIGNED_ALPHA*sw)) \ } struct nv40_texture_format { @@ -16,24 +18,26 @@ struct nv40_texture_format { uint pipe; int format; int swizzle; + int sign; }; static struct nv40_texture_format nv40_texture_formats[] = { - _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W), - _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W), - _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W), - _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W), - _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X), - _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), - _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X), - _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y), - _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X), - _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X), - _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W), - _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W), - _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W), - _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W), + _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0), + _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0), + _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X, 0, 0, 0, 0), + _(R16_SNORM , A16 , ZERO, ZERO, S1, ONE, X, X, X, Y, 1, 1, 1, 1), + _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X, 0, 0, 0, 0), + _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y, 0, 0, 0, 0), + _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0), + _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0), + _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0), + _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), {}, }; @@ -113,7 +117,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_data (so, ps->wrap); so_data (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en); so_data (so, txs); - so_data (so, ps->filt | 0x2000 /*voodoo*/); + so_data (so, ps->filt | tf->sign | 0x2000 /*voodoo*/); so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | pt->height[0]); so_data (so, ps->bcol); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 3872c0a0c9..a63a6136c5 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -110,7 +110,8 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R16_SNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: -- cgit v1.2.3 From fda01b584715c05696a0e6768fda669ef1eb5f3b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Aug 2008 11:26:17 +1000 Subject: nouveau: fix build --- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- src/gallium/drivers/nv40/nv40_state.c | 2 +- src/gallium/drivers/nv40/nv40_state.h | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 428348c338..a361509e8f 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -3,8 +3,8 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv40_context.h" diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 5d2c3ab881..63d0ecc915 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -5,7 +5,7 @@ #include "draw/draw_context.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv40_context.h" #include "nv40_state.h" diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 2b4225deb2..8a9d8c8fdf 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -2,7 +2,7 @@ #define __NV40_STATE_H__ #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct nv40_sampler_state { uint32_t fmt; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 1e486a66ef..ff988e6a5f 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -3,8 +3,8 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv40_context.h" #include "nv40_state.h" -- cgit v1.2.3 From ce8e846ffea8e1a11b8ae4ba05a7386e7c34cc9f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Aug 2008 11:38:56 +1000 Subject: nv40/nv50: enable mirror wrap modes --- src/gallium/drivers/nv40/nv40_screen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index a63a6136c5..0e1df89ee8 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -57,6 +57,9 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: -- cgit v1.2.3 From df4228deddea36b9d5b41ea395a216137e046205 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Aug 2008 16:14:42 +1000 Subject: nouveau: pf_sprint_name -> pf_name --- src/gallium/drivers/nv40/nv40_fragtex.c | 4 +--- src/gallium/drivers/nv40/nv40_vbo.c | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 2d45c2545c..566d5a8d5b 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -45,7 +45,6 @@ static struct nv40_texture_format * nv40_fragtex_format(uint pipe_format) { struct nv40_texture_format *tf = nv40_texture_formats; - char fs[128]; while (tf->defined) { if (tf->pipe == pipe_format) @@ -53,8 +52,7 @@ nv40_fragtex_format(uint pipe_format) tf++; } - pf_sprint_name(fs, pipe_format); - NOUVEAU_ERR("unknown texture format %s\n", fs); + NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); return NULL; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 93669e6192..755d5586b7 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -14,8 +14,6 @@ static INLINE int nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { - char fs[128]; - switch (pipe) { case PIPE_FORMAT_R32_FLOAT: case PIPE_FORMAT_R32G32_FLOAT: @@ -36,8 +34,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *fmt = NV40TCL_VTXFMT_TYPE_USHORT; break; default: - pf_sprint_name(fs, pipe); - NOUVEAU_ERR("Unknown format %s\n", fs); + NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); return 1; } @@ -63,8 +60,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *ncomp = 4; break; default: - pf_sprint_name(fs, pipe); - NOUVEAU_ERR("Unknown format %s\n", fs); + NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); return 1; } -- cgit v1.2.3 From dbec107c2549c00120ca6d67282f2a1a4bd8bdbd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 14 Aug 2008 00:22:49 +1000 Subject: nv30/nv40: KIL/KILP swapped meanings --- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index a361509e8f..91dcbebda0 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -533,10 +533,10 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, case TGSI_OPCODE_FRC: arith(fpc, sat, FRC, dst, mask, src[0], none, none); break; - case TGSI_OPCODE_KIL: + case TGSI_OPCODE_KILP: arith(fpc, 0, KIL, none, 0, none, none, none); break; - case TGSI_OPCODE_KILP: + case TGSI_OPCODE_KIL: dst = nv40_sr(NV40SR_NONE, 0); dst.cc_update = 1; arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none); -- cgit v1.2.3 From f302fca5eb63e4bca8af5b35c585451486143e6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 11 Sep 2008 06:41:18 +1000 Subject: nouveau: gallium directory structure changed again.. --- src/gallium/drivers/nv40/nv40_context.c | 1 - src/gallium/drivers/nv40/nv40_context.h | 4 ++++ src/gallium/drivers/nv40/nv40_draw.c | 3 ++- src/gallium/drivers/nv40/nv40_miptree.c | 11 ++++------- src/gallium/drivers/nv40/nv40_screen.c | 1 - src/gallium/drivers/nv40/nv40_state.c | 1 - src/gallium/drivers/nv40/nv40_surface.c | 4 ++-- src/gallium/drivers/nv40/nv40_vbo.c | 1 - 8 files changed, 12 insertions(+), 14 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index a40f14895f..cc63dd734b 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -1,7 +1,6 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" #include "nv40_context.h" #include "nv40_screen.h" diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 8e60a81e68..adcfbdd85a 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -4,6 +4,10 @@ #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 "draw/draw_vertex.h" diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 2cf58e2950..8e56cdc2fe 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -1,6 +1,7 @@ -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_pack_color.h" + #include "draw/draw_context.h" #include "draw/draw_vertex.h" #include "draw/draw_pipe.h" diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 38e1a5f04c..6c54c37ef7 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "nv40_context.h" @@ -33,7 +32,7 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) if (swizzled) pitch = pt->nblocksx[l]; - pitch = align_int(pitch, 64); + pitch = align(pitch, 64); nv40mt->level[l].pitch = pitch * pt->block.size; nv40mt->level[l].image_offset = @@ -84,7 +83,6 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) static void nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) { - struct pipe_winsys *ws = pscreen->winsys; struct pipe_texture *mt = *pt; *pt = NULL; @@ -92,7 +90,7 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) struct nv40_miptree *nv40mt = (struct nv40_miptree *)mt; int l; - pipe_buffer_reference(ws, &nv40mt->buffer, NULL); + pipe_buffer_reference(pscreen, &nv40mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv40mt->level[l].image_offset) FREE(nv40mt->level[l].image_offset); @@ -106,7 +104,6 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { - struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; @@ -114,7 +111,7 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, if (!ps) return NULL; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, nv40mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; @@ -148,7 +145,7 @@ nv40_miptree_surface_del(struct pipe_screen *pscreen, return; pipe_texture_reference(&ps->texture, NULL); - pipe_buffer_reference(pscreen->winsys, &ps->buffer, NULL); + pipe_buffer_reference(pscreen, &ps->buffer, NULL); FREE(ps); } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 0e1df89ee8..ada0238511 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -1,5 +1,4 @@ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv40_context.h" #include "nv40_screen.h" diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 63d0ecc915..255c4b294d 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 0916555d56..576af7c59e 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -28,10 +28,10 @@ #include "nv40_context.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" #include "pipe/p_inlines.h" -#include "util/p_tile.h" + +#include "util/u_tile.h" static void nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 755d5586b7..09f6e79d32 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -1,6 +1,5 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "nv40_context.h" #include "nv40_state.h" -- cgit v1.2.3 From 92674bc8889e10e580c630cf85c106fa6eb34d7b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 29 Oct 2008 18:12:48 +1100 Subject: nv40: rename some vars in texture layout code --- src/gallium/drivers/nv40/nv40_miptree.c | 52 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 6c54c37ef7..f8d4497bf7 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -5,9 +5,9 @@ #include "nv40_context.h" static void -nv40_miptree_layout(struct nv40_miptree *nv40mt) +nv40_miptree_layout(struct nv40_miptree *mt) { - struct pipe_texture *pt = &nv40mt->base; + struct pipe_texture *pt = &mt->base; boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; uint offset = 0; @@ -34,8 +34,8 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) pitch = pt->nblocksx[l]; pitch = align(pitch, 64); - nv40mt->level[l].pitch = pitch * pt->block.size; - nv40mt->level[l].image_offset = + mt->level[l].pitch = pitch * pt->block.size; + mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); width = MAX2(1, width >> 1); @@ -45,12 +45,12 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) for (f = 0; f < nr_faces; f++) { for (l = 0; l <= pt->last_level; l++) { - nv40mt->level[l].image_offset[f] = offset; - offset += nv40mt->level[l].pitch * pt->height[l]; + mt->level[l].image_offset[f] = offset; + offset += mt->level[l].pitch * pt->height[l]; } } - nv40mt->total_size = offset; + mt->total_size = offset; } static struct pipe_texture * @@ -81,22 +81,24 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) } static void -nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) +nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) { - struct pipe_texture *mt = *pt; + struct pipe_texture *pt = *ppt; + struct nv40_miptree *mt = (struct nv40_miptree *)pt; + int l; - *pt = NULL; - if (--mt->refcount <= 0) { - struct nv40_miptree *nv40mt = (struct nv40_miptree *)mt; - int l; + *ppt = NULL; + if (--pt->refcount) + return; - pipe_buffer_reference(pscreen, &nv40mt->buffer, NULL); - for (l = 0; l <= mt->last_level; l++) { - if (nv40mt->level[l].image_offset) - FREE(nv40mt->level[l].image_offset); - } - FREE(nv40mt); + + pipe_buffer_reference(pscreen, &mt->buffer, NULL); + for (l = 0; l <= pt->last_level; l++) { + if (mt->level[l].image_offset) + FREE(mt->level[l].image_offset); } + + FREE(mt); } static struct pipe_surface * @@ -104,31 +106,31 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { - struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; + struct nv40_miptree *mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(pscreen, &ps->buffer, nv40mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; ps->block = pt->block; ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; - ps->stride = nv40mt->level[level].pitch; + ps->stride = mt->level[level].pitch; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; if (pt->target == PIPE_TEXTURE_CUBE) { - ps->offset = nv40mt->level[level].image_offset[face]; + ps->offset = mt->level[level].image_offset[face]; } else if (pt->target == PIPE_TEXTURE_3D) { - ps->offset = nv40mt->level[level].image_offset[zslice]; + ps->offset = mt->level[level].image_offset[zslice]; } else { - ps->offset = nv40mt->level[level].image_offset[0]; + ps->offset = mt->level[level].image_offset[0]; } return ps; -- cgit v1.2.3 From e658950d4e6c0e5f8b09fa89718d358030885e08 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 10 Nov 2008 16:12:28 +1100 Subject: nv40: init pipe_surface correctly --- src/gallium/drivers/nv40/nv40_miptree.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index f8d4497bf7..f321b72149 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -123,6 +123,8 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->stride = mt->level[level].pitch; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; + ps->refcount = 1; + ps->winsys = pscreen->winsys; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = mt->level[level].image_offset[face]; -- cgit v1.2.3 From 6b4776df35c46892d7701072b8c03cb1cf2d6f01 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 1 Dec 2008 23:48:29 -0500 Subject: nouveau: Use swizzled textures & render targets on nv40 when possible. --- src/gallium/drivers/nv40/nv40_fragtex.c | 3 +- src/gallium/drivers/nv40/nv40_miptree.c | 33 ++++++++++++++++- src/gallium/drivers/nv40/nv40_screen.c | 63 +++++++++++++++++++++++++++++--- src/gallium/drivers/nv40/nv40_state.h | 3 ++ src/gallium/drivers/nv40/nv40_state_fb.c | 38 ++++++++++++++++++- 5 files changed, 130 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 566d5a8d5b..0227d22620 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -66,7 +66,6 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) struct nv40_texture_format *tf; struct nouveau_stateobj *so; uint32_t txf, txs, txp; - int swizzled = 0; /*XXX: implement in region code? */ unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; tf = nv40_fragtex_format(pt->format); @@ -98,7 +97,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) return NULL; } - if (swizzled) { + if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { txp = 0; } else { txp = nv40mt->level[0].pitch; diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index f321b72149..6516bff4b8 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -65,9 +65,32 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->base = *pt; mt->base.refcount = 1; mt->base.screen = pscreen; + mt->shadow_tex = NULL; + mt->shadow_surface = NULL; nv40_miptree_layout(mt); + /* Swizzled textures must be POT */ + if (pt->width[0] & (pt->width[0] - 1) || + pt->height[0] & (pt->height[0] - 1)) + mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + else + if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET)) + mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + else { + switch (pt->format) { + /* TODO: Figure out which formats can be swizzled */ + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + /* XXX: Re-enable when SIFM size limits are fixed */ + /*case PIPE_FORMAT_R16_SNORM:*/ + break; + default: + mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + } + } + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL | NOUVEAU_BUFFER_USAGE_TEXTURE, @@ -91,13 +114,18 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) if (--pt->refcount) return; - pipe_buffer_reference(pscreen, &mt->buffer, NULL); for (l = 0; l <= pt->last_level; l++) { if (mt->level[l].image_offset) FREE(mt->level[l].image_offset); } + if (mt->shadow_tex) { + assert(mt->shadow_surface); + pscreen->tex_surface_release(pscreen, &mt->shadow_surface); + nv40_miptree_release(pscreen, &mt->shadow_tex); + } + FREE(mt); } @@ -125,6 +153,9 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->status = PIPE_SURFACE_STATUS_DEFINED; ps->refcount = 1; ps->winsys = pscreen->winsys; + ps->face = face; + ps->level = level; + ps->zslice = zslice; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = mt->level[level].image_offset[face]; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index ada0238511..25c7868296 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -137,22 +137,73 @@ static void * nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, unsigned flags ) { - struct pipe_winsys *ws = screen->winsys; - void *map; + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface *surface_to_map; + void *map; + + if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; + + if (!mt->shadow_tex) { + unsigned old_tex_usage = surface->texture->tex_usage; + surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR; + mt->shadow_tex = screen->texture_create(screen, surface->texture); + surface->texture->tex_usage = old_tex_usage; + + assert(mt->shadow_tex->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR); + mt->shadow_surface = screen->get_tex_surface + ( + screen, mt->shadow_tex, + surface->face, surface->level, surface->zslice, + surface->usage + ); + } + + surface_to_map = mt->shadow_surface; + } + else + surface_to_map = surface; - map = ws->buffer_map(ws, surface->buffer, flags); + assert(surface_to_map); + + map = ws->buffer_map(ws, surface_to_map->buffer, flags); if (!map) return NULL; - return map + surface->offset; + return map + surface_to_map->offset; } static void nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) { - struct pipe_winsys *ws = screen->winsys; + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface *surface_to_unmap; + + /* TODO: Copy from shadow just before push buffer is flushed instead. + There are probably some programs that map/unmap excessively + before rendering. */ + if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; + + assert(mt->shadow_tex); - ws->buffer_unmap(ws, surface->buffer); + surface_to_unmap = mt->shadow_surface; + } + else + surface_to_unmap = surface; + + assert(surface_to_unmap); + + ws->buffer_unmap(ws, surface_to_unmap->buffer); + + if (surface_to_unmap != surface) { + struct nv40_screen *nvscreen = nv40_screen(screen); + + nvscreen->nvws->surface_copy(nvscreen->nvws, + surface, 0, 0, + surface_to_unmap, 0, 0, + surface->width, surface->height); + } } static void diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 8a9d8c8fdf..9c55903ae3 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -79,6 +79,9 @@ struct nv40_miptree { struct pipe_buffer *buffer; uint total_size; + struct pipe_texture *shadow_tex; + struct pipe_surface *shadow_surface; + struct { uint pitch; uint *image_offset; diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 0e4e60eaa7..f903b22ba0 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -1,5 +1,31 @@ #include "nv40_context.h" +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + static boolean nv40_state_framebuffer_validate(struct nv40_context *nv40) { @@ -32,7 +58,17 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) zeta = fb->zsbuf; } - rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR; + if (!(rt[0]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { + assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); + for (i = 1; i < fb->num_cbufs; i++) + assert(!(rt[i]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)); + + rt_format = NV40TCL_RT_FORMAT_TYPE_SWIZZLED | + log2i(fb->width) << NV40TCL_RT_FORMAT_LOG2_WIDTH_SHIFT | + log2i(fb->height) << NV40TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT; + } + else + rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR; switch (colour_format) { case PIPE_FORMAT_A8R8G8B8_UNORM: -- cgit v1.2.3 From 4371a24c320f3d26f07effa0c3e862078762c942 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Tue, 2 Dec 2008 16:12:49 -0500 Subject: nouveau: Calc pitch for swizzled textures appropriately. --- src/gallium/drivers/nv40/nv40_miptree.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 6516bff4b8..b68967c07f 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -8,7 +8,6 @@ static void nv40_miptree_layout(struct nv40_miptree *mt) { struct pipe_texture *pt = &mt->base; - boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; uint offset = 0; int nr_faces, l, f, pitch; @@ -30,7 +29,7 @@ nv40_miptree_layout(struct nv40_miptree *mt) pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); - if (swizzled) + if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) pitch = pt->nblocksx[l]; pitch = align(pitch, 64); @@ -68,8 +67,6 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->shadow_tex = NULL; mt->shadow_surface = NULL; - nv40_miptree_layout(mt); - /* Swizzled textures must be POT */ if (pt->width[0] & (pt->width[0] - 1) || pt->height[0] & (pt->height[0] - 1)) @@ -91,6 +88,8 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) } } + nv40_miptree_layout(mt); + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL | NOUVEAU_BUFFER_USAGE_TEXTURE, -- cgit v1.2.3 From f72848a09a9d3069705fbe8e4daa29b9918ea56e Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 13 Dec 2008 23:24:39 +0200 Subject: Nouveau: move the definition of log2i() to header Also make the type unsigned instead of signed, since negative values do not make sense. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv40/nv40_state_fb.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index f903b22ba0..28592d71c3 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -1,30 +1,5 @@ #include "nv40_context.h" - -static INLINE int log2i(int i) -{ - int r = 0; - - if (i & 0xffff0000) { - i >>= 16; - r += 16; - } - if (i & 0x0000ff00) { - i >>= 8; - r += 8; - } - if (i & 0x000000f0) { - i >>= 4; - r += 4; - } - if (i & 0x0000000c) { - i >>= 2; - r += 2; - } - if (i & 0x00000002) { - r += 1; - } - return r; -} +#include "nouveau/nouveau_util.h" static boolean nv40_state_framebuffer_validate(struct nv40_context *nv40) -- cgit v1.2.3 From 300e42d6f067b2b98b56a82674bf48564b0578a0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Dec 2008 17:30:04 +1100 Subject: nouveau: return a value for PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS --- src/gallium/drivers/nv40/nv40_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 25c7868296..995148e03f 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -59,6 +59,8 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_REPEAT: return 1; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + return 0; /* We have 4 - but unsupported currently */ case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: -- cgit v1.2.3 From 10e0129dbc70194d54c31ef3b97766b9b69c2442 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Dec 2008 17:34:04 +1100 Subject: nv40: apply ABS modifier to RSQ source in vp Gallium used to do this for us :) --- src/gallium/drivers/nv40/nv40_vertprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index ff988e6a5f..1392fe956f 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -571,7 +571,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, case TGSI_OPCODE_RET: break; case TGSI_OPCODE_RSQ: - arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]); + arith(vpc, 1, OP_RSQ, dst, mask, none, none, abs(src[0])); break; case TGSI_OPCODE_SGE: arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); -- cgit v1.2.3 From ab3a9f1eeda5b216099763f6eb932da723309f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 8 Jan 2009 12:41:45 +0000 Subject: gallium: Replace uint64 by standard uint64_t. uint64 is not (so?) standard, and often redefined by third parties, causing name clashes. --- src/gallium/drivers/nv40/nv40_query.c | 4 ++-- src/gallium/drivers/nv40/nv40_state_emit.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 57f39cfab0..9b9a43f49d 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -50,7 +50,7 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) * the existing query to notify completion, but it could be better. */ if (q->object) { - uint64 tmp; + uint64_t tmp; pipe->get_query_result(pipe, pq, 1, &tmp); } @@ -80,7 +80,7 @@ nv40_query_end(struct pipe_context *pipe, struct pipe_query *pq) static boolean nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq, - boolean wait, uint64 *result) + boolean wait, uint64_t *result) { struct nv40_context *nv40 = nv40_context(pipe); struct nv40_query *q = nv40_query(pq); diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index ab88dc416e..52ec4c044b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -65,7 +65,7 @@ nv40_state_emit(struct nv40_context *nv40) struct nv40_state *state = &nv40->state; struct nv40_screen *screen = nv40->screen; unsigned i, samplers; - uint64 states; + uint64_t states; if (nv40->pctx_id != screen->cur_pctx) { for (i = 0; i < NV40_STATE_MAX; i++) { -- cgit v1.2.3 From 72aa42e59468817798484defe5b3f6dfec0d33e3 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 5 Dec 2008 02:21:55 -0500 Subject: nouveau: Swizzle textures larger than nv04 SIFM limit in parts. Limit of SIFM on nv40 is 1024x1024, not sure about others. --- src/gallium/drivers/nv40/nv40_miptree.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index b68967c07f..36e08e73b9 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -80,8 +80,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) /* TODO: Figure out which formats can be swizzled */ case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_UNORM: - /* XXX: Re-enable when SIFM size limits are fixed */ - /*case PIPE_FORMAT_R16_SNORM:*/ + case PIPE_FORMAT_R16_SNORM: break; default: mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; -- cgit v1.2.3 From 34c0281879b589dc42d134a10349eac66c7b2f0d Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 5 Dec 2008 02:26:07 -0500 Subject: nouveau: Put dynamic textures in GART for CPU access and don't swizzle. Also flag shadows as dynamic since they're for CPU access as well. --- src/gallium/drivers/nv40/nv40_miptree.c | 13 +++++++++---- src/gallium/drivers/nv40/nv40_screen.c | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 36e08e73b9..5121434b54 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -57,6 +57,8 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *mt; + unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL | + NOUVEAU_BUFFER_USAGE_TEXTURE; mt = MALLOC(sizeof(struct nv40_miptree)); if (!mt) @@ -75,6 +77,9 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET)) mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; + else + if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) + mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; else { switch (pt->format) { /* TODO: Figure out which formats can be swizzled */ @@ -87,12 +92,12 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) } } + if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) + buf_usage |= NOUVEAU_BUFFER_USAGE_CPU; + nv40_miptree_layout(mt); - mt->buffer = ws->buffer_create(ws, 256, - PIPE_BUFFER_USAGE_PIXEL | - NOUVEAU_BUFFER_USAGE_TEXTURE, - mt->total_size); + mt->buffer = ws->buffer_create(ws, 256, buf_usage, mt->total_size); if (!mt->buffer) { FREE(mt); return NULL; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 995148e03f..9657a19c50 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -148,7 +148,8 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, if (!mt->shadow_tex) { unsigned old_tex_usage = surface->texture->tex_usage; - surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR; + surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR | + PIPE_TEXTURE_USAGE_DYNAMIC; mt->shadow_tex = screen->texture_create(screen, surface->texture); surface->texture->tex_usage = old_tex_usage; -- cgit v1.2.3 From 7289c388f442fe532de52058f9167bc331920b1a Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 6 Dec 2008 15:45:00 -0500 Subject: nouveau: Use PIPE_BUFFER_USAGE_CPU_* instead of custom. --- src/gallium/drivers/nv40/nv40_miptree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 5121434b54..00ce6be985 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -93,7 +93,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) } if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - buf_usage |= NOUVEAU_BUFFER_USAGE_CPU; + buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; nv40_miptree_layout(mt); -- cgit v1.2.3 From 5897383344da3320d158c26adae05de35480471f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 20 Jan 2009 12:22:49 +0000 Subject: gallium: Remove the standalone surfaces. This commit is mostly just a cosmetic change that cleans-up the interfaces, replacing pipe_winsys::surface_* calls by /** * Allocate storage for a display target surface. * * Often surfaces which are meant to be blitted to the front screen (i.e., * display targets) must be allocated with special characteristics, memory * pools, or obtained directly from the windowing system. * * This callback is invoked by the pipe_screenwhen creating a texture marked * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying * buffer storage. */ struct pipe_buffer *(*surface_buffer_create)(struct pipe_winsys *ws, unsigned width, unsigned height, enum pipe_format format, unsigned usage, unsigned *stride); Most drivers were updated but not all were tested. Use the softpipe pipe driver and the xlib winsys changes as a reference when fixing other drivers. --- src/gallium/drivers/nv40/nv40_miptree.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 00ce6be985..ba912ddcbb 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -155,7 +155,6 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; ps->refcount = 1; - ps->winsys = pscreen->winsys; ps->face = face; ps->level = level; ps->zslice = zslice; -- cgit v1.2.3 From 01cbd764962ff49bf104e5997914ced53360ef81 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 21 Jan 2009 16:55:35 -0500 Subject: nouveau: Map correct mip level when using the shadow (nv30, nv40). --- src/gallium/drivers/nv40/nv40_screen.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 9657a19c50..ab128fecda 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -154,14 +154,15 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, surface->texture->tex_usage = old_tex_usage; assert(mt->shadow_tex->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR); - mt->shadow_surface = screen->get_tex_surface - ( - screen, mt->shadow_tex, - surface->face, surface->level, surface->zslice, - surface->usage - ); } + mt->shadow_surface = screen->get_tex_surface + ( + screen, mt->shadow_tex, + surface->face, surface->level, surface->zslice, + surface->usage + ); + surface_to_map = mt->shadow_surface; } else -- cgit v1.2.3 From 872b515e8f0bb1be5bad85fd9d01529c71f07ba2 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 26 Jan 2009 13:45:45 -0500 Subject: gallium: standardize on stride instead of pitch in the interface --- src/gallium/drivers/nv40/nv40_vbo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 09f6e79d32..8f1834628f 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -501,7 +501,7 @@ nv40_vbo_validate(struct nv40_context *nv40) ve = &nv40->vtxelt[hw]; vb = &nv40->vtxbuf[ve->vertex_buffer_index]; - if (!vb->pitch) { + if (!vb->stride) { if (!sattr) sattr = so_new(16 * 5, 0); @@ -522,7 +522,7 @@ nv40_vbo_validate(struct nv40_context *nv40) so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, 0, NV40TCL_VTXBUF_ADDRESS_DMA1); - so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) | + so_data (vtxfmt, ((vb->stride << NV40TCL_VTXFMT_STRIDE_SHIFT) | (ncomp << NV40TCL_VTXFMT_SIZE_SHIFT) | type)); } -- cgit v1.2.3 From a7e72231e3c76a9410d192441da309002ea6422d Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 26 Jan 2009 14:37:21 -0500 Subject: gallium: standardize naming of masks --- src/gallium/drivers/nv40/nv40_state.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 255c4b294d..34d109f9af 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -459,10 +459,10 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, if (cso->stencil[0].enabled) { so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); so_data (so, cso->stencil[0].enabled ? 1 : 0); - so_data (so, cso->stencil[0].write_mask); + so_data (so, cso->stencil[0].writemask); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); so_data (so, cso->stencil[0].ref_value); - so_data (so, cso->stencil[0].value_mask); + so_data (so, cso->stencil[0].valuemask); 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)); @@ -474,10 +474,10 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, if (cso->stencil[1].enabled) { so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8); so_data (so, cso->stencil[1].enabled ? 1 : 0); - so_data (so, cso->stencil[1].write_mask); + so_data (so, cso->stencil[1].writemask); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); so_data (so, cso->stencil[1].ref_value); - so_data (so, cso->stencil[1].value_mask); + so_data (so, cso->stencil[1].valuemask); 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)); -- cgit v1.2.3 From 2299f21f8da816fc4588492965e7dac422da1a96 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 26 Jan 2009 14:49:54 -0500 Subject: gallium: standardize api on the prefix "nr" --- src/gallium/drivers/nv40/nv40_state_emit.c | 2 +- src/gallium/drivers/nv40/nv40_state_fb.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 52ec4c044b..ce859def10 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -41,7 +41,7 @@ nv40_state_do_validate(struct nv40_context *nv40, const struct pipe_framebuffer_state *fb = &nv40->framebuffer; unsigned i; - for (i = 0; i < fb->num_cbufs; i++) + for (i = 0; i < fb->nr_cbufs; i++) fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; if (fb->zsbuf) fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 28592d71c3..a2e09e18a4 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -14,7 +14,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) unsigned h = fb->height; rt_enable = 0; - for (i = 0; i < fb->num_cbufs; i++) { + for (i = 0; i < fb->nr_cbufs; i++) { if (colour_format) { assert(colour_format == fb->cbufs[i]->format); } else { @@ -35,7 +35,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) if (!(rt[0]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); - for (i = 1; i < fb->num_cbufs; i++) + for (i = 1; i < fb->nr_cbufs; i++) assert(!(rt[i]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)); rt_format = NV40TCL_RT_FORMAT_TYPE_SWIZZLED | -- cgit v1.2.3 From d6888e811d24eaa7e8d9093be606394f00435c05 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 26 Jan 2009 15:07:08 -0500 Subject: gallium: it's a reference value, not a reference number --- src/gallium/drivers/nv40/nv40_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 34d109f9af..d5d81b1371 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -454,7 +454,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3); so_data (so, cso->alpha.enabled ? 1 : 0); so_data (so, nvgl_comparison_op(cso->alpha.func)); - so_data (so, float_to_ubyte(cso->alpha.ref)); + so_data (so, float_to_ubyte(cso->alpha.ref_value)); if (cso->stencil[0].enabled) { so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); -- cgit v1.2.3 From 4f5308bdcb9e62f678975a77783a48096f6dfdc6 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 26 Jan 2009 15:22:53 -0500 Subject: gallium: remove redundant size from the constant buffer reuse the size of the actual buffer --- src/gallium/drivers/nv40/nv40_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index d5d81b1371..2eff25aa83 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -607,7 +607,7 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); nv40->constbuf[shader] = buf->buffer; - nv40->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); + nv40->constbuf_nr[shader] = buf->buffer->size / (4 * sizeof(float)); if (shader == PIPE_SHADER_VERTEX) { nv40->dirty |= NV40_NEW_VERTPROG; -- cgit v1.2.3 From b3028acd98e2b7fd09344f9005c5b20bba91262c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 29 Jan 2009 21:43:15 -0500 Subject: gallium: give the screen priority when it comes to buffer allocations allows the driver to overwrite buffer allocation, first step on the way to making winsys interface internal to the drivers. state trackers and the code above it will go through the screen --- src/gallium/drivers/nv40/nv40_draw.c | 14 +++++++------- src/gallium/drivers/nv40/nv40_fragprog.c | 10 +++++----- src/gallium/drivers/nv40/nv40_miptree.c | 2 +- src/gallium/drivers/nv40/nv40_screen.c | 4 ++-- src/gallium/drivers/nv40/nv40_vbo.c | 12 ++++++------ src/gallium/drivers/nv40/nv40_vertprog.c | 4 ++-- 6 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 8e56cdc2fe..3d5332a80b 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -241,13 +241,13 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, nv40_state_emit(nv40); for (i = 0; i < nv40->vtxbuf_nr; i++) { - map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + map = ws->_buffer_map(ws, nv40->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(nv40->draw, i, map); } if (idxbuf) { - map = ws->buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->_buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map); } else { draw_set_mapped_element_buffer(nv40->draw, 0, NULL); @@ -256,7 +256,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, if (nv40->constbuf[PIPE_SHADER_VERTEX]) { const unsigned nr = nv40->constbuf_nr[PIPE_SHADER_VERTEX]; - map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], + map = ws->_buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_constant_buffer(nv40->draw, map, nr); } @@ -264,13 +264,13 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, draw_arrays(nv40->draw, mode, start, count); for (i = 0; i < nv40->vtxbuf_nr; i++) - ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); + ws->_buffer_unmap(ws, nv40->vtxbuf[i].buffer); if (idxbuf) - ws->buffer_unmap(ws, idxbuf); + ws->_buffer_unmap(ws, idxbuf); if (nv40->constbuf[PIPE_SHADER_VERTEX]) - ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); + ws->_buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); draw_flush(nv40->draw); pipe->flush(pipe, 0, NULL); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 91dcbebda0..5a127d9c7b 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -886,7 +886,7 @@ nv40_fragprog_upload(struct nv40_context *nv40, uint32_t *map; int i; - map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + map = ws->_buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); #if 0 for (i = 0; i < fp->insn_len; i++) { @@ -908,7 +908,7 @@ nv40_fragprog_upload(struct nv40_context *nv40, } } - ws->buffer_unmap(ws, fp->buffer); + ws->_buffer_unmap(ws, fp->buffer); } static boolean @@ -932,7 +932,7 @@ nv40_fragprog_validate(struct nv40_context *nv40) return FALSE; } - fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); + fp->buffer = ws->_buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv40_fragprog_upload(nv40, fp); so = so_new(4, 1); @@ -948,7 +948,7 @@ update_constants: if (fp->nr_consts) { float *map; - map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->_buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); for (i = 0; i < fp->nr_consts; i++) { struct nv40_fragment_program_data *fpd = &fp->consts[i]; uint32_t *p = &fp->insn[fpd->offset]; @@ -959,7 +959,7 @@ update_constants: memcpy(p, cb, 4 * sizeof(float)); new_consts = TRUE; } - ws->buffer_unmap(ws, constbuf); + ws->_buffer_unmap(ws, constbuf); if (new_consts) nv40_fragprog_upload(nv40, fp); diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index ba912ddcbb..6ed0d39edf 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -97,7 +97,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) nv40_miptree_layout(mt); - mt->buffer = ws->buffer_create(ws, 256, buf_usage, mt->total_size); + mt->buffer = ws->_buffer_create(ws, 256, buf_usage, mt->total_size); if (!mt->buffer) { FREE(mt); return NULL; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index ab128fecda..20662fd3ff 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -170,7 +170,7 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, assert(surface_to_map); - map = ws->buffer_map(ws, surface_to_map->buffer, flags); + map = ws->_buffer_map(ws, surface_to_map->buffer, flags); if (!map) return NULL; @@ -198,7 +198,7 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) assert(surface_to_unmap); - ws->buffer_unmap(ws, surface_to_unmap->buffer); + ws->_buffer_unmap(ws, surface_to_unmap->buffer); if (surface_to_unmap != surface) { struct nv40_screen *nvscreen = nv40_screen(screen); diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 8f1834628f..f20183ddd4 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -116,7 +116,7 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) return FALSE; - map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->_buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); map += vb->buffer_offset + ve->src_offset; switch (type) { @@ -148,17 +148,17 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, so_data (so, fui(v[0])); break; default: - ws->buffer_unmap(ws, vb->buffer); + ws->_buffer_unmap(ws, vb->buffer); return FALSE; } } break; default: - ws->buffer_unmap(ws, vb->buffer); + ws->_buffer_unmap(ws, vb->buffer); return FALSE; } - ws->buffer_unmap(ws, vb->buffer); + ws->_buffer_unmap(ws, vb->buffer); return TRUE; } @@ -370,7 +370,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->_buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); return FALSE; @@ -391,7 +391,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, break; } - ws->buffer_unmap(ws, ib); + ws->_buffer_unmap(ws, ib); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 1392fe956f..7a82bb0f5e 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -980,7 +980,7 @@ check_gpu_resources: float *map = NULL; if (constbuf) { - map = ws->buffer_map(ws, constbuf, + map = ws->_buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); } @@ -1002,7 +1002,7 @@ check_gpu_resources: } if (constbuf) - ws->buffer_unmap(ws, constbuf); + ws->_buffer_unmap(ws, constbuf); } /* Upload vtxprog */ -- cgit v1.2.3 From adfbba476db1fc55006efb748656ebb1a481d143 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 30 Jan 2009 15:56:00 -0500 Subject: gallium: make p_winsys internal move it to pipe/internal/p_winsys_screen.h and start converting the state trackers to the screen usage --- src/gallium/drivers/nv40/nv40_context.c | 2 +- src/gallium/drivers/nv40/nv40_draw.c | 12 ++++++------ src/gallium/drivers/nv40/nv40_fragprog.c | 10 +++++----- src/gallium/drivers/nv40/nv40_miptree.c | 2 +- src/gallium/drivers/nv40/nv40_screen.c | 4 ++-- src/gallium/drivers/nv40/nv40_surface.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 12 ++++++------ src/gallium/drivers/nv40/nv40_vertprog.c | 4 ++-- 8 files changed, 24 insertions(+), 24 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index cc63dd734b..5d325f5067 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -1,6 +1,6 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "nv40_context.h" #include "nv40_screen.h" diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 3d5332a80b..c83ff91d7e 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -241,13 +241,13 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, nv40_state_emit(nv40); for (i = 0; i < nv40->vtxbuf_nr; i++) { - map = ws->_buffer_map(ws, nv40->vtxbuf[i].buffer, + map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(nv40->draw, i, map); } if (idxbuf) { - map = ws->_buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map); } else { draw_set_mapped_element_buffer(nv40->draw, 0, NULL); @@ -256,7 +256,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, if (nv40->constbuf[PIPE_SHADER_VERTEX]) { const unsigned nr = nv40->constbuf_nr[PIPE_SHADER_VERTEX]; - map = ws->_buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], + map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_constant_buffer(nv40->draw, map, nr); } @@ -264,13 +264,13 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, draw_arrays(nv40->draw, mode, start, count); for (i = 0; i < nv40->vtxbuf_nr; i++) - ws->_buffer_unmap(ws, nv40->vtxbuf[i].buffer); + ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); if (idxbuf) - ws->_buffer_unmap(ws, idxbuf); + ws->buffer_unmap(ws, idxbuf); if (nv40->constbuf[PIPE_SHADER_VERTEX]) - ws->_buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); + ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); draw_flush(nv40->draw); pipe->flush(pipe, 0, NULL); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 5a127d9c7b..91dcbebda0 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -886,7 +886,7 @@ nv40_fragprog_upload(struct nv40_context *nv40, uint32_t *map; int i; - map = ws->_buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); #if 0 for (i = 0; i < fp->insn_len; i++) { @@ -908,7 +908,7 @@ nv40_fragprog_upload(struct nv40_context *nv40, } } - ws->_buffer_unmap(ws, fp->buffer); + ws->buffer_unmap(ws, fp->buffer); } static boolean @@ -932,7 +932,7 @@ nv40_fragprog_validate(struct nv40_context *nv40) return FALSE; } - fp->buffer = ws->_buffer_create(ws, 0x100, 0, fp->insn_len * 4); + fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv40_fragprog_upload(nv40, fp); so = so_new(4, 1); @@ -948,7 +948,7 @@ update_constants: if (fp->nr_consts) { float *map; - map = ws->_buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); for (i = 0; i < fp->nr_consts; i++) { struct nv40_fragment_program_data *fpd = &fp->consts[i]; uint32_t *p = &fp->insn[fpd->offset]; @@ -959,7 +959,7 @@ update_constants: memcpy(p, cb, 4 * sizeof(float)); new_consts = TRUE; } - ws->_buffer_unmap(ws, constbuf); + ws->buffer_unmap(ws, constbuf); if (new_consts) nv40_fragprog_upload(nv40, fp); diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 6ed0d39edf..ba912ddcbb 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -97,7 +97,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) nv40_miptree_layout(mt); - mt->buffer = ws->_buffer_create(ws, 256, buf_usage, mt->total_size); + mt->buffer = ws->buffer_create(ws, 256, buf_usage, mt->total_size); if (!mt->buffer) { FREE(mt); return NULL; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 20662fd3ff..ab128fecda 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -170,7 +170,7 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, assert(surface_to_map); - map = ws->_buffer_map(ws, surface_to_map->buffer, flags); + map = ws->buffer_map(ws, surface_to_map->buffer, flags); if (!map) return NULL; @@ -198,7 +198,7 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) assert(surface_to_unmap); - ws->_buffer_unmap(ws, surface_to_unmap->buffer); + ws->buffer_unmap(ws, surface_to_unmap->buffer); if (surface_to_unmap != surface) { struct nv40_screen *nvscreen = nv40_screen(screen); diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 576af7c59e..aa51d04051 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -28,7 +28,7 @@ #include "nv40_context.h" #include "pipe/p_defines.h" -#include "pipe/p_winsys.h" +#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" #include "util/u_tile.h" diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index f20183ddd4..8f1834628f 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -116,7 +116,7 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) return FALSE; - map = ws->_buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); map += vb->buffer_offset + ve->src_offset; switch (type) { @@ -148,17 +148,17 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, so_data (so, fui(v[0])); break; default: - ws->_buffer_unmap(ws, vb->buffer); + ws->buffer_unmap(ws, vb->buffer); return FALSE; } } break; default: - ws->_buffer_unmap(ws, vb->buffer); + ws->buffer_unmap(ws, vb->buffer); return FALSE; } - ws->_buffer_unmap(ws, vb->buffer); + ws->buffer_unmap(ws, vb->buffer); return TRUE; } @@ -370,7 +370,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - map = ws->_buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); + map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); return FALSE; @@ -391,7 +391,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, break; } - ws->_buffer_unmap(ws, ib); + ws->buffer_unmap(ws, ib); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 7a82bb0f5e..1392fe956f 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -980,7 +980,7 @@ check_gpu_resources: float *map = NULL; if (constbuf) { - map = ws->_buffer_map(ws, constbuf, + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); } @@ -1002,7 +1002,7 @@ check_gpu_resources: } if (constbuf) - ws->_buffer_unmap(ws, constbuf); + ws->buffer_unmap(ws, constbuf); } /* Upload vtxprog */ -- cgit v1.2.3 From 969c728095e9a18036989f85610390c55ae61d5e Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 31 Jan 2009 15:14:38 -0500 Subject: gallium: initialize simple screen in drivers --- src/gallium/drivers/nv40/nv40_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index ab128fecda..46fe133d71 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -1,4 +1,5 @@ #include "pipe/p_screen.h" +#include "util/u_simple_screen.h" #include "nv40_context.h" #include "nv40_screen.h" @@ -363,6 +364,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) screen->pipe.surface_unmap = nv40_surface_unmap; nv40_screen_init_miptree_functions(&screen->pipe); + u_simple_screen_init(&screen->pipe); return &screen->pipe; } -- cgit v1.2.3 From 5069bfed29bcee2c89c36c74c6d65d388eb7792e Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 2 Feb 2009 23:47:16 -0500 Subject: gallium: remove pipe_buffer from surfaces this change disassociates, at least from the driver perspective, the surface from buffer. surfaces are technically now views on the textures so make it so by hiding the buffer in the internals of textures. --- src/gallium/drivers/nv40/nv40_miptree.c | 2 -- src/gallium/drivers/nv40/nv40_screen.c | 9 ++++++--- src/gallium/drivers/nv40/nv40_state_fb.c | 27 +++++++++++++++++---------- 3 files changed, 23 insertions(+), 15 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index ba912ddcbb..b1fba11d2f 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -144,7 +144,6 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, if (!ps) return NULL; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; @@ -182,7 +181,6 @@ nv40_miptree_surface_del(struct pipe_screen *pscreen, return; pipe_texture_reference(&ps->texture, NULL); - pipe_buffer_reference(pscreen, &ps->buffer, NULL); FREE(ps); } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 46fe133d71..41d342d27d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -143,6 +143,7 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, struct pipe_winsys *ws = screen->winsys; struct pipe_surface *surface_to_map; void *map; + struct nv40_miptree *mt; if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; @@ -170,8 +171,8 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, surface_to_map = surface; assert(surface_to_map); - - map = ws->buffer_map(ws, surface_to_map->buffer, flags); + mt = (struct nv40_miptree *)surface_to_map->texture; + map = ws->buffer_map(ws, mt->buffer, flags); if (!map) return NULL; @@ -183,6 +184,7 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) { struct pipe_winsys *ws = screen->winsys; struct pipe_surface *surface_to_unmap; + struct nv40_miptree *mt; /* TODO: Copy from shadow just before push buffer is flushed instead. There are probably some programs that map/unmap excessively @@ -199,7 +201,8 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) assert(surface_to_unmap); - ws->buffer_unmap(ws, surface_to_unmap->buffer); + mt = (struct nv40_miptree *)surface_to_unmap->texture; + ws->buffer_unmap(ws, mt->buffer); if (surface_to_unmap != surface) { struct nv40_screen *nvscreen = nv40_screen(screen); diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index a2e09e18a4..454abad31f 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -1,6 +1,13 @@ #include "nv40_context.h" #include "nouveau/nouveau_util.h" +static struct pipe_buffer * +nv40_surface_buffer(struct pipe_surface *surface) +{ + struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; + return mt->buffer; +} + static boolean nv40_state_framebuffer_validate(struct nv40_context *nv40) { @@ -71,33 +78,33 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR0, 1); - so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + so_reloc (so, nv40_surface_buffer(rt[0]), 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2); so_data (so, rt[0]->stride); - so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | + so_reloc (so, nv40_surface_buffer(rt[0]), rt[0]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR1, 1); - so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + so_reloc (so, nv40_surface_buffer(rt[1]), 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2); - so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | + so_reloc (so, nv40_surface_buffer(rt[1]), rt[1]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_data (so, rt[1]->stride); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR2, 1); - so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + so_reloc (so, nv40_surface_buffer(rt[2]), 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); so_method(so, nv40->screen->curie, NV40TCL_COLOR2_OFFSET, 1); - so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | + so_reloc (so, nv40_surface_buffer(rt[2]), rt[2]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1); so_data (so, rt[2]->stride); @@ -105,11 +112,11 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR3, 1); - so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + so_reloc (so, nv40_surface_buffer(rt[3]), 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); so_method(so, nv40->screen->curie, NV40TCL_COLOR3_OFFSET, 1); - so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | + so_reloc (so, nv40_surface_buffer(rt[3]), rt[3]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1); so_data (so, rt[3]->stride); @@ -117,11 +124,11 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) if (zeta_format) { so_method(so, nv40->screen->curie, NV40TCL_DMA_ZETA, 1); - so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, + so_reloc (so, nv40_surface_buffer(zeta), 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); so_method(so, nv40->screen->curie, NV40TCL_ZETA_OFFSET, 1); - so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + so_reloc (so, nv40_surface_buffer(zeta), zeta->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1); so_data (so, zeta->stride); -- cgit v1.2.3 From 79bf0bdc7ffe97ec128e5dd143c4ed54648aae42 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 4 Feb 2009 20:59:49 +1000 Subject: nouveau: get things building/running again after pipe_surface.buffer removal Don't look at nouveau_winsys_pipe.h... I promise it's temporary! --- src/gallium/drivers/nv40/nv40_miptree.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index b1fba11d2f..e8cd104ea4 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -106,6 +106,30 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) return &mt->base; } +static struct pipe_texture * +nv40_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, + const unsigned *stride, struct pipe_buffer *pb) +{ + struct nv40_miptree *mt; + + /* Only supports 2D, non-mipmapped textures for the moment */ + if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || + pt->depth[0] != 1) + return NULL; + + mt = CALLOC_STRUCT(nv40_miptree); + if (!mt) + return NULL; + + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = pscreen; + mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); + + pipe_buffer_reference(pscreen, &mt->buffer, pb); + return &mt->base; +} + static void nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) { @@ -188,6 +212,7 @@ void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv40_miptree_create; + pscreen->texture_blanket = nv40_miptree_blanket; pscreen->texture_release = nv40_miptree_release; pscreen->get_tex_surface = nv40_miptree_surface_new; pscreen->tex_surface_release = nv40_miptree_surface_del; -- cgit v1.2.3 From ff8dff017e537c6db4c86aad43e92b768cb187e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Feb 2009 18:19:32 +1000 Subject: nv04-nv40: move 2d blit/fill code into pipe driver --- src/gallium/drivers/nv40/nv40_screen.c | 12 ++++++++++++ src/gallium/drivers/nv40/nv40_screen.h | 2 ++ src/gallium/drivers/nv40/nv40_surface.c | 20 +++++++------------- 3 files changed, 21 insertions(+), 13 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 41d342d27d..a2b124d228 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -230,6 +230,14 @@ nv40_screen_destroy(struct pipe_screen *pscreen) FREE(pscreen); } +static struct pipe_buffer * +nv40_surface_buffer(struct pipe_surface *surf) +{ + struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture; + + return mt->buffer; +} + struct pipe_screen * nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { @@ -243,6 +251,10 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; screen->nvws = nvws; + /* 2D engine setup */ + screen->eng2d = nv04_surface_2d_init(nvws); + screen->eng2d->buf = nv40_surface_buffer; + /* 3D object */ switch (chipset & 0xf0) { case 0x40: diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index c04a1275a0..4500aa0e5c 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -2,6 +2,7 @@ #define __NV40_SCREEN_H__ #include "pipe/p_screen.h" +#include "nv04/nv04_surface_2d.h" struct nv40_screen { struct pipe_screen pipe; @@ -11,6 +12,7 @@ struct nv40_screen { unsigned cur_pctx; /* HW graphics objects */ + struct nv04_surface_2d *eng2d; struct nouveau_grobj *curie; struct nouveau_notifier *sync; diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index aa51d04051..68bbfce448 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -30,7 +30,6 @@ #include "pipe/p_defines.h" #include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" - #include "util/u_tile.h" static void @@ -40,22 +39,17 @@ nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, unsigned width, unsigned height) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_winsys *nvws = nv40->nvws; + struct nv04_surface_2d *eng2d = nv40->screen->eng2d; if (do_flip) { - /*XXX: This dodgyness will do for now for correctness. But, - * need to investigate whether the 2D engine is able to - * manage a flip (perhaps SIFM?), if not, use the 3D engine - */ desty += height; while (height--) { - nvws->surface_copy(nvws, dest, destx, desty--, src, - srcx, srcy++, width, 1); + eng2d->copy(eng2d, dest, destx, desty--, src, + srcx, srcy++, width, 1); } - } else { - nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, - width, height); } + + eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); } static void @@ -64,9 +58,9 @@ nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, unsigned height, unsigned value) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_winsys *nvws = nv40->nvws; + struct nv04_surface_2d *eng2d = nv40->screen->eng2d; - nvws->surface_fill(nvws, dest, destx, desty, width, height, value); + eng2d->fill(eng2d, dest, destx, desty, width, height, value); } void -- cgit v1.2.3 From a785a4ae2165c3b58c228f4de4b26b2c0800116c Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 5 Feb 2009 19:45:33 +0200 Subject: nv04-nv40: fix nv##_surface_copy() for flipped If do_flipp is true, it would first do the proper copy, height would wrap around to unsigned maximum, and then it attempts to do another copy. Return after doing the proper copy. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv40/nv40_surface.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 68bbfce448..c4a5fb20d9 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -47,6 +47,7 @@ nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, eng2d->copy(eng2d, dest, destx, desty--, src, srcx, srcy++, width, 1); } + return; } eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); -- cgit v1.2.3 From 5c8c728afe0e2a8e8819097ae1c2f3c738d9397b Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 6 Feb 2009 14:33:49 -0500 Subject: nouveau: Frontbuffer pitch needs to be set. --- src/gallium/drivers/nv40/nv40_miptree.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index e8cd104ea4..9bef23ad1f 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -124,6 +124,7 @@ nv40_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, mt->base = *pt; mt->base.refcount = 1; mt->base.screen = pscreen; + mt->level[0].pitch = stride[0]; mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); pipe_buffer_reference(pscreen, &mt->buffer, pb); -- cgit v1.2.3 From 32cd1a0345eaf1f4da8a60a4ac2145ff51383d59 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 7 Feb 2009 12:53:30 -0500 Subject: nouveau: Need to surface_copy() without a pipe context. --- src/gallium/drivers/nv40/nv40_screen.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers/nv40') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index a2b124d228..88a329ea24 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -136,6 +136,14 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, return FALSE; } +static struct pipe_buffer * +nv40_surface_buffer(struct pipe_surface *surf) +{ + struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture; + + return mt->buffer; +} + static void * nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, unsigned flags ) @@ -143,7 +151,6 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, struct pipe_winsys *ws = screen->winsys; struct pipe_surface *surface_to_map; void *map; - struct nv40_miptree *mt; if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; @@ -171,8 +178,7 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, surface_to_map = surface; assert(surface_to_map); - mt = (struct nv40_miptree *)surface_to_map->texture; - map = ws->buffer_map(ws, mt->buffer, flags); + map = ws->buffer_map(ws, nv40_surface_buffer(surface_to_map), flags); if (!map) return NULL; @@ -184,7 +190,6 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) { struct pipe_winsys *ws = screen->winsys; struct pipe_surface *surface_to_unmap; - struct nv40_miptree *mt; /* TODO: Copy from shadow just before push buffer is flushed instead. There are probably some programs that map/unmap excessively @@ -201,16 +206,14 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) assert(surface_to_unmap); - mt = (struct nv40_miptree *)surface_to_unmap->texture; - ws->buffer_unmap(ws, mt->buffer); + ws->buffer_unmap(ws, nv40_surface_buffer(surface_to_unmap)); if (surface_to_unmap != surface) { struct nv40_screen *nvscreen = nv40_screen(screen); - nvscreen->nvws->surface_copy(nvscreen->nvws, - surface, 0, 0, - surface_to_unmap, 0, 0, - surface->width, surface->height); + nvscreen->eng2d->copy(nvscreen->eng2d, surface, 0, 0, + surface_to_unmap, 0, 0, + surface->width, surface->height); } } @@ -230,14 +233,6 @@ nv40_screen_destroy(struct pipe_screen *pscreen) FREE(pscreen); } -static struct pipe_buffer * -nv40_surface_buffer(struct pipe_surface *surf) -{ - struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture; - - return mt->buffer; -} - struct pipe_screen * nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { -- cgit v1.2.3