1c9db97c8229689060fab0edee7df717f804b99ceZack Rusin/************************************************************************** 2c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * 3c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * Copyright 2010 VMware, Inc. 4c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * All Rights Reserved. 5c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * 6c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * Permission is hereby granted, free of charge, to any person obtaining a 7c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * copy of this software and associated documentation files (the 8c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * "Software"), to deal in the Software without restriction, including 9c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * without limitation the rights to use, copy, modify, merge, publish, 10c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * distribute, sub license, and/or sell copies of the Software, and to 11c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * permit persons to whom the Software is furnished to do so, subject to 12c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * the following conditions: 13c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * 14c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * The above copyright notice and this permission notice (including the 15c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * next paragraph) shall be included in all copies or substantial portions 16c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * of the Software. 17c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * 18c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25c9db97c8229689060fab0edee7df717f804b99ceZack Rusin * 26c9db97c8229689060fab0edee7df717f804b99ceZack Rusin **************************************************************************/ 27c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 28c9db97c8229689060fab0edee7df717f804b99ceZack Rusin#include "draw/draw_private.h" 29ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie#include "draw/draw_vs.h" 30ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie#include "draw/draw_context.h" 31c9db97c8229689060fab0edee7df717f804b99ceZack Rusin#include "draw/draw_vbuf.h" 32c9db97c8229689060fab0edee7df717f804b99ceZack Rusin#include "draw/draw_vertex.h" 33c9db97c8229689060fab0edee7df717f804b99ceZack Rusin#include "draw/draw_pt.h" 34287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 35ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie#include "pipe/p_state.h" 36ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie 37287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin#include "util/u_math.h" 38287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin#include "util/u_memory.h" 39c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 40c9db97c8229689060fab0edee7df717f804b99ceZack Rusinstruct pt_so_emit { 41c9db97c8229689060fab0edee7df717f804b99ceZack Rusin struct draw_context *draw; 42c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 43287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned input_vertex_stride; 44287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin const float (*inputs)[4]; 45c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 46c9db97c8229689060fab0edee7df717f804b99ceZack Rusin boolean has_so; 47c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 48287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned emitted_primitives; 49287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned emitted_vertices; 50ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie unsigned generated_primitives; 51287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin}; 52c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 53c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 54287531772ccea82c8a6c4dab5656d751a8943524Zack Rusinvoid draw_pt_so_emit_prepare(struct pt_so_emit *emit) 55c9db97c8229689060fab0edee7df717f804b99ceZack Rusin{ 56c9db97c8229689060fab0edee7df717f804b99ceZack Rusin struct draw_context *draw = emit->draw; 57c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 58ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie emit->has_so = (draw->vs.vertex_shader->state.stream_output.num_outputs > 0); 59c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 6091862051f98e646647906bb15aec5c5d537f87e4Zack Rusin /* if we have a state with outputs make sure we have 6191862051f98e646647906bb15aec5c5d537f87e4Zack Rusin * buffers to output to */ 6291862051f98e646647906bb15aec5c5d537f87e4Zack Rusin if (emit->has_so) { 6391862051f98e646647906bb15aec5c5d537f87e4Zack Rusin boolean has_valid_buffer = FALSE; 6491862051f98e646647906bb15aec5c5d537f87e4Zack Rusin unsigned i; 65ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie for (i = 0; i < draw->so.num_targets; ++i) { 66ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie if (draw->so.targets[i]) { 6791862051f98e646647906bb15aec5c5d537f87e4Zack Rusin has_valid_buffer = TRUE; 6891862051f98e646647906bb15aec5c5d537f87e4Zack Rusin break; 6991862051f98e646647906bb15aec5c5d537f87e4Zack Rusin } 7091862051f98e646647906bb15aec5c5d537f87e4Zack Rusin } 7191862051f98e646647906bb15aec5c5d537f87e4Zack Rusin emit->has_so = has_valid_buffer; 7291862051f98e646647906bb15aec5c5d537f87e4Zack Rusin } 7391862051f98e646647906bb15aec5c5d537f87e4Zack Rusin 74c9db97c8229689060fab0edee7df717f804b99ceZack Rusin if (!emit->has_so) 75c9db97c8229689060fab0edee7df717f804b99ceZack Rusin return; 76c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 77c9db97c8229689060fab0edee7df717f804b99ceZack Rusin /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 78c9db97c8229689060fab0edee7df717f804b99ceZack Rusin */ 79c9db97c8229689060fab0edee7df717f804b99ceZack Rusin draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 80287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin} 81c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 82287531772ccea82c8a6c4dab5656d751a8943524Zack Rusinstatic void so_emit_prim(struct pt_so_emit *so, 83287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned *indices, 84287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned num_vertices) 85287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin{ 86287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned slot, i; 87287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned input_vertex_stride = so->input_vertex_stride; 88287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin struct draw_context *draw = so->draw; 89287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin const float (*input_ptr)[4]; 90861a029ddb31e91bb4d8e18ab708d0d172f63aadMarek Olšák const struct pipe_stream_output_info *state = 91ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie &draw->vs.vertex_shader->state.stream_output; 92ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie float *buffer; 93ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie int buffer_total_bytes[PIPE_MAX_SO_BUFFERS]; 94287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 95287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin input_ptr = so->inputs; 96287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 97ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie ++so->generated_primitives; 98ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie 99ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie for (i = 0; i < draw->so.num_targets; i++) { 100ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie struct draw_so_target *target = draw->so.targets[i]; 101ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie buffer_total_bytes[i] = target->internal_offset; 102ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie } 103ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie 104ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie /* check have we space to emit prim first - if not don't do anything */ 105ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie for (i = 0; i < num_vertices; ++i) { 106ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie for (slot = 0; slot < state->num_outputs; ++slot) { 1072449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák unsigned num_comps = state->output[slot].num_components; 108ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie int ob = state->output[slot].output_buffer; 109ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie 1102449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák if ((buffer_total_bytes[ob] + num_comps * sizeof(float)) > 111ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie draw->so.targets[ob]->target.buffer_size) { 112ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie return; 113ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie } 1142449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák buffer_total_bytes[ob] += num_comps * sizeof(float); 115ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie } 116ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie } 117ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie 118287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin for (i = 0; i < num_vertices; ++i) { 119287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin const float (*input)[4]; 120638a80bc075a4b58123cb9ba03993bd8bfd024cdZack Rusin unsigned total_written_compos = 0; 121287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin /*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/ 122287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin input = (const float (*)[4])( 123287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin (const char *)input_ptr + (indices[i] * input_vertex_stride)); 124ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie 125287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin for (slot = 0; slot < state->num_outputs; ++slot) { 126861a029ddb31e91bb4d8e18ab708d0d172f63aadMarek Olšák unsigned idx = state->output[slot].register_index; 1272449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák unsigned start_comp = state->output[slot].start_component; 1282449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák unsigned num_comps = state->output[slot].num_components; 129ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie int ob = state->output[slot].output_buffer; 130287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 131ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie buffer = (float *)((char *)draw->so.targets[ob]->mapping + 132ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie draw->so.targets[ob]->target.buffer_offset + 133ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie draw->so.targets[ob]->internal_offset); 1342449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák memcpy(buffer, &input[idx][start_comp], num_comps * sizeof(float)); 1352449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák draw->so.targets[ob]->internal_offset += num_comps * sizeof(float); 1362449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák total_written_compos += num_comps; 137638a80bc075a4b58123cb9ba03993bd8bfd024cdZack Rusin } 138c9db97c8229689060fab0edee7df717f804b99ceZack Rusin } 139287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin so->emitted_vertices += num_vertices; 140287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin ++so->emitted_primitives; 141287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin} 142287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 143287531772ccea82c8a6c4dab5656d751a8943524Zack Rusinstatic void so_point(struct pt_so_emit *so, int idx) 144287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin{ 145287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned indices[1]; 146287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 147287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin indices[0] = idx; 148287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 149287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin so_emit_prim(so, indices, 1); 150287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin} 151287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 152287531772ccea82c8a6c4dab5656d751a8943524Zack Rusinstatic void so_line(struct pt_so_emit *so, int i0, int i1) 153287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin{ 154287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned indices[2]; 155c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 156287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin indices[0] = i0; 157287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin indices[1] = i1; 158c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 159287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin so_emit_prim(so, indices, 2); 160c9db97c8229689060fab0edee7df717f804b99ceZack Rusin} 161c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 162287531772ccea82c8a6c4dab5656d751a8943524Zack Rusinstatic void so_tri(struct pt_so_emit *so, int i0, int i1, int i2) 163287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin{ 164287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned indices[3]; 165287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 166287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin indices[0] = i0; 167287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin indices[1] = i1; 168287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin indices[2] = i2; 169287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 170287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin so_emit_prim(so, indices, 3); 171287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin} 172287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 173287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 17494d256591d83ac1330f7237e865784618d124d09Chia-I Wu#define FUNC so_run_linear 17594d256591d83ac1330f7237e865784618d124d09Chia-I Wu#define GET_ELT(idx) (start + (idx)) 176287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin#include "draw_so_emit_tmp.h" 177287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 178287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 17994d256591d83ac1330f7237e865784618d124d09Chia-I Wu#define FUNC so_run_elts 18094d256591d83ac1330f7237e865784618d124d09Chia-I Wu#define LOCAL_VARS const ushort *elts = input_prims->elts; 181c3fee80f2b35f6a7e48d6015bfc759c66b7e1a2cChia-I Wu#define GET_ELT(idx) (elts[start + (idx)]) 182287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin#include "draw_so_emit_tmp.h" 183287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 184c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 185c9db97c8229689060fab0edee7df717f804b99ceZack Rusinvoid draw_pt_so_emit( struct pt_so_emit *emit, 186287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin const struct draw_vertex_info *input_verts, 187287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin const struct draw_prim_info *input_prims ) 188c9db97c8229689060fab0edee7df717f804b99ceZack Rusin{ 189c9db97c8229689060fab0edee7df717f804b99ceZack Rusin struct draw_context *draw = emit->draw; 190c9db97c8229689060fab0edee7df717f804b99ceZack Rusin struct vbuf_render *render = draw->render; 191a192b5eeafae80f9f9e7e7e442abc5b44d583d1aZack Rusin unsigned start, i; 192c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 193c9db97c8229689060fab0edee7df717f804b99ceZack Rusin if (!emit->has_so) 194c9db97c8229689060fab0edee7df717f804b99ceZack Rusin return; 195c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 196287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin emit->emitted_vertices = 0; 197287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin emit->emitted_primitives = 0; 198ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie emit->generated_primitives = 0; 199287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin emit->input_vertex_stride = input_verts->stride; 200287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin emit->inputs = (const float (*)[4])input_verts->verts->data; 201c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 202c9db97c8229689060fab0edee7df717f804b99ceZack Rusin /* XXX: need to flush to get prim_vbuf.c to release its allocation??*/ 203c9db97c8229689060fab0edee7df717f804b99ceZack Rusin draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 204c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 205287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin for (start = i = 0; i < input_prims->primitive_count; 206287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin start += input_prims->primitive_lengths[i], i++) 207b85a361ccbac956d2842251395c048a4b3f4c440Keith Whitwell { 208287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin unsigned count = input_prims->primitive_lengths[i]; 209287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin 210287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin if (input_prims->linear) { 211287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin so_run_linear(emit, input_prims, input_verts, 212287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin start, count); 213287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin } else { 214287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin so_run_elts(emit, input_prims, input_verts, 215287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin start, count); 216b85a361ccbac956d2842251395c048a4b3f4c440Keith Whitwell } 217b85a361ccbac956d2842251395c048a4b3f4c440Keith Whitwell } 2182c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin 219287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin render->set_stream_output_info(render, 220287531772ccea82c8a6c4dab5656d751a8943524Zack Rusin emit->emitted_primitives, 221ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie emit->emitted_vertices, 222ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie emit->generated_primitives); 223c9db97c8229689060fab0edee7df717f804b99ceZack Rusin} 224c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 225c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 226c9db97c8229689060fab0edee7df717f804b99ceZack Rusinstruct pt_so_emit *draw_pt_so_emit_create( struct draw_context *draw ) 227c9db97c8229689060fab0edee7df717f804b99ceZack Rusin{ 228c9db97c8229689060fab0edee7df717f804b99ceZack Rusin struct pt_so_emit *emit = CALLOC_STRUCT(pt_so_emit); 229c9db97c8229689060fab0edee7df717f804b99ceZack Rusin if (!emit) 230c9db97c8229689060fab0edee7df717f804b99ceZack Rusin return NULL; 231c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 232c9db97c8229689060fab0edee7df717f804b99ceZack Rusin emit->draw = draw; 233c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 234c9db97c8229689060fab0edee7df717f804b99ceZack Rusin return emit; 235c9db97c8229689060fab0edee7df717f804b99ceZack Rusin} 236c9db97c8229689060fab0edee7df717f804b99ceZack Rusin 237c9db97c8229689060fab0edee7df717f804b99ceZack Rusinvoid draw_pt_so_emit_destroy( struct pt_so_emit *emit ) 238c9db97c8229689060fab0edee7df717f804b99ceZack Rusin{ 239c9db97c8229689060fab0edee7df717f804b99ceZack Rusin FREE(emit); 240c9db97c8229689060fab0edee7df717f804b99ceZack Rusin} 241