sp_draw_arrays.c revision 6d28bf917fb1d741d90fd3f05c22769376021fca
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 "util/u_inlines.h" 37#include "util/u_prim.h" 38#include "util/u_draw_quad.h" 39 40#include "sp_context.h" 41#include "sp_query.h" 42#include "sp_state.h" 43#include "sp_texture.h" 44 45#include "draw/draw_context.h" 46 47 48 49 50 51void 52softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode) 53{ 54 struct softpipe_context *sp = softpipe_context(pipe); 55 struct draw_context *draw = sp->draw; 56 const unsigned start = 0; 57 const unsigned count = sp->so_target.so_count[0]; 58 void *buf = sp->so_target.buffer[0]->data; 59 int offset = sp->so_target.offset[0]; 60 61 if (!softpipe_check_render_cond(sp) || 62 sp->so_target.num_buffers != 1) 63 return; 64 65 sp->reduced_api_prim = u_reduced_prim(mode); 66 67 if (sp->dirty) { 68 softpipe_update_derived(sp); 69 } 70 71 softpipe_map_transfers(sp); 72 73 /* Map so buffers */ 74 if (offset < 0) /* we were appending so start from beginning */ 75 offset = 0; 76 buf = (void*)((int32_t*)buf + offset); 77 draw_set_mapped_vertex_buffer(draw, 0, buf); 78 79 draw_set_mapped_element_buffer_range(draw, 80 0, 0, 81 start, 82 start + count - 1, 83 NULL); 84 85 /* draw! */ 86 draw_arrays_instanced(draw, mode, start, count, 0, 1); 87 88 /* unmap vertex/index buffers - will cause draw module to flush */ 89 draw_set_mapped_vertex_buffer(draw, 0, NULL); 90 91 /* 92 * TODO: Flush only when a user vertex/index buffer is present 93 * (or even better, modify draw module to do this 94 * internally when this condition is seen?) 95 */ 96 draw_flush(draw); 97 98 /* Note: leave drawing surfaces mapped */ 99 sp->dirty_render_cache = TRUE; 100} 101 102 103/** 104 * This function handles drawing indexed and non-indexed prims, 105 * instanced and non-instanced drawing, with or without min/max element 106 * indexes. 107 * All the other drawing functions are expressed in terms of this 108 * function. 109 * 110 * For non-indexed prims, indexBuffer should be NULL. 111 * For non-instanced drawing, instanceCount should be 1. 112 * When the min/max element indexes aren't known, minIndex should be 0 113 * and maxIndex should be ~0. 114 */ 115void 116softpipe_draw_vbo(struct pipe_context *pipe, 117 const struct pipe_draw_info *info) 118{ 119 struct softpipe_context *sp = softpipe_context(pipe); 120 struct draw_context *draw = sp->draw; 121 void *mapped_indices = NULL; 122 unsigned i; 123 124 if (!softpipe_check_render_cond(sp)) 125 return; 126 127 sp->reduced_api_prim = u_reduced_prim(info->mode); 128 129 if (sp->dirty) { 130 softpipe_update_derived(sp); 131 } 132 133 softpipe_map_transfers(sp); 134 135 /* Map vertex buffers */ 136 for (i = 0; i < sp->num_vertex_buffers; i++) { 137 void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data; 138 draw_set_mapped_vertex_buffer(draw, i, buf); 139 } 140 141 /* Map index buffer, if present */ 142 if (info->indexed && sp->index_buffer.buffer) { 143 mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data; 144 mapped_indices += sp->index_buffer.offset; 145 } 146 147 draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? 148 sp->index_buffer.index_size : 0, 149 info->index_bias, 150 info->min_index, 151 info->max_index, 152 mapped_indices); 153 154 /* draw! */ 155 draw_arrays_instanced(draw, info->mode, info->start, info->count, 156 info->start_instance, info->instance_count); 157 158 /* unmap vertex/index buffers - will cause draw module to flush */ 159 for (i = 0; i < sp->num_vertex_buffers; i++) { 160 draw_set_mapped_vertex_buffer(draw, i, NULL); 161 } 162 if (mapped_indices) { 163 draw_set_mapped_element_buffer(draw, 0, 0, NULL); 164 } 165 166 /* 167 * TODO: Flush only when a user vertex/index buffer is present 168 * (or even better, modify draw module to do this 169 * internally when this condition is seen?) 170 */ 171 draw_flush(draw); 172 173 /* Note: leave drawing surfaces mapped */ 174 sp->dirty_render_cache = TRUE; 175} 176 177static void 178softpipe_draw_range_elements_instanced(struct pipe_context *pipe, 179 struct pipe_resource *indexBuffer, 180 unsigned indexSize, 181 int indexBias, 182 unsigned minIndex, 183 unsigned maxIndex, 184 unsigned mode, 185 unsigned start, 186 unsigned count, 187 unsigned startInstance, 188 unsigned instanceCount) 189{ 190 struct softpipe_context *sp = softpipe_context(pipe); 191 struct pipe_draw_info info; 192 struct pipe_index_buffer saved_ib, ib; 193 194 util_draw_init_info(&info); 195 info.mode = mode; 196 info.start = start; 197 info.count = count; 198 info.start_instance = startInstance; 199 info.instance_count = instanceCount; 200 info.index_bias = indexBias; 201 info.min_index = minIndex; 202 info.max_index = maxIndex; 203 204 if (indexBuffer) { 205 info.indexed = TRUE; 206 207 saved_ib = sp->index_buffer; 208 ib.buffer = indexBuffer; 209 ib.offset = 0; 210 ib.index_size = indexSize; 211 pipe->set_index_buffer(pipe, &ib); 212 } 213 214 softpipe_draw_vbo(pipe, &info); 215 216 if (indexBuffer) 217 pipe->set_index_buffer(pipe, &saved_ib); 218} 219 220 221void 222softpipe_draw_range_elements(struct pipe_context *pipe, 223 struct pipe_resource *indexBuffer, 224 unsigned indexSize, 225 int indexBias, 226 unsigned min_index, 227 unsigned max_index, 228 unsigned mode, unsigned start, unsigned count) 229{ 230 softpipe_draw_range_elements_instanced(pipe, 231 indexBuffer, 232 indexSize, 233 indexBias, 234 min_index, 235 max_index, 236 mode, 237 start, 238 count, 239 0, 240 1); 241} 242 243 244void 245softpipe_draw_elements(struct pipe_context *pipe, 246 struct pipe_resource *indexBuffer, 247 unsigned indexSize, int indexBias, 248 unsigned mode, unsigned start, unsigned count) 249{ 250 softpipe_draw_range_elements_instanced(pipe, 251 indexBuffer, 252 indexSize, 253 indexBias, 254 0, 255 0xffffffff, 256 mode, 257 start, 258 count, 259 0, 260 1); 261} 262 263void 264softpipe_draw_arrays_instanced(struct pipe_context *pipe, 265 unsigned mode, 266 unsigned start, 267 unsigned count, 268 unsigned startInstance, 269 unsigned instanceCount) 270{ 271 softpipe_draw_range_elements_instanced(pipe, 272 NULL, 273 0, 274 0, 275 0, 276 0xffffffff, 277 mode, 278 start, 279 count, 280 startInstance, 281 instanceCount); 282} 283 284void 285softpipe_draw_elements_instanced(struct pipe_context *pipe, 286 struct pipe_resource *indexBuffer, 287 unsigned indexSize, 288 int indexBias, 289 unsigned mode, 290 unsigned start, 291 unsigned count, 292 unsigned startInstance, 293 unsigned instanceCount) 294{ 295 softpipe_draw_range_elements_instanced(pipe, 296 indexBuffer, 297 indexSize, 298 indexBias, 299 0, 300 0xffffffff, 301 mode, 302 start, 303 count, 304 startInstance, 305 instanceCount); 306} 307 308void 309softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, 310 unsigned start, unsigned count) 311{ 312 softpipe_draw_range_elements_instanced(pipe, 313 NULL, 314 0, 315 0, 316 0, 317 0xffffffff, 318 mode, 319 start, 320 count, 321 0, 322 1); 323} 324 325