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_draw.h" 37bf215546Sopenharmony_ci#include "util/u_prim.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#include "lp_context.h" 40bf215546Sopenharmony_ci#include "lp_state.h" 41bf215546Sopenharmony_ci#include "lp_query.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include "draw/draw_context.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci/** 48bf215546Sopenharmony_ci * Draw vertex arrays, with optional indexing, optional instancing. 49bf215546Sopenharmony_ci * All the other drawing functions are implemented in terms of this function. 50bf215546Sopenharmony_ci * Basically, map the vertex buffers (and drawing surfaces), then hand off 51bf215546Sopenharmony_ci * the drawing to the 'draw' module. 52bf215546Sopenharmony_ci */ 53bf215546Sopenharmony_cistatic void 54bf215546Sopenharmony_cillvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, 55bf215546Sopenharmony_ci unsigned drawid_offset, 56bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 57bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias *draws, 58bf215546Sopenharmony_ci unsigned num_draws) 59bf215546Sopenharmony_ci{ 60bf215546Sopenharmony_ci if (!indirect && (!draws[0].count || !info->instance_count)) 61bf215546Sopenharmony_ci return; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci struct llvmpipe_context *lp = llvmpipe_context(pipe); 64bf215546Sopenharmony_ci struct draw_context *draw = lp->draw; 65bf215546Sopenharmony_ci const void *mapped_indices = NULL; 66bf215546Sopenharmony_ci unsigned i; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci if (!llvmpipe_check_render_cond(lp)) 69bf215546Sopenharmony_ci return; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci if (indirect && indirect->buffer) { 72bf215546Sopenharmony_ci util_draw_indirect(pipe, info, indirect); 73bf215546Sopenharmony_ci return; 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci if (lp->dirty) 77bf215546Sopenharmony_ci llvmpipe_update_derived( lp ); 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci /* 80bf215546Sopenharmony_ci * Map vertex buffers 81bf215546Sopenharmony_ci */ 82bf215546Sopenharmony_ci for (i = 0; i < lp->num_vertex_buffers; i++) { 83bf215546Sopenharmony_ci const void *buf = lp->vertex_buffer[i].is_user_buffer ? 84bf215546Sopenharmony_ci lp->vertex_buffer[i].buffer.user : NULL; 85bf215546Sopenharmony_ci size_t size = ~0; 86bf215546Sopenharmony_ci if (!buf) { 87bf215546Sopenharmony_ci if (!lp->vertex_buffer[i].buffer.resource) { 88bf215546Sopenharmony_ci continue; 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer.resource); 91bf215546Sopenharmony_ci size = lp->vertex_buffer[i].buffer.resource->width0; 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, buf, size); 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci /* Map index buffer, if present */ 97bf215546Sopenharmony_ci if (info->index_size) { 98bf215546Sopenharmony_ci unsigned available_space = ~0; 99bf215546Sopenharmony_ci mapped_indices = info->has_user_indices ? info->index.user : NULL; 100bf215546Sopenharmony_ci if (!mapped_indices) { 101bf215546Sopenharmony_ci mapped_indices = llvmpipe_resource_data(info->index.resource); 102bf215546Sopenharmony_ci available_space = info->index.resource->width0; 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci draw_set_indexes(draw, 105bf215546Sopenharmony_ci (ubyte *) mapped_indices, 106bf215546Sopenharmony_ci info->index_size, available_space); 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci llvmpipe_prepare_vertex_sampling(lp, 110bf215546Sopenharmony_ci lp->num_sampler_views[PIPE_SHADER_VERTEX], 111bf215546Sopenharmony_ci lp->sampler_views[PIPE_SHADER_VERTEX]); 112bf215546Sopenharmony_ci llvmpipe_prepare_geometry_sampling(lp, 113bf215546Sopenharmony_ci lp->num_sampler_views[PIPE_SHADER_GEOMETRY], 114bf215546Sopenharmony_ci lp->sampler_views[PIPE_SHADER_GEOMETRY]); 115bf215546Sopenharmony_ci llvmpipe_prepare_tess_ctrl_sampling(lp, 116bf215546Sopenharmony_ci lp->num_sampler_views[PIPE_SHADER_TESS_CTRL], 117bf215546Sopenharmony_ci lp->sampler_views[PIPE_SHADER_TESS_CTRL]); 118bf215546Sopenharmony_ci llvmpipe_prepare_tess_eval_sampling(lp, 119bf215546Sopenharmony_ci lp->num_sampler_views[PIPE_SHADER_TESS_EVAL], 120bf215546Sopenharmony_ci lp->sampler_views[PIPE_SHADER_TESS_EVAL]); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci llvmpipe_prepare_vertex_images(lp, 123bf215546Sopenharmony_ci lp->num_images[PIPE_SHADER_VERTEX], 124bf215546Sopenharmony_ci lp->images[PIPE_SHADER_VERTEX]); 125bf215546Sopenharmony_ci llvmpipe_prepare_geometry_images(lp, 126bf215546Sopenharmony_ci lp->num_images[PIPE_SHADER_GEOMETRY], 127bf215546Sopenharmony_ci lp->images[PIPE_SHADER_GEOMETRY]); 128bf215546Sopenharmony_ci llvmpipe_prepare_tess_ctrl_images(lp, 129bf215546Sopenharmony_ci lp->num_images[PIPE_SHADER_TESS_CTRL], 130bf215546Sopenharmony_ci lp->images[PIPE_SHADER_TESS_CTRL]); 131bf215546Sopenharmony_ci llvmpipe_prepare_tess_eval_images(lp, 132bf215546Sopenharmony_ci lp->num_images[PIPE_SHADER_TESS_EVAL], 133bf215546Sopenharmony_ci lp->images[PIPE_SHADER_TESS_EVAL]); 134bf215546Sopenharmony_ci if (lp->gs && lp->gs->no_tokens) { 135bf215546Sopenharmony_ci /* we have an empty geometry shader with stream output, so 136bf215546Sopenharmony_ci attach the stream output info to the current vertex shader */ 137bf215546Sopenharmony_ci if (lp->vs) { 138bf215546Sopenharmony_ci draw_vs_attach_so(lp->vs, &lp->gs->stream_output); 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci draw_collect_pipeline_statistics(draw, 142bf215546Sopenharmony_ci lp->active_statistics_queries > 0 && 143bf215546Sopenharmony_ci !lp->queries_disabled); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci draw_collect_primitives_generated(draw, 146bf215546Sopenharmony_ci lp->active_primgen_queries && 147bf215546Sopenharmony_ci !lp->queries_disabled); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci /* draw! */ 150bf215546Sopenharmony_ci draw_vbo(draw, info, drawid_offset, indirect, draws, num_draws, 151bf215546Sopenharmony_ci lp->patch_vertices); 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci /* 154bf215546Sopenharmony_ci * unmap vertex/index buffers 155bf215546Sopenharmony_ci */ 156bf215546Sopenharmony_ci for (i = 0; i < lp->num_vertex_buffers; i++) { 157bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, NULL, 0); 158bf215546Sopenharmony_ci } 159bf215546Sopenharmony_ci if (mapped_indices) { 160bf215546Sopenharmony_ci draw_set_indexes(draw, NULL, 0, 0); 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci if (lp->gs && lp->gs->no_tokens) { 164bf215546Sopenharmony_ci /* we have attached stream output to the vs for rendering, 165bf215546Sopenharmony_ci now lets reset it */ 166bf215546Sopenharmony_ci if (lp->vs) { 167bf215546Sopenharmony_ci draw_vs_reset_so(lp->vs); 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_VERTEX); 172bf215546Sopenharmony_ci llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_GEOMETRY); 173bf215546Sopenharmony_ci llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_TESS_CTRL); 174bf215546Sopenharmony_ci llvmpipe_cleanup_stage_sampling(lp, PIPE_SHADER_TESS_EVAL); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_VERTEX); 177bf215546Sopenharmony_ci llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_GEOMETRY); 178bf215546Sopenharmony_ci llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_TESS_CTRL); 179bf215546Sopenharmony_ci llvmpipe_cleanup_stage_images(lp, PIPE_SHADER_TESS_EVAL); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci /* 182bf215546Sopenharmony_ci * TODO: Flush only when a user vertex/index buffer is present 183bf215546Sopenharmony_ci * (or even better, modify draw module to do this 184bf215546Sopenharmony_ci * internally when this condition is seen?) 185bf215546Sopenharmony_ci */ 186bf215546Sopenharmony_ci draw_flush(draw); 187bf215546Sopenharmony_ci} 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_civoid 191bf215546Sopenharmony_cillvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo; 194bf215546Sopenharmony_ci} 195