OSDN Git Service

gallium: michel's patch to rework texture/sampler binding interface
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 5 Mar 2008 09:50:14 +0000 (10:50 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Wed, 5 Mar 2008 09:56:49 +0000 (10:56 +0100)
Bind all the samplers/textures at once rather than piecemeal.
This is easier for drivers to understand.

25 files changed:
src/gallium/auxiliary/draw/draw_aaline.c
src/gallium/auxiliary/draw/draw_pstipple.c
src/gallium/drivers/failover/fo_context.h
src/gallium/drivers/failover/fo_state.c
src/gallium/drivers/failover/fo_state_emit.c
src/gallium/drivers/i915simple/i915_context.h
src/gallium/drivers/i915simple/i915_state.c
src/gallium/drivers/i915simple/i915_state_emit.c
src/gallium/drivers/i915simple/i915_state_sampler.c
src/gallium/drivers/i965simple/brw_context.h
src/gallium/drivers/i965simple/brw_state.c
src/gallium/drivers/i965simple/brw_wm_sampler_state.c
src/gallium/drivers/i965simple/brw_wm_surface_state.c
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_quad_fs.c
src/gallium/drivers/softpipe/sp_state.h
src/gallium/drivers/softpipe/sp_state_sampler.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/include/pipe/p_context.h
src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_gen_mipmap.c

index 7660e56..3ec73b0 100644 (file)
@@ -78,7 +78,8 @@ struct aaline_stage
 
    void *sampler_cso;
    struct pipe_texture *texture;
-   uint sampler_unit;
+   uint num_samplers;
+   uint num_textures;
 
 
    /*
@@ -98,11 +99,10 @@ struct aaline_stage
    void (*driver_bind_fs_state)(struct pipe_context *, void *);
    void (*driver_delete_fs_state)(struct pipe_context *, void *);
 
-   void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *);
-
-   void (*driver_set_sampler_texture)(struct pipe_context *,
-                                      unsigned sampler,
-                                      struct pipe_texture *);
+   void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
+                                      void **);
+   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
+                                       struct pipe_texture **);
 
    struct pipe_context *pipe;
 };
@@ -607,6 +607,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
    auto struct aaline_stage *aaline = aaline_stage(stage);
    struct draw_context *draw = stage->draw;
    struct pipe_context *pipe = aaline->pipe;
+   uint num = MAX2(aaline->num_textures, aaline->num_samplers);
 
    assert(draw->rasterizer->line_smooth);
 
@@ -624,8 +625,11 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
     */
    bind_aaline_fragment_shader(aaline);
 
-   aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, aaline->sampler_cso);
-   aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, aaline->texture);
+   aaline->state.sampler[num] = aaline->sampler_cso;
+   aaline->state.texture[num] = aaline->texture;
+
+   aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler);
+   aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture);
 
    /* now really draw first line */
    stage->line = aaline_line;
@@ -647,10 +651,10 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
    aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
 
    /* XXX restore original texture, sampler state */
-   aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit,
-                                 aaline->state.sampler[aaline->sampler_unit]);
-   aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit,
-                                 aaline->state.texture[aaline->sampler_unit]);
+   aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
+                                      aaline->state.sampler);
+   aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
+                                       aaline->state.texture);
 
    draw->extra_vp_outputs.slot = 0;
 }
@@ -745,26 +749,28 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
 
 
 static void
-aaline_bind_sampler_state(struct pipe_context *pipe,
-                          unsigned unit, void *sampler)
+aaline_bind_sampler_states(struct pipe_context *pipe,
+                           unsigned num, void **sampler)
 {
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    /* save current */
-   aaline->state.sampler[unit] = sampler;
+   memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
+   aaline->num_samplers = num;
    /* pass-through */
-   aaline->driver_bind_sampler_state(aaline->pipe, unit, sampler);
+   aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
 }
 
 
 static void
-aaline_set_sampler_texture(struct pipe_context *pipe,
-                           unsigned sampler, struct pipe_texture *texture)
+aaline_set_sampler_textures(struct pipe_context *pipe,
+                            unsigned num, struct pipe_texture **texture)
 {
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    /* save current */
-   aaline->state.texture[sampler] = texture;
+   memcpy(aaline->state.texture, texture, num * sizeof(struct pipe_texture *));
+   aaline->num_textures = num;
    /* pass-through */
-   aaline->driver_set_sampler_texture(aaline->pipe, sampler, texture);
+   aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
 }
 
 
@@ -798,14 +804,14 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
    aaline->driver_bind_fs_state = pipe->bind_fs_state;
    aaline->driver_delete_fs_state = pipe->delete_fs_state;
 
-   aaline->driver_bind_sampler_state = pipe->bind_sampler_state;
-   aaline->driver_set_sampler_texture = pipe->set_sampler_texture;
+   aaline->driver_bind_sampler_states = pipe->bind_sampler_states;
+   aaline->driver_set_sampler_textures = pipe->set_sampler_textures;
 
    /* override the driver's functions */
    pipe->create_fs_state = aaline_create_fs_state;
    pipe->bind_fs_state = aaline_bind_fs_state;
    pipe->delete_fs_state = aaline_delete_fs_state;
 
-   pipe->bind_sampler_state = aaline_bind_sampler_state;
-   pipe->set_sampler_texture = aaline_set_sampler_texture;
+   pipe->bind_sampler_states = aaline_bind_sampler_states;
+   pipe->set_sampler_textures = aaline_set_sampler_textures;
 }
index 2cfeb81..894b136 100644 (file)
@@ -68,7 +68,8 @@ struct pstip_stage
 
    void *sampler_cso;
    struct pipe_texture *texture;
-   uint sampler_unit;
+   uint num_samplers;
+   uint num_textures;
 
    /*
     * Currently bound state
@@ -88,11 +89,10 @@ struct pstip_stage
    void (*driver_bind_fs_state)(struct pipe_context *, void *);
    void (*driver_delete_fs_state)(struct pipe_context *, void *);
 
-   void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *);
+   void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **);
 
-   void (*driver_set_sampler_texture)(struct pipe_context *,
-                                      unsigned sampler,
-                                      struct pipe_texture *);
+   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
+                                       struct pipe_texture **);
 
    void (*driver_set_polygon_stipple)(struct pipe_context *,
                                       const struct pipe_poly_stipple *);
@@ -328,8 +328,6 @@ generate_pstip_fs(struct pstip_stage *pstip)
    tgsi_dump(pstip_fs.tokens, 0);
 #endif
 
-   pstip->sampler_unit = transform.maxSampler + 1;
-
 #if 1 /* XXX remove */
    if (transform.wincoordInput < 0) {
       pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION;
@@ -486,6 +484,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
    struct pstip_stage *pstip = pstip_stage(stage);
    struct draw_context *draw = stage->draw;
    struct pipe_context *pipe = pstip->pipe;
+   uint num = MAX2(pstip->num_textures, pstip->num_samplers);
 
    assert(draw->rasterizer->poly_stipple_enable);
 
@@ -494,8 +493,8 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
     */
    bind_pstip_fragment_shader(pstip);
 
-   pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, pstip->sampler_cso);
-   pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, pstip->texture);
+   pstip->driver_bind_sampler_states(pipe, num + 1, pstip->state.sampler);
+   pstip->driver_set_sampler_textures(pipe, num + 1, pstip->state.texture);
 
    /* now really draw first line */
    stage->tri = passthrough_tri;
@@ -517,10 +516,10 @@ pstip_flush(struct draw_stage *stage, unsigned flags)
    pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
 
    /* XXX restore original texture, sampler state */
-   pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit,
-                                 pstip->state.sampler[pstip->sampler_unit]);
-   pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit,
-                                 pstip->state.texture[pstip->sampler_unit]);
+   pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
+                                     pstip->state.sampler);
+   pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
+                                      pstip->state.texture);
 }
 
 
@@ -613,26 +612,28 @@ pstip_delete_fs_state(struct pipe_context *pipe, void *fs)
 
 
 static void
-pstip_bind_sampler_state(struct pipe_context *pipe,
-                         unsigned unit, void *sampler)
+pstip_bind_sampler_states(struct pipe_context *pipe,
+                          unsigned num, void **sampler)
 {
    struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
    /* save current */
-   pstip->state.sampler[unit] = sampler;
+   memcpy(pstip->state.sampler, sampler, num * sizeof(void *));
+   pstip->num_samplers = num;
    /* pass-through */
-   pstip->driver_bind_sampler_state(pstip->pipe, unit, sampler);
+   pstip->driver_bind_sampler_states(pstip->pipe, num, sampler);
 }
 
 
 static void
-pstip_set_sampler_texture(struct pipe_context *pipe,
-                          unsigned sampler, struct pipe_texture *texture)
+pstip_set_sampler_textures(struct pipe_context *pipe,
+                           unsigned num, struct pipe_texture **texture)
 {
    struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
    /* save current */
-   pstip->state.texture[sampler] = texture;
+   memcpy(pstip->state.texture, texture, num * sizeof(struct pipe_texture *));
+   pstip->num_textures = num;
    /* pass-through */
-   pstip->driver_set_sampler_texture(pstip->pipe, sampler, texture);
+   pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
 }
 
 
@@ -682,8 +683,8 @@ draw_install_pstipple_stage(struct draw_context *draw,
    pstip->driver_bind_fs_state = pipe->bind_fs_state;
    pstip->driver_delete_fs_state = pipe->delete_fs_state;
 
-   pstip->driver_bind_sampler_state = pipe->bind_sampler_state;
-   pstip->driver_set_sampler_texture = pipe->set_sampler_texture;
+   pstip->driver_bind_sampler_states = pipe->bind_sampler_states;
+   pstip->driver_set_sampler_textures = pipe->set_sampler_textures;
    pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
 
    /* override the driver's functions */
@@ -691,7 +692,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
    pipe->bind_fs_state = pstip_bind_fs_state;
    pipe->delete_fs_state = pstip_delete_fs_state;
 
-   pipe->bind_sampler_state = pstip_bind_sampler_state;
-   pipe->set_sampler_texture = pstip_set_sampler_texture;
+   pipe->bind_sampler_states = pstip_bind_sampler_states;
+   pipe->set_sampler_textures = pstip_set_sampler_textures;
    pipe->set_polygon_stipple = pstip_set_polygon_stipple;
 }
index 1dc8729..8f3ad3e 100644 (file)
@@ -87,12 +87,15 @@ struct failover_context {
    struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
    struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
 
+   void *sw_sampler_state[PIPE_MAX_SAMPLERS];
+   void *hw_sampler_state[PIPE_MAX_SAMPLERS];
+
    unsigned dirty;
-   unsigned dirty_sampler;
-   unsigned dirty_texture;
    unsigned dirty_vertex_buffer;
    unsigned dirty_vertex_element;
 
+   unsigned num_samplers;
+   unsigned num_textures;
 
    unsigned mode;
    struct pipe_context *hw;
index 0fc5568..11eec27 100644 (file)
@@ -28,6 +28,8 @@
 /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
  */
 
+#include "pipe/p_inlines.h"
+
 #include "fo_context.h"
 
 
@@ -322,18 +324,27 @@ failover_create_sampler_state(struct pipe_context *pipe,
 }
 
 static void
-failover_bind_sampler_state(struct pipe_context *pipe,
-                          unsigned unit, void *sampler)
+failover_bind_sampler_states(struct pipe_context *pipe,
+                             unsigned num, void **sampler)
 {
    struct failover_context *failover = failover_context(pipe);
    struct fo_state *state = (struct fo_state*)sampler;
-   failover->sampler[unit] = state;
+   uint i;
+   assert(num <= PIPE_MAX_SAMPLERS);
+   /* Check for no-op */
+   if (num == failover->num_samplers &&
+       !memcmp(failover->sampler, sampler, num * sizeof(void *)))
+      return;
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      failover->sw_sampler_state[i] = i < num ? state[i].sw_state : NULL;
+      failover->hw_sampler_state[i] = i < num ? state[i].hw_state : NULL;
+   }
    failover->dirty |= FO_NEW_SAMPLER;
-   failover->dirty_sampler |= (1<<unit);
-   failover->sw->bind_sampler_state(failover->sw, unit,
-                                    state->sw_state);
-   failover->hw->bind_sampler_state(failover->hw, unit,
-                                    state->hw_state);
+   failover->num_samplers = num;
+   failover->sw->bind_sampler_states(failover->sw, num,
+                                     failover->sw_sampler_state);
+   failover->hw->bind_sampler_states(failover->hw, num,
+                                     failover->hw_sampler_state);
 }
 
 static void
@@ -351,17 +362,29 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
 
 
 static void
-failover_set_sampler_texture(struct pipe_context *pipe,
-                            unsigned unit,
-                            struct pipe_texture *texture)
+failover_set_sampler_textures(struct pipe_context *pipe,
+                              unsigned num,
+                              struct pipe_texture **texture)
 {
    struct failover_context *failover = failover_context(pipe);
-
-   failover->texture[unit] = texture;
+   uint i;
+
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == failover->num_textures &&
+       !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *)))
+      return;
+   for (i = 0; i < num; i++)
+      pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
+                             texture[i]);
+   for (i = num; i < failover->num_textures; i++)
+      pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
+                             NULL);
    failover->dirty |= FO_NEW_TEXTURE;
-   failover->dirty_texture |= (1<<unit);
-   failover->sw->set_sampler_texture( failover->sw, unit, texture );
-   failover->hw->set_sampler_texture( failover->hw, unit, texture );
+   failover->num_textures = num;
+   failover->sw->set_sampler_textures( failover->sw, num, texture );
+   failover->hw->set_sampler_textures( failover->hw, num, texture );
 }
 
 
@@ -429,7 +452,7 @@ failover_init_state_functions( struct failover_context *failover )
    failover->pipe.bind_blend_state   = failover_bind_blend_state;
    failover->pipe.delete_blend_state = failover_delete_blend_state;
    failover->pipe.create_sampler_state = failover_create_sampler_state;
-   failover->pipe.bind_sampler_state   = failover_bind_sampler_state;
+   failover->pipe.bind_sampler_states  = failover_bind_sampler_states;
    failover->pipe.delete_sampler_state = failover_delete_sampler_state;
    failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state;
    failover->pipe.bind_depth_stencil_alpha_state   = failover_bind_depth_stencil_state;
@@ -449,7 +472,7 @@ failover_init_state_functions( struct failover_context *failover )
    failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
    failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
    failover->pipe.set_scissor_state = failover_set_scissor_state;
-   failover->pipe.set_sampler_texture = failover_set_sampler_texture;
+   failover->pipe.set_sampler_textures = failover_set_sampler_textures;
    failover->pipe.set_viewport_state = failover_set_viewport_state;
    failover->pipe.set_vertex_buffer = failover_set_vertex_buffer;
    failover->pipe.set_vertex_element = failover_set_vertex_element;
index c663dd4..3de931e 100644 (file)
@@ -94,21 +94,13 @@ failover_state_emit( struct failover_context *failover )
       failover->sw->set_viewport_state( failover->sw, &failover->viewport );
 
    if (failover->dirty & FO_NEW_SAMPLER) {
-      for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-        if (failover->dirty_sampler & (1<<i)) {
-           failover->sw->bind_sampler_state( failover->sw, i,
-                                              failover->sampler[i]->sw_state );
-        }
-      }
+      failover->sw->bind_sampler_states( failover->sw, failover->num_samplers,
+                                         failover->sw_sampler_state );
    }
 
    if (failover->dirty & FO_NEW_TEXTURE) {
-      for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-        if (failover->dirty_texture & (1<<i)) {
-           failover->sw->set_sampler_texture( failover->sw, i, 
-                                            failover->texture[i] );
-        }
-      }
+      failover->sw->set_sampler_textures( failover->sw, failover->num_textures, 
+                                          failover->texture );
    }
 
    if (failover->dirty & FO_NEW_VERTEX_BUFFER) {
@@ -132,6 +124,4 @@ failover_state_emit( struct failover_context *failover )
    failover->dirty = 0;
    failover->dirty_vertex_element = 0;
    failover->dirty_vertex_buffer = 0;
-   failover->dirty_texture = 0;
-   failover->dirty_sampler = 0;
 }
index 6401112..746f18b 100644 (file)
- /**************************************************************************
- * 
- * 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.
- * 
- **************************************************************************/
-
-#ifndef I915_CONTEXT_H
-#define I915_CONTEXT_H
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-
-#include "draw/draw_vertex.h"
-
-#include "tgsi/util/tgsi_scan.h"
-
-
-#define I915_TEX_UNITS 8
-
-#define I915_DYNAMIC_MODES4       0
-#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */
-#define I915_DYNAMIC_DEPTHSCALE_1 2 
-#define I915_DYNAMIC_IAB          3
-#define I915_DYNAMIC_BC_0         4 /* just the header */
-#define I915_DYNAMIC_BC_1         5
-#define I915_DYNAMIC_BFO_0        6 
-#define I915_DYNAMIC_BFO_1        7
-#define I915_DYNAMIC_STP_0        8 
-#define I915_DYNAMIC_STP_1        9 
-#define I915_DYNAMIC_SC_ENA_0     10 
-#define I915_DYNAMIC_SC_RECT_0    11 
-#define I915_DYNAMIC_SC_RECT_1    12 
-#define I915_DYNAMIC_SC_RECT_2    13 
-#define I915_MAX_DYNAMIC          14
-
-
-#define I915_IMMEDIATE_S0         0
-#define I915_IMMEDIATE_S1         1
-#define I915_IMMEDIATE_S2         2
-#define I915_IMMEDIATE_S3         3
-#define I915_IMMEDIATE_S4         4
-#define I915_IMMEDIATE_S5         5
-#define I915_IMMEDIATE_S6         6
-#define I915_IMMEDIATE_S7         7
-#define I915_MAX_IMMEDIATE        8
-
-/* These must mach the order of LI0_STATE_* bits, as they will be used
- * to generate hardware packets:
- */
-#define I915_CACHE_STATIC         0 
-#define I915_CACHE_DYNAMIC        1 /* handled specially */
-#define I915_CACHE_SAMPLER        2
-#define I915_CACHE_MAP            3
-#define I915_CACHE_PROGRAM        4
-#define I915_CACHE_CONSTANTS      5
-#define I915_MAX_CACHE            6
-
-#define I915_MAX_CONSTANT  32
-
-
-/** See constant_flags[] below */
-#define I915_CONSTFLAG_USER 0x1f
-
-
-/**
- * Subclass of pipe_shader_state
- */
-struct i915_fragment_shader
-{
-   struct pipe_shader_state state;
-
-   struct tgsi_shader_info info;
-
-   uint *program;
-   uint program_len;
-
-   /**
-    * constants introduced during translation.
-    * These are placed at the end of the constant buffer and grow toward
-    * the beginning (eg: slot 31, 30 29, ...)
-    * User-provided constants start at 0.
-    * This allows both types of constants to co-exist (until there's too many)
-    * and doesn't require regenerating/changing the fragment program to
-    * shuffle constants around.
-    */
-   uint num_constants;
-   float constants[I915_MAX_CONSTANT][4];
-
-   /**
-    * Status of each constant
-    * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding
-    * slot of the user's constant buffer. (set by pipe->set_constant_buffer())
-    * Else, the bitmask indicates which components are occupied by immediates.
-    */
-   ubyte constant_flags[I915_MAX_CONSTANT];
-};
-
-
-struct i915_cache_context;
-
-/* Use to calculate differences between state emitted to hardware and
- * current driver-calculated state.  
- */
-struct i915_state 
-{
-   unsigned immediate[I915_MAX_IMMEDIATE];
-   unsigned dynamic[I915_MAX_DYNAMIC];
-
-   float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];
-   /** number of constants passed in through a constant buffer */
-   uint num_user_constants[PIPE_SHADER_TYPES];
-
-   /* texture sampler state */
-   unsigned sampler[I915_TEX_UNITS][3];
-   unsigned sampler_enable_flags;
-   unsigned sampler_enable_nr;
-
-   /* texture image buffers */
-   unsigned texbuffer[I915_TEX_UNITS][2];
-
-   /** Describes the current hardware vertex layout */
-   struct vertex_info vertex_info;
-   
-   unsigned id;                        /* track lost context events */
-};
-
-struct i915_blend_state {
-   unsigned iab;
-   unsigned modes4;
-   unsigned LIS5;
-   unsigned LIS6;
-};
-
-struct i915_depth_stencil_state {
-   unsigned stencil_modes4;
-   unsigned bfo[2];
-   unsigned stencil_LIS5;
-   unsigned depth_LIS6;
-};
-
-struct i915_rasterizer_state {
-   int light_twoside : 1;
-   unsigned st;
-   enum interp_mode color_interp;
-
-   unsigned LIS4;
-   unsigned LIS7;
-   unsigned sc[1];
-
-   const struct pipe_rasterizer_state *templ;
-
-   union { float f; unsigned u; } ds[2];
-};
-
-struct i915_sampler_state {
-   unsigned state[3];
-   const struct pipe_sampler_state *templ;
-};
-
-
-struct i915_texture {
-   struct pipe_texture base;
-
-   /* Derived from the above:
-    */
-   unsigned pitch;
-   unsigned depth_pitch;          /* per-image on i945? */
-   unsigned total_height;
-
-   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
-
-   /* Explicitly store the offset of each image for each cube face or
-    * depth value.  Pretty much have to accept that hardware formats
-    * are going to be so diverse that there is no unified way to
-    * compute the offsets of depth/cube images within a mipmap level,
-    * so have to store them as a lookup table:
-    */
-   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];   /**< array [depth] of offsets */
-
-   /* Includes image offset tables:
-    */
-   unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
-
-   /* The data is held here:
-    */
-   struct pipe_buffer *buffer;
-};
-
-struct i915_context
-{
-   struct pipe_context pipe;
-   struct i915_winsys *winsys;
-   struct draw_context *draw;
-
-   /* The most recent drawing state as set by the driver:
-    */
-   const struct i915_blend_state           *blend;
-   const struct i915_sampler_state         *sampler[PIPE_MAX_SAMPLERS];
-   const struct i915_depth_stencil_state   *depth_stencil;
-   const struct i915_rasterizer_state      *rasterizer;
-
-   struct i915_fragment_shader *fs;
-
-   struct pipe_blend_color blend_color;
-   struct pipe_clip_state clip;
-   struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
-   struct pipe_framebuffer_state framebuffer;
-   struct pipe_poly_stipple poly_stipple;
-   struct pipe_scissor_state scissor;
-   struct i915_texture *texture[PIPE_MAX_SAMPLERS];
-   struct pipe_viewport_state viewport;
-   struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
-
-   unsigned dirty;
-
-   unsigned *batch_start;
-
-   /** Vertex buffer */
-   struct pipe_buffer *vbo;
-
-   struct i915_state current;
-   unsigned hardware_dirty;
-   
-   unsigned debug;
-};
-
-/* A flag for each state_tracker state object:
- */
-#define I915_NEW_VIEWPORT      0x1
-#define I915_NEW_RASTERIZER    0x2
-#define I915_NEW_FS            0x4
-#define I915_NEW_BLEND         0x8
-#define I915_NEW_CLIP          0x10
-#define I915_NEW_SCISSOR       0x20
-#define I915_NEW_STIPPLE       0x40
-#define I915_NEW_FRAMEBUFFER   0x80
-#define I915_NEW_ALPHA_TEST    0x100
-#define I915_NEW_DEPTH_STENCIL 0x200
-#define I915_NEW_SAMPLER       0x400
-#define I915_NEW_TEXTURE       0x800
-#define I915_NEW_CONSTANTS     0x1000
-#define I915_NEW_VBO           0x2000
-#define I915_NEW_VS            0x4000
-
-
-/* Driver's internally generated state flags:
- */
-#define I915_NEW_VERTEX_FORMAT    0x10000
-
-
-/* Dirty flags for hardware emit
- */
-#define I915_HW_STATIC            (1<<I915_CACHE_STATIC)
-#define I915_HW_DYNAMIC           (1<<I915_CACHE_DYNAMIC)
-#define I915_HW_SAMPLER           (1<<I915_CACHE_SAMPLER)
-#define I915_HW_MAP               (1<<I915_CACHE_MAP)
-#define I915_HW_PROGRAM           (1<<I915_CACHE_PROGRAM)
-#define I915_HW_CONSTANTS         (1<<I915_CACHE_CONSTANTS)
-#define I915_HW_IMMEDIATE         (1<<(I915_MAX_CACHE+0))
-#define I915_HW_INVARIENT         (1<<(I915_MAX_CACHE+1))
-
-
-/***********************************************************************
- * i915_prim_emit.c: 
- */
-struct draw_stage *i915_draw_render_stage( struct i915_context *i915 );
-
-
-/***********************************************************************
- * i915_prim_vbuf.c: 
- */
-struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 );
-
-
-/***********************************************************************
- * i915_state_emit.c: 
- */
-void i915_emit_hardware_state(struct i915_context *i915 );
-
-
-
-/***********************************************************************
- * i915_clear.c: 
- */
-void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
-               unsigned clearValue);
-
-
-/***********************************************************************
- * i915_surface.c: 
- */
-void i915_init_surface_functions( struct i915_context *i915 );
-
-void i915_init_state_functions( struct i915_context *i915 );
-void i915_init_flush_functions( struct i915_context *i915 );
-void i915_init_string_functions( struct i915_context *i915 );
-
-
-
-
-/***********************************************************************
- * Inline conversion functions.  These are better-typed than the
- * macros used previously:
- */
-static INLINE struct i915_context *
-i915_context( struct pipe_context *pipe )
-{
-   return (struct i915_context *)pipe;
-}
-
-
-
-#endif
+ /**************************************************************************\r
+ * \r
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.\r
+ * All Rights Reserved.\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the\r
+ * "Software"), to deal in the Software without restriction, including\r
+ * without limitation the rights to use, copy, modify, merge, publish,\r
+ * distribute, sub license, and/or sell copies of the Software, and to\r
+ * permit persons to whom the Software is furnished to do so, subject to\r
+ * the following conditions:\r
+ * \r
+ * The above copyright notice and this permission notice (including the\r
+ * next paragraph) shall be included in all copies or substantial portions\r
+ * of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ * \r
+ **************************************************************************/\r
+\r
+#ifndef I915_CONTEXT_H\r
+#define I915_CONTEXT_H\r
+\r
+\r
+#include "pipe/p_context.h"\r
+#include "pipe/p_defines.h"\r
+#include "pipe/p_state.h"\r
+\r
+#include "draw/draw_vertex.h"\r
+\r
+#include "tgsi/util/tgsi_scan.h"\r
+\r
+\r
+#define I915_TEX_UNITS 8\r
+\r
+#define I915_DYNAMIC_MODES4       0\r
+#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */\r
+#define I915_DYNAMIC_DEPTHSCALE_1 2 \r
+#define I915_DYNAMIC_IAB          3\r
+#define I915_DYNAMIC_BC_0         4 /* just the header */\r
+#define I915_DYNAMIC_BC_1         5\r
+#define I915_DYNAMIC_BFO_0        6 \r
+#define I915_DYNAMIC_BFO_1        7\r
+#define I915_DYNAMIC_STP_0        8 \r
+#define I915_DYNAMIC_STP_1        9 \r
+#define I915_DYNAMIC_SC_ENA_0     10 \r
+#define I915_DYNAMIC_SC_RECT_0    11 \r
+#define I915_DYNAMIC_SC_RECT_1    12 \r
+#define I915_DYNAMIC_SC_RECT_2    13 \r
+#define I915_MAX_DYNAMIC          14\r
+\r
+\r
+#define I915_IMMEDIATE_S0         0\r
+#define I915_IMMEDIATE_S1         1\r
+#define I915_IMMEDIATE_S2         2\r
+#define I915_IMMEDIATE_S3         3\r
+#define I915_IMMEDIATE_S4         4\r
+#define I915_IMMEDIATE_S5         5\r
+#define I915_IMMEDIATE_S6         6\r
+#define I915_IMMEDIATE_S7         7\r
+#define I915_MAX_IMMEDIATE        8\r
+\r
+/* These must mach the order of LI0_STATE_* bits, as they will be used\r
+ * to generate hardware packets:\r
+ */\r
+#define I915_CACHE_STATIC         0 \r
+#define I915_CACHE_DYNAMIC        1 /* handled specially */\r
+#define I915_CACHE_SAMPLER        2\r
+#define I915_CACHE_MAP            3\r
+#define I915_CACHE_PROGRAM        4\r
+#define I915_CACHE_CONSTANTS      5\r
+#define I915_MAX_CACHE            6\r
+\r
+#define I915_MAX_CONSTANT  32\r
+\r
+\r
+/** See constant_flags[] below */\r
+#define I915_CONSTFLAG_USER 0x1f\r
+\r
+\r
+/**\r
+ * Subclass of pipe_shader_state\r
+ */\r
+struct i915_fragment_shader\r
+{\r
+   struct pipe_shader_state state;\r
+\r
+   struct tgsi_shader_info info;\r
+\r
+   uint *program;\r
+   uint program_len;\r
+\r
+   /**\r
+    * constants introduced during translation.\r
+    * These are placed at the end of the constant buffer and grow toward\r
+    * the beginning (eg: slot 31, 30 29, ...)\r
+    * User-provided constants start at 0.\r
+    * This allows both types of constants to co-exist (until there's too many)\r
+    * and doesn't require regenerating/changing the fragment program to\r
+    * shuffle constants around.\r
+    */\r
+   uint num_constants;\r
+   float constants[I915_MAX_CONSTANT][4];\r
+\r
+   /**\r
+    * Status of each constant\r
+    * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding\r
+    * slot of the user's constant buffer. (set by pipe->set_constant_buffer())\r
+    * Else, the bitmask indicates which components are occupied by immediates.\r
+    */\r
+   ubyte constant_flags[I915_MAX_CONSTANT];\r
+};\r
+\r
+\r
+struct i915_cache_context;\r
+\r
+/* Use to calculate differences between state emitted to hardware and\r
+ * current driver-calculated state.  \r
+ */\r
+struct i915_state \r
+{\r
+   unsigned immediate[I915_MAX_IMMEDIATE];\r
+   unsigned dynamic[I915_MAX_DYNAMIC];\r
+\r
+   float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];\r
+   /** number of constants passed in through a constant buffer */\r
+   uint num_user_constants[PIPE_SHADER_TYPES];\r
+\r
+   /* texture sampler state */\r
+   unsigned sampler[I915_TEX_UNITS][3];\r
+   unsigned sampler_enable_flags;\r
+   unsigned sampler_enable_nr;\r
+\r
+   /* texture image buffers */\r
+   unsigned texbuffer[I915_TEX_UNITS][2];\r
+\r
+   /** Describes the current hardware vertex layout */\r
+   struct vertex_info vertex_info;\r
+   \r
+   unsigned id;                        /* track lost context events */\r
+};\r
+\r
+struct i915_blend_state {\r
+   unsigned iab;\r
+   unsigned modes4;\r
+   unsigned LIS5;\r
+   unsigned LIS6;\r
+};\r
+\r
+struct i915_depth_stencil_state {\r
+   unsigned stencil_modes4;\r
+   unsigned bfo[2];\r
+   unsigned stencil_LIS5;\r
+   unsigned depth_LIS6;\r
+};\r
+\r
+struct i915_rasterizer_state {\r
+   int light_twoside : 1;\r
+   unsigned st;\r
+   enum interp_mode color_interp;\r
+\r
+   unsigned LIS4;\r
+   unsigned LIS7;\r
+   unsigned sc[1];\r
+\r
+   const struct pipe_rasterizer_state *templ;\r
+\r
+   union { float f; unsigned u; } ds[2];\r
+};\r
+\r
+struct i915_sampler_state {\r
+   unsigned state[3];\r
+   const struct pipe_sampler_state *templ;\r
+};\r
+\r
+\r
+struct i915_texture {\r
+   struct pipe_texture base;\r
+\r
+   /* Derived from the above:\r
+    */\r
+   unsigned pitch;\r
+   unsigned depth_pitch;          /* per-image on i945? */\r
+   unsigned total_height;\r
+\r
+   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];\r
+\r
+   /* Explicitly store the offset of each image for each cube face or\r
+    * depth value.  Pretty much have to accept that hardware formats\r
+    * are going to be so diverse that there is no unified way to\r
+    * compute the offsets of depth/cube images within a mipmap level,\r
+    * so have to store them as a lookup table:\r
+    */\r
+   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];   /**< array [depth] of offsets */\r
+\r
+   /* Includes image offset tables:\r
+    */\r
+   unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];\r
+\r
+   /* The data is held here:\r
+    */\r
+   struct pipe_buffer *buffer;\r
+};\r
+\r
+struct i915_context\r
+{\r
+   struct pipe_context pipe;\r
+   struct i915_winsys *winsys;\r
+   struct draw_context *draw;\r
+\r
+   /* The most recent drawing state as set by the driver:\r
+    */\r
+   const struct i915_blend_state           *blend;\r
+   const struct i915_sampler_state         *sampler[PIPE_MAX_SAMPLERS];\r
+   const struct i915_depth_stencil_state   *depth_stencil;\r
+   const struct i915_rasterizer_state      *rasterizer;\r
+\r
+   struct i915_fragment_shader *fs;\r
+\r
+   struct pipe_blend_color blend_color;\r
+   struct pipe_clip_state clip;\r
+   struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];\r
+   struct pipe_framebuffer_state framebuffer;\r
+   struct pipe_poly_stipple poly_stipple;\r
+   struct pipe_scissor_state scissor;\r
+   struct i915_texture *texture[PIPE_MAX_SAMPLERS];\r
+   struct pipe_viewport_state viewport;\r
+   struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];\r
+\r
+   unsigned dirty;\r
+\r
+   unsigned num_samplers;\r
+   unsigned num_textures;\r
+\r
+   unsigned *batch_start;\r
+\r
+   /** Vertex buffer */\r
+   struct pipe_buffer *vbo;\r
+\r
+   struct i915_state current;\r
+   unsigned hardware_dirty;\r
+   \r
+   unsigned debug;\r
+};\r
+\r
+/* A flag for each state_tracker state object:\r
+ */\r
+#define I915_NEW_VIEWPORT      0x1\r
+#define I915_NEW_RASTERIZER    0x2\r
+#define I915_NEW_FS            0x4\r
+#define I915_NEW_BLEND         0x8\r
+#define I915_NEW_CLIP          0x10\r
+#define I915_NEW_SCISSOR       0x20\r
+#define I915_NEW_STIPPLE       0x40\r
+#define I915_NEW_FRAMEBUFFER   0x80\r
+#define I915_NEW_ALPHA_TEST    0x100\r
+#define I915_NEW_DEPTH_STENCIL 0x200\r
+#define I915_NEW_SAMPLER       0x400\r
+#define I915_NEW_TEXTURE       0x800\r
+#define I915_NEW_CONSTANTS     0x1000\r
+#define I915_NEW_VBO           0x2000\r
+#define I915_NEW_VS            0x4000\r
+\r
+\r
+/* Driver's internally generated state flags:\r
+ */\r
+#define I915_NEW_VERTEX_FORMAT    0x10000\r
+\r
+\r
+/* Dirty flags for hardware emit\r
+ */\r
+#define I915_HW_STATIC            (1<<I915_CACHE_STATIC)\r
+#define I915_HW_DYNAMIC           (1<<I915_CACHE_DYNAMIC)\r
+#define I915_HW_SAMPLER           (1<<I915_CACHE_SAMPLER)\r
+#define I915_HW_MAP               (1<<I915_CACHE_MAP)\r
+#define I915_HW_PROGRAM           (1<<I915_CACHE_PROGRAM)\r
+#define I915_HW_CONSTANTS         (1<<I915_CACHE_CONSTANTS)\r
+#define I915_HW_IMMEDIATE         (1<<(I915_MAX_CACHE+0))\r
+#define I915_HW_INVARIENT         (1<<(I915_MAX_CACHE+1))\r
+\r
+\r
+/***********************************************************************\r
+ * i915_prim_emit.c: \r
+ */\r
+struct draw_stage *i915_draw_render_stage( struct i915_context *i915 );\r
+\r
+\r
+/***********************************************************************\r
+ * i915_prim_vbuf.c: \r
+ */\r
+struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 );\r
+\r
+\r
+/***********************************************************************\r
+ * i915_state_emit.c: \r
+ */\r
+void i915_emit_hardware_state(struct i915_context *i915 );\r
+\r
+\r
+\r
+/***********************************************************************\r
+ * i915_clear.c: \r
+ */\r
+void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,\r
+               unsigned clearValue);\r
+\r
+\r
+/***********************************************************************\r
+ * i915_surface.c: \r
+ */\r
+void i915_init_surface_functions( struct i915_context *i915 );\r
+\r
+void i915_init_state_functions( struct i915_context *i915 );\r
+void i915_init_flush_functions( struct i915_context *i915 );\r
+void i915_init_string_functions( struct i915_context *i915 );\r
+\r
+\r
+\r
+\r
+/***********************************************************************\r
+ * Inline conversion functions.  These are better-typed than the\r
+ * macros used previously:\r
+ */\r
+static INLINE struct i915_context *\r
+i915_context( struct pipe_context *pipe )\r
+{\r
+   return (struct i915_context *)pipe;\r
+}\r
+\r
+\r
+\r
+#endif\r
index 27af46b..2414324 100644 (file)
@@ -269,13 +269,22 @@ i915_create_sampler_state(struct pipe_context *pipe,
    return cso;
 }
 
-static void i915_bind_sampler_state(struct pipe_context *pipe,
-                                    unsigned unit, void *sampler)
+static void i915_bind_sampler_states(struct pipe_context *pipe,
+                                     unsigned num, void **sampler)
 {
    struct i915_context *i915 = i915_context(pipe);
 
-   assert(unit < PIPE_MAX_SAMPLERS);
-   i915->sampler[unit] = (const struct i915_sampler_state*)sampler;
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == i915->num_samplers &&
+       !memcmp(i915->sampler, sampler, num * sizeof(void *)))
+      return;
+
+   memcpy(i915->sampler, sampler, num * sizeof(void *));
+   memset(&i915->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * sizeof(void *));
+
+   i915->num_samplers = num;
 
    i915->dirty |= I915_NEW_SAMPLER;
 }
@@ -526,14 +535,29 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
 }
 
 
-static void i915_set_sampler_texture(struct pipe_context *pipe,
-                                    unsigned sampler,
-                                    struct pipe_texture *texture)
+static void i915_set_sampler_textures(struct pipe_context *pipe,
+                                      unsigned num,
+                                      struct pipe_texture **texture)
 {
    struct i915_context *i915 = i915_context(pipe);
+   uint i;
+
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == i915->num_textures &&
+       !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *)))
+      return;
+
+   for (i = 0; i < num; i++)
+      pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
+                             texture[i]);
+
+   for (i = num; i < i915->num_textures; i++)
+      pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
+                             NULL);
 
-   pipe_texture_reference((struct pipe_texture **) &i915->texture[sampler],
-                          texture);
+   i915->num_textures = num;
 
    i915->dirty |= I915_NEW_TEXTURE;
 }
@@ -691,7 +715,7 @@ i915_init_state_functions( struct i915_context *i915 )
    i915->pipe.delete_blend_state = i915_delete_blend_state;
 
    i915->pipe.create_sampler_state = i915_create_sampler_state;
-   i915->pipe.bind_sampler_state = i915_bind_sampler_state;
+   i915->pipe.bind_sampler_states = i915_bind_sampler_states;
    i915->pipe.delete_sampler_state = i915_delete_sampler_state;
 
    i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
@@ -715,7 +739,7 @@ i915_init_state_functions( struct i915_context *i915 )
 
    i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
    i915->pipe.set_scissor_state = i915_set_scissor_state;
-   i915->pipe.set_sampler_texture = i915_set_sampler_texture;
+   i915->pipe.set_sampler_textures = i915_set_sampler_textures;
    i915->pipe.set_viewport_state = i915_set_viewport_state;
    i915->pipe.set_vertex_buffer = i915_set_vertex_buffer;
    i915->pipe.set_vertex_element = i915_set_vertex_element;
index 6bbaac4..a7498d2 100644 (file)
@@ -267,12 +267,6 @@ i915_emit_hardware_state(struct i915_context *i915 )
       /* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */
       if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER))
       {
-        /* XXX: we were refering to sampler state
-         * (current.sampler_enable_nr) below, but only checking
-         * I915_HW_MAP above.  Should probably calculate the enabled
-         * flags separately - but there will be further rework of
-         * state so perhaps not necessary yet.
-         */
          const uint nr = i915->current.sampler_enable_nr;
          if (nr) {
             const uint enabled = i915->current.sampler_enable_flags;
index 9c1a5bb..9dbb1b1 100644 (file)
@@ -106,7 +106,8 @@ void i915_update_samplers( struct i915_context *i915 )
    i915->current.sampler_enable_nr = 0;
    i915->current.sampler_enable_flags = 0x0;
 
-   for (unit = 0; unit < I915_TEX_UNITS; unit++) {
+   for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
+        unit++) {
       /* determine unit enable/disable by looking for a bound texture */
       /* could also examine the fragment program? */
       if (i915->texture[unit]) {
@@ -219,7 +220,8 @@ i915_update_textures(struct i915_context *i915)
 {
    uint unit;
 
-   for (unit = 0; unit < I915_TEX_UNITS; unit++) {
+   for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
+        unit++) {
       /* determine unit enable/disable by looking for a bound texture */
       /* could also examine the fragment program? */
       if (i915->texture[unit]) {
index 4da3a8c..b83a13c 100644 (file)
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  */
-
-
-#ifndef BRWCONTEXT_INC
-#define BRWCONTEXT_INC
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-
-#include "tgsi/util/tgsi_scan.h"
-
-#include "brw_structs.h"
-#include "brw_winsys.h"
-
-
-/* Glossary:
- *
- * URB - uniform resource buffer.  A mid-sized buffer which is
- * partitioned between the fixed function units and used for passing
- * values (vertices, primitives, constants) between them.
- *
- * CURBE - constant URB entry.  An urb region (entry) used to hold
- * constant values which the fixed function units can be instructed to
- * preload into the GRF when spawining a thread.
- *
- * VUE - vertex URB entry.  An urb entry holding a vertex and usually
- * a vertex header.  The header contains control information and
- * things like primitive type, Begin/end flags and clip codes.
- *
- * PUE - primitive URB entry.  An urb entry produced by the setup (SF)
- * unit holding rasterization and interpolation parameters.
- *
- * GRF - general register file.  One of several register files
- * addressable by programmed threads.  The inputs (r0, payload, curbe,
- * urb) of the thread are preloaded to this area before the thread is
- * spawned.  The registers are individually 8 dwords wide and suitable
- * for general usage.  Registers holding thread input values are not
- * special and may be overwritten.
- *
- * MRF - message register file.  Threads communicate (and terminate)
- * by sending messages.  Message parameters are placed in contigous
- * MRF registers.  All program output is via these messages.  URB
- * entries are populated by sending a message to the shared URB
- * function containing the new data, together with a control word,
- * often an unmodified copy of R0.
- *
- * R0 - GRF register 0.  Typically holds control information used when
- * sending messages to other threads.
- *
- * EU or GEN4 EU: The name of the programmable subsystem of the
- * i965 hardware.  Threads are executed by the EU, the registers
- * described above are part of the EU architecture.
- *
- * Fixed function units:
- *
- * CS - Command streamer.  Notional first unit, little software
- * interaction.  Holds the URB entries used for constant data, ie the
- * CURBEs.
- *
- * VF/VS - Vertex Fetch / Vertex Shader.  The fixed function part of
- * this unit is responsible for pulling vertices out of vertex buffers
- * in vram and injecting them into the processing pipe as VUEs.  If
- * enabled, it first passes them to a VS thread which is a good place
- * for the driver to implement any active vertex shader.
- *
- * GS - Geometry Shader.  This corresponds to a new DX10 concept.  If
- * enabled, incoming strips etc are passed to GS threads in individual
- * line/triangle/point units.  The GS thread may perform arbitary
- * computation and emit whatever primtives with whatever vertices it
- * chooses.  This makes GS an excellent place to implement GL's
- * unfilled polygon modes, though of course it is capable of much
- * more.  Additionally, GS is used to translate away primitives not
- * handled by latter units, including Quads and Lineloops.
- *
- * CS - Clipper.  Mesa's clipping algorithms are imported to run on
- * this unit.  The fixed function part performs cliptesting against
- * the 6 fixed clipplanes and makes descisions on whether or not the
- * incoming primitive needs to be passed to a thread for clipping.
- * User clip planes are handled via cooperation with the VS thread.
- *
- * SF - Strips Fans or Setup: Triangles are prepared for
- * rasterization.  Interpolation coefficients are calculated.
- * Flatshading and two-side lighting usually performed here.
- *
- * WM - Windower.  Interpolation of vertex attributes performed here.
- * Fragment shader implemented here.  SIMD aspects of EU taken full
- * advantage of, as pixels are processed in blocks of 16.
- *
- * CC - Color Calculator.  No EU threads associated with this unit.
- * Handles blending and (presumably) depth and stencil testing.
- */
-
-#define BRW_MAX_CURBE                    (32*16)
-
-struct brw_context;
-struct brw_winsys;
-
-
-/* Raised when we receive new state across the pipe interface:
- */
-#define BRW_NEW_VIEWPORT                0x1
-#define BRW_NEW_RASTERIZER              0x2
-#define BRW_NEW_FS                      0x4
-#define BRW_NEW_BLEND                   0x8
-#define BRW_NEW_CLIP                    0x10
-#define BRW_NEW_SCISSOR                 0x20
-#define BRW_NEW_STIPPLE                 0x40
-#define BRW_NEW_FRAMEBUFFER             0x80
-#define BRW_NEW_ALPHA_TEST              0x100
-#define BRW_NEW_DEPTH_STENCIL           0x200
-#define BRW_NEW_SAMPLER                 0x400
-#define BRW_NEW_TEXTURE                 0x800
-#define BRW_NEW_CONSTANTS               0x1000
-#define BRW_NEW_VBO                     0x2000
-#define BRW_NEW_VS                      0x4000
-
-/* Raised for other internal events:
- */
-#define BRW_NEW_URB_FENCE               0x10000
-#define BRW_NEW_PSP                     0x20000
-#define BRW_NEW_CURBE_OFFSETS           0x40000
-#define BRW_NEW_REDUCED_PRIMITIVE       0x80000
-#define BRW_NEW_PRIMITIVE               0x100000
-#define BRW_NEW_SCENE                 0x200000
-#define BRW_NEW_SF_LINKAGE              0x400000
-
-extern int BRW_DEBUG;
-
-#define DEBUG_TEXTURE  0x1
-#define DEBUG_STATE    0x2
-#define DEBUG_IOCTL    0x4
-#define DEBUG_PRIMS    0x8
-#define DEBUG_VERTS    0x10
-#define DEBUG_FALLBACKS        0x20
-#define DEBUG_VERBOSE  0x40
-#define DEBUG_DRI       0x80
-#define DEBUG_DMA       0x100
-#define DEBUG_SANITY    0x200
-#define DEBUG_SYNC      0x400
-#define DEBUG_SLEEP     0x800
-#define DEBUG_PIXEL     0x1000
-#define DEBUG_STATS     0x2000
-#define DEBUG_TILE      0x4000
-#define DEBUG_SINGLE_THREAD   0x8000
-#define DEBUG_WM        0x10000
-#define DEBUG_URB       0x20000
-#define DEBUG_VS        0x40000
-#define DEBUG_BATCH    0x80000
-#define DEBUG_BUFMGR   0x100000
-#define DEBUG_BLIT     0x200000
-#define DEBUG_REGION   0x400000
-#define DEBUG_MIPTREE  0x800000
-
-#define DBG(...) do {                                          \
-       if (BRW_DEBUG & FILE_DEBUG_FLAG)                        \
-              brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__);                 \
-} while(0)
-
-#define PRINT(...) do {                                                \
-              brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__);                 \
-} while(0)
-
-struct brw_state_flags {
-   unsigned cache;
-   unsigned brw;
-};
-
-
-struct brw_vertex_program {
-   struct pipe_shader_state program;
-   struct tgsi_shader_info info;
-   int id;
-};
-
-
-struct brw_fragment_program {
-   struct pipe_shader_state program;
-   struct tgsi_shader_info info;
-   
-   boolean UsesDepth; /* XXX add this to tgsi_shader_info? */
-   int id;
-};
-
-
-struct pipe_setup_linkage {
-   struct {
-      unsigned vp_output:5;
-      unsigned interp_mode:4;
-      unsigned bf_vp_output:5;
-   } fp_input[PIPE_MAX_SHADER_INPUTS];
-
-   unsigned fp_input_count:5;
-   unsigned max_vp_output:5;
-};
-   
-
-
-struct brw_texture {
-   struct pipe_texture base;
-
-   /* Derived from the above:
-    */
-   unsigned pitch;
-   unsigned depth_pitch;          /* per-image on i945? */
-   unsigned total_height;
-
-   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
-
-   /* Explicitly store the offset of each image for each cube face or
-    * depth value.  Pretty much have to accept that hardware formats
-    * are going to be so diverse that there is no unified way to
-    * compute the offsets of depth/cube images within a mipmap level,
-    * so have to store them as a lookup table:
-    */
-   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];   /**< array [depth] of offsets */
-
-   /* Includes image offset tables:
-    */
-   unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
-
-   /* The data is held here:
-    */
-   struct pipe_buffer *buffer;
-};
-
-/* Data about a particular attempt to compile a program.  Note that
- * there can be many of these, each in a different GL state
- * corresponding to a different brw_wm_prog_key struct, with different
- * compiled programs:
- */
-/* Data about a particular attempt to compile a program.  Note that
- * there can be many of these, each in a different GL state
- * corresponding to a different brw_wm_prog_key struct, with different
- * compiled programs:
- */
-
-struct brw_wm_prog_data {
-   unsigned curb_read_length;
-   unsigned urb_read_length;
-
-   unsigned first_curbe_grf;
-   unsigned total_grf;
-   unsigned total_scratch;
-
-   /* Internally generated constants for the CURBE.  These are loaded
-    * ahead of the data from the constant buffer.
-    */
-   const float internal_const[8];
-   unsigned nr_internal_consts;
-   unsigned max_const;
-
-   boolean error;
-};
-
-struct brw_sf_prog_data {
-   unsigned urb_read_length;
-   unsigned total_grf;
-
-   /* Each vertex may have upto 12 attributes, 4 components each,
-    * except WPOS which requires only 2.  (11*4 + 2) == 44 ==> 11
-    * rows.
-    *
-    * Actually we use 4 for each, so call it 12 rows.
-    */
-   unsigned urb_entry_size;
-};
-
-struct brw_clip_prog_data {
-   unsigned curb_read_length;  /* user planes? */
-   unsigned clip_mode;
-   unsigned urb_read_length;
-   unsigned total_grf;
-};
-
-struct brw_gs_prog_data {
-   unsigned urb_read_length;
-   unsigned total_grf;
-};
-
-struct brw_vs_prog_data {
-   unsigned curb_read_length;
-   unsigned urb_read_length;
-   unsigned total_grf;
-   unsigned outputs_written;
-
-   unsigned inputs_read;
-
-   unsigned max_const;
-
-   float    imm_buf[PIPE_MAX_CONSTANT][4];
-   unsigned num_imm;
-   unsigned num_consts;
-
-   /* Used for calculating urb partitions:
-    */
-   unsigned urb_entry_size;
-};
-
-
-#define BRW_MAX_TEX_UNIT 8
-#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1
-
-/* Create a fixed sized struct for caching binding tables:
- */
-struct brw_surface_binding_table {
-   unsigned surf_ss_offset[BRW_WM_MAX_SURF];
-};
-
-
-struct brw_cache;
-
-struct brw_mem_pool {
-   struct pipe_buffer *buffer;
-
-   unsigned size;
-   unsigned offset;            /* offset of first free byte */
-
-   struct brw_context *brw;
-};
-
-struct brw_cache_item {
-   unsigned hash;
-   unsigned key_size;          /* for variable-sized keys */
-   const void *key;
-
-   unsigned offset;            /* offset within pool's buffer */
-   unsigned data_size;
-
-   struct brw_cache_item *next;
-};
-
-
-
-struct brw_cache {
-   unsigned id;
-
-   const char *name;
-
-   struct brw_context *brw;
-   struct brw_mem_pool *pool;
-
-   struct brw_cache_item **items;
-   unsigned size, n_items;
-
-   unsigned key_size;          /* for fixed-size keys */
-   unsigned aux_size;
-
-   unsigned last_addr;                 /* offset of active item */
-};
-
-
-
-
-/* Considered adding a member to this struct to document which flags
- * an update might raise so that ordering of the state atoms can be
- * checked or derived at runtime.  Dropped the idea in favor of having
- * a debug mode where the state is monitored for flags which are
- * raised that have already been tested against.
- */
-struct brw_tracked_state {
-   struct brw_state_flags dirty;
-   void (*update)( struct brw_context *brw );
-};
-
-
-/* Flags for brw->state.cache.
- */
-#define CACHE_NEW_CC_VP                  (1<<BRW_CC_VP)
-#define CACHE_NEW_CC_UNIT                (1<<BRW_CC_UNIT)
-#define CACHE_NEW_WM_PROG                (1<<BRW_WM_PROG)
-#define CACHE_NEW_SAMPLER_DEFAULT_COLOR  (1<<BRW_SAMPLER_DEFAULT_COLOR)
-#define CACHE_NEW_SAMPLER                (1<<BRW_SAMPLER)
-#define CACHE_NEW_WM_UNIT                (1<<BRW_WM_UNIT)
-#define CACHE_NEW_SF_PROG                (1<<BRW_SF_PROG)
-#define CACHE_NEW_SF_VP                  (1<<BRW_SF_VP)
-#define CACHE_NEW_SF_UNIT                (1<<BRW_SF_UNIT)
-#define CACHE_NEW_VS_UNIT                (1<<BRW_VS_UNIT)
-#define CACHE_NEW_VS_PROG                (1<<BRW_VS_PROG)
-#define CACHE_NEW_GS_UNIT                (1<<BRW_GS_UNIT)
-#define CACHE_NEW_GS_PROG                (1<<BRW_GS_PROG)
-#define CACHE_NEW_CLIP_VP                (1<<BRW_CLIP_VP)
-#define CACHE_NEW_CLIP_UNIT              (1<<BRW_CLIP_UNIT)
-#define CACHE_NEW_CLIP_PROG              (1<<BRW_CLIP_PROG)
-#define CACHE_NEW_SURFACE                (1<<BRW_SS_SURFACE)
-#define CACHE_NEW_SURF_BIND              (1<<BRW_SS_SURF_BIND)
-
-
-
-
-enum brw_mempool_id {
-   BRW_GS_POOL,
-   BRW_SS_POOL,
-   BRW_MAX_POOL
-};
-
-
-struct brw_cached_batch_item {
-   struct header *header;
-   unsigned sz;
-   struct brw_cached_batch_item *next;
-};
-
-
-
-/* Protect against a future where PIPE_ATTRIB_MAX > 32.  Wouldn't life
- * be easier if C allowed arrays of packed elements?
- */
-#define ATTRIB_BIT_DWORDS  ((PIPE_ATTRIB_MAX+31)/32)
-
-
-
-
-struct brw_vertex_info {
-   unsigned varying;  /* varying:1[PIPE_ATTRIB_MAX] */
-   unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */
-};
-
-
-
-
-
-struct brw_context
-{
-   struct pipe_context pipe;
-   struct brw_winsys *winsys;
-
-   unsigned primitive;
-   unsigned reduced_primitive;
-
-   boolean emit_state_always;
-
-   struct {
-      struct brw_state_flags dirty;
-   } state;
-
-
-   struct {
-      const struct pipe_blend_state         *Blend;
-      const struct pipe_depth_stencil_alpha_state *DepthStencil;
-      const struct pipe_poly_stipple        *PolygonStipple;
-      const struct pipe_rasterizer_state    *Raster;
-      const struct pipe_sampler_state       *Samplers[PIPE_MAX_SAMPLERS];
-      const struct brw_vertex_program       *VertexProgram;
-      const struct brw_fragment_program     *FragmentProgram;
-
-      struct pipe_clip_state          Clip;
-      struct pipe_blend_color         BlendColor;
-      struct pipe_scissor_state       Scissor;
-      struct pipe_viewport_state      Viewport;
-      struct pipe_framebuffer_state   FrameBuffer;
-
-      const struct pipe_constant_buffer *Constants[2];
-      const struct brw_texture          *Texture[PIPE_MAX_SAMPLERS];
-   } attribs;
-
-   struct brw_mem_pool pool[BRW_MAX_POOL];
-   struct brw_cache cache[BRW_MAX_CACHE];
-   struct brw_cached_batch_item *cached_batch_items;
-
-   struct {
-
-      /* Arrays with buffer objects to copy non-bufferobj arrays into
-       * for upload:
-       */
-      const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX];
-
-      struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX];
-
-#define BRW_NR_UPLOAD_BUFS 17
-#define BRW_UPLOAD_INIT_SIZE (128*1024)
-
-      /* Summary of size and varying of active arrays, so we can check
-       * for changes to this state:
-       */
-      struct brw_vertex_info info;
-   } vb;
-
-
-   unsigned hardware_dirty;
-   unsigned dirty;
-   unsigned pci_id;
-   /* BRW_NEW_URB_ALLOCATIONS:
-    */
-   struct {
-      unsigned vsize;          /* vertex size plus header in urb registers */
-      unsigned csize;          /* constant buffer size in urb registers */
-      unsigned sfsize;         /* setup data size in urb registers */
-
-      boolean constrained;
-
-      unsigned nr_vs_entries;
-      unsigned nr_gs_entries;
-      unsigned nr_clip_entries;
-      unsigned nr_sf_entries;
-      unsigned nr_cs_entries;
-
-/*       unsigned vs_size; */
-/*       unsigned gs_size; */
-/*       unsigned clip_size; */
-/*       unsigned sf_size; */
-/*       unsigned cs_size; */
-
-      unsigned vs_start;
-      unsigned gs_start;
-      unsigned clip_start;
-      unsigned sf_start;
-      unsigned cs_start;
-   } urb;
-
-
-   /* BRW_NEW_CURBE_OFFSETS:
-    */
-   struct {
-      unsigned wm_start;
-      unsigned wm_size;
-      unsigned clip_start;
-      unsigned clip_size;
-      unsigned vs_start;
-      unsigned vs_size;
-      unsigned total_size;
-
-      unsigned gs_offset;
-
-      float *last_buf;
-      unsigned last_bufsz;
-   } curbe;
-
-   struct {
-      struct brw_vs_prog_data *prog_data;
-
-      unsigned prog_gs_offset;
-      unsigned state_gs_offset;
-   } vs;
-
-   struct {
-      struct brw_gs_prog_data *prog_data;
-
-      boolean prog_active;
-      unsigned prog_gs_offset;
-      unsigned state_gs_offset;
-   } gs;
-
-   struct {
-      struct brw_clip_prog_data *prog_data;
-
-      unsigned prog_gs_offset;
-      unsigned vp_gs_offset;
-      unsigned state_gs_offset;
-   } clip;
-
-
-   struct {
-      struct brw_sf_prog_data *prog_data;
-
-      struct pipe_setup_linkage linkage;
-
-      unsigned prog_gs_offset;
-      unsigned vp_gs_offset;
-      unsigned state_gs_offset;
-   } sf;
-
-   struct {
-      struct brw_wm_prog_data *prog_data;
-
-//      struct brw_wm_compiler *compile_data;
-
-
-      /**
-       * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER
-       * cache
-       */
-      struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
-
-      unsigned render_surf;
-      unsigned nr_surfaces;
-
-      unsigned max_threads;
-      struct pipe_buffer *scratch_buffer;
-      unsigned scratch_buffer_size;
-
-      unsigned sampler_count;
-      unsigned sampler_gs_offset;
-
-      struct brw_surface_binding_table bind;
-      unsigned bind_ss_offset;
-
-      unsigned prog_gs_offset;
-      unsigned state_gs_offset;
-   } wm;
-
-
-   struct {
-      unsigned vp_gs_offset;
-      unsigned state_gs_offset;
-   } cc;
-
-
-   /* Used to give every program string a unique id
-    */
-   unsigned program_id;
-};
-
-
-#define BRW_PACKCOLOR8888(r,g,b,a)  ((r<<24) | (g<<16) | (b<<8) | a)
-
-
-/*======================================================================
- * brw_vtbl.c
- */
-void brw_do_flush( struct brw_context *brw,
-                  unsigned flags );
-
-
-/*======================================================================
- * brw_state.c
- */
-void brw_validate_state(struct brw_context *brw);
-void brw_init_state(struct brw_context *brw);
-void brw_destroy_state(struct brw_context *brw);
-
-
-/*======================================================================
- * brw_tex.c
- */
-void brwUpdateTextureState( struct brw_context *brw );
-
-
-/* brw_urb.c
- */
-void brw_upload_urb_fence(struct brw_context *brw);
-
-void brw_upload_constant_buffer_state(struct brw_context *brw);
-
-void brw_init_surface_functions(struct brw_context *brw);
-void brw_init_state_functions(struct brw_context *brw);
-void brw_init_flush_functions(struct brw_context *brw);
-void brw_init_string_functions(struct brw_context *brw);
-
-/*======================================================================
- * Inline conversion functions.  These are better-typed than the
- * macros used previously:
- */
-static inline struct brw_context *
-brw_context( struct pipe_context *ctx )
-{
-   return (struct brw_context *)ctx;
-}
-
-#endif
-
+/*\r
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.\r
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to\r
+ develop this 3D driver.\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files (the\r
+ "Software"), to deal in the Software without restriction, including\r
+ without limitation the rights to use, copy, modify, merge, publish,\r
+ distribute, sublicense, and/or sell copies of the Software, and to\r
+ permit persons to whom the Software is furnished to do so, subject to\r
+ the following conditions:\r
+\r
+ The above copyright notice and this permission notice (including the\r
+ next paragraph) shall be included in all copies or substantial\r
+ portions of the Software.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE\r
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+\r
+ **********************************************************************/\r
+ /*\r
+  * Authors:\r
+  *   Keith Whitwell <keith@tungstengraphics.com>\r
+  */\r
+\r
+\r
+#ifndef BRWCONTEXT_INC\r
+#define BRWCONTEXT_INC\r
+\r
+\r
+#include "pipe/p_context.h"\r
+#include "pipe/p_defines.h"\r
+#include "pipe/p_state.h"\r
+\r
+#include "tgsi/util/tgsi_scan.h"\r
+\r
+#include "brw_structs.h"\r
+#include "brw_winsys.h"\r
+\r
+\r
+/* Glossary:\r
+ *\r
+ * URB - uniform resource buffer.  A mid-sized buffer which is\r
+ * partitioned between the fixed function units and used for passing\r
+ * values (vertices, primitives, constants) between them.\r
+ *\r
+ * CURBE - constant URB entry.  An urb region (entry) used to hold\r
+ * constant values which the fixed function units can be instructed to\r
+ * preload into the GRF when spawining a thread.\r
+ *\r
+ * VUE - vertex URB entry.  An urb entry holding a vertex and usually\r
+ * a vertex header.  The header contains control information and\r
+ * things like primitive type, Begin/end flags and clip codes.\r
+ *\r
+ * PUE - primitive URB entry.  An urb entry produced by the setup (SF)\r
+ * unit holding rasterization and interpolation parameters.\r
+ *\r
+ * GRF - general register file.  One of several register files\r
+ * addressable by programmed threads.  The inputs (r0, payload, curbe,\r
+ * urb) of the thread are preloaded to this area before the thread is\r
+ * spawned.  The registers are individually 8 dwords wide and suitable\r
+ * for general usage.  Registers holding thread input values are not\r
+ * special and may be overwritten.\r
+ *\r
+ * MRF - message register file.  Threads communicate (and terminate)\r
+ * by sending messages.  Message parameters are placed in contigous\r
+ * MRF registers.  All program output is via these messages.  URB\r
+ * entries are populated by sending a message to the shared URB\r
+ * function containing the new data, together with a control word,\r
+ * often an unmodified copy of R0.\r
+ *\r
+ * R0 - GRF register 0.  Typically holds control information used when\r
+ * sending messages to other threads.\r
+ *\r
+ * EU or GEN4 EU: The name of the programmable subsystem of the\r
+ * i965 hardware.  Threads are executed by the EU, the registers\r
+ * described above are part of the EU architecture.\r
+ *\r
+ * Fixed function units:\r
+ *\r
+ * CS - Command streamer.  Notional first unit, little software\r
+ * interaction.  Holds the URB entries used for constant data, ie the\r
+ * CURBEs.\r
+ *\r
+ * VF/VS - Vertex Fetch / Vertex Shader.  The fixed function part of\r
+ * this unit is responsible for pulling vertices out of vertex buffers\r
+ * in vram and injecting them into the processing pipe as VUEs.  If\r
+ * enabled, it first passes them to a VS thread which is a good place\r
+ * for the driver to implement any active vertex shader.\r
+ *\r
+ * GS - Geometry Shader.  This corresponds to a new DX10 concept.  If\r
+ * enabled, incoming strips etc are passed to GS threads in individual\r
+ * line/triangle/point units.  The GS thread may perform arbitary\r
+ * computation and emit whatever primtives with whatever vertices it\r
+ * chooses.  This makes GS an excellent place to implement GL's\r
+ * unfilled polygon modes, though of course it is capable of much\r
+ * more.  Additionally, GS is used to translate away primitives not\r
+ * handled by latter units, including Quads and Lineloops.\r
+ *\r
+ * CS - Clipper.  Mesa's clipping algorithms are imported to run on\r
+ * this unit.  The fixed function part performs cliptesting against\r
+ * the 6 fixed clipplanes and makes descisions on whether or not the\r
+ * incoming primitive needs to be passed to a thread for clipping.\r
+ * User clip planes are handled via cooperation with the VS thread.\r
+ *\r
+ * SF - Strips Fans or Setup: Triangles are prepared for\r
+ * rasterization.  Interpolation coefficients are calculated.\r
+ * Flatshading and two-side lighting usually performed here.\r
+ *\r
+ * WM - Windower.  Interpolation of vertex attributes performed here.\r
+ * Fragment shader implemented here.  SIMD aspects of EU taken full\r
+ * advantage of, as pixels are processed in blocks of 16.\r
+ *\r
+ * CC - Color Calculator.  No EU threads associated with this unit.\r
+ * Handles blending and (presumably) depth and stencil testing.\r
+ */\r
+\r
+#define BRW_MAX_CURBE                    (32*16)\r
+\r
+struct brw_context;\r
+struct brw_winsys;\r
+\r
+\r
+/* Raised when we receive new state across the pipe interface:\r
+ */\r
+#define BRW_NEW_VIEWPORT                0x1\r
+#define BRW_NEW_RASTERIZER              0x2\r
+#define BRW_NEW_FS                      0x4\r
+#define BRW_NEW_BLEND                   0x8\r
+#define BRW_NEW_CLIP                    0x10\r
+#define BRW_NEW_SCISSOR                 0x20\r
+#define BRW_NEW_STIPPLE                 0x40\r
+#define BRW_NEW_FRAMEBUFFER             0x80\r
+#define BRW_NEW_ALPHA_TEST              0x100\r
+#define BRW_NEW_DEPTH_STENCIL           0x200\r
+#define BRW_NEW_SAMPLER                 0x400\r
+#define BRW_NEW_TEXTURE                 0x800\r
+#define BRW_NEW_CONSTANTS               0x1000\r
+#define BRW_NEW_VBO                     0x2000\r
+#define BRW_NEW_VS                      0x4000\r
+\r
+/* Raised for other internal events:\r
+ */\r
+#define BRW_NEW_URB_FENCE               0x10000\r
+#define BRW_NEW_PSP                     0x20000\r
+#define BRW_NEW_CURBE_OFFSETS           0x40000\r
+#define BRW_NEW_REDUCED_PRIMITIVE       0x80000\r
+#define BRW_NEW_PRIMITIVE               0x100000\r
+#define BRW_NEW_SCENE                 0x200000\r
+#define BRW_NEW_SF_LINKAGE              0x400000\r
+\r
+extern int BRW_DEBUG;\r
+\r
+#define DEBUG_TEXTURE  0x1\r
+#define DEBUG_STATE    0x2\r
+#define DEBUG_IOCTL    0x4\r
+#define DEBUG_PRIMS    0x8\r
+#define DEBUG_VERTS    0x10\r
+#define DEBUG_FALLBACKS        0x20\r
+#define DEBUG_VERBOSE  0x40\r
+#define DEBUG_DRI       0x80\r
+#define DEBUG_DMA       0x100\r
+#define DEBUG_SANITY    0x200\r
+#define DEBUG_SYNC      0x400\r
+#define DEBUG_SLEEP     0x800\r
+#define DEBUG_PIXEL     0x1000\r
+#define DEBUG_STATS     0x2000\r
+#define DEBUG_TILE      0x4000\r
+#define DEBUG_SINGLE_THREAD   0x8000\r
+#define DEBUG_WM        0x10000\r
+#define DEBUG_URB       0x20000\r
+#define DEBUG_VS        0x40000\r
+#define DEBUG_BATCH    0x80000\r
+#define DEBUG_BUFMGR   0x100000\r
+#define DEBUG_BLIT     0x200000\r
+#define DEBUG_REGION   0x400000\r
+#define DEBUG_MIPTREE  0x800000\r
+\r
+#define DBG(...) do {                                          \\r
+       if (BRW_DEBUG & FILE_DEBUG_FLAG)                        \\r
+              brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__);                 \\r
+} while(0)\r
+\r
+#define PRINT(...) do {                                                \\r
+              brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__);                 \\r
+} while(0)\r
+\r
+struct brw_state_flags {\r
+   unsigned cache;\r
+   unsigned brw;\r
+};\r
+\r
+\r
+struct brw_vertex_program {\r
+   struct pipe_shader_state program;\r
+   struct tgsi_shader_info info;\r
+   int id;\r
+};\r
+\r
+\r
+struct brw_fragment_program {\r
+   struct pipe_shader_state program;\r
+   struct tgsi_shader_info info;\r
+   \r
+   boolean UsesDepth; /* XXX add this to tgsi_shader_info? */\r
+   int id;\r
+};\r
+\r
+\r
+struct pipe_setup_linkage {\r
+   struct {\r
+      unsigned vp_output:5;\r
+      unsigned interp_mode:4;\r
+      unsigned bf_vp_output:5;\r
+   } fp_input[PIPE_MAX_SHADER_INPUTS];\r
+\r
+   unsigned fp_input_count:5;\r
+   unsigned max_vp_output:5;\r
+};\r
+   \r
+\r
+\r
+struct brw_texture {\r
+   struct pipe_texture base;\r
+\r
+   /* Derived from the above:\r
+    */\r
+   unsigned pitch;\r
+   unsigned depth_pitch;          /* per-image on i945? */\r
+   unsigned total_height;\r
+\r
+   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];\r
+\r
+   /* Explicitly store the offset of each image for each cube face or\r
+    * depth value.  Pretty much have to accept that hardware formats\r
+    * are going to be so diverse that there is no unified way to\r
+    * compute the offsets of depth/cube images within a mipmap level,\r
+    * so have to store them as a lookup table:\r
+    */\r
+   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];   /**< array [depth] of offsets */\r
+\r
+   /* Includes image offset tables:\r
+    */\r
+   unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];\r
+\r
+   /* The data is held here:\r
+    */\r
+   struct pipe_buffer *buffer;\r
+};\r
+\r
+/* Data about a particular attempt to compile a program.  Note that\r
+ * there can be many of these, each in a different GL state\r
+ * corresponding to a different brw_wm_prog_key struct, with different\r
+ * compiled programs:\r
+ */\r
+/* Data about a particular attempt to compile a program.  Note that\r
+ * there can be many of these, each in a different GL state\r
+ * corresponding to a different brw_wm_prog_key struct, with different\r
+ * compiled programs:\r
+ */\r
+\r
+struct brw_wm_prog_data {\r
+   unsigned curb_read_length;\r
+   unsigned urb_read_length;\r
+\r
+   unsigned first_curbe_grf;\r
+   unsigned total_grf;\r
+   unsigned total_scratch;\r
+\r
+   /* Internally generated constants for the CURBE.  These are loaded\r
+    * ahead of the data from the constant buffer.\r
+    */\r
+   const float internal_const[8];\r
+   unsigned nr_internal_consts;\r
+   unsigned max_const;\r
+\r
+   boolean error;\r
+};\r
+\r
+struct brw_sf_prog_data {\r
+   unsigned urb_read_length;\r
+   unsigned total_grf;\r
+\r
+   /* Each vertex may have upto 12 attributes, 4 components each,\r
+    * except WPOS which requires only 2.  (11*4 + 2) == 44 ==> 11\r
+    * rows.\r
+    *\r
+    * Actually we use 4 for each, so call it 12 rows.\r
+    */\r
+   unsigned urb_entry_size;\r
+};\r
+\r
+struct brw_clip_prog_data {\r
+   unsigned curb_read_length;  /* user planes? */\r
+   unsigned clip_mode;\r
+   unsigned urb_read_length;\r
+   unsigned total_grf;\r
+};\r
+\r
+struct brw_gs_prog_data {\r
+   unsigned urb_read_length;\r
+   unsigned total_grf;\r
+};\r
+\r
+struct brw_vs_prog_data {\r
+   unsigned curb_read_length;\r
+   unsigned urb_read_length;\r
+   unsigned total_grf;\r
+   unsigned outputs_written;\r
+\r
+   unsigned inputs_read;\r
+\r
+   unsigned max_const;\r
+\r
+   float    imm_buf[PIPE_MAX_CONSTANT][4];\r
+   unsigned num_imm;\r
+   unsigned num_consts;\r
+\r
+   /* Used for calculating urb partitions:\r
+    */\r
+   unsigned urb_entry_size;\r
+};\r
+\r
+\r
+#define BRW_MAX_TEX_UNIT 8\r
+#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1\r
+\r
+/* Create a fixed sized struct for caching binding tables:\r
+ */\r
+struct brw_surface_binding_table {\r
+   unsigned surf_ss_offset[BRW_WM_MAX_SURF];\r
+};\r
+\r
+\r
+struct brw_cache;\r
+\r
+struct brw_mem_pool {\r
+   struct pipe_buffer *buffer;\r
+\r
+   unsigned size;\r
+   unsigned offset;            /* offset of first free byte */\r
+\r
+   struct brw_context *brw;\r
+};\r
+\r
+struct brw_cache_item {\r
+   unsigned hash;\r
+   unsigned key_size;          /* for variable-sized keys */\r
+   const void *key;\r
+\r
+   unsigned offset;            /* offset within pool's buffer */\r
+   unsigned data_size;\r
+\r
+   struct brw_cache_item *next;\r
+};\r
+\r
+\r
+\r
+struct brw_cache {\r
+   unsigned id;\r
+\r
+   const char *name;\r
+\r
+   struct brw_context *brw;\r
+   struct brw_mem_pool *pool;\r
+\r
+   struct brw_cache_item **items;\r
+   unsigned size, n_items;\r
+\r
+   unsigned key_size;          /* for fixed-size keys */\r
+   unsigned aux_size;\r
+\r
+   unsigned last_addr;                 /* offset of active item */\r
+};\r
+\r
+\r
+\r
+\r
+/* Considered adding a member to this struct to document which flags\r
+ * an update might raise so that ordering of the state atoms can be\r
+ * checked or derived at runtime.  Dropped the idea in favor of having\r
+ * a debug mode where the state is monitored for flags which are\r
+ * raised that have already been tested against.\r
+ */\r
+struct brw_tracked_state {\r
+   struct brw_state_flags dirty;\r
+   void (*update)( struct brw_context *brw );\r
+};\r
+\r
+\r
+/* Flags for brw->state.cache.\r
+ */\r
+#define CACHE_NEW_CC_VP                  (1<<BRW_CC_VP)\r
+#define CACHE_NEW_CC_UNIT                (1<<BRW_CC_UNIT)\r
+#define CACHE_NEW_WM_PROG                (1<<BRW_WM_PROG)\r
+#define CACHE_NEW_SAMPLER_DEFAULT_COLOR  (1<<BRW_SAMPLER_DEFAULT_COLOR)\r
+#define CACHE_NEW_SAMPLER                (1<<BRW_SAMPLER)\r
+#define CACHE_NEW_WM_UNIT                (1<<BRW_WM_UNIT)\r
+#define CACHE_NEW_SF_PROG                (1<<BRW_SF_PROG)\r
+#define CACHE_NEW_SF_VP                  (1<<BRW_SF_VP)\r
+#define CACHE_NEW_SF_UNIT                (1<<BRW_SF_UNIT)\r
+#define CACHE_NEW_VS_UNIT                (1<<BRW_VS_UNIT)\r
+#define CACHE_NEW_VS_PROG                (1<<BRW_VS_PROG)\r
+#define CACHE_NEW_GS_UNIT                (1<<BRW_GS_UNIT)\r
+#define CACHE_NEW_GS_PROG                (1<<BRW_GS_PROG)\r
+#define CACHE_NEW_CLIP_VP                (1<<BRW_CLIP_VP)\r
+#define CACHE_NEW_CLIP_UNIT              (1<<BRW_CLIP_UNIT)\r
+#define CACHE_NEW_CLIP_PROG              (1<<BRW_CLIP_PROG)\r
+#define CACHE_NEW_SURFACE                (1<<BRW_SS_SURFACE)\r
+#define CACHE_NEW_SURF_BIND              (1<<BRW_SS_SURF_BIND)\r
+\r
+\r
+\r
+\r
+enum brw_mempool_id {\r
+   BRW_GS_POOL,\r
+   BRW_SS_POOL,\r
+   BRW_MAX_POOL\r
+};\r
+\r
+\r
+struct brw_cached_batch_item {\r
+   struct header *header;\r
+   unsigned sz;\r
+   struct brw_cached_batch_item *next;\r
+};\r
+\r
+\r
+\r
+/* Protect against a future where PIPE_ATTRIB_MAX > 32.  Wouldn't life\r
+ * be easier if C allowed arrays of packed elements?\r
+ */\r
+#define ATTRIB_BIT_DWORDS  ((PIPE_ATTRIB_MAX+31)/32)\r
+\r
+\r
+\r
+\r
+struct brw_vertex_info {\r
+   unsigned varying;  /* varying:1[PIPE_ATTRIB_MAX] */\r
+   unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */\r
+};\r
+\r
+\r
+\r
+\r
+\r
+struct brw_context\r
+{\r
+   struct pipe_context pipe;\r
+   struct brw_winsys *winsys;\r
+\r
+   unsigned primitive;\r
+   unsigned reduced_primitive;\r
+\r
+   boolean emit_state_always;\r
+\r
+   struct {\r
+      struct brw_state_flags dirty;\r
+   } state;\r
+\r
+\r
+   struct {\r
+      const struct pipe_blend_state         *Blend;\r
+      const struct pipe_depth_stencil_alpha_state *DepthStencil;\r
+      const struct pipe_poly_stipple        *PolygonStipple;\r
+      const struct pipe_rasterizer_state    *Raster;\r
+      const struct pipe_sampler_state       *Samplers[PIPE_MAX_SAMPLERS];\r
+      const struct brw_vertex_program       *VertexProgram;\r
+      const struct brw_fragment_program     *FragmentProgram;\r
+\r
+      struct pipe_clip_state          Clip;\r
+      struct pipe_blend_color         BlendColor;\r
+      struct pipe_scissor_state       Scissor;\r
+      struct pipe_viewport_state      Viewport;\r
+      struct pipe_framebuffer_state   FrameBuffer;\r
+\r
+      const struct pipe_constant_buffer *Constants[2];\r
+      const struct brw_texture          *Texture[PIPE_MAX_SAMPLERS];\r
+   } attribs;\r
+\r
+   unsigned num_samplers;\r
+   unsigned num_textures;\r
+\r
+   struct brw_mem_pool pool[BRW_MAX_POOL];\r
+   struct brw_cache cache[BRW_MAX_CACHE];\r
+   struct brw_cached_batch_item *cached_batch_items;\r
+\r
+   struct {\r
+\r
+      /* Arrays with buffer objects to copy non-bufferobj arrays into\r
+       * for upload:\r
+       */\r
+      const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX];\r
+\r
+      struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX];\r
+\r
+#define BRW_NR_UPLOAD_BUFS 17\r
+#define BRW_UPLOAD_INIT_SIZE (128*1024)\r
+\r
+      /* Summary of size and varying of active arrays, so we can check\r
+       * for changes to this state:\r
+       */\r
+      struct brw_vertex_info info;\r
+   } vb;\r
+\r
+\r
+   unsigned hardware_dirty;\r
+   unsigned dirty;\r
+   unsigned pci_id;\r
+   /* BRW_NEW_URB_ALLOCATIONS:\r
+    */\r
+   struct {\r
+      unsigned vsize;          /* vertex size plus header in urb registers */\r
+      unsigned csize;          /* constant buffer size in urb registers */\r
+      unsigned sfsize;         /* setup data size in urb registers */\r
+\r
+      boolean constrained;\r
+\r
+      unsigned nr_vs_entries;\r
+      unsigned nr_gs_entries;\r
+      unsigned nr_clip_entries;\r
+      unsigned nr_sf_entries;\r
+      unsigned nr_cs_entries;\r
+\r
+/*       unsigned vs_size; */\r
+/*       unsigned gs_size; */\r
+/*       unsigned clip_size; */\r
+/*       unsigned sf_size; */\r
+/*       unsigned cs_size; */\r
+\r
+      unsigned vs_start;\r
+      unsigned gs_start;\r
+      unsigned clip_start;\r
+      unsigned sf_start;\r
+      unsigned cs_start;\r
+   } urb;\r
+\r
+\r
+   /* BRW_NEW_CURBE_OFFSETS:\r
+    */\r
+   struct {\r
+      unsigned wm_start;\r
+      unsigned wm_size;\r
+      unsigned clip_start;\r
+      unsigned clip_size;\r
+      unsigned vs_start;\r
+      unsigned vs_size;\r
+      unsigned total_size;\r
+\r
+      unsigned gs_offset;\r
+\r
+      float *last_buf;\r
+      unsigned last_bufsz;\r
+   } curbe;\r
+\r
+   struct {\r
+      struct brw_vs_prog_data *prog_data;\r
+\r
+      unsigned prog_gs_offset;\r
+      unsigned state_gs_offset;\r
+   } vs;\r
+\r
+   struct {\r
+      struct brw_gs_prog_data *prog_data;\r
+\r
+      boolean prog_active;\r
+      unsigned prog_gs_offset;\r
+      unsigned state_gs_offset;\r
+   } gs;\r
+\r
+   struct {\r
+      struct brw_clip_prog_data *prog_data;\r
+\r
+      unsigned prog_gs_offset;\r
+      unsigned vp_gs_offset;\r
+      unsigned state_gs_offset;\r
+   } clip;\r
+\r
+\r
+   struct {\r
+      struct brw_sf_prog_data *prog_data;\r
+\r
+      struct pipe_setup_linkage linkage;\r
+\r
+      unsigned prog_gs_offset;\r
+      unsigned vp_gs_offset;\r
+      unsigned state_gs_offset;\r
+   } sf;\r
+\r
+   struct {\r
+      struct brw_wm_prog_data *prog_data;\r
+\r
+//      struct brw_wm_compiler *compile_data;\r
+\r
+\r
+      /**\r
+       * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER\r
+       * cache\r
+       */\r
+      struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];\r
+\r
+      unsigned render_surf;\r
+      unsigned nr_surfaces;\r
+\r
+      unsigned max_threads;\r
+      struct pipe_buffer *scratch_buffer;\r
+      unsigned scratch_buffer_size;\r
+\r
+      unsigned sampler_count;\r
+      unsigned sampler_gs_offset;\r
+\r
+      struct brw_surface_binding_table bind;\r
+      unsigned bind_ss_offset;\r
+\r
+      unsigned prog_gs_offset;\r
+      unsigned state_gs_offset;\r
+   } wm;\r
+\r
+\r
+   struct {\r
+      unsigned vp_gs_offset;\r
+      unsigned state_gs_offset;\r
+   } cc;\r
+\r
+\r
+   /* Used to give every program string a unique id\r
+    */\r
+   unsigned program_id;\r
+};\r
+\r
+\r
+#define BRW_PACKCOLOR8888(r,g,b,a)  ((r<<24) | (g<<16) | (b<<8) | a)\r
+\r
+\r
+/*======================================================================\r
+ * brw_vtbl.c\r
+ */\r
+void brw_do_flush( struct brw_context *brw,\r
+                  unsigned flags );\r
+\r
+\r
+/*======================================================================\r
+ * brw_state.c\r
+ */\r
+void brw_validate_state(struct brw_context *brw);\r
+void brw_init_state(struct brw_context *brw);\r
+void brw_destroy_state(struct brw_context *brw);\r
+\r
+\r
+/*======================================================================\r
+ * brw_tex.c\r
+ */\r
+void brwUpdateTextureState( struct brw_context *brw );\r
+\r
+\r
+/* brw_urb.c\r
+ */\r
+void brw_upload_urb_fence(struct brw_context *brw);\r
+\r
+void brw_upload_constant_buffer_state(struct brw_context *brw);\r
+\r
+void brw_init_surface_functions(struct brw_context *brw);\r
+void brw_init_state_functions(struct brw_context *brw);\r
+void brw_init_flush_functions(struct brw_context *brw);\r
+void brw_init_string_functions(struct brw_context *brw);\r
+\r
+/*======================================================================\r
+ * Inline conversion functions.  These are better-typed than the\r
+ * macros used previously:\r
+ */\r
+static inline struct brw_context *\r
+brw_context( struct pipe_context *ctx )\r
+{\r
+   return (struct brw_context *)ctx;\r
+}\r
+\r
+#endif\r
+\r
index 6744a8a..f5efe9f 100644 (file)
-/**************************************************************************
- *
- * Copyright 2007 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.
- *
- **************************************************************************/
-
-/* Authors:  Zack Rusin <zack@tungstengraphics.com>
- *           Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/util/tgsi_dump.h"
-
-#include "brw_context.h"
-#include "brw_defines.h"
-#include "brw_state.h"
-#include "brw_draw.h"
-
-
-#define DUP( TYPE, VAL )                        \
-do {                                            \
-   struct TYPE *x = malloc(sizeof(*x));         \
-   memcpy(x, VAL, sizeof(*x) );                 \
-   return x;                                    \
-} while (0)
-
-/************************************************************************
- * Blend 
- */
-static void *
-brw_create_blend_state(struct pipe_context *pipe,
-                        const struct pipe_blend_state *blend)
-{   
-   DUP( pipe_blend_state, blend );
-}
-
-static void brw_bind_blend_state(struct pipe_context *pipe,
-                                 void *blend)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.Blend = (struct pipe_blend_state*)blend;
-   brw->state.dirty.brw |= BRW_NEW_BLEND;
-}
-
-
-static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)
-{
-   free(blend);
-}
-
-static void brw_set_blend_color( struct pipe_context *pipe,
-                            const struct pipe_blend_color *blend_color )
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.BlendColor = *blend_color;
-
-   brw->state.dirty.brw |= BRW_NEW_BLEND;
-}
-
-/************************************************************************
- * Sampler 
- */
-
-static void *
-brw_create_sampler_state(struct pipe_context *pipe,
-                          const struct pipe_sampler_state *sampler)
-{
-   DUP( pipe_sampler_state, sampler );
-}
-
-static void brw_bind_sampler_state(struct pipe_context *pipe,
-                                    unsigned unit, void *sampler)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.Samplers[unit] = sampler;
-   brw->state.dirty.brw |= BRW_NEW_SAMPLER;
-}
-
-static void brw_delete_sampler_state(struct pipe_context *pipe,
-                                      void *sampler)
-{
-   free(sampler);
-}
-
-
-/************************************************************************
- * Depth stencil 
- */
-
-static void *
-brw_create_depth_stencil_state(struct pipe_context *pipe,
-                           const struct pipe_depth_stencil_alpha_state *depth_stencil)
-{
-   DUP( pipe_depth_stencil_alpha_state, depth_stencil );
-}
-
-static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
-                                         void *depth_stencil)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
-
-   brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
-}
-
-static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
-                                           void *depth_stencil)
-{
-   free(depth_stencil);
-}
-
-/************************************************************************
- * Scissor
- */
-static void brw_set_scissor_state( struct pipe_context *pipe,
-                                 const struct pipe_scissor_state *scissor )
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
-   brw->state.dirty.brw |= BRW_NEW_SCISSOR;
-}
-
-
-/************************************************************************
- * Stipple
- */
-
-static void brw_set_polygon_stipple( struct pipe_context *pipe,
-                                   const struct pipe_poly_stipple *stipple )
-{
-}
-
-
-/************************************************************************
- * Fragment shader
- */
-
-static void * brw_create_fs_state(struct pipe_context *pipe,
-                                   const struct pipe_shader_state *shader)
-{
-   struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
-
-   /* XXX: Do I have to duplicate the tokens as well??
-    */
-   brw_fp->program = *shader;
-   brw_fp->id = brw_context(pipe)->program_id++;
-
-   tgsi_scan_shader(shader->tokens, &brw_fp->info);
-
-#if 0
-   brw_shader_info(shader->tokens,
-                  &brw_fp->info2);
-#endif
-
-   tgsi_dump(shader->tokens, 0);
-
-
-   return (void *)brw_fp;
-}
-
-static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
-   brw->state.dirty.brw |= BRW_NEW_FS;
-}
-
-static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
-{
-   FREE(shader);
-}
-
-
-/************************************************************************
- * Vertex shader and other TNL state 
- */
-
-static void *brw_create_vs_state(struct pipe_context *pipe,
-                                 const struct pipe_shader_state *shader)
-{
-   struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
-
-   /* XXX: Do I have to duplicate the tokens as well??
-    */
-   brw_vp->program = *shader;
-   brw_vp->id = brw_context(pipe)->program_id++;
-
-   tgsi_scan_shader(shader->tokens, &brw_vp->info);
-
-#if 0
-   brw_shader_info(shader->tokens,
-                  &brw_vp->info2);
-#endif
-   tgsi_dump(shader->tokens, 0);
-
-   return (void *)brw_vp;
-}
-
-static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
-   brw->state.dirty.brw |= BRW_NEW_VS;
-
-   debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
-}
-
-static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
-{
-   FREE(shader);
-}
-
-
-static void brw_set_clip_state( struct pipe_context *pipe,
-                                const struct pipe_clip_state *clip )
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.Clip = *clip;
-}
-
-
-static void brw_set_viewport_state( struct pipe_context *pipe,
-                                    const struct pipe_viewport_state *viewport )
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.Viewport = *viewport; /* struct copy */
-   brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
-
-   /* pass the viewport info to the draw module */
-   //draw_set_viewport_state(brw->draw, viewport);
-}
-
-
-static void brw_set_vertex_buffer( struct pipe_context *pipe,
-                                  unsigned index,
-                                  const struct pipe_vertex_buffer *buffer )
-{
-   struct brw_context *brw = brw_context(pipe);
-   brw->vb.vbo_array[index] = buffer;
-}
-
-static void brw_set_vertex_element(struct pipe_context *pipe,
-                                   unsigned index,
-                                   const struct pipe_vertex_element *element)
-{
-   /* flush ? */
-   struct brw_context *brw = brw_context(pipe);
-
-   assert(index < PIPE_ATTRIB_MAX);
-   struct brw_vertex_element_state el;
-   memset(&el, 0, sizeof(el));
-
-   el.ve0.src_offset = element->src_offset;
-   el.ve0.src_format = brw_translate_surface_format(element->src_format);
-   el.ve0.valid = 1;
-   el.ve0.vertex_buffer_index = element->vertex_buffer_index;
-
-   el.ve1.dst_offset   = index * 4;
-
-   el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
-   el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
-   el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
-   el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
-
-   switch (element->nr_components) {
-   case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
-   case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
-   case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
-      break;
-   }
-
-   brw->vb.inputs[index] = el;
-}
-
-
-
-/************************************************************************
- * Constant buffers
- */
-
-static void brw_set_constant_buffer(struct pipe_context *pipe,
-                                     uint shader, uint index,
-                                     const struct pipe_constant_buffer *buf)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   assert(buf == 0 || index == 0);
-
-   brw->attribs.Constants[shader] = buf;
-   brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
-}
-
-
-/************************************************************************
- * Texture surfaces
- */
-
-
-static void brw_set_sampler_texture(struct pipe_context *pipe,
-                                  unsigned unit,
-                                  struct pipe_texture *texture)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit],
-                          texture);
-
-   brw->state.dirty.brw |= BRW_NEW_TEXTURE;
-}
-
-
-/************************************************************************
- * Render targets, etc
- */
-
-static void brw_set_framebuffer_state(struct pipe_context *pipe,
-                                      const struct pipe_framebuffer_state *fb)
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.FrameBuffer = *fb; /* struct copy */
-
-   brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
-}
-
-
-
-/************************************************************************
- * Rasterizer state
- */
-
-static void *
-brw_create_rasterizer_state(struct pipe_context *pipe,
-                             const struct pipe_rasterizer_state *rasterizer)
-{
-   DUP(pipe_rasterizer_state, rasterizer);
-}
-
-static void brw_bind_rasterizer_state( struct pipe_context *pipe,
-                                        void *setup )
-{
-   struct brw_context *brw = brw_context(pipe);
-
-   brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
-
-   /* Also pass-through to draw module:
-    */
-   //draw_set_rasterizer_state(brw->draw, setup);
-
-   brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
-}
-
-static void brw_delete_rasterizer_state(struct pipe_context *pipe,
-                                         void *setup)
-{
-   free(setup);
-}
-
-
-
-void
-brw_init_state_functions( struct brw_context *brw )
-{
-   brw->pipe.create_blend_state = brw_create_blend_state;
-   brw->pipe.bind_blend_state = brw_bind_blend_state;
-   brw->pipe.delete_blend_state = brw_delete_blend_state;
-
-   brw->pipe.create_sampler_state = brw_create_sampler_state;
-   brw->pipe.bind_sampler_state = brw_bind_sampler_state;
-   brw->pipe.delete_sampler_state = brw_delete_sampler_state;
-
-   brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
-   brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
-   brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
-
-   brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
-   brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
-   brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
-   brw->pipe.create_fs_state = brw_create_fs_state;
-   brw->pipe.bind_fs_state = brw_bind_fs_state;
-   brw->pipe.delete_fs_state = brw_delete_fs_state;
-   brw->pipe.create_vs_state = brw_create_vs_state;
-   brw->pipe.bind_vs_state = brw_bind_vs_state;
-   brw->pipe.delete_vs_state = brw_delete_vs_state;
-
-   brw->pipe.set_blend_color = brw_set_blend_color;
-   brw->pipe.set_clip_state = brw_set_clip_state;
-   brw->pipe.set_constant_buffer = brw_set_constant_buffer;
-   brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
-
-//   brw->pipe.set_feedback_state = brw_set_feedback_state;
-//   brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
-
-   brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
-   brw->pipe.set_scissor_state = brw_set_scissor_state;
-   brw->pipe.set_sampler_texture = brw_set_sampler_texture;
-   brw->pipe.set_viewport_state = brw_set_viewport_state;
-   brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
-   brw->pipe.set_vertex_element = brw_set_vertex_element;
-}
+/**************************************************************************\r
+ *\r
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.\r
+ * All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the\r
+ * "Software"), to deal in the Software without restriction, including\r
+ * without limitation the rights to use, copy, modify, merge, publish,\r
+ * distribute, sub license, and/or sell copies of the Software, and to\r
+ * permit persons to whom the Software is furnished to do so, subject to\r
+ * the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice (including the\r
+ * next paragraph) shall be included in all copies or substantial portions\r
+ * of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ **************************************************************************/\r
+\r
+/* Authors:  Zack Rusin <zack@tungstengraphics.com>\r
+ *           Keith Whitwell <keith@tungstengraphics.com>\r
+ */\r
+\r
+\r
+#include "pipe/p_winsys.h"\r
+#include "pipe/p_util.h"\r
+#include "pipe/p_inlines.h"\r
+#include "pipe/p_shader_tokens.h"\r
+#include "tgsi/util/tgsi_dump.h"\r
+\r
+#include "brw_context.h"\r
+#include "brw_defines.h"\r
+#include "brw_state.h"\r
+#include "brw_draw.h"\r
+\r
+\r
+#define DUP( TYPE, VAL )                        \\r
+do {                                            \\r
+   struct TYPE *x = malloc(sizeof(*x));         \\r
+   memcpy(x, VAL, sizeof(*x) );                 \\r
+   return x;                                    \\r
+} while (0)\r
+\r
+/************************************************************************\r
+ * Blend \r
+ */\r
+static void *\r
+brw_create_blend_state(struct pipe_context *pipe,\r
+                        const struct pipe_blend_state *blend)\r
+{   \r
+   DUP( pipe_blend_state, blend );\r
+}\r
+\r
+static void brw_bind_blend_state(struct pipe_context *pipe,\r
+                                 void *blend)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.Blend = (struct pipe_blend_state*)blend;\r
+   brw->state.dirty.brw |= BRW_NEW_BLEND;\r
+}\r
+\r
+\r
+static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)\r
+{\r
+   free(blend);\r
+}\r
+\r
+static void brw_set_blend_color( struct pipe_context *pipe,\r
+                            const struct pipe_blend_color *blend_color )\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.BlendColor = *blend_color;\r
+\r
+   brw->state.dirty.brw |= BRW_NEW_BLEND;\r
+}\r
+\r
+/************************************************************************\r
+ * Sampler \r
+ */\r
+\r
+static void *\r
+brw_create_sampler_state(struct pipe_context *pipe,\r
+                          const struct pipe_sampler_state *sampler)\r
+{\r
+   DUP( pipe_sampler_state, sampler );\r
+}\r
+\r
+static void brw_bind_sampler_states(struct pipe_context *pipe,\r
+                                    unsigned num, void **sampler)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   assert(num <= PIPE_MAX_SAMPLERS);\r
+\r
+   /* Check for no-op */\r
+   if (num == brw->num_samplers &&\r
+       !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *)))\r
+      return;\r
+\r
+   memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *));\r
+   memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) *\r
+          sizeof(void *));\r
+\r
+   brw->num_samplers = num;\r
+\r
+   brw->state.dirty.brw |= BRW_NEW_SAMPLER;\r
+}\r
+\r
+static void brw_delete_sampler_state(struct pipe_context *pipe,\r
+                                      void *sampler)\r
+{\r
+   free(sampler);\r
+}\r
+\r
+\r
+/************************************************************************\r
+ * Depth stencil \r
+ */\r
+\r
+static void *\r
+brw_create_depth_stencil_state(struct pipe_context *pipe,\r
+                           const struct pipe_depth_stencil_alpha_state *depth_stencil)\r
+{\r
+   DUP( pipe_depth_stencil_alpha_state, depth_stencil );\r
+}\r
+\r
+static void brw_bind_depth_stencil_state(struct pipe_context *pipe,\r
+                                         void *depth_stencil)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;\r
+\r
+   brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;\r
+}\r
+\r
+static void brw_delete_depth_stencil_state(struct pipe_context *pipe,\r
+                                           void *depth_stencil)\r
+{\r
+   free(depth_stencil);\r
+}\r
+\r
+/************************************************************************\r
+ * Scissor\r
+ */\r
+static void brw_set_scissor_state( struct pipe_context *pipe,\r
+                                 const struct pipe_scissor_state *scissor )\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );\r
+   brw->state.dirty.brw |= BRW_NEW_SCISSOR;\r
+}\r
+\r
+\r
+/************************************************************************\r
+ * Stipple\r
+ */\r
+\r
+static void brw_set_polygon_stipple( struct pipe_context *pipe,\r
+                                   const struct pipe_poly_stipple *stipple )\r
+{\r
+}\r
+\r
+\r
+/************************************************************************\r
+ * Fragment shader\r
+ */\r
+\r
+static void * brw_create_fs_state(struct pipe_context *pipe,\r
+                                   const struct pipe_shader_state *shader)\r
+{\r
+   struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);\r
+\r
+   /* XXX: Do I have to duplicate the tokens as well??\r
+    */\r
+   brw_fp->program = *shader;\r
+   brw_fp->id = brw_context(pipe)->program_id++;\r
+\r
+   tgsi_scan_shader(shader->tokens, &brw_fp->info);\r
+\r
+#if 0\r
+   brw_shader_info(shader->tokens,\r
+                  &brw_fp->info2);\r
+#endif\r
+\r
+   tgsi_dump(shader->tokens, 0);\r
+\r
+\r
+   return (void *)brw_fp;\r
+}\r
+\r
+static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;\r
+   brw->state.dirty.brw |= BRW_NEW_FS;\r
+}\r
+\r
+static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)\r
+{\r
+   FREE(shader);\r
+}\r
+\r
+\r
+/************************************************************************\r
+ * Vertex shader and other TNL state \r
+ */\r
+\r
+static void *brw_create_vs_state(struct pipe_context *pipe,\r
+                                 const struct pipe_shader_state *shader)\r
+{\r
+   struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);\r
+\r
+   /* XXX: Do I have to duplicate the tokens as well??\r
+    */\r
+   brw_vp->program = *shader;\r
+   brw_vp->id = brw_context(pipe)->program_id++;\r
+\r
+   tgsi_scan_shader(shader->tokens, &brw_vp->info);\r
+\r
+#if 0\r
+   brw_shader_info(shader->tokens,\r
+                  &brw_vp->info2);\r
+#endif\r
+   tgsi_dump(shader->tokens, 0);\r
+\r
+   return (void *)brw_vp;\r
+}\r
+\r
+static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;\r
+   brw->state.dirty.brw |= BRW_NEW_VS;\r
+\r
+   debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");\r
+}\r
+\r
+static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)\r
+{\r
+   FREE(shader);\r
+}\r
+\r
+\r
+static void brw_set_clip_state( struct pipe_context *pipe,\r
+                                const struct pipe_clip_state *clip )\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.Clip = *clip;\r
+}\r
+\r
+\r
+static void brw_set_viewport_state( struct pipe_context *pipe,\r
+                                    const struct pipe_viewport_state *viewport )\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.Viewport = *viewport; /* struct copy */\r
+   brw->state.dirty.brw |= BRW_NEW_VIEWPORT;\r
+\r
+   /* pass the viewport info to the draw module */\r
+   //draw_set_viewport_state(brw->draw, viewport);\r
+}\r
+\r
+\r
+static void brw_set_vertex_buffer( struct pipe_context *pipe,\r
+                                  unsigned index,\r
+                                  const struct pipe_vertex_buffer *buffer )\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+   brw->vb.vbo_array[index] = buffer;\r
+}\r
+\r
+static void brw_set_vertex_element(struct pipe_context *pipe,\r
+                                   unsigned index,\r
+                                   const struct pipe_vertex_element *element)\r
+{\r
+   /* flush ? */\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   assert(index < PIPE_ATTRIB_MAX);\r
+   struct brw_vertex_element_state el;\r
+   memset(&el, 0, sizeof(el));\r
+\r
+   el.ve0.src_offset = element->src_offset;\r
+   el.ve0.src_format = brw_translate_surface_format(element->src_format);\r
+   el.ve0.valid = 1;\r
+   el.ve0.vertex_buffer_index = element->vertex_buffer_index;\r
+\r
+   el.ve1.dst_offset   = index * 4;\r
+\r
+   el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;\r
+   el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;\r
+   el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;\r
+   el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;\r
+\r
+   switch (element->nr_components) {\r
+   case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;\r
+   case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;\r
+   case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;\r
+      break;\r
+   }\r
+\r
+   brw->vb.inputs[index] = el;\r
+}\r
+\r
+\r
+\r
+/************************************************************************\r
+ * Constant buffers\r
+ */\r
+\r
+static void brw_set_constant_buffer(struct pipe_context *pipe,\r
+                                     uint shader, uint index,\r
+                                     const struct pipe_constant_buffer *buf)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   assert(buf == 0 || index == 0);\r
+\r
+   brw->attribs.Constants[shader] = buf;\r
+   brw->state.dirty.brw |= BRW_NEW_CONSTANTS;\r
+}\r
+\r
+\r
+/************************************************************************\r
+ * Texture surfaces\r
+ */\r
+\r
+\r
+static void brw_set_sampler_textures(struct pipe_context *pipe,\r
+                                     unsigned num,\r
+                                     struct pipe_texture **texture)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+   uint i;\r
+\r
+   assert(num <= PIPE_MAX_SAMPLERS);\r
+\r
+   /* Check for no-op */\r
+   if (num == brw->num_textures &&\r
+       !memcmp(brw->attribs.Texture, texture, num *\r
+               sizeof(struct pipe_texture *)))\r
+      return;\r
+\r
+   for (i = 0; i < num; i++)\r
+      pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],\r
+                             texture[i]);\r
+\r
+   for (i = num; i < brw->num_textures; i++)\r
+      pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],\r
+                             NULL);\r
+\r
+   brw->num_textures = num;\r
+\r
+   brw->state.dirty.brw |= BRW_NEW_TEXTURE;\r
+}\r
+\r
+\r
+/************************************************************************\r
+ * Render targets, etc\r
+ */\r
+\r
+static void brw_set_framebuffer_state(struct pipe_context *pipe,\r
+                                      const struct pipe_framebuffer_state *fb)\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.FrameBuffer = *fb; /* struct copy */\r
+\r
+   brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;\r
+}\r
+\r
+\r
+\r
+/************************************************************************\r
+ * Rasterizer state\r
+ */\r
+\r
+static void *\r
+brw_create_rasterizer_state(struct pipe_context *pipe,\r
+                             const struct pipe_rasterizer_state *rasterizer)\r
+{\r
+   DUP(pipe_rasterizer_state, rasterizer);\r
+}\r
+\r
+static void brw_bind_rasterizer_state( struct pipe_context *pipe,\r
+                                        void *setup )\r
+{\r
+   struct brw_context *brw = brw_context(pipe);\r
+\r
+   brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;\r
+\r
+   /* Also pass-through to draw module:\r
+    */\r
+   //draw_set_rasterizer_state(brw->draw, setup);\r
+\r
+   brw->state.dirty.brw |= BRW_NEW_RASTERIZER;\r
+}\r
+\r
+static void brw_delete_rasterizer_state(struct pipe_context *pipe,\r
+                                         void *setup)\r
+{\r
+   free(setup);\r
+}\r
+\r
+\r
+\r
+void\r
+brw_init_state_functions( struct brw_context *brw )\r
+{\r
+   brw->pipe.create_blend_state = brw_create_blend_state;\r
+   brw->pipe.bind_blend_state = brw_bind_blend_state;\r
+   brw->pipe.delete_blend_state = brw_delete_blend_state;\r
+\r
+   brw->pipe.create_sampler_state = brw_create_sampler_state;\r
+   brw->pipe.bind_sampler_states = brw_bind_sampler_states;\r
+   brw->pipe.delete_sampler_state = brw_delete_sampler_state;\r
+\r
+   brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;\r
+   brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;\r
+   brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;\r
+\r
+   brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;\r
+   brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;\r
+   brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;\r
+   brw->pipe.create_fs_state = brw_create_fs_state;\r
+   brw->pipe.bind_fs_state = brw_bind_fs_state;\r
+   brw->pipe.delete_fs_state = brw_delete_fs_state;\r
+   brw->pipe.create_vs_state = brw_create_vs_state;\r
+   brw->pipe.bind_vs_state = brw_bind_vs_state;\r
+   brw->pipe.delete_vs_state = brw_delete_vs_state;\r
+\r
+   brw->pipe.set_blend_color = brw_set_blend_color;\r
+   brw->pipe.set_clip_state = brw_set_clip_state;\r
+   brw->pipe.set_constant_buffer = brw_set_constant_buffer;\r
+   brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;\r
+\r
+//   brw->pipe.set_feedback_state = brw_set_feedback_state;\r
+//   brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;\r
+\r
+   brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;\r
+   brw->pipe.set_scissor_state = brw_set_scissor_state;\r
+   brw->pipe.set_sampler_textures = brw_set_sampler_textures;\r
+   brw->pipe.set_viewport_state = brw_set_viewport_state;\r
+   brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;\r
+   brw->pipe.set_vertex_element = brw_set_vertex_element;\r
+}\r
index de42ffc..ff5ba7e 100644 (file)
@@ -235,7 +235,8 @@ static void upload_wm_samplers(struct brw_context *brw)
    unsigned sampler_count = 0;
 
    /* BRW_NEW_SAMPLER */
-   for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
+   for (unit = 0; unit < brw->num_textures && unit < brw->num_samplers;
+        unit++) {
       /* determine unit enable/disable by looking for a bound texture */
       if (brw->attribs.Texture[unit]) {
          const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit];
index d16d919..853c743 100644 (file)
@@ -237,7 +237,7 @@ static void upload_wm_surfaces(struct brw_context *brw )
 
    /* BRW_NEW_TEXTURE
     */
-   for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+   for (i = 0; i < brw->num_textures && i < brw->num_samplers; i++) {
       const struct brw_texture *texUnit = brw->attribs.Texture[i];
 
       if (texUnit &&
index fa16ed9..316ae55 100644 (file)
-/**************************************************************************
- * 
- * Copyright 2007 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.
- * 
- **************************************************************************/
-
-/* Author:
- *    Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "draw/draw_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_util.h"
-#include "sp_clear.h"
-#include "sp_context.h"
-#include "sp_flush.h"
-#include "sp_prim_setup.h"
-#include "sp_prim_vbuf.h"
-#include "sp_state.h"
-#include "sp_surface.h"
-#include "sp_tile_cache.h"
-#include "sp_texture.h"
-#include "sp_winsys.h"
-#include "sp_query.h"
-
-
-
-/**
- * Map any drawing surfaces which aren't already mapped
- */
-void
-softpipe_map_surfaces(struct softpipe_context *sp)
-{
-   unsigned i;
-
-   for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
-      sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
-   }
-
-   sp_tile_cache_map_surfaces(sp->zsbuf_cache);
-}
-
-
-/**
- * Unmap any mapped drawing surfaces
- */
-void
-softpipe_unmap_surfaces(struct softpipe_context *sp)
-{
-   uint i;
-
-   for (i = 0; i < sp->framebuffer.num_cbufs; i++)
-      sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
-   sp_flush_tile_cache(sp, sp->zsbuf_cache);
-
-   for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
-      sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
-   }
-   sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
-}
-
-
-static void softpipe_destroy( struct pipe_context *pipe )
-{
-   struct softpipe_context *softpipe = softpipe_context( pipe );
-   struct pipe_winsys *ws = pipe->winsys;
-   uint i;
-
-   draw_destroy( softpipe->draw );
-
-   softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
-   softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
-   softpipe->quad.shade->destroy( softpipe->quad.shade );
-   softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
-   softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
-   softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
-   softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
-   softpipe->quad.coverage->destroy( softpipe->quad.coverage );
-   softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
-   softpipe->quad.blend->destroy( softpipe->quad.blend );
-   softpipe->quad.colormask->destroy( softpipe->quad.colormask );
-   softpipe->quad.output->destroy( softpipe->quad.output );
-
-   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
-      sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
-   sp_destroy_tile_cache(softpipe->zsbuf_cache);
-
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
-      sp_destroy_tile_cache(softpipe->tex_cache[i]);
-
-   for (i = 0; i < Elements(softpipe->constants); i++) {
-      if (softpipe->constants[i].buffer) {
-         pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
-      }
-   }
-
-   FREE( softpipe );
-}
-
-
-struct pipe_context *
-softpipe_create( struct pipe_screen *screen,
-                 struct pipe_winsys *pipe_winsys,
-                 struct softpipe_winsys *softpipe_winsys )
-{
-   struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
-   uint i;
-
-#if defined(__i386__) || defined(__386__)
-   softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
-#else
-   softpipe->use_sse = FALSE;
-#endif
-
-   softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
-
-   softpipe->pipe.winsys = pipe_winsys;
-   softpipe->pipe.screen = screen;
-   softpipe->pipe.destroy = softpipe_destroy;
-
-   /* state setters */
-   softpipe->pipe.create_blend_state = softpipe_create_blend_state;
-   softpipe->pipe.bind_blend_state   = softpipe_bind_blend_state;
-   softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
-
-   softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
-   softpipe->pipe.bind_sampler_state   = softpipe_bind_sampler_state;
-   softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
-
-   softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
-   softpipe->pipe.bind_depth_stencil_alpha_state   = softpipe_bind_depth_stencil_state;
-   softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
-
-   softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
-   softpipe->pipe.bind_rasterizer_state   = softpipe_bind_rasterizer_state;
-   softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
-
-   softpipe->pipe.create_fs_state = softpipe_create_fs_state;
-   softpipe->pipe.bind_fs_state   = softpipe_bind_fs_state;
-   softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
-
-   softpipe->pipe.create_vs_state = softpipe_create_vs_state;
-   softpipe->pipe.bind_vs_state   = softpipe_bind_vs_state;
-   softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
-
-   softpipe->pipe.set_blend_color = softpipe_set_blend_color;
-   softpipe->pipe.set_clip_state = softpipe_set_clip_state;
-   softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
-   softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
-   softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
-   softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
-   softpipe->pipe.set_sampler_texture = softpipe_set_sampler_texture;
-   softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
-
-   softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
-   softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
-
-   softpipe->pipe.draw_arrays = softpipe_draw_arrays;
-   softpipe->pipe.draw_elements = softpipe_draw_elements;
-
-   softpipe->pipe.clear = softpipe_clear;
-   softpipe->pipe.flush = softpipe_flush;
-
-   softpipe_init_query_funcs( softpipe );
-   softpipe_init_texture_funcs( softpipe );
-
-   /*
-    * Alloc caches for accessing drawing surfaces and textures.
-    * Must be before quad stage setup!
-    */
-   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
-      softpipe->cbuf_cache[i] = sp_create_tile_cache();
-   softpipe->zsbuf_cache = sp_create_tile_cache();
-
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
-      softpipe->tex_cache[i] = sp_create_tile_cache();
-
-
-   /* setup quad rendering stages */
-   softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
-   softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
-   softpipe->quad.shade = sp_quad_shade_stage(softpipe);
-   softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
-   softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
-   softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
-   softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
-   softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
-   softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
-   softpipe->quad.blend = sp_quad_blend_stage(softpipe);
-   softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
-   softpipe->quad.output = sp_quad_output_stage(softpipe);
-
-   softpipe->winsys = softpipe_winsys;
-
-   /*
-    * Create drawing context and plug our rendering stage into it.
-    */
-   softpipe->draw = draw_create();
-   assert(softpipe->draw);
-   softpipe->setup = sp_draw_render_stage(softpipe);
-
-   if (GETENV( "SP_VBUF" ) != NULL) {
-      sp_init_vbuf(softpipe);
-   }
-   else {
-      draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
-   }
-
-   /* plug in AA line/point stages */
-   draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
-   draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
-
-#if USE_DRAW_STAGE_PSTIPPLE
-   /* Do polygon stipple w/ texture map + frag prog? */
-   draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
-#endif
-
-   sp_init_surface_functions(softpipe);
-
-   return &softpipe->pipe;
-}
+/**************************************************************************\r
+ * \r
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.\r
+ * All Rights Reserved.\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the\r
+ * "Software"), to deal in the Software without restriction, including\r
+ * without limitation the rights to use, copy, modify, merge, publish,\r
+ * distribute, sub license, and/or sell copies of the Software, and to\r
+ * permit persons to whom the Software is furnished to do so, subject to\r
+ * the following conditions:\r
+ * \r
+ * The above copyright notice and this permission notice (including the\r
+ * next paragraph) shall be included in all copies or substantial portions\r
+ * of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ * \r
+ **************************************************************************/\r
+\r
+/* Author:\r
+ *    Keith Whitwell <keith@tungstengraphics.com>\r
+ */\r
+\r
+#include "draw/draw_context.h"\r
+#include "pipe/p_defines.h"\r
+#include "pipe/p_inlines.h"\r
+#include "pipe/p_util.h"\r
+#include "sp_clear.h"\r
+#include "sp_context.h"\r
+#include "sp_flush.h"\r
+#include "sp_prim_setup.h"\r
+#include "sp_prim_vbuf.h"\r
+#include "sp_state.h"\r
+#include "sp_surface.h"\r
+#include "sp_tile_cache.h"\r
+#include "sp_texture.h"\r
+#include "sp_winsys.h"\r
+#include "sp_query.h"\r
+\r
+\r
+\r
+/**\r
+ * Map any drawing surfaces which aren't already mapped\r
+ */\r
+void\r
+softpipe_map_surfaces(struct softpipe_context *sp)\r
+{\r
+   unsigned i;\r
+\r
+   for (i = 0; i < sp->framebuffer.num_cbufs; i++) {\r
+      sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);\r
+   }\r
+\r
+   sp_tile_cache_map_surfaces(sp->zsbuf_cache);\r
+}\r
+\r
+\r
+/**\r
+ * Unmap any mapped drawing surfaces\r
+ */\r
+void\r
+softpipe_unmap_surfaces(struct softpipe_context *sp)\r
+{\r
+   uint i;\r
+\r
+   for (i = 0; i < sp->framebuffer.num_cbufs; i++)\r
+      sp_flush_tile_cache(sp, sp->cbuf_cache[i]);\r
+   sp_flush_tile_cache(sp, sp->zsbuf_cache);\r
+\r
+   for (i = 0; i < sp->framebuffer.num_cbufs; i++) {\r
+      sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);\r
+   }\r
+   sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);\r
+}\r
+\r
+\r
+static void softpipe_destroy( struct pipe_context *pipe )\r
+{\r
+   struct softpipe_context *softpipe = softpipe_context( pipe );\r
+   struct pipe_winsys *ws = pipe->winsys;\r
+   uint i;\r
+\r
+   draw_destroy( softpipe->draw );\r
+\r
+   softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );\r
+   softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );\r
+   softpipe->quad.shade->destroy( softpipe->quad.shade );\r
+   softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );\r
+   softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );\r
+   softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );\r
+   softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );\r
+   softpipe->quad.coverage->destroy( softpipe->quad.coverage );\r
+   softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );\r
+   softpipe->quad.blend->destroy( softpipe->quad.blend );\r
+   softpipe->quad.colormask->destroy( softpipe->quad.colormask );\r
+   softpipe->quad.output->destroy( softpipe->quad.output );\r
+\r
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)\r
+      sp_destroy_tile_cache(softpipe->cbuf_cache[i]);\r
+   sp_destroy_tile_cache(softpipe->zsbuf_cache);\r
+\r
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)\r
+      sp_destroy_tile_cache(softpipe->tex_cache[i]);\r
+\r
+   for (i = 0; i < Elements(softpipe->constants); i++) {\r
+      if (softpipe->constants[i].buffer) {\r
+         pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);\r
+      }\r
+   }\r
+\r
+   FREE( softpipe );\r
+}\r
+\r
+\r
+struct pipe_context *\r
+softpipe_create( struct pipe_screen *screen,\r
+                 struct pipe_winsys *pipe_winsys,\r
+                 struct softpipe_winsys *softpipe_winsys )\r
+{\r
+   struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);\r
+   uint i;\r
+\r
+#if defined(__i386__) || defined(__386__)\r
+   softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;\r
+#else\r
+   softpipe->use_sse = FALSE;\r
+#endif\r
+\r
+   softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;\r
+\r
+   softpipe->pipe.winsys = pipe_winsys;\r
+   softpipe->pipe.screen = screen;\r
+   softpipe->pipe.destroy = softpipe_destroy;\r
+\r
+   /* state setters */\r
+   softpipe->pipe.create_blend_state = softpipe_create_blend_state;\r
+   softpipe->pipe.bind_blend_state   = softpipe_bind_blend_state;\r
+   softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;\r
+\r
+   softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;\r
+   softpipe->pipe.bind_sampler_states  = softpipe_bind_sampler_states;\r
+   softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;\r
+\r
+   softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;\r
+   softpipe->pipe.bind_depth_stencil_alpha_state   = softpipe_bind_depth_stencil_state;\r
+   softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;\r
+\r
+   softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;\r
+   softpipe->pipe.bind_rasterizer_state   = softpipe_bind_rasterizer_state;\r
+   softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;\r
+\r
+   softpipe->pipe.create_fs_state = softpipe_create_fs_state;\r
+   softpipe->pipe.bind_fs_state   = softpipe_bind_fs_state;\r
+   softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;\r
+\r
+   softpipe->pipe.create_vs_state = softpipe_create_vs_state;\r
+   softpipe->pipe.bind_vs_state   = softpipe_bind_vs_state;\r
+   softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;\r
+\r
+   softpipe->pipe.set_blend_color = softpipe_set_blend_color;\r
+   softpipe->pipe.set_clip_state = softpipe_set_clip_state;\r
+   softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;\r
+   softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;\r
+   softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;\r
+   softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;\r
+   softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;\r
+   softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;\r
+\r
+   softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;\r
+   softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;\r
+\r
+   softpipe->pipe.draw_arrays = softpipe_draw_arrays;\r
+   softpipe->pipe.draw_elements = softpipe_draw_elements;\r
+\r
+   softpipe->pipe.clear = softpipe_clear;\r
+   softpipe->pipe.flush = softpipe_flush;\r
+\r
+   softpipe_init_query_funcs( softpipe );\r
+   softpipe_init_texture_funcs( softpipe );\r
+\r
+   /*\r
+    * Alloc caches for accessing drawing surfaces and textures.\r
+    * Must be before quad stage setup!\r
+    */\r
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)\r
+      softpipe->cbuf_cache[i] = sp_create_tile_cache();\r
+   softpipe->zsbuf_cache = sp_create_tile_cache();\r
+\r
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)\r
+      softpipe->tex_cache[i] = sp_create_tile_cache();\r
+\r
+\r
+   /* setup quad rendering stages */\r
+   softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);\r
+   softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);\r
+   softpipe->quad.shade = sp_quad_shade_stage(softpipe);\r
+   softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);\r
+   softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);\r
+   softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);\r
+   softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);\r
+   softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);\r
+   softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);\r
+   softpipe->quad.blend = sp_quad_blend_stage(softpipe);\r
+   softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);\r
+   softpipe->quad.output = sp_quad_output_stage(softpipe);\r
+\r
+   softpipe->winsys = softpipe_winsys;\r
+\r
+   /*\r
+    * Create drawing context and plug our rendering stage into it.\r
+    */\r
+   softpipe->draw = draw_create();\r
+   assert(softpipe->draw);\r
+   softpipe->setup = sp_draw_render_stage(softpipe);\r
+\r
+   if (GETENV( "SP_VBUF" ) != NULL) {\r
+      sp_init_vbuf(softpipe);\r
+   }\r
+   else {\r
+      draw_set_rasterize_stage(softpipe->draw, softpipe->setup);\r
+   }\r
+\r
+   /* plug in AA line/point stages */\r
+   draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);\r
+   draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);\r
+\r
+#if USE_DRAW_STAGE_PSTIPPLE\r
+   /* Do polygon stipple w/ texture map + frag prog? */\r
+   draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);\r
+#endif\r
+\r
+   sp_init_surface_functions(softpipe);\r
+\r
+   return &softpipe->pipe;\r
+}\r
index feeafc7..19e6cfa 100644 (file)
@@ -81,6 +81,9 @@ struct softpipe_context {
    struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
    unsigned dirty;
 
+   unsigned num_samplers;
+   unsigned num_textures;
+
    /* Counter for occlusion queries.  Note this supports overlapping
     * queries.
     */
index 1fbb2e3..9198198 100644 (file)
-/**************************************************************************
- * 
- * Copyright 2007 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.
- * 
- **************************************************************************/
-
-/* Vertices are just an array of floats, with all the attributes
- * packed.  We currently assume a layout like:
- *
- * attr[0][0..3] - window position
- * attr[1..n][0..3] - remaining attributes.
- *
- * Attributes are assumed to be 4 floats wide but are packed so that
- * all the enabled attributes run contiguously.
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "sp_context.h"
-#include "sp_state.h"
-#include "sp_headers.h"
-#include "sp_quad.h"
-#include "sp_texture.h"
-#include "sp_tex_sample.h"
-
-
-struct quad_shade_stage
-{
-   struct quad_stage stage;
-   struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
-   struct tgsi_exec_machine machine;
-   struct tgsi_exec_vector *inputs, *outputs;
-   int colorOutSlot, depthOutSlot;
-};
-
-
-/** cast wrapper */
-static INLINE struct quad_shade_stage *
-quad_shade_stage(struct quad_stage *qs)
-{
-   return (struct quad_shade_stage *) qs;
-}
-
-
-
-/**
- * Execute fragment shader for the four fragments in the quad.
- */
-static void
-shade_quad(
-   struct quad_stage *qs,
-   struct quad_header *quad )
-{
-   struct quad_shade_stage *qss = quad_shade_stage( qs );
-   struct softpipe_context *softpipe = qs->softpipe;
-   struct tgsi_exec_machine *machine = &qss->machine;
-
-   /* Consts do not require 16 byte alignment. */
-   machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
-
-   machine->InterpCoefs = quad->coef;
-
-   /* run shader */
-   quad->mask &= softpipe->fs->run( softpipe->fs, 
-                                   &qss->machine,
-                                   quad );
-
-   /* store result color */
-   if (qss->colorOutSlot >= 0) {
-      /* XXX need to handle multiple color outputs someday */
-      assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
-             == TGSI_SEMANTIC_COLOR);
-      memcpy(
-             quad->outputs.color,
-             &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
-             sizeof( quad->outputs.color ) );
-   }
-
-   /*
-    * XXX the following code for updating quad->outputs.depth
-    * isn't really needed if we did early z testing.
-    */
-
-   /* store result Z */
-   if (qss->depthOutSlot >= 0) {
-      /* output[slot] is new Z */
-      uint i;
-      for (i = 0; i < 4; i++) {
-         quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
-      }
-   }
-   else {
-      /* copy input Z (which was interpolated by the executor) to output Z */
-      uint i;
-      for (i = 0; i < 4; i++) {
-         quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
-         /* XXX not sure the above line is always correct.  The following
-          * might be better:
-         quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
-          */
-      }
-   }
-
-   /* shader may cull fragments */
-   if( quad->mask ) {
-      qs->next->run( qs->next, quad );
-   }
-}
-
-/**
- * Per-primitive (or per-begin?) setup
- */
-static void shade_begin(struct quad_stage *qs)
-{
-   struct quad_shade_stage *qss = quad_shade_stage(qs);
-   struct softpipe_context *softpipe = qs->softpipe;
-   unsigned i;
-
-   /* set TGSI sampler state that varies */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      qss->samplers[i].state = softpipe->sampler[i];
-      qss->samplers[i].texture = softpipe->texture[i];
-   }
-
-   /* find output slots for depth, color */
-   qss->colorOutSlot = -1;
-   qss->depthOutSlot = -1;
-   for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
-      switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
-      case TGSI_SEMANTIC_POSITION:
-         qss->depthOutSlot = i;
-         break;
-      case TGSI_SEMANTIC_COLOR:
-         qss->colorOutSlot = i;
-         break;
-      }
-   }
-   
-   softpipe->fs->prepare( softpipe->fs, 
-                         &qss->machine,
-                         qss->samplers );
-
-   qs->next->begin(qs->next);
-}
-
-
-static void shade_destroy(struct quad_stage *qs)
-{
-   struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
-
-   tgsi_exec_machine_free_data(&qss->machine);
-   FREE( qss->inputs );
-   FREE( qss->outputs );
-   FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
-{
-   struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
-   uint i;
-
-   /* allocate storage for program inputs/outputs, aligned to 16 bytes */
-   qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
-   qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
-   qss->machine.Inputs = align16(qss->inputs);
-   qss->machine.Outputs = align16(qss->outputs);
-
-   qss->stage.softpipe = softpipe;
-   qss->stage.begin = shade_begin;
-   qss->stage.run = shade_quad;
-   qss->stage.destroy = shade_destroy;
-
-   /* set TGSI sampler state that's constant */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      assert(softpipe->tex_cache[i]);
-      qss->samplers[i].get_samples = sp_get_samples;
-      qss->samplers[i].pipe = &softpipe->pipe;
-      qss->samplers[i].cache = softpipe->tex_cache[i];
-   }
-
-   tgsi_exec_machine_init( &qss->machine );
-
-   return &qss->stage;
-}
+/**************************************************************************\r
+ * \r
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.\r
+ * All Rights Reserved.\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the\r
+ * "Software"), to deal in the Software without restriction, including\r
+ * without limitation the rights to use, copy, modify, merge, publish,\r
+ * distribute, sub license, and/or sell copies of the Software, and to\r
+ * permit persons to whom the Software is furnished to do so, subject to\r
+ * the following conditions:\r
+ * \r
+ * The above copyright notice and this permission notice (including the\r
+ * next paragraph) shall be included in all copies or substantial portions\r
+ * of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ * \r
+ **************************************************************************/\r
+\r
+/* Vertices are just an array of floats, with all the attributes\r
+ * packed.  We currently assume a layout like:\r
+ *\r
+ * attr[0][0..3] - window position\r
+ * attr[1..n][0..3] - remaining attributes.\r
+ *\r
+ * Attributes are assumed to be 4 floats wide but are packed so that\r
+ * all the enabled attributes run contiguously.\r
+ */\r
+\r
+#include "pipe/p_util.h"\r
+#include "pipe/p_defines.h"\r
+#include "pipe/p_shader_tokens.h"\r
+\r
+#include "sp_context.h"\r
+#include "sp_state.h"\r
+#include "sp_headers.h"\r
+#include "sp_quad.h"\r
+#include "sp_texture.h"\r
+#include "sp_tex_sample.h"\r
+\r
+\r
+struct quad_shade_stage\r
+{\r
+   struct quad_stage stage;\r
+   struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];\r
+   struct tgsi_exec_machine machine;\r
+   struct tgsi_exec_vector *inputs, *outputs;\r
+   int colorOutSlot, depthOutSlot;\r
+};\r
+\r
+\r
+/** cast wrapper */\r
+static INLINE struct quad_shade_stage *\r
+quad_shade_stage(struct quad_stage *qs)\r
+{\r
+   return (struct quad_shade_stage *) qs;\r
+}\r
+\r
+\r
+\r
+/**\r
+ * Execute fragment shader for the four fragments in the quad.\r
+ */\r
+static void\r
+shade_quad(\r
+   struct quad_stage *qs,\r
+   struct quad_header *quad )\r
+{\r
+   struct quad_shade_stage *qss = quad_shade_stage( qs );\r
+   struct softpipe_context *softpipe = qs->softpipe;\r
+   struct tgsi_exec_machine *machine = &qss->machine;\r
+\r
+   /* Consts do not require 16 byte alignment. */\r
+   machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];\r
+\r
+   machine->InterpCoefs = quad->coef;\r
+\r
+   /* run shader */\r
+   quad->mask &= softpipe->fs->run( softpipe->fs, \r
+                                   &qss->machine,\r
+                                   quad );\r
+\r
+   /* store result color */\r
+   if (qss->colorOutSlot >= 0) {\r
+      /* XXX need to handle multiple color outputs someday */\r
+      assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]\r
+             == TGSI_SEMANTIC_COLOR);\r
+      memcpy(\r
+             quad->outputs.color,\r
+             &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],\r
+             sizeof( quad->outputs.color ) );\r
+   }\r
+\r
+   /*\r
+    * XXX the following code for updating quad->outputs.depth\r
+    * isn't really needed if we did early z testing.\r
+    */\r
+\r
+   /* store result Z */\r
+   if (qss->depthOutSlot >= 0) {\r
+      /* output[slot] is new Z */\r
+      uint i;\r
+      for (i = 0; i < 4; i++) {\r
+         quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];\r
+      }\r
+   }\r
+   else {\r
+      /* copy input Z (which was interpolated by the executor) to output Z */\r
+      uint i;\r
+      for (i = 0; i < 4; i++) {\r
+         quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];\r
+         /* XXX not sure the above line is always correct.  The following\r
+          * might be better:\r
+         quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];\r
+          */\r
+      }\r
+   }\r
+\r
+   /* shader may cull fragments */\r
+   if( quad->mask ) {\r
+      qs->next->run( qs->next, quad );\r
+   }\r
+}\r
+\r
+/**\r
+ * Per-primitive (or per-begin?) setup\r
+ */\r
+static void shade_begin(struct quad_stage *qs)\r
+{\r
+   struct quad_shade_stage *qss = quad_shade_stage(qs);\r
+   struct softpipe_context *softpipe = qs->softpipe;\r
+   unsigned i;\r
+   unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers);\r
+\r
+   /* set TGSI sampler state that varies */\r
+   for (i = 0; i < num; i++) {\r
+      qss->samplers[i].state = softpipe->sampler[i];\r
+      qss->samplers[i].texture = softpipe->texture[i];\r
+   }\r
+\r
+   /* find output slots for depth, color */\r
+   qss->colorOutSlot = -1;\r
+   qss->depthOutSlot = -1;\r
+   for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {\r
+      switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {\r
+      case TGSI_SEMANTIC_POSITION:\r
+         qss->depthOutSlot = i;\r
+         break;\r
+      case TGSI_SEMANTIC_COLOR:\r
+         qss->colorOutSlot = i;\r
+         break;\r
+      }\r
+   }\r
+   \r
+   softpipe->fs->prepare( softpipe->fs, \r
+                         &qss->machine,\r
+                         qss->samplers );\r
+\r
+   qs->next->begin(qs->next);\r
+}\r
+\r
+\r
+static void shade_destroy(struct quad_stage *qs)\r
+{\r
+   struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;\r
+\r
+   tgsi_exec_machine_free_data(&qss->machine);\r
+   FREE( qss->inputs );\r
+   FREE( qss->outputs );\r
+   FREE( qs );\r
+}\r
+\r
+\r
+struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )\r
+{\r
+   struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);\r
+   uint i;\r
+\r
+   /* allocate storage for program inputs/outputs, aligned to 16 bytes */\r
+   qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);\r
+   qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);\r
+   qss->machine.Inputs = align16(qss->inputs);\r
+   qss->machine.Outputs = align16(qss->outputs);\r
+\r
+   qss->stage.softpipe = softpipe;\r
+   qss->stage.begin = shade_begin;\r
+   qss->stage.run = shade_quad;\r
+   qss->stage.destroy = shade_destroy;\r
+\r
+   /* set TGSI sampler state that's constant */\r
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {\r
+      assert(softpipe->tex_cache[i]);\r
+      qss->samplers[i].get_samples = sp_get_samples;\r
+      qss->samplers[i].pipe = &softpipe->pipe;\r
+      qss->samplers[i].cache = softpipe->tex_cache[i];\r
+   }\r
+\r
+   tgsi_exec_machine_init( &qss->machine );\r
+\r
+   return &qss->stage;\r
+}\r
index 3943d4e..45d1591 100644 (file)
-/**************************************************************************
- * 
- * Copyright 2007 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.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef SP_STATE_H
-#define SP_STATE_H
-
-#include "pipe/p_state.h"
-#include "tgsi/util/tgsi_scan.h"
-
-
-#define SP_NEW_VIEWPORT      0x1
-#define SP_NEW_RASTERIZER    0x2
-#define SP_NEW_FS            0x4
-#define SP_NEW_BLEND         0x8
-#define SP_NEW_CLIP          0x10
-#define SP_NEW_SCISSOR       0x20
-#define SP_NEW_STIPPLE       0x40
-#define SP_NEW_FRAMEBUFFER   0x80
-#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100
-#define SP_NEW_CONSTANTS     0x200
-#define SP_NEW_SAMPLER       0x400
-#define SP_NEW_TEXTURE       0x800
-#define SP_NEW_VERTEX        0x1000
-#define SP_NEW_VS            0x2000
-#define SP_NEW_QUERY         0x4000
-
-
-struct tgsi_sampler;
-struct tgsi_exec_machine;
-
-
-/** Subclass of pipe_shader_state (though it doesn't really need to be).
- *
- * This is starting to look an awful lot like a quad pipeline stage...
- */
-struct sp_fragment_shader {
-   struct pipe_shader_state shader;
-
-   struct tgsi_shader_info info;
-
-   void (*prepare)( const struct sp_fragment_shader *shader,
-                   struct tgsi_exec_machine *machine,
-                   struct tgsi_sampler *samplers);
-
-   /* Run the shader - this interface will get cleaned up in the
-    * future:
-    */
-   unsigned (*run)( const struct sp_fragment_shader *shader,
-                   struct tgsi_exec_machine *machine,
-                   struct quad_header *quad );
-
-
-   void (*delete)( struct sp_fragment_shader * );
-};
-
-struct vertex_info;
-
-/** Subclass of pipe_shader_state */
-struct sp_vertex_shader {
-   struct pipe_shader_state shader;
-   struct draw_vertex_shader *draw_data;
-};
-
-
-
-void *
-softpipe_create_blend_state(struct pipe_context *,
-                            const struct pipe_blend_state *);
-void softpipe_bind_blend_state(struct pipe_context *,
-                               void *);
-void softpipe_delete_blend_state(struct pipe_context *,
-                                 void *);
-
-void *
-softpipe_create_sampler_state(struct pipe_context *,
-                              const struct pipe_sampler_state *);
-void softpipe_bind_sampler_state(struct pipe_context *, unsigned, void *);
-void softpipe_delete_sampler_state(struct pipe_context *, void *);
-
-void *
-softpipe_create_depth_stencil_state(struct pipe_context *,
-                                    const struct pipe_depth_stencil_alpha_state *);
-void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
-void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
-
-void *
-softpipe_create_rasterizer_state(struct pipe_context *,
-                                 const struct pipe_rasterizer_state *);
-void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
-void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
-
-void softpipe_set_framebuffer_state( struct pipe_context *,
-                            const struct pipe_framebuffer_state * );
-
-void softpipe_set_blend_color( struct pipe_context *pipe,
-                               const struct pipe_blend_color *blend_color );
-
-void softpipe_set_clip_state( struct pipe_context *,
-                            const struct pipe_clip_state * );
-
-void softpipe_set_constant_buffer(struct pipe_context *,
-                                  uint shader, uint index,
-                                  const struct pipe_constant_buffer *buf);
-
-void *softpipe_create_fs_state(struct pipe_context *,
-                               const struct pipe_shader_state *);
-void softpipe_bind_fs_state(struct pipe_context *, void *);
-void softpipe_delete_fs_state(struct pipe_context *, void *);
-void *softpipe_create_vs_state(struct pipe_context *,
-                               const struct pipe_shader_state *);
-void softpipe_bind_vs_state(struct pipe_context *, void *);
-void softpipe_delete_vs_state(struct pipe_context *, void *);
-
-void softpipe_set_polygon_stipple( struct pipe_context *,
-                                 const struct pipe_poly_stipple * );
-
-void softpipe_set_scissor_state( struct pipe_context *,
-                                 const struct pipe_scissor_state * );
-
-void softpipe_set_sampler_texture( struct pipe_context *,
-                                 unsigned unit,
-                                 struct pipe_texture * );
-
-void softpipe_set_viewport_state( struct pipe_context *,
-                                  const struct pipe_viewport_state * );
-
-void softpipe_set_vertex_element(struct pipe_context *,
-                                 unsigned index,
-                                 const struct pipe_vertex_element *);
-
-void softpipe_set_vertex_buffer(struct pipe_context *,
-                                unsigned index,
-                                const struct pipe_vertex_buffer *);
-
-
-void softpipe_update_derived( struct softpipe_context *softpipe );
-
-
-boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
-                            unsigned start, unsigned count);
-
-boolean softpipe_draw_elements(struct pipe_context *pipe,
-                              struct pipe_buffer *indexBuffer,
-                              unsigned indexSize,
-                              unsigned mode, unsigned start, unsigned count);
-
-
-void
-softpipe_map_surfaces(struct softpipe_context *sp);
-
-void
-softpipe_unmap_surfaces(struct softpipe_context *sp);
-
-void
-softpipe_map_texture_surfaces(struct softpipe_context *sp);
-
-void
-softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
-
-
-struct vertex_info *
-softpipe_get_vertex_info(struct softpipe_context *softpipe);
-
-struct vertex_info *
-softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
-
-
-#endif
+/**************************************************************************\r
+ * \r
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.\r
+ * All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the\r
+ * "Software"), to deal in the Software without restriction, including\r
+ * without limitation the rights to use, copy, modify, merge, publish,\r
+ * distribute, sub license, and/or sell copies of the Software, and to\r
+ * permit persons to whom the Software is furnished to do so, subject to\r
+ * the following conditions:\r
+ * \r
+ * The above copyright notice and this permission notice (including the\r
+ * next paragraph) shall be included in all copies or substantial portions\r
+ * of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ * \r
+ **************************************************************************/\r
+\r
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>\r
+ */\r
+\r
+#ifndef SP_STATE_H\r
+#define SP_STATE_H\r
+\r
+#include "pipe/p_state.h"\r
+#include "tgsi/util/tgsi_scan.h"\r
+\r
+\r
+#define SP_NEW_VIEWPORT      0x1\r
+#define SP_NEW_RASTERIZER    0x2\r
+#define SP_NEW_FS            0x4\r
+#define SP_NEW_BLEND         0x8\r
+#define SP_NEW_CLIP          0x10\r
+#define SP_NEW_SCISSOR       0x20\r
+#define SP_NEW_STIPPLE       0x40\r
+#define SP_NEW_FRAMEBUFFER   0x80\r
+#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100\r
+#define SP_NEW_CONSTANTS     0x200\r
+#define SP_NEW_SAMPLER       0x400\r
+#define SP_NEW_TEXTURE       0x800\r
+#define SP_NEW_VERTEX        0x1000\r
+#define SP_NEW_VS            0x2000\r
+#define SP_NEW_QUERY         0x4000\r
+\r
+\r
+struct tgsi_sampler;\r
+struct tgsi_exec_machine;\r
+\r
+\r
+/** Subclass of pipe_shader_state (though it doesn't really need to be).\r
+ *\r
+ * This is starting to look an awful lot like a quad pipeline stage...\r
+ */\r
+struct sp_fragment_shader {\r
+   struct pipe_shader_state shader;\r
+\r
+   struct tgsi_shader_info info;\r
+\r
+   void (*prepare)( const struct sp_fragment_shader *shader,\r
+                   struct tgsi_exec_machine *machine,\r
+                   struct tgsi_sampler *samplers);\r
+\r
+   /* Run the shader - this interface will get cleaned up in the\r
+    * future:\r
+    */\r
+   unsigned (*run)( const struct sp_fragment_shader *shader,\r
+                   struct tgsi_exec_machine *machine,\r
+                   struct quad_header *quad );\r
+\r
+\r
+   void (*delete)( struct sp_fragment_shader * );\r
+};\r
+\r
+struct vertex_info;\r
+\r
+/** Subclass of pipe_shader_state */\r
+struct sp_vertex_shader {\r
+   struct pipe_shader_state shader;\r
+   struct draw_vertex_shader *draw_data;\r
+};\r
+\r
+\r
+\r
+void *\r
+softpipe_create_blend_state(struct pipe_context *,\r
+                            const struct pipe_blend_state *);\r
+void softpipe_bind_blend_state(struct pipe_context *,\r
+                               void *);\r
+void softpipe_delete_blend_state(struct pipe_context *,\r
+                                 void *);\r
+\r
+void *\r
+softpipe_create_sampler_state(struct pipe_context *,\r
+                              const struct pipe_sampler_state *);\r
+void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);\r
+void softpipe_delete_sampler_state(struct pipe_context *, void *);\r
+\r
+void *\r
+softpipe_create_depth_stencil_state(struct pipe_context *,\r
+                                    const struct pipe_depth_stencil_alpha_state *);\r
+void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);\r
+void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);\r
+\r
+void *\r
+softpipe_create_rasterizer_state(struct pipe_context *,\r
+                                 const struct pipe_rasterizer_state *);\r
+void softpipe_bind_rasterizer_state(struct pipe_context *, void *);\r
+void softpipe_delete_rasterizer_state(struct pipe_context *, void *);\r
+\r
+void softpipe_set_framebuffer_state( struct pipe_context *,\r
+                            const struct pipe_framebuffer_state * );\r
+\r
+void softpipe_set_blend_color( struct pipe_context *pipe,\r
+                               const struct pipe_blend_color *blend_color );\r
+\r
+void softpipe_set_clip_state( struct pipe_context *,\r
+                            const struct pipe_clip_state * );\r
+\r
+void softpipe_set_constant_buffer(struct pipe_context *,\r
+                                  uint shader, uint index,\r
+                                  const struct pipe_constant_buffer *buf);\r
+\r
+void *softpipe_create_fs_state(struct pipe_context *,\r
+                               const struct pipe_shader_state *);\r
+void softpipe_bind_fs_state(struct pipe_context *, void *);\r
+void softpipe_delete_fs_state(struct pipe_context *, void *);\r
+void *softpipe_create_vs_state(struct pipe_context *,\r
+                               const struct pipe_shader_state *);\r
+void softpipe_bind_vs_state(struct pipe_context *, void *);\r
+void softpipe_delete_vs_state(struct pipe_context *, void *);\r
+\r
+void softpipe_set_polygon_stipple( struct pipe_context *,\r
+                                 const struct pipe_poly_stipple * );\r
+\r
+void softpipe_set_scissor_state( struct pipe_context *,\r
+                                 const struct pipe_scissor_state * );\r
+\r
+void softpipe_set_sampler_textures( struct pipe_context *,\r
+                                    unsigned num,\r
+                                    struct pipe_texture ** );\r
+\r
+void softpipe_set_viewport_state( struct pipe_context *,\r
+                                  const struct pipe_viewport_state * );\r
+\r
+void softpipe_set_vertex_element(struct pipe_context *,\r
+                                 unsigned index,\r
+                                 const struct pipe_vertex_element *);\r
+\r
+void softpipe_set_vertex_buffer(struct pipe_context *,\r
+                                unsigned index,\r
+                                const struct pipe_vertex_buffer *);\r
+\r
+\r
+void softpipe_update_derived( struct softpipe_context *softpipe );\r
+\r
+\r
+boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,\r
+                            unsigned start, unsigned count);\r
+\r
+boolean softpipe_draw_elements(struct pipe_context *pipe,\r
+                              struct pipe_buffer *indexBuffer,\r
+                              unsigned indexSize,\r
+                              unsigned mode, unsigned start, unsigned count);\r
+\r
+\r
+void\r
+softpipe_map_surfaces(struct softpipe_context *sp);\r
+\r
+void\r
+softpipe_unmap_surfaces(struct softpipe_context *sp);\r
+\r
+void\r
+softpipe_map_texture_surfaces(struct softpipe_context *sp);\r
+\r
+void\r
+softpipe_unmap_texture_surfaces(struct softpipe_context *sp);\r
+\r
+\r
+struct vertex_info *\r
+softpipe_get_vertex_info(struct softpipe_context *softpipe);\r
+\r
+struct vertex_info *\r
+softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);\r
+\r
+\r
+#endif\r
index 1d6dd17..7cf85b9 100644 (file)
@@ -50,45 +50,67 @@ softpipe_create_sampler_state(struct pipe_context *pipe,
    return mem_dup(sampler, sizeof(*sampler));
 }
 
+
 void
-softpipe_bind_sampler_state(struct pipe_context *pipe,
-                            unsigned unit, void *sampler)
+softpipe_bind_sampler_states(struct pipe_context *pipe,
+                             unsigned num, void **sampler)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == softpipe->num_samplers &&
+       !memcmp(softpipe->sampler, sampler, num * sizeof(void *)))
+      return;
+
    draw_flush(softpipe->draw);
 
-   assert(unit < PIPE_MAX_SAMPLERS);
-   softpipe->sampler[unit] = (struct pipe_sampler_state *)sampler;
+   memcpy(softpipe->sampler, sampler, num * sizeof(void *));
+   memset(&softpipe->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) *
+          sizeof(void *));
+
+   softpipe->num_samplers = num;
 
    softpipe->dirty |= SP_NEW_SAMPLER;
 }
 
 
 void
-softpipe_delete_sampler_state(struct pipe_context *pipe,
-                              void *sampler)
+softpipe_set_sampler_textures(struct pipe_context *pipe,
+                              unsigned num, struct pipe_texture **texture)
 {
-   FREE( sampler );
-}
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+   uint i;
 
+   assert(num <= PIPE_MAX_SAMPLERS);
 
-void
-softpipe_set_sampler_texture(struct pipe_context *pipe,
-                            unsigned unit,
-                            struct pipe_texture *texture)
-{
-   struct softpipe_context *softpipe = softpipe_context(pipe);
+   /* Check for no-op */
+   if (num == softpipe->num_textures &&
+       !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *)))
+      return;
 
    draw_flush(softpipe->draw);
 
-   assert(unit < PIPE_MAX_SAMPLERS);
-   pipe_texture_reference(&softpipe->texture[unit], texture);
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      struct pipe_texture *tex = i < num ? texture[i] : NULL;
+
+      pipe_texture_reference(&softpipe->texture[i], tex);
+      sp_tile_cache_set_texture(pipe, softpipe->tex_cache[i], tex);
+   }
 
-   sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture);
+   softpipe->num_textures = num;
 
    softpipe->dirty |= SP_NEW_TEXTURE;
 }
 
 
+void
+softpipe_delete_sampler_state(struct pipe_context *pipe,
+                              void *sampler)
+{
+   FREE( sampler );
+}
+
+
 
index c605ed9..bbf2d80 100644 (file)
-/**************************************************************************
- * 
- * Copyright 2006 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.
- * 
- **************************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Michel Dänzer <michel@tungstengraphics.com>
-  */
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_util.h"
-#include "pipe/p_winsys.h"
-
-#include "sp_context.h"
-#include "sp_state.h"
-#include "sp_texture.h"
-#include "sp_tile_cache.h"
-
-
-/* Simple, maximally packed layout.
- */
-
-static unsigned minify( unsigned d )
-{
-   return MAX2(1, d>>1);
-}
-
-
-static void
-softpipe_texture_layout(struct softpipe_texture * spt)
-{
-   struct pipe_texture *pt = &spt->base;
-   unsigned level;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned depth = pt->depth[0];
-
-   spt->buffer_size = 0;
-
-   for (level = 0; level <= pt->last_level; level++) {
-      pt->width[level] = width;
-      pt->height[level] = height;
-      pt->depth[level] = depth;
-
-      spt->level_offset[level] = spt->buffer_size;
-
-      spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
-                         ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
-                         width * pt->cpp;
-
-      width  = minify(width);
-      height = minify(height);
-      depth = minify(depth);
-   }
-}
-
-
-static struct pipe_texture *
-softpipe_texture_create_screen(struct pipe_screen *screen,
-                               const struct pipe_texture *templat)
-{
-   struct pipe_winsys *ws = screen->winsys;
-   struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
-   if (!spt)
-      return NULL;
-
-   spt->base = *templat;
-   spt->base.refcount = 1;
-   spt->base.screen = screen;
-
-   softpipe_texture_layout(spt);
-
-   spt->buffer = ws->buffer_create(ws, 32,
-                                   PIPE_BUFFER_USAGE_PIXEL,
-                                   spt->buffer_size);
-   if (!spt->buffer) {
-      FREE(spt);
-      return NULL;
-   }
-
-   assert(spt->base.refcount == 1);
-
-   return &spt->base;
-}
-
-
-static void
-softpipe_texture_release_screen(struct pipe_screen *screen,
-                                struct pipe_texture **pt)
-{
-   if (!*pt)
-      return;
-
-   /*
-   DBG("%s %p refcount will be %d\n",
-       __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
-   */
-   if (--(*pt)->refcount <= 0) {
-      struct softpipe_texture *spt = softpipe_texture(*pt);
-
-      /*
-      DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
-      */
-
-      pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
-
-      FREE(spt);
-   }
-   *pt = NULL;
-}
-
-
-static struct pipe_surface *
-softpipe_get_tex_surface_screen(struct pipe_screen *screen,
-                                struct pipe_texture *pt,
-                                unsigned face, unsigned level, unsigned zslice)
-{
-   struct pipe_winsys *ws = screen->winsys;
-   struct softpipe_texture *spt = softpipe_texture(pt);
-   struct pipe_surface *ps;
-
-   assert(level <= pt->last_level);
-
-   ps = ws->surface_alloc(ws);
-   if (ps) {
-      assert(ps->refcount);
-      assert(ps->winsys);
-      pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
-      ps->format = pt->format;
-      ps->cpp = pt->cpp;
-      ps->width = pt->width[level];
-      ps->height = pt->height[level];
-      ps->pitch = ps->width;
-      ps->offset = spt->level_offset[level];
-
-      if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
-        ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
-                      (pt->compressed ? ps->height/4 : ps->height) *
-                      ps->width * ps->cpp;
-      }
-      else {
-        assert(face == 0);
-        assert(zslice == 0);
-      }
-   }
-   return ps;
-}
-
-
-static void
-softpipe_texture_update(struct pipe_context *pipe,
-                        struct pipe_texture *texture)
-{
-   struct softpipe_context *softpipe = softpipe_context(pipe);
-   uint unit;
-   for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) {
-      if (softpipe->texture[unit] == texture) {
-         sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
-      }
-   }
-}
-
-
-void
-softpipe_init_texture_funcs( struct softpipe_context *softpipe )
-{
-   softpipe->pipe.texture_update = softpipe_texture_update;
-}
-
-
-void
-softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
-{
-   screen->texture_create = softpipe_texture_create_screen;
-   screen->texture_release = softpipe_texture_release_screen;
-   screen->get_tex_surface = softpipe_get_tex_surface_screen;
-}
+/**************************************************************************\r
+ * \r
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.\r
+ * All Rights Reserved.\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the\r
+ * "Software"), to deal in the Software without restriction, including\r
+ * without limitation the rights to use, copy, modify, merge, publish,\r
+ * distribute, sub license, and/or sell copies of the Software, and to\r
+ * permit persons to whom the Software is furnished to do so, subject to\r
+ * the following conditions:\r
+ * \r
+ * The above copyright notice and this permission notice (including the\r
+ * next paragraph) shall be included in all copies or substantial portions\r
+ * of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ * \r
+ **************************************************************************/\r
+ /*\r
+  * Authors:\r
+  *   Keith Whitwell <keith@tungstengraphics.com>\r
+  *   Michel Dänzer <michel@tungstengraphics.com>\r
+  */\r
+\r
+#include "pipe/p_context.h"\r
+#include "pipe/p_defines.h"\r
+#include "pipe/p_inlines.h"\r
+#include "pipe/p_util.h"\r
+#include "pipe/p_winsys.h"\r
+\r
+#include "sp_context.h"\r
+#include "sp_state.h"\r
+#include "sp_texture.h"\r
+#include "sp_tile_cache.h"\r
+\r
+\r
+/* Simple, maximally packed layout.\r
+ */\r
+\r
+static unsigned minify( unsigned d )\r
+{\r
+   return MAX2(1, d>>1);\r
+}\r
+\r
+\r
+static void\r
+softpipe_texture_layout(struct softpipe_texture * spt)\r
+{\r
+   struct pipe_texture *pt = &spt->base;\r
+   unsigned level;\r
+   unsigned width = pt->width[0];\r
+   unsigned height = pt->height[0];\r
+   unsigned depth = pt->depth[0];\r
+\r
+   spt->buffer_size = 0;\r
+\r
+   for (level = 0; level <= pt->last_level; level++) {\r
+      pt->width[level] = width;\r
+      pt->height[level] = height;\r
+      pt->depth[level] = depth;\r
+\r
+      spt->level_offset[level] = spt->buffer_size;\r
+\r
+      spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *\r
+                         ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *\r
+                         width * pt->cpp;\r
+\r
+      width  = minify(width);\r
+      height = minify(height);\r
+      depth = minify(depth);\r
+   }\r
+}\r
+\r
+\r
+static struct pipe_texture *\r
+softpipe_texture_create_screen(struct pipe_screen *screen,\r
+                               const struct pipe_texture *templat)\r
+{\r
+   struct pipe_winsys *ws = screen->winsys;\r
+   struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);\r
+   if (!spt)\r
+      return NULL;\r
+\r
+   spt->base = *templat;\r
+   spt->base.refcount = 1;\r
+   spt->base.screen = screen;\r
+\r
+   softpipe_texture_layout(spt);\r
+\r
+   spt->buffer = ws->buffer_create(ws, 32,\r
+                                   PIPE_BUFFER_USAGE_PIXEL,\r
+                                   spt->buffer_size);\r
+   if (!spt->buffer) {\r
+      FREE(spt);\r
+      return NULL;\r
+   }\r
+\r
+   assert(spt->base.refcount == 1);\r
+\r
+   return &spt->base;\r
+}\r
+\r
+\r
+static void\r
+softpipe_texture_release_screen(struct pipe_screen *screen,\r
+                                struct pipe_texture **pt)\r
+{\r
+   if (!*pt)\r
+      return;\r
+\r
+   /*\r
+   DBG("%s %p refcount will be %d\n",\r
+       __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);\r
+   */\r
+   if (--(*pt)->refcount <= 0) {\r
+      struct softpipe_texture *spt = softpipe_texture(*pt);\r
+\r
+      /*\r
+      DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);\r
+      */\r
+\r
+      pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);\r
+\r
+      FREE(spt);\r
+   }\r
+   *pt = NULL;\r
+}\r
+\r
+\r
+static struct pipe_surface *\r
+softpipe_get_tex_surface_screen(struct pipe_screen *screen,\r
+                                struct pipe_texture *pt,\r
+                                unsigned face, unsigned level, unsigned zslice)\r
+{\r
+   struct pipe_winsys *ws = screen->winsys;\r
+   struct softpipe_texture *spt = softpipe_texture(pt);\r
+   struct pipe_surface *ps;\r
+\r
+   assert(level <= pt->last_level);\r
+\r
+   ps = ws->surface_alloc(ws);\r
+   if (ps) {\r
+      assert(ps->refcount);\r
+      assert(ps->winsys);\r
+      pipe_buffer_reference(ws, &ps->buffer, spt->buffer);\r
+      ps->format = pt->format;\r
+      ps->cpp = pt->cpp;\r
+      ps->width = pt->width[level];\r
+      ps->height = pt->height[level];\r
+      ps->pitch = ps->width;\r
+      ps->offset = spt->level_offset[level];\r
+\r
+      if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {\r
+        ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *\r
+                      (pt->compressed ? ps->height/4 : ps->height) *\r
+                      ps->width * ps->cpp;\r
+      }\r
+      else {\r
+        assert(face == 0);\r
+        assert(zslice == 0);\r
+      }\r
+   }\r
+   return ps;\r
+}\r
+\r
+\r
+static void\r
+softpipe_texture_update(struct pipe_context *pipe,\r
+                        struct pipe_texture *texture)\r
+{\r
+   struct softpipe_context *softpipe = softpipe_context(pipe);\r
+   uint unit;\r
+   for (unit = 0; unit < softpipe->num_textures; unit++) {\r
+      if (softpipe->texture[unit] == texture) {\r
+         sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);\r
+      }\r
+   }\r
+}\r
+\r
+\r
+void\r
+softpipe_init_texture_funcs( struct softpipe_context *softpipe )\r
+{\r
+   softpipe->pipe.texture_update = softpipe_texture_update;\r
+}\r
+\r
+\r
+void\r
+softpipe_init_screen_texture_funcs(struct pipe_screen *screen)\r
+{\r
+   screen->texture_create = softpipe_texture_create_screen;\r
+   screen->texture_release = softpipe_texture_release_screen;\r
+   screen->get_tex_surface = softpipe_get_tex_surface_screen;\r
+}\r
index 1501b52..b64948f 100644 (file)
@@ -100,7 +100,7 @@ struct pipe_context {
 
    void * (*create_sampler_state)(struct pipe_context *,
                                   const struct pipe_sampler_state *);
-   void   (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *);
+   void   (*bind_sampler_states)(struct pipe_context *, unsigned num, void **);
    void   (*delete_sampler_state)(struct pipe_context *, void *);
 
    void * (*create_rasterizer_state)(struct pipe_context *,
@@ -148,9 +148,9 @@ struct pipe_context {
 
    /* Currently a sampler is constrained to sample from a single texture:
     */
-   void (*set_sampler_texture)( struct pipe_context *,
-                               unsigned sampler,
-                               struct pipe_texture * );
+   void (*set_sampler_textures)( struct pipe_context *,
+                                 unsigned num,
+                                 struct pipe_texture ** );
 
    void (*set_viewport_state)( struct pipe_context *,
                                const struct pipe_viewport_state * );
index 92263cb..1000f98 100644 (file)
@@ -120,10 +120,11 @@ update_samplers(struct st_context *st)
    const struct st_fragment_program *fs = st->fp;
    GLuint su;
 
+   st->state.num_samplers = 0;
+
    /* loop over sampler units (aka tex image units) */
    for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
       struct pipe_sampler_state sampler;
-      const struct cso_sampler *cso;
 
       memset(&sampler, 0, sizeof(sampler));
 
@@ -168,17 +169,16 @@ update_samplers(struct st_context *st)
                = st_compare_func_to_pipe(texobj->CompareFunc);
          }
 
+         st->state.num_samplers = su + 1;
+
          /* XXX more sampler state here */
       }
 
-      cso = st_cached_sampler_state(st, &sampler);
-
-      if (cso != st->state.sampler[su]) {
-         /* state has changed */
-         st->state.sampler[su] = cso;
-         st->pipe->bind_sampler_state(st->pipe, su, cso->data);
-      }
+      st->state.sampler[su] = st_cached_sampler_state(st, &sampler)->data;
    }
+
+   st->pipe->bind_sampler_states(st->pipe, st->state.num_samplers,
+                                 st->state.sampler);
 }
 
 
index 697d2cd..e53a897 100644 (file)
@@ -37,6 +37,7 @@
 #include "st_texture.h"
 #include "st_cb_texture.h"
 #include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
 
 
 /**
@@ -51,6 +52,8 @@ update_textures(struct st_context *st)
    struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
    GLuint unit;
 
+   st->state.num_textures = 0;
+
    for (unit = 0; unit < st->ctx->Const.MaxTextureCoordUnits; unit++) {
       const GLuint su = fprog->Base.SamplerUnits[unit];
       struct gl_texture_object *texObj = st->ctx->Texture.Unit[su]._Current;
@@ -62,6 +65,8 @@ update_textures(struct st_context *st)
 
          retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
          /* XXX retval indicates whether there's a texture border */
+
+         st->state.num_textures = unit + 1;
       }
 
       /* XXX: need to ensure that textures are unbound/removed from
@@ -70,18 +75,16 @@ update_textures(struct st_context *st)
        */
 
       pt = st_get_stobj_texture(stObj);
-
-      if (st->state.sampler_texture[unit] != pt) {
-         st->state.sampler_texture[unit] = pt;
-         st->pipe->set_sampler_texture(st->pipe, unit, pt);
-      }
+      pipe_texture_reference(&st->state.sampler_texture[unit], pt);
 
       if (stObj && stObj->dirtyData) {
          st->pipe->texture_update(st->pipe, pt);
          stObj->dirtyData = GL_FALSE;
       }
-
    }
+
+   st->pipe->set_sampler_textures(st->pipe, st->state.num_textures,
+                                  st->state.sampler_texture);
 }
 
 
index 65c9fda..dee4c41 100644 (file)
@@ -641,7 +641,6 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
                    const GLfloat *color,
                    GLboolean invertTex)
 {
-   const GLuint unit = 0;
    struct pipe_context *pipe = ctx->st->pipe;
    GLfloat x0, y0, x1, y1;
    GLuint maxSize;
@@ -684,7 +683,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
       sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
       sampler.normalized_coords = 1;
       cso = st_cached_sampler_state(ctx->st, &sampler);
-      pipe->bind_sampler_state(pipe, unit, cso->data);
+      pipe->bind_sampler_states(pipe, 1, (void**)&cso->data);
    }
 
    /* viewport state: viewport matching window dims */
@@ -705,7 +704,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
 
    /* texture state: */
    {
-      pipe->set_sampler_texture(pipe, unit, pt);
+      pipe->set_sampler_textures(pipe, 1, &pt);
    }
 
    /* Compute window coords (y=0=bottom) with pixel zoom.
@@ -727,8 +726,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    pipe->bind_rasterizer_state(pipe, ctx->st->state.rasterizer->data);
    pipe->bind_fs_state(pipe, ctx->st->state.fs->data);
    pipe->bind_vs_state(pipe, ctx->st->state.vs->cso->data);
-   pipe->set_sampler_texture(pipe, unit, ctx->st->state.sampler_texture[unit]);
-   pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]->data);
+   pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
+                              ctx->st->state.sampler_texture);
+   pipe->bind_sampler_states(pipe, ctx->st->state.num_samplers,
+                             ctx->st->state.sampler);
    pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
 }
 
index 1fbf972..897a510 100644 (file)
@@ -76,7 +76,7 @@ struct st_context
    struct {
       const struct cso_alpha_test      *alpha_test;
       const struct cso_blend           *blend;
-      const struct cso_sampler         *sampler[PIPE_MAX_SAMPLERS];
+      void                             *sampler[PIPE_MAX_SAMPLERS];
       const struct cso_depth_stencil_alpha   *depth_stencil;
       const struct cso_rasterizer      *rasterizer;
       const struct cso_fragment_shader *fs;
@@ -90,6 +90,9 @@ struct st_context
       struct pipe_poly_stipple poly_stipple;
       struct pipe_scissor_state scissor;
       struct pipe_viewport_state viewport;
+
+      GLuint num_samplers;
+      GLuint num_textures;
    } state;
 
    struct {
index 841d77a..3723e26 100644 (file)
@@ -284,7 +284,7 @@ st_render_mipmap(struct st_context *st,
        */
       sampler.min_lod = sampler.max_lod = srcLevel;
       sampler_cso = pipe->create_sampler_state(pipe, &sampler);
-      pipe->bind_sampler_state(pipe, 0, sampler_cso);
+      pipe->bind_sampler_states(pipe, 1, &sampler_cso);
 
       simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
 
@@ -293,7 +293,7 @@ st_render_mipmap(struct st_context *st,
        * the right mipmap level.
        */
       /*pt->first_level = srcLevel;*/
-      pipe->set_sampler_texture(pipe, 0, pt);
+      pipe->set_sampler_textures(pipe, 1, &pt);
 
       draw_quad(st->ctx);
 
@@ -310,9 +310,10 @@ st_render_mipmap(struct st_context *st,
       pipe->bind_fs_state(pipe, st->state.fs->data);
    if (st->state.vs)
       pipe->bind_vs_state(pipe, st->state.vs->cso->data);
-   if (st->state.sampler[0])
-      pipe->bind_sampler_state(pipe, 0, st->state.sampler[0]->data);
-   pipe->set_sampler_texture(pipe, 0, st->state.sampler_texture[0]);
+   pipe->bind_sampler_states(pipe, st->state.num_samplers,
+                             st->state.sampler);
+   pipe->set_sampler_textures(pipe, st->state.num_textures,
+                              st->state.sampler_texture);
    pipe->set_viewport_state(pipe, &st->state.viewport);
 
    return TRUE;