From 570020c810667b4493f84eae475b57aadf5bee9c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 23 May 2022 17:25:46 -0700 Subject: [PATCH] lima: implement lima-specific blitter It should be more efficient than u_blitter since it skips vertex shader stage. Also it's a prerequisite for supporting MSAA since u_blitter can't do MSAA resolve for us. Reviewed-by: Erico Nunes Signed-off-by: Vasily Khoruzhick Part-of: --- docs/drivers/lima.rst | 5 + src/gallium/drivers/lima/ci/lima-fails.txt | 2 - src/gallium/drivers/lima/lima_blit.c | 304 +++++++++++++++++++++ src/gallium/drivers/lima/lima_blit.h | 28 ++ src/gallium/drivers/lima/lima_draw.c | 11 - src/gallium/drivers/lima/lima_job.c | 160 ++++------- src/gallium/drivers/lima/lima_job.h | 3 + src/gallium/drivers/lima/lima_resource.c | 5 + src/gallium/drivers/lima/lima_screen.c | 2 + src/gallium/drivers/lima/lima_screen.h | 1 + src/gallium/drivers/lima/lima_util.c | 12 + src/gallium/drivers/lima/lima_util.h | 5 + src/gallium/drivers/lima/meson.build | 2 + 13 files changed, 413 insertions(+), 127 deletions(-) create mode 100644 src/gallium/drivers/lima/lima_blit.c create mode 100644 src/gallium/drivers/lima/lima_blit.h diff --git a/docs/drivers/lima.rst b/docs/drivers/lima.rst index 91c16c0c3c5..870517d2002 100644 --- a/docs/drivers/lima.rst +++ b/docs/drivers/lima.rst @@ -68,10 +68,14 @@ accepts the following comma-separated list of flags: ``bocache`` print debug info for BO cache + ``diskcache`` + print debug info for shader disk cache ``dump`` dump GPU command stream to ``$PWD/lima.dump`` ``gp`` print GP shader compiler result of each stage + ``noblit`` + use generic u_blitter instead of lima-specific ``nobocache`` disable BO cache ``nogrowheap`` @@ -87,6 +91,7 @@ accepts the following comma-separated list of flags: ``singlejob`` disable multi job optimization + .. envvar:: LIMA_CTX_NUM_PLB (None) set number of PLB per context (used for development purposes) diff --git a/src/gallium/drivers/lima/ci/lima-fails.txt b/src/gallium/drivers/lima/ci/lima-fails.txt index a41e3a5ddeb..d8f83aafc38 100644 --- a/src/gallium/drivers/lima/ci/lima-fails.txt +++ b/src/gallium/drivers/lima/ci/lima-fails.txt @@ -64,8 +64,6 @@ spec@arb_depth_texture@fbo-depth-gl_depth_component32-blit,Fail spec@arb_depth_texture@fbo-depth-gl_depth_component32-copypixels,Fail spec@arb_depth_texture@fbo-depth-gl_depth_component32-readpixels,Fail spec@arb_depth_texture@fbo-generatemipmap-formats,Fail -spec@arb_depth_texture@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT16,Fail -spec@arb_depth_texture@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT16 NPOT,Fail spec@arb_depth_texture@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT24,Fail spec@arb_depth_texture@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT24 NPOT,Fail spec@arb_depth_texture@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT32,Fail diff --git a/src/gallium/drivers/lima/lima_blit.c b/src/gallium/drivers/lima/lima_blit.c new file mode 100644 index 00000000000..b7340485fd4 --- /dev/null +++ b/src/gallium/drivers/lima/lima_blit.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2022 Lima Project + * + * SPDX-License-Identifier: MIT + * + */ + +#include "drm-uapi/lima_drm.h" + +#include "util/u_math.h" +#include "util/format/u_format.h" +#include "util/u_surface.h" +#include "util/u_inlines.h" +#include "util/hash_table.h" + +#include "lima_context.h" +#include "lima_gpu.h" +#include "lima_resource.h" +#include "lima_texture.h" +#include "lima_format.h" +#include "lima_job.h" +#include "lima_screen.h" +#include "lima_bo.h" +#include "lima_parser.h" +#include "lima_util.h" +#include "lima_blit.h" + +void +lima_pack_blit_cmd(struct lima_job *job, + struct util_dynarray *cmd_array, + struct pipe_surface *psurf, + const struct pipe_box *src, + const struct pipe_box *dst, + unsigned filter, + bool scissor) +{ + #define lima_blit_render_state_offset 0x0000 + #define lima_blit_gl_pos_offset 0x0040 + #define lima_blit_varying_offset 0x0080 + #define lima_blit_tex_desc_offset 0x00c0 + #define lima_blit_tex_array_offset 0x0100 + #define lima_blit_buffer_size 0x0140 + + struct lima_context *ctx = job->ctx; + struct lima_surface *surf = lima_surface(psurf); + int level = psurf->u.tex.level; + unsigned first_layer = psurf->u.tex.first_layer; + float fb_width = dst->width, fb_height = dst->height; + + uint32_t va; + void *cpu = lima_job_create_stream_bo( + job, LIMA_PIPE_PP, lima_blit_buffer_size, &va); + + struct lima_screen *screen = lima_screen(ctx->base.screen); + + uint32_t reload_shader_first_instr_size = + ((uint32_t *)(screen->pp_buffer->map + pp_reload_program_offset))[0] & 0x1f; + uint32_t reload_shader_va = screen->pp_buffer->va + pp_reload_program_offset; + + struct lima_render_state reload_render_state = { + .alpha_blend = 0xf03b1ad2, + .depth_test = 0x0000000e, + .depth_range = 0xffff0000, + .stencil_front = 0x00000007, + .stencil_back = 0x00000007, + .multi_sample = 0x0000f007, + .shader_address = reload_shader_va | reload_shader_first_instr_size, + .varying_types = 0x00000001, + .textures_address = va + lima_blit_tex_array_offset, + .aux0 = 0x00004021, + .varyings_address = va + lima_blit_varying_offset, + }; + + if (job->key.cbuf) { + fb_width = job->key.cbuf->width; + fb_height = job->key.cbuf->height; + } else { + fb_width = job->key.zsbuf->width; + fb_height = job->key.zsbuf->height; + } + + if (util_format_is_depth_or_stencil(psurf->format)) { + reload_render_state.alpha_blend &= 0x0fffffff; + if (psurf->format != PIPE_FORMAT_Z16_UNORM) + reload_render_state.depth_test |= 0x400; + if (surf->reload & PIPE_CLEAR_DEPTH) + reload_render_state.depth_test |= 0x801; + if (surf->reload & PIPE_CLEAR_STENCIL) { + reload_render_state.depth_test |= 0x1000; + reload_render_state.stencil_front = 0x0000024f; + reload_render_state.stencil_back = 0x0000024f; + reload_render_state.stencil_test = 0x0000ffff; + } + } + + memcpy(cpu + lima_blit_render_state_offset, &reload_render_state, + sizeof(reload_render_state)); + + lima_tex_desc *td = cpu + lima_blit_tex_desc_offset; + memset(td, 0, lima_min_tex_desc_size); + lima_texture_desc_set_res(ctx, td, psurf->texture, level, level, first_layer); + td->format = lima_format_get_texel_reload(psurf->format); + td->unnorm_coords = 1; + td->sampler_dim = LIMA_SAMPLER_DIM_2D; + td->min_img_filter_nearest = 1; + td->mag_img_filter_nearest = 1; + td->wrap_s = LIMA_TEX_WRAP_CLAMP_TO_EDGE; + td->wrap_t = LIMA_TEX_WRAP_CLAMP_TO_EDGE; + td->wrap_r = LIMA_TEX_WRAP_CLAMP_TO_EDGE; + + if (filter != PIPE_TEX_FILTER_NEAREST) { + td->min_img_filter_nearest = 0; + td->mag_img_filter_nearest = 0; + } + + uint32_t *ta = cpu + lima_blit_tex_array_offset; + ta[0] = va + lima_blit_tex_desc_offset; + + float reload_gl_pos[] = { + dst->x + dst->width, dst->y, 0, 1, + dst->x, dst->y, 0, 1, + dst->x, dst->y + dst->height, 0, 1, + }; + memcpy(cpu + lima_blit_gl_pos_offset, reload_gl_pos, + sizeof(reload_gl_pos)); + + float reload_varying[] = { + src->x + src->width, src->y, + src->x, src->y, + src->x, src->y + src->height, + 0, 0, /* unused */ + }; + memcpy(cpu + lima_blit_varying_offset, reload_varying, + sizeof(reload_varying)); + + PLBU_CMD_BEGIN(cmd_array, scissor ? 22 : 20); + + PLBU_CMD_VIEWPORT_LEFT(0); + PLBU_CMD_VIEWPORT_RIGHT(fui(fb_width)); + PLBU_CMD_VIEWPORT_BOTTOM(0); + PLBU_CMD_VIEWPORT_TOP(fui(fb_height)); + + PLBU_CMD_RSW_VERTEX_ARRAY( + va + lima_blit_render_state_offset, + va + lima_blit_gl_pos_offset); + + + if (scissor) { + int minx = MIN2(dst->x, dst->x + dst->width); + int maxx = MAX2(dst->x, dst->x + dst->width); + int miny = MIN2(dst->y, dst->y + dst->height); + int maxy = MAX2(dst->y, dst->y + dst->height); + + PLBU_CMD_SCISSORS(minx, maxx, miny, maxy); + lima_damage_rect_union(&job->damage_rect, minx, maxx, miny, maxy); + } + + PLBU_CMD_UNKNOWN2(); + PLBU_CMD_UNKNOWN1(); + + PLBU_CMD_INDICES(screen->pp_buffer->va + pp_shared_index_offset); + PLBU_CMD_INDEXED_DEST(va + lima_blit_gl_pos_offset); + PLBU_CMD_DRAW_ELEMENTS(0xf, 0, 3); + + PLBU_CMD_END(); + + lima_dump_command_stream_print(job->dump, cpu, lima_blit_buffer_size, + false, "blit plbu cmd at va %x\n", va); +} + +static struct pipe_surface * +lima_get_blit_surface(struct pipe_context *pctx, + struct pipe_resource *prsc, + unsigned level) +{ + struct pipe_surface tmpl; + + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.format = prsc->format; + tmpl.u.tex.level = level; + tmpl.u.tex.first_layer = 0; + tmpl.u.tex.last_layer = 0; + + return pctx->create_surface(pctx, prsc, &tmpl); +} + +bool +lima_do_blit(struct pipe_context *pctx, + const struct pipe_blit_info *info) +{ + struct lima_context *ctx = lima_context(pctx); + unsigned reload_flags = PIPE_CLEAR_COLOR0; + uint8_t identity[4] = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, + PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }; + + if (lima_debug & LIMA_DEBUG_NO_BLIT) + return false; + + /* Blitting of swizzled formats (R and RG) isn't implemented yet */ + if (memcmp(identity, + lima_format_get_texel_swizzle(info->src.resource->format), + sizeof(identity))) + return false; + + if (memcmp(identity, + lima_format_get_texel_swizzle(info->dst.resource->format), + sizeof(identity))) + return false; + + if (util_format_is_depth_or_stencil(info->src.resource->format)) { + const struct util_format_description *desc = + util_format_description(info->src.resource->format); + reload_flags = 0; + if (util_format_has_depth(desc)) + reload_flags |= PIPE_CLEAR_DEPTH; + if (util_format_has_stencil(desc)) + reload_flags |= PIPE_CLEAR_STENCIL; + } + + if (!lima_format_pixel_supported(info->dst.resource->format)) + return false; + + if (!lima_format_texel_supported(info->src.resource->format)) + return false; + + if (info->dst.resource->target != PIPE_TEXTURE_2D || + info->src.resource->target != PIPE_TEXTURE_2D) + return false; + + if (info->dst.box.x < 0 || info->dst.box.y < 0 || + info->src.box.x < 0 || info->src.box.y < 0) + return false; + + if (info->src.box.depth != 1 || + info->dst.box.depth != 1) + return false; + + /* Scissored blit isn't implemented yet */ + if (info->scissor_enable) + return false; + + if ((reload_flags & PIPE_CLEAR_COLOR) && !(info->mask & PIPE_MASK_RGBA)) + return false; + + if ((reload_flags & PIPE_CLEAR_DEPTH) && !(info->mask & PIPE_MASK_Z)) + return false; + + if ((reload_flags & PIPE_CLEAR_STENCIL) && !(info->mask & PIPE_MASK_S)) + return false; + + struct pipe_surface *dst_surf = + lima_get_blit_surface(pctx, info->dst.resource, info->dst.level); + struct lima_surface *lima_dst_surf = lima_surface(dst_surf); + + struct pipe_surface *src_surf = + lima_get_blit_surface(pctx, info->src.resource, info->src.level); + + struct lima_job *job; + + if (util_format_is_depth_or_stencil(info->dst.resource->format)) + job = lima_job_get_with_fb(ctx, NULL, dst_surf); + else + job = lima_job_get_with_fb(ctx, dst_surf, NULL); + + struct lima_resource *src_res = lima_resource(src_surf->texture); + struct lima_resource *dst_res = lima_resource(dst_surf->texture); + + lima_flush_job_accessing_bo(ctx, src_res->bo, true); + lima_flush_job_accessing_bo(ctx, dst_res->bo, true); + + lima_job_add_bo(job, LIMA_PIPE_PP, src_res->bo, LIMA_SUBMIT_BO_READ); + _mesa_hash_table_insert(ctx->write_jobs, &dst_res->base, job); + lima_job_add_bo(job, LIMA_PIPE_PP, dst_res->bo, LIMA_SUBMIT_BO_WRITE); + + lima_pack_blit_cmd(job, &job->plbu_cmd_array, + src_surf, &info->src.box, + &info->dst.box, info->filter, true); + + bool tile_aligned = false; + + if (info->dst.box.x == 0 && info->dst.box.y == 0 && + info->dst.box.width == lima_dst_surf->base.width && + info->dst.box.height == lima_dst_surf->base.height) + tile_aligned = true; + + if (info->dst.box.x % 16 == 0 && info->dst.box.y % 16 == 0 && + info->dst.box.width % 16 == 0 && info->dst.box.height % 16 == 0) + tile_aligned = true; + + /* Reload if dest is not aligned to tile boundaries */ + if (!tile_aligned) + lima_dst_surf->reload = reload_flags; + else + lima_dst_surf->reload = 0; + + job->resolve = reload_flags; + + lima_do_job(job); + + pipe_surface_reference(&dst_surf, NULL); + pipe_surface_reference(&src_surf, NULL); + + return true; +} diff --git a/src/gallium/drivers/lima/lima_blit.h b/src/gallium/drivers/lima/lima_blit.h new file mode 100644 index 00000000000..d678bc3cace --- /dev/null +++ b/src/gallium/drivers/lima/lima_blit.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 Lima Project + * + * SPDX-License-Identifier: MIT + * + */ + +#ifndef H_LIMA_BLIT +#define H_LIMA_BLIT + +#include + +struct util_dynarray; + +void +lima_pack_blit_cmd(struct lima_job *job, + struct util_dynarray *cmd, + struct pipe_surface *psurf, + const struct pipe_box *src, + const struct pipe_box *dst, + unsigned filter, + bool scissor); + +bool lima_do_blit(struct pipe_context *ctx, + const struct pipe_blit_info *blit_info); + +#endif + diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 5728cae7e79..1d5a82ff2da 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -146,17 +146,6 @@ lima_update_job_wb(struct lima_context *ctx, unsigned buffers) job->resolve |= buffers; } -static void -lima_damage_rect_union(struct pipe_scissor_state *rect, - unsigned minx, unsigned maxx, - unsigned miny, unsigned maxy) -{ - rect->minx = MIN2(rect->minx, minx); - rect->miny = MIN2(rect->miny, miny); - rect->maxx = MAX2(rect->maxx, maxx); - rect->maxy = MAX2(rect->maxy, maxy); -} - static void lima_clear(struct pipe_context *pctx, unsigned buffers, const struct pipe_scissor_state *scissor_state, const union pipe_color_union *color, double depth, unsigned stencil) diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c index 14f52da4c7e..e8fe97317ff 100644 --- a/src/gallium/drivers/lima/lima_job.c +++ b/src/gallium/drivers/lima/lima_job.c @@ -45,6 +45,7 @@ #include "lima_texture.h" #include "lima_fence.h" #include "lima_gpu.h" +#include "lima_blit.h" #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) @@ -53,9 +54,19 @@ lima_get_fb_info(struct lima_job *job) { struct lima_context *ctx = job->ctx; struct lima_job_fb_info *fb = &job->fb; + struct lima_surface *surf = lima_surface(job->key.cbuf); - fb->width = ctx->framebuffer.base.width; - fb->height = ctx->framebuffer.base.height; + if (!surf) + surf = lima_surface(job->key.zsbuf); + + if (!surf) { + /* We don't have neither cbuf nor zsbuf, use dimensions from ctx */ + fb->width = ctx->framebuffer.base.width; + fb->height = ctx->framebuffer.base.height; + } else { + fb->width = surf->base.width; + fb->height = surf->base.height; + } int width = align(fb->width, 16) >> 4; int height = align(fb->height, 16) >> 4; @@ -86,7 +97,9 @@ lima_get_fb_info(struct lima_job *job) } static struct lima_job * -lima_job_create(struct lima_context *ctx) +lima_job_create(struct lima_context *ctx, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf) { struct lima_job *s; @@ -112,9 +125,8 @@ lima_job_create(struct lima_context *ctx) util_dynarray_init(&s->plbu_cmd_array, s); util_dynarray_init(&s->plbu_cmd_head, s); - struct lima_context_framebuffer *fb = &ctx->framebuffer; - pipe_surface_reference(&s->key.cbuf, fb->base.cbufs[0]); - pipe_surface_reference(&s->key.zsbuf, fb->base.zsbuf); + pipe_surface_reference(&s->key.cbuf, cbuf); + pipe_surface_reference(&s->key.zsbuf, zsbuf); lima_get_fb_info(s); @@ -145,20 +157,21 @@ lima_job_free(struct lima_job *job) ralloc_free(job); } -static struct lima_job * -_lima_job_get(struct lima_context *ctx) +struct lima_job * +lima_job_get_with_fb(struct lima_context *ctx, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf) { - struct lima_context_framebuffer *fb = &ctx->framebuffer; struct lima_job_key local_key = { - .cbuf = fb->base.cbufs[0], - .zsbuf = fb->base.zsbuf, + .cbuf = cbuf, + .zsbuf = zsbuf, }; struct hash_entry *entry = _mesa_hash_table_search(ctx->jobs, &local_key); if (entry) return entry->data; - struct lima_job *job = lima_job_create(ctx); + struct lima_job *job = lima_job_create(ctx, cbuf, zsbuf); if (!job) return NULL; @@ -167,6 +180,14 @@ _lima_job_get(struct lima_context *ctx) return job; } +static struct lima_job * +_lima_job_get(struct lima_context *ctx) +{ + struct lima_context_framebuffer *fb = &ctx->framebuffer; + + return lima_job_get_with_fb(ctx, fb->base.cbufs[0], fb->base.zsbuf); +} + /* * Note: this function can only be called in draw code path, * must not exist in flush code path. @@ -337,112 +358,23 @@ lima_fb_zsbuf_needs_reload(struct lima_job *job) static void lima_pack_reload_plbu_cmd(struct lima_job *job, struct pipe_surface *psurf) { - #define lima_reload_render_state_offset 0x0000 - #define lima_reload_gl_pos_offset 0x0040 - #define lima_reload_varying_offset 0x0080 - #define lima_reload_tex_desc_offset 0x00c0 - #define lima_reload_tex_array_offset 0x0100 - #define lima_reload_buffer_size 0x0140 - - struct lima_context *ctx = job->ctx; - struct lima_surface *surf = lima_surface(psurf); - int level = psurf->u.tex.level; - unsigned first_layer = psurf->u.tex.first_layer; - - uint32_t va; - void *cpu = lima_job_create_stream_bo( - job, LIMA_PIPE_PP, lima_reload_buffer_size, &va); - - struct lima_screen *screen = lima_screen(ctx->base.screen); - - uint32_t reload_shader_first_instr_size = - ((uint32_t *)(screen->pp_buffer->map + pp_reload_program_offset))[0] & 0x1f; - uint32_t reload_shader_va = screen->pp_buffer->va + pp_reload_program_offset; - - struct lima_render_state reload_render_state = { - .alpha_blend = 0xf03b1ad2, - .depth_test = 0x0000000e, - .depth_range = 0xffff0000, - .stencil_front = 0x00000007, - .stencil_back = 0x00000007, - .multi_sample = 0x0000f007, - .shader_address = reload_shader_va | reload_shader_first_instr_size, - .varying_types = 0x00000001, - .textures_address = va + lima_reload_tex_array_offset, - .aux0 = 0x00004021, - .varyings_address = va + lima_reload_varying_offset, - }; - - if (util_format_is_depth_or_stencil(psurf->format)) { - reload_render_state.alpha_blend &= 0x0fffffff; - if (psurf->format != PIPE_FORMAT_Z16_UNORM) - reload_render_state.depth_test |= 0x400; - if (surf->reload & PIPE_CLEAR_DEPTH) - reload_render_state.depth_test |= 0x801; - if (surf->reload & PIPE_CLEAR_STENCIL) { - reload_render_state.depth_test |= 0x1000; - reload_render_state.stencil_front = 0x0000024f; - reload_render_state.stencil_back = 0x0000024f; - reload_render_state.stencil_test = 0x0000ffff; - } - } - - memcpy(cpu + lima_reload_render_state_offset, &reload_render_state, - sizeof(reload_render_state)); - - lima_tex_desc *td = cpu + lima_reload_tex_desc_offset; - memset(td, 0, lima_min_tex_desc_size); - lima_texture_desc_set_res(ctx, td, psurf->texture, level, level, first_layer); - td->format = lima_format_get_texel_reload(psurf->format); - td->unnorm_coords = 1; - td->sampler_dim = LIMA_SAMPLER_DIM_2D; - td->min_img_filter_nearest = 1; - td->mag_img_filter_nearest = 1; - td->wrap_s = LIMA_TEX_WRAP_CLAMP_TO_EDGE; - td->wrap_t = LIMA_TEX_WRAP_CLAMP_TO_EDGE; - td->wrap_r = LIMA_TEX_WRAP_CLAMP_TO_EDGE; - - uint32_t *ta = cpu + lima_reload_tex_array_offset; - ta[0] = va + lima_reload_tex_desc_offset; - struct lima_job_fb_info *fb = &job->fb; - float reload_gl_pos[] = { - fb->width, 0, 0, 1, - 0, 0, 0, 1, - 0, fb->height, 0, 1, + struct pipe_box src = { + .x = 0, + .y = 0, + .width = fb->width, + .height = fb->height, }; - memcpy(cpu + lima_reload_gl_pos_offset, reload_gl_pos, - sizeof(reload_gl_pos)); - float reload_varying[] = { - fb->width, 0, 0, 0, - 0, fb->height, 0, 0, + struct pipe_box dst = { + .x = 0, + .y = 0, + .width = fb->width, + .height = fb->height, }; - memcpy(cpu + lima_reload_varying_offset, reload_varying, - sizeof(reload_varying)); - - PLBU_CMD_BEGIN(&job->plbu_cmd_head, 20); - - PLBU_CMD_VIEWPORT_LEFT(0); - PLBU_CMD_VIEWPORT_RIGHT(fui(fb->width)); - PLBU_CMD_VIEWPORT_BOTTOM(0); - PLBU_CMD_VIEWPORT_TOP(fui(fb->height)); - - PLBU_CMD_RSW_VERTEX_ARRAY( - va + lima_reload_render_state_offset, - va + lima_reload_gl_pos_offset); - - PLBU_CMD_UNKNOWN2(); - PLBU_CMD_UNKNOWN1(); - - PLBU_CMD_INDICES(screen->pp_buffer->va + pp_shared_index_offset); - PLBU_CMD_INDEXED_DEST(va + lima_reload_gl_pos_offset); - PLBU_CMD_DRAW_ELEMENTS(0xf, 0, 3); - - PLBU_CMD_END(); - - lima_dump_command_stream_print(job->dump, cpu, lima_reload_buffer_size, - false, "reload plbu cmd at va %x\n", va); + lima_pack_blit_cmd(job, &job->plbu_cmd_head, + psurf, &src, &dst, + PIPE_TEX_FILTER_NEAREST, false); } static void diff --git a/src/gallium/drivers/lima/lima_job.h b/src/gallium/drivers/lima/lima_job.h index a43b8be1c10..0eb05a5378c 100644 --- a/src/gallium/drivers/lima/lima_job.h +++ b/src/gallium/drivers/lima/lima_job.h @@ -95,6 +95,9 @@ lima_job_has_draw_pending(struct lima_job *job) } struct lima_job *lima_job_get(struct lima_context *ctx); +struct lima_job * lima_job_get_with_fb(struct lima_context *ctx, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf); bool lima_job_add_bo(struct lima_job *job, int pipe, struct lima_bo *bo, uint32_t flags); diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c index e8f5aa6e620..9793fac9fdf 100644 --- a/src/gallium/drivers/lima/lima_resource.c +++ b/src/gallium/drivers/lima/lima_resource.c @@ -45,6 +45,7 @@ #include "lima_resource.h" #include "lima_bo.h" #include "lima_util.h" +#include "lima_blit.h" #include "pan_minmax_cache.h" #include "pan_tiling.h" @@ -855,6 +856,10 @@ lima_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) struct lima_context *ctx = lima_context(pctx); struct pipe_blit_info info = *blit_info; + if (lima_do_blit(pctx, blit_info)) { + return; + } + if (util_try_blit_via_copy_region(pctx, &info, false)) { return; /* done */ } diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c index 9eadf44b48a..90dcbe8383f 100644 --- a/src/gallium/drivers/lima/lima_screen.c +++ b/src/gallium/drivers/lima/lima_screen.c @@ -598,6 +598,8 @@ static const struct debug_named_value lima_debug_options[] = { "Precompile shaders for shader-db" }, { "diskcache", LIMA_DEBUG_DISK_CACHE, "print debug info for shader disk cache" }, + { "noblit", LIMA_DEBUG_NO_BLIT, + "use generic u_blitter instead of lima-specific" }, { NULL } }; diff --git a/src/gallium/drivers/lima/lima_screen.h b/src/gallium/drivers/lima/lima_screen.h index bc08a490236..fe2edf08d74 100644 --- a/src/gallium/drivers/lima/lima_screen.h +++ b/src/gallium/drivers/lima/lima_screen.h @@ -45,6 +45,7 @@ #define LIMA_DEBUG_SINGLE_JOB (1 << 8) #define LIMA_DEBUG_PRECOMPILE (1 << 9) #define LIMA_DEBUG_DISK_CACHE (1 << 10) +#define LIMA_DEBUG_NO_BLIT (1 << 11) extern uint32_t lima_debug; extern int lima_ctx_num_plb; diff --git a/src/gallium/drivers/lima/lima_util.c b/src/gallium/drivers/lima/lima_util.c index 832fbf68ec4..cf3fe2da04a 100644 --- a/src/gallium/drivers/lima/lima_util.c +++ b/src/gallium/drivers/lima/lima_util.c @@ -29,6 +29,7 @@ #include "util/u_debug.h" #include "util/u_memory.h" +#include "util/u_box.h" #include "lima_util.h" #include "lima_parser.h" @@ -182,3 +183,14 @@ _lima_dump_command_stream_print(struct lima_dump *dump, void *data, lima_dump_blob(dump->fp, data, size, is_float); } + +void +lima_damage_rect_union(struct pipe_scissor_state *rect, + unsigned minx, unsigned maxx, + unsigned miny, unsigned maxy) +{ + rect->minx = MIN2(rect->minx, minx); + rect->miny = MIN2(rect->miny, miny); + rect->maxx = MAX2(rect->maxx, maxx); + rect->maxy = MAX2(rect->maxy, maxy); +} diff --git a/src/gallium/drivers/lima/lima_util.h b/src/gallium/drivers/lima/lima_util.h index ebab8a40e62..af3a75ea7fc 100644 --- a/src/gallium/drivers/lima/lima_util.h +++ b/src/gallium/drivers/lima/lima_util.h @@ -55,4 +55,9 @@ void _lima_dump_command_stream_print(struct lima_dump *dump, void *data, _lima_dump_command_stream_print(dump, __VA_ARGS__); \ } while (0) +struct pipe_scissor_state; + +void lima_damage_rect_union(struct pipe_scissor_state *rect, + unsigned minx, unsigned maxx, + unsigned miny, unsigned maxy); #endif diff --git a/src/gallium/drivers/lima/meson.build b/src/gallium/drivers/lima/meson.build index 6810c362ccf..5d8f21c2cf8 100644 --- a/src/gallium/drivers/lima/meson.build +++ b/src/gallium/drivers/lima/meson.build @@ -82,6 +82,8 @@ files_lima = files( 'lima_format.h', 'lima_format.c', 'lima_gpu.h', + 'lima_blit.c', + 'lima_blit.h', ) lima_nir_algebraic_c = custom_target(