X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Filo%2Filo_blit.c;h=f0e9412b7942500403fbd33d3341811b6538fe86;hb=40b9812a761ce0745d9e17b92fd0abd27eb86bd7;hp=20e09ae340bd4a9e9ebb6973b61ca658bde80945;hpb=0754ff33e3b500d756a2065b601e8dd68252c81e;p=mesa.git diff --git a/src/gallium/drivers/ilo/ilo_blit.c b/src/gallium/drivers/ilo/ilo_blit.c index 20e09ae340b..f0e9412b794 100644 --- a/src/gallium/drivers/ilo/ilo_blit.c +++ b/src/gallium/drivers/ilo/ilo_blit.c @@ -25,149 +25,35 @@ * Chia-I Wu */ -#include "util/u_blitter.h" -#include "util/u_clear.h" -#include "util/u_pack_color.h" #include "util/u_surface.h" -#include "intel_reg.h" +#include "ilo_blitter.h" #include "ilo_context.h" -#include "ilo_cp.h" -#include "ilo_resource.h" -#include "ilo_screen.h" #include "ilo_blit.h" -static bool -blitter_xy_color_blt(struct pipe_context *pipe, - struct pipe_resource *r, - int16_t x1, int16_t y1, - int16_t x2, int16_t y2, - uint32_t color) +static void +ilo_resource_copy_region(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) { - const int cmd_len = 6; struct ilo_context *ilo = ilo_context(pipe); - struct ilo_resource *res = ilo_resource(r); - uint32_t cmd, br13; - int cpp, stride; - struct intel_bo *bo_check[2]; - - /* how to support Y-tiling? */ - if (res->tiling == INTEL_TILING_Y) - return false; - - /* nothing to clear */ - if (x1 >= x2 || y1 >= y2) - return true; - - cmd = XY_COLOR_BLT_CMD | (cmd_len - 2); - br13 = 0xf0 << 16; - - cpp = util_format_get_blocksize(res->base.format); - switch (cpp) { - case 4: - cmd |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - br13 |= BR13_8888; - break; - case 2: - br13 |= BR13_565; - break; - case 1: - br13 |= BR13_8; - break; - default: - return false; - break; - } - - stride = res->bo_stride; - if (res->tiling != INTEL_TILING_NONE) { - assert(res->tiling == INTEL_TILING_X); - - cmd |= XY_DST_TILED; - /* in dwords */ - stride /= 4; - } - /* make room if necessary */ - bo_check[0] = ilo->cp->bo; - bo_check[1] = res->bo; - if (ilo->winsys->check_aperture_space(ilo->winsys, bo_check, 2)) - ilo_cp_flush(ilo->cp); - - ilo_cp_set_ring(ilo->cp, ILO_CP_RING_BLT); - - ilo_cp_begin(ilo->cp, cmd_len); - ilo_cp_write(ilo->cp, cmd); - ilo_cp_write(ilo->cp, br13 | stride); - ilo_cp_write(ilo->cp, (y1 << 16) | x1); - ilo_cp_write(ilo->cp, (y2 << 16) | x2); - ilo_cp_write_bo(ilo->cp, 0, res->bo, - INTEL_DOMAIN_RENDER, - INTEL_DOMAIN_RENDER); - ilo_cp_write(ilo->cp, color); - ilo_cp_end(ilo->cp); - - return true; -} - -enum ilo_blitter_op { - ILO_BLITTER_CLEAR, - ILO_BLITTER_CLEAR_SURFACE, - ILO_BLITTER_BLIT, -}; + if (ilo_blitter_blt_copy_resource(ilo->blitter, + dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box)) + return; -static void -ilo_blitter_begin(struct ilo_context *ilo, enum ilo_blitter_op op) -{ - /* as documented in util/u_blitter.h */ - util_blitter_save_vertex_buffer_slot(ilo->blitter, - ilo->vertex_buffers.buffers); - util_blitter_save_vertex_elements(ilo->blitter, ilo->vertex_elements); - util_blitter_save_vertex_shader(ilo->blitter, ilo->vs); - util_blitter_save_geometry_shader(ilo->blitter, ilo->gs); - util_blitter_save_so_targets(ilo->blitter, - ilo->stream_output_targets.num_targets, - ilo->stream_output_targets.targets); - - util_blitter_save_fragment_shader(ilo->blitter, ilo->fs); - util_blitter_save_depth_stencil_alpha(ilo->blitter, - ilo->depth_stencil_alpha); - util_blitter_save_blend(ilo->blitter, ilo->blend); - - /* undocumented? */ - util_blitter_save_viewport(ilo->blitter, &ilo->viewport); - util_blitter_save_stencil_ref(ilo->blitter, &ilo->stencil_ref); - util_blitter_save_sample_mask(ilo->blitter, ilo->sample_mask); - - switch (op) { - case ILO_BLITTER_CLEAR: - util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer); - break; - case ILO_BLITTER_CLEAR_SURFACE: - util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer); - break; - case ILO_BLITTER_BLIT: - util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer); - util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer); - - util_blitter_save_fragment_sampler_states(ilo->blitter, - ilo->samplers[PIPE_SHADER_FRAGMENT].num_samplers, - (void **) ilo->samplers[PIPE_SHADER_FRAGMENT].samplers); - - util_blitter_save_fragment_sampler_views(ilo->blitter, - ilo->sampler_views[PIPE_SHADER_FRAGMENT].num_views, - ilo->sampler_views[PIPE_SHADER_FRAGMENT].views); - - /* disable render condition? */ - break; - default: - break; - } -} + if (ilo_blitter_pipe_copy_resource(ilo->blitter, + dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box)) + return; -static void -ilo_blitter_end(struct ilo_context *ilo) -{ + util_resource_copy_region(&ilo->base, dst, dst_level, + dstx, dsty, dstz, src, src_level, src_box); } static void @@ -179,17 +65,16 @@ ilo_clear(struct pipe_context *pipe, { struct ilo_context *ilo = ilo_context(pipe); - /* TODO we should pause/resume some queries */ - ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR); + if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && ilo->fb.state.zsbuf) { + if (ilo_blitter_rectlist_clear_zs(ilo->blitter, ilo->fb.state.zsbuf, + buffers & PIPE_CLEAR_DEPTHSTENCIL, depth, stencil)) + buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; - util_blitter_clear(ilo->blitter, - ilo->framebuffer.width, ilo->framebuffer.height, - ilo->framebuffer.nr_cbufs, buffers, - (ilo->framebuffer.nr_cbufs) ? ilo->framebuffer.cbufs[0]->format : - PIPE_FORMAT_NONE, - color, depth, stencil); + if (!buffers) + return; + } - ilo_blitter_end(ilo); + ilo_blitter_pipe_clear_fb(ilo->blitter, buffers, color, depth, stencil); } static void @@ -200,7 +85,6 @@ ilo_clear_render_target(struct pipe_context *pipe, unsigned width, unsigned height) { struct ilo_context *ilo = ilo_context(pipe); - union util_color packed; if (!width || !height || dstx >= dst->width || dsty >= dst->height) return; @@ -210,19 +94,12 @@ ilo_clear_render_target(struct pipe_context *pipe, if (dsty + height > dst->height) height = dst->height - dsty; - util_pack_color(color->f, dst->format, &packed); - - /* try HW blit first */ - if (blitter_xy_color_blt(pipe, dst->texture, - dstx, dsty, - dstx + width, dsty + height, - packed.ui)) + if (ilo_blitter_blt_clear_rt(ilo->blitter, + dst, color, dstx, dsty, width, height)) return; - ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE); - util_blitter_clear_render_target(ilo->blitter, + ilo_blitter_pipe_clear_rt(ilo->blitter, dst, color, dstx, dsty, width, height); - ilo_blitter_end(ilo); } static void @@ -236,48 +113,129 @@ ilo_clear_depth_stencil(struct pipe_context *pipe, { struct ilo_context *ilo = ilo_context(pipe); - /* - * The PRM claims that HW blit supports Y-tiling since GEN6, but it does - * not tell us how to program it. Since depth buffers are always Y-tiled, - * HW blit will not work. - */ - ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE); - util_blitter_clear_depth_stencil(ilo->blitter, + if (!width || !height || dstx >= dst->width || dsty >= dst->height) + return; + + if (dstx + width > dst->width) + width = dst->width - dstx; + if (dsty + height > dst->height) + height = dst->height - dsty; + + if (ilo_blitter_blt_clear_zs(ilo->blitter, + dst, clear_flags, depth, stencil, dstx, dsty, width, height)) + return; + + ilo_blitter_pipe_clear_zs(ilo->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height); - ilo_blitter_end(ilo); } static void ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) { struct ilo_context *ilo = ilo_context(pipe); - struct pipe_blit_info skip_stencil; - if (util_try_blit_via_copy_region(pipe, info)) - return; + ilo_blitter_pipe_blit(ilo->blitter, info); +} - if (!util_blitter_is_blit_supported(ilo->blitter, info)) { - /* try without stencil */ - if (info->mask & PIPE_MASK_S) { - skip_stencil = *info; - skip_stencil.mask = info->mask & ~PIPE_MASK_S; +static void +ilo_flush_resource(struct pipe_context *pipe, struct pipe_resource *res) +{ + struct ilo_context *ilo = ilo_context(pipe); + const unsigned flags = ILO_TEXTURE_CPU_READ | + ILO_TEXTURE_BLT_READ | + ILO_TEXTURE_RENDER_READ; - if (util_blitter_is_blit_supported(ilo->blitter, &skip_stencil)) - info = &skip_stencil; - } + ilo_blit_resolve_resource(ilo, res, flags); +} - if (info == &skip_stencil) { - ilo_warn("ignore stencil buffer blitting\n"); +void +ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo, + struct pipe_resource *res, unsigned level, + unsigned first_slice, unsigned num_slices, + unsigned resolve_flags) +{ + struct ilo_texture *tex = ilo_texture(res); + const unsigned any_reader = + ILO_TEXTURE_RENDER_READ | + ILO_TEXTURE_BLT_READ | + ILO_TEXTURE_CPU_READ; + const unsigned other_writers = + ILO_TEXTURE_BLT_WRITE | + ILO_TEXTURE_CPU_WRITE; + unsigned i; + + assert(tex->base.target != PIPE_BUFFER && + ilo_texture_can_enable_hiz(tex, level, first_slice, num_slices)); + + if (resolve_flags & ILO_TEXTURE_RENDER_WRITE) { + /* + * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader. We + * need to perform a HiZ Buffer Resolve in case the resource was + * previously written by another writer, unless this is a clear. + * + * When slices have different clear values, we perform a Depth Buffer + * Resolve on all slices not sharing the clear value of the first slice. + * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can + * be made to have the same clear value as the first slice does. This + * way, + * + * - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice + * - we will not resolve unnecessarily next time this function is + * called + * + * Since slice clear value is the value the slice is cleared to when + * ILO_TEXTURE_CLEAR is set, the bit needs to be unset. + */ + assert(!(resolve_flags & (other_writers | any_reader))); + + if (!(resolve_flags & ILO_TEXTURE_CLEAR)) { + bool set_clear_value = false; + uint32_t first_clear_value; + + for (i = 0; i < num_slices; i++) { + const struct ilo_texture_slice *slice = + ilo_texture_get_slice(tex, level, first_slice + i); + + if (slice->flags & other_writers) { + ilo_blitter_rectlist_resolve_hiz(ilo->blitter, + res, level, first_slice + i); + } + else if (i == 0) { + first_clear_value = slice->clear_value; + } + else if (slice->clear_value != first_clear_value && + (slice->flags & ILO_TEXTURE_RENDER_WRITE)) { + ilo_blitter_rectlist_resolve_z(ilo->blitter, + res, level, first_slice + i); + set_clear_value = true; + } + } + + if (set_clear_value) { + /* ILO_TEXTURE_CLEAR will be cleared later */ + ilo_texture_set_slice_clear_value(tex, level, + first_slice, num_slices, first_clear_value); + } } - else { - ilo_warn("failed to blit with the generic blitter\n"); - return; + } + else if ((resolve_flags & any_reader) || + ((resolve_flags & other_writers) && + !(resolve_flags & ILO_TEXTURE_CLEAR))) { + /* + * When there is at least a reader or writer, we need to perform a + * Depth Buffer Resolve in case the resource was previously written + * by ILO_TEXTURE_RENDER_WRITE. + */ + for (i = 0; i < num_slices; i++) { + const struct ilo_texture_slice *slice = + ilo_texture_get_slice(tex, level, first_slice + i); + + if (slice->flags & ILO_TEXTURE_RENDER_WRITE) { + ilo_blitter_rectlist_resolve_z(ilo->blitter, + &tex->base, level, first_slice + i); + } } } - - ilo_blitter_begin(ilo, ILO_BLITTER_BLIT); - util_blitter_blit(ilo->blitter, info); - ilo_blitter_end(ilo); } /** @@ -286,8 +244,9 @@ ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) void ilo_init_blit_functions(struct ilo_context *ilo) { - ilo->base.resource_copy_region = util_resource_copy_region; + ilo->base.resource_copy_region = ilo_resource_copy_region; ilo->base.blit = ilo_blit; + ilo->base.flush_resource = ilo_flush_resource; ilo->base.clear = ilo_clear; ilo->base.clear_render_target = ilo_clear_render_target;