1/********************************************************** 2 * Copyright 2008-2009 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26#include "svga_cmd.h" 27 28#include "pipe/p_defines.h" 29#include "util/u_inlines.h" 30#include "pipe/p_screen.h" 31#include "util/u_memory.h" 32#include "util/u_bitmask.h" 33#include "util/u_upload_mgr.h" 34 35#include "svga_context.h" 36#include "svga_screen.h" 37#include "svga_surface.h" 38#include "svga_resource_texture.h" 39#include "svga_resource_buffer.h" 40#include "svga_resource.h" 41#include "svga_winsys.h" 42#include "svga_swtnl.h" 43#include "svga_draw.h" 44#include "svga_debug.h" 45#include "svga_state.h" 46#include "svga_winsys.h" 47#include "svga_streamout.h" 48 49#define CONST0_UPLOAD_DEFAULT_SIZE 65536 50 51DEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE) 52DEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE); 53DEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE); 54DEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE); 55DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE); 56 57 58static void 59svga_destroy(struct pipe_context *pipe) 60{ 61 struct svga_context *svga = svga_context(pipe); 62 unsigned shader, i; 63 64 /* free any alternate rasterizer states used for point sprite */ 65 for (i = 0; i < ARRAY_SIZE(svga->rasterizer_no_cull); i++) { 66 if (svga->rasterizer_no_cull[i]) { 67 pipe->delete_rasterizer_state(pipe, svga->rasterizer_no_cull[i]); 68 } 69 } 70 71 /* free depthstencil_disable state */ 72 if (svga->depthstencil_disable) { 73 pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable); 74 } 75 76 /* free HW constant buffers */ 77 for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) { 78 for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.constbuf[0]); i++) { 79 pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][i], NULL); 80 } 81 } 82 83 pipe->delete_blend_state(pipe, svga->noop_blend); 84 85 /* destroy stream output statistics queries */ 86 svga_destroy_stream_output_queries(svga); 87 88 /* free query gb object */ 89 if (svga->gb_query) { 90 pipe->destroy_query(pipe, NULL); 91 svga->gb_query = NULL; 92 } 93 94 util_blitter_destroy(svga->blitter); 95 96 svga_cleanup_sampler_state(svga); 97 svga_cleanup_framebuffer(svga); 98 svga_cleanup_tss_binding(svga); 99 svga_cleanup_vertex_state(svga); 100 svga_cleanup_tcs_state(svga); 101 102 svga_destroy_swtnl(svga); 103 svga_hwtnl_destroy(svga->hwtnl); 104 105 svga->swc->destroy(svga->swc); 106 107 util_bitmask_destroy(svga->blend_object_id_bm); 108 util_bitmask_destroy(svga->ds_object_id_bm); 109 util_bitmask_destroy(svga->input_element_object_id_bm); 110 util_bitmask_destroy(svga->rast_object_id_bm); 111 util_bitmask_destroy(svga->sampler_object_id_bm); 112 util_bitmask_destroy(svga->sampler_view_id_bm); 113 util_bitmask_destroy(svga->shader_id_bm); 114 util_bitmask_destroy(svga->surface_view_id_bm); 115 util_bitmask_destroy(svga->stream_output_id_bm); 116 util_bitmask_destroy(svga->query_id_bm); 117 u_upload_destroy(svga->const0_upload); 118 u_upload_destroy(svga->pipe.stream_uploader); 119 u_upload_destroy(svga->pipe.const_uploader); 120 svga_texture_transfer_map_upload_destroy(svga); 121 122 /* free user's constant buffers */ 123 for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) { 124 for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) { 125 pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL); 126 } 127 } 128 129 FREE(svga); 130} 131 132 133struct pipe_context * 134svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags) 135{ 136 struct svga_screen *svgascreen = svga_screen(screen); 137 struct svga_context *svga = NULL; 138 enum pipe_error ret; 139 140 SVGA_STATS_TIME_PUSH(svgascreen->sws, SVGA_STATS_TIME_CREATECONTEXT); 141 142 svga = CALLOC_STRUCT(svga_context); 143 if (!svga) 144 goto done; 145 146 list_inithead(&svga->dirty_buffers); 147 148 svga->pipe.screen = screen; 149 svga->pipe.priv = priv; 150 svga->pipe.destroy = svga_destroy; 151 svga->pipe.stream_uploader = u_upload_create(&svga->pipe, 1024 * 1024, 152 PIPE_BIND_VERTEX_BUFFER | 153 PIPE_BIND_INDEX_BUFFER, 154 PIPE_USAGE_STREAM, 0); 155 if (!svga->pipe.stream_uploader) 156 goto cleanup; 157 158 u_upload_disable_persistent(svga->pipe.stream_uploader); 159 160 svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024, 161 PIPE_BIND_CONSTANT_BUFFER, 162 PIPE_USAGE_STREAM, 0); 163 if (!svga->pipe.const_uploader) 164 goto cleanup; 165 166 u_upload_disable_persistent(svga->pipe.const_uploader); 167 168 svga->swc = svgascreen->sws->context_create(svgascreen->sws); 169 if (!svga->swc) 170 goto cleanup; 171 172 svga_init_resource_functions(svga); 173 svga_init_blend_functions(svga); 174 svga_init_blit_functions(svga); 175 svga_init_depth_stencil_functions(svga); 176 svga_init_draw_functions(svga); 177 svga_init_flush_functions(svga); 178 svga_init_misc_functions(svga); 179 svga_init_rasterizer_functions(svga); 180 svga_init_sampler_functions(svga); 181 svga_init_fs_functions(svga); 182 svga_init_vs_functions(svga); 183 svga_init_gs_functions(svga); 184 svga_init_ts_functions(svga); 185 svga_init_vertex_functions(svga); 186 svga_init_constbuffer_functions(svga); 187 svga_init_query_functions(svga); 188 svga_init_surface_functions(svga); 189 svga_init_stream_output_functions(svga); 190 svga_init_clear_functions(svga); 191 svga_init_tracked_state(svga); 192 193 /* init misc state */ 194 svga->curr.sample_mask = ~0; 195 196 /* debug */ 197 svga->debug.no_swtnl = debug_get_option_no_swtnl(); 198 svga->debug.force_swtnl = debug_get_option_force_swtnl(); 199 svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap(); 200 svga->debug.no_line_width = debug_get_option_no_line_width(); 201 svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple(); 202 203 if (!(svga->blend_object_id_bm = util_bitmask_create())) 204 goto cleanup; 205 206 if (!(svga->ds_object_id_bm = util_bitmask_create())) 207 goto cleanup; 208 209 if (!(svga->input_element_object_id_bm = util_bitmask_create())) 210 goto cleanup; 211 212 if (!(svga->rast_object_id_bm = util_bitmask_create())) 213 goto cleanup; 214 215 if (!(svga->sampler_object_id_bm = util_bitmask_create())) 216 goto cleanup; 217 218 if (!(svga->sampler_view_id_bm = util_bitmask_create())) 219 goto cleanup; 220 221 if (!(svga->shader_id_bm = util_bitmask_create())) 222 goto cleanup; 223 224 if (!(svga->surface_view_id_bm = util_bitmask_create())) 225 goto cleanup; 226 227 if (!(svga->stream_output_id_bm = util_bitmask_create())) 228 goto cleanup; 229 230 if (!(svga->query_id_bm = util_bitmask_create())) 231 goto cleanup; 232 233 svga->hwtnl = svga_hwtnl_create(svga); 234 if (svga->hwtnl == NULL) 235 goto cleanup; 236 237 if (!svga_init_swtnl(svga)) 238 goto cleanup; 239 240 ret = svga_emit_initial_state(svga); 241 if (ret != PIPE_OK) 242 goto cleanup; 243 244 svga->const0_upload = u_upload_create(&svga->pipe, 245 CONST0_UPLOAD_DEFAULT_SIZE, 246 PIPE_BIND_CONSTANT_BUFFER | 247 PIPE_BIND_CUSTOM, 248 PIPE_USAGE_STREAM, 0); 249 if (!svga->const0_upload) 250 goto cleanup; 251 252 u_upload_disable_persistent(svga->const0_upload); 253 254 if (!svga_texture_transfer_map_upload_create(svga)) 255 goto cleanup; 256 257 /* Avoid shortcircuiting state with initial value of zero. 258 */ 259 memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear)); 260 memset(&svga->state.hw_clear.framebuffer, 0x0, 261 sizeof(svga->state.hw_clear.framebuffer)); 262 memset(&svga->state.hw_clear.rtv, 0, sizeof(svga->state.hw_clear.rtv)); 263 svga->state.hw_clear.num_rendertargets = 0; 264 svga->state.hw_clear.dsv = NULL; 265 266 memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw)); 267 memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views)); 268 memset(&svga->state.hw_draw.num_samplers, 0, 269 sizeof(svga->state.hw_draw.num_samplers)); 270 memset(&svga->state.hw_draw.num_sampler_views, 0, 271 sizeof(svga->state.hw_draw.num_sampler_views)); 272 memset(svga->state.hw_draw.sampler_views, 0, 273 sizeof(svga->state.hw_draw.sampler_views)); 274 svga->state.hw_draw.num_views = 0; 275 svga->state.hw_draw.num_backed_views = 0; 276 svga->state.hw_draw.rasterizer_discard = FALSE; 277 278 /* Initialize the shader pointers */ 279 svga->state.hw_draw.vs = NULL; 280 svga->state.hw_draw.gs = NULL; 281 svga->state.hw_draw.fs = NULL; 282 svga->state.hw_draw.tcs = NULL; 283 svga->state.hw_draw.tes = NULL; 284 285 /* Initialize the currently bound buffer resources */ 286 memset(svga->state.hw_draw.constbuf, 0, 287 sizeof(svga->state.hw_draw.constbuf)); 288 memset(svga->state.hw_draw.default_constbuf_size, 0, 289 sizeof(svga->state.hw_draw.default_constbuf_size)); 290 memset(svga->state.hw_draw.enabled_constbufs, 0, 291 sizeof(svga->state.hw_draw.enabled_constbufs)); 292 svga->state.hw_draw.ib = NULL; 293 svga->state.hw_draw.num_vbuffers = 0; 294 memset(svga->state.hw_draw.vbuffers, 0, 295 sizeof(svga->state.hw_draw.vbuffers)); 296 svga->state.hw_draw.const0_buffer = NULL; 297 svga->state.hw_draw.const0_handle = NULL; 298 299 /* Create a no-operation blend state which we will bind whenever the 300 * requested blend state is impossible (e.g. due to having an integer 301 * render target attached). 302 * 303 * XXX: We will probably actually need 16 of these, one for each possible 304 * RGBA color mask (4 bits). Then, we would bind the one with a color mask 305 * matching the blend state it is replacing. 306 */ 307 { 308 struct pipe_blend_state noop_tmpl = {0}; 309 unsigned i; 310 311 for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) { 312 // Set the color mask to all-ones. Later this may change. 313 noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA; 314 } 315 svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl); 316 } 317 318 svga->dirty = SVGA_NEW_ALL; 319 svga->pred.query_id = SVGA3D_INVALID_ID; 320 svga->disable_rasterizer = FALSE; 321 322 /** 323 * Create stream output statistics queries used in the workaround for auto 324 * draw with stream instancing. 325 */ 326 svga_create_stream_output_queries(svga); 327 328 goto done; 329 330cleanup: 331 svga_destroy_swtnl(svga); 332 333 if (svga->const0_upload) 334 u_upload_destroy(svga->const0_upload); 335 if (svga->pipe.const_uploader) 336 u_upload_destroy(svga->pipe.const_uploader); 337 if (svga->pipe.stream_uploader) 338 u_upload_destroy(svga->pipe.stream_uploader); 339 svga_texture_transfer_map_upload_destroy(svga); 340 if (svga->hwtnl) 341 svga_hwtnl_destroy(svga->hwtnl); 342 if (svga->swc) 343 svga->swc->destroy(svga->swc); 344 util_bitmask_destroy(svga->blend_object_id_bm); 345 util_bitmask_destroy(svga->ds_object_id_bm); 346 util_bitmask_destroy(svga->input_element_object_id_bm); 347 util_bitmask_destroy(svga->rast_object_id_bm); 348 util_bitmask_destroy(svga->sampler_object_id_bm); 349 util_bitmask_destroy(svga->sampler_view_id_bm); 350 util_bitmask_destroy(svga->shader_id_bm); 351 util_bitmask_destroy(svga->surface_view_id_bm); 352 util_bitmask_destroy(svga->stream_output_id_bm); 353 util_bitmask_destroy(svga->query_id_bm); 354 FREE(svga); 355 svga = NULL; 356 357done: 358 SVGA_STATS_TIME_POP(svgascreen->sws); 359 return svga ? &svga->pipe:NULL; 360} 361 362 363void 364svga_context_flush(struct svga_context *svga, 365 struct pipe_fence_handle **pfence) 366{ 367 struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); 368 struct pipe_fence_handle *fence = NULL; 369 uint64_t t0; 370 371 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH); 372 373 svga->curr.nr_fbs = 0; 374 375 /* Unmap the 0th/default constant buffer. The u_upload_unmap() function 376 * will call pipe_context::transfer_flush_region() to indicate the 377 * region of the buffer which was modified (and needs to be uploaded). 378 */ 379 if (svga->state.hw_draw.const0_handle) { 380 assert(svga->state.hw_draw.const0_buffer); 381 u_upload_unmap(svga->const0_upload); 382 pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL); 383 svga->state.hw_draw.const0_handle = NULL; 384 } 385 386 /* Ensure that texture dma uploads are processed 387 * before submitting commands. 388 */ 389 svga_context_flush_buffers(svga); 390 391 svga->hud.command_buffer_size += 392 svga->swc->get_command_buffer_size(svga->swc); 393 394 /* Flush pending commands to hardware: 395 */ 396 t0 = svga_get_time(svga); 397 svga->swc->flush(svga->swc, &fence); 398 svga->hud.flush_time += (svga_get_time(svga) - t0); 399 400 svga->hud.num_flushes++; 401 402 svga_screen_cache_flush(svgascreen, svga, fence); 403 404 SVGA3D_ResetLastCommand(svga->swc); 405 406 /* To force the re-emission of rendertargets and texture sampler bindings on 407 * the next command buffer. 408 */ 409 svga->rebind.flags.rendertargets = TRUE; 410 svga->rebind.flags.texture_samplers = TRUE; 411 412 if (svga_have_gb_objects(svga)) { 413 414 svga->rebind.flags.constbufs = TRUE; 415 svga->rebind.flags.vs = TRUE; 416 svga->rebind.flags.fs = TRUE; 417 svga->rebind.flags.gs = TRUE; 418 419 if (svga_have_sm5(svga)) { 420 svga->rebind.flags.tcs = TRUE; 421 svga->rebind.flags.tes = TRUE; 422 } 423 424 if (svga_need_to_rebind_resources(svga)) { 425 svga->rebind.flags.query = TRUE; 426 } 427 } 428 429 if (SVGA_DEBUG & DEBUG_SYNC) { 430 if (fence) 431 svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence, 432 PIPE_TIMEOUT_INFINITE); 433 } 434 435 if (pfence) 436 svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence); 437 438 svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); 439 440 SVGA_STATS_TIME_POP(svga_sws(svga)); 441} 442 443 444/** 445 * Flush pending commands and wait for completion with a fence. 446 */ 447void 448svga_context_finish(struct svga_context *svga) 449{ 450 struct pipe_screen *screen = svga->pipe.screen; 451 struct pipe_fence_handle *fence = NULL; 452 453 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH); 454 455 svga_context_flush(svga, &fence); 456 screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); 457 screen->fence_reference(screen, &fence, NULL); 458 459 SVGA_STATS_TIME_POP(svga_sws(svga)); 460} 461 462 463/** 464 * Emit pending drawing commands to the command buffer. 465 * If the command buffer overflows, we flush it and retry. 466 * \sa svga_hwtnl_flush() 467 */ 468void 469svga_hwtnl_flush_retry(struct svga_context *svga) 470{ 471 enum pipe_error ret = PIPE_OK; 472 473 SVGA_RETRY_OOM(svga, ret, svga_hwtnl_flush(svga->hwtnl)); 474 assert(ret == PIPE_OK); 475} 476 477 478/** 479 * Flush the primitive queue if this buffer is referred. 480 * 481 * Otherwise DMA commands on the referred buffer will be emitted too late. 482 */ 483void 484svga_hwtnl_flush_buffer(struct svga_context *svga, 485 struct pipe_resource *buffer) 486{ 487 if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) { 488 svga_hwtnl_flush_retry(svga); 489 } 490} 491 492 493/** 494 * Emit all operations pending on host surfaces. 495 */ 496void 497svga_surfaces_flush(struct svga_context *svga) 498{ 499 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH); 500 501 /* Emit buffered drawing commands. 502 */ 503 svga_hwtnl_flush_retry(svga); 504 505 /* Emit back-copy from render target views to textures. 506 */ 507 svga_propagate_rendertargets(svga); 508 509 SVGA_STATS_TIME_POP(svga_sws(svga)); 510} 511 512 513struct svga_winsys_context * 514svga_winsys_context(struct pipe_context *pipe) 515{ 516 return svga_context(pipe)->swc; 517} 518