1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2003 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "i915_surface.h" 29bf215546Sopenharmony_ci#include "pipe/p_defines.h" 30bf215546Sopenharmony_ci#include "util/format/u_format.h" 31bf215546Sopenharmony_ci#include "util/u_inlines.h" 32bf215546Sopenharmony_ci#include "util/u_math.h" 33bf215546Sopenharmony_ci#include "util/u_memory.h" 34bf215546Sopenharmony_ci#include "util/u_pack_color.h" 35bf215546Sopenharmony_ci#include "util/u_surface.h" 36bf215546Sopenharmony_ci#include "i915_blit.h" 37bf215546Sopenharmony_ci#include "i915_reg.h" 38bf215546Sopenharmony_ci#include "i915_resource.h" 39bf215546Sopenharmony_ci#include "i915_screen.h" 40bf215546Sopenharmony_ci#include "i915_state.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic struct pipe_surface * 43bf215546Sopenharmony_cii915_create_surface_custom(struct pipe_context *ctx, struct pipe_resource *pt, 44bf215546Sopenharmony_ci const struct pipe_surface *surf_tmpl, 45bf215546Sopenharmony_ci unsigned width0, unsigned height0); 46bf215546Sopenharmony_ci/* 47bf215546Sopenharmony_ci * surface functions using the render engine 48bf215546Sopenharmony_ci */ 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic void 51bf215546Sopenharmony_cii915_util_blitter_save_states(struct i915_context *i915) 52bf215546Sopenharmony_ci{ 53bf215546Sopenharmony_ci util_blitter_save_blend(i915->blitter, (void *)i915->blend); 54bf215546Sopenharmony_ci util_blitter_save_depth_stencil_alpha(i915->blitter, 55bf215546Sopenharmony_ci (void *)i915->depth_stencil); 56bf215546Sopenharmony_ci util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref); 57bf215546Sopenharmony_ci util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer); 58bf215546Sopenharmony_ci util_blitter_save_fragment_shader(i915->blitter, i915->fs); 59bf215546Sopenharmony_ci util_blitter_save_vertex_shader(i915->blitter, i915->vs); 60bf215546Sopenharmony_ci util_blitter_save_viewport(i915->blitter, &i915->viewport); 61bf215546Sopenharmony_ci util_blitter_save_scissor(i915->blitter, &i915->scissor); 62bf215546Sopenharmony_ci util_blitter_save_vertex_elements(i915->blitter, i915->velems); 63bf215546Sopenharmony_ci util_blitter_save_vertex_buffer_slot(i915->blitter, i915->vertex_buffers); 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci util_blitter_save_fragment_sampler_states(i915->blitter, i915->num_samplers, 68bf215546Sopenharmony_ci (void **)i915->fragment_sampler); 69bf215546Sopenharmony_ci util_blitter_save_fragment_sampler_views(i915->blitter, 70bf215546Sopenharmony_ci i915->num_fragment_sampler_views, 71bf215546Sopenharmony_ci i915->fragment_sampler_views); 72bf215546Sopenharmony_ci} 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_cistatic void 75bf215546Sopenharmony_cii915_surface_copy_render(struct pipe_context *pipe, struct pipe_resource *dst, 76bf215546Sopenharmony_ci unsigned dst_level, unsigned dstx, unsigned dsty, 77bf215546Sopenharmony_ci unsigned dstz, struct pipe_resource *src, 78bf215546Sopenharmony_ci unsigned src_level, const struct pipe_box *src_box) 79bf215546Sopenharmony_ci{ 80bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 81bf215546Sopenharmony_ci unsigned src_width0 = src->width0; 82bf215546Sopenharmony_ci unsigned src_height0 = src->height0; 83bf215546Sopenharmony_ci unsigned dst_width0 = dst->width0; 84bf215546Sopenharmony_ci unsigned dst_height0 = dst->height0; 85bf215546Sopenharmony_ci struct pipe_box dstbox; 86bf215546Sopenharmony_ci struct pipe_sampler_view src_templ, *src_view; 87bf215546Sopenharmony_ci struct pipe_surface dst_templ, *dst_view; 88bf215546Sopenharmony_ci const struct util_format_description *desc; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci /* Fallback for buffers. */ 91bf215546Sopenharmony_ci if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) 92bf215546Sopenharmony_ci goto fallback; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci /* Fallback for depth&stencil. XXX: see if we can use a proxy format */ 95bf215546Sopenharmony_ci desc = util_format_description(src->format); 96bf215546Sopenharmony_ci if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 97bf215546Sopenharmony_ci goto fallback; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci desc = util_format_description(dst->format); 100bf215546Sopenharmony_ci if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 101bf215546Sopenharmony_ci goto fallback; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 104bf215546Sopenharmony_ci util_blitter_default_src_texture(i915->blitter, &src_templ, src, src_level); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci if (!util_blitter_is_copy_supported(i915->blitter, dst, src)) 107bf215546Sopenharmony_ci goto fallback; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci i915_util_blitter_save_states(i915); 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci dst_view = i915_create_surface_custom(pipe, dst, &dst_templ, dst_width0, 112bf215546Sopenharmony_ci dst_height0); 113bf215546Sopenharmony_ci src_view = i915_create_sampler_view_custom(pipe, src, &src_templ, src_width0, 114bf215546Sopenharmony_ci src_height0); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), 117bf215546Sopenharmony_ci abs(src_box->depth), &dstbox); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci util_blitter_blit_generic(i915->blitter, dst_view, &dstbox, src_view, 120bf215546Sopenharmony_ci src_box, src_width0, src_height0, PIPE_MASK_RGBAZS, 121bf215546Sopenharmony_ci PIPE_TEX_FILTER_NEAREST, NULL, false, false, 0); 122bf215546Sopenharmony_ci return; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_cifallback: 125bf215546Sopenharmony_ci util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, 126bf215546Sopenharmony_ci src_level, src_box); 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_cistatic void 130bf215546Sopenharmony_cii915_clear_render_target_render(struct pipe_context *pipe, 131bf215546Sopenharmony_ci struct pipe_surface *dst, 132bf215546Sopenharmony_ci const union pipe_color_union *color, 133bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned width, 134bf215546Sopenharmony_ci unsigned height, bool render_condition_enabled) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 137bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci fb_state.width = dst->width; 142bf215546Sopenharmony_ci fb_state.height = dst->height; 143bf215546Sopenharmony_ci fb_state.nr_cbufs = 1; 144bf215546Sopenharmony_ci fb_state.cbufs[0] = dst; 145bf215546Sopenharmony_ci fb_state.zsbuf = NULL; 146bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (i915->dirty) 149bf215546Sopenharmony_ci i915_update_derived(i915); 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0, dstx, dsty, width, 152bf215546Sopenharmony_ci height); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); 155bf215546Sopenharmony_ci util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); 156bf215546Sopenharmony_ci i915->blitter->saved_fb_state.nr_cbufs = ~0; 157bf215546Sopenharmony_ci} 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_cistatic void 160bf215546Sopenharmony_cii915_clear_depth_stencil_render(struct pipe_context *pipe, 161bf215546Sopenharmony_ci struct pipe_surface *dst, unsigned clear_flags, 162bf215546Sopenharmony_ci double depth, unsigned stencil, unsigned dstx, 163bf215546Sopenharmony_ci unsigned dsty, unsigned width, unsigned height, 164bf215546Sopenharmony_ci bool render_condition_enabled) 165bf215546Sopenharmony_ci{ 166bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 167bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci fb_state.width = dst->width; 172bf215546Sopenharmony_ci fb_state.height = dst->height; 173bf215546Sopenharmony_ci fb_state.nr_cbufs = 0; 174bf215546Sopenharmony_ci fb_state.zsbuf = dst; 175bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci if (i915->dirty) 178bf215546Sopenharmony_ci i915_update_derived(i915); 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL, NULL, depth, 181bf215546Sopenharmony_ci stencil, dstx, dsty, width, height); 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); 184bf215546Sopenharmony_ci util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); 185bf215546Sopenharmony_ci i915->blitter->saved_fb_state.nr_cbufs = ~0; 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci/* 189bf215546Sopenharmony_ci * surface functions using the blitter 190bf215546Sopenharmony_ci */ 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci/* Assumes all values are within bounds -- no checking at this level - 193bf215546Sopenharmony_ci * do it higher up if required. 194bf215546Sopenharmony_ci */ 195bf215546Sopenharmony_cistatic void 196bf215546Sopenharmony_cii915_surface_copy_blitter(struct pipe_context *pipe, struct pipe_resource *dst, 197bf215546Sopenharmony_ci unsigned dst_level, unsigned dstx, unsigned dsty, 198bf215546Sopenharmony_ci unsigned dstz, struct pipe_resource *src, 199bf215546Sopenharmony_ci unsigned src_level, const struct pipe_box *src_box) 200bf215546Sopenharmony_ci{ 201bf215546Sopenharmony_ci /* Fallback for buffers. */ 202bf215546Sopenharmony_ci if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 203bf215546Sopenharmony_ci util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, 204bf215546Sopenharmony_ci src_level, src_box); 205bf215546Sopenharmony_ci return; 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci struct i915_texture *dst_tex = i915_texture(dst); 209bf215546Sopenharmony_ci struct i915_texture *src_tex = i915_texture(src); 210bf215546Sopenharmony_ci struct pipe_resource *dpt = &dst_tex->b; 211bf215546Sopenharmony_ci ASSERTED struct pipe_resource *spt = &src_tex->b; 212bf215546Sopenharmony_ci unsigned dst_offset, src_offset; /* in bytes */ 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci /* XXX cannot copy 3d regions at this time */ 215bf215546Sopenharmony_ci assert(src_box->depth == 1); 216bf215546Sopenharmony_ci if (dst->target != PIPE_TEXTURE_CUBE && dst->target != PIPE_TEXTURE_3D) 217bf215546Sopenharmony_ci assert(dstz == 0); 218bf215546Sopenharmony_ci dst_offset = i915_texture_offset(dst_tex, dst_level, dstz); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci if (src->target != PIPE_TEXTURE_CUBE && src->target != PIPE_TEXTURE_3D) 221bf215546Sopenharmony_ci assert(src_box->z == 0); 222bf215546Sopenharmony_ci src_offset = i915_texture_offset(src_tex, src_level, src_box->z); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci int block_width = util_format_get_blockwidth(dpt->format); 225bf215546Sopenharmony_ci int block_height = util_format_get_blockheight(dpt->format); 226bf215546Sopenharmony_ci int block_size = util_format_get_blocksize(dpt->format); 227bf215546Sopenharmony_ci assert(util_format_get_blocksize(spt->format) == block_size); 228bf215546Sopenharmony_ci assert(util_format_get_blockwidth(spt->format) == block_width); 229bf215546Sopenharmony_ci assert(util_format_get_blockheight(spt->format) == block_height); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci dstx /= block_width; 232bf215546Sopenharmony_ci dsty /= block_height; 233bf215546Sopenharmony_ci int srcx = src_box->x / block_width; 234bf215546Sopenharmony_ci int srcy = src_box->y / block_height; 235bf215546Sopenharmony_ci int width = DIV_ROUND_UP(src_box->width, block_width); 236bf215546Sopenharmony_ci int height = DIV_ROUND_UP(src_box->height, block_height); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci if (block_size > 4) { 239bf215546Sopenharmony_ci srcx *= (block_size / 4); 240bf215546Sopenharmony_ci dstx *= (block_size / 4); 241bf215546Sopenharmony_ci width *= (block_size / 4); 242bf215546Sopenharmony_ci block_size = 4; 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci i915_copy_blit(i915_context(pipe), block_size, 246bf215546Sopenharmony_ci (unsigned short)src_tex->stride, src_tex->buffer, src_offset, 247bf215546Sopenharmony_ci (unsigned short)dst_tex->stride, dst_tex->buffer, dst_offset, 248bf215546Sopenharmony_ci (short)srcx, (short)srcy, (short)dstx, (short)dsty, 249bf215546Sopenharmony_ci (short)width, (short)height); 250bf215546Sopenharmony_ci} 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_cistatic void 253bf215546Sopenharmony_cii915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) 254bf215546Sopenharmony_ci{ 255bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 256bf215546Sopenharmony_ci struct pipe_blit_info info = *blit_info; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci if (util_try_blit_via_copy_region(pipe, &info, false)) { 259bf215546Sopenharmony_ci return; /* done */ 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci if (info.mask & PIPE_MASK_S) { 263bf215546Sopenharmony_ci debug_printf("i915: cannot blit stencil, skipping\n"); 264bf215546Sopenharmony_ci info.mask &= ~PIPE_MASK_S; 265bf215546Sopenharmony_ci } 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci if (!util_blitter_is_blit_supported(i915->blitter, &info)) { 268bf215546Sopenharmony_ci debug_printf("i915: blit unsupported %s -> %s\n", 269bf215546Sopenharmony_ci util_format_short_name(info.src.resource->format), 270bf215546Sopenharmony_ci util_format_short_name(info.dst.resource->format)); 271bf215546Sopenharmony_ci return; 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci i915_util_blitter_save_states(i915); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci util_blitter_blit(i915->blitter, &info); 277bf215546Sopenharmony_ci} 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_cistatic void 280bf215546Sopenharmony_cii915_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) 281bf215546Sopenharmony_ci{ 282bf215546Sopenharmony_ci} 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_cistatic void 285bf215546Sopenharmony_cii915_clear_render_target_blitter(struct pipe_context *pipe, 286bf215546Sopenharmony_ci struct pipe_surface *dst, 287bf215546Sopenharmony_ci const union pipe_color_union *color, 288bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned width, 289bf215546Sopenharmony_ci unsigned height, bool render_condition_enabled) 290bf215546Sopenharmony_ci{ 291bf215546Sopenharmony_ci struct i915_texture *tex = i915_texture(dst->texture); 292bf215546Sopenharmony_ci struct pipe_resource *pt = &tex->b; 293bf215546Sopenharmony_ci union util_color uc; 294bf215546Sopenharmony_ci unsigned offset = 295bf215546Sopenharmony_ci i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci assert(util_format_get_blockwidth(pt->format) == 1); 298bf215546Sopenharmony_ci assert(util_format_get_blockheight(pt->format) == 1); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci util_pack_color(color->f, dst->format, &uc); 301bf215546Sopenharmony_ci i915_fill_blit(i915_context(pipe), util_format_get_blocksize(pt->format), 302bf215546Sopenharmony_ci XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB, 303bf215546Sopenharmony_ci (unsigned short)tex->stride, tex->buffer, offset, (short)dstx, 304bf215546Sopenharmony_ci (short)dsty, (short)width, (short)height, uc.ui[0]); 305bf215546Sopenharmony_ci} 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_cistatic void 308bf215546Sopenharmony_cii915_clear_depth_stencil_blitter(struct pipe_context *pipe, 309bf215546Sopenharmony_ci struct pipe_surface *dst, unsigned clear_flags, 310bf215546Sopenharmony_ci double depth, unsigned stencil, unsigned dstx, 311bf215546Sopenharmony_ci unsigned dsty, unsigned width, unsigned height, 312bf215546Sopenharmony_ci bool render_condition_enabled) 313bf215546Sopenharmony_ci{ 314bf215546Sopenharmony_ci struct i915_texture *tex = i915_texture(dst->texture); 315bf215546Sopenharmony_ci struct pipe_resource *pt = &tex->b; 316bf215546Sopenharmony_ci unsigned packedds; 317bf215546Sopenharmony_ci unsigned mask = 0; 318bf215546Sopenharmony_ci unsigned offset = 319bf215546Sopenharmony_ci i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci assert(util_format_get_blockwidth(pt->format) == 1); 322bf215546Sopenharmony_ci assert(util_format_get_blockheight(pt->format) == 1); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci packedds = util_pack_z_stencil(dst->format, depth, stencil); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if (clear_flags & PIPE_CLEAR_DEPTH) 327bf215546Sopenharmony_ci mask |= XY_COLOR_BLT_WRITE_RGB; 328bf215546Sopenharmony_ci /* XXX presumably this does read-modify-write 329bf215546Sopenharmony_ci (otherwise this won't work anyway). Hence will only want to 330bf215546Sopenharmony_ci do it if really have stencil and it isn't cleared */ 331bf215546Sopenharmony_ci if ((clear_flags & PIPE_CLEAR_STENCIL) || 332bf215546Sopenharmony_ci (dst->format != PIPE_FORMAT_Z24_UNORM_S8_UINT)) 333bf215546Sopenharmony_ci mask |= XY_COLOR_BLT_WRITE_ALPHA; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci i915_fill_blit(i915_context(pipe), util_format_get_blocksize(pt->format), 336bf215546Sopenharmony_ci mask, (unsigned short)tex->stride, tex->buffer, offset, 337bf215546Sopenharmony_ci (short)dstx, (short)dsty, (short)width, (short)height, 338bf215546Sopenharmony_ci packedds); 339bf215546Sopenharmony_ci} 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci/* 342bf215546Sopenharmony_ci * Screen surface functions 343bf215546Sopenharmony_ci */ 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_cistatic void 346bf215546Sopenharmony_cii915_set_color_surface_swizzle(struct i915_surface *surf) 347bf215546Sopenharmony_ci{ 348bf215546Sopenharmony_ci enum pipe_format format = surf->templ.format; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci const struct { 351bf215546Sopenharmony_ci enum pipe_format format; 352bf215546Sopenharmony_ci uint8_t color_swizzle[4]; 353bf215546Sopenharmony_ci uint32_t oc_swizzle; 354bf215546Sopenharmony_ci } fixup_formats[] = { 355bf215546Sopenharmony_ci {PIPE_FORMAT_R8G8B8A8_UNORM, {2, 1, 0, 3}, 0x21030000 /* BGRA */}, 356bf215546Sopenharmony_ci {PIPE_FORMAT_R8G8B8X8_UNORM, {2, 1, 0, 3}, 0x21030000 /* BGRX */}, 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci /* These are rendered to using COLORBUF_8BIT, where the G channel written 359bf215546Sopenharmony_ci * by shader (and output by blending) is used. 360bf215546Sopenharmony_ci */ 361bf215546Sopenharmony_ci {PIPE_FORMAT_L8_UNORM, {0, 0, 0, 0}, 0x00030000 /* RRRA */}, 362bf215546Sopenharmony_ci {PIPE_FORMAT_I8_UNORM, {0, 0, 0, 0}, 0x00030000 /* RRRA */}, 363bf215546Sopenharmony_ci {PIPE_FORMAT_A8_UNORM, {3, 3, 3, 3}, 0x33330000 /* AAAA */}, 364bf215546Sopenharmony_ci }; 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci if (format == PIPE_FORMAT_A8_UNORM) 367bf215546Sopenharmony_ci surf->alpha_in_g = true; 368bf215546Sopenharmony_ci else if (util_format_is_rgbx_or_bgrx(format)) 369bf215546Sopenharmony_ci surf->alpha_is_x = true; 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(fixup_formats); i++) { 372bf215546Sopenharmony_ci if (fixup_formats[i].format == format) { 373bf215546Sopenharmony_ci memcpy(surf->color_swizzle, fixup_formats[i].color_swizzle, 374bf215546Sopenharmony_ci sizeof(surf->color_swizzle)); 375bf215546Sopenharmony_ci surf->oc_swizzle = fixup_formats[i].oc_swizzle; 376bf215546Sopenharmony_ci return; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci } 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 381bf215546Sopenharmony_ci surf->color_swizzle[i] = i; 382bf215546Sopenharmony_ci} 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_cistatic struct pipe_surface * 385bf215546Sopenharmony_cii915_create_surface_custom(struct pipe_context *ctx, struct pipe_resource *pt, 386bf215546Sopenharmony_ci const struct pipe_surface *surf_tmpl, 387bf215546Sopenharmony_ci unsigned width0, unsigned height0) 388bf215546Sopenharmony_ci{ 389bf215546Sopenharmony_ci struct i915_texture *tex = i915_texture(pt); 390bf215546Sopenharmony_ci struct i915_surface *surf; 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); 393bf215546Sopenharmony_ci if (pt->target != PIPE_TEXTURE_CUBE && pt->target != PIPE_TEXTURE_3D) 394bf215546Sopenharmony_ci assert(surf_tmpl->u.tex.first_layer == 0); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci surf = CALLOC_STRUCT(i915_surface); 397bf215546Sopenharmony_ci if (!surf) 398bf215546Sopenharmony_ci return NULL; 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci struct pipe_surface *ps = &surf->templ; 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci pipe_reference_init(&ps->reference, 1); 403bf215546Sopenharmony_ci pipe_resource_reference(&ps->texture, pt); 404bf215546Sopenharmony_ci ps->format = surf_tmpl->format; 405bf215546Sopenharmony_ci ps->width = u_minify(width0, surf_tmpl->u.tex.level); 406bf215546Sopenharmony_ci ps->height = u_minify(height0, surf_tmpl->u.tex.level); 407bf215546Sopenharmony_ci ps->u.tex.level = surf_tmpl->u.tex.level; 408bf215546Sopenharmony_ci ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; 409bf215546Sopenharmony_ci ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; 410bf215546Sopenharmony_ci ps->context = ctx; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(ps->format)) { 413bf215546Sopenharmony_ci surf->buf_info = BUF_3D_ID_DEPTH; 414bf215546Sopenharmony_ci } else { 415bf215546Sopenharmony_ci surf->buf_info = BUF_3D_ID_COLOR_BACK; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci i915_set_color_surface_swizzle(surf); 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci surf->buf_info |= BUF_3D_PITCH(tex->stride); /* pitch in bytes */ 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci switch (tex->tiling) { 423bf215546Sopenharmony_ci case I915_TILE_Y: 424bf215546Sopenharmony_ci surf->buf_info |= BUF_3D_TILED_SURFACE | BUF_3D_TILE_WALK_Y; 425bf215546Sopenharmony_ci break; 426bf215546Sopenharmony_ci case I915_TILE_X: 427bf215546Sopenharmony_ci surf->buf_info |= BUF_3D_TILED_SURFACE; 428bf215546Sopenharmony_ci break; 429bf215546Sopenharmony_ci case I915_TILE_NONE: 430bf215546Sopenharmony_ci break; 431bf215546Sopenharmony_ci } 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci return ps; 434bf215546Sopenharmony_ci} 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_cistatic struct pipe_surface * 437bf215546Sopenharmony_cii915_create_surface(struct pipe_context *ctx, struct pipe_resource *pt, 438bf215546Sopenharmony_ci const struct pipe_surface *surf_tmpl) 439bf215546Sopenharmony_ci{ 440bf215546Sopenharmony_ci return i915_create_surface_custom(ctx, pt, surf_tmpl, pt->width0, 441bf215546Sopenharmony_ci pt->height0); 442bf215546Sopenharmony_ci} 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_cistatic void 445bf215546Sopenharmony_cii915_surface_destroy(struct pipe_context *ctx, struct pipe_surface *surf) 446bf215546Sopenharmony_ci{ 447bf215546Sopenharmony_ci pipe_resource_reference(&surf->texture, NULL); 448bf215546Sopenharmony_ci FREE(surf); 449bf215546Sopenharmony_ci} 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_civoid 452bf215546Sopenharmony_cii915_init_surface_functions(struct i915_context *i915) 453bf215546Sopenharmony_ci{ 454bf215546Sopenharmony_ci if (i915_screen(i915->base.screen)->debug.use_blitter) { 455bf215546Sopenharmony_ci i915->base.resource_copy_region = i915_surface_copy_blitter; 456bf215546Sopenharmony_ci i915->base.clear_render_target = i915_clear_render_target_blitter; 457bf215546Sopenharmony_ci i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter; 458bf215546Sopenharmony_ci } else { 459bf215546Sopenharmony_ci i915->base.resource_copy_region = i915_surface_copy_render; 460bf215546Sopenharmony_ci i915->base.clear_render_target = i915_clear_render_target_render; 461bf215546Sopenharmony_ci i915->base.clear_depth_stencil = i915_clear_depth_stencil_render; 462bf215546Sopenharmony_ci } 463bf215546Sopenharmony_ci i915->base.blit = i915_blit; 464bf215546Sopenharmony_ci i915->base.flush_resource = i915_flush_resource; 465bf215546Sopenharmony_ci i915->base.create_surface = i915_create_surface; 466bf215546Sopenharmony_ci i915->base.surface_destroy = i915_surface_destroy; 467bf215546Sopenharmony_ci} 468