13733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca/************************************************************************** 23733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * 33733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * Copyright 2011 VMware, Inc. 43733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * All Rights Reserved. 53733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * 63733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 73733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * copy of this software and associated documentation files (the 83733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * "Software"), to deal in the Software without restriction, including 93733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * without limitation the rights to use, copy, modify, merge, publish, 103733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * distribute, sub license, and/or sell copies of the Software, and to 113733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * permit persons to whom the Software is furnished to do so, subject to 123733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * the following conditions: 133733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * 143733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * The above copyright notice and this permission notice (including the 153733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * next paragraph) shall be included in all copies or substantial portions 163733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * of the Software. 173733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * 183733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 193733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 203733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 213733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 223733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 233733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 243733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 253733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * 263733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca **************************************************************************/ 273733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 283733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 293733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca#include "util/u_debug.h" 303733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca#include "util/u_math.h" 313733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca#include "util/u_format.h" 323733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca#include "util/u_draw.h" 333733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 343733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 353733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca/** 36438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * Returns the largest legal index value plus one for the current set 37438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * of bound vertex buffers. Regardless of any other consideration, 38438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * all vertex lookups need to be clamped to 0..max_index-1 to prevent 39438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * an out-of-bound access. 40438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * 41438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * Note that if zero is returned it means that one or more buffers is 42438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul * too small to contain any valid vertex data. 433733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca */ 443733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonsecaunsigned 453733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonsecautil_draw_max_index( 463733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca const struct pipe_vertex_buffer *vertex_buffers, 473733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca const struct pipe_vertex_element *vertex_elements, 483733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca unsigned nr_vertex_elements, 493733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca const struct pipe_draw_info *info) 503733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca{ 513733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca unsigned max_index; 523733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca unsigned i; 533733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 54438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul max_index = ~0U - 1; 553733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca for (i = 0; i < nr_vertex_elements; i++) { 563733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca const struct pipe_vertex_element *element = 573733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca &vertex_elements[i]; 583733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca const struct pipe_vertex_buffer *buffer = 593733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca &vertex_buffers[element->vertex_buffer_index]; 603733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca unsigned buffer_size; 613733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca const struct util_format_description *format_desc; 623733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca unsigned format_size; 633733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 644552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák if (!buffer->buffer) { 654552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák continue; 664552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák } 674552fd50d959ab99546cfa994f8ba5bdf5d66bc7Marek Olšák 683733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca assert(buffer->buffer->height0 == 1); 693733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca assert(buffer->buffer->depth0 == 1); 703733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca buffer_size = buffer->buffer->width0; 713733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 723733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca format_desc = util_format_description(element->src_format); 733733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca assert(format_desc->block.width == 1); 743733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca assert(format_desc->block.height == 1); 753733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca assert(format_desc->block.bits % 8 == 0); 763733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca format_size = format_desc->block.bits/8; 773733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 78438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul if (buffer->buffer_offset >= buffer_size) { 79438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul /* buffer is too small */ 80438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul return 0; 81438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul } 82438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul 833733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca buffer_size -= buffer->buffer_offset; 843733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 85438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul if (element->src_offset >= buffer_size) { 86438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul /* buffer is too small */ 87438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul return 0; 88438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul } 89438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul 903733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca buffer_size -= element->src_offset; 913733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 92438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul if (format_size > buffer_size) { 93438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul /* buffer is too small */ 94438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul return 0; 95438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul } 96438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul 973733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca buffer_size -= format_size; 983733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 993733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca if (buffer->stride != 0) { 1003733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca unsigned buffer_max_index; 1013733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 1023733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca buffer_max_index = buffer_size / buffer->stride; 1033733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 1043733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca if (element->instance_divisor == 0) { 1053733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca /* Per-vertex data */ 1063733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca max_index = MIN2(max_index, buffer_max_index); 1073733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca } 1083733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca else { 1093733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca /* Per-instance data. Simply make sure the state tracker didn't 1103733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca * request more instances than those that fit in the buffer */ 1113733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca assert((info->start_instance + info->instance_count)/element->instance_divisor 1123733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca <= (buffer_max_index + 1)); 1133733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca } 1143733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca } 1153733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca } 1163733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca 117438d7ac146dc89d1c2943610c662c57e11a47382Brian Paul return max_index + 1; 1183733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca} 119