summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/lima/lima_job.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/lima/lima_job.c')
-rw-r--r--src/gallium/drivers/lima/lima_job.c218
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;
}