mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 02:00:12 +01:00
ilo: hook up pipe context blit functions
This commit is contained in:
parent
89d1702b9b
commit
0754ff33e3
3 changed files with 269 additions and 5 deletions
|
|
@ -25,19 +25,271 @@
|
|||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include "util/u_blitter.h"
|
||||
#include "util/u_clear.h"
|
||||
#include "util/u_pack_color.h"
|
||||
#include "util/u_surface.h"
|
||||
#include "intel_reg.h"
|
||||
|
||||
#include "ilo_context.h"
|
||||
#include "ilo_cp.h"
|
||||
#include "ilo_resource.h"
|
||||
#include "ilo_screen.h"
|
||||
#include "ilo_blit.h"
|
||||
|
||||
static bool
|
||||
blitter_xy_color_blt(struct pipe_context *pipe,
|
||||
struct pipe_resource *r,
|
||||
int16_t x1, int16_t y1,
|
||||
int16_t x2, int16_t y2,
|
||||
uint32_t color)
|
||||
{
|
||||
const int cmd_len = 6;
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct ilo_resource *res = ilo_resource(r);
|
||||
uint32_t cmd, br13;
|
||||
int cpp, stride;
|
||||
struct intel_bo *bo_check[2];
|
||||
|
||||
/* how to support Y-tiling? */
|
||||
if (res->tiling == INTEL_TILING_Y)
|
||||
return false;
|
||||
|
||||
/* nothing to clear */
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
return true;
|
||||
|
||||
cmd = XY_COLOR_BLT_CMD | (cmd_len - 2);
|
||||
br13 = 0xf0 << 16;
|
||||
|
||||
cpp = util_format_get_blocksize(res->base.format);
|
||||
switch (cpp) {
|
||||
case 4:
|
||||
cmd |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
|
||||
br13 |= BR13_8888;
|
||||
break;
|
||||
case 2:
|
||||
br13 |= BR13_565;
|
||||
break;
|
||||
case 1:
|
||||
br13 |= BR13_8;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
stride = res->bo_stride;
|
||||
if (res->tiling != INTEL_TILING_NONE) {
|
||||
assert(res->tiling == INTEL_TILING_X);
|
||||
|
||||
cmd |= XY_DST_TILED;
|
||||
/* in dwords */
|
||||
stride /= 4;
|
||||
}
|
||||
|
||||
/* make room if necessary */
|
||||
bo_check[0] = ilo->cp->bo;
|
||||
bo_check[1] = res->bo;
|
||||
if (ilo->winsys->check_aperture_space(ilo->winsys, bo_check, 2))
|
||||
ilo_cp_flush(ilo->cp);
|
||||
|
||||
ilo_cp_set_ring(ilo->cp, ILO_CP_RING_BLT);
|
||||
|
||||
ilo_cp_begin(ilo->cp, cmd_len);
|
||||
ilo_cp_write(ilo->cp, cmd);
|
||||
ilo_cp_write(ilo->cp, br13 | stride);
|
||||
ilo_cp_write(ilo->cp, (y1 << 16) | x1);
|
||||
ilo_cp_write(ilo->cp, (y2 << 16) | x2);
|
||||
ilo_cp_write_bo(ilo->cp, 0, res->bo,
|
||||
INTEL_DOMAIN_RENDER,
|
||||
INTEL_DOMAIN_RENDER);
|
||||
ilo_cp_write(ilo->cp, color);
|
||||
ilo_cp_end(ilo->cp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum ilo_blitter_op {
|
||||
ILO_BLITTER_CLEAR,
|
||||
ILO_BLITTER_CLEAR_SURFACE,
|
||||
ILO_BLITTER_BLIT,
|
||||
};
|
||||
|
||||
static void
|
||||
ilo_blitter_begin(struct ilo_context *ilo, enum ilo_blitter_op op)
|
||||
{
|
||||
/* as documented in util/u_blitter.h */
|
||||
util_blitter_save_vertex_buffer_slot(ilo->blitter,
|
||||
ilo->vertex_buffers.buffers);
|
||||
util_blitter_save_vertex_elements(ilo->blitter, ilo->vertex_elements);
|
||||
util_blitter_save_vertex_shader(ilo->blitter, ilo->vs);
|
||||
util_blitter_save_geometry_shader(ilo->blitter, ilo->gs);
|
||||
util_blitter_save_so_targets(ilo->blitter,
|
||||
ilo->stream_output_targets.num_targets,
|
||||
ilo->stream_output_targets.targets);
|
||||
|
||||
util_blitter_save_fragment_shader(ilo->blitter, ilo->fs);
|
||||
util_blitter_save_depth_stencil_alpha(ilo->blitter,
|
||||
ilo->depth_stencil_alpha);
|
||||
util_blitter_save_blend(ilo->blitter, ilo->blend);
|
||||
|
||||
/* undocumented? */
|
||||
util_blitter_save_viewport(ilo->blitter, &ilo->viewport);
|
||||
util_blitter_save_stencil_ref(ilo->blitter, &ilo->stencil_ref);
|
||||
util_blitter_save_sample_mask(ilo->blitter, ilo->sample_mask);
|
||||
|
||||
switch (op) {
|
||||
case ILO_BLITTER_CLEAR:
|
||||
util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer);
|
||||
break;
|
||||
case ILO_BLITTER_CLEAR_SURFACE:
|
||||
util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer);
|
||||
break;
|
||||
case ILO_BLITTER_BLIT:
|
||||
util_blitter_save_rasterizer(ilo->blitter, ilo->rasterizer);
|
||||
util_blitter_save_framebuffer(ilo->blitter, &ilo->framebuffer);
|
||||
|
||||
util_blitter_save_fragment_sampler_states(ilo->blitter,
|
||||
ilo->samplers[PIPE_SHADER_FRAGMENT].num_samplers,
|
||||
(void **) ilo->samplers[PIPE_SHADER_FRAGMENT].samplers);
|
||||
|
||||
util_blitter_save_fragment_sampler_views(ilo->blitter,
|
||||
ilo->sampler_views[PIPE_SHADER_FRAGMENT].num_views,
|
||||
ilo->sampler_views[PIPE_SHADER_FRAGMENT].views);
|
||||
|
||||
/* disable render condition? */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_blitter_end(struct ilo_context *ilo)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_clear(struct pipe_context *pipe,
|
||||
unsigned buffers,
|
||||
const union pipe_color_union *color,
|
||||
double depth,
|
||||
unsigned stencil)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
|
||||
/* TODO we should pause/resume some queries */
|
||||
ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR);
|
||||
|
||||
util_blitter_clear(ilo->blitter,
|
||||
ilo->framebuffer.width, ilo->framebuffer.height,
|
||||
ilo->framebuffer.nr_cbufs, buffers,
|
||||
(ilo->framebuffer.nr_cbufs) ? ilo->framebuffer.cbufs[0]->format :
|
||||
PIPE_FORMAT_NONE,
|
||||
color, depth, stencil);
|
||||
|
||||
ilo_blitter_end(ilo);
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_clear_render_target(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
const union pipe_color_union *color,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
union util_color packed;
|
||||
|
||||
if (!width || !height || dstx >= dst->width || dsty >= dst->height)
|
||||
return;
|
||||
|
||||
if (dstx + width > dst->width)
|
||||
width = dst->width - dstx;
|
||||
if (dsty + height > dst->height)
|
||||
height = dst->height - dsty;
|
||||
|
||||
util_pack_color(color->f, dst->format, &packed);
|
||||
|
||||
/* try HW blit first */
|
||||
if (blitter_xy_color_blt(pipe, dst->texture,
|
||||
dstx, dsty,
|
||||
dstx + width, dsty + height,
|
||||
packed.ui))
|
||||
return;
|
||||
|
||||
ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE);
|
||||
util_blitter_clear_render_target(ilo->blitter,
|
||||
dst, color, dstx, dsty, width, height);
|
||||
ilo_blitter_end(ilo);
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_clear_depth_stencil(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
unsigned clear_flags,
|
||||
double depth,
|
||||
unsigned stencil,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
|
||||
/*
|
||||
* The PRM claims that HW blit supports Y-tiling since GEN6, but it does
|
||||
* not tell us how to program it. Since depth buffers are always Y-tiled,
|
||||
* HW blit will not work.
|
||||
*/
|
||||
ilo_blitter_begin(ilo, ILO_BLITTER_CLEAR_SURFACE);
|
||||
util_blitter_clear_depth_stencil(ilo->blitter,
|
||||
dst, clear_flags, depth, stencil, dstx, dsty, width, height);
|
||||
ilo_blitter_end(ilo);
|
||||
}
|
||||
|
||||
static void
|
||||
ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct pipe_blit_info skip_stencil;
|
||||
|
||||
if (util_try_blit_via_copy_region(pipe, info))
|
||||
return;
|
||||
|
||||
if (!util_blitter_is_blit_supported(ilo->blitter, info)) {
|
||||
/* try without stencil */
|
||||
if (info->mask & PIPE_MASK_S) {
|
||||
skip_stencil = *info;
|
||||
skip_stencil.mask = info->mask & ~PIPE_MASK_S;
|
||||
|
||||
if (util_blitter_is_blit_supported(ilo->blitter, &skip_stencil))
|
||||
info = &skip_stencil;
|
||||
}
|
||||
|
||||
if (info == &skip_stencil) {
|
||||
ilo_warn("ignore stencil buffer blitting\n");
|
||||
}
|
||||
else {
|
||||
ilo_warn("failed to blit with the generic blitter\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ilo_blitter_begin(ilo, ILO_BLITTER_BLIT);
|
||||
util_blitter_blit(ilo->blitter, info);
|
||||
ilo_blitter_end(ilo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize blit-related functions.
|
||||
*/
|
||||
void
|
||||
ilo_init_blit_functions(struct ilo_context *ilo)
|
||||
{
|
||||
ilo->base.resource_copy_region = NULL;
|
||||
ilo->base.blit = NULL;
|
||||
ilo->base.resource_copy_region = util_resource_copy_region;
|
||||
ilo->base.blit = ilo_blit;
|
||||
|
||||
ilo->base.clear = NULL;
|
||||
ilo->base.clear_render_target = NULL;
|
||||
ilo->base.clear_depth_stencil = NULL;
|
||||
ilo->base.clear = ilo_clear;
|
||||
ilo->base.clear_render_target = ilo_clear_render_target;
|
||||
ilo->base.clear_depth_stencil = ilo_clear_depth_stencil;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include "util/u_blitter.h"
|
||||
#include "intel_chipset.h"
|
||||
|
||||
#include "ilo_3d.h"
|
||||
|
|
@ -100,6 +101,8 @@ ilo_context_destroy(struct pipe_context *pipe)
|
|||
if (ilo->last_cp_bo)
|
||||
ilo->last_cp_bo->unreference(ilo->last_cp_bo);
|
||||
|
||||
if (ilo->blitter)
|
||||
util_blitter_destroy(ilo->blitter);
|
||||
if (ilo->shader_cache)
|
||||
ilo_shader_cache_destroy(ilo->shader_cache);
|
||||
if (ilo->cp)
|
||||
|
|
@ -203,6 +206,13 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
|
|||
ilo_init_video_functions(ilo);
|
||||
ilo_init_gpgpu_functions(ilo);
|
||||
|
||||
/* this must be called last as u_blitter is a client of the pipe context */
|
||||
ilo->blitter = util_blitter_create(&ilo->base);
|
||||
if (!ilo->blitter) {
|
||||
ilo_context_destroy(&ilo->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &ilo->base;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#define ILO_WM_CONST_SURFACE(i) (ILO_MAX_DRAW_BUFFERS + i)
|
||||
#define ILO_WM_TEXTURE_SURFACE(i) (ILO_MAX_DRAW_BUFFERS + ILO_MAX_CONST_BUFFERS + i)
|
||||
|
||||
struct blitter_context;
|
||||
struct intel_winsys;
|
||||
struct intel_bo;
|
||||
struct ilo_cp;
|
||||
|
|
@ -86,6 +87,7 @@ struct ilo_context {
|
|||
struct intel_bo *last_cp_bo;
|
||||
|
||||
struct ilo_shader_cache *shader_cache;
|
||||
struct blitter_context *blitter;
|
||||
|
||||
uint32_t dirty;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue