Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / drivers / i965simple / brw_state.c
index 6744a8aa4f7620962e338c20ecba4c61ea5d1c41..af46cb546fac689ff4842a9a36d42239fac336ca 100644 (file)
 
 
 #include "pipe/p_winsys.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
 #include "pipe/p_inlines.h"
 #include "pipe/p_shader_tokens.h"
-#include "tgsi/util/tgsi_dump.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_parse.h"
 
 #include "brw_context.h"
 #include "brw_defines.h"
@@ -95,12 +96,24 @@ brw_create_sampler_state(struct pipe_context *pipe,
    DUP( pipe_sampler_state, sampler );
 }
 
-static void brw_bind_sampler_state(struct pipe_context *pipe,
-                                    unsigned unit, void *sampler)
+static void brw_bind_sampler_states(struct pipe_context *pipe,
+                                    unsigned num, void **sampler)
 {
    struct brw_context *brw = brw_context(pipe);
 
-   brw->attribs.Samplers[unit] = sampler;
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == brw->num_samplers &&
+       !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *)))
+      return;
+
+   memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *));
+   memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) *
+          sizeof(void *));
+
+   brw->num_samplers = num;
+
    brw->state.dirty.brw |= BRW_NEW_SAMPLER;
 }
 
@@ -170,9 +183,7 @@ static void * brw_create_fs_state(struct pipe_context *pipe,
 {
    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->program.tokens = tgsi_dup_tokens(shader->tokens);
    brw_fp->id = brw_context(pipe)->program_id++;
 
    tgsi_scan_shader(shader->tokens, &brw_fp->info);
@@ -198,7 +209,10 @@ static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
 
 static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
 {
-   FREE(shader);
+   struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader;
+
+   FREE((void *) brw_fp->program.tokens);
+   FREE(brw_fp);
 }
 
 
@@ -211,9 +225,7 @@ static void *brw_create_vs_state(struct pipe_context *pipe,
 {
    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->program.tokens = tgsi_dup_tokens(shader->tokens);
    brw_vp->id = brw_context(pipe)->program_id++;
 
    tgsi_scan_shader(shader->tokens, &brw_vp->info);
@@ -239,7 +251,10 @@ static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
 
 static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
 {
-   FREE(shader);
+   struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader;
+
+   FREE((void *) brw_vp->program.tokens);
+   FREE(brw_vp);
 }
 
 
@@ -265,45 +280,49 @@ static void brw_set_viewport_state( struct pipe_context *pipe,
 }
 
 
-static void brw_set_vertex_bufferstruct pipe_context *pipe,
-                                  unsigned index,
-                                  const struct pipe_vertex_buffer *buffer )
+static void brw_set_vertex_buffers(struct pipe_context *pipe,
+                                  unsigned count,
+                                  const struct pipe_vertex_buffer *buffers)
 {
    struct brw_context *brw = brw_context(pipe);
-   brw->vb.vbo_array[index] = buffer;
+   memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0]));
 }
 
-static void brw_set_vertex_element(struct pipe_context *pipe,
-                                   unsigned index,
-                                   const struct pipe_vertex_element *element)
+static void brw_set_vertex_elements(struct pipe_context *pipe,
+                                    unsigned count,
+                                    const struct pipe_vertex_element *elements)
 {
    /* flush ? */
    struct brw_context *brw = brw_context(pipe);
+   uint i;
 
-   assert(index < PIPE_ATTRIB_MAX);
-   struct brw_vertex_element_state el;
-   memset(&el, 0, sizeof(el));
+   assert(count <= PIPE_MAX_ATTRIBS);
 
-   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;
+   for (i = 0; i < count; i++) {
+      struct brw_vertex_element_state el;
+      memset(&el, 0, sizeof(el));
 
-   el.ve1.dst_offset   = index * 4;
+      el.ve0.src_offset = elements[i].src_offset;
+      el.ve0.src_format = brw_translate_surface_format(elements[i].src_format);
+      el.ve0.valid = 1;
+      el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index;
 
-   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;
+      el.ve1.dst_offset   = i * 4;
 
-   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;
-   }
+      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 (elements[i].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;
+      brw->vb.inputs[i] = el;
+   }
 }
 
 
@@ -330,14 +349,30 @@ static void brw_set_constant_buffer(struct pipe_context *pipe,
  */
 
 
-static void brw_set_sampler_texture(struct pipe_context *pipe,
-                                  unsigned unit,
-                                  struct pipe_texture *texture)
+static void brw_set_sampler_textures(struct pipe_context *pipe,
+                                     unsigned num,
+                                     struct pipe_texture **texture)
 {
    struct brw_context *brw = brw_context(pipe);
+   uint i;
+
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == brw->num_textures &&
+       !memcmp(brw->attribs.Texture, texture, num *
+               sizeof(struct pipe_texture *)))
+      return;
+
+   for (i = 0; i < num; i++)
+      pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
+                             texture[i]);
+
+   for (i = num; i < brw->num_textures; i++)
+      pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
+                             NULL);
 
-   pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit],
-                          texture);
+   brw->num_textures = num;
 
    brw->state.dirty.brw |= BRW_NEW_TEXTURE;
 }
@@ -400,7 +435,7 @@ brw_init_state_functions( struct brw_context *brw )
    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.bind_sampler_states = brw_bind_sampler_states;
    brw->pipe.delete_sampler_state = brw_delete_sampler_state;
 
    brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
@@ -427,8 +462,8 @@ brw_init_state_functions( struct brw_context *brw )
 
    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_sampler_textures = brw_set_sampler_textures;
    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;
+   brw->pipe.set_vertex_buffers = brw_set_vertex_buffers;
+   brw->pipe.set_vertex_elements = brw_set_vertex_elements;
 }