From: Keith Whitwell Date: Mon, 15 Mar 2010 09:44:52 +0000 (+0000) Subject: Merge commit 'origin/master' into gallium-sampler-view X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=42910ebe7b9748c0ecb6a597bae3e7d43c7e170f;p=mesa.git Merge commit 'origin/master' into gallium-sampler-view Conflicts: src/gallium/drivers/nv30/nv30_context.h src/gallium/drivers/nv30/nv30_state.c src/gallium/drivers/nv40/nv40_context.h src/gallium/drivers/nv40/nv40_state.c src/gallium/drivers/r300/r300_emit.c --- 42910ebe7b9748c0ecb6a597bae3e7d43c7e170f diff --cc src/gallium/drivers/nv40/nv40_transfer.c index c552a681138,3d8c8e8c78a..00000000000 deleted file mode 100644,100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ /dev/null @@@ -1,181 -1,181 +1,0 @@@ --#include "pipe/p_state.h" --#include "pipe/p_defines.h" --#include "util/u_inlines.h" --#include "util/u_format.h" --#include "util/u_memory.h" --#include "util/u_math.h" --#include "nouveau/nouveau_winsys.h" --#include "nv40_context.h" - #include "nv40_screen.h" - #include "nv40_state.h" -#include "nvfx_screen.h" -#include "nvfx_state.h" -- --struct nv40_transfer { -- struct pipe_transfer base; -- struct pipe_surface *surface; -- boolean direct; --}; -- --static void --nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, -- struct pipe_texture *template) --{ -- memset(template, 0, sizeof(struct pipe_texture)); -- template->target = pt->target; -- template->format = pt->format; -- template->width0 = width; -- template->height0 = height; -- template->depth0 = 1; -- template->last_level = 0; -- template->nr_samples = pt->nr_samples; -- -- template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | -- NOUVEAU_TEXTURE_USAGE_LINEAR; --} -- --static struct pipe_transfer * --nv40_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt, -- unsigned face, unsigned level, unsigned zslice, -- enum pipe_transfer_usage usage, -- unsigned x, unsigned y, unsigned w, unsigned h) --{ -- struct pipe_screen *pscreen = pcontext->screen; - struct nv40_miptree *mt = (struct nv40_miptree *)pt; - struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; -- struct nv40_transfer *tx; -- struct pipe_texture tx_tex_template, *tx_tex; -- -- tx = CALLOC_STRUCT(nv40_transfer); -- if (!tx) -- return NULL; -- -- pipe_texture_reference(&tx->base.texture, pt); -- tx->base.x = x; -- tx->base.y = y; -- tx->base.width = w; -- tx->base.height = h; -- tx->base.stride = mt->level[level].pitch; -- tx->base.usage = usage; -- tx->base.face = face; -- tx->base.level = level; -- tx->base.zslice = zslice; -- -- /* Direct access to texture */ -- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || -- debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && -- pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) -- { -- tx->direct = true; -- tx->surface = pscreen->get_tex_surface(pscreen, pt, -- face, level, zslice, -- pipe_transfer_buffer_flags(&tx->base)); -- return &tx->base; -- } -- -- tx->direct = false; -- -- nv40_compatible_transfer_tex(pt, w, h, &tx_tex_template); -- -- tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); -- if (!tx_tex) -- { -- FREE(tx); -- return NULL; -- } -- - tx->base.stride = ((struct nv40_miptree*)tx_tex)->level[0].pitch; - tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch; -- -- tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, -- 0, 0, 0, -- pipe_transfer_buffer_flags(&tx->base)); -- -- pipe_texture_reference(&tx_tex, NULL); -- -- if (!tx->surface) -- { -- pipe_surface_reference(&tx->surface, NULL); -- FREE(tx); -- return NULL; -- } -- -- if (usage & PIPE_TRANSFER_READ) { - struct nv40_screen *nvscreen = nv40_screen(pscreen); - struct nvfx_screen *nvscreen = nvfx_screen(pscreen); -- struct pipe_surface *src; -- -- src = pscreen->get_tex_surface(pscreen, pt, -- face, level, zslice, -- PIPE_BUFFER_USAGE_GPU_READ); -- -- /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ -- /* TODO: Check if SIFM can un-swizzle */ -- nvscreen->eng2d->copy(nvscreen->eng2d, -- tx->surface, 0, 0, -- src, x, y, -- w, h); -- -- pipe_surface_reference(&src, NULL); -- } -- -- return &tx->base; --} -- --static void --nv40_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx) --{ -- struct nv40_transfer *tx = (struct nv40_transfer *)ptx; -- -- if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { -- struct pipe_screen *pscreen = pcontext->screen; - struct nv40_screen *nvscreen = nv40_screen(pscreen); - struct nvfx_screen *nvscreen = nvfx_screen(pscreen); -- struct pipe_surface *dst; -- -- dst = pscreen->get_tex_surface(pscreen, ptx->texture, -- ptx->face, ptx->level, ptx->zslice, -- PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER); -- -- /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ -- nvscreen->eng2d->copy(nvscreen->eng2d, -- dst, tx->base.x, tx->base.y, -- tx->surface, 0, 0, -- tx->base.width, tx->base.height); -- -- pipe_surface_reference(&dst, NULL); -- } -- -- pipe_surface_reference(&tx->surface, NULL); -- pipe_texture_reference(&ptx->texture, NULL); -- FREE(ptx); --} -- --static void * --nv40_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx) --{ -- struct pipe_screen *pscreen = pcontext->screen; -- struct nv40_transfer *tx = (struct nv40_transfer *)ptx; -- struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture; - struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; -- void *map = pipe_buffer_map(pscreen, mt->buffer, -- pipe_transfer_buffer_flags(ptx)); -- -- if(!tx->direct) -- return map + ns->base.offset; -- else -- return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); --} -- --static void --nv40_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx) --{ -- struct pipe_screen *pscreen = pcontext->screen; -- struct nv40_transfer *tx = (struct nv40_transfer *)ptx; - struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture; - struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; -- -- pipe_buffer_unmap(pscreen, mt->buffer); --} -- --void - nv40_init_transfer_functions(struct nv40_context *nv40) -nv40_init_transfer_functions(struct nvfx_context *nvfx) --{ - nv40->pipe.get_tex_transfer = nv40_transfer_new; - nv40->pipe.tex_transfer_destroy = nv40_transfer_del; - nv40->pipe.transfer_map = nv40_transfer_map; - nv40->pipe.transfer_unmap = nv40_transfer_unmap; - nvfx->pipe.get_tex_transfer = nv40_transfer_new; - nvfx->pipe.tex_transfer_destroy = nv40_transfer_del; - nvfx->pipe.transfer_map = nv40_transfer_map; - nvfx->pipe.transfer_unmap = nv40_transfer_unmap; --} diff --cc src/gallium/drivers/nvfx/nvfx_context.h index 00000000000,5eed8a560e5..001b19eedf0 mode 000000,100644..100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@@ -1,0 -1,264 +1,265 @@@ + #ifndef __NVFX_CONTEXT_H__ + #define __NVFX_CONTEXT_H__ + + #include + + #include "pipe/p_context.h" + #include "pipe/p_defines.h" + #include "pipe/p_state.h" + #include "pipe/p_compiler.h" + + #include "util/u_memory.h" + #include "util/u_math.h" + #include "util/u_inlines.h" + + #include "draw/draw_vertex.h" + + #include "nouveau/nouveau_winsys.h" + #include "nouveau/nouveau_gldefs.h" + #include "nouveau/nouveau_context.h" + #include "nouveau/nouveau_stateobj.h" + + #include "nvfx_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); + + enum nvfx_state_index { + NVFX_STATE_FB = 0, + NVFX_STATE_VIEWPORT = 1, + NVFX_STATE_BLEND = 2, + NVFX_STATE_RAST = 3, + NVFX_STATE_ZSA = 4, + NVFX_STATE_BCOL = 5, + NVFX_STATE_CLIP = 6, + NVFX_STATE_SCISSOR = 7, + NVFX_STATE_STIPPLE = 8, + NVFX_STATE_FRAGPROG = 9, + NVFX_STATE_VERTPROG = 10, + NVFX_STATE_FRAGTEX0 = 11, + NVFX_STATE_FRAGTEX1 = 12, + NVFX_STATE_FRAGTEX2 = 13, + NVFX_STATE_FRAGTEX3 = 14, + NVFX_STATE_FRAGTEX4 = 15, + NVFX_STATE_FRAGTEX5 = 16, + NVFX_STATE_FRAGTEX6 = 17, + NVFX_STATE_FRAGTEX7 = 18, + NVFX_STATE_FRAGTEX8 = 19, + NVFX_STATE_FRAGTEX9 = 20, + NVFX_STATE_FRAGTEX10 = 21, + NVFX_STATE_FRAGTEX11 = 22, + NVFX_STATE_FRAGTEX12 = 23, + NVFX_STATE_FRAGTEX13 = 24, + NVFX_STATE_FRAGTEX14 = 25, + NVFX_STATE_FRAGTEX15 = 26, + NVFX_STATE_VERTTEX0 = 27, + NVFX_STATE_VERTTEX1 = 28, + NVFX_STATE_VERTTEX2 = 29, + NVFX_STATE_VERTTEX3 = 30, + NVFX_STATE_VTXBUF = 31, + NVFX_STATE_VTXFMT = 32, + NVFX_STATE_VTXATTR = 33, + NVFX_STATE_SR = 34, + NVFX_STATE_MAX = 35 + }; + + #include "nvfx_screen.h" + + #define NVFX_NEW_BLEND (1 << 0) + #define NVFX_NEW_RAST (1 << 1) + #define NVFX_NEW_ZSA (1 << 2) + #define NVFX_NEW_SAMPLER (1 << 3) + #define NVFX_NEW_FB (1 << 4) + #define NVFX_NEW_STIPPLE (1 << 5) + #define NVFX_NEW_SCISSOR (1 << 6) + #define NVFX_NEW_VIEWPORT (1 << 7) + #define NVFX_NEW_BCOL (1 << 8) + #define NVFX_NEW_VERTPROG (1 << 9) + #define NVFX_NEW_FRAGPROG (1 << 10) + #define NVFX_NEW_ARRAYS (1 << 11) + #define NVFX_NEW_UCP (1 << 12) + #define NVFX_NEW_SR (1 << 13) + + struct nvfx_rasterizer_state { + struct pipe_rasterizer_state pipe; + struct nouveau_stateobj *so; + }; + + struct nvfx_zsa_state { + struct pipe_depth_stencil_alpha_state pipe; + struct nouveau_stateobj *so; + }; + + struct nvfx_blend_state { + struct pipe_blend_state pipe; + struct nouveau_stateobj *so; + }; + + + struct nvfx_state { + unsigned scissor_enabled; + unsigned stipple_enabled; + unsigned fp_samplers; + + uint64_t dirty; + struct nouveau_stateobj *hw[NVFX_STATE_MAX]; + }; + + struct nvfx_vtxelt_state { + struct pipe_vertex_element pipe[16]; + unsigned num_elements; + }; + + struct nvfx_context { + struct pipe_context pipe; + + struct nouveau_winsys *nvws; + struct nvfx_screen *screen; + + unsigned is_nv4x; /* either 0 or ~0 */ + + struct draw_context *draw; + + /* HW state derived from pipe states */ + struct nvfx_state state; + struct { + struct nvfx_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, draw_dirty; + struct pipe_scissor_state scissor; + unsigned stipple[32]; + struct pipe_clip_state clip; + struct nvfx_vertex_program *vertprog; + struct nvfx_fragment_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + unsigned constbuf_nr[PIPE_SHADER_TYPES]; + struct nvfx_rasterizer_state *rasterizer; + struct nvfx_zsa_state *zsa; + struct nvfx_blend_state *blend; + struct pipe_blend_color blend_colour; + struct pipe_stencil_ref stencil_ref; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; + struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nvfx_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; ++ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + unsigned nr_textures; + unsigned dirty_samplers; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + unsigned vtxbuf_nr; + struct nvfx_vtxelt_state *vtxelt; + }; + + static INLINE struct nvfx_context * + nvfx_context(struct pipe_context *pipe) + { + return (struct nvfx_context *)pipe; + } + + struct nvfx_state_entry { + boolean (*validate)(struct nvfx_context *nvfx); + struct { + unsigned pipe; + unsigned hw; + } dirty; + }; + + extern struct nvfx_state_entry nvfx_state_blend; + extern struct nvfx_state_entry nvfx_state_blend_colour; + extern struct nvfx_state_entry nvfx_state_fragprog; + extern struct nvfx_state_entry nvfx_state_fragtex; + extern struct nvfx_state_entry nvfx_state_framebuffer; + extern struct nvfx_state_entry nvfx_state_rasterizer; + extern struct nvfx_state_entry nvfx_state_scissor; + extern struct nvfx_state_entry nvfx_state_sr; + extern struct nvfx_state_entry nvfx_state_stipple; + extern struct nvfx_state_entry nvfx_state_vbo; + extern struct nvfx_state_entry nvfx_state_vertprog; + extern struct nvfx_state_entry nvfx_state_viewport; + extern struct nvfx_state_entry nvfx_state_vtxfmt; + extern struct nvfx_state_entry nvfx_state_zsa; + + extern void nvfx_init_query_functions(struct nvfx_context *nvfx); + extern void nvfx_init_surface_functions(struct nvfx_context *nvfx); + + /* nvfx_context.c */ + struct pipe_context * + nvfx_create(struct pipe_screen *pscreen, void *priv); + + /* nvfx_clear.c */ + extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); + + /* nvfx_draw.c */ + extern struct draw_stage *nvfx_draw_render_stage(struct nvfx_context *nvfx); + extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, + unsigned ib_size, unsigned mode, + unsigned start, unsigned count); + + /* nvfx_fragprog.c */ + extern void nvfx_fragprog_destroy(struct nvfx_context *, + struct nvfx_fragment_program *); + + /* nv30_fragtex.c */ + extern void + nv30_sampler_state_init(struct pipe_context *pipe, + struct nvfx_sampler_state *ps, + const struct pipe_sampler_state *cso); + extern void nv30_fragtex_bind(struct nvfx_context *); + extern struct nouveau_stateobj * + nv30_fragtex_build(struct nvfx_context *nvfx, int unit); + + /* nv40_fragtex.c */ + extern void + nv40_sampler_state_init(struct pipe_context *pipe, + struct nvfx_sampler_state *ps, + const struct pipe_sampler_state *cso); + extern void nv40_fragtex_bind(struct nvfx_context *); + extern struct nouveau_stateobj * + nv40_fragtex_build(struct nvfx_context *nvfx, int unit); + + /* nvfx_state.c */ + extern void nvfx_init_state_functions(struct nvfx_context *nvfx); + + /* nvfx_state_emit.c */ + extern void nvfx_state_flush_notify(struct nouveau_channel *chan); + extern boolean nvfx_state_validate(struct nvfx_context *nvfx); + extern boolean nvfx_state_validate_swtnl(struct nvfx_context *nvfx); + extern void nvfx_state_emit(struct nvfx_context *nvfx); + + /* nvfx_transfer.c */ + extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx); + + /* nvfx_vbo.c */ + extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); + extern void nvfx_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count); + + /* nvfx_vertprog.c */ + extern void nvfx_vertprog_destroy(struct nvfx_context *, + struct nvfx_vertex_program *); + + #endif diff --cc src/gallium/drivers/nvfx/nvfx_state.c index 00000000000,88a9d01c509..32a81997528 mode 000000,100644..100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@@ -1,0 -1,619 +1,652 @@@ + #include "pipe/p_state.h" + #include "pipe/p_defines.h" + #include "util/u_inlines.h" + + #include "draw/draw_context.h" + + #include "tgsi/tgsi_parse.h" + + #include "nvfx_context.h" + #include "nvfx_state.h" + #include "nvfx_tex.h" + + static void * + nvfx_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nouveau_grobj *eng3d = nvfx->screen->eng3d; + struct nvfx_blend_state *bso = CALLOC(1, sizeof(*bso)); + struct nouveau_stateobj *so = so_new(5, 8, 0); + + if (cso->rt[0].blend_enable) { + so_method(so, eng3d, NV34TCL_BLEND_FUNC_ENABLE, 3); + so_data (so, 1); + so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) | + nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rt[0].rgb_dst_factor)); + if(nvfx->screen->base.device->chipset < 0x40) { + so_method(so, eng3d, NV34TCL_BLEND_EQUATION, 1); + so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); + } else { + so_method(so, eng3d, NV40TCL_BLEND_EQUATION, 1); + so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func) << 16 | + nvgl_blend_eqn(cso->rt[0].rgb_func)); + } + } else { + so_method(so, eng3d, NV34TCL_BLEND_FUNC_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, eng3d, NV34TCL_COLOR_MASK, 1); + so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + + /* TODO: add NV40 MRT color mask */ + + if (cso->logicop_enable) { + so_method(so, eng3d, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); + so_data (so, 1); + so_data (so, nvgl_logicop_func(cso->logicop_func)); + } else { + so_method(so, eng3d, NV34TCL_COLOR_LOGIC_OP_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, eng3d, NV34TCL_DITHER_ENABLE, 1); + so_data (so, cso->dither ? 1 : 0); + + so_ref(so, &bso->so); + so_ref(NULL, &so); + bso->pipe = *cso; + return (void *)bso; + } + + static void + nvfx_blend_state_bind(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->blend = hwcso; + nvfx->dirty |= NVFX_NEW_BLEND; + } + + static void + nvfx_blend_state_delete(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_blend_state *bso = hwcso; + + so_ref(NULL, &bso->so); + FREE(bso); + } + + static void * + nvfx_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_sampler_state *ps; + + ps = MALLOC(sizeof(struct nvfx_sampler_state)); + + /* on nv30, we use this as an internal flag */ + ps->fmt = cso->normalized_coords ? 0 : NV40TCL_TEX_FORMAT_RECT; + ps->en = 0; + ps->filt = nvfx_tex_filter(cso); + ps->wrap = (nvfx_tex_wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) | + (nvfx_tex_wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) | + (nvfx_tex_wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT) | + nvfx_tex_wrap_compare_mode(cso); + ps->bcol = nvfx_tex_border_color(cso->border_color); + + if(nvfx->is_nv4x) + nv40_sampler_state_init(pipe, ps, cso); + else + nv30_sampler_state_init(pipe, ps, cso); + + return (void *)ps; + } + + static void + nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nvfx->tex_sampler[unit] = sampler[unit]; + nvfx->dirty_samplers |= (1 << unit); + } + + for (unit = nr; unit < nvfx->nr_samplers; unit++) { + nvfx->tex_sampler[unit] = NULL; + nvfx->dirty_samplers |= (1 << unit); + } + + nvfx->nr_samplers = nr; + nvfx->dirty |= NVFX_NEW_SAMPLER; + } + + static void + nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso) + { + FREE(hwcso); + } + + static void -nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr, - struct pipe_texture **miptree) ++nvfx_set_fragment_sampler_views(struct pipe_context *pipe, ++ unsigned nr, ++ struct pipe_sampler_view **views) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { ++ pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit], ++ views[unit]); + pipe_texture_reference((struct pipe_texture **) + &nvfx->tex_miptree[unit], miptree[unit]); + nvfx->dirty_samplers |= (1 << unit); + } + + for (unit = nr; unit < nvfx->nr_textures; unit++) { ++ pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit], ++ NULL); + pipe_texture_reference((struct pipe_texture **) + &nvfx->tex_miptree[unit], NULL); + nvfx->dirty_samplers |= (1 << unit); + } + + nvfx->nr_textures = nr; + nvfx->dirty |= NVFX_NEW_SAMPLER; + } + ++ ++static struct pipe_sampler_view * ++nv30_create_sampler_view(struct pipe_context *pipe, ++ struct pipe_texture *texture, ++ const struct pipe_sampler_view *templ) ++{ ++ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); ++ ++ if (view) { ++ *view = *templ; ++ view->reference.count = 1; ++ view->texture = NULL; ++ pipe_texture_reference(&view->texture, texture); ++ view->context = pipe; ++ } ++ ++ return view; ++} ++ ++ ++static void ++nv30_sampler_view_destroy(struct pipe_context *pipe, ++ struct pipe_sampler_view *view) ++{ ++ pipe_texture_reference(&view->texture, NULL); ++ FREE(view); ++} ++ + static void * + nvfx_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); + struct nouveau_stateobj *so = so_new(9, 19, 0); + struct nouveau_grobj *eng3d = nvfx->screen->eng3d; + + /*XXX: ignored: + * light_twoside + * point_smooth -nohw + * multisample + */ + + so_method(so, eng3d, NV34TCL_SHADE_MODEL, 1); + so_data (so, cso->flatshade ? NV34TCL_SHADE_MODEL_FLAT : + NV34TCL_SHADE_MODEL_SMOOTH); + + so_method(so, eng3d, NV34TCL_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, eng3d, NV34TCL_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, eng3d, NV34TCL_POINT_SIZE, 1); + so_data (so, fui(cso->point_size)); + + so_method(so, eng3d, NV34TCL_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, NV34TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_CW: + so_data(so, NV34TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV34TCL_CULL_FACE_BACK); + break; + } + so_data(so, NV34TCL_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, NV34TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_CW: + so_data(so, NV34TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV34TCL_CULL_FACE_BACK); + break; + } + so_data(so, NV34TCL_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, eng3d, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, cso->poly_stipple_enable ? 1 : 0); + + so_method(so, eng3d, NV34TCL_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); + 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, eng3d, NV34TCL_POLYGON_OFFSET_FACTOR, 2); + so_data (so, fui(cso->offset_scale)); + so_data (so, fui(cso->offset_units * 2)); + } + + so_method(so, eng3d, NV34TCL_POINT_SPRITE, 1); + if (cso->point_quad_rasterization) { + unsigned psctl = (1 << 0), i; + + for (i = 0; i < 8; i++) { + if ((cso->sprite_coord_enable >> i) & 1) + psctl |= (1 << (8 + i)); + } + + so_data(so, psctl); + } else { + so_data(so, 0); + } + + so_ref(so, &rsso->so); + so_ref(NULL, &so); + rsso->pipe = *cso; + return (void *)rsso; + } + + static void + nvfx_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->rasterizer = hwcso; + nvfx->dirty |= NVFX_NEW_RAST; + nvfx->draw_dirty |= NVFX_NEW_RAST; + } + + static void + nvfx_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_rasterizer_state *rsso = hwcso; + + so_ref(NULL, &rsso->so); + FREE(rsso); + } + + static void * + nvfx_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); + struct nouveau_stateobj *so = so_new(6, 20, 0); + struct nouveau_grobj *eng3d = nvfx->screen->eng3d; + + so_method(so, eng3d, NV34TCL_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, eng3d, NV34TCL_ALPHA_FUNC_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_value)); + + if (cso->stencil[0].enabled) { + so_method(so, eng3d, NV34TCL_STENCIL_FRONT_ENABLE, 3); + so_data (so, cso->stencil[0].enabled ? 1 : 0); + so_data (so, cso->stencil[0].writemask); + so_data (so, nvgl_comparison_op(cso->stencil[0].func)); + so_method(so, eng3d, NV34TCL_STENCIL_FRONT_FUNC_MASK, 4); + 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)); + } else { + so_method(so, eng3d, NV34TCL_STENCIL_FRONT_ENABLE, 1); + so_data (so, 0); + } + + if (cso->stencil[1].enabled) { + so_method(so, eng3d, NV34TCL_STENCIL_BACK_ENABLE, 3); + so_data (so, cso->stencil[1].enabled ? 1 : 0); + so_data (so, cso->stencil[1].writemask); + so_data (so, nvgl_comparison_op(cso->stencil[1].func)); + so_method(so, eng3d, NV34TCL_STENCIL_BACK_FUNC_MASK, 4); + 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)); + } else { + so_method(so, eng3d, NV34TCL_STENCIL_BACK_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &zsaso->so); + so_ref(NULL, &so); + zsaso->pipe = *cso; + return (void *)zsaso; + } + + static void + nvfx_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->zsa = hwcso; + nvfx->dirty |= NVFX_NEW_ZSA; + } + + static void + nvfx_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_zsa_state *zsaso = hwcso; + + so_ref(NULL, &zsaso->so); + FREE(zsaso); + } + + static void * + nvfx_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nvfx_vertex_program)); + vp->pipe.tokens = tgsi_dup_tokens(cso->tokens); + vp->draw = draw_create_vertex_shader(nvfx->draw, &vp->pipe); + + return (void *)vp; + } + + static void + nvfx_vp_state_bind(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->vertprog = hwcso; + nvfx->dirty |= NVFX_NEW_VERTPROG; + nvfx->draw_dirty |= NVFX_NEW_VERTPROG; + } + + static void + nvfx_vp_state_delete(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_vertex_program *vp = hwcso; + + draw_delete_vertex_shader(nvfx->draw, vp->draw); + nvfx_vertprog_destroy(nvfx, vp); + FREE((void*)vp->pipe.tokens); + FREE(vp); + } + + static void * + nvfx_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) + { + struct nvfx_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nvfx_fragment_program)); + fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); + + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + + return (void *)fp; + } + + static void + nvfx_fp_state_bind(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->fragprog = hwcso; + nvfx->dirty |= NVFX_NEW_FRAGPROG; + } + + static void + nvfx_fp_state_delete(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_fragment_program *fp = hwcso; + + nvfx_fragprog_destroy(nvfx, fp); + FREE((void*)fp->pipe.tokens); + FREE(fp); + } + + static void + nvfx_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->blend_colour = *bcol; + nvfx->dirty |= NVFX_NEW_BCOL; + } + + static void + nvfx_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *sr) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->stencil_ref = *sr; + nvfx->dirty |= NVFX_NEW_SR; + } + + static void + nvfx_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->clip = *clip; + nvfx->dirty |= NVFX_NEW_UCP; + nvfx->draw_dirty |= NVFX_NEW_UCP; + } + + static void + nvfx_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + struct pipe_buffer *buf ) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->constbuf[shader] = buf; + nvfx->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); + + if (shader == PIPE_SHADER_VERTEX) { + nvfx->dirty |= NVFX_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nvfx->dirty |= NVFX_NEW_FRAGPROG; + } + } + + static void + nvfx_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->framebuffer = *fb; + nvfx->dirty |= NVFX_NEW_FB; + } + + static void + nvfx_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + memcpy(nvfx->stipple, stipple->stipple, 4 * 32); + nvfx->dirty |= NVFX_NEW_STIPPLE; + } + + static void + nvfx_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->scissor = *s; + nvfx->dirty |= NVFX_NEW_SCISSOR; + } + + static void + nvfx_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->viewport = *vpt; + nvfx->dirty |= NVFX_NEW_VIEWPORT; + nvfx->draw_dirty |= NVFX_NEW_VIEWPORT; + } + + static void + nvfx_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + memcpy(nvfx->vtxbuf, vb, sizeof(*vb) * count); + nvfx->vtxbuf_nr = count; + + nvfx->dirty |= NVFX_NEW_ARRAYS; + nvfx->draw_dirty |= NVFX_NEW_ARRAYS; + } + + static void * + nvfx_vtxelts_state_create(struct pipe_context *pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) + { + struct nvfx_vtxelt_state *cso = CALLOC_STRUCT(nvfx_vtxelt_state); + + assert(num_elements < 16); /* not doing fallbacks yet */ + cso->num_elements = num_elements; + memcpy(cso->pipe, elements, num_elements * sizeof(*elements)); + + /* nvfx_vtxelt_construct(cso);*/ + + return (void *)cso; + } + + static void + nvfx_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso) + { + FREE(hwcso); + } + + static void + nvfx_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso) + { + struct nvfx_context *nvfx = nvfx_context(pipe); + + nvfx->vtxelt = hwcso; + nvfx->dirty |= NVFX_NEW_ARRAYS; + /*nvfx->draw_dirty |= NVFX_NEW_ARRAYS;*/ + } + + void + nvfx_init_state_functions(struct nvfx_context *nvfx) + { + nvfx->pipe.create_blend_state = nvfx_blend_state_create; + nvfx->pipe.bind_blend_state = nvfx_blend_state_bind; + nvfx->pipe.delete_blend_state = nvfx_blend_state_delete; + + nvfx->pipe.create_sampler_state = nvfx_sampler_state_create; + nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind; + nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete; + nvfx->pipe.set_fragment_sampler_textures = nvfx_set_sampler_texture; + + nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create; + nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind; + nvfx->pipe.delete_rasterizer_state = nvfx_rasterizer_state_delete; + + nvfx->pipe.create_depth_stencil_alpha_state = + nvfx_depth_stencil_alpha_state_create; + nvfx->pipe.bind_depth_stencil_alpha_state = + nvfx_depth_stencil_alpha_state_bind; + nvfx->pipe.delete_depth_stencil_alpha_state = + nvfx_depth_stencil_alpha_state_delete; + + nvfx->pipe.create_vs_state = nvfx_vp_state_create; + nvfx->pipe.bind_vs_state = nvfx_vp_state_bind; + nvfx->pipe.delete_vs_state = nvfx_vp_state_delete; + + nvfx->pipe.create_fs_state = nvfx_fp_state_create; + nvfx->pipe.bind_fs_state = nvfx_fp_state_bind; + nvfx->pipe.delete_fs_state = nvfx_fp_state_delete; + + nvfx->pipe.set_blend_color = nvfx_set_blend_color; + nvfx->pipe.set_stencil_ref = nvfx_set_stencil_ref; + nvfx->pipe.set_clip_state = nvfx_set_clip_state; + nvfx->pipe.set_constant_buffer = nvfx_set_constant_buffer; + nvfx->pipe.set_framebuffer_state = nvfx_set_framebuffer_state; + nvfx->pipe.set_polygon_stipple = nvfx_set_polygon_stipple; + nvfx->pipe.set_scissor_state = nvfx_set_scissor_state; + nvfx->pipe.set_viewport_state = nvfx_set_viewport_state; + + nvfx->pipe.create_vertex_elements_state = nvfx_vtxelts_state_create; + nvfx->pipe.delete_vertex_elements_state = nvfx_vtxelts_state_delete; + nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind; + + nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers; + } diff --cc src/gallium/drivers/r300/r300_emit.c index fc8a8a27738,d8c64dd9001..0a3f0f45c03 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@@ -1034,12 -1042,12 +1042,12 @@@ validate } } /* ...textures... */ - for (i = 0; i < texstate->count; i++) { - tex = texstate->textures[i]; - if (!tex || !texstate->sampler_states[i]) + for (i = 0; i < r300->fragment_sampler_view_count; i++) { + if (!r300->fragment_sampler_views[i]) continue; + tex = (struct r300_texture *)r300->fragment_sampler_views[i]->texture; - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { + if (!r300_add_texture(r300->rws, tex, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; }