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