X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_surface.c;h=953b26e8cdbab4ad858e5d1cc8e6c4a0788325d2;hb=f90a60fe7951c7cd063581770e7a3860c253ced3;hp=1432782cefa70af82584c948aa98917aa47b627a;hpb=7567f05199f1ca114cc57e3a11ac101d3707f819;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 1432782cefa..953b26e8cdb 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * 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. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * 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. @@ -26,128 +26,214 @@ **************************************************************************/ #include "util/u_rect.h" +#include "util/u_surface.h" #include "lp_context.h" #include "lp_flush.h" #include "lp_limits.h" #include "lp_surface.h" #include "lp_texture.h" +#include "lp_query.h" -/** - * Adjust x, y, width, height to lie on tile bounds. - */ static void -adjust_to_tile_bounds(unsigned x, unsigned y, unsigned width, unsigned height, - unsigned *x_tile, unsigned *y_tile, - unsigned *w_tile, unsigned *h_tile) +lp_resource_copy(struct pipe_context *pipe, + struct pipe_resource *dst, unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box) { - *x_tile = x & ~(TILE_SIZE - 1); - *y_tile = y & ~(TILE_SIZE - 1); - *w_tile = ((x + width + TILE_SIZE - 1) & ~(TILE_SIZE - 1)) - *x_tile; - *h_tile = ((y + height + TILE_SIZE - 1) & ~(TILE_SIZE - 1)) - *y_tile; + llvmpipe_flush_resource(pipe, + dst, dst_level, + 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 */ + "blit src"); + + util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); } +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; + + if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp)) + return; + + if (info.src.resource->nr_samples > 1 && + info.dst.resource->nr_samples <= 1 && + !util_format_is_depth_or_stencil(info.src.resource->format) && + !util_format_is_pure_integer(info.src.resource->format)) { + debug_printf("llvmpipe: color resolve unimplemented\n"); + return; + } + + if (util_try_blit_via_copy_region(pipe, &info)) { + return; /* done */ + } + + 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), + util_format_short_name(info.dst.resource->format)); + return; + } + + /* XXX turn off occlusion and streamout queries */ + + util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer); + 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); + 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]); + util_blitter_save_fragment_shader(lp->blitter, lp->fs); + util_blitter_save_blend(lp->blitter, (void*)lp->blend); + 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(sp->blitter, lp->sample_mask);*/ + util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer); + util_blitter_save_fragment_sampler_states(lp->blitter, + lp->num_samplers[PIPE_SHADER_FRAGMENT], + (void**)lp->samplers[PIPE_SHADER_FRAGMENT]); + util_blitter_save_fragment_sampler_views(lp->blitter, + 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); + util_blitter_blit(lp->blitter, &info); +} + static void -lp_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dst, unsigned dstx, unsigned dsty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) +lp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) { - struct llvmpipe_resource *src_tex = llvmpipe_resource(src->texture); - struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst->texture); - const enum pipe_format format = src_tex->base.format; +} - llvmpipe_flush_resource(pipe, - dst->texture, dst->face, dst->level, - 0, /* flush_flags */ - FALSE, /* read_only */ - FALSE, /* cpu_access */ - FALSE); /* do_not_block */ - llvmpipe_flush_resource(pipe, - src->texture, src->face, src->level, - 0, /* flush_flags */ - TRUE, /* read_only */ - FALSE, /* cpu_access */ - FALSE); /* do_not_block */ - - /* - printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n", - src_tex->id, dst_tex->id, - srcx, srcy, dstx, dsty, width, height); - */ - - /* set src tiles to linear layout */ - { - unsigned tx, ty, tw, th; - unsigned x, y; - - adjust_to_tile_bounds(srcx, srcy, width, height, &tx, &ty, &tw, &th); - - for (y = 0; y < th; y += TILE_SIZE) { - for (x = 0; x < tw; x += TILE_SIZE) { - (void) llvmpipe_get_texture_tile_linear(src_tex, - src->face, src->level, - LP_TEX_USAGE_READ, - tx + x, ty + y); - } +static struct pipe_surface * +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)) { + pt->bind |= PIPE_BIND_DEPTH_STENCIL; + } + else { + pt->bind |= PIPE_BIND_RENDER_TARGET; } } - /* set dst tiles to linear layout */ - { - unsigned tx, ty, tw, th; - unsigned x, y; - enum lp_texture_usage usage; - - /* XXX for the tiles which are completely contained by the - * dest rectangle, we could set the usage mode to WRITE_ALL. - * Just test for the case of replacing the whole dest region for now. - */ - if (width == dst_tex->base.width0 && height == dst_tex->base.height0) - usage = LP_TEX_USAGE_WRITE_ALL; - else - usage = LP_TEX_USAGE_READ_WRITE; - - adjust_to_tile_bounds(dstx, dsty, width, height, &tx, &ty, &tw, &th); - - for (y = 0; y < th; y += TILE_SIZE) { - for (x = 0; x < tw; x += TILE_SIZE) { - (void) llvmpipe_get_texture_tile_linear(dst_tex, - dst->face, dst->level, - usage, - tx + x, ty + y); - } + ps = CALLOC_STRUCT(pipe_surface); + if (ps) { + pipe_reference_init(&ps->reference, 1); + pipe_resource_reference(&ps->texture, pt); + ps->context = pipe; + ps->format = surf_tmpl->format; + if (llvmpipe_resource_is_texture(pt)) { + assert(surf_tmpl->u.tex.level <= pt->last_level); + assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer); + ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); + ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); + 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; + 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; + assert(ps->u.buf.first_element <= ps->u.buf.last_element); + assert(util_format_get_blocksize(surf_tmpl->format) * + (ps->u.buf.last_element + 1) <= pt->width0); } } + return ps; +} - /* copy */ - { - const ubyte *src_linear_ptr - = llvmpipe_get_texture_image_address(src_tex, src->face, - src->level, - LP_TEX_LAYOUT_LINEAR); - ubyte *dst_linear_ptr - = llvmpipe_get_texture_image_address(dst_tex, dst->face, - dst->level, - LP_TEX_LAYOUT_LINEAR); - - util_copy_rect(dst_linear_ptr, format, - llvmpipe_resource_stride(&dst_tex->base, dst->level), - dstx, dsty, - width, height, - src_linear_ptr, - llvmpipe_resource_stride(&src_tex->base, src->level), - srcx, srcy); - } + +static void +llvmpipe_surface_destroy(struct pipe_context *pipe, + struct pipe_surface *surf) +{ + /* Effectively do the texture_update work here - if texture images + * needed post-processing to put them into hardware layout, this is + * where it would happen. For llvmpipe, nothing to do. + */ + assert(surf->texture); + pipe_resource_reference(&surf->texture, NULL); + FREE(surf); +} + + +static void +llvmpipe_clear_render_target(struct pipe_context *pipe, + struct pipe_surface *dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) + return; + + util_clear_render_target(pipe, dst, color, + dstx, dsty, width, height); +} + + +static void +llvmpipe_clear_depth_stencil(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) + return; + + util_clear_depth_stencil(pipe, dst, clear_flags, + depth, stencil, + dstx, dsty, width, height); } void -lp_init_surface_functions(struct llvmpipe_context *lp) +llvmpipe_init_surface_functions(struct llvmpipe_context *lp) { - lp->pipe.surface_copy = lp_surface_copy; - lp->pipe.surface_fill = util_surface_fill; + lp->pipe.clear_render_target = llvmpipe_clear_render_target; + lp->pipe.clear_depth_stencil = llvmpipe_clear_depth_stencil; + lp->pipe.create_surface = llvmpipe_create_surface; + lp->pipe.surface_destroy = llvmpipe_surface_destroy; + /* These are not actually functions dealing with surfaces */ + lp->pipe.clear_texture = util_clear_texture; + lp->pipe.resource_copy_region = lp_resource_copy; + lp->pipe.blit = lp_blit; + lp->pipe.flush_resource = lp_flush_resource; }