draw_gs.c revision d4ef0f6c67aefe06d8dd647acf8d9005df39a709
189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin/**************************************************************************
289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin *
389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * Copyright 2009 VMWare Inc.
489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * All Rights Reserved.
589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin *
689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * Permission is hereby granted, free of charge, to any person obtaining a
789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * copy of this software and associated documentation files (the
889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * "Software"), to deal in the Software without restriction, including
989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * without limitation the rights to use, copy, modify, merge, publish,
1089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * distribute, sub license, and/or sell copies of the Software, and to
1189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * permit persons to whom the Software is furnished to do so, subject to
1289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * the following conditions:
1389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin *
1489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * The above copyright notice and this permission notice (including the
1589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * next paragraph) shall be included in all copies or substantial portions
1689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * of the Software.
1789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin *
1889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin *
2689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin **************************************************************************/
2789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
2889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "draw_gs.h"
2989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
3089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "draw_private.h"
3189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "draw_context.h"
3289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
3389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "tgsi/tgsi_parse.h"
3489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "tgsi/tgsi_exec.h"
3589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
3689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "pipe/p_shader_tokens.h"
3789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
3889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "util/u_math.h"
3989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#include "util/u_memory.h"
4089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
4189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#define MAX_PRIM_VERTICES 6
4289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin/* fixme: move it from here */
4389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#define MAX_PRIMITIVES 64
4489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
4589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinboolean
4689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusindraw_gs_init( struct draw_context *draw )
4789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
4889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   draw->gs.machine = tgsi_exec_machine_create();
4989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (!draw->gs.machine)
5089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return FALSE;
5189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
5289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   draw->gs.machine->Primitives = align_malloc(
5389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
5489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (!draw->gs.machine->Primitives)
5589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return FALSE;
5689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   memset(draw->gs.machine->Primitives, 0,
5789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin          MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
5889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
5989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   return TRUE;
6089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
6189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
62a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantzvoid draw_gs_destroy( struct draw_context *draw )
63a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz{
64a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz   if (!draw->gs.machine)
65a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz      return;
66a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz
67a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz   align_free(draw->gs.machine->Primitives);
68a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz
69a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz   tgsi_exec_machine_destroy(draw->gs.machine);
70a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz}
7189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
729851644435f991a1a1bbb145333a97601627b37dMichal Krolvoid
739851644435f991a1a1bbb145333a97601627b37dMichal Kroldraw_gs_set_constants(struct draw_context *draw,
749851644435f991a1a1bbb145333a97601627b37dMichal Krol                      unsigned slot,
759851644435f991a1a1bbb145333a97601627b37dMichal Krol                      const void *constants,
769851644435f991a1a1bbb145333a97601627b37dMichal Krol                      unsigned size)
7789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
7889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
7989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
8089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
8189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinstruct draw_geometry_shader *
8289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusindraw_create_geometry_shader(struct draw_context *draw,
8389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            const struct pipe_shader_state *state)
8489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
8589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct draw_geometry_shader *gs;
8689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   int i;
8789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
8889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs = CALLOC_STRUCT(draw_geometry_shader);
8989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
9089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (!gs)
9189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return NULL;
9289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
9389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs->state = *state;
9489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs->state.tokens = tgsi_dup_tokens(state->tokens);
9589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (!gs->state.tokens) {
9689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      FREE(gs);
9789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return NULL;
9889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
9989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
10089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   tgsi_scan_shader(state->tokens, &gs->info);
10189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
10289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   /* setup the defaults */
10389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs->input_primitive = PIPE_PRIM_TRIANGLES;
10489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
10589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs->max_output_vertices = 32;
10689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
10789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   for (i = 0; i < gs->info.num_properties; ++i) {
10889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      if (gs->info.properties[i].name ==
10989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin          TGSI_PROPERTY_GS_INPUT_PRIM)
11089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         gs->input_primitive = gs->info.properties[i].data[0];
11189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      else if (gs->info.properties[i].name ==
11289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               TGSI_PROPERTY_GS_OUTPUT_PRIM)
11389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         gs->output_primitive = gs->info.properties[i].data[0];
11489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      else if (gs->info.properties[i].name ==
115d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin               TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES)
11689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         gs->max_output_vertices = gs->info.properties[i].data[0];
11789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
11889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
11989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   gs->machine = draw->gs.machine;
12089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
12189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (gs)
12289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   {
12389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      uint i;
12489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      for (i = 0; i < gs->info.num_outputs; i++) {
12589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
12689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin             gs->info.output_semantic_index[i] == 0)
12789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            gs->position_output = i;
12889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      }
12989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
13089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
13189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   return gs;
13289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
13389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
13489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_bind_geometry_shader(struct draw_context *draw,
13589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                               struct draw_geometry_shader *dgs)
13689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
13789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
13889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
13989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   if (dgs) {
14089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw->gs.geometry_shader = dgs;
14189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw->gs.num_gs_outputs = dgs->info.num_outputs;
14289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw->gs.position_output = dgs->position_output;
14389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw_geometry_shader_prepare(dgs, draw);
14489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
14589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   else {
14689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw->gs.geometry_shader = NULL;
14789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw->gs.num_gs_outputs = 0;
14889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
14989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
15089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
15189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_delete_geometry_shader(struct draw_context *draw,
15289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                 struct draw_geometry_shader *dgs)
15389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
15489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   FREE(dgs);
15589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
15689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
15789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinstatic INLINE int num_vertices_for_prim(int prim)
15889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
15989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   switch(prim) {
16089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_POINTS:
16189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 1;
16289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_LINES:
16389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 2;
16489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_LINE_LOOP:
16589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 2;
16689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_LINE_STRIP:
16789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 2;
16889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_TRIANGLES:
16989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 3;
17089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_TRIANGLE_STRIP:
17189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 3;
17289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_TRIANGLE_FAN:
17389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 3;
17489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_LINES_ADJACENCY:
17589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
17689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 4;
17789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_TRIANGLES_ADJACENCY:
17889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
17989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 6;
18089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   default:
18189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      assert(!"Bad geometry shader input");
18289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      return 0;
18389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
18489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
18589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
18689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinstatic void draw_fetch_geometry_input(struct draw_geometry_shader *shader,
18789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                      int start_primitive,
18889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                      int num_primitives,
18989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                      const float (*input_ptr)[4],
19089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                      unsigned input_vertex_stride,
19189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                      unsigned inputs_from_vs)
19289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
19389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct tgsi_exec_machine *machine = shader->machine;
19489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned slot, vs_slot, k, j;
19589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
19689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   int idx = 0;
19789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
19889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; slot++) {
199b0bc582db761ea3f47580dd2908a227987177dc2Zack Rusin      /*debug_printf("Slot = %d (semantic = %d)\n", slot,
200b0bc582db761ea3f47580dd2908a227987177dc2Zack Rusin        shader->info.input_semantic_name[slot]);*/
20189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      if (shader->info.input_semantic_name[slot] ==
202fb0a9aa5e0476d8ca332753f52a9e56f9cfa8dfaZack Rusin          TGSI_SEMANTIC_PRIMID) {
20389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         for (j = 0; j < num_primitives; ++j) {
204fb0a9aa5e0476d8ca332753f52a9e56f9cfa8dfaZack Rusin            machine->Inputs[idx].xyzw[0].f[j] = (float)start_primitive + j;
205fb0a9aa5e0476d8ca332753f52a9e56f9cfa8dfaZack Rusin            machine->Inputs[idx].xyzw[1].f[j] = (float)start_primitive + j;
206fb0a9aa5e0476d8ca332753f52a9e56f9cfa8dfaZack Rusin            machine->Inputs[idx].xyzw[2].f[j] = (float)start_primitive + j;
207fb0a9aa5e0476d8ca332753f52a9e56f9cfa8dfaZack Rusin            machine->Inputs[idx].xyzw[3].f[j] = (float)start_primitive + j;
20889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         }
20989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         ++idx;
21089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      } else {
21189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         for (j = 0; j < num_primitives; ++j) {
21289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            int vidx = idx;
21389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            const float (*prim_ptr)[4];
214b0bc582db761ea3f47580dd2908a227987177dc2Zack Rusin            /*debug_printf("    %d) Prim (num_verts = %d)\n", start_primitive + j,
215b0bc582db761ea3f47580dd2908a227987177dc2Zack Rusin              num_vertices);*/
21689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            prim_ptr = (const float (*)[4])(
21789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               (const char *)input_ptr +
21889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               (j * num_vertices * input_vertex_stride));
21989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
22089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            for (k = 0; k < num_vertices; ++k, ++vidx) {
22189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               const float (*input)[4];
22289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               input = (const float (*)[4])(
22389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                  (const char *)prim_ptr + (k * input_vertex_stride));
22449155c3264d019869fadde50ff6167a369e966b6Zack Rusin               vidx = k * TGSI_EXEC_MAX_INPUT_ATTRIBS + slot;
225b0bc582db761ea3f47580dd2908a227987177dc2Zack Rusin               /*debug_printf("\t%d)(%d) Input vert:\n", vidx, k);*/
22689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#if 1
22789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               assert(!util_is_inf_or_nan(input[vs_slot][0]));
22889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               assert(!util_is_inf_or_nan(input[vs_slot][1]));
22989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               assert(!util_is_inf_or_nan(input[vs_slot][2]));
23089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               assert(!util_is_inf_or_nan(input[vs_slot][3]));
23189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#endif
23289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               machine->Inputs[vidx].xyzw[0].f[j] = input[vs_slot][0];
23389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               machine->Inputs[vidx].xyzw[1].f[j] = input[vs_slot][1];
23489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               machine->Inputs[vidx].xyzw[2].f[j] = input[vs_slot][2];
23589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               machine->Inputs[vidx].xyzw[3].f[j] = input[vs_slot][3];
23689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#if 0
23789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin               debug_printf("\t\t%d %f %f %f %f\n", slot,
23889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            machine->Inputs[vidx].xyzw[0].f[j],
23989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            machine->Inputs[vidx].xyzw[1].f[j],
24089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            machine->Inputs[vidx].xyzw[2].f[j],
24189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            machine->Inputs[vidx].xyzw[3].f[j]);
24289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#endif
24389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            }
24489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         }
24589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         ++vs_slot;
24689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         idx += num_vertices;
24789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      }
24889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
24989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
250d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin/*#define DEBUG_OUTPUTS 1*/
25189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinstatic INLINE void
25289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusindraw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
25389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            int num_primitives,
25489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            float (*output)[4],
25589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                            unsigned vertex_size)
25689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
25789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct tgsi_exec_machine *machine = shader->machine;
25889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned prim_idx, j, slot;
25989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
26089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   /* Unswizzle all output results.
26189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin    */
26289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   /* FIXME: handle all the primitives produced by the gs, not just
26389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin    * the first one
26489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin    unsigned prim_count =
26589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin    mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];*/
266d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin
267d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin   shader->emitted_primitives += num_primitives;
26889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) {
26989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      unsigned num_verts_per_prim = machine->Primitives[0];
270d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin      shader->emitted_vertices += num_verts_per_prim;
27189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      for (j = 0; j < num_verts_per_prim; j++) {
27289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         int idx = (prim_idx * num_verts_per_prim + j) *
27389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                   shader->info.num_outputs;
27489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#ifdef DEBUG_OUTPUTS
27589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         debug_printf("%d) Output vert:\n", idx);
27689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#endif
27789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         for (slot = 0; slot < shader->info.num_outputs; slot++) {
27889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            output[slot][0] = machine->Outputs[idx + slot].xyzw[0].f[prim_idx];
27989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            output[slot][1] = machine->Outputs[idx + slot].xyzw[1].f[prim_idx];
28089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            output[slot][2] = machine->Outputs[idx + slot].xyzw[2].f[prim_idx];
28189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            output[slot][3] = machine->Outputs[idx + slot].xyzw[3].f[prim_idx];
28289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#ifdef DEBUG_OUTPUTS
28389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            debug_printf("\t%d: %f %f %f %f\n", slot,
28489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         output[slot][0],
28589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         output[slot][1],
28689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         output[slot][2],
28789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         output[slot][3]);
28889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#endif
28989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin            debug_assert(!util_is_inf_or_nan(output[slot][0]));
29089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         }
29189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         output = (float (*)[4])((char *)output + vertex_size);
29289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      }
29389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
29489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
29589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
296d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusinint draw_geometry_shader_run(struct draw_geometry_shader *shader,
297d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin                             const float (*input)[4],
298d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin                             float (*output)[4],
299d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin                             const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
300d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin                             unsigned count,
301d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin                             unsigned input_stride,
302d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin                             unsigned vertex_size)
30389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
30489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   struct tgsi_exec_machine *machine = shader->machine;
30589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned int i;
30689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
30789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned num_primitives = count/num_vertices;
30889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   unsigned inputs_from_vs = 0;
30989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
310d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin   shader->emitted_vertices = 0;
311d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin   shader->emitted_primitives = 0;
312d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin
3137c5f255201f42303188137f56ea8acc030444f0eMichal Krol   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
3149851644435f991a1a1bbb145333a97601627b37dMichal Krol      machine->Consts[i] = constants[i];
3159851644435f991a1a1bbb145333a97601627b37dMichal Krol   }
31689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
31789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   for (i = 0; i < shader->info.num_inputs; ++i) {
318fb0a9aa5e0476d8ca332753f52a9e56f9cfa8dfaZack Rusin      if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID)
31989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin         ++inputs_from_vs;
32089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
32189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
32289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   for (i = 0; i < num_primitives; ++i) {
32389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      unsigned int max_primitives = 1;
32489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
32589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw_fetch_geometry_input(shader, i, max_primitives, input,
32689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                input_stride, inputs_from_vs);
32789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
32889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      tgsi_set_exec_mask(machine,
32989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         1,
33089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         max_primitives > 1,
33189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         max_primitives > 2,
33289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                         max_primitives > 3);
33389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
33489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      /* run interpreter */
33589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      tgsi_exec_machine_run(machine);
33689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
33789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin      draw_geometry_fetch_outputs(shader, max_primitives,
33889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                  output, vertex_size);
33989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   }
340d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin   return shader->emitted_vertices;
34189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
34289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
34389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_geometry_shader_delete(struct draw_geometry_shader *shader)
34489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
34589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   FREE((void*) shader->state.tokens);
34689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   FREE(shader);
34789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
34889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin
34989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
35089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin                                  struct draw_context *draw)
35189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{
3521963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin   if (shader && shader->machine->Tokens != shader->state.tokens) {
3531963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin      tgsi_exec_machine_bind_shader(shader->machine,
3541963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin                                    shader->state.tokens,
3551963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin                                    draw->gs.num_samplers,
3561963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin                                    draw->gs.samplers);
3571963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin   }
35889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin}
359