1/************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "util/u_rect.h" 29#include "util/u_surface.h" 30#include "util/u_memset.h" 31#include "lp_context.h" 32#include "lp_flush.h" 33#include "lp_limits.h" 34#include "lp_surface.h" 35#include "lp_texture.h" 36#include "lp_query.h" 37#include "lp_rast.h" 38 39static void 40lp_resource_copy_ms(struct pipe_context *pipe, 41 struct pipe_resource *dst, unsigned dst_level, 42 unsigned dstx, unsigned dsty, unsigned dstz, 43 struct pipe_resource *src, unsigned src_level, 44 const struct pipe_box *src_box) 45{ 46 struct pipe_box dst_box = *src_box; 47 enum pipe_format src_format; 48 dst_box.x = dstx; 49 dst_box.y = dsty; 50 dst_box.z = dstz; 51 52 src_format = src->format; 53 54 for (unsigned i = 0; i < MAX2(src->nr_samples, dst->nr_samples); i++) { 55 struct pipe_transfer *src_trans, *dst_trans; 56 const uint8_t *src_map = llvmpipe_transfer_map_ms(pipe, 57 src, 0, PIPE_MAP_READ, MIN2(i, src->nr_samples - 1), 58 src_box, 59 &src_trans); 60 if (!src_map) 61 return; 62 63 uint8_t *dst_map = llvmpipe_transfer_map_ms(pipe, 64 dst, 0, PIPE_MAP_WRITE, i, 65 &dst_box, 66 &dst_trans); 67 if (!dst_map) { 68 pipe->texture_unmap(pipe, src_trans); 69 return; 70 } 71 72 util_copy_box(dst_map, 73 src_format, 74 dst_trans->stride, dst_trans->layer_stride, 75 0, 0, 0, 76 src_box->width, src_box->height, src_box->depth, 77 src_map, 78 src_trans->stride, src_trans->layer_stride, 79 0, 0, 0); 80 pipe->texture_unmap(pipe, dst_trans); 81 pipe->texture_unmap(pipe, src_trans); 82 } 83} 84static void 85lp_resource_copy(struct pipe_context *pipe, 86 struct pipe_resource *dst, unsigned dst_level, 87 unsigned dstx, unsigned dsty, unsigned dstz, 88 struct pipe_resource *src, unsigned src_level, 89 const struct pipe_box *src_box) 90{ 91 llvmpipe_flush_resource(pipe, 92 dst, dst_level, 93 FALSE, /* read_only */ 94 TRUE, /* cpu_access */ 95 FALSE, /* do_not_block */ 96 "blit dest"); 97 98 llvmpipe_flush_resource(pipe, 99 src, src_level, 100 TRUE, /* read_only */ 101 TRUE, /* cpu_access */ 102 FALSE, /* do_not_block */ 103 "blit src"); 104 105 if (dst->nr_samples > 1 && 106 (dst->nr_samples == src->nr_samples || 107 (src->nr_samples == 1 && dst->nr_samples > 1))) { 108 lp_resource_copy_ms(pipe, dst, dst_level, dstx, dsty, dstz, 109 src, src_level, src_box); 110 return; 111 } 112 util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 113 src, src_level, src_box); 114} 115 116 117static void lp_blit(struct pipe_context *pipe, 118 const struct pipe_blit_info *blit_info) 119{ 120 struct llvmpipe_context *lp = llvmpipe_context(pipe); 121 struct pipe_blit_info info = *blit_info; 122 123 if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp)) 124 return; 125 126 if (util_try_blit_via_copy_region(pipe, &info, lp->render_cond_query != NULL)) { 127 return; /* done */ 128 } 129 130 if (blit_info->src.resource->format == blit_info->src.format && 131 blit_info->dst.resource->format == blit_info->dst.format && 132 blit_info->src.format == blit_info->dst.format && 133 blit_info->src.resource->nr_samples > 1 && 134 blit_info->dst.resource->nr_samples < 2 && 135 blit_info->sample0_only) { 136 util_resource_copy_region(pipe, blit_info->dst.resource, blit_info->dst.level, blit_info->dst.box.x, blit_info->dst.box.y, blit_info->dst.box.z, 137 blit_info->src.resource, blit_info->src.level, &blit_info->src.box); 138 return; 139 } 140 141 if (!util_blitter_is_blit_supported(lp->blitter, &info)) { 142 debug_printf("llvmpipe: blit unsupported %s -> %s\n", 143 util_format_short_name(info.src.resource->format), 144 util_format_short_name(info.dst.resource->format)); 145 return; 146 } 147 148 /* for 32-bit unorm depth, avoid the conversions to float and back, 149 which can introduce accuracy errors. */ 150 if (blit_info->src.format == PIPE_FORMAT_Z32_UNORM && 151 blit_info->dst.format == PIPE_FORMAT_Z32_UNORM && info.filter == PIPE_TEX_FILTER_NEAREST) { 152 info.src.format = PIPE_FORMAT_R32_UINT; 153 info.dst.format = PIPE_FORMAT_R32_UINT; 154 info.mask = PIPE_MASK_R; 155 } 156 157 util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer); 158 util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems); 159 util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs); 160 util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs); 161 util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, 162 (struct pipe_stream_output_target**)lp->so_targets); 163 util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); 164 util_blitter_save_viewport(lp->blitter, &lp->viewports[0]); 165 util_blitter_save_scissor(lp->blitter, &lp->scissors[0]); 166 util_blitter_save_fragment_shader(lp->blitter, lp->fs); 167 util_blitter_save_blend(lp->blitter, (void*)lp->blend); 168 util_blitter_save_tessctrl_shader(lp->blitter, (void*)lp->tcs); 169 util_blitter_save_tesseval_shader(lp->blitter, (void*)lp->tes); 170 util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil); 171 util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref); 172 util_blitter_save_sample_mask(lp->blitter, lp->sample_mask, lp->min_samples); 173 util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer); 174 util_blitter_save_fragment_sampler_states(lp->blitter, 175 lp->num_samplers[PIPE_SHADER_FRAGMENT], 176 (void**)lp->samplers[PIPE_SHADER_FRAGMENT]); 177 util_blitter_save_fragment_sampler_views(lp->blitter, 178 lp->num_sampler_views[PIPE_SHADER_FRAGMENT], 179 lp->sampler_views[PIPE_SHADER_FRAGMENT]); 180 util_blitter_save_render_condition(lp->blitter, lp->render_cond_query, 181 lp->render_cond_cond, lp->render_cond_mode); 182 util_blitter_blit(lp->blitter, &info); 183} 184 185 186static void 187lp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) 188{ 189 llvmpipe_flush_resource(ctx, resource, 0, true, true, false, "resource"); 190} 191 192 193static struct pipe_surface * 194llvmpipe_create_surface(struct pipe_context *pipe, 195 struct pipe_resource *pt, 196 const struct pipe_surface *surf_tmpl) 197{ 198 struct pipe_surface *ps; 199 200 if (!(pt->bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET))) { 201 debug_printf("Illegal surface creation without bind flag\n"); 202 if (util_format_is_depth_or_stencil(surf_tmpl->format)) { 203 pt->bind |= PIPE_BIND_DEPTH_STENCIL; 204 } 205 else { 206 pt->bind |= PIPE_BIND_RENDER_TARGET; 207 } 208 } 209 210 ps = CALLOC_STRUCT(pipe_surface); 211 if (ps) { 212 pipe_reference_init(&ps->reference, 1); 213 pipe_resource_reference(&ps->texture, pt); 214 ps->context = pipe; 215 ps->format = surf_tmpl->format; 216 if (llvmpipe_resource_is_texture(pt)) { 217 assert(surf_tmpl->u.tex.level <= pt->last_level); 218 assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer); 219 ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); 220 ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); 221 ps->u.tex.level = surf_tmpl->u.tex.level; 222 ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; 223 ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; 224 } 225 else { 226 /* setting width as number of elements should get us correct renderbuffer width */ 227 ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1; 228 ps->height = pt->height0; 229 ps->u.buf.first_element = surf_tmpl->u.buf.first_element; 230 ps->u.buf.last_element = surf_tmpl->u.buf.last_element; 231 assert(ps->u.buf.first_element <= ps->u.buf.last_element); 232 assert(util_format_get_blocksize(surf_tmpl->format) * 233 (ps->u.buf.last_element + 1) <= pt->width0); 234 } 235 } 236 return ps; 237} 238 239 240static void 241llvmpipe_surface_destroy(struct pipe_context *pipe, 242 struct pipe_surface *surf) 243{ 244 /* Effectively do the texture_update work here - if texture images 245 * needed post-processing to put them into hardware layout, this is 246 * where it would happen. For llvmpipe, nothing to do. 247 */ 248 assert(surf->texture); 249 pipe_resource_reference(&surf->texture, NULL); 250 FREE(surf); 251} 252 253 254 255static void 256llvmpipe_get_sample_position(struct pipe_context *pipe, 257 unsigned sample_count, 258 unsigned sample_index, 259 float *out_value) 260{ 261 switch (sample_count) { 262 case 4: 263 out_value[0] = lp_sample_pos_4x[sample_index][0]; 264 out_value[1] = lp_sample_pos_4x[sample_index][1]; 265 break; 266 default: 267 break; 268 } 269} 270 271static void 272lp_clear_color_texture_helper(struct pipe_transfer *dst_trans, 273 ubyte *dst_map, 274 enum pipe_format format, 275 const union pipe_color_union *color, 276 unsigned width, unsigned height, unsigned depth) 277{ 278 union util_color uc; 279 280 assert(dst_trans->stride > 0); 281 282 util_pack_color_union(format, &uc, color); 283 284 util_fill_box(dst_map, format, 285 dst_trans->stride, dst_trans->layer_stride, 286 0, 0, 0, width, height, depth, &uc); 287} 288 289static void 290lp_clear_color_texture_msaa(struct pipe_context *pipe, 291 struct pipe_resource *texture, 292 enum pipe_format format, 293 const union pipe_color_union *color, 294 unsigned sample, 295 const struct pipe_box *box) 296{ 297 struct pipe_transfer *dst_trans; 298 ubyte *dst_map; 299 300 dst_map = llvmpipe_transfer_map_ms(pipe, texture, 0, PIPE_MAP_WRITE, 301 sample, box, &dst_trans); 302 if (!dst_map) 303 return; 304 305 if (dst_trans->stride > 0) { 306 lp_clear_color_texture_helper(dst_trans, dst_map, format, color, 307 box->width, box->height, box->depth); 308 } 309 pipe->texture_unmap(pipe, dst_trans); 310} 311 312static void 313llvmpipe_clear_render_target(struct pipe_context *pipe, 314 struct pipe_surface *dst, 315 const union pipe_color_union *color, 316 unsigned dstx, unsigned dsty, 317 unsigned width, unsigned height, 318 bool render_condition_enabled) 319{ 320 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 321 322 if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) 323 return; 324 325 width = MIN2(width, dst->texture->width0 - dstx); 326 height = MIN2(height, dst->texture->height0 - dsty); 327 328 if (dst->texture->nr_samples > 1) { 329 struct pipe_box box; 330 u_box_2d(dstx, dsty, width, height, &box); 331 if (dst->texture->target != PIPE_BUFFER) { 332 box.z = dst->u.tex.first_layer; 333 box.depth = dst->u.tex.last_layer - dst->u.tex.first_layer + 1; 334 } 335 for (unsigned s = 0; s < util_res_sample_count(dst->texture); s++) { 336 lp_clear_color_texture_msaa(pipe, dst->texture, dst->format, 337 color, s, &box); 338 } 339 } else 340 util_clear_render_target(pipe, dst, color, 341 dstx, dsty, width, height); 342} 343 344 345static void 346lp_clear_depth_stencil_texture_msaa(struct pipe_context *pipe, 347 struct pipe_resource *texture, 348 enum pipe_format format, 349 unsigned clear_flags, 350 uint64_t zstencil, unsigned sample, 351 const struct pipe_box *box) 352{ 353 struct pipe_transfer *dst_trans; 354 ubyte *dst_map; 355 boolean need_rmw = FALSE; 356 357 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && 358 ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && 359 util_format_is_depth_and_stencil(format)) 360 need_rmw = TRUE; 361 362 dst_map = llvmpipe_transfer_map_ms(pipe, 363 texture, 364 0, 365 (need_rmw ? PIPE_MAP_READ_WRITE : 366 PIPE_MAP_WRITE), 367 sample, box, &dst_trans); 368 assert(dst_map); 369 if (!dst_map) 370 return; 371 372 assert(dst_trans->stride > 0); 373 374 util_fill_zs_box(dst_map, format, need_rmw, clear_flags, 375 dst_trans->stride, dst_trans->layer_stride, 376 box->width, box->height, box->depth, zstencil); 377 378 pipe->texture_unmap(pipe, dst_trans); 379} 380 381static void 382llvmpipe_clear_depth_stencil(struct pipe_context *pipe, 383 struct pipe_surface *dst, 384 unsigned clear_flags, 385 double depth, 386 unsigned stencil, 387 unsigned dstx, unsigned dsty, 388 unsigned width, unsigned height, 389 bool render_condition_enabled) 390{ 391 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 392 393 if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) 394 return; 395 396 width = MIN2(width, dst->texture->width0 - dstx); 397 height = MIN2(height, dst->texture->height0 - dsty); 398 399 if (dst->texture->nr_samples > 1) { 400 uint64_t zstencil = util_pack64_z_stencil(dst->format, depth, stencil); 401 struct pipe_box box; 402 u_box_2d(dstx, dsty, width, height, &box); 403 if (dst->texture->target != PIPE_BUFFER) { 404 box.z = dst->u.tex.first_layer; 405 box.depth = dst->u.tex.last_layer - dst->u.tex.first_layer + 1; 406 } 407 for (unsigned s = 0; s < util_res_sample_count(dst->texture); s++) 408 lp_clear_depth_stencil_texture_msaa(pipe, dst->texture, 409 dst->format, clear_flags, 410 zstencil, s, &box); 411 } else 412 util_clear_depth_stencil(pipe, dst, clear_flags, 413 depth, stencil, 414 dstx, dsty, width, height); 415} 416 417static void 418llvmpipe_clear_texture(struct pipe_context *pipe, 419 struct pipe_resource *tex, 420 unsigned level, 421 const struct pipe_box *box, 422 const void *data) 423{ 424 const struct util_format_description *desc = 425 util_format_description(tex->format); 426 if (tex->nr_samples <= 1) { 427 util_clear_texture(pipe, tex, level, box, data); 428 return; 429 } 430 union pipe_color_union color; 431 432 if (util_format_is_depth_or_stencil(tex->format)) { 433 unsigned clear = 0; 434 float depth = 0.0f; 435 uint8_t stencil = 0; 436 uint64_t zstencil; 437 438 if (util_format_has_depth(desc)) { 439 clear |= PIPE_CLEAR_DEPTH; 440 util_format_unpack_z_float(tex->format, &depth, data, 1); 441 } 442 443 if (util_format_has_stencil(desc)) { 444 clear |= PIPE_CLEAR_STENCIL; 445 util_format_unpack_s_8uint(tex->format, &stencil, data, 1); 446 } 447 448 zstencil = util_pack64_z_stencil(tex->format, depth, stencil); 449 450 for (unsigned s = 0; s < util_res_sample_count(tex); s++) 451 lp_clear_depth_stencil_texture_msaa(pipe, tex, tex->format, clear, zstencil, 452 s, box); 453 } else { 454 util_format_unpack_rgba(tex->format, color.ui, data, 1); 455 456 for (unsigned s = 0; s < util_res_sample_count(tex); s++) { 457 lp_clear_color_texture_msaa(pipe, tex, tex->format, &color, s, 458 box); 459 } 460 } 461} 462 463static void 464llvmpipe_clear_buffer(struct pipe_context *pipe, 465 struct pipe_resource *res, 466 unsigned offset, 467 unsigned size, 468 const void *clear_value, 469 int clear_value_size) 470{ 471 struct pipe_transfer *dst_t; 472 struct pipe_box box; 473 char *dst; 474 u_box_1d(offset, size, &box); 475 476 dst = pipe->buffer_map(pipe, 477 res, 478 0, 479 PIPE_MAP_WRITE, 480 &box, 481 &dst_t); 482 483 switch (clear_value_size) { 484 case 1: 485 memset(dst, *(uint8_t *)clear_value, size); 486 break; 487 case 4: 488 util_memset32(dst, *(uint32_t *)clear_value, size / 4); 489 break; 490 default: 491 for (unsigned i = 0; i < size; i += clear_value_size) 492 memcpy(&dst[i], clear_value, clear_value_size); 493 break; 494 } 495 pipe->buffer_unmap(pipe, dst_t); 496} 497 498void 499llvmpipe_init_surface_functions(struct llvmpipe_context *lp) 500{ 501 lp->pipe.clear_render_target = llvmpipe_clear_render_target; 502 lp->pipe.clear_depth_stencil = llvmpipe_clear_depth_stencil; 503 lp->pipe.create_surface = llvmpipe_create_surface; 504 lp->pipe.surface_destroy = llvmpipe_surface_destroy; 505 /* These are not actually functions dealing with surfaces */ 506 lp->pipe.clear_texture = llvmpipe_clear_texture; 507 lp->pipe.clear_buffer = llvmpipe_clear_buffer; 508 lp->pipe.resource_copy_region = lp_resource_copy; 509 lp->pipe.blit = lp_blit; 510 lp->pipe.flush_resource = lp_flush_resource; 511 lp->pipe.get_sample_position = llvmpipe_get_sample_position; 512} 513