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