i965: Make intelEmitCopyBlit static

And rename to emit_copy_blit.

v2: sed --in-place -e 's/color_logic_ops/gl_logicop_mode/g' $(grep -lr
color_logic_ops src/) suggested by Brian.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> [v1]
This commit is contained in:
Ian Romanick 2018-01-03 12:40:00 -08:00
parent 4e9e964de6
commit 9eed6bea6b
2 changed files with 199 additions and 215 deletions

View File

@ -202,6 +202,183 @@ get_blit_intratile_offset_el(const struct brw_context *brw,
}
}
static bool
alignment_valid(struct brw_context *brw, unsigned offset,
enum isl_tiling tiling)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
/* Tiled buffers must be page-aligned (4K). */
if (tiling != ISL_TILING_LINEAR)
return (offset & 4095) == 0;
/* On Gen8+, linear buffers must be cacheline-aligned. */
if (devinfo->gen >= 8)
return (offset & 63) == 0;
return true;
}
static uint32_t
xy_blit_cmd(enum isl_tiling src_tiling, enum isl_tiling dst_tiling,
uint32_t cpp)
{
uint32_t CMD = 0;
assert(cpp <= 4);
switch (cpp) {
case 1:
case 2:
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
unreachable("not reached");
}
if (dst_tiling != ISL_TILING_LINEAR)
CMD |= XY_DST_TILED;
if (src_tiling != ISL_TILING_LINEAR)
CMD |= XY_SRC_TILED;
return CMD;
}
/* Copy BitBlt
*/
static bool
emit_copy_blit(struct brw_context *brw,
GLuint cpp,
int32_t src_pitch,
struct brw_bo *src_buffer,
GLuint src_offset,
enum isl_tiling src_tiling,
int32_t dst_pitch,
struct brw_bo *dst_buffer,
GLuint dst_offset,
enum isl_tiling dst_tiling,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h,
enum gl_logicop_mode logic_op)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
bool dst_y_tiled = dst_tiling == ISL_TILING_Y0;
bool src_y_tiled = src_tiling == ISL_TILING_Y0;
uint32_t src_tile_w, src_tile_h;
uint32_t dst_tile_w, dst_tile_h;
if ((dst_y_tiled || src_y_tiled) && devinfo->gen < 6)
return false;
const unsigned bo_sizes = dst_buffer->size + src_buffer->size;
/* do space check before going any further */
if (!brw_batch_has_aperture_space(brw, bo_sizes))
intel_batchbuffer_flush(brw);
if (!brw_batch_has_aperture_space(brw, bo_sizes))
return false;
unsigned length = devinfo->gen >= 8 ? 10 : 8;
intel_batchbuffer_require_space(brw, length * 4, BLT_RING);
DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__func__,
src_buffer, src_pitch, src_offset, src_x, src_y,
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
intel_get_tile_dims(src_tiling, cpp, &src_tile_w, &src_tile_h);
intel_get_tile_dims(dst_tiling, cpp, &dst_tile_w, &dst_tile_h);
/* For Tiled surfaces, the pitch has to be a multiple of the Tile width
* (X direction width of the Tile). This is ensured while allocating the
* buffer object.
*/
assert(src_tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0);
assert(dst_tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0);
/* For big formats (such as floating point), do the copy using 16 or
* 32bpp and multiply the coordinates.
*/
if (cpp > 4) {
if (cpp % 4 == 2) {
dst_x *= cpp / 2;
dst_x2 *= cpp / 2;
src_x *= cpp / 2;
cpp = 2;
} else {
assert(cpp % 4 == 0);
dst_x *= cpp / 4;
dst_x2 *= cpp / 4;
src_x *= cpp / 4;
cpp = 4;
}
}
if (!alignment_valid(brw, dst_offset, dst_tiling))
return false;
if (!alignment_valid(brw, src_offset, src_tiling))
return false;
/* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop
* the low bits. Offsets must be naturally aligned.
*/
if (src_pitch % 4 != 0 || src_offset % cpp != 0 ||
dst_pitch % 4 != 0 || dst_offset % cpp != 0)
return false;
assert(cpp <= 4);
BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
CMD = xy_blit_cmd(src_tiling, dst_tiling, cpp);
/* For tiled source and destination, pitch value should be specified
* as a number of Dwords.
*/
if (dst_tiling != ISL_TILING_LINEAR)
dst_pitch /= 4;
if (src_tiling != ISL_TILING_LINEAR)
src_pitch /= 4;
if (dst_y2 <= dst_y || dst_x2 <= dst_x)
return true;
assert(dst_x < dst_x2);
assert(dst_y < dst_y2);
BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, src_y_tiled);
OUT_BATCH(CMD | (length - 2));
OUT_BATCH(BR13 | (uint16_t)dst_pitch);
OUT_BATCH(SET_FIELD(dst_y, BLT_Y) | SET_FIELD(dst_x, BLT_X));
OUT_BATCH(SET_FIELD(dst_y2, BLT_Y) | SET_FIELD(dst_x2, BLT_X));
if (devinfo->gen >= 8) {
OUT_RELOC64(dst_buffer, RELOC_WRITE, dst_offset);
} else {
OUT_RELOC(dst_buffer, RELOC_WRITE, dst_offset);
}
OUT_BATCH(SET_FIELD(src_y, BLT_Y) | SET_FIELD(src_x, BLT_X));
OUT_BATCH((uint16_t)src_pitch);
if (devinfo->gen >= 8) {
OUT_RELOC64(src_buffer, 0, src_offset);
} else {
OUT_RELOC(src_buffer, 0, src_offset);
}
ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled);
brw_emit_mi_flush(brw);
return true;
}
static bool
emit_miptree_blit(struct brw_context *brw,
struct intel_mipmap_tree *src_mt,
@ -254,19 +431,19 @@ emit_miptree_blit(struct brw_context *brw,
dst_x + chunk_x, dst_y + chunk_y,
&dst_offset, &dst_tile_x, &dst_tile_y);
if (!intelEmitCopyBlit(brw,
src_mt->cpp,
reverse ? -src_mt->surf.row_pitch :
src_mt->surf.row_pitch,
src_mt->bo, src_mt->offset + src_offset,
src_mt->surf.tiling,
dst_mt->surf.row_pitch,
dst_mt->bo, dst_mt->offset + dst_offset,
dst_mt->surf.tiling,
src_tile_x, src_tile_y,
dst_tile_x, dst_tile_y,
chunk_w, chunk_h,
logicop)) {
if (!emit_copy_blit(brw,
src_mt->cpp,
reverse ? -src_mt->surf.row_pitch :
src_mt->surf.row_pitch,
src_mt->bo, src_mt->offset + src_offset,
src_mt->surf.tiling,
dst_mt->surf.row_pitch,
dst_mt->bo, dst_mt->offset + dst_offset,
dst_mt->surf.tiling,
src_tile_x, src_tile_y,
dst_tile_x, dst_tile_y,
chunk_w, chunk_h,
logicop)) {
/* If this is ever going to fail, it will fail on the first chunk */
assert(chunk_x == 0 && chunk_y == 0);
return false;
@ -448,183 +625,6 @@ intel_miptree_copy(struct brw_context *brw,
src_width, src_height, false, COLOR_LOGICOP_COPY);
}
static bool
alignment_valid(struct brw_context *brw, unsigned offset,
enum isl_tiling tiling)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
/* Tiled buffers must be page-aligned (4K). */
if (tiling != ISL_TILING_LINEAR)
return (offset & 4095) == 0;
/* On Gen8+, linear buffers must be cacheline-aligned. */
if (devinfo->gen >= 8)
return (offset & 63) == 0;
return true;
}
static uint32_t
xy_blit_cmd(enum isl_tiling src_tiling, enum isl_tiling dst_tiling,
uint32_t cpp)
{
uint32_t CMD = 0;
assert(cpp <= 4);
switch (cpp) {
case 1:
case 2:
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
unreachable("not reached");
}
if (dst_tiling != ISL_TILING_LINEAR)
CMD |= XY_DST_TILED;
if (src_tiling != ISL_TILING_LINEAR)
CMD |= XY_SRC_TILED;
return CMD;
}
/* Copy BitBlt
*/
bool
intelEmitCopyBlit(struct brw_context *brw,
GLuint cpp,
int32_t src_pitch,
struct brw_bo *src_buffer,
GLuint src_offset,
enum isl_tiling src_tiling,
int32_t dst_pitch,
struct brw_bo *dst_buffer,
GLuint dst_offset,
enum isl_tiling dst_tiling,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h,
enum gl_logicop_mode logic_op)
{
const struct gen_device_info *devinfo = &brw->screen->devinfo;
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
bool dst_y_tiled = dst_tiling == ISL_TILING_Y0;
bool src_y_tiled = src_tiling == ISL_TILING_Y0;
uint32_t src_tile_w, src_tile_h;
uint32_t dst_tile_w, dst_tile_h;
if ((dst_y_tiled || src_y_tiled) && devinfo->gen < 6)
return false;
const unsigned bo_sizes = dst_buffer->size + src_buffer->size;
/* do space check before going any further */
if (!brw_batch_has_aperture_space(brw, bo_sizes))
intel_batchbuffer_flush(brw);
if (!brw_batch_has_aperture_space(brw, bo_sizes))
return false;
unsigned length = devinfo->gen >= 8 ? 10 : 8;
intel_batchbuffer_require_space(brw, length * 4, BLT_RING);
DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__func__,
src_buffer, src_pitch, src_offset, src_x, src_y,
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
intel_get_tile_dims(src_tiling, cpp, &src_tile_w, &src_tile_h);
intel_get_tile_dims(dst_tiling, cpp, &dst_tile_w, &dst_tile_h);
/* For Tiled surfaces, the pitch has to be a multiple of the Tile width
* (X direction width of the Tile). This is ensured while allocating the
* buffer object.
*/
assert(src_tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0);
assert(dst_tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0);
/* For big formats (such as floating point), do the copy using 16 or
* 32bpp and multiply the coordinates.
*/
if (cpp > 4) {
if (cpp % 4 == 2) {
dst_x *= cpp / 2;
dst_x2 *= cpp / 2;
src_x *= cpp / 2;
cpp = 2;
} else {
assert(cpp % 4 == 0);
dst_x *= cpp / 4;
dst_x2 *= cpp / 4;
src_x *= cpp / 4;
cpp = 4;
}
}
if (!alignment_valid(brw, dst_offset, dst_tiling))
return false;
if (!alignment_valid(brw, src_offset, src_tiling))
return false;
/* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop
* the low bits. Offsets must be naturally aligned.
*/
if (src_pitch % 4 != 0 || src_offset % cpp != 0 ||
dst_pitch % 4 != 0 || dst_offset % cpp != 0)
return false;
assert(cpp <= 4);
BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
CMD = xy_blit_cmd(src_tiling, dst_tiling, cpp);
/* For tiled source and destination, pitch value should be specified
* as a number of Dwords.
*/
if (dst_tiling != ISL_TILING_LINEAR)
dst_pitch /= 4;
if (src_tiling != ISL_TILING_LINEAR)
src_pitch /= 4;
if (dst_y2 <= dst_y || dst_x2 <= dst_x)
return true;
assert(dst_x < dst_x2);
assert(dst_y < dst_y2);
BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, src_y_tiled);
OUT_BATCH(CMD | (length - 2));
OUT_BATCH(BR13 | (uint16_t)dst_pitch);
OUT_BATCH(SET_FIELD(dst_y, BLT_Y) | SET_FIELD(dst_x, BLT_X));
OUT_BATCH(SET_FIELD(dst_y2, BLT_Y) | SET_FIELD(dst_x2, BLT_X));
if (devinfo->gen >= 8) {
OUT_RELOC64(dst_buffer, RELOC_WRITE, dst_offset);
} else {
OUT_RELOC(dst_buffer, RELOC_WRITE, dst_offset);
}
OUT_BATCH(SET_FIELD(src_y, BLT_Y) | SET_FIELD(src_x, BLT_X));
OUT_BATCH((uint16_t)src_pitch);
if (devinfo->gen >= 8) {
OUT_RELOC64(src_buffer, 0, src_offset);
} else {
OUT_RELOC(src_buffer, 0, src_offset);
}
ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled);
brw_emit_mi_flush(brw);
return true;
}
bool
intelEmitImmediateColorExpandBlit(struct brw_context *brw,
GLuint cpp,
@ -737,15 +737,15 @@ intel_emit_linear_blit(struct brw_context *brw,
assert(src_x + pitch < 1 << 15);
assert(dst_x + pitch < 1 << 15);
ok = intelEmitCopyBlit(brw, 1,
pitch, src_bo, src_offset - src_x,
ISL_TILING_LINEAR,
pitch, dst_bo, dst_offset - dst_x,
ISL_TILING_LINEAR,
src_x, 0, /* src x/y */
dst_x, 0, /* dst x/y */
MIN2(size, pitch), height, /* w, h */
COLOR_LOGICOP_COPY);
ok = emit_copy_blit(brw, 1,
pitch, src_bo, src_offset - src_x,
ISL_TILING_LINEAR,
pitch, dst_bo, dst_offset - dst_x,
ISL_TILING_LINEAR,
src_x, 0, /* src x/y */
dst_x, 0, /* dst x/y */
MIN2(size, pitch), height, /* w, h */
COLOR_LOGICOP_COPY);
if (!ok) {
_mesa_problem(ctx, "Failed to linear blit %dx%d\n",
MIN2(size, pitch), height);

View File

@ -28,22 +28,6 @@
#include "brw_context.h"
bool
intelEmitCopyBlit(struct brw_context *brw,
GLuint cpp,
int32_t src_pitch,
struct brw_bo *src_buffer,
GLuint src_offset,
enum isl_tiling src_tiling,
int32_t dst_pitch,
struct brw_bo *dst_buffer,
GLuint dst_offset,
enum isl_tiling dst_tiling,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
GLshort w, GLshort h,
enum gl_logicop_mode logicop);
bool intel_miptree_blit_compatible_formats(mesa_format src, mesa_format dst);
bool intel_miptree_blit(struct brw_context *brw,