14a49301eSmrg/************************************************************************** 24a49301eSmrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 134a49301eSmrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 174a49301eSmrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254a49301eSmrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 284a49301eSmrg#include "util/u_rect.h" 293464ebd5Sriastradh#include "util/u_surface.h" 307ec681f3Smrg#include "util/u_memset.h" 314a49301eSmrg#include "lp_context.h" 323464ebd5Sriastradh#include "lp_flush.h" 333464ebd5Sriastradh#include "lp_limits.h" 344a49301eSmrg#include "lp_surface.h" 353464ebd5Sriastradh#include "lp_texture.h" 36af69d88dSmrg#include "lp_query.h" 377ec681f3Smrg#include "lp_rast.h" 383464ebd5Sriastradh 397ec681f3Smrgstatic void 407ec681f3Smrglp_resource_copy_ms(struct pipe_context *pipe, 417ec681f3Smrg struct pipe_resource *dst, unsigned dst_level, 427ec681f3Smrg unsigned dstx, unsigned dsty, unsigned dstz, 437ec681f3Smrg struct pipe_resource *src, unsigned src_level, 447ec681f3Smrg const struct pipe_box *src_box) 457ec681f3Smrg{ 467ec681f3Smrg struct pipe_box dst_box = *src_box; 477ec681f3Smrg enum pipe_format src_format; 487ec681f3Smrg dst_box.x = dstx; 497ec681f3Smrg dst_box.y = dsty; 507ec681f3Smrg dst_box.z = dstz; 517ec681f3Smrg 527ec681f3Smrg src_format = src->format; 533464ebd5Sriastradh 547ec681f3Smrg for (unsigned i = 0; i < src->nr_samples; i++) { 557ec681f3Smrg struct pipe_transfer *src_trans, *dst_trans; 567ec681f3Smrg const uint8_t *src_map = llvmpipe_transfer_map_ms(pipe, 577ec681f3Smrg src, 0, PIPE_MAP_READ, i, 587ec681f3Smrg src_box, 597ec681f3Smrg &src_trans); 607ec681f3Smrg if (!src_map) 617ec681f3Smrg return; 627ec681f3Smrg 637ec681f3Smrg uint8_t *dst_map = llvmpipe_transfer_map_ms(pipe, 647ec681f3Smrg dst, 0, PIPE_MAP_WRITE, i, 657ec681f3Smrg &dst_box, 667ec681f3Smrg &dst_trans); 677ec681f3Smrg if (!dst_map) { 687ec681f3Smrg pipe->texture_unmap(pipe, src_trans); 697ec681f3Smrg return; 707ec681f3Smrg } 717ec681f3Smrg 727ec681f3Smrg util_copy_box(dst_map, 737ec681f3Smrg src_format, 747ec681f3Smrg dst_trans->stride, dst_trans->layer_stride, 757ec681f3Smrg 0, 0, 0, 767ec681f3Smrg src_box->width, src_box->height, src_box->depth, 777ec681f3Smrg src_map, 787ec681f3Smrg src_trans->stride, src_trans->layer_stride, 797ec681f3Smrg 0, 0, 0); 807ec681f3Smrg pipe->texture_unmap(pipe, dst_trans); 817ec681f3Smrg pipe->texture_unmap(pipe, src_trans); 827ec681f3Smrg } 837ec681f3Smrg} 843464ebd5Sriastradhstatic void 853464ebd5Sriastradhlp_resource_copy(struct pipe_context *pipe, 863464ebd5Sriastradh struct pipe_resource *dst, unsigned dst_level, 873464ebd5Sriastradh unsigned dstx, unsigned dsty, unsigned dstz, 883464ebd5Sriastradh struct pipe_resource *src, unsigned src_level, 893464ebd5Sriastradh const struct pipe_box *src_box) 903464ebd5Sriastradh{ 913464ebd5Sriastradh llvmpipe_flush_resource(pipe, 92af69d88dSmrg dst, dst_level, 933464ebd5Sriastradh FALSE, /* read_only */ 943464ebd5Sriastradh TRUE, /* cpu_access */ 953464ebd5Sriastradh FALSE, /* do_not_block */ 963464ebd5Sriastradh "blit dest"); 973464ebd5Sriastradh 983464ebd5Sriastradh llvmpipe_flush_resource(pipe, 99af69d88dSmrg src, src_level, 1003464ebd5Sriastradh TRUE, /* read_only */ 1013464ebd5Sriastradh TRUE, /* cpu_access */ 1023464ebd5Sriastradh FALSE, /* do_not_block */ 1033464ebd5Sriastradh "blit src"); 1043464ebd5Sriastradh 1057ec681f3Smrg if (dst->nr_samples > 1 && 1067ec681f3Smrg dst->nr_samples == src->nr_samples) { 1077ec681f3Smrg lp_resource_copy_ms(pipe, dst, dst_level, dstx, dsty, dstz, 1087ec681f3Smrg src, src_level, src_box); 1097ec681f3Smrg return; 1107ec681f3Smrg } 11101e04c3fSmrg util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 11201e04c3fSmrg src, src_level, src_box); 113af69d88dSmrg} 114af69d88dSmrg 115af69d88dSmrg 116af69d88dSmrgstatic void lp_blit(struct pipe_context *pipe, 117af69d88dSmrg const struct pipe_blit_info *blit_info) 118af69d88dSmrg{ 119af69d88dSmrg struct llvmpipe_context *lp = llvmpipe_context(pipe); 120af69d88dSmrg struct pipe_blit_info info = *blit_info; 121af69d88dSmrg 122af69d88dSmrg if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp)) 123af69d88dSmrg return; 124af69d88dSmrg 125af69d88dSmrg if (util_try_blit_via_copy_region(pipe, &info)) { 126af69d88dSmrg return; /* done */ 127af69d88dSmrg } 128af69d88dSmrg 129af69d88dSmrg if (!util_blitter_is_blit_supported(lp->blitter, &info)) { 130af69d88dSmrg debug_printf("llvmpipe: blit unsupported %s -> %s\n", 131af69d88dSmrg util_format_short_name(info.src.resource->format), 132af69d88dSmrg util_format_short_name(info.dst.resource->format)); 133af69d88dSmrg return; 134af69d88dSmrg } 135af69d88dSmrg 1367ec681f3Smrg /* for 32-bit unorm depth, avoid the conversions to float and back, 1377ec681f3Smrg which can introduce accuracy errors. */ 1387ec681f3Smrg if (blit_info->src.format == PIPE_FORMAT_Z32_UNORM && 1397ec681f3Smrg blit_info->dst.format == PIPE_FORMAT_Z32_UNORM && info.filter == PIPE_TEX_FILTER_NEAREST) { 1407ec681f3Smrg info.src.format = PIPE_FORMAT_R32_UINT; 1417ec681f3Smrg info.dst.format = PIPE_FORMAT_R32_UINT; 1427ec681f3Smrg info.mask = PIPE_MASK_R; 1437ec681f3Smrg } 1447ec681f3Smrg 145af69d88dSmrg /* XXX turn off occlusion and streamout queries */ 146af69d88dSmrg 147af69d88dSmrg util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer); 148af69d88dSmrg util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems); 149af69d88dSmrg util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs); 150af69d88dSmrg util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs); 151af69d88dSmrg util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, 152af69d88dSmrg (struct pipe_stream_output_target**)lp->so_targets); 153af69d88dSmrg util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); 154af69d88dSmrg util_blitter_save_viewport(lp->blitter, &lp->viewports[0]); 155af69d88dSmrg util_blitter_save_scissor(lp->blitter, &lp->scissors[0]); 156af69d88dSmrg util_blitter_save_fragment_shader(lp->blitter, lp->fs); 157af69d88dSmrg util_blitter_save_blend(lp->blitter, (void*)lp->blend); 1587ec681f3Smrg util_blitter_save_tessctrl_shader(lp->blitter, (void*)lp->tcs); 1597ec681f3Smrg util_blitter_save_tesseval_shader(lp->blitter, (void*)lp->tes); 160af69d88dSmrg util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil); 161af69d88dSmrg util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref); 1627ec681f3Smrg util_blitter_save_sample_mask(lp->blitter, lp->sample_mask); 163af69d88dSmrg util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer); 164af69d88dSmrg util_blitter_save_fragment_sampler_states(lp->blitter, 165af69d88dSmrg lp->num_samplers[PIPE_SHADER_FRAGMENT], 166af69d88dSmrg (void**)lp->samplers[PIPE_SHADER_FRAGMENT]); 167af69d88dSmrg util_blitter_save_fragment_sampler_views(lp->blitter, 168af69d88dSmrg lp->num_sampler_views[PIPE_SHADER_FRAGMENT], 169af69d88dSmrg lp->sampler_views[PIPE_SHADER_FRAGMENT]); 170af69d88dSmrg util_blitter_save_render_condition(lp->blitter, lp->render_cond_query, 171af69d88dSmrg lp->render_cond_cond, lp->render_cond_mode); 172af69d88dSmrg util_blitter_blit(lp->blitter, &info); 173af69d88dSmrg} 174af69d88dSmrg 175af69d88dSmrg 176af69d88dSmrgstatic void 177af69d88dSmrglp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) 178af69d88dSmrg{ 179af69d88dSmrg} 180af69d88dSmrg 181af69d88dSmrg 182af69d88dSmrgstatic struct pipe_surface * 183af69d88dSmrgllvmpipe_create_surface(struct pipe_context *pipe, 184af69d88dSmrg struct pipe_resource *pt, 185af69d88dSmrg const struct pipe_surface *surf_tmpl) 186af69d88dSmrg{ 187af69d88dSmrg struct pipe_surface *ps; 188af69d88dSmrg 18901e04c3fSmrg if (!(pt->bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET))) { 190af69d88dSmrg debug_printf("Illegal surface creation without bind flag\n"); 19101e04c3fSmrg if (util_format_is_depth_or_stencil(surf_tmpl->format)) { 19201e04c3fSmrg pt->bind |= PIPE_BIND_DEPTH_STENCIL; 19301e04c3fSmrg } 19401e04c3fSmrg else { 19501e04c3fSmrg pt->bind |= PIPE_BIND_RENDER_TARGET; 19601e04c3fSmrg } 19701e04c3fSmrg } 198af69d88dSmrg 199af69d88dSmrg ps = CALLOC_STRUCT(pipe_surface); 200af69d88dSmrg if (ps) { 201af69d88dSmrg pipe_reference_init(&ps->reference, 1); 202af69d88dSmrg pipe_resource_reference(&ps->texture, pt); 203af69d88dSmrg ps->context = pipe; 204af69d88dSmrg ps->format = surf_tmpl->format; 205af69d88dSmrg if (llvmpipe_resource_is_texture(pt)) { 206af69d88dSmrg assert(surf_tmpl->u.tex.level <= pt->last_level); 207af69d88dSmrg assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer); 208af69d88dSmrg ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); 209af69d88dSmrg ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); 210af69d88dSmrg ps->u.tex.level = surf_tmpl->u.tex.level; 211af69d88dSmrg ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; 212af69d88dSmrg ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; 213af69d88dSmrg } 214af69d88dSmrg else { 215af69d88dSmrg /* setting width as number of elements should get us correct renderbuffer width */ 216af69d88dSmrg ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1; 217af69d88dSmrg ps->height = pt->height0; 218af69d88dSmrg ps->u.buf.first_element = surf_tmpl->u.buf.first_element; 219af69d88dSmrg ps->u.buf.last_element = surf_tmpl->u.buf.last_element; 220af69d88dSmrg assert(ps->u.buf.first_element <= ps->u.buf.last_element); 221af69d88dSmrg assert(util_format_get_blocksize(surf_tmpl->format) * 222af69d88dSmrg (ps->u.buf.last_element + 1) <= pt->width0); 223af69d88dSmrg } 224af69d88dSmrg } 225af69d88dSmrg return ps; 226af69d88dSmrg} 227af69d88dSmrg 228af69d88dSmrg 229af69d88dSmrgstatic void 230af69d88dSmrgllvmpipe_surface_destroy(struct pipe_context *pipe, 231af69d88dSmrg struct pipe_surface *surf) 232af69d88dSmrg{ 233af69d88dSmrg /* Effectively do the texture_update work here - if texture images 234af69d88dSmrg * needed post-processing to put them into hardware layout, this is 235af69d88dSmrg * where it would happen. For llvmpipe, nothing to do. 236af69d88dSmrg */ 237af69d88dSmrg assert(surf->texture); 238af69d88dSmrg pipe_resource_reference(&surf->texture, NULL); 239af69d88dSmrg FREE(surf); 240af69d88dSmrg} 241af69d88dSmrg 242af69d88dSmrg 2437ec681f3Smrg 2447ec681f3Smrgstatic void 2457ec681f3Smrgllvmpipe_get_sample_position(struct pipe_context *pipe, 2467ec681f3Smrg unsigned sample_count, 2477ec681f3Smrg unsigned sample_index, 2487ec681f3Smrg float *out_value) 2497ec681f3Smrg{ 2507ec681f3Smrg switch (sample_count) { 2517ec681f3Smrg case 4: 2527ec681f3Smrg out_value[0] = lp_sample_pos_4x[sample_index][0]; 2537ec681f3Smrg out_value[1] = lp_sample_pos_4x[sample_index][1]; 2547ec681f3Smrg break; 2557ec681f3Smrg default: 2567ec681f3Smrg break; 2577ec681f3Smrg } 2587ec681f3Smrg} 2597ec681f3Smrg 2607ec681f3Smrgstatic void 2617ec681f3Smrglp_clear_color_texture_helper(struct pipe_transfer *dst_trans, 2627ec681f3Smrg ubyte *dst_map, 2637ec681f3Smrg enum pipe_format format, 2647ec681f3Smrg const union pipe_color_union *color, 2657ec681f3Smrg unsigned width, unsigned height, unsigned depth) 2667ec681f3Smrg{ 2677ec681f3Smrg union util_color uc; 2687ec681f3Smrg 2697ec681f3Smrg assert(dst_trans->stride > 0); 2707ec681f3Smrg 2717ec681f3Smrg util_pack_color_union(format, &uc, color); 2727ec681f3Smrg 2737ec681f3Smrg util_fill_box(dst_map, format, 2747ec681f3Smrg dst_trans->stride, dst_trans->layer_stride, 2757ec681f3Smrg 0, 0, 0, width, height, depth, &uc); 2767ec681f3Smrg} 2777ec681f3Smrg 2787ec681f3Smrgstatic void 2797ec681f3Smrglp_clear_color_texture_msaa(struct pipe_context *pipe, 2807ec681f3Smrg struct pipe_resource *texture, 2817ec681f3Smrg enum pipe_format format, 2827ec681f3Smrg const union pipe_color_union *color, 2837ec681f3Smrg unsigned sample, 2847ec681f3Smrg const struct pipe_box *box) 2857ec681f3Smrg{ 2867ec681f3Smrg struct pipe_transfer *dst_trans; 2877ec681f3Smrg ubyte *dst_map; 2887ec681f3Smrg 2897ec681f3Smrg dst_map = llvmpipe_transfer_map_ms(pipe, texture, 0, PIPE_MAP_WRITE, 2907ec681f3Smrg sample, box, &dst_trans); 2917ec681f3Smrg if (!dst_map) 2927ec681f3Smrg return; 2937ec681f3Smrg 2947ec681f3Smrg if (dst_trans->stride > 0) { 2957ec681f3Smrg lp_clear_color_texture_helper(dst_trans, dst_map, format, color, 2967ec681f3Smrg box->width, box->height, box->depth); 2977ec681f3Smrg } 2987ec681f3Smrg pipe->texture_unmap(pipe, dst_trans); 2997ec681f3Smrg} 3007ec681f3Smrg 301af69d88dSmrgstatic void 302af69d88dSmrgllvmpipe_clear_render_target(struct pipe_context *pipe, 303af69d88dSmrg struct pipe_surface *dst, 304af69d88dSmrg const union pipe_color_union *color, 305af69d88dSmrg unsigned dstx, unsigned dsty, 30601e04c3fSmrg unsigned width, unsigned height, 30701e04c3fSmrg bool render_condition_enabled) 308af69d88dSmrg{ 309af69d88dSmrg struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 310af69d88dSmrg 31101e04c3fSmrg if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) 312af69d88dSmrg return; 313af69d88dSmrg 3147ec681f3Smrg if (dst->texture->nr_samples > 1) { 3157ec681f3Smrg struct pipe_box box; 3167ec681f3Smrg u_box_2d(dstx, dsty, width, height, &box); 3177ec681f3Smrg if (dst->texture->target != PIPE_BUFFER) { 3187ec681f3Smrg box.z = dst->u.tex.first_layer; 3197ec681f3Smrg box.depth = dst->u.tex.last_layer - dst->u.tex.first_layer + 1; 3207ec681f3Smrg } 3217ec681f3Smrg for (unsigned s = 0; s < util_res_sample_count(dst->texture); s++) { 3227ec681f3Smrg lp_clear_color_texture_msaa(pipe, dst->texture, dst->format, 3237ec681f3Smrg color, s, &box); 3247ec681f3Smrg } 3257ec681f3Smrg } else 3267ec681f3Smrg util_clear_render_target(pipe, dst, color, 3277ec681f3Smrg dstx, dsty, width, height); 328af69d88dSmrg} 329af69d88dSmrg 330af69d88dSmrg 3317ec681f3Smrgstatic void 3327ec681f3Smrglp_clear_depth_stencil_texture_msaa(struct pipe_context *pipe, 3337ec681f3Smrg struct pipe_resource *texture, 3347ec681f3Smrg enum pipe_format format, 3357ec681f3Smrg unsigned clear_flags, 3367ec681f3Smrg uint64_t zstencil, unsigned sample, 3377ec681f3Smrg const struct pipe_box *box) 3387ec681f3Smrg{ 3397ec681f3Smrg struct pipe_transfer *dst_trans; 3407ec681f3Smrg ubyte *dst_map; 3417ec681f3Smrg boolean need_rmw = FALSE; 3427ec681f3Smrg 3437ec681f3Smrg if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && 3447ec681f3Smrg ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && 3457ec681f3Smrg util_format_is_depth_and_stencil(format)) 3467ec681f3Smrg need_rmw = TRUE; 3477ec681f3Smrg 3487ec681f3Smrg dst_map = llvmpipe_transfer_map_ms(pipe, 3497ec681f3Smrg texture, 3507ec681f3Smrg 0, 3517ec681f3Smrg (need_rmw ? PIPE_MAP_READ_WRITE : 3527ec681f3Smrg PIPE_MAP_WRITE), 3537ec681f3Smrg sample, box, &dst_trans); 3547ec681f3Smrg assert(dst_map); 3557ec681f3Smrg if (!dst_map) 3567ec681f3Smrg return; 3577ec681f3Smrg 3587ec681f3Smrg assert(dst_trans->stride > 0); 3597ec681f3Smrg 3607ec681f3Smrg util_fill_zs_box(dst_map, format, need_rmw, clear_flags, 3617ec681f3Smrg dst_trans->stride, dst_trans->layer_stride, 3627ec681f3Smrg box->width, box->height, box->depth, zstencil); 3637ec681f3Smrg 3647ec681f3Smrg pipe->texture_unmap(pipe, dst_trans); 3657ec681f3Smrg} 3667ec681f3Smrg 367af69d88dSmrgstatic void 368af69d88dSmrgllvmpipe_clear_depth_stencil(struct pipe_context *pipe, 369af69d88dSmrg struct pipe_surface *dst, 370af69d88dSmrg unsigned clear_flags, 371af69d88dSmrg double depth, 372af69d88dSmrg unsigned stencil, 373af69d88dSmrg unsigned dstx, unsigned dsty, 37401e04c3fSmrg unsigned width, unsigned height, 37501e04c3fSmrg bool render_condition_enabled) 376af69d88dSmrg{ 377af69d88dSmrg struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 378af69d88dSmrg 37901e04c3fSmrg if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) 380af69d88dSmrg return; 381af69d88dSmrg 3827ec681f3Smrg if (dst->texture->nr_samples > 1) { 3837ec681f3Smrg uint64_t zstencil = util_pack64_z_stencil(dst->format, depth, stencil); 3847ec681f3Smrg struct pipe_box box; 3857ec681f3Smrg u_box_2d(dstx, dsty, width, height, &box); 3867ec681f3Smrg if (dst->texture->target != PIPE_BUFFER) { 3877ec681f3Smrg box.z = dst->u.tex.first_layer; 3887ec681f3Smrg box.depth = dst->u.tex.last_layer - dst->u.tex.first_layer + 1; 3897ec681f3Smrg } 3907ec681f3Smrg for (unsigned s = 0; s < util_res_sample_count(dst->texture); s++) 3917ec681f3Smrg lp_clear_depth_stencil_texture_msaa(pipe, dst->texture, 3927ec681f3Smrg dst->format, clear_flags, 3937ec681f3Smrg zstencil, s, &box); 3947ec681f3Smrg } else 3957ec681f3Smrg util_clear_depth_stencil(pipe, dst, clear_flags, 3967ec681f3Smrg depth, stencil, 3977ec681f3Smrg dstx, dsty, width, height); 3983464ebd5Sriastradh} 3993464ebd5Sriastradh 4007ec681f3Smrgstatic void 4017ec681f3Smrgllvmpipe_clear_texture(struct pipe_context *pipe, 4027ec681f3Smrg struct pipe_resource *tex, 4037ec681f3Smrg unsigned level, 4047ec681f3Smrg const struct pipe_box *box, 4057ec681f3Smrg const void *data) 4067ec681f3Smrg{ 4077ec681f3Smrg const struct util_format_description *desc = 4087ec681f3Smrg util_format_description(tex->format); 4097ec681f3Smrg if (tex->nr_samples <= 1) { 4107ec681f3Smrg util_clear_texture(pipe, tex, level, box, data); 4117ec681f3Smrg return; 4127ec681f3Smrg } 4137ec681f3Smrg union pipe_color_union color; 4147ec681f3Smrg 4157ec681f3Smrg if (util_format_is_depth_or_stencil(tex->format)) { 4167ec681f3Smrg unsigned clear = 0; 4177ec681f3Smrg float depth = 0.0f; 4187ec681f3Smrg uint8_t stencil = 0; 4197ec681f3Smrg uint64_t zstencil; 4207ec681f3Smrg 4217ec681f3Smrg if (util_format_has_depth(desc)) { 4227ec681f3Smrg clear |= PIPE_CLEAR_DEPTH; 4237ec681f3Smrg util_format_unpack_z_float(tex->format, &depth, data, 1); 4247ec681f3Smrg } 4257ec681f3Smrg 4267ec681f3Smrg if (util_format_has_stencil(desc)) { 4277ec681f3Smrg clear |= PIPE_CLEAR_STENCIL; 4287ec681f3Smrg util_format_unpack_s_8uint(tex->format, &stencil, data, 1); 4297ec681f3Smrg } 4307ec681f3Smrg 4317ec681f3Smrg zstencil = util_pack64_z_stencil(tex->format, depth, stencil); 4327ec681f3Smrg 4337ec681f3Smrg for (unsigned s = 0; s < util_res_sample_count(tex); s++) 4347ec681f3Smrg lp_clear_depth_stencil_texture_msaa(pipe, tex, tex->format, clear, zstencil, 4357ec681f3Smrg s, box); 4367ec681f3Smrg } else { 4377ec681f3Smrg util_format_unpack_rgba(tex->format, color.ui, data, 1); 4387ec681f3Smrg 4397ec681f3Smrg for (unsigned s = 0; s < util_res_sample_count(tex); s++) { 4407ec681f3Smrg lp_clear_color_texture_msaa(pipe, tex, tex->format, &color, s, 4417ec681f3Smrg box); 4427ec681f3Smrg } 4437ec681f3Smrg } 4447ec681f3Smrg} 4457ec681f3Smrg 4467ec681f3Smrgstatic void 4477ec681f3Smrgllvmpipe_clear_buffer(struct pipe_context *pipe, 4487ec681f3Smrg struct pipe_resource *res, 4497ec681f3Smrg unsigned offset, 4507ec681f3Smrg unsigned size, 4517ec681f3Smrg const void *clear_value, 4527ec681f3Smrg int clear_value_size) 4537ec681f3Smrg{ 4547ec681f3Smrg struct pipe_transfer *dst_t; 4557ec681f3Smrg struct pipe_box box; 4567ec681f3Smrg char *dst; 4577ec681f3Smrg u_box_1d(offset, size, &box); 4587ec681f3Smrg 4597ec681f3Smrg dst = pipe->buffer_map(pipe, 4607ec681f3Smrg res, 4617ec681f3Smrg 0, 4627ec681f3Smrg PIPE_MAP_WRITE, 4637ec681f3Smrg &box, 4647ec681f3Smrg &dst_t); 4657ec681f3Smrg 4667ec681f3Smrg switch (clear_value_size) { 4677ec681f3Smrg case 1: 4687ec681f3Smrg memset(dst, *(uint8_t *)clear_value, size); 4697ec681f3Smrg break; 4707ec681f3Smrg case 4: 4717ec681f3Smrg util_memset32(dst, *(uint32_t *)clear_value, size / 4); 4727ec681f3Smrg break; 4737ec681f3Smrg default: 4747ec681f3Smrg for (unsigned i = 0; i < size; i += clear_value_size) 4757ec681f3Smrg memcpy(&dst[i], clear_value, clear_value_size); 4767ec681f3Smrg break; 4777ec681f3Smrg } 4787ec681f3Smrg pipe->buffer_unmap(pipe, dst_t); 4797ec681f3Smrg} 4803464ebd5Sriastradh 4814a49301eSmrgvoid 4823464ebd5Sriastradhllvmpipe_init_surface_functions(struct llvmpipe_context *lp) 4834a49301eSmrg{ 484af69d88dSmrg lp->pipe.clear_render_target = llvmpipe_clear_render_target; 485af69d88dSmrg lp->pipe.clear_depth_stencil = llvmpipe_clear_depth_stencil; 486af69d88dSmrg lp->pipe.create_surface = llvmpipe_create_surface; 487af69d88dSmrg lp->pipe.surface_destroy = llvmpipe_surface_destroy; 48801e04c3fSmrg /* These are not actually functions dealing with surfaces */ 4897ec681f3Smrg lp->pipe.clear_texture = llvmpipe_clear_texture; 4907ec681f3Smrg lp->pipe.clear_buffer = llvmpipe_clear_buffer; 4913464ebd5Sriastradh lp->pipe.resource_copy_region = lp_resource_copy; 492af69d88dSmrg lp->pipe.blit = lp_blit; 493af69d88dSmrg lp->pipe.flush_resource = lp_flush_resource; 4947ec681f3Smrg lp->pipe.get_sample_position = llvmpipe_get_sample_position; 4954a49301eSmrg} 496