~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/auxiliary/draw/draw_pt_so_emit.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 *
 
3
 * Copyright 2010 VMware, Inc.
 
4
 * All Rights Reserved.
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * copy of this software and associated documentation files (the
 
8
 * "Software"), to deal in the Software without restriction, including
 
9
 * without limitation the rights to use, copy, modify, merge, publish,
 
10
 * distribute, sub license, and/or sell copies of the Software, and to
 
11
 * permit persons to whom the Software is furnished to do so, subject to
 
12
 * the following conditions:
 
13
 *
 
14
 * The above copyright notice and this permission notice (including the
 
15
 * next paragraph) shall be included in all copies or substantial portions
 
16
 * of the Software.
 
17
 *
 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
21
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
 
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 *
 
26
 **************************************************************************/
 
27
 
 
28
#include "draw/draw_context.h"
 
29
#include "draw/draw_private.h"
 
30
#include "draw/draw_vbuf.h"
 
31
#include "draw/draw_vertex.h"
 
32
#include "draw/draw_pt.h"
 
33
 
 
34
#include "util/u_math.h"
 
35
#include "util/u_memory.h"
 
36
 
 
37
struct pt_so_emit {
 
38
   struct draw_context *draw;
 
39
 
 
40
   void *buffers[PIPE_MAX_SO_BUFFERS];
 
41
 
 
42
   unsigned input_vertex_stride;
 
43
   const float (*inputs)[4];
 
44
 
 
45
   boolean has_so;
 
46
 
 
47
   boolean single_buffer;
 
48
 
 
49
   unsigned emitted_primitives;
 
50
   unsigned emitted_vertices;
 
51
};
 
52
 
 
53
 
 
54
void draw_pt_so_emit_prepare(struct pt_so_emit *emit)
 
55
{
 
56
   struct draw_context *draw = emit->draw;
 
57
 
 
58
   emit->has_so = (draw->so.state.num_outputs > 0);
 
59
 
 
60
   /* if we have a state with outputs make sure we have
 
61
    * buffers to output to */
 
62
   if (emit->has_so) {
 
63
      boolean has_valid_buffer = FALSE;
 
64
      unsigned i;
 
65
      for (i = 0; i < draw->so.num_buffers; ++i) {
 
66
         if (draw->so.buffers[i]) {
 
67
            has_valid_buffer = TRUE;
 
68
            break;
 
69
         }
 
70
      }
 
71
      emit->has_so = has_valid_buffer;
 
72
   }
 
73
 
 
74
   if (!emit->has_so)
 
75
      return;
 
76
 
 
77
   /* XXX: need to flush to get prim_vbuf.c to release its allocation??
 
78
    */
 
79
   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
80
}
 
81
 
 
82
static boolean
 
83
is_component_writable(unsigned mask,
 
84
                      unsigned compo)
 
85
{
 
86
   switch (mask) {
 
87
   case TGSI_WRITEMASK_NONE:
 
88
      return FALSE;
 
89
   case TGSI_WRITEMASK_X:
 
90
      return compo == 0;
 
91
   case TGSI_WRITEMASK_Y:
 
92
      return compo == 1;
 
93
   case TGSI_WRITEMASK_XY:
 
94
      return compo == 0 || compo == 1;
 
95
   case TGSI_WRITEMASK_Z:
 
96
      return compo == 2;
 
97
   case TGSI_WRITEMASK_XZ:
 
98
      return compo == 0 || compo == 2;
 
99
   case TGSI_WRITEMASK_YZ:
 
100
      return compo == 1 || compo == 2;
 
101
   case TGSI_WRITEMASK_XYZ:
 
102
      return compo == 0 || compo == 1 || compo == 2;
 
103
   case TGSI_WRITEMASK_W:
 
104
      return compo == 3;
 
105
   case TGSI_WRITEMASK_XW:
 
106
      return compo == 0 || compo == 3;
 
107
   case TGSI_WRITEMASK_YW:
 
108
      return compo == 1 || compo == 3;
 
109
   case TGSI_WRITEMASK_XYW:
 
110
      return compo == 0 || compo == 1 || compo == 3;
 
111
   case TGSI_WRITEMASK_ZW:
 
112
      return compo == 2 || compo == 3;
 
113
   case TGSI_WRITEMASK_XZW:
 
114
      return compo == 0 || compo == 1 || compo == 3;
 
115
   case TGSI_WRITEMASK_YZW:
 
116
      return compo == 1 || compo == 2 || compo == 4;
 
117
   case TGSI_WRITEMASK_XYZW:
 
118
      return compo < 4;
 
119
   default:
 
120
      debug_assert(!"Unknown writemask in stream out");
 
121
      return compo < 4;
 
122
   }
 
123
}
 
124
 
 
125
static void so_emit_prim(struct pt_so_emit *so,
 
126
                         unsigned *indices,
 
127
                         unsigned num_vertices)
 
128
{
 
129
   unsigned slot, i;
 
130
   unsigned input_vertex_stride = so->input_vertex_stride;
 
131
   struct draw_context *draw = so->draw;
 
132
   const float (*input_ptr)[4];
 
133
   const struct pipe_stream_output_state *state =
 
134
      &draw->so.state;
 
135
   float **buffer = 0;
 
136
 
 
137
   input_ptr = so->inputs;
 
138
 
 
139
   for (i = 0; i < num_vertices; ++i) {
 
140
      const float (*input)[4];
 
141
      unsigned total_written_compos = 0;
 
142
      /*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/
 
143
      input = (const float (*)[4])(
 
144
         (const char *)input_ptr + (indices[i] * input_vertex_stride));
 
145
      for (slot = 0; slot < state->num_outputs; ++slot) {
 
146
         unsigned idx = state->register_index[slot];
 
147
         unsigned writemask = state->register_mask[slot];
 
148
         unsigned written_compos = 0;
 
149
         unsigned compo;
 
150
 
 
151
         buffer = (float**)&so->buffers[state->output_buffer[slot]];
 
152
 
 
153
         /*debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n",
 
154
           slot, vs_slot, idx);*/
 
155
#if 1
 
156
         assert(!util_is_inf_or_nan(input[idx][0]));
 
157
         assert(!util_is_inf_or_nan(input[idx][1]));
 
158
         assert(!util_is_inf_or_nan(input[idx][2]));
 
159
         assert(!util_is_inf_or_nan(input[idx][3]));
 
160
#endif
 
161
         for (compo = 0; compo < 4; ++compo) {
 
162
            if (is_component_writable(writemask, compo)) {
 
163
               float *buf = *buffer;
 
164
               buf[written_compos++] = input[idx][compo];
 
165
            }
 
166
         }
 
167
#if 0
 
168
         debug_printf("\t\t(writemask = %d)%f %f %f %f\n",
 
169
                      writemask,
 
170
                      input[idx][0],
 
171
                      input[idx][1],
 
172
                      input[idx][2],
 
173
                      input[idx][3]);
 
174
#endif
 
175
         *buffer += written_compos;
 
176
         total_written_compos += written_compos;
 
177
      }
 
178
      if (so->single_buffer) {
 
179
         int stride = (int)state->stride -
 
180
                      sizeof(float) * total_written_compos;
 
181
 
 
182
         debug_assert(stride >= 0);
 
183
         *buffer = (float*) (((char*)*buffer) + stride);
 
184
      }
 
185
   }
 
186
   so->emitted_vertices += num_vertices;
 
187
   ++so->emitted_primitives;
 
188
}
 
189
 
 
190
static void so_point(struct pt_so_emit *so, int idx)
 
191
{
 
192
   unsigned indices[1];
 
193
 
 
194
   indices[0] = idx;
 
195
 
 
196
   so_emit_prim(so, indices, 1);
 
197
}
 
198
 
 
199
static void so_line(struct pt_so_emit *so, int i0, int i1)
 
200
{
 
201
   unsigned indices[2];
 
202
 
 
203
   indices[0] = i0;
 
204
   indices[1] = i1;
 
205
 
 
206
   so_emit_prim(so, indices, 2);
 
207
}
 
208
 
 
209
static void so_tri(struct pt_so_emit *so, int i0, int i1, int i2)
 
210
{
 
211
   unsigned indices[3];
 
212
 
 
213
   indices[0] = i0;
 
214
   indices[1] = i1;
 
215
   indices[2] = i2;
 
216
 
 
217
   so_emit_prim(so, indices, 3);
 
218
}
 
219
 
 
220
 
 
221
#define FUNC         so_run_linear
 
222
#define GET_ELT(idx) (start + (idx))
 
223
#include "draw_so_emit_tmp.h"
 
224
 
 
225
 
 
226
#define FUNC         so_run_elts
 
227
#define LOCAL_VARS   const ushort *elts = input_prims->elts;
 
228
#define GET_ELT(idx) (elts[start + (idx)])
 
229
#include "draw_so_emit_tmp.h"
 
230
 
 
231
 
 
232
void draw_pt_so_emit( struct pt_so_emit *emit,
 
233
                      const struct draw_vertex_info *input_verts,
 
234
                      const struct draw_prim_info *input_prims )
 
235
{
 
236
   struct draw_context *draw = emit->draw;
 
237
   struct vbuf_render *render = draw->render;
 
238
   unsigned start, i;
 
239
 
 
240
   if (!emit->has_so)
 
241
      return;
 
242
 
 
243
   emit->emitted_vertices = 0;
 
244
   emit->emitted_primitives = 0;
 
245
   emit->input_vertex_stride = input_verts->stride;
 
246
   emit->inputs = (const float (*)[4])input_verts->verts->data;
 
247
   for (i = 0; i < draw->so.num_buffers; ++i) {
 
248
      emit->buffers[i] = draw->so.buffers[i];
 
249
   }
 
250
   emit->single_buffer = TRUE;
 
251
   for (i = 0; i < draw->so.state.num_outputs; ++i) {
 
252
      if (draw->so.state.output_buffer[i] != 0)
 
253
         emit->single_buffer = FALSE;
 
254
   }
 
255
 
 
256
   /* XXX: need to flush to get prim_vbuf.c to release its allocation??*/
 
257
   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
258
 
 
259
   for (start = i = 0; i < input_prims->primitive_count;
 
260
        start += input_prims->primitive_lengths[i], i++)
 
261
   {
 
262
      unsigned count = input_prims->primitive_lengths[i];
 
263
 
 
264
      if (input_prims->linear) {
 
265
         so_run_linear(emit, input_prims, input_verts,
 
266
                       start, count);
 
267
      } else {
 
268
         so_run_elts(emit, input_prims, input_verts,
 
269
                     start, count);
 
270
      }
 
271
   }
 
272
 
 
273
   render->set_stream_output_info(render,
 
274
                                  emit->emitted_primitives,
 
275
                                  emit->emitted_vertices);
 
276
}
 
277
 
 
278
 
 
279
struct pt_so_emit *draw_pt_so_emit_create( struct draw_context *draw )
 
280
{
 
281
   struct pt_so_emit *emit = CALLOC_STRUCT(pt_so_emit);
 
282
   if (!emit)
 
283
      return NULL;
 
284
 
 
285
   emit->draw = draw;
 
286
 
 
287
   return emit;
 
288
}
 
289
 
 
290
void draw_pt_so_emit_destroy( struct pt_so_emit *emit )
 
291
{
 
292
   FREE(emit);
 
293
}