vc4: Add support for drawing in MSAA.
This commit is contained in:
parent
e7c8ad0a6c
commit
edfd4d853a
|
@ -51,8 +51,13 @@ static bool
|
|||
vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
|
||||
{
|
||||
struct vc4_context *vc4 = vc4_context(pctx);
|
||||
int tile_width = 64;
|
||||
int tile_height = 64;
|
||||
bool old_msaa = vc4->msaa;
|
||||
int old_tile_width = vc4->tile_width;
|
||||
int old_tile_height = vc4->tile_height;
|
||||
bool msaa = (info->src.resource->nr_samples ||
|
||||
info->dst.resource->nr_samples);
|
||||
int tile_width = msaa ? 32 : 64;
|
||||
int tile_height = msaa ? 32 : 64;
|
||||
|
||||
if (util_format_is_depth_or_stencil(info->dst.resource->format))
|
||||
return false;
|
||||
|
@ -104,9 +109,14 @@ vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
|
|||
vc4_get_blit_surface(pctx, info->src.resource, info->src.level);
|
||||
|
||||
pipe_surface_reference(&vc4->color_read, src_surf);
|
||||
pipe_surface_reference(&vc4->color_write, dst_surf);
|
||||
pipe_surface_reference(&vc4->color_write,
|
||||
dst_surf->texture->nr_samples ? NULL : dst_surf);
|
||||
pipe_surface_reference(&vc4->msaa_color_write,
|
||||
dst_surf->texture->nr_samples ? dst_surf : NULL);
|
||||
pipe_surface_reference(&vc4->zs_read, NULL);
|
||||
pipe_surface_reference(&vc4->zs_write, NULL);
|
||||
pipe_surface_reference(&vc4->msaa_zs_write, NULL);
|
||||
|
||||
vc4->draw_min_x = info->dst.box.x;
|
||||
vc4->draw_min_y = info->dst.box.y;
|
||||
vc4->draw_max_x = info->dst.box.x + info->dst.box.width;
|
||||
|
@ -114,9 +124,17 @@ vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
|
|||
vc4->draw_width = dst_surf->width;
|
||||
vc4->draw_height = dst_surf->height;
|
||||
|
||||
vc4->tile_width = tile_width;
|
||||
vc4->tile_height = tile_height;
|
||||
vc4->msaa = msaa;
|
||||
vc4->needs_flush = true;
|
||||
|
||||
vc4_job_submit(vc4);
|
||||
|
||||
vc4->msaa = old_msaa;
|
||||
vc4->tile_width = old_tile_width;
|
||||
vc4->tile_height = old_tile_height;
|
||||
|
||||
pipe_surface_reference(&dst_surf, NULL);
|
||||
pipe_surface_reference(&src_surf, NULL);
|
||||
|
||||
|
@ -166,14 +184,6 @@ vc4_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
|||
{
|
||||
struct pipe_blit_info info = *blit_info;
|
||||
|
||||
if (info.src.resource->nr_samples > 1 &&
|
||||
info.dst.resource->nr_samples <= 1 &&
|
||||
!util_format_is_depth_or_stencil(info.src.resource->format) &&
|
||||
!util_format_is_pure_integer(info.src.resource->format)) {
|
||||
fprintf(stderr, "color resolve unimplemented\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (vc4_tile_blit(pctx, blit_info))
|
||||
return;
|
||||
|
||||
|
|
|
@ -67,8 +67,16 @@ vc4_flush(struct pipe_context *pctx)
|
|||
cl_u8(&bcl, VC4_PACKET_FLUSH);
|
||||
cl_end(&vc4->bcl, bcl);
|
||||
|
||||
vc4->msaa = false;
|
||||
if (cbuf && (vc4->resolve & PIPE_CLEAR_COLOR0)) {
|
||||
pipe_surface_reference(&vc4->color_write, cbuf);
|
||||
pipe_surface_reference(&vc4->color_write,
|
||||
cbuf->texture->nr_samples ? NULL : cbuf);
|
||||
pipe_surface_reference(&vc4->msaa_color_write,
|
||||
cbuf->texture->nr_samples ? cbuf : NULL);
|
||||
|
||||
if (cbuf->texture->nr_samples)
|
||||
vc4->msaa = true;
|
||||
|
||||
if (!(vc4->cleared & PIPE_CLEAR_COLOR0)) {
|
||||
pipe_surface_reference(&vc4->color_read, cbuf);
|
||||
} else {
|
||||
|
@ -78,11 +86,21 @@ vc4_flush(struct pipe_context *pctx)
|
|||
} else {
|
||||
pipe_surface_reference(&vc4->color_write, NULL);
|
||||
pipe_surface_reference(&vc4->color_read, NULL);
|
||||
pipe_surface_reference(&vc4->msaa_color_write, NULL);
|
||||
}
|
||||
|
||||
if (vc4->framebuffer.zsbuf &&
|
||||
(vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
|
||||
pipe_surface_reference(&vc4->zs_write, zsbuf);
|
||||
pipe_surface_reference(&vc4->zs_write,
|
||||
zsbuf->texture->nr_samples ?
|
||||
NULL : zsbuf);
|
||||
pipe_surface_reference(&vc4->msaa_zs_write,
|
||||
zsbuf->texture->nr_samples ?
|
||||
zsbuf : NULL);
|
||||
|
||||
if (zsbuf->texture->nr_samples)
|
||||
vc4->msaa = true;
|
||||
|
||||
if (!(vc4->cleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
|
||||
pipe_surface_reference(&vc4->zs_read, zsbuf);
|
||||
} else {
|
||||
|
@ -91,6 +109,7 @@ vc4_flush(struct pipe_context *pctx)
|
|||
} else {
|
||||
pipe_surface_reference(&vc4->zs_write, NULL);
|
||||
pipe_surface_reference(&vc4->zs_read, NULL);
|
||||
pipe_surface_reference(&vc4->msaa_zs_write, NULL);
|
||||
}
|
||||
|
||||
vc4_job_submit(vc4);
|
||||
|
|
|
@ -206,6 +206,8 @@ struct vc4_context {
|
|||
struct pipe_surface *color_write;
|
||||
struct pipe_surface *zs_read;
|
||||
struct pipe_surface *zs_write;
|
||||
struct pipe_surface *msaa_color_write;
|
||||
struct pipe_surface *msaa_zs_write;
|
||||
/** @} */
|
||||
/** @{
|
||||
* Bounding box of the scissor across all queued drawing.
|
||||
|
@ -224,6 +226,15 @@ struct vc4_context {
|
|||
uint32_t draw_width;
|
||||
uint32_t draw_height;
|
||||
/** @} */
|
||||
/** @{ Tile information, depending on MSAA and float color buffer. */
|
||||
uint32_t draw_tiles_x; /** @< Number of tiles wide for framebuffer. */
|
||||
uint32_t draw_tiles_y; /** @< Number of tiles high for framebuffer. */
|
||||
|
||||
uint32_t tile_width; /** @< Width of a tile. */
|
||||
uint32_t tile_height; /** @< Height of a tile. */
|
||||
/** Whether the current rendering is in a 4X MSAA tile buffer. */
|
||||
bool msaa;
|
||||
/** @} */
|
||||
|
||||
struct util_slab_mempool transfer_pool;
|
||||
struct blitter_context *blitter;
|
||||
|
|
|
@ -68,21 +68,17 @@ vc4_start_draw(struct vc4_context *vc4)
|
|||
|
||||
vc4_get_draw_cl_space(vc4);
|
||||
|
||||
uint32_t width = vc4->framebuffer.width;
|
||||
uint32_t height = vc4->framebuffer.height;
|
||||
uint32_t tilew = align(width, 64) / 64;
|
||||
uint32_t tileh = align(height, 64) / 64;
|
||||
struct vc4_cl_out *bcl = cl_start(&vc4->bcl);
|
||||
|
||||
// Tile state data is 48 bytes per tile, I think it can be thrown away
|
||||
// as soon as binning is finished.
|
||||
cl_u8(&bcl, VC4_PACKET_TILE_BINNING_MODE_CONFIG);
|
||||
cl_u32(&bcl, 0); /* tile alloc addr, filled by kernel */
|
||||
cl_u32(&bcl, 0); /* tile alloc size, filled by kernel */
|
||||
cl_u32(&bcl, 0); /* tile state addr, filled by kernel */
|
||||
cl_u8(&bcl, tilew);
|
||||
cl_u8(&bcl, tileh);
|
||||
cl_u8(&bcl, 0); /* flags, filled by kernel. */
|
||||
cl_u8(&bcl, vc4->draw_tiles_x);
|
||||
cl_u8(&bcl, vc4->draw_tiles_y);
|
||||
/* Other flags are filled by kernel. */
|
||||
cl_u8(&bcl, vc4->msaa ? VC4_BIN_CONFIG_MS_MODE_4X : 0);
|
||||
|
||||
/* START_TILE_BINNING resets the statechange counters in the hardware,
|
||||
* which are what is used when a primitive is binned to a tile to
|
||||
|
@ -102,8 +98,8 @@ vc4_start_draw(struct vc4_context *vc4)
|
|||
|
||||
vc4->needs_flush = true;
|
||||
vc4->draw_calls_queued++;
|
||||
vc4->draw_width = width;
|
||||
vc4->draw_height = height;
|
||||
vc4->draw_width = vc4->framebuffer.width;
|
||||
vc4->draw_height = vc4->framebuffer.height;
|
||||
|
||||
cl_end(&vc4->bcl, bcl);
|
||||
}
|
||||
|
|
|
@ -89,22 +89,28 @@ vc4_submit_setup_rcl_surface(struct vc4_context *vc4,
|
|||
submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
|
||||
submit_surf->offset = surf->offset;
|
||||
|
||||
if (is_depth) {
|
||||
submit_surf->bits =
|
||||
VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS,
|
||||
VC4_LOADSTORE_TILE_BUFFER_BUFFER);
|
||||
if (psurf->texture->nr_samples == 0) {
|
||||
if (is_depth) {
|
||||
submit_surf->bits =
|
||||
VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS,
|
||||
VC4_LOADSTORE_TILE_BUFFER_BUFFER);
|
||||
|
||||
} else {
|
||||
submit_surf->bits =
|
||||
VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR,
|
||||
VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
|
||||
VC4_SET_FIELD(vc4_rt_format_is_565(psurf->format) ?
|
||||
VC4_LOADSTORE_TILE_BUFFER_BGR565 :
|
||||
VC4_LOADSTORE_TILE_BUFFER_RGBA8888,
|
||||
VC4_LOADSTORE_TILE_BUFFER_FORMAT);
|
||||
}
|
||||
submit_surf->bits |=
|
||||
VC4_SET_FIELD(surf->tiling,
|
||||
VC4_LOADSTORE_TILE_BUFFER_TILING);
|
||||
} else {
|
||||
submit_surf->bits =
|
||||
VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR,
|
||||
VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
|
||||
VC4_SET_FIELD(vc4_rt_format_is_565(psurf->format) ?
|
||||
VC4_LOADSTORE_TILE_BUFFER_BGR565 :
|
||||
VC4_LOADSTORE_TILE_BUFFER_RGBA8888,
|
||||
VC4_LOADSTORE_TILE_BUFFER_FORMAT);
|
||||
assert(!is_write);
|
||||
submit_surf->flags |= VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES;
|
||||
}
|
||||
submit_surf->bits |=
|
||||
VC4_SET_FIELD(surf->tiling, VC4_LOADSTORE_TILE_BUFFER_TILING);
|
||||
|
||||
if (is_write)
|
||||
rsc->writes++;
|
||||
|
@ -126,16 +132,38 @@ vc4_submit_setup_rcl_render_config_surface(struct vc4_context *vc4,
|
|||
submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
|
||||
submit_surf->offset = surf->offset;
|
||||
|
||||
submit_surf->bits =
|
||||
VC4_SET_FIELD(vc4_rt_format_is_565(surf->base.format) ?
|
||||
VC4_RENDER_CONFIG_FORMAT_BGR565 :
|
||||
VC4_RENDER_CONFIG_FORMAT_RGBA8888,
|
||||
VC4_RENDER_CONFIG_FORMAT) |
|
||||
VC4_SET_FIELD(surf->tiling, VC4_RENDER_CONFIG_MEMORY_FORMAT);
|
||||
if (psurf->texture->nr_samples == 0) {
|
||||
submit_surf->bits =
|
||||
VC4_SET_FIELD(vc4_rt_format_is_565(surf->base.format) ?
|
||||
VC4_RENDER_CONFIG_FORMAT_BGR565 :
|
||||
VC4_RENDER_CONFIG_FORMAT_RGBA8888,
|
||||
VC4_RENDER_CONFIG_FORMAT) |
|
||||
VC4_SET_FIELD(surf->tiling,
|
||||
VC4_RENDER_CONFIG_MEMORY_FORMAT);
|
||||
}
|
||||
|
||||
rsc->writes++;
|
||||
}
|
||||
|
||||
static void
|
||||
vc4_submit_setup_rcl_msaa_surface(struct vc4_context *vc4,
|
||||
struct drm_vc4_submit_rcl_surface *submit_surf,
|
||||
struct pipe_surface *psurf)
|
||||
{
|
||||
struct vc4_surface *surf = vc4_surface(psurf);
|
||||
|
||||
if (!surf) {
|
||||
submit_surf->hindex = ~0;
|
||||
return;
|
||||
}
|
||||
|
||||
struct vc4_resource *rsc = vc4_resource(psurf->texture);
|
||||
submit_surf->hindex = vc4_gem_hindex(vc4, rsc->bo);
|
||||
submit_surf->offset = surf->offset;
|
||||
submit_surf->bits = 0;
|
||||
rsc->writes++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits the job to the kernel and then reinitializes it.
|
||||
*/
|
||||
|
@ -150,8 +178,8 @@ vc4_job_submit(struct vc4_context *vc4)
|
|||
struct drm_vc4_submit_cl submit;
|
||||
memset(&submit, 0, sizeof(submit));
|
||||
|
||||
cl_ensure_space(&vc4->bo_handles, 4 * sizeof(uint32_t));
|
||||
cl_ensure_space(&vc4->bo_pointers, 4 * sizeof(struct vc4_bo *));
|
||||
cl_ensure_space(&vc4->bo_handles, 6 * sizeof(uint32_t));
|
||||
cl_ensure_space(&vc4->bo_pointers, 6 * sizeof(struct vc4_bo *));
|
||||
|
||||
vc4_submit_setup_rcl_surface(vc4, &submit.color_read,
|
||||
vc4->color_read, false, false);
|
||||
|
@ -161,8 +189,23 @@ vc4_job_submit(struct vc4_context *vc4)
|
|||
vc4->zs_read, true, false);
|
||||
vc4_submit_setup_rcl_surface(vc4, &submit.zs_write,
|
||||
vc4->zs_write, true, true);
|
||||
submit.msaa_color_write.hindex = ~0;
|
||||
submit.msaa_zs_write.hindex = ~0;
|
||||
|
||||
vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_color_write,
|
||||
vc4->msaa_color_write);
|
||||
vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_zs_write,
|
||||
vc4->msaa_zs_write);
|
||||
|
||||
if (vc4->msaa) {
|
||||
/* This bit controls how many pixels the general
|
||||
* (i.e. subsampled) loads/stores are iterating over
|
||||
* (multisample loads replicate out to the other samples).
|
||||
*/
|
||||
submit.color_write.bits |= VC4_RENDER_CONFIG_MS_MODE_4X;
|
||||
/* Controls whether color_write's
|
||||
* VC4_PACKET_STORE_MS_TILE_BUFFER does 4x decimation
|
||||
*/
|
||||
submit.color_write.bits |= VC4_RENDER_CONFIG_DECIMATE_MODE_4X;
|
||||
}
|
||||
|
||||
submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
|
||||
submit.bo_handle_count = cl_offset(&vc4->bo_handles) / 4;
|
||||
|
@ -175,10 +218,10 @@ vc4_job_submit(struct vc4_context *vc4)
|
|||
submit.uniforms_size = cl_offset(&vc4->uniforms);
|
||||
|
||||
assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0);
|
||||
submit.min_x_tile = vc4->draw_min_x / 64;
|
||||
submit.min_y_tile = vc4->draw_min_y / 64;
|
||||
submit.max_x_tile = (vc4->draw_max_x - 1) / 64;
|
||||
submit.max_y_tile = (vc4->draw_max_y - 1) / 64;
|
||||
submit.min_x_tile = vc4->draw_min_x / vc4->tile_width;
|
||||
submit.min_y_tile = vc4->draw_min_y / vc4->tile_height;
|
||||
submit.max_x_tile = (vc4->draw_max_x - 1) / vc4->tile_width;
|
||||
submit.max_y_tile = (vc4->draw_max_y - 1) / vc4->tile_height;
|
||||
submit.width = vc4->draw_width;
|
||||
submit.height = vc4->draw_height;
|
||||
if (vc4->cleared) {
|
||||
|
|
|
@ -121,6 +121,9 @@ vc4_create_rasterizer_state(struct pipe_context *pctx,
|
|||
so->offset_factor = float_to_187_half(cso->offset_scale);
|
||||
}
|
||||
|
||||
if (cso->multisample)
|
||||
so->config_bits[0] |= VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
||||
|
@ -457,6 +460,22 @@ vc4_set_framebuffer_state(struct pipe_context *pctx,
|
|||
rsc->cpp);
|
||||
}
|
||||
|
||||
vc4->msaa = false;
|
||||
if (cso->cbufs[0])
|
||||
vc4->msaa = cso->cbufs[0]->texture->nr_samples != 0;
|
||||
else if (cso->zsbuf)
|
||||
vc4->msaa = cso->zsbuf->texture->nr_samples != 0;
|
||||
|
||||
if (vc4->msaa) {
|
||||
vc4->tile_width = 32;
|
||||
vc4->tile_height = 32;
|
||||
} else {
|
||||
vc4->tile_width = 64;
|
||||
vc4->tile_height = 64;
|
||||
}
|
||||
vc4->draw_tiles_x = DIV_ROUND_UP(cso->width, vc4->tile_width);
|
||||
vc4->draw_tiles_y = DIV_ROUND_UP(cso->height, vc4->tile_height);
|
||||
|
||||
vc4->dirty |= VC4_DIRTY_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue