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_vbuf.h" 27bf215546Sopenharmony_ci#include "draw/draw_context.h" 28bf215546Sopenharmony_ci#include "draw/draw_vertex.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/u_debug.h" 31bf215546Sopenharmony_ci#include "util/u_inlines.h" 32bf215546Sopenharmony_ci#include "util/u_math.h" 33bf215546Sopenharmony_ci#include "util/u_memory.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "svga_context.h" 36bf215546Sopenharmony_ci#include "svga_state.h" 37bf215546Sopenharmony_ci#include "svga_swtnl.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#include "svga_types.h" 40bf215546Sopenharmony_ci#include "svga_reg.h" 41bf215546Sopenharmony_ci#include "svga3d_reg.h" 42bf215546Sopenharmony_ci#include "svga_draw.h" 43bf215546Sopenharmony_ci#include "svga_shader.h" 44bf215546Sopenharmony_ci#include "svga_swtnl_private.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_cistatic const struct vertex_info * 48bf215546Sopenharmony_cisvga_vbuf_render_get_vertex_info(struct vbuf_render *render) 49bf215546Sopenharmony_ci{ 50bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 51bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci svga_swtnl_update_vdecl(svga); 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci return &svga_render->vertex_info; 56bf215546Sopenharmony_ci} 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cistatic boolean 60bf215546Sopenharmony_cisvga_vbuf_render_allocate_vertices(struct vbuf_render *render, 61bf215546Sopenharmony_ci ushort vertex_size, 62bf215546Sopenharmony_ci ushort nr_vertices) 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 65bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 66bf215546Sopenharmony_ci struct pipe_screen *screen = svga->pipe.screen; 67bf215546Sopenharmony_ci size_t size = (size_t)nr_vertices * (size_t)vertex_size; 68bf215546Sopenharmony_ci boolean new_vbuf = FALSE; 69bf215546Sopenharmony_ci boolean new_ibuf = FALSE; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), 72bf215546Sopenharmony_ci SVGA_STATS_TIME_VBUFRENDERALLOCVERT); 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci if (svga_render->vertex_size != vertex_size) 75bf215546Sopenharmony_ci svga->swtnl.new_vdecl = TRUE; 76bf215546Sopenharmony_ci svga_render->vertex_size = (size_t)vertex_size; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci if (svga->swtnl.new_vbuf) 79bf215546Sopenharmony_ci new_ibuf = new_vbuf = TRUE; 80bf215546Sopenharmony_ci svga->swtnl.new_vbuf = FALSE; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci if (svga_render->vbuf_size 83bf215546Sopenharmony_ci < svga_render->vbuf_offset + svga_render->vbuf_used + size) 84bf215546Sopenharmony_ci new_vbuf = TRUE; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci if (new_vbuf) 87bf215546Sopenharmony_ci pipe_resource_reference(&svga_render->vbuf, NULL); 88bf215546Sopenharmony_ci if (new_ibuf) 89bf215546Sopenharmony_ci pipe_resource_reference(&svga_render->ibuf, NULL); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci if (!svga_render->vbuf) { 92bf215546Sopenharmony_ci svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); 93bf215546Sopenharmony_ci svga_render->vbuf = SVGA_TRY_PTR(pipe_buffer_create 94bf215546Sopenharmony_ci (screen, PIPE_BIND_VERTEX_BUFFER, 95bf215546Sopenharmony_ci PIPE_USAGE_STREAM, 96bf215546Sopenharmony_ci svga_render->vbuf_size)); 97bf215546Sopenharmony_ci if (!svga_render->vbuf) { 98bf215546Sopenharmony_ci svga_retry_enter(svga); 99bf215546Sopenharmony_ci svga_context_flush(svga, NULL); 100bf215546Sopenharmony_ci assert(!svga_render->vbuf); 101bf215546Sopenharmony_ci svga_render->vbuf = pipe_buffer_create(screen, 102bf215546Sopenharmony_ci PIPE_BIND_VERTEX_BUFFER, 103bf215546Sopenharmony_ci PIPE_USAGE_STREAM, 104bf215546Sopenharmony_ci svga_render->vbuf_size); 105bf215546Sopenharmony_ci /* The buffer allocation may fail if we run out of memory. 106bf215546Sopenharmony_ci * The draw module's vbuf code should handle that without crashing. 107bf215546Sopenharmony_ci */ 108bf215546Sopenharmony_ci svga_retry_exit(svga); 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci svga->swtnl.new_vdecl = TRUE; 112bf215546Sopenharmony_ci svga_render->vbuf_offset = 0; 113bf215546Sopenharmony_ci } else { 114bf215546Sopenharmony_ci svga_render->vbuf_offset += svga_render->vbuf_used; 115bf215546Sopenharmony_ci } 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci svga_render->vbuf_used = 0; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci if (svga->swtnl.new_vdecl) 120bf215546Sopenharmony_ci svga_render->vdecl_offset = svga_render->vbuf_offset; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci return TRUE; 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_cistatic void * 129bf215546Sopenharmony_cisvga_vbuf_render_map_vertices(struct vbuf_render *render) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 132bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 133bf215546Sopenharmony_ci void * retPtr = NULL; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), 136bf215546Sopenharmony_ci SVGA_STATS_TIME_VBUFRENDERMAPVERT); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci if (svga_render->vbuf) { 139bf215546Sopenharmony_ci char *ptr = (char*)pipe_buffer_map(&svga->pipe, 140bf215546Sopenharmony_ci svga_render->vbuf, 141bf215546Sopenharmony_ci PIPE_MAP_WRITE | 142bf215546Sopenharmony_ci PIPE_MAP_FLUSH_EXPLICIT | 143bf215546Sopenharmony_ci PIPE_MAP_DISCARD_RANGE | 144bf215546Sopenharmony_ci PIPE_MAP_UNSYNCHRONIZED, 145bf215546Sopenharmony_ci &svga_render->vbuf_transfer); 146bf215546Sopenharmony_ci if (ptr) { 147bf215546Sopenharmony_ci svga_render->vbuf_ptr = ptr; 148bf215546Sopenharmony_ci retPtr = ptr + svga_render->vbuf_offset; 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci else { 151bf215546Sopenharmony_ci svga_render->vbuf_ptr = NULL; 152bf215546Sopenharmony_ci svga_render->vbuf_transfer = NULL; 153bf215546Sopenharmony_ci retPtr = NULL; 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci else { 157bf215546Sopenharmony_ci /* we probably ran out of memory when allocating the vertex buffer */ 158bf215546Sopenharmony_ci retPtr = NULL; 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 162bf215546Sopenharmony_ci return retPtr; 163bf215546Sopenharmony_ci} 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_cistatic void 167bf215546Sopenharmony_cisvga_vbuf_render_unmap_vertices(struct vbuf_render *render, 168bf215546Sopenharmony_ci ushort min_index, 169bf215546Sopenharmony_ci ushort max_index) 170bf215546Sopenharmony_ci{ 171bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 172bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 173bf215546Sopenharmony_ci unsigned offset, length; 174bf215546Sopenharmony_ci size_t used = svga_render->vertex_size * ((size_t)max_index + 1); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), 177bf215546Sopenharmony_ci SVGA_STATS_TIME_VBUFRENDERUNMAPVERT); 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index; 180bf215546Sopenharmony_ci length = svga_render->vertex_size * (max_index + 1 - min_index); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci if (0) { 183bf215546Sopenharmony_ci /* dump vertex data */ 184bf215546Sopenharmony_ci const float *f = (const float *) ((char *) svga_render->vbuf_ptr + 185bf215546Sopenharmony_ci svga_render->vbuf_offset); 186bf215546Sopenharmony_ci unsigned i; 187bf215546Sopenharmony_ci debug_printf("swtnl vertex data:\n"); 188bf215546Sopenharmony_ci for (i = 0; i < length / 4; i += 4) { 189bf215546Sopenharmony_ci debug_printf("%u: %f %f %f %f\n", i, f[i], f[i+1], f[i+2], f[i+3]); 190bf215546Sopenharmony_ci } 191bf215546Sopenharmony_ci } 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci pipe_buffer_flush_mapped_range(&svga->pipe, 194bf215546Sopenharmony_ci svga_render->vbuf_transfer, 195bf215546Sopenharmony_ci offset, length); 196bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, svga_render->vbuf_transfer); 197bf215546Sopenharmony_ci svga_render->min_index = min_index; 198bf215546Sopenharmony_ci svga_render->max_index = max_index; 199bf215546Sopenharmony_ci svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used); 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 202bf215546Sopenharmony_ci} 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_cistatic void 206bf215546Sopenharmony_cisvga_vbuf_render_set_primitive(struct vbuf_render *render, 207bf215546Sopenharmony_ci enum pipe_prim_type prim) 208bf215546Sopenharmony_ci{ 209bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 210bf215546Sopenharmony_ci svga_render->prim = prim; 211bf215546Sopenharmony_ci} 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_cistatic void 215bf215546Sopenharmony_cisvga_vbuf_submit_state(struct svga_vbuf_render *svga_render) 216bf215546Sopenharmony_ci{ 217bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 218bf215546Sopenharmony_ci SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS]; 219bf215546Sopenharmony_ci unsigned i; 220bf215546Sopenharmony_ci static const unsigned zero[PIPE_MAX_ATTRIBS] = {0}; 221bf215546Sopenharmony_ci boolean retried; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci /* if the vdecl or vbuf hasn't changed do nothing */ 224bf215546Sopenharmony_ci if (!svga->swtnl.new_vdecl) 225bf215546Sopenharmony_ci return; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), 228bf215546Sopenharmony_ci SVGA_STATS_TIME_VBUFSUBMITSTATE); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci memcpy(vdecl, svga_render->vdecl, sizeof(vdecl)); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci /* flush the hw state */ 233bf215546Sopenharmony_ci SVGA_RETRY_CHECK(svga, svga_hwtnl_flush(svga->hwtnl), retried); 234bf215546Sopenharmony_ci if (retried) { 235bf215546Sopenharmony_ci /* if we hit this path we might become synced with hw */ 236bf215546Sopenharmony_ci svga->swtnl.new_vbuf = TRUE; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci for (i = 0; i < svga_render->vdecl_count; i++) { 240bf215546Sopenharmony_ci vdecl[i].array.offset += svga_render->vdecl_offset; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci svga_hwtnl_vertex_decls(svga->hwtnl, 244bf215546Sopenharmony_ci svga_render->vdecl_count, 245bf215546Sopenharmony_ci vdecl, 246bf215546Sopenharmony_ci zero, 247bf215546Sopenharmony_ci svga_render->layout_id); 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci /* Specify the vertex buffer (there's only ever one) */ 250bf215546Sopenharmony_ci { 251bf215546Sopenharmony_ci struct pipe_vertex_buffer vb; 252bf215546Sopenharmony_ci vb.is_user_buffer = false; 253bf215546Sopenharmony_ci vb.buffer.resource = svga_render->vbuf; 254bf215546Sopenharmony_ci vb.buffer_offset = svga_render->vdecl_offset; 255bf215546Sopenharmony_ci vb.stride = vdecl[0].array.stride; 256bf215546Sopenharmony_ci svga_hwtnl_vertex_buffers(svga->hwtnl, 1, &vb); 257bf215546Sopenharmony_ci } 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci /* We have already taken care of flatshading, so let the hwtnl 260bf215546Sopenharmony_ci * module use whatever is most convenient: 261bf215546Sopenharmony_ci */ 262bf215546Sopenharmony_ci if (svga->state.sw.need_pipeline) { 263bf215546Sopenharmony_ci svga_hwtnl_set_flatshade(svga->hwtnl, FALSE, FALSE); 264bf215546Sopenharmony_ci svga_hwtnl_set_fillmode(svga->hwtnl, PIPE_POLYGON_MODE_FILL); 265bf215546Sopenharmony_ci } 266bf215546Sopenharmony_ci else { 267bf215546Sopenharmony_ci svga_hwtnl_set_flatshade(svga->hwtnl, 268bf215546Sopenharmony_ci svga->curr.rast->templ.flatshade || 269bf215546Sopenharmony_ci svga_is_using_flat_shading(svga), 270bf215546Sopenharmony_ci svga->curr.rast->templ.flatshade_first); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci svga_hwtnl_set_fillmode(svga->hwtnl, svga->curr.rast->hw_fillmode); 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci svga->swtnl.new_vdecl = FALSE; 276bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 277bf215546Sopenharmony_ci} 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_cistatic void 281bf215546Sopenharmony_cisvga_vbuf_render_draw_arrays(struct vbuf_render *render, 282bf215546Sopenharmony_ci unsigned start, uint nr) 283bf215546Sopenharmony_ci{ 284bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 285bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 286bf215546Sopenharmony_ci unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) 287bf215546Sopenharmony_ci / svga_render->vertex_size; 288bf215546Sopenharmony_ci /* instancing will already have been resolved at this point by 'draw' */ 289bf215546Sopenharmony_ci const unsigned start_instance = 0; 290bf215546Sopenharmony_ci const unsigned instance_count = 1; 291bf215546Sopenharmony_ci boolean retried; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_VBUFDRAWARRAYS); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci /* off to hardware */ 296bf215546Sopenharmony_ci svga_vbuf_submit_state(svga_render); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci /* Need to call update_state() again as the draw module may have 299bf215546Sopenharmony_ci * altered some of our state behind our backs. Testcase: 300bf215546Sopenharmony_ci * redbook/polys.c 301bf215546Sopenharmony_ci */ 302bf215546Sopenharmony_ci svga_update_state_retry(svga, SVGA_STATE_HW_DRAW); 303bf215546Sopenharmony_ci SVGA_RETRY_CHECK(svga, svga_hwtnl_draw_arrays 304bf215546Sopenharmony_ci (svga->hwtnl, svga_render->prim, start + bias, 305bf215546Sopenharmony_ci nr, start_instance, instance_count, 0), retried); 306bf215546Sopenharmony_ci if (retried) { 307bf215546Sopenharmony_ci svga->swtnl.new_vbuf = TRUE; 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 311bf215546Sopenharmony_ci} 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_cistatic void 315bf215546Sopenharmony_cisvga_vbuf_render_draw_elements(struct vbuf_render *render, 316bf215546Sopenharmony_ci const ushort *indices, 317bf215546Sopenharmony_ci uint nr_indices) 318bf215546Sopenharmony_ci{ 319bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 320bf215546Sopenharmony_ci struct svga_context *svga = svga_render->svga; 321bf215546Sopenharmony_ci int bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) 322bf215546Sopenharmony_ci / svga_render->vertex_size; 323bf215546Sopenharmony_ci boolean retried; 324bf215546Sopenharmony_ci /* instancing will already have been resolved at this point by 'draw' */ 325bf215546Sopenharmony_ci const struct pipe_draw_info info = { 326bf215546Sopenharmony_ci .index_size = 2, 327bf215546Sopenharmony_ci .mode = svga_render->prim, 328bf215546Sopenharmony_ci .has_user_indices = 1, 329bf215546Sopenharmony_ci .index.user = indices, 330bf215546Sopenharmony_ci .start_instance = 0, 331bf215546Sopenharmony_ci .instance_count = 1, 332bf215546Sopenharmony_ci .index_bounds_valid = true, 333bf215546Sopenharmony_ci .min_index = svga_render->min_index, 334bf215546Sopenharmony_ci .max_index = svga_render->max_index, 335bf215546Sopenharmony_ci }; 336bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias draw = { 337bf215546Sopenharmony_ci .start = 0, 338bf215546Sopenharmony_ci .count = nr_indices, 339bf215546Sopenharmony_ci .index_bias = bias, 340bf215546Sopenharmony_ci }; 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci assert((svga_render->vbuf_offset - svga_render->vdecl_offset) 343bf215546Sopenharmony_ci % svga_render->vertex_size == 0); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_VBUFDRAWELEMENTS); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci /* off to hardware */ 348bf215546Sopenharmony_ci svga_vbuf_submit_state(svga_render); 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci /* Need to call update_state() again as the draw module may have 351bf215546Sopenharmony_ci * altered some of our state behind our backs. Testcase: 352bf215546Sopenharmony_ci * redbook/polys.c 353bf215546Sopenharmony_ci */ 354bf215546Sopenharmony_ci svga_update_state_retry(svga, SVGA_STATE_HW_DRAW); 355bf215546Sopenharmony_ci SVGA_RETRY_CHECK(svga, svga_hwtnl_draw_range_elements(svga->hwtnl, &info, 356bf215546Sopenharmony_ci &draw, 357bf215546Sopenharmony_ci nr_indices), retried); 358bf215546Sopenharmony_ci if (retried) { 359bf215546Sopenharmony_ci svga->swtnl.new_vbuf = TRUE; 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 363bf215546Sopenharmony_ci} 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_cistatic void 367bf215546Sopenharmony_cisvga_vbuf_render_release_vertices(struct vbuf_render *render) 368bf215546Sopenharmony_ci{ 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci} 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_cistatic void 374bf215546Sopenharmony_cisvga_vbuf_render_destroy(struct vbuf_render *render) 375bf215546Sopenharmony_ci{ 376bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = svga_vbuf_render(render); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci pipe_resource_reference(&svga_render->vbuf, NULL); 379bf215546Sopenharmony_ci pipe_resource_reference(&svga_render->ibuf, NULL); 380bf215546Sopenharmony_ci FREE(svga_render); 381bf215546Sopenharmony_ci} 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci/** 385bf215546Sopenharmony_ci * Create a new primitive render. 386bf215546Sopenharmony_ci */ 387bf215546Sopenharmony_cistruct vbuf_render * 388bf215546Sopenharmony_cisvga_vbuf_render_create(struct svga_context *svga) 389bf215546Sopenharmony_ci{ 390bf215546Sopenharmony_ci struct svga_vbuf_render *svga_render = CALLOC_STRUCT(svga_vbuf_render); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci svga_render->svga = svga; 393bf215546Sopenharmony_ci svga_render->ibuf_size = 0; 394bf215546Sopenharmony_ci svga_render->vbuf_size = 0; 395bf215546Sopenharmony_ci svga_render->ibuf_alloc_size = 4*1024; 396bf215546Sopenharmony_ci svga_render->vbuf_alloc_size = 64*1024; 397bf215546Sopenharmony_ci svga_render->layout_id = SVGA3D_INVALID_ID; 398bf215546Sopenharmony_ci svga_render->base.max_vertex_buffer_bytes = 64*1024/10; 399bf215546Sopenharmony_ci svga_render->base.max_indices = 65536; 400bf215546Sopenharmony_ci svga_render->base.get_vertex_info = svga_vbuf_render_get_vertex_info; 401bf215546Sopenharmony_ci svga_render->base.allocate_vertices = svga_vbuf_render_allocate_vertices; 402bf215546Sopenharmony_ci svga_render->base.map_vertices = svga_vbuf_render_map_vertices; 403bf215546Sopenharmony_ci svga_render->base.unmap_vertices = svga_vbuf_render_unmap_vertices; 404bf215546Sopenharmony_ci svga_render->base.set_primitive = svga_vbuf_render_set_primitive; 405bf215546Sopenharmony_ci svga_render->base.draw_elements = svga_vbuf_render_draw_elements; 406bf215546Sopenharmony_ci svga_render->base.draw_arrays = svga_vbuf_render_draw_arrays; 407bf215546Sopenharmony_ci svga_render->base.release_vertices = svga_vbuf_render_release_vertices; 408bf215546Sopenharmony_ci svga_render->base.destroy = svga_vbuf_render_destroy; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci return &svga_render->base; 411bf215546Sopenharmony_ci} 412