lima: implement zsbuf reload

Fragment shader can write depth and stencil if we set necessary flags
in RSW. In addition to that we need to use special format for Z24S8.
Original format is apparently Z24X8 since we can't sample stencil in GLES2.
This new format also seems to use several components for storing depth
since we saw r != g != b when sampling with this format.

[vasily: - initialize clear->depth to 0xffffff if we reload depth, just
           like blob does. Reloading doesn't work otherwise
         - use single bitmap for reload type]

Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Reviewed-by: Andreas Baierl <ichgeh@imkreisrum.de>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4197>
This commit is contained in:
Icenowy Zheng 2020-02-07 00:53:46 +08:00 committed by Marge Bot
parent dbceabed72
commit 9205762cae
7 changed files with 85 additions and 39 deletions

View File

@ -4,27 +4,6 @@ dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_neg_y_pos_z_a
dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_pos_y_pos_z_and_pos_x_neg_y_neg_z
dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_neg_y_pos_z_and_neg_x_pos_y_neg_z
dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_pos_y_pos_z_and_neg_x_neg_y_neg_z
dEQP-GLES2.functional.depth_stencil_clear.depth_stencil_masked
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb565_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb565_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb5_a1_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb5_a1_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgba4_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgba4_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgba_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgba_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgb_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgb_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb565_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb565_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb5_a1_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb5_a1_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgba4_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgba4_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgba_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgba_stencil_index8
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgb_depth_component16
dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgb_stencil_index8
dEQP-GLES2.functional.fbo.render.shared_depthbuffer.rbo_rgb565_depth_component16
dEQP-GLES2.functional.fbo.render.shared_depthbuffer.rbo_rgb5_a1_depth_component16
dEQP-GLES2.functional.fbo.render.shared_depthbuffer.rbo_rgba4_depth_component16

View File

@ -118,7 +118,7 @@ lima_clear(struct pipe_context *pctx, unsigned buffers,
/* no need to reload if cleared */
if (ctx->framebuffer.base.nr_cbufs && (buffers & PIPE_CLEAR_COLOR0)) {
struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
surf->reload = false;
surf->reload &= ~PIPE_CLEAR_COLOR0;
}
struct lima_job_clear *clear = &job->clear;
@ -138,11 +138,20 @@ lima_clear(struct pipe_context *pctx, unsigned buffers,
float_to_ushort(color->f[0]);
}
if (buffers & PIPE_CLEAR_DEPTH)
clear->depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
struct lima_surface *zsbuf = lima_surface(ctx->framebuffer.base.zsbuf);
if (buffers & PIPE_CLEAR_STENCIL)
if (buffers & PIPE_CLEAR_DEPTH) {
clear->depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
if (zsbuf)
zsbuf->reload &= ~PIPE_CLEAR_DEPTH;
} else
clear->depth = 0x00ffffff;
if (buffers & PIPE_CLEAR_STENCIL) {
clear->stencil = stencil;
if (zsbuf)
zsbuf->reload &= ~PIPE_CLEAR_STENCIL;
}
ctx->dirty |= LIMA_CONTEXT_DIRTY_CLEAR;

View File

@ -44,7 +44,9 @@
#define LIMA_TEXEL_FORMAT_RGBA_8888 0x16
#define LIMA_TEXEL_FORMAT_RGBX_8888 0x17
#define LIMA_TEXEL_FORMAT_ETC1_RGB8 0x20
#define LIMA_TEXEL_FORMAT_Z24S8 0x2c
#define LIMA_TEXEL_FORMAT_Z24X8 0x2c
/* This format is only used for depth/stencil reload */
#define LIMA_TEXEL_FORMAT_Z24S8_RLD 0x32
#define LIMA_TEXEL_FORMAT_NONE -1
#define LIMA_PIXEL_FORMAT_B5G6R5 0x00
@ -81,8 +83,8 @@ static const struct lima_format lima_format_table[] = {
/* BGRA_5551 seems to need channel layout 0x8565, it's not a typo */
LIMA_FORMAT(B5G5R5A1_UNORM, BGRA_5551, B5G5R5A1, false, 0x8565),
LIMA_FORMAT(B4G4R4A4_UNORM, BGRA_4444, B4G4R4A4, false, 0x8444),
LIMA_FORMAT(Z24_UNORM_S8_UINT, Z24S8, Z24S8, false, 0x0000),
LIMA_FORMAT(Z24X8_UNORM, Z24S8, Z24S8, false, 0x0000),
LIMA_FORMAT(Z24_UNORM_S8_UINT, Z24X8, Z24S8, false, 0x0000),
LIMA_FORMAT(Z24X8_UNORM, Z24X8, Z24S8, false, 0x0000),
LIMA_FORMAT(L16_UNORM, L16, NONE, false, 0x0000),
LIMA_FORMAT(L8_UNORM, L8, NONE, false, 0x0000),
LIMA_FORMAT(A16_UNORM, A16, NONE, false, 0x0000),
@ -131,6 +133,18 @@ lima_format_get_texel(enum pipe_format f)
return lima_format_table[f].texel;
}
int
lima_format_get_texel_reload(enum pipe_format f)
{
switch (f) {
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
case PIPE_FORMAT_Z24X8_UNORM:
return LIMA_TEXEL_FORMAT_Z24S8_RLD;
default:
return lima_format_get_texel(f);
}
}
int
lima_format_get_pixel(enum pipe_format f)
{

View File

@ -32,6 +32,7 @@ bool lima_format_texel_supported(enum pipe_format f);
bool lima_format_pixel_supported(enum pipe_format f);
int lima_format_get_texel(enum pipe_format f);
int lima_format_get_pixel(enum pipe_format f);
int lima_format_get_texel_reload(enum pipe_format f);
bool lima_format_get_swap_rb(enum pipe_format f);
uint32_t lima_format_get_channel_layout(enum pipe_format f);

View File

@ -31,6 +31,7 @@
#include "util/ralloc.h"
#include "util/os_time.h"
#include "util/hash_table.h"
#include "util/format/u_format.h"
#include "util/u_upload_mgr.h"
#include "util/u_inlines.h"
@ -296,9 +297,8 @@ lima_job_get_damage(struct lima_job *job)
}
static bool
lima_fb_need_reload(struct lima_job *job)
lima_fb_cbuf_needs_reload(struct lima_job *job)
{
/* Depth buffer is always discarded */
if (!(job->key.cbuf && (job->resolve & PIPE_CLEAR_COLOR0)))
return false;
@ -312,14 +312,27 @@ lima_fb_need_reload(struct lima_job *job)
// return true;
return true;
}
else if (surf->reload)
else if (surf->reload & PIPE_CLEAR_COLOR0)
return true;
return false;
}
static bool
lima_fb_zsbuf_needs_reload(struct lima_job *job)
{
if (!(job->key.zsbuf && (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))))
return false;
struct lima_surface *surf = lima_surface(job->key.zsbuf);
if (surf->reload & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))
return true;
return false;
}
static void
lima_pack_reload_plbu_cmd(struct lima_job *job)
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
@ -329,6 +342,7 @@ lima_pack_reload_plbu_cmd(struct lima_job *job)
#define lima_reload_buffer_size 0x0140
struct lima_context *ctx = job->ctx;
struct lima_surface *surf = lima_surface(psurf);
uint32_t va;
void *cpu = lima_job_create_stream_bo(
@ -353,12 +367,27 @@ lima_pack_reload_plbu_cmd(struct lima_job *job)
.aux0 = 0x00004021,
.varyings_address = va + lima_reload_varying_offset,
};
if (util_format_is_depth_or_stencil(psurf->format)) {
reload_render_state.alpha_blend &= 0x0fffffff;
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, job->key.cbuf->texture, 0, 0);
lima_texture_desc_set_res(ctx, td, psurf->texture, 0, 0);
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;
@ -426,8 +455,11 @@ lima_pack_head_plbu_cmd(struct lima_job *job)
PLBU_CMD_END();
if (lima_fb_need_reload(job))
lima_pack_reload_plbu_cmd(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);
}
static void
@ -986,10 +1018,15 @@ lima_do_job(struct lima_job *job)
ctx->plb_index = (ctx->plb_index + 1) % lima_ctx_num_plb;
/* Set reload flags for next draw. It'll be unset if buffer is cleared */
if (job->key.cbuf && (job->resolve & PIPE_CLEAR_COLOR0)) {
/* Set reload flag for next draw. It'll be unset if buffer is cleared */
struct lima_surface *surf = lima_surface(job->key.cbuf);
surf->reload = true;
surf->reload = PIPE_CLEAR_COLOR0;
}
if (job->key.zsbuf && (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
struct lima_surface *surf = lima_surface(job->key.zsbuf);
surf->reload = (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL));
}
if (ctx->job == job)

View File

@ -508,7 +508,13 @@ lima_surface_create(struct pipe_context *pctx,
surf->tiled_w = align(psurf->width, 16) >> 4;
surf->tiled_h = align(psurf->height, 16) >> 4;
surf->reload = true;
surf->reload = 0;
if (util_format_has_stencil(util_format_description(psurf->format)))
surf->reload |= PIPE_CLEAR_STENCIL;
if (util_format_has_depth(util_format_description(psurf->format)))
surf->reload |= PIPE_CLEAR_DEPTH;
if (!util_format_is_depth_or_stencil(psurf->format))
surf->reload |= PIPE_CLEAR_COLOR0;
return &surf->base;
}

View File

@ -62,7 +62,7 @@ struct lima_resource {
struct lima_surface {
struct pipe_surface base;
int tiled_w, tiled_h;
bool reload;
unsigned reload;
};
struct lima_transfer {