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