X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_surface.c;h=953b26e8cdbab4ad858e5d1cc8e6c4a0788325d2;hb=f90a60fe7951c7cd063581770e7a3860c253ced3;hp=6110b0a193e654b209fdb6da8007131398c6c8de;hpb=7549a8397b310acf672f97a08c8e7d866cdf492c;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 6110b0a193e..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,25 +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" static void -lp_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) +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) +{ + 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_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) { - util_surface_copy(pipe, FALSE, - dest, destx, desty, - src, srcx, srcy, - width, height); } + +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; + } + } + + 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; +} + + +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; }