diff options
Diffstat (limited to 'src/gallium/drivers/lima/lima_job.c')
-rw-r--r-- | src/gallium/drivers/lima/lima_job.c | 218 |
1 files changed, 95 insertions, 123 deletions
diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c index ef8a6444cb9..6400fdb2dd9 100644 --- a/src/gallium/drivers/lima/lima_job.c +++ b/src/gallium/drivers/lima/lima_job.c @@ -34,6 +34,7 @@ #include "util/format/u_format.h" #include "util/u_upload_mgr.h" #include "util/u_inlines.h" +#include "util/u_framebuffer.h" #include "lima_screen.h" #include "lima_context.h" @@ -45,6 +46,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 +55,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); + + if (!surf) + surf = lima_surface(job->key.zsbuf); - fb->width = ctx->framebuffer.base.width; - fb->height = ctx->framebuffer.base.height; + 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; @@ -69,8 +81,9 @@ lima_get_fb_info(struct lima_job *job) fb->shift_w = 0; int limit = screen->plb_max_blk; - while ((width * height) > limit) { - if (width >= height) { + while ((width * height) > limit || + width > PLBU_BLOCK_W_MASK || height > PLBU_BLOCK_H_MASK) { + if (width >= height || width > PLBU_BLOCK_W_MASK) { width = (width + 1) >> 1; fb->shift_w++; } else { @@ -86,7 +99,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 +127,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 +159,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 +182,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 +360,35 @@ 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_job_fb_info *fb = &job->fb; 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); + struct pipe_box src = { + .x = 0, + .y = 0, + .width = fb->width, + .height = fb->height, + }; - 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, + struct pipe_box dst = { + .x = 0, + .y = 0, + .width = fb->width, + .height = fb->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; + if (ctx->framebuffer.base.samples > 1) { + for (int i = 0; i < LIMA_MAX_SAMPLES; i++) { + lima_pack_blit_cmd(job, &job->plbu_cmd_head, + psurf, &src, &dst, + PIPE_TEX_FILTER_NEAREST, false, + (1 << i), i); } + } else { + lima_pack_blit_cmd(job, &job->plbu_cmd_head, + psurf, &src, &dst, + PIPE_TEX_FILTER_NEAREST, false, + 0xf, 0); } - - 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->texture_type = LIMA_TEXTURE_TYPE_2D; - td->min_img_filter_nearest = 1; - td->mag_img_filter_nearest = 1; - td->wrap_s_clamp_to_edge = 1; - td->wrap_t_clamp_to_edge = 1; - td->unknown_2_2 = 0x1; - - 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, - }; - 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, - }; - 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); } static void @@ -453,6 +399,9 @@ lima_pack_head_plbu_cmd(struct lima_job *job) PLBU_CMD_BEGIN(&job->plbu_cmd_head, 10); + assert((fb->block_w & PLBU_BLOCK_W_MASK) == fb->block_w); + assert((fb->block_h & PLBU_BLOCK_H_MASK) == fb->block_h); + PLBU_CMD_UNKNOWN2(); PLBU_CMD_BLOCK_STEP(fb->shift_min, fb->shift_h, fb->shift_w); PLBU_CMD_TILED_DIMENSIONS(fb->tiled_w, fb->tiled_h); @@ -464,8 +413,9 @@ lima_pack_head_plbu_cmd(struct lima_job *job) PLBU_CMD_END(); - if (lima_fb_cbuf_needs_reload(job)) + if (lima_fb_cbuf_needs_reload(job)) { lima_pack_reload_plbu_cmd(job, job->key.cbuf); + } if (lima_fb_zsbuf_needs_reload(job)) lima_pack_reload_plbu_cmd(job, job->key.zsbuf); @@ -543,7 +493,8 @@ lima_generate_pp_stream(struct lima_job *job, int off_x, int off_y, struct lima_pp_stream_state *ps = &ctx->pp_stream; struct lima_job_fb_info *fb = &job->fb; struct lima_screen *screen = lima_screen(ctx->base.screen); - int i, num_pp = screen->num_pp; + int num_pp = screen->num_pp; + assert(num_pp > 0); /* use hilbert_coords to generates 1D to 2D relationship. * 1D for pp stream index and 2D for plb block x/y on framebuffer. @@ -565,10 +516,10 @@ lima_generate_pp_stream(struct lima_job *job, int off_x, int off_y, count = 1 << (dim + dim); } - for (i = 0; i < num_pp; i++) + for (int i = 0; i < num_pp; i++) stream[i] = ps->map + ps->offset[i]; - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { int x, y; hilbert_coords(max, i, &x, &y); if (x < tiled_w && y < tiled_h) { @@ -589,7 +540,7 @@ lima_generate_pp_stream(struct lima_job *job, int off_x, int off_y, } } - for (i = 0; i < num_pp; i++) { + for (int i = 0; i < num_pp; i++) { stream[i][si[i]++] = 0; stream[i][si[i]++] = 0xBC000000; stream[i][si[i]++] = 0; @@ -800,7 +751,13 @@ lima_pack_wb_zsbuf_reg(struct lima_job *job, uint32_t *wb_reg, int wb_idx) wb[wb_idx].pixel_layout = 0x0; wb[wb_idx].pitch = res->levels[level].stride / 8; } - wb[wb_idx].mrt_bits = 0; + wb[wb_idx].flags = 0; + unsigned nr_samples = zsbuf->nr_samples ? + zsbuf->nr_samples : MAX2(1, zsbuf->texture->nr_samples); + if (nr_samples > 1) { + wb[wb_idx].mrt_pitch = res->mrt_pitch; + wb[wb_idx].mrt_bits = u_bit_consecutive(0, nr_samples); + } } static void @@ -829,7 +786,13 @@ lima_pack_wb_cbuf_reg(struct lima_job *job, uint32_t *frame_reg, wb[wb_idx].pixel_layout = 0x0; wb[wb_idx].pitch = res->levels[level].stride / 8; } - wb[wb_idx].mrt_bits = swap_channels ? 0x4 : 0x0; + wb[wb_idx].flags = swap_channels ? 0x4 : 0x0; + unsigned nr_samples = cbuf->nr_samples ? + cbuf->nr_samples : MAX2(1, cbuf->texture->nr_samples); + if (nr_samples > 1) { + wb[wb_idx].mrt_pitch = res->mrt_pitch; + wb[wb_idx].mrt_bits = u_bit_consecutive(0, nr_samples); + } } static void @@ -949,7 +912,7 @@ lima_do_job(struct lima_job *job) fprintf(stderr, "gp job error\n"); if (job->dump) { - if (lima_job_wait(job, LIMA_PIPE_GP, PIPE_TIMEOUT_INFINITE)) { + if (lima_job_wait(job, LIMA_PIPE_GP, OS_TIMEOUT_INFINITE)) { if (ctx->gp_output) { float *pos = lima_bo_map(ctx->gp_output); lima_dump_command_stream_print( @@ -1030,7 +993,7 @@ lima_do_job(struct lima_job *job) } if (job->dump) { - if (!lima_job_wait(job, LIMA_PIPE_PP, PIPE_TIMEOUT_INFINITE)) { + if (!lima_job_wait(job, LIMA_PIPE_PP, OS_TIMEOUT_INFINITE)) { fprintf(stderr, "pp wait error\n"); exit(1); } @@ -1111,6 +1074,14 @@ lima_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, } } +static void +lima_texture_barrier(struct pipe_context *pctx, unsigned flags) +{ + struct lima_context *ctx = lima_context(pctx); + + lima_flush(ctx); +} + static bool lima_job_compare(const void *s1, const void *s2) { @@ -1145,6 +1116,7 @@ bool lima_job_init(struct lima_context *ctx) } ctx->base.flush = lima_pipe_flush; + ctx->base.texture_barrier = lima_texture_barrier; return true; } |