1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg#include "util/u_rect.h" 29848b8605Smrg#include "util/u_surface.h" 30848b8605Smrg#include "lp_context.h" 31848b8605Smrg#include "lp_flush.h" 32848b8605Smrg#include "lp_limits.h" 33848b8605Smrg#include "lp_surface.h" 34848b8605Smrg#include "lp_texture.h" 35848b8605Smrg#include "lp_query.h" 36848b8605Smrg 37848b8605Smrg 38848b8605Smrgstatic void 39848b8605Smrglp_resource_copy(struct pipe_context *pipe, 40848b8605Smrg struct pipe_resource *dst, unsigned dst_level, 41848b8605Smrg unsigned dstx, unsigned dsty, unsigned dstz, 42848b8605Smrg struct pipe_resource *src, unsigned src_level, 43848b8605Smrg const struct pipe_box *src_box) 44848b8605Smrg{ 45848b8605Smrg llvmpipe_flush_resource(pipe, 46848b8605Smrg dst, dst_level, 47848b8605Smrg FALSE, /* read_only */ 48848b8605Smrg TRUE, /* cpu_access */ 49848b8605Smrg FALSE, /* do_not_block */ 50848b8605Smrg "blit dest"); 51848b8605Smrg 52848b8605Smrg llvmpipe_flush_resource(pipe, 53848b8605Smrg src, src_level, 54848b8605Smrg TRUE, /* read_only */ 55848b8605Smrg TRUE, /* cpu_access */ 56848b8605Smrg FALSE, /* do_not_block */ 57848b8605Smrg "blit src"); 58848b8605Smrg 59b8e80941Smrg util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 60b8e80941Smrg src, src_level, src_box); 61848b8605Smrg} 62848b8605Smrg 63848b8605Smrg 64848b8605Smrgstatic void lp_blit(struct pipe_context *pipe, 65848b8605Smrg const struct pipe_blit_info *blit_info) 66848b8605Smrg{ 67848b8605Smrg struct llvmpipe_context *lp = llvmpipe_context(pipe); 68848b8605Smrg struct pipe_blit_info info = *blit_info; 69848b8605Smrg 70848b8605Smrg if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp)) 71848b8605Smrg return; 72848b8605Smrg 73848b8605Smrg if (info.src.resource->nr_samples > 1 && 74848b8605Smrg info.dst.resource->nr_samples <= 1 && 75848b8605Smrg !util_format_is_depth_or_stencil(info.src.resource->format) && 76848b8605Smrg !util_format_is_pure_integer(info.src.resource->format)) { 77848b8605Smrg debug_printf("llvmpipe: color resolve unimplemented\n"); 78848b8605Smrg return; 79848b8605Smrg } 80848b8605Smrg 81848b8605Smrg if (util_try_blit_via_copy_region(pipe, &info)) { 82848b8605Smrg return; /* done */ 83848b8605Smrg } 84848b8605Smrg 85848b8605Smrg if (!util_blitter_is_blit_supported(lp->blitter, &info)) { 86848b8605Smrg debug_printf("llvmpipe: blit unsupported %s -> %s\n", 87848b8605Smrg util_format_short_name(info.src.resource->format), 88848b8605Smrg util_format_short_name(info.dst.resource->format)); 89848b8605Smrg return; 90848b8605Smrg } 91848b8605Smrg 92848b8605Smrg /* XXX turn off occlusion and streamout queries */ 93848b8605Smrg 94848b8605Smrg util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer); 95848b8605Smrg util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems); 96848b8605Smrg util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs); 97848b8605Smrg util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs); 98848b8605Smrg util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, 99848b8605Smrg (struct pipe_stream_output_target**)lp->so_targets); 100848b8605Smrg util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); 101848b8605Smrg util_blitter_save_viewport(lp->blitter, &lp->viewports[0]); 102848b8605Smrg util_blitter_save_scissor(lp->blitter, &lp->scissors[0]); 103848b8605Smrg util_blitter_save_fragment_shader(lp->blitter, lp->fs); 104848b8605Smrg util_blitter_save_blend(lp->blitter, (void*)lp->blend); 105848b8605Smrg util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil); 106848b8605Smrg util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref); 107848b8605Smrg /*util_blitter_save_sample_mask(sp->blitter, lp->sample_mask);*/ 108848b8605Smrg util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer); 109848b8605Smrg util_blitter_save_fragment_sampler_states(lp->blitter, 110848b8605Smrg lp->num_samplers[PIPE_SHADER_FRAGMENT], 111848b8605Smrg (void**)lp->samplers[PIPE_SHADER_FRAGMENT]); 112848b8605Smrg util_blitter_save_fragment_sampler_views(lp->blitter, 113848b8605Smrg lp->num_sampler_views[PIPE_SHADER_FRAGMENT], 114848b8605Smrg lp->sampler_views[PIPE_SHADER_FRAGMENT]); 115848b8605Smrg util_blitter_save_render_condition(lp->blitter, lp->render_cond_query, 116848b8605Smrg lp->render_cond_cond, lp->render_cond_mode); 117848b8605Smrg util_blitter_blit(lp->blitter, &info); 118848b8605Smrg} 119848b8605Smrg 120848b8605Smrg 121848b8605Smrgstatic void 122848b8605Smrglp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) 123848b8605Smrg{ 124848b8605Smrg} 125848b8605Smrg 126848b8605Smrg 127848b8605Smrgstatic struct pipe_surface * 128848b8605Smrgllvmpipe_create_surface(struct pipe_context *pipe, 129848b8605Smrg struct pipe_resource *pt, 130848b8605Smrg const struct pipe_surface *surf_tmpl) 131848b8605Smrg{ 132848b8605Smrg struct pipe_surface *ps; 133848b8605Smrg 134b8e80941Smrg if (!(pt->bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET))) { 135848b8605Smrg debug_printf("Illegal surface creation without bind flag\n"); 136b8e80941Smrg if (util_format_is_depth_or_stencil(surf_tmpl->format)) { 137b8e80941Smrg pt->bind |= PIPE_BIND_DEPTH_STENCIL; 138b8e80941Smrg } 139b8e80941Smrg else { 140b8e80941Smrg pt->bind |= PIPE_BIND_RENDER_TARGET; 141b8e80941Smrg } 142b8e80941Smrg } 143848b8605Smrg 144848b8605Smrg ps = CALLOC_STRUCT(pipe_surface); 145848b8605Smrg if (ps) { 146848b8605Smrg pipe_reference_init(&ps->reference, 1); 147848b8605Smrg pipe_resource_reference(&ps->texture, pt); 148848b8605Smrg ps->context = pipe; 149848b8605Smrg ps->format = surf_tmpl->format; 150848b8605Smrg if (llvmpipe_resource_is_texture(pt)) { 151848b8605Smrg assert(surf_tmpl->u.tex.level <= pt->last_level); 152848b8605Smrg assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer); 153848b8605Smrg ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); 154848b8605Smrg ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); 155848b8605Smrg ps->u.tex.level = surf_tmpl->u.tex.level; 156848b8605Smrg ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; 157848b8605Smrg ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; 158848b8605Smrg } 159848b8605Smrg else { 160848b8605Smrg /* setting width as number of elements should get us correct renderbuffer width */ 161848b8605Smrg ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1; 162848b8605Smrg ps->height = pt->height0; 163848b8605Smrg ps->u.buf.first_element = surf_tmpl->u.buf.first_element; 164848b8605Smrg ps->u.buf.last_element = surf_tmpl->u.buf.last_element; 165848b8605Smrg assert(ps->u.buf.first_element <= ps->u.buf.last_element); 166848b8605Smrg assert(util_format_get_blocksize(surf_tmpl->format) * 167848b8605Smrg (ps->u.buf.last_element + 1) <= pt->width0); 168848b8605Smrg } 169848b8605Smrg } 170848b8605Smrg return ps; 171848b8605Smrg} 172848b8605Smrg 173848b8605Smrg 174848b8605Smrgstatic void 175848b8605Smrgllvmpipe_surface_destroy(struct pipe_context *pipe, 176848b8605Smrg struct pipe_surface *surf) 177848b8605Smrg{ 178848b8605Smrg /* Effectively do the texture_update work here - if texture images 179848b8605Smrg * needed post-processing to put them into hardware layout, this is 180848b8605Smrg * where it would happen. For llvmpipe, nothing to do. 181848b8605Smrg */ 182848b8605Smrg assert(surf->texture); 183848b8605Smrg pipe_resource_reference(&surf->texture, NULL); 184848b8605Smrg FREE(surf); 185848b8605Smrg} 186848b8605Smrg 187848b8605Smrg 188848b8605Smrgstatic void 189848b8605Smrgllvmpipe_clear_render_target(struct pipe_context *pipe, 190848b8605Smrg struct pipe_surface *dst, 191848b8605Smrg const union pipe_color_union *color, 192848b8605Smrg unsigned dstx, unsigned dsty, 193b8e80941Smrg unsigned width, unsigned height, 194b8e80941Smrg bool render_condition_enabled) 195848b8605Smrg{ 196848b8605Smrg struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 197848b8605Smrg 198b8e80941Smrg if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) 199848b8605Smrg return; 200848b8605Smrg 201848b8605Smrg util_clear_render_target(pipe, dst, color, 202848b8605Smrg dstx, dsty, width, height); 203848b8605Smrg} 204848b8605Smrg 205848b8605Smrg 206848b8605Smrgstatic void 207848b8605Smrgllvmpipe_clear_depth_stencil(struct pipe_context *pipe, 208848b8605Smrg struct pipe_surface *dst, 209848b8605Smrg unsigned clear_flags, 210848b8605Smrg double depth, 211848b8605Smrg unsigned stencil, 212848b8605Smrg unsigned dstx, unsigned dsty, 213b8e80941Smrg unsigned width, unsigned height, 214b8e80941Smrg bool render_condition_enabled) 215848b8605Smrg{ 216848b8605Smrg struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 217848b8605Smrg 218b8e80941Smrg if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe)) 219848b8605Smrg return; 220848b8605Smrg 221848b8605Smrg util_clear_depth_stencil(pipe, dst, clear_flags, 222848b8605Smrg depth, stencil, 223848b8605Smrg dstx, dsty, width, height); 224848b8605Smrg} 225848b8605Smrg 226848b8605Smrg 227848b8605Smrgvoid 228848b8605Smrgllvmpipe_init_surface_functions(struct llvmpipe_context *lp) 229848b8605Smrg{ 230848b8605Smrg lp->pipe.clear_render_target = llvmpipe_clear_render_target; 231848b8605Smrg lp->pipe.clear_depth_stencil = llvmpipe_clear_depth_stencil; 232848b8605Smrg lp->pipe.create_surface = llvmpipe_create_surface; 233848b8605Smrg lp->pipe.surface_destroy = llvmpipe_surface_destroy; 234b8e80941Smrg /* These are not actually functions dealing with surfaces */ 235b8e80941Smrg lp->pipe.clear_texture = util_clear_texture; 236848b8605Smrg lp->pipe.resource_copy_region = lp_resource_copy; 237848b8605Smrg lp->pipe.blit = lp_blit; 238848b8605Smrg lp->pipe.flush_resource = lp_flush_resource; 239848b8605Smrg} 240