1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci/* Author: 29bf215546Sopenharmony_ci * Brian Paul 30bf215546Sopenharmony_ci * Keith Whitwell 31bf215546Sopenharmony_ci */ 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "pipe/p_defines.h" 35bf215546Sopenharmony_ci#include "pipe/p_context.h" 36bf215546Sopenharmony_ci#include "util/u_inlines.h" 37bf215546Sopenharmony_ci#include "util/u_draw.h" 38bf215546Sopenharmony_ci#include "util/u_prim.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include "sp_context.h" 41bf215546Sopenharmony_ci#include "sp_query.h" 42bf215546Sopenharmony_ci#include "sp_state.h" 43bf215546Sopenharmony_ci#include "sp_texture.h" 44bf215546Sopenharmony_ci#include "sp_screen.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#include "draw/draw_context.h" 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci/** 49bf215546Sopenharmony_ci * This function handles drawing indexed and non-indexed prims, 50bf215546Sopenharmony_ci * instanced and non-instanced drawing, with or without min/max element 51bf215546Sopenharmony_ci * indexes. 52bf215546Sopenharmony_ci * All the other drawing functions are expressed in terms of this 53bf215546Sopenharmony_ci * function. 54bf215546Sopenharmony_ci * 55bf215546Sopenharmony_ci * For non-indexed prims, indexBuffer should be NULL. 56bf215546Sopenharmony_ci * For non-instanced drawing, instanceCount should be 1. 57bf215546Sopenharmony_ci * When the min/max element indexes aren't known, minIndex should be 0 58bf215546Sopenharmony_ci * and maxIndex should be ~0. 59bf215546Sopenharmony_ci */ 60bf215546Sopenharmony_civoid 61bf215546Sopenharmony_cisoftpipe_draw_vbo(struct pipe_context *pipe, 62bf215546Sopenharmony_ci const struct pipe_draw_info *info, 63bf215546Sopenharmony_ci unsigned drawid_offset, 64bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 65bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias *draws, 66bf215546Sopenharmony_ci unsigned num_draws) 67bf215546Sopenharmony_ci{ 68bf215546Sopenharmony_ci if (num_draws > 1) { 69bf215546Sopenharmony_ci util_draw_multi(pipe, info, drawid_offset, indirect, draws, num_draws); 70bf215546Sopenharmony_ci return; 71bf215546Sopenharmony_ci } 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci if (!indirect && (!draws[0].count || !info->instance_count)) 74bf215546Sopenharmony_ci return; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci struct softpipe_context *sp = softpipe_context(pipe); 77bf215546Sopenharmony_ci struct draw_context *draw = sp->draw; 78bf215546Sopenharmony_ci const void *mapped_indices = NULL; 79bf215546Sopenharmony_ci unsigned i; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci if (!softpipe_check_render_cond(sp)) 82bf215546Sopenharmony_ci return; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci if (indirect && indirect->buffer) { 85bf215546Sopenharmony_ci util_draw_indirect(pipe, info, indirect); 86bf215546Sopenharmony_ci return; 87bf215546Sopenharmony_ci } 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci sp->reduced_api_prim = u_reduced_prim(info->mode); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci if (sp->dirty) { 92bf215546Sopenharmony_ci softpipe_update_derived(sp, sp->reduced_api_prim); 93bf215546Sopenharmony_ci } 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci /* Map vertex buffers */ 96bf215546Sopenharmony_ci for (i = 0; i < sp->num_vertex_buffers; i++) { 97bf215546Sopenharmony_ci const void *buf = sp->vertex_buffer[i].is_user_buffer ? 98bf215546Sopenharmony_ci sp->vertex_buffer[i].buffer.user : NULL; 99bf215546Sopenharmony_ci size_t size = ~0; 100bf215546Sopenharmony_ci if (!buf) { 101bf215546Sopenharmony_ci if (!sp->vertex_buffer[i].buffer.resource) { 102bf215546Sopenharmony_ci continue; 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci buf = softpipe_resource_data(sp->vertex_buffer[i].buffer.resource); 105bf215546Sopenharmony_ci size = sp->vertex_buffer[i].buffer.resource->width0; 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, buf, size); 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci /* Map index buffer, if present */ 111bf215546Sopenharmony_ci if (info->index_size) { 112bf215546Sopenharmony_ci unsigned available_space = ~0; 113bf215546Sopenharmony_ci mapped_indices = info->has_user_indices ? info->index.user : NULL; 114bf215546Sopenharmony_ci if (!mapped_indices) { 115bf215546Sopenharmony_ci mapped_indices = softpipe_resource_data(info->index.resource); 116bf215546Sopenharmony_ci available_space = info->index.resource->width0; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci draw_set_indexes(draw, 120bf215546Sopenharmony_ci (ubyte *) mapped_indices, 121bf215546Sopenharmony_ci info->index_size, available_space); 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci if (softpipe_screen(sp->pipe.screen)->use_llvm) { 125bf215546Sopenharmony_ci softpipe_prepare_vertex_sampling(sp, 126bf215546Sopenharmony_ci sp->num_sampler_views[PIPE_SHADER_VERTEX], 127bf215546Sopenharmony_ci sp->sampler_views[PIPE_SHADER_VERTEX]); 128bf215546Sopenharmony_ci softpipe_prepare_geometry_sampling(sp, 129bf215546Sopenharmony_ci sp->num_sampler_views[PIPE_SHADER_GEOMETRY], 130bf215546Sopenharmony_ci sp->sampler_views[PIPE_SHADER_GEOMETRY]); 131bf215546Sopenharmony_ci } 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci if (sp->gs && !sp->gs->shader.tokens) { 134bf215546Sopenharmony_ci /* we have an empty geometry shader with stream output, so 135bf215546Sopenharmony_ci attach the stream output info to the current vertex shader */ 136bf215546Sopenharmony_ci if (sp->vs) { 137bf215546Sopenharmony_ci draw_vs_attach_so(sp->vs->draw_data, &sp->gs->shader.stream_output); 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci draw_collect_pipeline_statistics(draw, 141bf215546Sopenharmony_ci sp->active_statistics_queries > 0); 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci /* draw! */ 144bf215546Sopenharmony_ci draw_vbo(draw, info, drawid_offset, indirect, draws, num_draws, 0); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci /* unmap vertex/index buffers - will cause draw module to flush */ 147bf215546Sopenharmony_ci for (i = 0; i < sp->num_vertex_buffers; i++) { 148bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, NULL, 0); 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci if (mapped_indices) { 151bf215546Sopenharmony_ci draw_set_indexes(draw, NULL, 0, 0); 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci if (softpipe_screen(sp->pipe.screen)->use_llvm) { 155bf215546Sopenharmony_ci softpipe_cleanup_vertex_sampling(sp); 156bf215546Sopenharmony_ci softpipe_cleanup_geometry_sampling(sp); 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci /* 160bf215546Sopenharmony_ci * TODO: Flush only when a user vertex/index buffer is present 161bf215546Sopenharmony_ci * (or even better, modify draw module to do this 162bf215546Sopenharmony_ci * internally when this condition is seen?) 163bf215546Sopenharmony_ci */ 164bf215546Sopenharmony_ci draw_flush(draw); 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci /* Note: leave drawing surfaces mapped */ 167bf215546Sopenharmony_ci sp->dirty_render_cache = TRUE; 168bf215546Sopenharmony_ci} 169