draw_gs.c revision 29639932f7d42ce3eb2f4b487366c67bb0bc910b
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" 40da4185ca77395b9dddc362891d8f7bbc2fa924cdZack Rusin#include "util/u_prim.h" 4189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 4289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#define MAX_PRIM_VERTICES 6 4389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin/* fixme: move it from here */ 4489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#define MAX_PRIMITIVES 64 4589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 4689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinboolean 4789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusindraw_gs_init( struct draw_context *draw ) 4889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 4989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.machine = tgsi_exec_machine_create(); 5089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (!draw->gs.machine) 5189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return FALSE; 5289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 5389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.machine->Primitives = align_malloc( 5489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16); 5589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (!draw->gs.machine->Primitives) 5689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return FALSE; 5789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin memset(draw->gs.machine->Primitives, 0, 5889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector)); 5989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 6089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return TRUE; 6189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 6289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 63a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantzvoid draw_gs_destroy( struct draw_context *draw ) 64a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz{ 65a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz if (!draw->gs.machine) 66a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz return; 67a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz 68a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz align_free(draw->gs.machine->Primitives); 69a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz 70a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz tgsi_exec_machine_destroy(draw->gs.machine); 71a5c03bd6f16517bf35c273741080492d70d64c29Jakob Bornecrantz} 7289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 739851644435f991a1a1bbb145333a97601627b37dMichal Krolvoid 749851644435f991a1a1bbb145333a97601627b37dMichal Kroldraw_gs_set_constants(struct draw_context *draw, 759851644435f991a1a1bbb145333a97601627b37dMichal Krol unsigned slot, 769851644435f991a1a1bbb145333a97601627b37dMichal Krol const void *constants, 779851644435f991a1a1bbb145333a97601627b37dMichal Krol unsigned size) 7889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 7989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 8089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 8189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 8289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinstruct draw_geometry_shader * 8389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusindraw_create_geometry_shader(struct draw_context *draw, 8489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin const struct pipe_shader_state *state) 8589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 8689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct draw_geometry_shader *gs; 8789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin int i; 8889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 8989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs = CALLOC_STRUCT(draw_geometry_shader); 9089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 9189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (!gs) 9289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return NULL; 9389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 944d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin gs->draw = draw; 9589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->state = *state; 9689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->state.tokens = tgsi_dup_tokens(state->tokens); 9789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (!gs->state.tokens) { 9889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE(gs); 9989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return NULL; 10089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 10189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 10289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin tgsi_scan_shader(state->tokens, &gs->info); 10389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 10489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin /* setup the defaults */ 10589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->input_primitive = PIPE_PRIM_TRIANGLES; 10689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP; 10789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->max_output_vertices = 32; 10889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 10989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin for (i = 0; i < gs->info.num_properties; ++i) { 11089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (gs->info.properties[i].name == 11189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin TGSI_PROPERTY_GS_INPUT_PRIM) 11289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->input_primitive = gs->info.properties[i].data[0]; 11389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin else if (gs->info.properties[i].name == 11489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin TGSI_PROPERTY_GS_OUTPUT_PRIM) 11589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->output_primitive = gs->info.properties[i].data[0]; 11689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin else if (gs->info.properties[i].name == 117d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES) 11889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->max_output_vertices = gs->info.properties[i].data[0]; 11989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 12089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 12189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->machine = draw->gs.machine; 12289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 12389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (gs) 12489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin { 12589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin uint i; 12689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin for (i = 0; i < gs->info.num_outputs; i++) { 12789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION && 12889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->info.output_semantic_index[i] == 0) 12989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin gs->position_output = i; 13089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 13189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 13289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 13389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin return gs; 13489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 13589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 13689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_bind_geometry_shader(struct draw_context *draw, 13789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct draw_geometry_shader *dgs) 13889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 13989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE); 14089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 14189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin if (dgs) { 14289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.geometry_shader = dgs; 14389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.num_gs_outputs = dgs->info.num_outputs; 14489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.position_output = dgs->position_output; 14589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw_geometry_shader_prepare(dgs, draw); 14689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 14789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin else { 14889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.geometry_shader = NULL; 14989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin draw->gs.num_gs_outputs = 0; 15089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 15189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 15289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 15389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_delete_geometry_shader(struct draw_context *draw, 15489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct draw_geometry_shader *dgs) 15589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 15689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE(dgs); 15789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 15889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 159d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin/*#define DEBUG_OUTPUTS 1*/ 16089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinstatic INLINE void 16189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusindraw_geometry_fetch_outputs(struct draw_geometry_shader *shader, 16289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin int num_primitives, 16329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin float (**p_output)[4]) 16489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 16589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct tgsi_exec_machine *machine = shader->machine; 16689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin unsigned prim_idx, j, slot; 1671d11eac93f408053a0807783b434624a6dfcb3fbZack Rusin float (*output)[4]; 1681d11eac93f408053a0807783b434624a6dfcb3fbZack Rusin 1691d11eac93f408053a0807783b434624a6dfcb3fbZack Rusin output = *p_output; 17089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 17189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin /* Unswizzle all output results. 17289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin */ 173d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin 174d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin shader->emitted_primitives += num_primitives; 17589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) { 17604490ad31d0d763a0a1da7b521da55f5ea14e1cdZack Rusin unsigned num_verts_per_prim = machine->Primitives[prim_idx]; 177d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin shader->emitted_vertices += num_verts_per_prim; 17889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin for (j = 0; j < num_verts_per_prim; j++) { 17989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin int idx = (prim_idx * num_verts_per_prim + j) * 18089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin shader->info.num_outputs; 18189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#ifdef DEBUG_OUTPUTS 1821d11eac93f408053a0807783b434624a6dfcb3fbZack Rusin debug_printf("%d) Output vert:\n", idx / shader->info.num_outputs); 18389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#endif 18489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin for (slot = 0; slot < shader->info.num_outputs; slot++) { 18504490ad31d0d763a0a1da7b521da55f5ea14e1cdZack Rusin output[slot][0] = machine->Outputs[idx + slot].xyzw[0].f[0]; 18604490ad31d0d763a0a1da7b521da55f5ea14e1cdZack Rusin output[slot][1] = machine->Outputs[idx + slot].xyzw[1].f[0]; 18704490ad31d0d763a0a1da7b521da55f5ea14e1cdZack Rusin output[slot][2] = machine->Outputs[idx + slot].xyzw[2].f[0]; 18804490ad31d0d763a0a1da7b521da55f5ea14e1cdZack Rusin output[slot][3] = machine->Outputs[idx + slot].xyzw[3].f[0]; 18989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#ifdef DEBUG_OUTPUTS 19089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin debug_printf("\t%d: %f %f %f %f\n", slot, 19189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin output[slot][0], 19289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin output[slot][1], 19389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin output[slot][2], 19489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin output[slot][3]); 19589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin#endif 19689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin debug_assert(!util_is_inf_or_nan(output[slot][0])); 19789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 19829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin output = (float (*)[4])((char *)output + shader->vertex_size); 19989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 20089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin } 2011d11eac93f408053a0807783b434624a6dfcb3fbZack Rusin *p_output = output; 20289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 20389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 20429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 20529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusinstatic void draw_fetch_gs_input(struct draw_geometry_shader *shader, 20629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned *indices, 20729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned num_vertices, 20829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned prim_idx) 20929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin{ 21029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin struct tgsi_exec_machine *machine = shader->machine; 21129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned slot, vs_slot, i; 21229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned input_vertex_stride = shader->input_vertex_stride; 21329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin const float (*input_ptr)[4]; 21429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 21529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin input_ptr = shader->input; 21629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 21729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin for (i = 0; i < num_vertices; ++i) { 21829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin const float (*input)[4]; 21929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin /*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/ 22029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin input = (const float (*)[4])( 22129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin (const char *)input_ptr + (indices[i] * input_vertex_stride)); 22229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) { 22329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned idx = i * TGSI_EXEC_MAX_INPUT_ATTRIBS + slot; 22429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_PRIMID) { 22529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[0].f[prim_idx] = (float)shader->in_prim_idx; 22629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[1].f[prim_idx] = (float)shader->in_prim_idx; 22729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[2].f[prim_idx] = (float)shader->in_prim_idx; 22829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[3].f[prim_idx] = (float)shader->in_prim_idx; 22929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin } else { 23029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin /*debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n", 23129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin slot, vs_slot, idx);*/ 23229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#if 1 23329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin assert(!util_is_inf_or_nan(input[vs_slot][0])); 23429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin assert(!util_is_inf_or_nan(input[vs_slot][1])); 23529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin assert(!util_is_inf_or_nan(input[vs_slot][2])); 23629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin assert(!util_is_inf_or_nan(input[vs_slot][3])); 23729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#endif 23829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[0].f[prim_idx] = input[vs_slot][0]; 23929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[1].f[prim_idx] = input[vs_slot][1]; 24029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[2].f[prim_idx] = input[vs_slot][2]; 24129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[3].f[prim_idx] = input[vs_slot][3]; 24229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#if 0 24329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin debug_printf("\t\t%f %f %f %f\n", 24429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[0].f[prim_idx], 24529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[1].f[prim_idx], 24629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[2].f[prim_idx], 24729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Inputs[idx].xyzw[3].f[prim_idx]); 24829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#endif 24929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin ++vs_slot; 25029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin } 25129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin } 25229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin } 25329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin} 25429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 25529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 25629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusinstatic void gs_flush(struct draw_geometry_shader *shader, 25729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned input_primitives) 25829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin{ 25929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned out_prim_count; 26029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin struct tgsi_exec_machine *machine = shader->machine; 26129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 26229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin debug_assert(input_primitives > 0 && 26329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin input_primitives < 4); 26429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 26529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin tgsi_set_exec_mask(machine, 26629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 1, 26729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin input_primitives > 1, 26829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin input_primitives > 2, 26929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin input_primitives > 3); 27029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 27129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin /* run interpreter */ 27229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin tgsi_exec_machine_run(machine); 27329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 27429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin out_prim_count = 27529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin machine->Temps[TGSI_EXEC_TEMP_PRIMITIVE_I].xyzw[TGSI_EXEC_TEMP_PRIMITIVE_C].u[0]; 27629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 27729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin draw_geometry_fetch_outputs(shader, out_prim_count, 27829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin &shader->tmp_output); 27929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin} 28029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 28129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusinstatic void gs_point(struct draw_geometry_shader *shader, 28229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin int idx) 28329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin{ 28429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned indices[1]; 28529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 28629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin indices[0] = idx; 28729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 28829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin draw_fetch_gs_input(shader, indices, 1, 0); 28929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin ++shader->in_prim_idx; 29029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 29129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin gs_flush(shader, 1); 29229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin} 29329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 29429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusinstatic void gs_line(struct draw_geometry_shader *shader, 29529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin int i0, int i1) 29629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin{ 29729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned indices[2]; 29829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 29929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin indices[0] = i0; 30029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin indices[1] = i1; 30129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 30229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin draw_fetch_gs_input(shader, indices, 2, 0); 30329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin ++shader->in_prim_idx; 30429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 30529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin gs_flush(shader, 1); 30629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin} 30729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 30829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusinstatic void gs_tri(struct draw_geometry_shader *shader, 30929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin int i0, int i1, int i2) 31029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin{ 31129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin unsigned indices[3]; 31229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 31329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin indices[0] = i0; 31429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin indices[1] = i1; 31529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin indices[2] = i2; 31629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 31729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin draw_fetch_gs_input(shader, indices, 3, 0); 31829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin ++shader->in_prim_idx; 31929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 32029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin gs_flush(shader, 1); 32129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin} 32229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 32329639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2) 32429639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#define LINE(gs,i0,i1) gs_line(gs,i0,i1) 32529639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#define POINT(gs,i0) gs_point(gs,i0) 32629639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#define FUNC gs_run 32729639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin#include "draw_gs_tmp.h" 32829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 329d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusinint draw_geometry_shader_run(struct draw_geometry_shader *shader, 3304d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned pipe_prim, 331d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin const float (*input)[4], 332d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin float (*output)[4], 333d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin const void *constants[PIPE_MAX_CONSTANT_BUFFERS], 334d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin unsigned count, 335d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin unsigned input_stride, 336d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin unsigned vertex_size) 33789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 33889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct tgsi_exec_machine *machine = shader->machine; 33989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin unsigned int i; 3404d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned num_in_primitives = 3414d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin u_gs_prims_for_vertices(pipe_prim, count); 3424d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned alloc_count = draw_max_output_vertices(shader->draw, 3434d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin pipe_prim, 3444d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin count); 3454d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin /* this is bad, but we can't be overwriting the output array 3464d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin * because it's the same as input array here */ 3474d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin struct vertex_header *pipeline_verts = 3484d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin (struct vertex_header *)MALLOC(vertex_size * alloc_count); 34989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 35029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin if (!pipeline_verts) 35129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin return 0; 35229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin 3534d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin if (0) debug_printf("%s count = %d (prims = %d)\n", __FUNCTION__, 3544d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin count, num_in_primitives); 355da4185ca77395b9dddc362891d8f7bbc2fa924cdZack Rusin 356d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin shader->emitted_vertices = 0; 357d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin shader->emitted_primitives = 0; 35829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin shader->vertex_size = vertex_size; 35929639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin shader->tmp_output = ( float (*)[4])pipeline_verts->data; 36029639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin shader->in_prim_idx = 0; 36129639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin shader->input_vertex_stride = input_stride; 36229639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin shader->input = input; 363d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin 3647c5f255201f42303188137f56ea8acc030444f0eMichal Krol for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { 3659851644435f991a1a1bbb145333a97601627b37dMichal Krol machine->Consts[i] = constants[i]; 3669851644435f991a1a1bbb145333a97601627b37dMichal Krol } 36789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 36829639932f7d42ce3eb2f4b487366c67bb0bc910bZack Rusin gs_run(shader, pipe_prim, count); 3694d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin 3704d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin memcpy(output, pipeline_verts->data, 3714d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin shader->info.num_outputs * 4 * sizeof(float) + 3724d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin vertex_size * (shader->emitted_vertices -1)); 3734d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin 3744d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin FREE(pipeline_verts); 375d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin return shader->emitted_vertices; 37689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 37789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 37889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_geometry_shader_delete(struct draw_geometry_shader *shader) 37989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 38089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE((void*) shader->state.tokens); 38189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin FREE(shader); 38289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 38389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin 38489d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusinvoid draw_geometry_shader_prepare(struct draw_geometry_shader *shader, 38589d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin struct draw_context *draw) 38689d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin{ 3871963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin if (shader && shader->machine->Tokens != shader->state.tokens) { 3881963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin tgsi_exec_machine_bind_shader(shader->machine, 3891963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin shader->state.tokens, 3901963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin draw->gs.num_samplers, 3911963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin draw->gs.samplers); 3921963112f9d0a2ed8e237641eef8eb384365d1375Zack Rusin } 39389d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin} 3944d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin 3954d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusinint draw_max_output_vertices(struct draw_context *draw, 3964d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned pipe_prim, 3974d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned count) 3984d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin{ 3994d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned alloc_count = align( count, 4 ); 4004d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin 4014d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin if (draw->gs.geometry_shader) { 4024d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned input_primitives = u_gs_prims_for_vertices(pipe_prim, 4034d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin count); 4044d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin /* max GS output is number of input primitives * max output 4054d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin * vertices per each invocation */ 4064d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin unsigned gs_max_verts = input_primitives * 4074d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin draw->gs.geometry_shader->max_output_vertices; 4084d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin if (gs_max_verts > count) 4094d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin alloc_count = align(gs_max_verts, 4); 4104d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin } 4114d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin /*debug_printf("------- alloc count = %d (input = %d)\n", 4124d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin alloc_count, count);*/ 4134d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin return alloc_count; 4144d0baa73c9e1a40b4ac089c786af79dc7f1ff219Zack Rusin} 415