ilo: hook up pipe context blit functions

This commit is contained in:
Chia-I Wu 2012-12-13 05:15:10 +08:00 committed by Chia-I Wu
parent 89d1702b9b
commit 0754ff33e3
3 changed files with 269 additions and 5 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;