1 /************************************************************************** 2 * 3 * Copyright 2009 Marek Olk <maraeo (at) gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27 #ifndef U_BLITTER_H 28 #define U_BLITTER_H 29 30 #include "util/u_framebuffer.h" 31 #include "util/u_inlines.h" 32 33 #include "pipe/p_state.h" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 struct pipe_context; 40 41 enum blitter_attrib_type { 42 UTIL_BLITTER_ATTRIB_NONE, 43 UTIL_BLITTER_ATTRIB_COLOR, 44 UTIL_BLITTER_ATTRIB_TEXCOORD_XY, 45 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW, 46 }; 47 48 union blitter_attrib { 49 float color[4]; 50 51 struct { 52 float x1, y1, x2, y2, z, w; 53 } texcoord; 54 }; 55 56 struct blitter_context; 57 58 typedef void *(*blitter_get_vs_func)(struct blitter_context *blitter); 59 60 struct blitter_context 61 { 62 /** 63 * Draw a rectangle. 64 * 65 * \param get_vs Callback for obtaining the vertex shader for the draw call. 66 * It might invoke the shader compiler. The driver is 67 * responsible for setting the vertex shader, and the callback 68 * allows the driver to query the vertex shader CSO if it 69 * wants to use the default one. 70 * \param x1 An X coordinate of the top-left corner. 71 * \param y1 A Y coordinate of the top-left corner. 72 * \param x2 An X coordinate of the bottom-right corner. 73 * \param y2 A Y coordinate of the bottom-right corner. 74 * \param depth A depth which the rectangle is rendered at. 75 * 76 * \param type Semantics of the attributes "attrib". 77 * If type is UTIL_BLITTER_ATTRIB_NONE, ignore them. 78 * If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes 79 * make up a constant RGBA color, and should go 80 * to the GENERIC0 varying slot of a fragment shader. 81 * If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and 82 * {a3, a4} specify top-left and bottom-right texture 83 * coordinates of the rectangle, respectively, and should go 84 * to the GENERIC0 varying slot of a fragment shader. 85 * 86 * \param attrib See type. 87 * 88 * \note A driver may optionally override this callback to implement 89 * a specialized hardware path for drawing a rectangle, e.g. using 90 * a rectangular point sprite. 91 */ 92 void (*draw_rectangle)(struct blitter_context *blitter, 93 void *vertex_elements_cso, 94 blitter_get_vs_func get_vs, 95 int x1, int y1, int x2, int y2, 96 float depth, unsigned num_instances, 97 enum blitter_attrib_type type, 98 const union blitter_attrib *attrib); 99 100 /* Whether the blitter is running. */ 101 bool running; 102 103 /* Private members, really. */ 104 struct pipe_context *pipe; /**< pipe context */ 105 106 void *saved_blend_state; /**< blend state */ 107 void *saved_dsa_state; /**< depth stencil alpha state */ 108 void *saved_velem_state; /**< vertex elements state */ 109 void *saved_rs_state; /**< rasterizer state */ 110 void *saved_fs, *saved_vs, *saved_gs, *saved_tcs, *saved_tes; /**< shaders */ 111 112 struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ 113 struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ 114 struct pipe_viewport_state saved_viewport; 115 struct pipe_scissor_state saved_scissor; 116 bool skip_viewport_restore; 117 bool is_sample_mask_saved; 118 unsigned saved_sample_mask; 119 120 unsigned saved_num_sampler_states; 121 void *saved_sampler_states[PIPE_MAX_SAMPLERS]; 122 123 unsigned saved_num_sampler_views; 124 struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; 125 126 unsigned cb_slot; 127 struct pipe_constant_buffer saved_fs_constant_buffer; 128 129 unsigned vb_slot; 130 struct pipe_vertex_buffer saved_vertex_buffer; 131 132 unsigned saved_num_so_targets; 133 struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS]; 134 135 struct pipe_query *saved_render_cond_query; 136 uint saved_render_cond_mode; 137 bool saved_render_cond_cond; 138 }; 139 140 /** 141 * Create a blitter context. 142 */ 143 struct blitter_context *util_blitter_create(struct pipe_context *pipe); 144 145 /** 146 * Destroy a blitter context. 147 */ 148 void util_blitter_destroy(struct blitter_context *blitter); 149 150 void util_blitter_cache_all_shaders(struct blitter_context *blitter); 151 152 /** 153 * Return the pipe context associated with a blitter context. 154 */ 155 static inline 156 struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) 157 { 158 return blitter->pipe; 159 } 160 161 /** 162 * Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver. 163 */ 164 void util_blitter_set_texture_multisample(struct blitter_context *blitter, 165 bool supported); 166 167 /* The default function to draw a rectangle. This can only be used 168 * inside of the draw_rectangle callback if the driver overrides it. */ 169 void util_blitter_draw_rectangle(struct blitter_context *blitter, 170 void *vertex_elements_cso, 171 blitter_get_vs_func get_vs, 172 int x1, int y1, int x2, int y2, 173 float depth, unsigned num_instances, 174 enum blitter_attrib_type type, 175 const union blitter_attrib *attrib); 176 177 178 /* 179 * These states must be saved before any of the following functions are called: 180 * - vertex buffers 181 * - vertex elements 182 * - vertex shader 183 * - geometry shader (if supported) 184 * - stream output targets (if supported) 185 * - rasterizer state 186 */ 187 188 /** 189 * Clear a specified set of currently bound buffers to specified values. 190 * 191 * These states must be saved in the blitter in addition to the state objects 192 * already required to be saved: 193 * - fragment shader 194 * - depth stencil alpha state 195 * - blend state 196 */ 197 void util_blitter_clear(struct blitter_context *blitter, 198 unsigned width, unsigned height, unsigned num_layers, 199 unsigned clear_buffers, 200 const union pipe_color_union *color, 201 double depth, unsigned stencil); 202 203 /** 204 * Check if the blitter (with the help of the driver) can blit between 205 * the two resources. 206 */ 207 bool util_blitter_is_copy_supported(struct blitter_context *blitter, 208 const struct pipe_resource *dst, 209 const struct pipe_resource *src); 210 211 bool util_blitter_is_blit_supported(struct blitter_context *blitter, 212 const struct pipe_blit_info *info); 213 214 /** 215 * Copy a block of pixels from one surface to another. 216 * 217 * These states must be saved in the blitter in addition to the state objects 218 * already required to be saved: 219 * - fragment shader 220 * - depth stencil alpha state 221 * - blend state 222 * - fragment sampler states 223 * - fragment sampler textures 224 * - framebuffer state 225 * - sample mask 226 */ 227 void util_blitter_copy_texture(struct blitter_context *blitter, 228 struct pipe_resource *dst, 229 unsigned dst_level, 230 unsigned dstx, unsigned dsty, unsigned dstz, 231 struct pipe_resource *src, 232 unsigned src_level, 233 const struct pipe_box *srcbox); 234 235 /** 236 * This is a generic implementation of pipe->blit, which accepts 237 * sampler/surface views instead of resources. 238 * 239 * The layer and mipmap level are specified by the views. 240 * 241 * Drivers can use this to change resource properties (like format, width, 242 * height) by changing how the views interpret them, instead of changing 243 * pipe_resource directly. This is used to blit resources of formats which 244 * are not renderable. 245 * 246 * src_width0 and src_height0 are sampler_view-private properties that 247 * override pipe_resource. The blitter uses them for computation of texture 248 * coordinates. The dst dimensions are supplied through pipe_surface::width 249 * and height. 250 * 251 * The mask is a combination of the PIPE_MASK_* flags. 252 * Set to PIPE_MASK_RGBAZS if unsure. 253 */ 254 void util_blitter_blit_generic(struct blitter_context *blitter, 255 struct pipe_surface *dst, 256 const struct pipe_box *dstbox, 257 struct pipe_sampler_view *src, 258 const struct pipe_box *srcbox, 259 unsigned src_width0, unsigned src_height0, 260 unsigned mask, unsigned filter, 261 const struct pipe_scissor_state *scissor, 262 bool alpha_blend); 263 264 void util_blitter_blit(struct blitter_context *blitter, 265 const struct pipe_blit_info *info); 266 267 void util_blitter_generate_mipmap(struct blitter_context *blitter, 268 struct pipe_resource *tex, 269 enum pipe_format format, 270 unsigned base_level, unsigned last_level, 271 unsigned first_layer, unsigned last_layer); 272 273 /** 274 * Helper function to initialize a view for copy_texture_view. 275 * The parameters must match copy_texture_view. 276 */ 277 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, 278 struct pipe_resource *dst, 279 unsigned dstlevel, 280 unsigned dstz); 281 282 /** 283 * Helper function to initialize a view for copy_texture_view. 284 * The parameters must match copy_texture_view. 285 */ 286 void util_blitter_default_src_texture(struct blitter_context *blitter, 287 struct pipe_sampler_view *src_templ, 288 struct pipe_resource *src, 289 unsigned srclevel); 290 291 /** 292 * Copy data from one buffer to another using the Stream Output functionality. 293 * 4-byte alignment is required, otherwise software fallback is used. 294 */ 295 void util_blitter_copy_buffer(struct blitter_context *blitter, 296 struct pipe_resource *dst, 297 unsigned dstx, 298 struct pipe_resource *src, 299 unsigned srcx, 300 unsigned size); 301 302 /** 303 * Clear the contents of a buffer using the Stream Output functionality. 304 * 4-byte alignment is required. 305 * 306 * "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is 307 * R, RG, RGB, or RGBA. 308 * 309 * For each element, only "num_channels" components of "clear_value" are 310 * copied to the buffer, then the offset is incremented by num_channels*4. 311 */ 312 void util_blitter_clear_buffer(struct blitter_context *blitter, 313 struct pipe_resource *dst, 314 unsigned offset, unsigned size, 315 unsigned num_channels, 316 const union pipe_color_union *clear_value); 317 318 /** 319 * Clear a region of a (color) surface to a constant value. 320 * 321 * These states must be saved in the blitter in addition to the state objects 322 * already required to be saved: 323 * - fragment shader 324 * - depth stencil alpha state 325 * - blend state 326 * - framebuffer state 327 */ 328 void util_blitter_clear_render_target(struct blitter_context *blitter, 329 struct pipe_surface *dst, 330 const union pipe_color_union *color, 331 unsigned dstx, unsigned dsty, 332 unsigned width, unsigned height); 333 334 /** 335 * Clear a region of a depth-stencil surface, both stencil and depth 336 * or only one of them if this is a combined depth-stencil surface. 337 * 338 * These states must be saved in the blitter in addition to the state objects 339 * already required to be saved: 340 * - fragment shader 341 * - depth stencil alpha state 342 * - blend state 343 * - framebuffer state 344 */ 345 void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 346 struct pipe_surface *dst, 347 unsigned clear_flags, 348 double depth, 349 unsigned stencil, 350 unsigned dstx, unsigned dsty, 351 unsigned width, unsigned height); 352 353 /* The following functions are customized variants of the clear functions. 354 * Some drivers use them internally to do things like MSAA resolve 355 * and resource decompression. It usually consists of rendering a full-screen 356 * quad with a special blend or DSA state. 357 */ 358 359 /* Used by r300g for depth decompression. */ 360 void util_blitter_custom_clear_depth(struct blitter_context *blitter, 361 unsigned width, unsigned height, 362 double depth, void *custom_dsa); 363 364 /* Used by r600g for depth decompression. */ 365 void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 366 struct pipe_surface *zsurf, 367 struct pipe_surface *cbsurf, 368 unsigned sample_mask, 369 void *dsa_stage, float depth); 370 371 /* Used by r600g for color decompression. */ 372 void util_blitter_custom_color(struct blitter_context *blitter, 373 struct pipe_surface *dstsurf, 374 void *custom_blend); 375 376 /* Used by r600g for MSAA color resolve. */ 377 void util_blitter_custom_resolve_color(struct blitter_context *blitter, 378 struct pipe_resource *dst, 379 unsigned dst_level, 380 unsigned dst_layer, 381 struct pipe_resource *src, 382 unsigned src_layer, 383 unsigned sampled_mask, 384 void *custom_blend, 385 enum pipe_format format); 386 387 /* The functions below should be used to save currently bound constant state 388 * objects inside a driver. The objects are automatically restored at the end 389 * of the util_blitter_{clear, copy_region, fill_region} functions and then 390 * forgotten. 391 * 392 * States not listed here are not affected by util_blitter. */ 393 394 static inline void 395 util_blitter_save_blend(struct blitter_context *blitter, void *state) 396 { 397 blitter->saved_blend_state = state; 398 } 399 400 static inline void 401 util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, 402 void *state) 403 { 404 blitter->saved_dsa_state = state; 405 } 406 407 static inline void 408 util_blitter_save_vertex_elements(struct blitter_context *blitter, void *state) 409 { 410 blitter->saved_velem_state = state; 411 } 412 413 static inline void 414 util_blitter_save_stencil_ref(struct blitter_context *blitter, 415 const struct pipe_stencil_ref *state) 416 { 417 blitter->saved_stencil_ref = *state; 418 } 419 420 static inline void 421 util_blitter_save_rasterizer(struct blitter_context *blitter, void *state) 422 { 423 blitter->saved_rs_state = state; 424 } 425 426 static inline void 427 util_blitter_save_fragment_shader(struct blitter_context *blitter, void *fs) 428 { 429 blitter->saved_fs = fs; 430 } 431 432 static inline void 433 util_blitter_save_vertex_shader(struct blitter_context *blitter, void *vs) 434 { 435 blitter->saved_vs = vs; 436 } 437 438 static inline void 439 util_blitter_save_geometry_shader(struct blitter_context *blitter, void *gs) 440 { 441 blitter->saved_gs = gs; 442 } 443 444 static inline void 445 util_blitter_save_tessctrl_shader(struct blitter_context *blitter, 446 void *sh) 447 { 448 blitter->saved_tcs = sh; 449 } 450 451 static inline void 452 util_blitter_save_tesseval_shader(struct blitter_context *blitter, 453 void *sh) 454 { 455 blitter->saved_tes = sh; 456 } 457 458 static inline void 459 util_blitter_save_framebuffer(struct blitter_context *blitter, 460 const struct pipe_framebuffer_state *state) 461 { 462 blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */ 463 util_copy_framebuffer_state(&blitter->saved_fb_state, state); 464 } 465 466 static inline void 467 util_blitter_save_viewport(struct blitter_context *blitter, 468 struct pipe_viewport_state *state) 469 { 470 blitter->saved_viewport = *state; 471 } 472 473 static inline void 474 util_blitter_save_scissor(struct blitter_context *blitter, 475 struct pipe_scissor_state *state) 476 { 477 blitter->saved_scissor = *state; 478 } 479 480 static inline void 481 util_blitter_save_fragment_sampler_states( 482 struct blitter_context *blitter, 483 unsigned num_sampler_states, 484 void **sampler_states) 485 { 486 assert(num_sampler_states <= ARRAY_SIZE(blitter->saved_sampler_states)); 487 488 blitter->saved_num_sampler_states = num_sampler_states; 489 memcpy(blitter->saved_sampler_states, sampler_states, 490 num_sampler_states * sizeof(void *)); 491 } 492 493 static inline void 494 util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, 495 unsigned num_views, 496 struct pipe_sampler_view **views) 497 { 498 unsigned i; 499 assert(num_views <= ARRAY_SIZE(blitter->saved_sampler_views)); 500 501 blitter->saved_num_sampler_views = num_views; 502 for (i = 0; i < num_views; i++) 503 pipe_sampler_view_reference(&blitter->saved_sampler_views[i], 504 views[i]); 505 } 506 507 static inline void 508 util_blitter_save_fragment_constant_buffer_slot( 509 struct blitter_context *blitter, 510 struct pipe_constant_buffer *constant_buffers) 511 { 512 pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer, 513 constant_buffers[blitter->cb_slot].buffer); 514 memcpy(&blitter->saved_fs_constant_buffer, &constant_buffers[blitter->cb_slot], 515 sizeof(struct pipe_constant_buffer)); 516 } 517 518 static inline void 519 util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter, 520 struct pipe_vertex_buffer *vertex_buffers) 521 { 522 pipe_vertex_buffer_reference(&blitter->saved_vertex_buffer, 523 &vertex_buffers[blitter->vb_slot]); 524 } 525 526 static inline void 527 util_blitter_save_so_targets(struct blitter_context *blitter, 528 unsigned num_targets, 529 struct pipe_stream_output_target **targets) 530 { 531 unsigned i; 532 assert(num_targets <= ARRAY_SIZE(blitter->saved_so_targets)); 533 534 blitter->saved_num_so_targets = num_targets; 535 for (i = 0; i < num_targets; i++) 536 pipe_so_target_reference(&blitter->saved_so_targets[i], 537 targets[i]); 538 } 539 540 static inline void 541 util_blitter_save_sample_mask(struct blitter_context *blitter, 542 unsigned sample_mask) 543 { 544 blitter->is_sample_mask_saved = true; 545 blitter->saved_sample_mask = sample_mask; 546 } 547 548 static inline void 549 util_blitter_save_render_condition(struct blitter_context *blitter, 550 struct pipe_query *query, 551 bool condition, 552 enum pipe_render_cond_flag mode) 553 { 554 blitter->saved_render_cond_query = query; 555 blitter->saved_render_cond_mode = mode; 556 blitter->saved_render_cond_cond = condition; 557 } 558 559 void util_blitter_common_clear_setup(struct blitter_context *blitter, 560 unsigned width, unsigned height, 561 unsigned clear_buffers, 562 void *custom_blend, void *custom_dsa); 563 564 void util_blitter_set_running_flag(struct blitter_context *blitter); 565 void util_blitter_unset_running_flag(struct blitter_context *blitter); 566 567 void util_blitter_restore_vertex_states(struct blitter_context *blitter); 568 void util_blitter_restore_fragment_states(struct blitter_context *blitter); 569 void util_blitter_restore_render_cond(struct blitter_context *blitter); 570 void util_blitter_restore_fb_state(struct blitter_context *blitter); 571 void util_blitter_restore_textures(struct blitter_context *blitter); 572 void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter); 573 574 #ifdef __cplusplus 575 } 576 #endif 577 578 #endif 579