+++ /dev/null
--#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;
--}
--- /dev/null
+ #ifndef __NVFX_CONTEXT_H__
+ #define __NVFX_CONTEXT_H__
+
+ #include <stdio.h>
+
+ #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
--- /dev/null
-nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
- struct pipe_texture **miptree)
+ #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_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;
+ }