1/************************************************************************** 2 * 3 * Copyright 2009 Marek Olšák <maraeo@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 36extern "C" { 37#endif 38 39struct pipe_context; 40 41enum 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 48union blitter_attrib { 49 float color[4]; 50 51 struct { 52 float x1, y1, x2, y2, z, w; 53 } texcoord; 54}; 55 56struct blitter_context; 57 58typedef void *(*blitter_get_vs_func)(struct blitter_context *blitter); 59 60struct 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 bool use_index_buffer; 104 105 /* Private members, really. */ 106 struct pipe_context *pipe; /**< pipe context */ 107 108 void *saved_blend_state; /**< blend state */ 109 void *saved_dsa_state; /**< depth stencil alpha state */ 110 void *saved_velem_state; /**< vertex elements state */ 111 void *saved_rs_state; /**< rasterizer state */ 112 void *saved_fs, *saved_vs, *saved_gs, *saved_tcs, *saved_tes; /**< shaders */ 113 114 struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ 115 struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ 116 struct pipe_viewport_state saved_viewport; 117 struct pipe_scissor_state saved_scissor; 118 bool skip_viewport_restore; 119 bool is_sample_mask_saved; 120 unsigned saved_sample_mask; 121 122 unsigned saved_num_sampler_states; 123 void *saved_sampler_states[PIPE_MAX_SAMPLERS]; 124 125 unsigned saved_num_sampler_views; 126 struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; 127 128 unsigned cb_slot; 129 struct pipe_constant_buffer saved_fs_constant_buffer; 130 131 unsigned vb_slot; 132 struct pipe_vertex_buffer saved_vertex_buffer; 133 134 unsigned saved_num_so_targets; 135 struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS]; 136 137 struct pipe_query *saved_render_cond_query; 138 uint saved_render_cond_mode; 139 bool saved_render_cond_cond; 140 141 boolean saved_window_rectangles_include; 142 unsigned saved_num_window_rectangles; 143 struct pipe_scissor_state saved_window_rectangles[PIPE_MAX_WINDOW_RECTANGLES]; 144}; 145 146/** 147 * Create a blitter context. 148 */ 149struct blitter_context *util_blitter_create(struct pipe_context *pipe); 150 151/** 152 * Destroy a blitter context. 153 */ 154void util_blitter_destroy(struct blitter_context *blitter); 155 156void util_blitter_cache_all_shaders(struct blitter_context *blitter); 157 158/** 159 * Return the pipe context associated with a blitter context. 160 */ 161static inline 162struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) 163{ 164 return blitter->pipe; 165} 166 167/** 168 * Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver. 169 */ 170void util_blitter_set_texture_multisample(struct blitter_context *blitter, 171 bool supported); 172 173/* The default function to draw a rectangle. This can only be used 174 * inside of the draw_rectangle callback if the driver overrides it. */ 175void util_blitter_draw_rectangle(struct blitter_context *blitter, 176 void *vertex_elements_cso, 177 blitter_get_vs_func get_vs, 178 int x1, int y1, int x2, int y2, 179 float depth, unsigned num_instances, 180 enum blitter_attrib_type type, 181 const union blitter_attrib *attrib); 182 183 184/* 185 * These states must be saved before any of the following functions are called: 186 * - vertex buffers 187 * - vertex elements 188 * - vertex shader 189 * - geometry shader (if supported) 190 * - stream output targets (if supported) 191 * - rasterizer state 192 */ 193 194/** 195 * Clear a specified set of currently bound buffers to specified values. 196 * 197 * These states must be saved in the blitter in addition to the state objects 198 * already required to be saved: 199 * - fragment shader 200 * - depth stencil alpha state 201 * - blend state 202 */ 203void util_blitter_clear(struct blitter_context *blitter, 204 unsigned width, unsigned height, unsigned num_layers, 205 unsigned clear_buffers, 206 const union pipe_color_union *color, 207 double depth, unsigned stencil); 208 209/** 210 * Check if the blitter (with the help of the driver) can blit between 211 * the two resources. 212 */ 213bool util_blitter_is_copy_supported(struct blitter_context *blitter, 214 const struct pipe_resource *dst, 215 const struct pipe_resource *src); 216 217bool util_blitter_is_blit_supported(struct blitter_context *blitter, 218 const struct pipe_blit_info *info); 219 220/** 221 * Copy a block of pixels from one surface to another. 222 * 223 * These states must be saved in the blitter in addition to the state objects 224 * already required to be saved: 225 * - fragment shader 226 * - depth stencil alpha state 227 * - blend state 228 * - fragment sampler states 229 * - fragment sampler textures 230 * - framebuffer state 231 * - sample mask 232 */ 233void util_blitter_copy_texture(struct blitter_context *blitter, 234 struct pipe_resource *dst, 235 unsigned dst_level, 236 unsigned dstx, unsigned dsty, unsigned dstz, 237 struct pipe_resource *src, 238 unsigned src_level, 239 const struct pipe_box *srcbox); 240 241/** 242 * This is a generic implementation of pipe->blit, which accepts 243 * sampler/surface views instead of resources. 244 * 245 * The layer and mipmap level are specified by the views. 246 * 247 * Drivers can use this to change resource properties (like format, width, 248 * height) by changing how the views interpret them, instead of changing 249 * pipe_resource directly. This is used to blit resources of formats which 250 * are not renderable. 251 * 252 * src_width0 and src_height0 are sampler_view-private properties that 253 * override pipe_resource. The blitter uses them for computation of texture 254 * coordinates. The dst dimensions are supplied through pipe_surface::width 255 * and height. 256 * 257 * The mask is a combination of the PIPE_MASK_* flags. 258 * Set to PIPE_MASK_RGBAZS if unsure. 259 */ 260void util_blitter_blit_generic(struct blitter_context *blitter, 261 struct pipe_surface *dst, 262 const struct pipe_box *dstbox, 263 struct pipe_sampler_view *src, 264 const struct pipe_box *srcbox, 265 unsigned src_width0, unsigned src_height0, 266 unsigned mask, unsigned filter, 267 const struct pipe_scissor_state *scissor, 268 bool alpha_blend); 269 270void util_blitter_blit(struct blitter_context *blitter, 271 const struct pipe_blit_info *info); 272 273void util_blitter_generate_mipmap(struct blitter_context *blitter, 274 struct pipe_resource *tex, 275 enum pipe_format format, 276 unsigned base_level, unsigned last_level, 277 unsigned first_layer, unsigned last_layer); 278 279/** 280 * Helper function to initialize a view for copy_texture_view. 281 * The parameters must match copy_texture_view. 282 */ 283void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, 284 struct pipe_resource *dst, 285 unsigned dstlevel, 286 unsigned dstz); 287 288/** 289 * Helper function to initialize a view for copy_texture_view. 290 * The parameters must match copy_texture_view. 291 */ 292void util_blitter_default_src_texture(struct blitter_context *blitter, 293 struct pipe_sampler_view *src_templ, 294 struct pipe_resource *src, 295 unsigned srclevel); 296 297/** 298 * Copy data from one buffer to another using the Stream Output functionality. 299 * 4-byte alignment is required, otherwise software fallback is used. 300 */ 301void util_blitter_copy_buffer(struct blitter_context *blitter, 302 struct pipe_resource *dst, 303 unsigned dstx, 304 struct pipe_resource *src, 305 unsigned srcx, 306 unsigned size); 307 308/** 309 * Clear the contents of a buffer using the Stream Output functionality. 310 * 4-byte alignment is required. 311 * 312 * "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is 313 * R, RG, RGB, or RGBA. 314 * 315 * For each element, only "num_channels" components of "clear_value" are 316 * copied to the buffer, then the offset is incremented by num_channels*4. 317 */ 318void util_blitter_clear_buffer(struct blitter_context *blitter, 319 struct pipe_resource *dst, 320 unsigned offset, unsigned size, 321 unsigned num_channels, 322 const union pipe_color_union *clear_value); 323 324/** 325 * Clear a region of a (color) surface to a constant value. 326 * 327 * These states must be saved in the blitter in addition to the state objects 328 * already required to be saved: 329 * - fragment shader 330 * - depth stencil alpha state 331 * - blend state 332 * - framebuffer state 333 */ 334void util_blitter_clear_render_target(struct blitter_context *blitter, 335 struct pipe_surface *dst, 336 const union pipe_color_union *color, 337 unsigned dstx, unsigned dsty, 338 unsigned width, unsigned height); 339 340/** 341 * Clear a region of a depth-stencil surface, both stencil and depth 342 * or only one of them if this is a combined depth-stencil surface. 343 * 344 * These states must be saved in the blitter in addition to the state objects 345 * already required to be saved: 346 * - fragment shader 347 * - depth stencil alpha state 348 * - blend state 349 * - framebuffer state 350 */ 351void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 352 struct pipe_surface *dst, 353 unsigned clear_flags, 354 double depth, 355 unsigned stencil, 356 unsigned dstx, unsigned dsty, 357 unsigned width, unsigned height); 358 359/* The following functions are customized variants of the clear functions. 360 * Some drivers use them internally to do things like MSAA resolve 361 * and resource decompression. It usually consists of rendering a full-screen 362 * quad with a special blend or DSA state. 363 */ 364 365/* Used by r300g for depth decompression. */ 366void util_blitter_custom_clear_depth(struct blitter_context *blitter, 367 unsigned width, unsigned height, 368 double depth, void *custom_dsa); 369 370/* Used by r600g for depth decompression. */ 371void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 372 struct pipe_surface *zsurf, 373 struct pipe_surface *cbsurf, 374 unsigned sample_mask, 375 void *dsa_stage, float depth); 376 377/* Used by r600g for color decompression. */ 378void util_blitter_custom_color(struct blitter_context *blitter, 379 struct pipe_surface *dstsurf, 380 void *custom_blend); 381 382/* Used by r600g for MSAA color resolve. */ 383void util_blitter_custom_resolve_color(struct blitter_context *blitter, 384 struct pipe_resource *dst, 385 unsigned dst_level, 386 unsigned dst_layer, 387 struct pipe_resource *src, 388 unsigned src_layer, 389 unsigned sampled_mask, 390 void *custom_blend, 391 enum pipe_format format); 392 393/* Used by vc4 for 8/16-bit linear-to-tiled blits */ 394void util_blitter_custom_shader(struct blitter_context *blitter, 395 struct pipe_surface *dstsurf, 396 void *custom_vs, void *custom_fs); 397 398/* The functions below should be used to save currently bound constant state 399 * objects inside a driver. The objects are automatically restored at the end 400 * of the util_blitter_{clear, copy_region, fill_region} functions and then 401 * forgotten. 402 * 403 * States not listed here are not affected by util_blitter. */ 404 405static inline void 406util_blitter_save_blend(struct blitter_context *blitter, void *state) 407{ 408 blitter->saved_blend_state = state; 409} 410 411static inline void 412util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, 413 void *state) 414{ 415 blitter->saved_dsa_state = state; 416} 417 418static inline void 419util_blitter_save_vertex_elements(struct blitter_context *blitter, void *state) 420{ 421 blitter->saved_velem_state = state; 422} 423 424static inline void 425util_blitter_save_stencil_ref(struct blitter_context *blitter, 426 const struct pipe_stencil_ref *state) 427{ 428 blitter->saved_stencil_ref = *state; 429} 430 431static inline void 432util_blitter_save_rasterizer(struct blitter_context *blitter, void *state) 433{ 434 blitter->saved_rs_state = state; 435} 436 437static inline void 438util_blitter_save_fragment_shader(struct blitter_context *blitter, void *fs) 439{ 440 blitter->saved_fs = fs; 441} 442 443static inline void 444util_blitter_save_vertex_shader(struct blitter_context *blitter, void *vs) 445{ 446 blitter->saved_vs = vs; 447} 448 449static inline void 450util_blitter_save_geometry_shader(struct blitter_context *blitter, void *gs) 451{ 452 blitter->saved_gs = gs; 453} 454 455static inline void 456util_blitter_save_tessctrl_shader(struct blitter_context *blitter, 457 void *sh) 458{ 459 blitter->saved_tcs = sh; 460} 461 462static inline void 463util_blitter_save_tesseval_shader(struct blitter_context *blitter, 464 void *sh) 465{ 466 blitter->saved_tes = sh; 467} 468 469static inline void 470util_blitter_save_framebuffer(struct blitter_context *blitter, 471 const struct pipe_framebuffer_state *state) 472{ 473 blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */ 474 util_copy_framebuffer_state(&blitter->saved_fb_state, state); 475} 476 477static inline void 478util_blitter_save_viewport(struct blitter_context *blitter, 479 struct pipe_viewport_state *state) 480{ 481 blitter->saved_viewport = *state; 482} 483 484static inline void 485util_blitter_save_scissor(struct blitter_context *blitter, 486 struct pipe_scissor_state *state) 487{ 488 blitter->saved_scissor = *state; 489} 490 491static inline void 492util_blitter_save_fragment_sampler_states( 493 struct blitter_context *blitter, 494 unsigned num_sampler_states, 495 void **sampler_states) 496{ 497 assert(num_sampler_states <= ARRAY_SIZE(blitter->saved_sampler_states)); 498 499 blitter->saved_num_sampler_states = num_sampler_states; 500 memcpy(blitter->saved_sampler_states, sampler_states, 501 num_sampler_states * sizeof(void *)); 502} 503 504static inline void 505util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, 506 unsigned num_views, 507 struct pipe_sampler_view **views) 508{ 509 unsigned i; 510 assert(num_views <= ARRAY_SIZE(blitter->saved_sampler_views)); 511 512 blitter->saved_num_sampler_views = num_views; 513 for (i = 0; i < num_views; i++) 514 pipe_sampler_view_reference(&blitter->saved_sampler_views[i], 515 views[i]); 516} 517 518static inline void 519util_blitter_save_fragment_constant_buffer_slot( 520 struct blitter_context *blitter, 521 struct pipe_constant_buffer *constant_buffers) 522{ 523 pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer, 524 constant_buffers[blitter->cb_slot].buffer); 525 memcpy(&blitter->saved_fs_constant_buffer, &constant_buffers[blitter->cb_slot], 526 sizeof(struct pipe_constant_buffer)); 527} 528 529static inline void 530util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter, 531 struct pipe_vertex_buffer *vertex_buffers) 532{ 533 pipe_vertex_buffer_reference(&blitter->saved_vertex_buffer, 534 &vertex_buffers[blitter->vb_slot]); 535} 536 537static inline void 538util_blitter_save_so_targets(struct blitter_context *blitter, 539 unsigned num_targets, 540 struct pipe_stream_output_target **targets) 541{ 542 unsigned i; 543 assert(num_targets <= ARRAY_SIZE(blitter->saved_so_targets)); 544 545 blitter->saved_num_so_targets = num_targets; 546 for (i = 0; i < num_targets; i++) 547 pipe_so_target_reference(&blitter->saved_so_targets[i], 548 targets[i]); 549} 550 551static inline void 552util_blitter_save_sample_mask(struct blitter_context *blitter, 553 unsigned sample_mask) 554{ 555 blitter->is_sample_mask_saved = true; 556 blitter->saved_sample_mask = sample_mask; 557} 558 559static inline void 560util_blitter_save_render_condition(struct blitter_context *blitter, 561 struct pipe_query *query, 562 bool condition, 563 enum pipe_render_cond_flag mode) 564{ 565 blitter->saved_render_cond_query = query; 566 blitter->saved_render_cond_mode = mode; 567 blitter->saved_render_cond_cond = condition; 568} 569 570static inline void 571util_blitter_save_window_rectangles(struct blitter_context *blitter, 572 boolean include, 573 unsigned num_rectangles, 574 const struct pipe_scissor_state *rects) 575{ 576 blitter->saved_window_rectangles_include = include; 577 blitter->saved_num_window_rectangles = num_rectangles; 578 if (num_rectangles > 0) { 579 assert(num_rectangles < ARRAY_SIZE(blitter->saved_window_rectangles)); 580 memcpy(blitter->saved_window_rectangles, rects, 581 sizeof(*rects) * num_rectangles); 582 } 583} 584 585void util_blitter_common_clear_setup(struct blitter_context *blitter, 586 unsigned width, unsigned height, 587 unsigned clear_buffers, 588 void *custom_blend, void *custom_dsa); 589 590void util_blitter_set_running_flag(struct blitter_context *blitter); 591void util_blitter_unset_running_flag(struct blitter_context *blitter); 592 593void util_blitter_restore_vertex_states(struct blitter_context *blitter); 594void util_blitter_restore_fragment_states(struct blitter_context *blitter); 595void util_blitter_restore_render_cond(struct blitter_context *blitter); 596void util_blitter_restore_fb_state(struct blitter_context *blitter); 597void util_blitter_restore_textures(struct blitter_context *blitter); 598void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter); 599 600#ifdef __cplusplus 601} 602#endif 603 604#endif 605