14a49301eSmrg/************************************************************************** 27ec681f3Smrg * 3af69d88dSmrg * Copyright 2003 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 57ec681f3Smrg * 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: 137ec681f3Smrg * 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. 177ec681f3Smrg * 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. 257ec681f3Smrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 283464ebd5Sriastradh#include "i915_surface.h" 294a49301eSmrg#include "pipe/p_defines.h" 307ec681f3Smrg#include "util/format/u_format.h" 313464ebd5Sriastradh#include "util/u_inlines.h" 323464ebd5Sriastradh#include "util/u_math.h" 333464ebd5Sriastradh#include "util/u_memory.h" 343464ebd5Sriastradh#include "util/u_pack_color.h" 353464ebd5Sriastradh#include "util/u_surface.h" 367ec681f3Smrg#include "i915_blit.h" 377ec681f3Smrg#include "i915_reg.h" 387ec681f3Smrg#include "i915_resource.h" 397ec681f3Smrg#include "i915_screen.h" 407ec681f3Smrg#include "i915_state.h" 414a49301eSmrg 42af69d88dSmrgstatic struct pipe_surface * 437ec681f3Smrgi915_create_surface_custom(struct pipe_context *ctx, struct pipe_resource *pt, 44af69d88dSmrg const struct pipe_surface *surf_tmpl, 457ec681f3Smrg unsigned width0, unsigned height0); 463464ebd5Sriastradh/* 473464ebd5Sriastradh * surface functions using the render engine 483464ebd5Sriastradh */ 493464ebd5Sriastradh 503464ebd5Sriastradhstatic void 51af69d88dSmrgi915_util_blitter_save_states(struct i915_context *i915) 523464ebd5Sriastradh{ 533464ebd5Sriastradh util_blitter_save_blend(i915->blitter, (void *)i915->blend); 547ec681f3Smrg util_blitter_save_depth_stencil_alpha(i915->blitter, 557ec681f3Smrg (void *)i915->depth_stencil); 563464ebd5Sriastradh util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref); 573464ebd5Sriastradh util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer); 58af69d88dSmrg util_blitter_save_fragment_shader(i915->blitter, i915->fs); 59af69d88dSmrg util_blitter_save_vertex_shader(i915->blitter, i915->vs); 603464ebd5Sriastradh util_blitter_save_viewport(i915->blitter, &i915->viewport); 61af69d88dSmrg util_blitter_save_scissor(i915->blitter, &i915->scissor); 62af69d88dSmrg util_blitter_save_vertex_elements(i915->blitter, i915->velems); 637ec681f3Smrg util_blitter_save_vertex_buffer_slot(i915->blitter, i915->vertex_buffers); 643464ebd5Sriastradh 653464ebd5Sriastradh util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); 663464ebd5Sriastradh 677ec681f3Smrg util_blitter_save_fragment_sampler_states(i915->blitter, i915->num_samplers, 687ec681f3Smrg (void **)i915->fragment_sampler); 693464ebd5Sriastradh util_blitter_save_fragment_sampler_views(i915->blitter, 70af69d88dSmrg i915->num_fragment_sampler_views, 71af69d88dSmrg i915->fragment_sampler_views); 723464ebd5Sriastradh} 7301e04c3fSmrg 74af69d88dSmrgstatic void 757ec681f3Smrgi915_surface_copy_render(struct pipe_context *pipe, struct pipe_resource *dst, 767ec681f3Smrg unsigned dst_level, unsigned dstx, unsigned dsty, 777ec681f3Smrg unsigned dstz, struct pipe_resource *src, 787ec681f3Smrg unsigned src_level, const struct pipe_box *src_box) 79af69d88dSmrg{ 80af69d88dSmrg struct i915_context *i915 = i915_context(pipe); 81af69d88dSmrg unsigned src_width0 = src->width0; 82af69d88dSmrg unsigned src_height0 = src->height0; 83af69d88dSmrg unsigned dst_width0 = dst->width0; 84af69d88dSmrg unsigned dst_height0 = dst->height0; 85af69d88dSmrg struct pipe_box dstbox; 86af69d88dSmrg struct pipe_sampler_view src_templ, *src_view; 87af69d88dSmrg struct pipe_surface dst_templ, *dst_view; 8801e04c3fSmrg const struct util_format_description *desc; 8901e04c3fSmrg 9001e04c3fSmrg /* Fallback for buffers. */ 9101e04c3fSmrg if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) 9201e04c3fSmrg goto fallback; 93af69d88dSmrg 9401e04c3fSmrg /* Fallback for depth&stencil. XXX: see if we can use a proxy format */ 9501e04c3fSmrg desc = util_format_description(src->format); 9601e04c3fSmrg if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 9701e04c3fSmrg goto fallback; 9801e04c3fSmrg 9901e04c3fSmrg desc = util_format_description(dst->format); 10001e04c3fSmrg if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 101af69d88dSmrg goto fallback; 102af69d88dSmrg 103af69d88dSmrg util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 10401e04c3fSmrg util_blitter_default_src_texture(i915->blitter, &src_templ, src, src_level); 105af69d88dSmrg 106af69d88dSmrg if (!util_blitter_is_copy_supported(i915->blitter, dst, src)) 107af69d88dSmrg goto fallback; 108af69d88dSmrg 109af69d88dSmrg i915_util_blitter_save_states(i915); 110af69d88dSmrg 1117ec681f3Smrg dst_view = i915_create_surface_custom(pipe, dst, &dst_templ, dst_width0, 1127ec681f3Smrg dst_height0); 1137ec681f3Smrg src_view = i915_create_sampler_view_custom(pipe, src, &src_templ, src_width0, 1147ec681f3Smrg src_height0); 115af69d88dSmrg 116af69d88dSmrg u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), 117af69d88dSmrg abs(src_box->depth), &dstbox); 118af69d88dSmrg 1197ec681f3Smrg util_blitter_blit_generic(i915->blitter, dst_view, &dstbox, src_view, 1207ec681f3Smrg src_box, src_width0, src_height0, PIPE_MASK_RGBAZS, 1217ec681f3Smrg PIPE_TEX_FILTER_NEAREST, NULL, false, false); 122af69d88dSmrg return; 123af69d88dSmrg 124af69d88dSmrgfallback: 1257ec681f3Smrg util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, 1267ec681f3Smrg src_level, src_box); 12701e04c3fSmrg} 1283464ebd5Sriastradh 1293464ebd5Sriastradhstatic void 1303464ebd5Sriastradhi915_clear_render_target_render(struct pipe_context *pipe, 1313464ebd5Sriastradh struct pipe_surface *dst, 132af69d88dSmrg const union pipe_color_union *color, 1337ec681f3Smrg unsigned dstx, unsigned dsty, unsigned width, 1347ec681f3Smrg unsigned height, bool render_condition_enabled) 1353464ebd5Sriastradh{ 1363464ebd5Sriastradh struct i915_context *i915 = i915_context(pipe); 1373464ebd5Sriastradh struct pipe_framebuffer_state fb_state; 1383464ebd5Sriastradh 1393464ebd5Sriastradh util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); 1403464ebd5Sriastradh 1413464ebd5Sriastradh fb_state.width = dst->width; 1423464ebd5Sriastradh fb_state.height = dst->height; 1433464ebd5Sriastradh fb_state.nr_cbufs = 1; 1443464ebd5Sriastradh fb_state.cbufs[0] = dst; 1453464ebd5Sriastradh fb_state.zsbuf = NULL; 1463464ebd5Sriastradh pipe->set_framebuffer_state(pipe, &fb_state); 1473464ebd5Sriastradh 1483464ebd5Sriastradh if (i915->dirty) 1493464ebd5Sriastradh i915_update_derived(i915); 1503464ebd5Sriastradh 1517ec681f3Smrg i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0, dstx, dsty, width, 1527ec681f3Smrg height); 1533464ebd5Sriastradh 1543464ebd5Sriastradh pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); 1553464ebd5Sriastradh util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); 1563464ebd5Sriastradh i915->blitter->saved_fb_state.nr_cbufs = ~0; 1573464ebd5Sriastradh} 1583464ebd5Sriastradh 1593464ebd5Sriastradhstatic void 1603464ebd5Sriastradhi915_clear_depth_stencil_render(struct pipe_context *pipe, 1617ec681f3Smrg struct pipe_surface *dst, unsigned clear_flags, 1627ec681f3Smrg double depth, unsigned stencil, unsigned dstx, 1637ec681f3Smrg unsigned dsty, unsigned width, unsigned height, 16401e04c3fSmrg bool render_condition_enabled) 1653464ebd5Sriastradh{ 1663464ebd5Sriastradh struct i915_context *i915 = i915_context(pipe); 1673464ebd5Sriastradh struct pipe_framebuffer_state fb_state; 1683464ebd5Sriastradh 1693464ebd5Sriastradh util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); 1703464ebd5Sriastradh 1713464ebd5Sriastradh fb_state.width = dst->width; 1723464ebd5Sriastradh fb_state.height = dst->height; 1733464ebd5Sriastradh fb_state.nr_cbufs = 0; 1743464ebd5Sriastradh fb_state.zsbuf = dst; 1753464ebd5Sriastradh pipe->set_framebuffer_state(pipe, &fb_state); 1763464ebd5Sriastradh 1773464ebd5Sriastradh if (i915->dirty) 1783464ebd5Sriastradh i915_update_derived(i915); 1793464ebd5Sriastradh 1807ec681f3Smrg i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL, NULL, depth, 1817ec681f3Smrg stencil, dstx, dsty, width, height); 1823464ebd5Sriastradh 1833464ebd5Sriastradh pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); 1843464ebd5Sriastradh util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); 1853464ebd5Sriastradh i915->blitter->saved_fb_state.nr_cbufs = ~0; 1863464ebd5Sriastradh} 1873464ebd5Sriastradh 1883464ebd5Sriastradh/* 1893464ebd5Sriastradh * surface functions using the blitter 1903464ebd5Sriastradh */ 1914a49301eSmrg 1924a49301eSmrg/* Assumes all values are within bounds -- no checking at this level - 1934a49301eSmrg * do it higher up if required. 1944a49301eSmrg */ 1954a49301eSmrgstatic void 1967ec681f3Smrgi915_surface_copy_blitter(struct pipe_context *pipe, struct pipe_resource *dst, 1977ec681f3Smrg unsigned dst_level, unsigned dstx, unsigned dsty, 1987ec681f3Smrg unsigned dstz, struct pipe_resource *src, 1997ec681f3Smrg unsigned src_level, const struct pipe_box *src_box) 2004a49301eSmrg{ 2013464ebd5Sriastradh /* Fallback for buffers. */ 2023464ebd5Sriastradh if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 2037ec681f3Smrg util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, 2047ec681f3Smrg src_level, src_box); 2053464ebd5Sriastradh return; 2063464ebd5Sriastradh } 2073464ebd5Sriastradh 2087ec681f3Smrg struct i915_texture *dst_tex = i915_texture(dst); 2097ec681f3Smrg struct i915_texture *src_tex = i915_texture(src); 2107ec681f3Smrg struct pipe_resource *dpt = &dst_tex->b; 2117ec681f3Smrg ASSERTED struct pipe_resource *spt = &src_tex->b; 2127ec681f3Smrg unsigned dst_offset, src_offset; /* in bytes */ 2137ec681f3Smrg 2143464ebd5Sriastradh /* XXX cannot copy 3d regions at this time */ 2153464ebd5Sriastradh assert(src_box->depth == 1); 2167ec681f3Smrg if (dst->target != PIPE_TEXTURE_CUBE && dst->target != PIPE_TEXTURE_3D) 2173464ebd5Sriastradh assert(dstz == 0); 2183464ebd5Sriastradh dst_offset = i915_texture_offset(dst_tex, dst_level, dstz); 2193464ebd5Sriastradh 2207ec681f3Smrg if (src->target != PIPE_TEXTURE_CUBE && src->target != PIPE_TEXTURE_3D) 2213464ebd5Sriastradh assert(src_box->z == 0); 2223464ebd5Sriastradh src_offset = i915_texture_offset(src_tex, src_level, src_box->z); 2234a49301eSmrg 2247ec681f3Smrg int block_width = util_format_get_blockwidth(dpt->format); 2257ec681f3Smrg int block_height = util_format_get_blockheight(dpt->format); 2267ec681f3Smrg int block_size = util_format_get_blocksize(dpt->format); 2277ec681f3Smrg assert(util_format_get_blocksize(spt->format) == block_size); 2287ec681f3Smrg assert(util_format_get_blockwidth(spt->format) == block_width); 2297ec681f3Smrg assert(util_format_get_blockheight(spt->format) == block_height); 2307ec681f3Smrg 2317ec681f3Smrg dstx /= block_width; 2327ec681f3Smrg dsty /= block_height; 2337ec681f3Smrg int srcx = src_box->x / block_width; 2347ec681f3Smrg int srcy = src_box->y / block_height; 2357ec681f3Smrg int width = DIV_ROUND_UP(src_box->width, block_width); 2367ec681f3Smrg int height = DIV_ROUND_UP(src_box->height, block_height); 2377ec681f3Smrg 2387ec681f3Smrg if (block_size > 4) { 2397ec681f3Smrg srcx *= (block_size / 4); 2407ec681f3Smrg dstx *= (block_size / 4); 2417ec681f3Smrg width *= (block_size / 4); 2427ec681f3Smrg block_size = 4; 2437ec681f3Smrg } 2447ec681f3Smrg 2457ec681f3Smrg i915_copy_blit(i915_context(pipe), block_size, 2467ec681f3Smrg (unsigned short)src_tex->stride, src_tex->buffer, src_offset, 2477ec681f3Smrg (unsigned short)dst_tex->stride, dst_tex->buffer, dst_offset, 2487ec681f3Smrg (short)srcx, (short)srcy, (short)dstx, (short)dsty, 2497ec681f3Smrg (short)width, (short)height); 2504a49301eSmrg} 2514a49301eSmrg 252af69d88dSmrgstatic void 253af69d88dSmrgi915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) 254af69d88dSmrg{ 255af69d88dSmrg struct i915_context *i915 = i915_context(pipe); 256af69d88dSmrg struct pipe_blit_info info = *blit_info; 257af69d88dSmrg 258af69d88dSmrg if (util_try_blit_via_copy_region(pipe, &info)) { 259af69d88dSmrg return; /* done */ 260af69d88dSmrg } 261af69d88dSmrg 262af69d88dSmrg if (info.mask & PIPE_MASK_S) { 263af69d88dSmrg debug_printf("i915: cannot blit stencil, skipping\n"); 264af69d88dSmrg info.mask &= ~PIPE_MASK_S; 265af69d88dSmrg } 266af69d88dSmrg 267af69d88dSmrg if (!util_blitter_is_blit_supported(i915->blitter, &info)) { 268af69d88dSmrg debug_printf("i915: blit unsupported %s -> %s\n", 269af69d88dSmrg util_format_short_name(info.src.resource->format), 270af69d88dSmrg util_format_short_name(info.dst.resource->format)); 271af69d88dSmrg return; 272af69d88dSmrg } 273af69d88dSmrg 274af69d88dSmrg i915_util_blitter_save_states(i915); 275af69d88dSmrg 276af69d88dSmrg util_blitter_blit(i915->blitter, &info); 277af69d88dSmrg} 278af69d88dSmrg 279af69d88dSmrgstatic void 280af69d88dSmrgi915_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) 281af69d88dSmrg{ 282af69d88dSmrg} 283af69d88dSmrg 2843464ebd5Sriastradhstatic void 2853464ebd5Sriastradhi915_clear_render_target_blitter(struct pipe_context *pipe, 2863464ebd5Sriastradh struct pipe_surface *dst, 287af69d88dSmrg const union pipe_color_union *color, 2887ec681f3Smrg unsigned dstx, unsigned dsty, unsigned width, 2897ec681f3Smrg unsigned height, bool render_condition_enabled) 2903464ebd5Sriastradh{ 2913464ebd5Sriastradh struct i915_texture *tex = i915_texture(dst->texture); 2927ec681f3Smrg struct pipe_resource *pt = &tex->b; 2933464ebd5Sriastradh union util_color uc; 2947ec681f3Smrg unsigned offset = 2957ec681f3Smrg i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); 2963464ebd5Sriastradh 2973464ebd5Sriastradh assert(util_format_get_blockwidth(pt->format) == 1); 2983464ebd5Sriastradh assert(util_format_get_blockheight(pt->format) == 1); 2993464ebd5Sriastradh 300af69d88dSmrg util_pack_color(color->f, dst->format, &uc); 3017ec681f3Smrg i915_fill_blit(i915_context(pipe), util_format_get_blocksize(pt->format), 3027ec681f3Smrg XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB, 3037ec681f3Smrg (unsigned short)tex->stride, tex->buffer, offset, (short)dstx, 3047ec681f3Smrg (short)dsty, (short)width, (short)height, uc.ui[0]); 3053464ebd5Sriastradh} 3064a49301eSmrg 3074a49301eSmrgstatic void 3083464ebd5Sriastradhi915_clear_depth_stencil_blitter(struct pipe_context *pipe, 3097ec681f3Smrg struct pipe_surface *dst, unsigned clear_flags, 3107ec681f3Smrg double depth, unsigned stencil, unsigned dstx, 3117ec681f3Smrg unsigned dsty, unsigned width, unsigned height, 31201e04c3fSmrg bool render_condition_enabled) 3134a49301eSmrg{ 3143464ebd5Sriastradh struct i915_texture *tex = i915_texture(dst->texture); 3157ec681f3Smrg struct pipe_resource *pt = &tex->b; 3163464ebd5Sriastradh unsigned packedds; 3173464ebd5Sriastradh unsigned mask = 0; 3187ec681f3Smrg unsigned offset = 3197ec681f3Smrg i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); 3204a49301eSmrg 321cdc920a0Smrg assert(util_format_get_blockwidth(pt->format) == 1); 322cdc920a0Smrg assert(util_format_get_blockheight(pt->format) == 1); 3234a49301eSmrg 3243464ebd5Sriastradh packedds = util_pack_z_stencil(dst->format, depth, stencil); 3253464ebd5Sriastradh 3263464ebd5Sriastradh if (clear_flags & PIPE_CLEAR_DEPTH) 3273464ebd5Sriastradh mask |= XY_COLOR_BLT_WRITE_RGB; 3283464ebd5Sriastradh /* XXX presumably this does read-modify-write 3293464ebd5Sriastradh (otherwise this won't work anyway). Hence will only want to 3303464ebd5Sriastradh do it if really have stencil and it isn't cleared */ 3313464ebd5Sriastradh if ((clear_flags & PIPE_CLEAR_STENCIL) || 332af69d88dSmrg (dst->format != PIPE_FORMAT_Z24_UNORM_S8_UINT)) 3333464ebd5Sriastradh mask |= XY_COLOR_BLT_WRITE_ALPHA; 3343464ebd5Sriastradh 3357ec681f3Smrg i915_fill_blit(i915_context(pipe), util_format_get_blocksize(pt->format), 3367ec681f3Smrg mask, (unsigned short)tex->stride, tex->buffer, offset, 3377ec681f3Smrg (short)dstx, (short)dsty, (short)width, (short)height, 3387ec681f3Smrg packedds); 3393464ebd5Sriastradh} 3403464ebd5Sriastradh 3413464ebd5Sriastradh/* 3423464ebd5Sriastradh * Screen surface functions 3433464ebd5Sriastradh */ 3443464ebd5Sriastradh 3457ec681f3Smrgstatic void 3467ec681f3Smrgi915_set_color_surface_swizzle(struct i915_surface *surf) 3477ec681f3Smrg{ 3487ec681f3Smrg enum pipe_format format = surf->templ.format; 3497ec681f3Smrg 3507ec681f3Smrg const struct { 3517ec681f3Smrg enum pipe_format format; 3527ec681f3Smrg uint8_t color_swizzle[4]; 3537ec681f3Smrg uint32_t oc_swizzle; 3547ec681f3Smrg } fixup_formats[] = { 3557ec681f3Smrg {PIPE_FORMAT_R8G8B8A8_UNORM, {2, 1, 0, 3}, 0x21030000 /* BGRA */}, 3567ec681f3Smrg {PIPE_FORMAT_R8G8B8X8_UNORM, {2, 1, 0, 3}, 0x21030000 /* BGRX */}, 3577ec681f3Smrg 3587ec681f3Smrg /* These are rendered to using COLORBUF_8BIT, where the G channel written 3597ec681f3Smrg * by shader (and output by blending) is used. 3607ec681f3Smrg */ 3617ec681f3Smrg {PIPE_FORMAT_L8_UNORM, {0, 0, 0, 0}, 0x00030000 /* RRRA */}, 3627ec681f3Smrg {PIPE_FORMAT_I8_UNORM, {0, 0, 0, 0}, 0x00030000 /* RRRA */}, 3637ec681f3Smrg {PIPE_FORMAT_A8_UNORM, {3, 3, 3, 3}, 0x33330000 /* AAAA */}, 3647ec681f3Smrg }; 3657ec681f3Smrg 3667ec681f3Smrg if (format == PIPE_FORMAT_A8_UNORM) 3677ec681f3Smrg surf->alpha_in_g = true; 3687ec681f3Smrg else if (util_format_is_rgbx_or_bgrx(format)) 3697ec681f3Smrg surf->alpha_is_x = true; 3707ec681f3Smrg 3717ec681f3Smrg for (int i = 0; i < ARRAY_SIZE(fixup_formats); i++) { 3727ec681f3Smrg if (fixup_formats[i].format == format) { 3737ec681f3Smrg memcpy(surf->color_swizzle, fixup_formats[i].color_swizzle, 3747ec681f3Smrg sizeof(surf->color_swizzle)); 3757ec681f3Smrg surf->oc_swizzle = fixup_formats[i].oc_swizzle; 3767ec681f3Smrg return; 3777ec681f3Smrg } 3787ec681f3Smrg } 3797ec681f3Smrg 3807ec681f3Smrg for (int i = 0; i < 4; i++) 3817ec681f3Smrg surf->color_swizzle[i] = i; 3827ec681f3Smrg} 3833464ebd5Sriastradh 3843464ebd5Sriastradhstatic struct pipe_surface * 3857ec681f3Smrgi915_create_surface_custom(struct pipe_context *ctx, struct pipe_resource *pt, 386af69d88dSmrg const struct pipe_surface *surf_tmpl, 3877ec681f3Smrg unsigned width0, unsigned height0) 3883464ebd5Sriastradh{ 3897ec681f3Smrg struct i915_texture *tex = i915_texture(pt); 3907ec681f3Smrg struct i915_surface *surf; 3913464ebd5Sriastradh 3923464ebd5Sriastradh assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); 3937ec681f3Smrg if (pt->target != PIPE_TEXTURE_CUBE && pt->target != PIPE_TEXTURE_3D) 3943464ebd5Sriastradh assert(surf_tmpl->u.tex.first_layer == 0); 3953464ebd5Sriastradh 3967ec681f3Smrg surf = CALLOC_STRUCT(i915_surface); 3977ec681f3Smrg if (!surf) 3987ec681f3Smrg return NULL; 3997ec681f3Smrg 4007ec681f3Smrg struct pipe_surface *ps = &surf->templ; 4017ec681f3Smrg 4027ec681f3Smrg pipe_reference_init(&ps->reference, 1); 4037ec681f3Smrg pipe_resource_reference(&ps->texture, pt); 4047ec681f3Smrg ps->format = surf_tmpl->format; 4057ec681f3Smrg ps->width = u_minify(width0, surf_tmpl->u.tex.level); 4067ec681f3Smrg ps->height = u_minify(height0, surf_tmpl->u.tex.level); 4077ec681f3Smrg ps->u.tex.level = surf_tmpl->u.tex.level; 4087ec681f3Smrg ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; 4097ec681f3Smrg ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; 4107ec681f3Smrg ps->context = ctx; 4117ec681f3Smrg 4127ec681f3Smrg if (util_format_is_depth_or_stencil(ps->format)) { 4137ec681f3Smrg surf->buf_info = BUF_3D_ID_DEPTH; 4147ec681f3Smrg } else { 4157ec681f3Smrg surf->buf_info = BUF_3D_ID_COLOR_BACK; 4167ec681f3Smrg 4177ec681f3Smrg i915_set_color_surface_swizzle(surf); 4183464ebd5Sriastradh } 4197ec681f3Smrg 4207ec681f3Smrg surf->buf_info |= BUF_3D_PITCH(tex->stride); /* pitch in bytes */ 4217ec681f3Smrg 4227ec681f3Smrg switch (tex->tiling) { 4237ec681f3Smrg case I915_TILE_Y: 4247ec681f3Smrg surf->buf_info |= BUF_3D_TILED_SURFACE | BUF_3D_TILE_WALK_Y; 4257ec681f3Smrg break; 4267ec681f3Smrg case I915_TILE_X: 4277ec681f3Smrg surf->buf_info |= BUF_3D_TILED_SURFACE; 4287ec681f3Smrg break; 4297ec681f3Smrg case I915_TILE_NONE: 4307ec681f3Smrg break; 4317ec681f3Smrg } 4327ec681f3Smrg 4333464ebd5Sriastradh return ps; 4343464ebd5Sriastradh} 4353464ebd5Sriastradh 436af69d88dSmrgstatic struct pipe_surface * 4377ec681f3Smrgi915_create_surface(struct pipe_context *ctx, struct pipe_resource *pt, 438af69d88dSmrg const struct pipe_surface *surf_tmpl) 439af69d88dSmrg{ 4407ec681f3Smrg return i915_create_surface_custom(ctx, pt, surf_tmpl, pt->width0, 4417ec681f3Smrg pt->height0); 442af69d88dSmrg} 443af69d88dSmrg 4443464ebd5Sriastradhstatic void 4457ec681f3Smrgi915_surface_destroy(struct pipe_context *ctx, struct pipe_surface *surf) 4463464ebd5Sriastradh{ 4473464ebd5Sriastradh pipe_resource_reference(&surf->texture, NULL); 4483464ebd5Sriastradh FREE(surf); 4494a49301eSmrg} 4504a49301eSmrg 4514a49301eSmrgvoid 4524a49301eSmrgi915_init_surface_functions(struct i915_context *i915) 4534a49301eSmrg{ 4543464ebd5Sriastradh if (i915_screen(i915->base.screen)->debug.use_blitter) { 4553464ebd5Sriastradh i915->base.resource_copy_region = i915_surface_copy_blitter; 4563464ebd5Sriastradh i915->base.clear_render_target = i915_clear_render_target_blitter; 4573464ebd5Sriastradh i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter; 4583464ebd5Sriastradh } else { 4593464ebd5Sriastradh i915->base.resource_copy_region = i915_surface_copy_render; 4603464ebd5Sriastradh i915->base.clear_render_target = i915_clear_render_target_render; 4613464ebd5Sriastradh i915->base.clear_depth_stencil = i915_clear_depth_stencil_render; 4623464ebd5Sriastradh } 463af69d88dSmrg i915->base.blit = i915_blit; 464af69d88dSmrg i915->base.flush_resource = i915_flush_resource; 4653464ebd5Sriastradh i915->base.create_surface = i915_create_surface; 4663464ebd5Sriastradh i915->base.surface_destroy = i915_surface_destroy; 4674a49301eSmrg} 468