*/
#include "genhw/genhw.h"
+#include "core/ilo_builder_mi.h"
+#include "core/ilo_builder_blt.h"
#include "util/u_pack_color.h"
-#include "ilo_3d.h"
#include "ilo_context.h"
#include "ilo_cp.h"
#include "ilo_blit.h"
#include "ilo_resource.h"
#include "ilo_blitter.h"
-#ifndef COLOR_BLT_CMD
-#define COLOR_BLT_CMD (CMD_2D | (0x40 << 22))
-#endif
-
-#ifndef SRC_COPY_BLT_CMD
-#define SRC_COPY_BLT_CMD (CMD_2D | (0x43 << 22))
-#endif
-
-enum gen6_blt_mask {
- GEN6_BLT_MASK_8,
- GEN6_BLT_MASK_16,
- GEN6_BLT_MASK_32,
- GEN6_BLT_MASK_32_LO,
- GEN6_BLT_MASK_32_HI,
-};
-
-/*
- * From the Sandy Bridge PRM, volume 1 part 5, page 7:
- *
- * "The BLT engine is capable of transferring very large quantities of
- * graphics data. Any graphics data read from and written to the
- * destination is permitted to represent a number of pixels that occupies
- * up to 65,536 scan lines and up to 32,768 bytes per scan line at the
- * destination. The maximum number of pixels that may be represented per
- * scan line's worth of graphics data depends on the color depth."
- */
-static const int gen6_max_bytes_per_scanline = 32768;
-static const int gen6_max_scanlines = 65536;
-
-static void
-gen6_emit_MI_FLUSH_DW(struct ilo_dev_info *dev, struct ilo_cp *cp)
-{
- const uint8_t cmd_len = 4;
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, MI_FLUSH_DW | (cmd_len - 2));
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_MI_LOAD_REGISTER_IMM(struct ilo_dev_info *dev,
- uint32_t reg, uint32_t val,
- struct ilo_cp *cp)
-{
- const uint8_t cmd_len = 3;
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, MI_LOAD_REGISTER_IMM | (cmd_len - 2));
- ilo_cp_write(cp, reg);
- ilo_cp_write(cp, val);
- ilo_cp_end(cp);
-}
-
-static uint32_t
-gen6_translate_blt_value_mask(enum gen6_blt_mask value_mask)
-{
- switch (value_mask) {
- case GEN6_BLT_MASK_8: return GEN6_BLITTER_BR13_FORMAT_8;
- case GEN6_BLT_MASK_16: return GEN6_BLITTER_BR13_FORMAT_565;
- default: return GEN6_BLITTER_BR13_FORMAT_8888;
- }
-}
-
-static uint32_t
-gen6_translate_blt_write_mask(enum gen6_blt_mask write_mask)
-{
- switch (write_mask) {
- case GEN6_BLT_MASK_32: return GEN6_BLITTER_BR00_WRITE_RGB |
- GEN6_BLITTER_BR00_WRITE_A;
- case GEN6_BLT_MASK_32_LO: return GEN6_BLITTER_BR00_WRITE_RGB;
- case GEN6_BLT_MASK_32_HI: return GEN6_BLITTER_BR00_WRITE_A;
- default: return 0;
- }
-}
-
-static uint32_t
-gen6_translate_blt_cpp(enum gen6_blt_mask mask)
-{
- switch (mask) {
- case GEN6_BLT_MASK_8: return 1;
- case GEN6_BLT_MASK_16: return 2;
- default: return 4;
- }
-}
-
-static void
-gen6_emit_COLOR_BLT(struct ilo_dev_info *dev,
- struct intel_bo *dst_bo,
- int16_t dst_pitch, uint32_t dst_offset,
- uint16_t width, uint16_t height,
- uint32_t pattern, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask,
- struct ilo_cp *cp)
-{
- const uint8_t cmd_len = 5;
- const int cpp = gen6_translate_blt_cpp(value_mask);
- uint32_t dw0, dw1;
-
- dw0 = COLOR_BLT_CMD |
- gen6_translate_blt_write_mask(write_mask) |
- (cmd_len - 2);
-
- assert(width < gen6_max_bytes_per_scanline);
- assert(height < gen6_max_scanlines);
- /* offsets are naturally aligned and pitches are dword-aligned */
- assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
-
- dw1 = rop << 16 |
- gen6_translate_blt_value_mask(value_mask) |
- dst_pitch;
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, dw0);
- ilo_cp_write(cp, dw1);
- ilo_cp_write(cp, height << 16 | width);
- ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
- INTEL_DOMAIN_RENDER);
- ilo_cp_write(cp, pattern);
- ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_XY_COLOR_BLT(struct ilo_dev_info *dev,
- struct intel_bo *dst_bo,
- enum intel_tiling_mode dst_tiling,
- int16_t dst_pitch, uint32_t dst_offset,
- int16_t x1, int16_t y1, int16_t x2, int16_t y2,
- uint32_t pattern, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask,
- struct ilo_cp *cp)
-{
- const uint8_t cmd_len = 6;
- const int cpp = gen6_translate_blt_cpp(value_mask);
- int dst_align, dst_pitch_shift;
- uint32_t dw0, dw1;
-
- dw0 = XY_COLOR_BLT_CMD |
- gen6_translate_blt_write_mask(write_mask) |
- (cmd_len - 2);
-
- if (dst_tiling == INTEL_TILING_NONE) {
- dst_align = 4;
- dst_pitch_shift = 0;
- }
- else {
- dw0 |= GEN6_BLITTER_BR00_DST_TILED;
-
- dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
- /* in dwords when tiled */
- dst_pitch_shift = 2;
- }
-
- assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
- assert(y2 - y1 < gen6_max_scanlines);
- assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
-
- dw1 = rop << 16 |
- gen6_translate_blt_value_mask(value_mask) |
- dst_pitch >> dst_pitch_shift;
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, dw0);
- ilo_cp_write(cp, dw1);
- ilo_cp_write(cp, y1 << 16 | x1);
- ilo_cp_write(cp, y2 << 16 | x2);
- ilo_cp_write_bo(cp, dst_offset, dst_bo,
- INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
- ilo_cp_write(cp, pattern);
- ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_SRC_COPY_BLT(struct ilo_dev_info *dev,
- struct intel_bo *dst_bo,
- int16_t dst_pitch, uint32_t dst_offset,
- uint16_t width, uint16_t height,
- struct intel_bo *src_bo,
- int16_t src_pitch, uint32_t src_offset,
- bool dir_rtl, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask,
- struct ilo_cp *cp)
-{
- const uint8_t cmd_len = 6;
- const int cpp = gen6_translate_blt_cpp(value_mask);
- uint32_t dw0, dw1;
-
- dw0 = SRC_COPY_BLT_CMD |
- gen6_translate_blt_write_mask(write_mask) |
- (cmd_len - 2);
-
- assert(width < gen6_max_bytes_per_scanline);
- assert(height < gen6_max_scanlines);
- /* offsets are naturally aligned and pitches are dword-aligned */
- assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
- assert(src_offset % cpp == 0 && src_pitch % 4 == 0);
-
- dw1 = rop << 16 |
- gen6_translate_blt_value_mask(value_mask) |
- dst_pitch;
-
- if (dir_rtl)
- dw1 |= 1 << 30;
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, dw0);
- ilo_cp_write(cp, dw1);
- ilo_cp_write(cp, height << 16 | width);
- ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
- INTEL_DOMAIN_RENDER);
- ilo_cp_write(cp, src_pitch);
- ilo_cp_write_bo(cp, src_offset, src_bo, INTEL_DOMAIN_RENDER, 0);
- ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_XY_SRC_COPY_BLT(struct ilo_dev_info *dev,
- struct intel_bo *dst_bo,
- enum intel_tiling_mode dst_tiling,
- int16_t dst_pitch, uint32_t dst_offset,
- int16_t x1, int16_t y1, int16_t x2, int16_t y2,
- struct intel_bo *src_bo,
- enum intel_tiling_mode src_tiling,
- int16_t src_pitch, uint32_t src_offset,
- int16_t src_x, int16_t src_y, uint8_t rop,
- enum gen6_blt_mask value_mask,
- enum gen6_blt_mask write_mask,
- struct ilo_cp *cp)
-{
- const uint8_t cmd_len = 8;
- const int cpp = gen6_translate_blt_cpp(value_mask);
- int dst_align, dst_pitch_shift;
- int src_align, src_pitch_shift;
- uint32_t dw0, dw1;
-
- dw0 = XY_SRC_COPY_BLT_CMD |
- gen6_translate_blt_write_mask(write_mask) |
- (cmd_len - 2);
-
- if (dst_tiling == INTEL_TILING_NONE) {
- dst_align = 4;
- dst_pitch_shift = 0;
- }
- else {
- dw0 |= GEN6_BLITTER_BR00_DST_TILED;
-
- dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
- /* in dwords when tiled */
- dst_pitch_shift = 2;
- }
-
- if (src_tiling == INTEL_TILING_NONE) {
- src_align = 4;
- src_pitch_shift = 0;
- }
- else {
- dw0 |= GEN6_BLITTER_BR00_SRC_TILED;
-
- src_align = (src_tiling == INTEL_TILING_Y) ? 128 : 512;
- /* in dwords when tiled */
- src_pitch_shift = 2;
- }
-
- assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
- assert(y2 - y1 < gen6_max_scanlines);
- assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
- assert(src_offset % src_align == 0 && src_pitch % src_align == 0);
-
- dw1 = rop << 16 |
- gen6_translate_blt_value_mask(value_mask) |
- dst_pitch >> dst_pitch_shift;
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, dw0);
- ilo_cp_write(cp, dw1);
- ilo_cp_write(cp, y1 << 16 | x1);
- ilo_cp_write(cp, y2 << 16 | x2);
- ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
- INTEL_DOMAIN_RENDER);
- ilo_cp_write(cp, src_y << 16 | src_x);
- ilo_cp_write(cp, src_pitch >> src_pitch_shift);
- ilo_cp_write_bo(cp, src_offset, src_bo, INTEL_DOMAIN_RENDER, 0);
- ilo_cp_end(cp);
-}
-
static uint32_t
ilo_blitter_blt_begin(struct ilo_blitter *blitter, int max_cmd_size,
- struct intel_bo *dst, enum intel_tiling_mode dst_tiling,
- struct intel_bo *src, enum intel_tiling_mode src_tiling)
+ struct intel_bo *dst,
+ enum gen_surface_tiling dst_tiling,
+ struct intel_bo *src,
+ enum gen_surface_tiling src_tiling)
{
- struct ilo_context *ilo = blitter->ilo;
- struct intel_bo *aper_check[3];
+ struct ilo_cp *cp = blitter->ilo->cp;
+ struct intel_bo *aper_check[2];
int count;
uint32_t swctrl;
- /* change ring */
- ilo_cp_set_ring(ilo->cp, INTEL_RING_BLT);
- ilo_cp_set_owner(ilo->cp, NULL, 0);
+ /* change owner */
+ ilo_cp_set_owner(cp, INTEL_RING_BLT, NULL);
/* check aperture space */
- aper_check[0] = ilo->cp->bo;
- aper_check[1] = dst;
- count = 2;
+ aper_check[0] = dst;
+ count = 1;
if (src) {
- aper_check[2] = src;
+ aper_check[1] = src;
count++;
}
- if (!intel_winsys_can_submit_bo(ilo->winsys, aper_check, count))
- ilo_cp_flush(ilo->cp, "out of aperture");
+ if (!ilo_builder_validate(&cp->builder, count, aper_check))
+ ilo_cp_submit(cp, "out of aperture");
- /* set GEN6_REG_BCS_SWCTRL */
+ /* set BCS_SWCTRL */
swctrl = 0x0;
- if (dst_tiling == INTEL_TILING_Y) {
+ assert(dst_tiling == GEN6_TILING_NONE ||
+ dst_tiling == GEN6_TILING_X ||
+ dst_tiling == GEN6_TILING_Y);
+ assert(src_tiling == GEN6_TILING_NONE ||
+ src_tiling == GEN6_TILING_X ||
+ src_tiling == GEN6_TILING_Y);
+
+ if (dst_tiling == GEN6_TILING_Y) {
swctrl |= GEN6_REG_BCS_SWCTRL_DST_TILING_Y << 16 |
GEN6_REG_BCS_SWCTRL_DST_TILING_Y;
}
- if (src && src_tiling == INTEL_TILING_Y) {
+ if (src && src_tiling == GEN6_TILING_Y) {
swctrl |= GEN6_REG_BCS_SWCTRL_SRC_TILING_Y << 16 |
GEN6_REG_BCS_SWCTRL_SRC_TILING_Y;
}
- if (swctrl) {
- /*
- * Most clients expect BLT engine to be stateless. If we have to set
- * GEN6_REG_BCS_SWCTRL to a non-default value, we have to set it back in the same
- * batch buffer.
- */
- if (ilo_cp_space(ilo->cp) < (4 + 3) * 2 + max_cmd_size)
- ilo_cp_flush(ilo->cp, "out of space");
-
- ilo_cp_assert_no_implicit_flush(ilo->cp, true);
+ /*
+ * Most clients expect BLT engine to be stateless. If we have to set
+ * BCS_SWCTRL to a non-default value, we have to set it back in the same
+ * batch buffer.
+ */
+ if (swctrl)
+ max_cmd_size += (4 + 3) * 2;
+
+ if (ilo_cp_space(cp) < max_cmd_size) {
+ ilo_cp_submit(cp, "out of space");
+ assert(ilo_cp_space(cp) >= max_cmd_size);
+ }
+ if (swctrl) {
/*
* From the Ivy Bridge PRM, volume 1 part 4, page 133:
*
* "SW is required to flush the HW before changing the polarity of
* this bit (Tile Y Destination/Source)."
*/
- gen6_emit_MI_FLUSH_DW(ilo->dev, ilo->cp);
- gen6_emit_MI_LOAD_REGISTER_IMM(ilo->dev, GEN6_REG_BCS_SWCTRL, swctrl, ilo->cp);
+ gen6_MI_FLUSH_DW(&cp->builder);
+ gen6_MI_LOAD_REGISTER_IMM(&cp->builder, GEN6_REG_BCS_SWCTRL, swctrl);
- swctrl &= ~(GEN6_REG_BCS_SWCTRL_DST_TILING_Y | GEN6_REG_BCS_SWCTRL_SRC_TILING_Y);
+ swctrl &= ~(GEN6_REG_BCS_SWCTRL_DST_TILING_Y |
+ GEN6_REG_BCS_SWCTRL_SRC_TILING_Y);
}
return swctrl;
static void
ilo_blitter_blt_end(struct ilo_blitter *blitter, uint32_t swctrl)
{
- struct ilo_context *ilo = blitter->ilo;
+ struct ilo_builder *builder = &blitter->ilo->cp->builder;
- /* set GEN6_REG_BCS_SWCTRL back */
+ /* set BCS_SWCTRL back */
if (swctrl) {
- gen6_emit_MI_FLUSH_DW(ilo->dev, ilo->cp);
- gen6_emit_MI_LOAD_REGISTER_IMM(ilo->dev, GEN6_REG_BCS_SWCTRL, swctrl, ilo->cp);
-
- ilo_cp_assert_no_implicit_flush(ilo->cp, false);
+ gen6_MI_FLUSH_DW(builder);
+ gen6_MI_LOAD_REGISTER_IMM(builder, GEN6_REG_BCS_SWCTRL, swctrl);
}
}
static bool
buf_clear_region(struct ilo_blitter *blitter,
- struct ilo_buffer *dst,
- unsigned dst_offset, unsigned dst_size,
- uint32_t val,
+ struct ilo_buffer_resource *buf, unsigned offset,
+ uint32_t val, unsigned size,
enum gen6_blt_mask value_mask,
enum gen6_blt_mask write_mask)
{
const uint8_t rop = 0xf0; /* PATCOPY */
- const int cpp = gen6_translate_blt_cpp(value_mask);
- struct ilo_context *ilo = blitter->ilo;
- unsigned offset = 0;
+ const int cpp = gen6_blt_translate_value_cpp(value_mask);
+ struct ilo_builder *builder = &blitter->ilo->cp->builder;
+ struct gen6_blt_bo dst;
- if (dst_offset % cpp || dst_size % cpp)
+ if (offset % cpp || size % cpp)
return false;
- ilo_blitter_blt_begin(blitter, 0,
- dst->bo, INTEL_TILING_NONE, NULL, INTEL_TILING_NONE);
+ dst.bo = buf->vma.bo;
+ dst.offset = buf->vma.bo_offset + offset;
+
+ ilo_blitter_blt_begin(blitter, GEN6_COLOR_BLT__SIZE *
+ (1 + size / 32764 / gen6_blt_max_scanlines),
+ dst.bo, GEN6_TILING_NONE, NULL, GEN6_TILING_NONE);
- while (dst_size) {
+ while (size) {
unsigned width, height;
- int16_t pitch;
- width = dst_size;
+ width = size;
height = 1;
- pitch = 0;
- if (width > gen6_max_bytes_per_scanline) {
+ if (width > gen6_blt_max_bytes_per_scanline) {
/* less than INT16_MAX and dword-aligned */
- pitch = 32764;
+ width = 32764;
+ height = size / width;
+ if (height > gen6_blt_max_scanlines)
+ height = gen6_blt_max_scanlines;
- width = pitch;
- height = dst_size / width;
- if (height > gen6_max_scanlines)
- height = gen6_max_scanlines;
+ dst.pitch = width;
+ } else {
+ dst.pitch = 0;
}
- gen6_emit_COLOR_BLT(ilo->dev, dst->bo, pitch, dst_offset + offset,
- width, height, val, rop, value_mask, write_mask, ilo->cp);
+ gen6_COLOR_BLT(builder, &dst, val,
+ width, height, rop, value_mask, write_mask);
- offset += pitch * height;
- dst_size -= width * height;
+ dst.offset += dst.pitch * height;
+ size -= width * height;
}
ilo_blitter_blt_end(blitter, 0);
static bool
buf_copy_region(struct ilo_blitter *blitter,
- struct ilo_buffer *dst, unsigned dst_offset,
- struct ilo_buffer *src, unsigned src_offset,
+ struct ilo_buffer_resource *dst_buf, unsigned dst_offset,
+ struct ilo_buffer_resource *src_buf, unsigned src_offset,
unsigned size)
{
const uint8_t rop = 0xcc; /* SRCCOPY */
- struct ilo_context *ilo = blitter->ilo;
- unsigned offset = 0;
+ struct ilo_builder *builder = &blitter->ilo->cp->builder;
+ struct gen6_blt_bo dst, src;
+
+ dst.bo = dst_buf->vma.bo;
+ dst.offset = dst_buf->vma.bo_offset + dst_offset;
+ dst.pitch = 0;
+
+ src.bo = src_buf->vma.bo;
+ src.offset = src_buf->vma.bo_offset + src_offset;
+ src.pitch = 0;
- ilo_blitter_blt_begin(blitter, 0,
- dst->bo, INTEL_TILING_NONE, src->bo, INTEL_TILING_NONE);
+ ilo_blitter_blt_begin(blitter, GEN6_SRC_COPY_BLT__SIZE *
+ (1 + size / 32764 / gen6_blt_max_scanlines),
+ dst_buf->vma.bo, GEN6_TILING_NONE,
+ src_buf->vma.bo, GEN6_TILING_NONE);
while (size) {
unsigned width, height;
- int16_t pitch;
width = size;
height = 1;
- pitch = 0;
- if (width > gen6_max_bytes_per_scanline) {
+ if (width > gen6_blt_max_bytes_per_scanline) {
/* less than INT16_MAX and dword-aligned */
- pitch = 32764;
-
- width = pitch;
+ width = 32764;
height = size / width;
- if (height > gen6_max_scanlines)
- height = gen6_max_scanlines;
+ if (height > gen6_blt_max_scanlines)
+ height = gen6_blt_max_scanlines;
+
+ dst.pitch = width;
+ src.pitch = width;
+ } else {
+ dst.pitch = 0;
+ src.pitch = 0;
}
- gen6_emit_SRC_COPY_BLT(ilo->dev,
- dst->bo, pitch, dst_offset + offset,
- width, height,
- src->bo, pitch, src_offset + offset,
- false, rop, GEN6_BLT_MASK_8, GEN6_BLT_MASK_8,
- ilo->cp);
+ gen6_SRC_COPY_BLT(builder, &dst, &src,
+ width, height, rop, GEN6_BLT_MASK_8, GEN6_BLT_MASK_8);
- offset += pitch * height;
+ dst.offset += dst.pitch * height;
+ src.offset += src.pitch * height;
size -= width * height;
}
static bool
tex_clear_region(struct ilo_blitter *blitter,
- struct ilo_texture *dst, unsigned dst_level,
+ struct ilo_texture *dst_tex, unsigned dst_level,
const struct pipe_box *dst_box,
uint32_t val,
enum gen6_blt_mask value_mask,
enum gen6_blt_mask write_mask)
{
- const int cpp = gen6_translate_blt_cpp(value_mask);
+ const int cpp = gen6_blt_translate_value_cpp(value_mask);
const unsigned max_extent = 32767; /* INT16_MAX */
const uint8_t rop = 0xf0; /* PATCOPY */
- struct ilo_context *ilo = blitter->ilo;
+ struct ilo_builder *builder = &blitter->ilo->cp->builder;
+ struct gen6_blt_xy_bo dst;
uint32_t swctrl;
int slice;
- /* no W-tiling support */
- if (dst->separate_s8)
+ /* no W-tiling nor separate stencil support */
+ if (dst_tex->image.tiling == GEN8_TILING_W || dst_tex->separate_s8)
+ return false;
+
+ if (dst_tex->image.bo_stride > max_extent)
return false;
- if (dst->bo_stride > max_extent)
+ if (dst_box->width * cpp > gen6_blt_max_bytes_per_scanline)
return false;
- swctrl = ilo_blitter_blt_begin(blitter, dst_box->depth * 6,
- dst->bo, dst->tiling, NULL, INTEL_TILING_NONE);
+ dst.bo = dst_tex->vma.bo;
+ dst.offset = dst_tex->vma.bo_offset;
+ dst.pitch = dst_tex->image.bo_stride;
+ dst.tiling = dst_tex->image.tiling;
+
+ swctrl = ilo_blitter_blt_begin(blitter,
+ GEN6_XY_COLOR_BLT__SIZE * dst_box->depth,
+ dst_tex->vma.bo, dst_tex->image.tiling, NULL, GEN6_TILING_NONE);
for (slice = 0; slice < dst_box->depth; slice++) {
- const struct ilo_texture_slice *dst_slice =
- ilo_texture_get_slice(dst, dst_level, dst_box->z + slice);
- unsigned x1, y1, x2, y2;
+ unsigned x, y;
+
+ ilo_image_get_slice_pos(&dst_tex->image,
+ dst_level, dst_box->z + slice, &x, &y);
- x1 = dst_slice->x + dst_box->x;
- y1 = dst_slice->y + dst_box->y;
- x2 = x1 + dst_box->width;
- y2 = y1 + dst_box->height;
+ dst.x = x + dst_box->x;
+ dst.y = y + dst_box->y;
- if (x2 > max_extent || y2 > max_extent ||
- (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
+ if (dst.x + dst_box->width > max_extent ||
+ dst.y + dst_box->height > max_extent)
break;
- gen6_emit_XY_COLOR_BLT(ilo->dev,
- dst->bo, dst->tiling, dst->bo_stride, 0,
- x1, y1, x2, y2, val, rop, value_mask, write_mask,
- ilo->cp);
+ gen6_XY_COLOR_BLT(builder, &dst, val,
+ dst_box->width, dst_box->height, rop, value_mask, write_mask);
}
ilo_blitter_blt_end(blitter, swctrl);
static bool
tex_copy_region(struct ilo_blitter *blitter,
- struct ilo_texture *dst,
+ struct ilo_texture *dst_tex,
unsigned dst_level,
unsigned dst_x, unsigned dst_y, unsigned dst_z,
- struct ilo_texture *src,
+ struct ilo_texture *src_tex,
unsigned src_level,
const struct pipe_box *src_box)
{
const struct util_format_description *desc =
- util_format_description(dst->bo_format);
+ util_format_description(dst_tex->image_format);
const unsigned max_extent = 32767; /* INT16_MAX */
const uint8_t rop = 0xcc; /* SRCCOPY */
- struct ilo_context *ilo = blitter->ilo;
+ struct ilo_builder *builder = &blitter->ilo->cp->builder;
enum gen6_blt_mask mask;
+ struct gen6_blt_xy_bo dst, src;
uint32_t swctrl;
int cpp, xscale, slice;
- /* no W-tiling support */
- if (dst->separate_s8 || src->separate_s8)
+ /* no W-tiling nor separate stencil support */
+ if (dst_tex->image.tiling == GEN8_TILING_W || dst_tex->separate_s8 ||
+ src_tex->image.tiling == GEN8_TILING_W || src_tex->separate_s8)
return false;
- if (dst->bo_stride > max_extent || src->bo_stride > max_extent)
+ if (dst_tex->image.bo_stride > max_extent ||
+ src_tex->image.bo_stride > max_extent)
return false;
cpp = desc->block.bits / 8;
xscale = (desc->block.bits / 8) / cpp;
}
+ if (src_box->width * cpp * xscale > gen6_blt_max_bytes_per_scanline)
+ return false;
+
switch (cpp) {
case 1:
mask = GEN6_BLT_MASK_8;
break;
}
- swctrl = ilo_blitter_blt_begin(blitter, src_box->depth * 8,
- dst->bo, dst->tiling, src->bo, src->tiling);
+ dst.bo = dst_tex->vma.bo;
+ dst.offset = dst_tex->vma.bo_offset;
+ dst.pitch = dst_tex->image.bo_stride;
+ dst.tiling = dst_tex->image.tiling;
+
+ src.bo = src_tex->vma.bo;
+ src.offset = src_tex->vma.bo_offset;
+ src.pitch = src_tex->image.bo_stride;
+ src.tiling = src_tex->image.tiling;
+
+ swctrl = ilo_blitter_blt_begin(blitter,
+ GEN6_XY_SRC_COPY_BLT__SIZE * src_box->depth,
+ dst.bo, dst.tiling, src.bo, src.tiling);
for (slice = 0; slice < src_box->depth; slice++) {
- const struct ilo_texture_slice *dst_slice =
- ilo_texture_get_slice(dst, dst_level, dst_z + slice);
- const struct ilo_texture_slice *src_slice =
- ilo_texture_get_slice(src, src_level, src_box->z + slice);
- unsigned x1, y1, x2, y2, src_x, src_y;
-
- x1 = (dst_slice->x + dst_x) * xscale;
- y1 = dst_slice->y + dst_y;
- x2 = (x1 + src_box->width) * xscale;
- y2 = y1 + src_box->height;
- src_x = (src_slice->x + src_box->x) * xscale;
- src_y = src_slice->y + src_box->y;
+ unsigned dx, dy, sx, sy, width, height;
+
+ ilo_image_get_slice_pos(&dst_tex->image,
+ dst_level, dst_z + slice, &dx, &dy);
+ ilo_image_get_slice_pos(&src_tex->image,
+ src_level, src_box->z + slice, &sx, &sy);
+
+ dst.x = (dx + dst_x) * xscale;
+ dst.y = dy + dst_y;
+ src.x = (sx + src_box->x) * xscale;
+ src.y = sy + src_box->y;
+ width = src_box->width * xscale;
+ height = src_box->height;
/* in blocks */
- x1 /= desc->block.width;
- y1 /= desc->block.height;
- x2 = (x2 + desc->block.width - 1) / desc->block.width;
- y2 = (y2 + desc->block.height - 1) / desc->block.height;
- src_x /= desc->block.width;
- src_y /= desc->block.height;
-
- if (x2 > max_extent || y2 > max_extent ||
- src_x > max_extent || src_y > max_extent ||
- (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
+ dst.x /= desc->block.width;
+ dst.y /= desc->block.height;
+ src.x /= desc->block.width;
+ src.y /= desc->block.height;
+ width /= desc->block.width;
+ height /= desc->block.height;
+
+ if (src.x + width > max_extent || src.y + height > max_extent ||
+ dst.x + width > max_extent || dst.y + height > max_extent)
break;
- gen6_emit_XY_SRC_COPY_BLT(ilo->dev,
- dst->bo, dst->tiling, dst->bo_stride, 0,
- x1, y1, x2, y2,
- src->bo, src->tiling, src->bo_stride, 0,
- src_x, src_y, rop, mask, mask,
- ilo->cp);
+ gen6_XY_SRC_COPY_BLT(builder, &dst, &src,
+ width, height, rop, mask, mask);
}
ilo_blitter_blt_end(blitter, swctrl);
src_box->height == 1 &&
src_box->depth == 1);
- success = buf_copy_region(blitter,
- ilo_buffer(dst), dst_offset, ilo_buffer(src), src_offset, size);
+ success = buf_copy_region(blitter, ilo_buffer_resource(dst), dst_offset,
+ ilo_buffer_resource(src), src_offset, size);
}
else if (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER) {
success = tex_copy_region(blitter,
union util_color packed;
bool success;
- if (!ilo_3d_pass_render_condition(blitter->ilo))
+ if (ilo_skip_rendering(blitter->ilo))
return true;
switch (cpp) {
if (offset + size > end)
size = end - offset;
- success = buf_clear_region(blitter, ilo_buffer(rt->texture),
- offset, size, packed.ui, mask, mask);
+ success = buf_clear_region(blitter, ilo_buffer_resource(rt->texture),
+ offset, packed.ui[0], size, mask, mask);
}
else {
struct pipe_box box;
rt->u.tex.last_layer - rt->u.tex.first_layer + 1, &box);
success = tex_clear_region(blitter, ilo_texture(rt->texture),
- rt->u.tex.level, &box, packed.ui, mask, mask);
+ rt->u.tex.level, &box, packed.ui[0], mask, mask);
}
return success;
struct pipe_box box;
uint32_t val;
- if (!ilo_3d_pass_render_condition(blitter->ilo))
+ if (ilo_skip_rendering(blitter->ilo))
return true;
switch (zs->format) {