1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "draw/draw_context.h" 27bf215546Sopenharmony_ci#include "draw/draw_vbuf.h" 28bf215546Sopenharmony_ci#include "util/u_inlines.h" 29bf215546Sopenharmony_ci#include "pipe/p_state.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "svga_context.h" 32bf215546Sopenharmony_ci#include "svga_screen.h" 33bf215546Sopenharmony_ci#include "svga_swtnl.h" 34bf215546Sopenharmony_ci#include "svga_state.h" 35bf215546Sopenharmony_ci#include "svga_swtnl_private.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cienum pipe_error 40bf215546Sopenharmony_cisvga_swtnl_draw_vbo(struct svga_context *svga, 41bf215546Sopenharmony_ci const struct pipe_draw_info *info, 42bf215546Sopenharmony_ci unsigned drawid_offset, 43bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 44bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias *draw_one) 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = { 0 }; 47bf215546Sopenharmony_ci struct pipe_transfer *ib_transfer = NULL; 48bf215546Sopenharmony_ci struct pipe_transfer *cb_transfer[SVGA_MAX_CONST_BUFS] = { 0 }; 49bf215546Sopenharmony_ci struct draw_context *draw = svga->swtnl.draw; 50bf215546Sopenharmony_ci ASSERTED unsigned old_num_vertex_buffers; 51bf215546Sopenharmony_ci unsigned i; 52bf215546Sopenharmony_ci const void *map; 53bf215546Sopenharmony_ci boolean retried; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLDRAWVBO); 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci assert(!svga->dirty); 58bf215546Sopenharmony_ci assert(svga->state.sw.need_swtnl); 59bf215546Sopenharmony_ci assert(draw); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci /* Make sure that the need_swtnl flag does not go away */ 62bf215546Sopenharmony_ci svga->state.sw.in_swtnl_draw = TRUE; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci SVGA_RETRY_CHECK(svga, svga_update_state(svga, SVGA_STATE_SWTNL_DRAW), retried); 65bf215546Sopenharmony_ci if (retried) { 66bf215546Sopenharmony_ci svga->swtnl.new_vbuf = TRUE; 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci /* 70bf215546Sopenharmony_ci * Map vertex buffers 71bf215546Sopenharmony_ci */ 72bf215546Sopenharmony_ci for (i = 0; i < svga->curr.num_vertex_buffers; i++) { 73bf215546Sopenharmony_ci if (svga->curr.vb[i].buffer.resource) { 74bf215546Sopenharmony_ci map = pipe_buffer_map(&svga->pipe, 75bf215546Sopenharmony_ci svga->curr.vb[i].buffer.resource, 76bf215546Sopenharmony_ci PIPE_MAP_READ | 77bf215546Sopenharmony_ci PIPE_MAP_UNSYNCHRONIZED, 78bf215546Sopenharmony_ci &vb_transfer[i]); 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, map, ~0); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci old_num_vertex_buffers = svga->curr.num_vertex_buffers; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci /* Map index buffer, if present */ 86bf215546Sopenharmony_ci map = NULL; 87bf215546Sopenharmony_ci if (info->index_size) { 88bf215546Sopenharmony_ci if (info->has_user_indices) { 89bf215546Sopenharmony_ci map = (ubyte *) info->index.user; 90bf215546Sopenharmony_ci } else { 91bf215546Sopenharmony_ci map = pipe_buffer_map(&svga->pipe, info->index.resource, 92bf215546Sopenharmony_ci PIPE_MAP_READ | 93bf215546Sopenharmony_ci PIPE_MAP_UNSYNCHRONIZED, &ib_transfer); 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci draw_set_indexes(draw, 96bf215546Sopenharmony_ci (const ubyte *) map, 97bf215546Sopenharmony_ci info->index_size, ~0); 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci /* Map constant buffers */ 101bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[PIPE_SHADER_VERTEX]); ++i) { 102bf215546Sopenharmony_ci if (svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer == NULL) { 103bf215546Sopenharmony_ci continue; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci map = pipe_buffer_map(&svga->pipe, 107bf215546Sopenharmony_ci svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer, 108bf215546Sopenharmony_ci PIPE_MAP_READ | 109bf215546Sopenharmony_ci PIPE_MAP_UNSYNCHRONIZED, 110bf215546Sopenharmony_ci &cb_transfer[i]); 111bf215546Sopenharmony_ci assert(map); 112bf215546Sopenharmony_ci draw_set_mapped_constant_buffer( 113bf215546Sopenharmony_ci draw, PIPE_SHADER_VERTEX, i, 114bf215546Sopenharmony_ci map, 115bf215546Sopenharmony_ci svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer->width0); 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci draw_vbo(draw, info, drawid_offset, indirect, draw_one, 1, 119bf215546Sopenharmony_ci svga->patch_vertices); 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci draw_flush(svga->swtnl.draw); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci /* Ensure the draw module didn't touch this */ 124bf215546Sopenharmony_ci assert(old_num_vertex_buffers == svga->curr.num_vertex_buffers); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci /* 127bf215546Sopenharmony_ci * unmap vertex/index buffers 128bf215546Sopenharmony_ci */ 129bf215546Sopenharmony_ci for (i = 0; i < svga->curr.num_vertex_buffers; i++) { 130bf215546Sopenharmony_ci if (svga->curr.vb[i].buffer.resource) { 131bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, vb_transfer[i]); 132bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, NULL, 0); 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci if (ib_transfer) { 137bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, ib_transfer); 138bf215546Sopenharmony_ci draw_set_indexes(draw, NULL, 0, 0); 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[PIPE_SHADER_VERTEX]); ++i) { 142bf215546Sopenharmony_ci if (svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer) { 143bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, cb_transfer[i]); 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci } 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci /* Now safe to remove the need_swtnl flag in any update_state call */ 148bf215546Sopenharmony_ci svga->state.sw.in_swtnl_draw = FALSE; 149bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_NEED_PIPELINE | SVGA_NEW_NEED_SWVFETCH; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 152bf215546Sopenharmony_ci return PIPE_OK; 153bf215546Sopenharmony_ci} 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ciboolean 157bf215546Sopenharmony_cisvga_init_swtnl(struct svga_context *svga) 158bf215546Sopenharmony_ci{ 159bf215546Sopenharmony_ci struct svga_screen *screen = svga_screen(svga->pipe.screen); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci svga->swtnl.backend = svga_vbuf_render_create(svga); 162bf215546Sopenharmony_ci if (!svga->swtnl.backend) 163bf215546Sopenharmony_ci goto fail; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci /* 166bf215546Sopenharmony_ci * Create drawing context and plug our rendering stage into it. 167bf215546Sopenharmony_ci */ 168bf215546Sopenharmony_ci svga->swtnl.draw = draw_create(&svga->pipe); 169bf215546Sopenharmony_ci if (svga->swtnl.draw == NULL) 170bf215546Sopenharmony_ci goto fail; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci draw_set_rasterize_stage(svga->swtnl.draw, 174bf215546Sopenharmony_ci draw_vbuf_stage(svga->swtnl.draw, svga->swtnl.backend)); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci draw_set_render(svga->swtnl.draw, svga->swtnl.backend); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci svga->blitter = util_blitter_create(&svga->pipe); 179bf215546Sopenharmony_ci if (!svga->blitter) 180bf215546Sopenharmony_ci goto fail; 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci /* must be done before installing Draw stages */ 183bf215546Sopenharmony_ci util_blitter_cache_all_shaders(svga->blitter); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci if (!screen->haveLineSmooth) 186bf215546Sopenharmony_ci draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci /* enable/disable line stipple stage depending on device caps */ 189bf215546Sopenharmony_ci draw_enable_line_stipple(svga->swtnl.draw, !screen->haveLineStipple); 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci /* always install AA point stage */ 192bf215546Sopenharmony_ci draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe); 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci /* Set wide line threshold above device limit (so we'll never really use it) 195bf215546Sopenharmony_ci */ 196bf215546Sopenharmony_ci draw_wide_line_threshold(svga->swtnl.draw, 197bf215546Sopenharmony_ci MAX2(screen->maxLineWidth, 198bf215546Sopenharmony_ci screen->maxLineWidthAA)); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if (debug_get_bool_option("SVGA_SWTNL_FSE", FALSE)) 201bf215546Sopenharmony_ci draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE, TRUE, FALSE); 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci return TRUE; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_cifail: 206bf215546Sopenharmony_ci if (svga->blitter) 207bf215546Sopenharmony_ci util_blitter_destroy(svga->blitter); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci if (svga->swtnl.backend) 210bf215546Sopenharmony_ci svga->swtnl.backend->destroy(svga->swtnl.backend); 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci if (svga->swtnl.draw) 213bf215546Sopenharmony_ci draw_destroy(svga->swtnl.draw); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci return FALSE; 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_civoid 220bf215546Sopenharmony_cisvga_destroy_swtnl(struct svga_context *svga) 221bf215546Sopenharmony_ci{ 222bf215546Sopenharmony_ci draw_destroy(svga->swtnl.draw); 223bf215546Sopenharmony_ci} 224