sp_draw_arrays.c revision 89d8577fb3036547ef0b47498cc8dc5c77f886e0
1/**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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/* Author:
29 *    Brian Paul
30 *    Keith Whitwell
31 */
32
33
34#include "pipe/p_defines.h"
35#include "pipe/p_context.h"
36#include "pipe/internal/p_winsys_screen.h"
37#include "pipe/p_inlines.h"
38#include "util/u_prim.h"
39
40#include "sp_context.h"
41#include "sp_state.h"
42
43#include "draw/draw_context.h"
44
45
46
47static void
48softpipe_map_constant_buffers(struct softpipe_context *sp)
49{
50   struct pipe_winsys *ws = sp->pipe.winsys;
51   uint i, vssize, gssize;
52
53   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
54      if (sp->constants[i].buffer && sp->constants[i].buffer->size)
55         sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer,
56                                                  PIPE_BUFFER_USAGE_CPU_READ);
57   }
58
59   if (sp->constants[PIPE_SHADER_VERTEX].buffer)
60      vssize = sp->constants[PIPE_SHADER_VERTEX].buffer->size;
61   else
62      vssize = 0;
63
64   if (sp->constants[PIPE_SHADER_GEOMETRY].buffer)
65      gssize = sp->constants[PIPE_SHADER_GEOMETRY].buffer->size;
66   else
67      gssize = 0;
68
69   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
70                                   sp->mapped_constants[PIPE_SHADER_VERTEX],
71                                   vssize);
72   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY,
73                                   sp->mapped_constants[PIPE_SHADER_GEOMETRY],
74                                   gssize);
75}
76
77
78static void
79softpipe_unmap_constant_buffers(struct softpipe_context *sp)
80{
81   struct pipe_winsys *ws = sp->pipe.winsys;
82   uint i;
83
84   /* really need to flush all prims since the vert/frag shaders const buffers
85    * are going away now.
86    */
87   draw_flush(sp->draw);
88
89   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, NULL, 0);
90   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0);
91
92   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
93      if (sp->constants[i].buffer && sp->constants[i].buffer->size)
94         ws->buffer_unmap(ws, sp->constants[i].buffer);
95      sp->mapped_constants[i] = NULL;
96   }
97}
98
99
100boolean
101softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
102                     unsigned start, unsigned count)
103{
104   return softpipe_draw_elements(pipe, NULL, 0, mode, start, count);
105}
106
107
108/**
109 * Draw vertex arrays, with optional indexing.
110 * Basically, map the vertex buffers (and drawing surfaces), then hand off
111 * the drawing to the 'draw' module.
112 */
113boolean
114softpipe_draw_range_elements(struct pipe_context *pipe,
115                             struct pipe_buffer *indexBuffer,
116                             unsigned indexSize,
117                             unsigned min_index,
118                             unsigned max_index,
119                             unsigned mode, unsigned start, unsigned count)
120{
121   struct softpipe_context *sp = softpipe_context(pipe);
122   struct draw_context *draw = sp->draw;
123   unsigned i;
124
125   sp->reduced_api_prim = u_reduced_prim(mode);
126
127   if (sp->dirty)
128      softpipe_update_derived( sp );
129
130   softpipe_map_transfers(sp);
131   softpipe_map_constant_buffers(sp);
132
133   /*
134    * Map vertex buffers
135    */
136   for (i = 0; i < sp->num_vertex_buffers; i++) {
137      void *buf
138         = pipe_buffer_map(pipe->screen,
139                                    sp->vertex_buffer[i].buffer,
140                                    PIPE_BUFFER_USAGE_CPU_READ);
141      draw_set_mapped_vertex_buffer(draw, i, buf);
142   }
143
144   /* Map index buffer, if present */
145   if (indexBuffer) {
146      void *mapped_indexes
147         = pipe_buffer_map(pipe->screen, indexBuffer,
148                                    PIPE_BUFFER_USAGE_CPU_READ);
149      draw_set_mapped_element_buffer_range(draw, indexSize,
150                                           min_index,
151                                           max_index,
152                                           mapped_indexes);
153   }
154   else {
155      /* no index/element buffer */
156      draw_set_mapped_element_buffer_range(draw, 0, start,
157                                           start + count - 1, NULL);
158   }
159
160   /* draw! */
161   draw_arrays(draw, mode, start, count);
162
163   /*
164    * unmap vertex/index buffers - will cause draw module to flush
165    */
166   for (i = 0; i < sp->num_vertex_buffers; i++) {
167      draw_set_mapped_vertex_buffer(draw, i, NULL);
168      pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
169   }
170   if (indexBuffer) {
171      draw_set_mapped_element_buffer(draw, 0, NULL);
172      pipe_buffer_unmap(pipe->screen, indexBuffer);
173   }
174
175
176   /* Note: leave drawing surfaces mapped */
177   softpipe_unmap_constant_buffers(sp);
178
179   sp->dirty_render_cache = TRUE;
180
181   return TRUE;
182}
183
184
185boolean
186softpipe_draw_elements(struct pipe_context *pipe,
187                       struct pipe_buffer *indexBuffer,
188                       unsigned indexSize,
189                       unsigned mode, unsigned start, unsigned count)
190{
191   return softpipe_draw_range_elements( pipe, indexBuffer,
192                                        indexSize,
193                                        0, 0xffffffff,
194                                        mode, start, count );
195}
196