nv30: Emit sampler state using state objects
authorPatrice Mandin <pmandin@caramail.com>
Fri, 4 Jul 2008 16:53:44 +0000 (18:53 +0200)
committerPatrice Mandin <pmandin@caramail.com>
Fri, 4 Jul 2008 16:53:44 +0000 (18:53 +0200)
src/gallium/drivers/nv30/nv30_context.h
src/gallium/drivers/nv30/nv30_state.c
src/gallium/drivers/nv30/nv30_state_emit.c

index 0ad1dc6f912a4a7a80c813f6fa5cb360c0543082..5404685da258193b959460648f6e5cfcb449125d 100644 (file)
@@ -96,6 +96,7 @@ struct nv30_state {
        unsigned scissor_enabled;
        unsigned stipple_enabled;
        unsigned viewport_bypass;
+       unsigned fp_samplers;
 
        uint64_t dirty;
        struct nouveau_stateobj *hw[NV30_STATE_MAX];
@@ -129,6 +130,8 @@ struct nv30_context {
        struct pipe_blend_color blend_colour;
        struct pipe_viewport_state viewport;
        struct pipe_framebuffer_state framebuffer;
+       unsigned nr_samplers;
+       unsigned nr_textures;
 
        uint32_t rt_enable;
        struct pipe_buffer *rt[2];
index e65c4b215d4121f013e134e1bc8160579458214b..97becd2be378f52de94b1b94347982560fdac99a 100644 (file)
@@ -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 "nv30_context.h"
 #include "nv30_state.h"
@@ -116,7 +117,7 @@ nv30_sampler_state_create(struct pipe_context *pipe,
        struct nv30_sampler_state *ps;
        uint32_t filter = 0;
 
-       ps = malloc(sizeof(struct nv30_sampler_state));
+       ps = MALLOC(sizeof(struct nv30_sampler_state));
 
        ps->fmt = 0;
        if (!cso->normalized_coords)
@@ -197,6 +198,19 @@ nv30_sampler_state_create(struct pipe_context *pipe,
 
        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:
@@ -242,20 +256,24 @@ nv30_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
        struct nv30_context *nv30 = nv30_context(pipe);
        unsigned unit;
 
-       if (!sampler) {
-               return;
-       }
-
        for (unit = 0; unit < nr; unit++) {
                nv30->tex_sampler[unit] = sampler[unit];
                nv30->dirty_samplers |= (1 << unit);
        }
+
+       for (unit = nr; unit < nv30->nr_samplers; unit++) {
+               nv30->tex_sampler[unit] = NULL;
+               nv30->dirty_samplers |= (1 << unit);
+       }
+
+       nv30->nr_samplers = nr;
+       nv30->dirty |= NV30_NEW_SAMPLER;
 }
 
 static void
 nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
 {
-       free(hwcso);
+       FREE(hwcso);
 }
 
 static void
@@ -266,9 +284,19 @@ nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
        unsigned unit;
 
        for (unit = 0; unit < nr; unit++) {
-               nv30->tex_miptree[unit] = (struct nv30_miptree *)miptree[unit];
+               pipe_texture_reference((struct pipe_texture **)
+                                      &nv30->tex_miptree[unit], miptree[unit]);
                nv30->dirty_samplers |= (1 << unit);
        }
+
+       for (unit = nr; unit < nv30->nr_textures; unit++) {
+               pipe_texture_reference((struct pipe_texture **)
+                                      &nv30->tex_miptree[unit], NULL);
+               nv30->dirty_samplers |= (1 << unit);
+       }
+
+       nv30->nr_textures = nr;
+       nv30->dirty |= NV30_NEW_SAMPLER;
 }
 
 static void *
index eca1f0652cc68ed185e81618137d4d8aec10eb72..0ea7857197252ab55f2479264b3c6730973ae67e 100644 (file)
@@ -47,7 +47,7 @@ nv30_emit_hw_state(struct nv30_context *nv30)
 {
        struct nv30_state *state = &nv30->state;
        struct nv30_screen *screen = nv30->screen;
-       unsigned i;
+       unsigned i, samplers;
        uint64 states;
 
        if (nv30->pctx_id != screen->cur_pctx) {
@@ -91,6 +91,13 @@ nv30_emit_hw_state(struct nv30_context *nv30)
        nv30->dirty_samplers = 0;
 
        so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
+       for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
+               if (!(samplers & (1 << i)))
+                       continue;
+               so_emit_reloc_markers(nv30->nvws,
+                                     state->hw[NV30_STATE_FRAGTEX0+i]);
+               samplers &= ~(1ULL << i);
+       }
 
        /* Texture images, emitted in nv30_fragtex_build */
 #if 0