diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_surface.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_surface.c | 169 |
1 files changed, 101 insertions, 68 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 8e905b8d7a0..cf5e4a48cdd 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 VMware, Inc. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include "util/u_rect.h" @@ -36,6 +36,7 @@ #include "lp_query.h" #include "lp_rast.h" + static void lp_resource_copy_ms(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, @@ -44,19 +45,18 @@ lp_resource_copy_ms(struct pipe_context *pipe, const struct pipe_box *src_box) { struct pipe_box dst_box = *src_box; - enum pipe_format src_format; dst_box.x = dstx; dst_box.y = dsty; dst_box.z = dstz; - src_format = src->format; + enum pipe_format src_format = src->format; - for (unsigned i = 0; i < src->nr_samples; i++) { + for (unsigned i = 0; i < MAX2(src->nr_samples, dst->nr_samples); i++) { struct pipe_transfer *src_trans, *dst_trans; - const uint8_t *src_map = llvmpipe_transfer_map_ms(pipe, - src, 0, PIPE_MAP_READ, i, - src_box, - &src_trans); + const uint8_t *src_map = + llvmpipe_transfer_map_ms(pipe,src, 0, PIPE_MAP_READ, + MIN2(i, src->nr_samples - 1), + src_box, &src_trans); if (!src_map) return; @@ -81,6 +81,8 @@ lp_resource_copy_ms(struct pipe_context *pipe, pipe->texture_unmap(pipe, src_trans); } } + + static void lp_resource_copy(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, @@ -90,20 +92,21 @@ lp_resource_copy(struct pipe_context *pipe, { llvmpipe_flush_resource(pipe, dst, dst_level, - FALSE, /* read_only */ - TRUE, /* cpu_access */ - FALSE, /* do_not_block */ + false, /* read_only */ + true, /* cpu_access */ + false, /* do_not_block */ "blit dest"); llvmpipe_flush_resource(pipe, src, src_level, - TRUE, /* read_only */ - TRUE, /* cpu_access */ - FALSE, /* do_not_block */ + true, /* read_only */ + true, /* cpu_access */ + false, /* do_not_block */ "blit src"); if (dst->nr_samples > 1 && - dst->nr_samples == src->nr_samples) { + (dst->nr_samples == src->nr_samples || + (src->nr_samples == 1 && dst->nr_samples > 1))) { lp_resource_copy_ms(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; @@ -113,8 +116,9 @@ lp_resource_copy(struct pipe_context *pipe, } -static void lp_blit(struct pipe_context *pipe, - const struct pipe_blit_info *blit_info) +static void +lp_blit(struct pipe_context *pipe, + const struct pipe_blit_info *blit_info) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct pipe_blit_info info = *blit_info; @@ -122,10 +126,25 @@ static void lp_blit(struct pipe_context *pipe, if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp)) return; - if (util_try_blit_via_copy_region(pipe, &info)) { + if (util_try_blit_via_copy_region(pipe, &info, + lp->render_cond_query != NULL)) { return; /* done */ } + if (blit_info->src.resource->format == blit_info->src.format && + blit_info->dst.resource->format == blit_info->dst.format && + blit_info->src.format == blit_info->dst.format && + blit_info->src.resource->nr_samples > 1 && + blit_info->dst.resource->nr_samples < 2 && + blit_info->sample0_only) { + 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, + blit_info->src.resource, blit_info->src.level, + &blit_info->src.box); + return; + } + if (!util_blitter_is_blit_supported(lp->blitter, &info)) { debug_printf("llvmpipe: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), @@ -136,20 +155,20 @@ static void lp_blit(struct pipe_context *pipe, /* for 32-bit unorm depth, avoid the conversions to float and back, which can introduce accuracy errors. */ if (blit_info->src.format == PIPE_FORMAT_Z32_UNORM && - blit_info->dst.format == PIPE_FORMAT_Z32_UNORM && info.filter == PIPE_TEX_FILTER_NEAREST) { + blit_info->dst.format == PIPE_FORMAT_Z32_UNORM && + info.filter == PIPE_TEX_FILTER_NEAREST) { info.src.format = PIPE_FORMAT_R32_UINT; info.dst.format = PIPE_FORMAT_R32_UINT; info.mask = PIPE_MASK_R; } - /* XXX turn off occlusion and streamout queries */ - - util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer); + util_blitter_save_vertex_buffers(lp->blitter, lp->vertex_buffer, + lp->num_vertex_buffers); util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems); util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs); util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs); util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, - (struct pipe_stream_output_target**)lp->so_targets); + (struct pipe_stream_output_target**)lp->so_targets); util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); util_blitter_save_viewport(lp->blitter, &lp->viewports[0]); util_blitter_save_scissor(lp->blitter, &lp->scissors[0]); @@ -157,9 +176,11 @@ static void lp_blit(struct pipe_context *pipe, util_blitter_save_blend(lp->blitter, (void*)lp->blend); util_blitter_save_tessctrl_shader(lp->blitter, (void*)lp->tcs); util_blitter_save_tesseval_shader(lp->blitter, (void*)lp->tes); - util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil); + util_blitter_save_depth_stencil_alpha(lp->blitter, + (void*)lp->depth_stencil); util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref); - util_blitter_save_sample_mask(lp->blitter, lp->sample_mask); + util_blitter_save_sample_mask(lp->blitter, lp->sample_mask, + lp->min_samples); util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer); util_blitter_save_fragment_sampler_states(lp->blitter, lp->num_samplers[PIPE_SHADER_FRAGMENT], @@ -168,7 +189,8 @@ static void lp_blit(struct pipe_context *pipe, lp->num_sampler_views[PIPE_SHADER_FRAGMENT], lp->sampler_views[PIPE_SHADER_FRAGMENT]); util_blitter_save_render_condition(lp->blitter, lp->render_cond_query, - lp->render_cond_cond, lp->render_cond_mode); + lp->render_cond_cond, + lp->render_cond_mode); util_blitter_blit(lp->blitter, &info); } @@ -176,6 +198,7 @@ static void lp_blit(struct pipe_context *pipe, static void lp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) { + llvmpipe_flush_resource(ctx, resource, 0, true, true, false, "resource"); } @@ -184,8 +207,6 @@ llvmpipe_create_surface(struct pipe_context *pipe, struct pipe_resource *pt, const struct pipe_surface *surf_tmpl) { - struct pipe_surface *ps; - if (!(pt->bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET))) { debug_printf("Illegal surface creation without bind flag\n"); if (util_format_is_depth_or_stencil(surf_tmpl->format)) { @@ -196,7 +217,7 @@ llvmpipe_create_surface(struct pipe_context *pipe, } } - ps = CALLOC_STRUCT(pipe_surface); + struct pipe_surface *ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); pipe_resource_reference(&ps->texture, pt); @@ -210,10 +231,12 @@ llvmpipe_create_surface(struct pipe_context *pipe, ps->u.tex.level = surf_tmpl->u.tex.level; ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; - } - else { - /* setting width as number of elements should get us correct renderbuffer width */ - ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1; + } else { + /* setting width as number of elements should get us correct + * renderbuffer width + */ + ps->width = surf_tmpl->u.buf.last_element + - surf_tmpl->u.buf.first_element + 1; ps->height = pt->height0; ps->u.buf.first_element = surf_tmpl->u.buf.first_element; ps->u.buf.last_element = surf_tmpl->u.buf.last_element; @@ -240,7 +263,6 @@ llvmpipe_surface_destroy(struct pipe_context *pipe, } - static void llvmpipe_get_sample_position(struct pipe_context *pipe, unsigned sample_count, @@ -257,12 +279,14 @@ llvmpipe_get_sample_position(struct pipe_context *pipe, } } + static void lp_clear_color_texture_helper(struct pipe_transfer *dst_trans, - ubyte *dst_map, - enum pipe_format format, - const union pipe_color_union *color, - unsigned width, unsigned height, unsigned depth) + uint8_t *dst_map, + enum pipe_format format, + const union pipe_color_union *color, + unsigned width, unsigned height, + unsigned depth) { union util_color uc; @@ -275,6 +299,7 @@ lp_clear_color_texture_helper(struct pipe_transfer *dst_trans, 0, 0, 0, width, height, depth, &uc); } + static void lp_clear_color_texture_msaa(struct pipe_context *pipe, struct pipe_resource *texture, @@ -284,7 +309,7 @@ lp_clear_color_texture_msaa(struct pipe_context *pipe, const struct pipe_box *box) { struct pipe_transfer *dst_trans; - ubyte *dst_map; + uint8_t *dst_map; dst_map = llvmpipe_transfer_map_ms(pipe, texture, 0, PIPE_MAP_WRITE, sample, box, &dst_trans); @@ -298,6 +323,7 @@ lp_clear_color_texture_msaa(struct pipe_context *pipe, pipe->texture_unmap(pipe, dst_trans); } + static void llvmpipe_clear_render_target(struct pipe_context *pipe, struct pipe_surface *dst, @@ -311,6 +337,9 @@ llvmpipe_clear_render_target(struct pipe_context *pipe, if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) return; + width = MIN2(width, dst->texture->width0 - dstx); + height = MIN2(height, dst->texture->height0 - dsty); + if (dst->texture->nr_samples > 1) { struct pipe_box box; u_box_2d(dstx, dsty, width, height, &box); @@ -322,9 +351,10 @@ llvmpipe_clear_render_target(struct pipe_context *pipe, lp_clear_color_texture_msaa(pipe, dst->texture, dst->format, color, s, &box); } - } else + } else { util_clear_render_target(pipe, dst, color, dstx, dsty, width, height); + } } @@ -337,20 +367,20 @@ lp_clear_depth_stencil_texture_msaa(struct pipe_context *pipe, const struct pipe_box *box) { struct pipe_transfer *dst_trans; - ubyte *dst_map; - boolean need_rmw = FALSE; + bool need_rmw = false; if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && - util_format_is_depth_and_stencil(format)) - need_rmw = TRUE; - - dst_map = llvmpipe_transfer_map_ms(pipe, - texture, - 0, - (need_rmw ? PIPE_MAP_READ_WRITE : - PIPE_MAP_WRITE), - sample, box, &dst_trans); + util_format_is_depth_and_stencil(format)) { + need_rmw = true; + } + + uint8_t *dst_map = llvmpipe_transfer_map_ms(pipe, + texture, + 0, + (need_rmw ? PIPE_MAP_READ_WRITE : + PIPE_MAP_WRITE), + sample, box, &dst_trans); assert(dst_map); if (!dst_map) return; @@ -358,12 +388,13 @@ lp_clear_depth_stencil_texture_msaa(struct pipe_context *pipe, assert(dst_trans->stride > 0); util_fill_zs_box(dst_map, format, need_rmw, clear_flags, - dst_trans->stride, dst_trans->layer_stride, - box->width, box->height, box->depth, zstencil); + dst_trans->stride, dst_trans->layer_stride, + box->width, box->height, box->depth, zstencil); pipe->texture_unmap(pipe, dst_trans); } + static void llvmpipe_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *dst, @@ -379,6 +410,9 @@ llvmpipe_clear_depth_stencil(struct pipe_context *pipe, if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) return; + width = MIN2(width, dst->texture->width0 - dstx); + height = MIN2(height, dst->texture->height0 - dsty); + if (dst->texture->nr_samples > 1) { uint64_t zstencil = util_pack64_z_stencil(dst->format, depth, stencil); struct pipe_box box; @@ -391,12 +425,14 @@ llvmpipe_clear_depth_stencil(struct pipe_context *pipe, lp_clear_depth_stencil_texture_msaa(pipe, dst->texture, dst->format, clear_flags, zstencil, s, &box); - } else + } else { util_clear_depth_stencil(pipe, dst, clear_flags, depth, stencil, dstx, dsty, width, height); + } } + static void llvmpipe_clear_texture(struct pipe_context *pipe, struct pipe_resource *tex, @@ -407,7 +443,7 @@ llvmpipe_clear_texture(struct pipe_context *pipe, const struct util_format_description *desc = util_format_description(tex->format); if (tex->nr_samples <= 1) { - util_clear_texture(pipe, tex, level, box, data); + util_clear_texture_sw(pipe, tex, level, box, data); return; } union pipe_color_union color; @@ -431,8 +467,8 @@ llvmpipe_clear_texture(struct pipe_context *pipe, zstencil = util_pack64_z_stencil(tex->format, depth, stencil); for (unsigned s = 0; s < util_res_sample_count(tex); s++) - lp_clear_depth_stencil_texture_msaa(pipe, tex, tex->format, clear, zstencil, - s, box); + lp_clear_depth_stencil_texture_msaa(pipe, tex, tex->format, clear, + zstencil, s, box); } else { util_format_unpack_rgba(tex->format, color.ui, data, 1); @@ -443,6 +479,7 @@ llvmpipe_clear_texture(struct pipe_context *pipe, } } + static void llvmpipe_clear_buffer(struct pipe_context *pipe, struct pipe_resource *res, @@ -453,15 +490,10 @@ llvmpipe_clear_buffer(struct pipe_context *pipe, { struct pipe_transfer *dst_t; struct pipe_box box; - char *dst; + u_box_1d(offset, size, &box); - dst = pipe->buffer_map(pipe, - res, - 0, - PIPE_MAP_WRITE, - &box, - &dst_t); + char *dst = pipe->buffer_map(pipe, res, 0, PIPE_MAP_WRITE, &box, &dst_t); switch (clear_value_size) { case 1: @@ -478,6 +510,7 @@ llvmpipe_clear_buffer(struct pipe_context *pipe, pipe->buffer_unmap(pipe, dst_t); } + void llvmpipe_init_surface_functions(struct llvmpipe_context *lp) { |