-struct lima_gp_frame_reg {
- uint32_t vs_cmd_start;
- uint32_t vs_cmd_end;
- uint32_t plbu_cmd_start;
- uint32_t plbu_cmd_end;
- uint32_t tile_heap_start;
- uint32_t tile_heap_end;
-};
-
-struct lima_pp_frame_reg {
- uint32_t plbu_array_address;
- uint32_t render_address;
- uint32_t unused_0;
- uint32_t flags;
- uint32_t clear_value_depth;
- uint32_t clear_value_stencil;
- uint32_t clear_value_color;
- uint32_t clear_value_color_1;
- uint32_t clear_value_color_2;
- uint32_t clear_value_color_3;
- uint32_t width;
- uint32_t height;
- uint32_t fragment_stack_address;
- uint32_t fragment_stack_size;
- uint32_t unused_1;
- uint32_t unused_2;
- uint32_t one;
- uint32_t supersampled_height;
- uint32_t dubya;
- uint32_t onscreen;
- uint32_t blocking;
- uint32_t scale;
- uint32_t foureight;
-};
-
-struct lima_pp_wb_reg {
- uint32_t type;
- uint32_t address;
- uint32_t pixel_format;
- uint32_t downsample_factor;
- uint32_t pixel_layout;
- uint32_t pitch;
- uint32_t mrt_bits;
- uint32_t mrt_pitch;
- uint32_t zero;
- uint32_t unused0;
- uint32_t unused1;
- uint32_t unused2;
-};
-
-struct lima_render_state {
- uint32_t blend_color_bg;
- uint32_t blend_color_ra;
- uint32_t alpha_blend;
- uint32_t depth_test;
- uint32_t depth_range;
- uint32_t stencil_front;
- uint32_t stencil_back;
- uint32_t stencil_test;
- uint32_t multi_sample;
- uint32_t shader_address;
- uint32_t varying_types;
- uint32_t uniforms_address;
- uint32_t textures_address;
- uint32_t aux0;
- uint32_t aux1;
- uint32_t varyings_address;
-};
-
-
-/* plbu commands */
-#define PLBU_CMD_BEGIN(max) { \
- int i = 0, max_n = max; \
- uint32_t *plbu_cmd = util_dynarray_ensure_cap(&ctx->plbu_cmd_array, ctx->plbu_cmd_array.size + max_n * 4);
-
-#define PLBU_CMD_END() \
- assert(i <= max_n); \
- ctx->plbu_cmd_array.size += i * 4; \
-}
-
-#define PLBU_CMD(v1, v2) \
- do { \
- plbu_cmd[i++] = v1; \
- plbu_cmd[i++] = v2; \
- } while (0)
-
-#define PLBU_CMD_BLOCK_STEP(shift_min, shift_h, shift_w) \
- PLBU_CMD(((shift_min) << 28) | ((shift_h) << 16) | (shift_w), 0x1000010C)
-#define PLBU_CMD_TILED_DIMENSIONS(tiled_w, tiled_h) \
- PLBU_CMD((((tiled_w) - 1) << 24) | (((tiled_h) - 1) << 8), 0x10000109)
-#define PLBU_CMD_BLOCK_STRIDE(block_w) PLBU_CMD((block_w) & 0xff, 0x30000000)
-#define PLBU_CMD_ARRAY_ADDRESS(gp_stream, block_num) \
- PLBU_CMD(gp_stream, 0x28000000 | ((block_num) - 1) | 1)
-#define PLBU_CMD_VIEWPORT_LEFT(v) PLBU_CMD(v, 0x10000107)
-#define PLBU_CMD_VIEWPORT_RIGHT(v) PLBU_CMD(v, 0x10000108)
-#define PLBU_CMD_VIEWPORT_BOTTOM(v) PLBU_CMD(v, 0x10000105)
-#define PLBU_CMD_VIEWPORT_TOP(v) PLBU_CMD(v, 0x10000106)
-#define PLBU_CMD_ARRAYS_SEMAPHORE_BEGIN() PLBU_CMD(0x00010002, 0x60000000)
-#define PLBU_CMD_ARRAYS_SEMAPHORE_END() PLBU_CMD(0x00010001, 0x60000000)
-#define PLBU_CMD_PRIMITIVE_SETUP(prim, cull, index_size) \
- PLBU_CMD(0x200 | (prim) | (cull) | ((index_size) << 9), 0x1000010B)
-#define PLBU_CMD_RSW_VERTEX_ARRAY(rsw, gl_pos) \
- PLBU_CMD(rsw, 0x80000000 | ((gl_pos) >> 4))
-#define PLBU_CMD_SCISSORS(minx, maxx, miny, maxy) \
- PLBU_CMD(((minx) << 30) | ((maxy) - 1) << 15 | (miny), \
- 0x70000000 | ((maxx) - 1) << 13 | ((minx) >> 2))
-#define PLBU_CMD_UNKNOWN1() PLBU_CMD(0x00000000, 0x1000010A)
-#define PLBU_CMD_UNKNOWN2() PLBU_CMD(0x00000200, 0x1000010B)
-#define PLBU_CMD_LOW_PRIM_SIZE(v) PLBU_CMD(v, 0x1000010D)
-#define PLBU_CMD_DEPTH_RANGE_NEAR(v) PLBU_CMD(v, 0x1000010E)
-#define PLBU_CMD_DEPTH_RANGE_FAR(v) PLBU_CMD(v, 0x1000010F)
-#define PLBU_CMD_INDEXED_DEST(gl_pos) PLBU_CMD(gl_pos, 0x10000100)
-#define PLBU_CMD_INDEXED_PT_SIZE(pt_size) PLBU_CMD(pt_size, 0x10000102)
-#define PLBU_CMD_INDICES(va) PLBU_CMD(va, 0x10000101)
-#define PLBU_CMD_DRAW_ARRAYS(mode, start, count) \
- PLBU_CMD(((count) << 24) | (start), (((mode) & 0x1F) << 16) | ((count) >> 8))
-#define PLBU_CMD_DRAW_ELEMENTS(mode, start, count) \
- PLBU_CMD(((count) << 24) | (start), \
- 0x00200000 | (((mode) & 0x1F) << 16) | ((count) >> 8))
-
-/* vs commands */
-#define VS_CMD_BEGIN(max) { \
- int i = 0, max_n = max; \
- uint32_t *vs_cmd = util_dynarray_ensure_cap(&ctx->vs_cmd_array, ctx->vs_cmd_array.size + max_n * 4);
-
-#define VS_CMD_END() \
- assert(i <= max_n); \
- ctx->vs_cmd_array.size += i * 4; \
-}
-
-#define VS_CMD(v1, v2) \
- do { \
- vs_cmd[i++] = v1; \
- vs_cmd[i++] = v2; \
- } while (0)
-
-#define VS_CMD_ARRAYS_SEMAPHORE_BEGIN_1() VS_CMD(0x00028000, 0x50000000)
-#define VS_CMD_ARRAYS_SEMAPHORE_BEGIN_2() VS_CMD(0x00000001, 0x50000000)
-#define VS_CMD_ARRAYS_SEMAPHORE_END(index_draw) \
- VS_CMD((index_draw) ? 0x00018000 : 0x00000000, 0x50000000)
-#define VS_CMD_UNIFORMS_ADDRESS(addr, size) \
- VS_CMD(addr, 0x30000000 | ((size) << 12))
-#define VS_CMD_SHADER_ADDRESS(addr, size) \
- VS_CMD(addr, 0x40000000 | ((size) << 12))
-#define VS_CMD_SHADER_INFO(prefetch, size) \
- VS_CMD(((prefetch) << 20) | ((((size) >> 4) - 1) << 10), 0x10000040)
-#define VS_CMD_VARYING_ATTRIBUTE_COUNT(nv, na) \
- VS_CMD((((nv) - 1) << 8) | (((na) - 1) << 24), 0x10000042)
-#define VS_CMD_UNKNOWN1() VS_CMD(0x00000003, 0x10000041)
-#define VS_CMD_UNKNOWN2() VS_CMD(0x00000000, 0x60000000)
-#define VS_CMD_ATTRIBUTES_ADDRESS(addr, na) \
- VS_CMD(addr, 0x20000000 | ((na) << 17))
-#define VS_CMD_VARYINGS_ADDRESS(addr, nv) \
- VS_CMD(addr, 0x20000008 | ((nv) << 17))
-#define VS_CMD_DRAW(num, index_draw) \
- VS_CMD(((num) << 24) | ((index_draw) ? 1 : 0), ((num) >> 8))
-
-static inline bool
-lima_ctx_dirty(struct lima_context *ctx)
-{
- return ctx->plbu_cmd_array.size;
-}
-
-static inline struct lima_damage_region *
-lima_ctx_get_damage(struct lima_context *ctx)
-{
- if (!ctx->framebuffer.base.nr_cbufs)
- return NULL;
-
- struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
- struct lima_resource *res = lima_resource(surf->base.texture);
- return &res->damage;
-}
-
-static bool
-lima_fb_need_reload(struct lima_context *ctx)
-{
- /* Depth buffer is always discarded */
- if (!ctx->framebuffer.base.nr_cbufs)
- return false;
-
- struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
- struct lima_resource *res = lima_resource(surf->base.texture);
- if (res->damage.region) {
- /* for EGL_KHR_partial_update, when EGL_EXT_buffer_age is enabled,
- * we need to reload damage region, otherwise just want to reload
- * the region not aligned to tile boundary */
- //if (!res->damage.aligned)
- // return true;
- return true;
- }
- else if (surf->reload)
- return true;
-
- return false;
-}
-
-static void
-lima_pack_reload_plbu_cmd(struct lima_context *ctx)
-{
- #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
-
- void *cpu;
- unsigned offset;
- struct pipe_resource *pres = NULL;
- u_upload_alloc(ctx->uploader, 0, lima_reload_buffer_size,
- 0x40, &offset, &pres, &cpu);
-
- struct lima_resource *res = lima_resource(pres);
- uint32_t va = res->bo->va + offset;
-
- 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,
- };
- memcpy(cpu + lima_reload_render_state_offset, &reload_render_state,
- sizeof(reload_render_state));
-
- struct lima_context_framebuffer *fb = &ctx->framebuffer;
- 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, fb->base.cbufs[0]->texture, 0, 0);
- 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;
-
- float reload_gl_pos[] = {
- fb->base.width, 0, 0, 1,
- 0, 0, 0, 1,
- 0, fb->base.height, 0, 1,
- };
- memcpy(cpu + lima_reload_gl_pos_offset, reload_gl_pos,
- sizeof(reload_gl_pos));
-
- float reload_varying[] = {
- fb->base.width, 0, 0, 0,
- 0, fb->base.height, 0, 0,
- };
- memcpy(cpu + lima_reload_varying_offset, reload_varying,
- sizeof(reload_varying));
-
- lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_READ);
- pipe_resource_reference(&pres, NULL);
-
- PLBU_CMD_BEGIN(20);
-
- PLBU_CMD_VIEWPORT_LEFT(0);
- PLBU_CMD_VIEWPORT_RIGHT(fui(fb->base.width));
- PLBU_CMD_VIEWPORT_BOTTOM(0);
- PLBU_CMD_VIEWPORT_TOP(fui(fb->base.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();
-}
-
-static void
-lima_pack_head_plbu_cmd(struct lima_context *ctx)
-{
- /* first draw need create a PLBU command header */
- if (lima_ctx_dirty(ctx))
- return;
-
- struct lima_context_framebuffer *fb = &ctx->framebuffer;
-
- PLBU_CMD_BEGIN(10);
-
- 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);
- PLBU_CMD_BLOCK_STRIDE(fb->block_w);
-
- PLBU_CMD_ARRAY_ADDRESS(
- ctx->plb_gp_stream->va + ctx->plb_index * ctx->plb_gp_size,
- fb->block_w * fb->block_h);
-
- PLBU_CMD_END();
-
- if (lima_fb_need_reload(ctx))
- lima_pack_reload_plbu_cmd(ctx);
-}
-