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 48#define CONST0_UPLOAD_DEFAULT_SIZE 65536 49 50DEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE) 51DEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE); 52DEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE); 53DEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE); 54DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE); 55 56 57static void 58svga_destroy(struct pipe_context *pipe) 59{ 60 struct svga_context *svga = svga_context(pipe); 61 unsigned shader, i; 62 63 /* free any alternate rasterizer states used for point sprite */ 64 for (i = 0; i < ARRAY_SIZE(svga->rasterizer_no_cull); i++) { 65 if (svga->rasterizer_no_cull[i]) { 66 pipe->delete_rasterizer_state(pipe, svga->rasterizer_no_cull[i]); 67 } 68 } 69 70 /* free depthstencil_disable state */ 71 if (svga->depthstencil_disable) { 72 pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable); 73 } 74 75 /* free HW constant buffers */ 76 for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) { 77 pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], NULL); 78 } 79 80 pipe->delete_blend_state(pipe, svga->noop_blend); 81 82 /* free query gb object */ 83 if (svga->gb_query) { 84 pipe->destroy_query(pipe, NULL); 85 svga->gb_query = NULL; 86 } 87 88 util_blitter_destroy(svga->blitter); 89 90 svga_cleanup_sampler_state(svga); 91 svga_cleanup_framebuffer(svga); 92 svga_cleanup_tss_binding(svga); 93 svga_cleanup_vertex_state(svga); 94 95 svga_destroy_swtnl(svga); 96 svga_hwtnl_destroy(svga->hwtnl); 97 98 svga->swc->destroy(svga->swc); 99 100 util_bitmask_destroy(svga->blend_object_id_bm); 101 util_bitmask_destroy(svga->ds_object_id_bm); 102 util_bitmask_destroy(svga->input_element_object_id_bm); 103 util_bitmask_destroy(svga->rast_object_id_bm); 104 util_bitmask_destroy(svga->sampler_object_id_bm); 105 util_bitmask_destroy(svga->sampler_view_id_bm); 106 util_bitmask_destroy(svga->shader_id_bm); 107 util_bitmask_destroy(svga->surface_view_id_bm); 108 util_bitmask_destroy(svga->stream_output_id_bm); 109 util_bitmask_destroy(svga->query_id_bm); 110 u_upload_destroy(svga->const0_upload); 111 u_upload_destroy(svga->pipe.stream_uploader); 112 u_upload_destroy(svga->pipe.const_uploader); 113 svga_texture_transfer_map_upload_destroy(svga); 114 115 /* free user's constant buffers */ 116 for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) { 117 for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) { 118 pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL); 119 } 120 } 121 122 FREE(svga); 123} 124 125 126struct pipe_context * 127svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags) 128{ 129 struct svga_screen *svgascreen = svga_screen(screen); 130 struct svga_context *svga = NULL; 131 enum pipe_error ret; 132 133 SVGA_STATS_TIME_PUSH(svgascreen->sws, SVGA_STATS_TIME_CREATECONTEXT); 134 135 svga = CALLOC_STRUCT(svga_context); 136 if (!svga) 137 goto done; 138 139 LIST_INITHEAD(&svga->dirty_buffers); 140 141 svga->pipe.screen = screen; 142 svga->pipe.priv = priv; 143 svga->pipe.destroy = svga_destroy; 144 svga->pipe.stream_uploader = u_upload_create(&svga->pipe, 1024 * 1024, 145 PIPE_BIND_VERTEX_BUFFER | 146 PIPE_BIND_INDEX_BUFFER, 147 PIPE_USAGE_STREAM, 0); 148 if (!svga->pipe.stream_uploader) 149 goto cleanup; 150 151 svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024, 152 PIPE_BIND_CONSTANT_BUFFER, 153 PIPE_USAGE_STREAM, 0); 154 if (!svga->pipe.const_uploader) 155 goto cleanup; 156 157 svga->swc = svgascreen->sws->context_create(svgascreen->sws); 158 if (!svga->swc) 159 goto cleanup; 160 161 svga_init_resource_functions(svga); 162 svga_init_blend_functions(svga); 163 svga_init_blit_functions(svga); 164 svga_init_depth_stencil_functions(svga); 165 svga_init_draw_functions(svga); 166 svga_init_flush_functions(svga); 167 svga_init_misc_functions(svga); 168 svga_init_rasterizer_functions(svga); 169 svga_init_sampler_functions(svga); 170 svga_init_fs_functions(svga); 171 svga_init_vs_functions(svga); 172 svga_init_gs_functions(svga); 173 svga_init_vertex_functions(svga); 174 svga_init_constbuffer_functions(svga); 175 svga_init_query_functions(svga); 176 svga_init_surface_functions(svga); 177 svga_init_stream_output_functions(svga); 178 svga_init_clear_functions(svga); 179 180 /* init misc state */ 181 svga->curr.sample_mask = ~0; 182 183 /* debug */ 184 svga->debug.no_swtnl = debug_get_option_no_swtnl(); 185 svga->debug.force_swtnl = debug_get_option_force_swtnl(); 186 svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap(); 187 svga->debug.no_line_width = debug_get_option_no_line_width(); 188 svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple(); 189 190 if (!(svga->blend_object_id_bm = util_bitmask_create())) 191 goto cleanup; 192 193 if (!(svga->ds_object_id_bm = util_bitmask_create())) 194 goto cleanup; 195 196 if (!(svga->input_element_object_id_bm = util_bitmask_create())) 197 goto cleanup; 198 199 if (!(svga->rast_object_id_bm = util_bitmask_create())) 200 goto cleanup; 201 202 if (!(svga->sampler_object_id_bm = util_bitmask_create())) 203 goto cleanup; 204 205 if (!(svga->sampler_view_id_bm = util_bitmask_create())) 206 goto cleanup; 207 208 if (!(svga->shader_id_bm = util_bitmask_create())) 209 goto cleanup; 210 211 if (!(svga->surface_view_id_bm = util_bitmask_create())) 212 goto cleanup; 213 214 if (!(svga->stream_output_id_bm = util_bitmask_create())) 215 goto cleanup; 216 217 if (!(svga->query_id_bm = util_bitmask_create())) 218 goto cleanup; 219 220 svga->hwtnl = svga_hwtnl_create(svga); 221 if (svga->hwtnl == NULL) 222 goto cleanup; 223 224 if (!svga_init_swtnl(svga)) 225 goto cleanup; 226 227 ret = svga_emit_initial_state(svga); 228 if (ret != PIPE_OK) 229 goto cleanup; 230 231 svga->const0_upload = u_upload_create(&svga->pipe, 232 CONST0_UPLOAD_DEFAULT_SIZE, 233 PIPE_BIND_CONSTANT_BUFFER | 234 PIPE_BIND_CUSTOM, 235 PIPE_USAGE_STREAM, 0); 236 if (!svga->const0_upload) 237 goto cleanup; 238 239 if (!svga_texture_transfer_map_upload_create(svga)) 240 goto cleanup; 241 242 /* Avoid shortcircuiting state with initial value of zero. 243 */ 244 memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear)); 245 memset(&svga->state.hw_clear.framebuffer, 0x0, 246 sizeof(svga->state.hw_clear.framebuffer)); 247 svga->state.hw_clear.num_rendertargets = 0; 248 svga->state.hw_clear.dsv = NULL; 249 250 memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw)); 251 memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views)); 252 memset(&svga->state.hw_draw.num_samplers, 0, 253 sizeof(svga->state.hw_draw.num_samplers)); 254 memset(&svga->state.hw_draw.num_sampler_views, 0, 255 sizeof(svga->state.hw_draw.num_sampler_views)); 256 memset(svga->state.hw_draw.sampler_views, 0, 257 sizeof(svga->state.hw_draw.sampler_views)); 258 svga->state.hw_draw.num_views = 0; 259 svga->state.hw_draw.num_backed_views = 0; 260 svga->state.hw_draw.rasterizer_discard = FALSE; 261 262 /* Initialize the shader pointers */ 263 svga->state.hw_draw.vs = NULL; 264 svga->state.hw_draw.gs = NULL; 265 svga->state.hw_draw.fs = NULL; 266 267 /* Initialize the currently bound buffer resources */ 268 memset(svga->state.hw_draw.constbuf, 0, 269 sizeof(svga->state.hw_draw.constbuf)); 270 memset(svga->state.hw_draw.default_constbuf_size, 0, 271 sizeof(svga->state.hw_draw.default_constbuf_size)); 272 memset(svga->state.hw_draw.enabled_constbufs, 0, 273 sizeof(svga->state.hw_draw.enabled_constbufs)); 274 svga->state.hw_draw.ib = NULL; 275 svga->state.hw_draw.num_vbuffers = 0; 276 memset(svga->state.hw_draw.vbuffers, 0, 277 sizeof(svga->state.hw_draw.vbuffers)); 278 svga->state.hw_draw.const0_buffer = NULL; 279 svga->state.hw_draw.const0_handle = NULL; 280 281 /* Create a no-operation blend state which we will bind whenever the 282 * requested blend state is impossible (e.g. due to having an integer 283 * render target attached). 284 * 285 * XXX: We will probably actually need 16 of these, one for each possible 286 * RGBA color mask (4 bits). Then, we would bind the one with a color mask 287 * matching the blend state it is replacing. 288 */ 289 { 290 struct pipe_blend_state noop_tmpl = {0}; 291 unsigned i; 292 293 for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) { 294 // Set the color mask to all-ones. Later this may change. 295 noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA; 296 } 297 svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl); 298 } 299 300 svga->dirty = ~0; 301 svga->pred.query_id = SVGA3D_INVALID_ID; 302 svga->disable_rasterizer = FALSE; 303 304 goto done; 305 306cleanup: 307 svga_destroy_swtnl(svga); 308 309 if (svga->const0_upload) 310 u_upload_destroy(svga->const0_upload); 311 if (svga->pipe.const_uploader) 312 u_upload_destroy(svga->pipe.const_uploader); 313 if (svga->pipe.stream_uploader) 314 u_upload_destroy(svga->pipe.stream_uploader); 315 svga_texture_transfer_map_upload_destroy(svga); 316 if (svga->hwtnl) 317 svga_hwtnl_destroy(svga->hwtnl); 318 if (svga->swc) 319 svga->swc->destroy(svga->swc); 320 util_bitmask_destroy(svga->blend_object_id_bm); 321 util_bitmask_destroy(svga->ds_object_id_bm); 322 util_bitmask_destroy(svga->input_element_object_id_bm); 323 util_bitmask_destroy(svga->rast_object_id_bm); 324 util_bitmask_destroy(svga->sampler_object_id_bm); 325 util_bitmask_destroy(svga->sampler_view_id_bm); 326 util_bitmask_destroy(svga->shader_id_bm); 327 util_bitmask_destroy(svga->surface_view_id_bm); 328 util_bitmask_destroy(svga->stream_output_id_bm); 329 util_bitmask_destroy(svga->query_id_bm); 330 FREE(svga); 331 svga = NULL; 332 333done: 334 SVGA_STATS_TIME_POP(svgascreen->sws); 335 return svga ? &svga->pipe:NULL; 336} 337 338 339void 340svga_context_flush(struct svga_context *svga, 341 struct pipe_fence_handle **pfence) 342{ 343 struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); 344 struct pipe_fence_handle *fence = NULL; 345 uint64_t t0; 346 347 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH); 348 349 svga->curr.nr_fbs = 0; 350 351 /* Unmap the 0th/default constant buffer. The u_upload_unmap() function 352 * will call pipe_context::transfer_flush_region() to indicate the 353 * region of the buffer which was modified (and needs to be uploaded). 354 */ 355 if (svga->state.hw_draw.const0_handle) { 356 assert(svga->state.hw_draw.const0_buffer); 357 u_upload_unmap(svga->const0_upload); 358 pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL); 359 svga->state.hw_draw.const0_handle = NULL; 360 } 361 362 /* Ensure that texture dma uploads are processed 363 * before submitting commands. 364 */ 365 svga_context_flush_buffers(svga); 366 367 svga->hud.command_buffer_size += 368 svga->swc->get_command_buffer_size(svga->swc); 369 370 /* Flush pending commands to hardware: 371 */ 372 t0 = svga_get_time(svga); 373 svga->swc->flush(svga->swc, &fence); 374 svga->hud.flush_time += (svga_get_time(svga) - t0); 375 376 svga->hud.num_flushes++; 377 378 svga_screen_cache_flush(svgascreen, svga, fence); 379 380 SVGA3D_ResetLastCommand(svga->swc); 381 382 /* To force the re-emission of rendertargets and texture sampler bindings on 383 * the next command buffer. 384 */ 385 svga->rebind.flags.rendertargets = TRUE; 386 svga->rebind.flags.texture_samplers = TRUE; 387 388 if (svga_have_gb_objects(svga)) { 389 390 svga->rebind.flags.constbufs = TRUE; 391 svga->rebind.flags.vs = TRUE; 392 svga->rebind.flags.fs = TRUE; 393 svga->rebind.flags.gs = TRUE; 394 395 if (svga_need_to_rebind_resources(svga)) { 396 svga->rebind.flags.query = TRUE; 397 } 398 } 399 400 if (SVGA_DEBUG & DEBUG_SYNC) { 401 if (fence) 402 svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence, 403 PIPE_TIMEOUT_INFINITE); 404 } 405 406 if (pfence) 407 svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence); 408 409 svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); 410 411 SVGA_STATS_TIME_POP(svga_sws(svga)); 412} 413 414 415/** 416 * Flush pending commands and wait for completion with a fence. 417 */ 418void 419svga_context_finish(struct svga_context *svga) 420{ 421 struct pipe_screen *screen = svga->pipe.screen; 422 struct pipe_fence_handle *fence = NULL; 423 424 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH); 425 426 svga_context_flush(svga, &fence); 427 screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); 428 screen->fence_reference(screen, &fence, NULL); 429 430 SVGA_STATS_TIME_POP(svga_sws(svga)); 431} 432 433 434/** 435 * Emit pending drawing commands to the command buffer. 436 * If the command buffer overflows, we flush it and retry. 437 * \sa svga_hwtnl_flush() 438 */ 439void 440svga_hwtnl_flush_retry(struct svga_context *svga) 441{ 442 enum pipe_error ret = PIPE_OK; 443 444 ret = svga_hwtnl_flush(svga->hwtnl); 445 if (ret == PIPE_ERROR_OUT_OF_MEMORY) { 446 svga_context_flush(svga, NULL); 447 ret = svga_hwtnl_flush(svga->hwtnl); 448 } 449 450 assert(ret == PIPE_OK); 451} 452 453 454/** 455 * Flush the primitive queue if this buffer is referred. 456 * 457 * Otherwise DMA commands on the referred buffer will be emitted too late. 458 */ 459void 460svga_hwtnl_flush_buffer(struct svga_context *svga, 461 struct pipe_resource *buffer) 462{ 463 if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) { 464 svga_hwtnl_flush_retry(svga); 465 } 466} 467 468 469/** 470 * Emit all operations pending on host surfaces. 471 */ 472void 473svga_surfaces_flush(struct svga_context *svga) 474{ 475 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH); 476 477 /* Emit buffered drawing commands. 478 */ 479 svga_hwtnl_flush_retry(svga); 480 481 /* Emit back-copy from render target views to textures. 482 */ 483 svga_propagate_rendertargets(svga); 484 485 SVGA_STATS_TIME_POP(svga_sws(svga)); 486} 487 488 489struct svga_winsys_context * 490svga_winsys_context(struct pipe_context *pipe) 491{ 492 return svga_context(pipe)->swc; 493} 494