summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mueller <MarkKMueller@gmail.com>2013-12-16 20:29:38 -0800
committerMark Mueller <MarkKMueller@gmail.com>2014-01-13 09:46:00 -0800
commit36491e0ae972d14e8fb2961b095240a2bd56aae3 (patch)
tree456bb39e84dded34276dd3483d7232b37c56138e
parenta649d6a0f924a65a4671b9774e7d3b561fa64f1d (diff)
Add handler to blorp for basic type conversion. Eliminate blorp
operations on irrelevant color components for performance.
-rw-r--r--src/mesa/drivers/dri/i965/brw_blorp.h9
-rw-r--r--src/mesa/drivers/dri/i965/brw_blorp_blit.cpp168
2 files changed, 164 insertions, 13 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
index 3d0ba1854b..d07aabfcf1 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -300,8 +300,13 @@ struct brw_blorp_blit_prog_key
/* Type of the data to be read from the texture (one of
* BRW_REGISTER_TYPE_{UD,D,F}), and written to the target.
*/
- unsigned src_texture_data_type;
- unsigned dst_texture_data_type;
+ unsigned char src_texture_data_type;
+ unsigned char dst_texture_data_type;
+
+ /* Individual selection of dst component registers for performance
+ * optimization.
+ */
+ unsigned char dst_component_sel;
/* True if the source image is W tiled. If true, the surface state for the
* source image must be configured as Y tiled, and tex_samples must be 0.
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index 0662f2ad9e..9c462d260b 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -421,6 +421,7 @@ brw_blorp_GPUcopytexsubimage(struct brw_context *brw,
if (packing->Alignment > _mesa_get_format_bytes(cacheTexFormat)) {
_mesa_debug(&brw->ctx, "%s: Alignment exceeds pixel size, which is not yet supported.\n", __FUNCTION__);
+ return false;
}
struct intel_mipmap_tree *src_mt =
@@ -1550,15 +1551,137 @@ brw_blorp_blit_program::kill_if_outside_dst_rect()
void
brw_blorp_blit_program::translate_texture_formats()
{
- /* Move the floats to UD registers. */
-// struct brw_reg reg = offset(texture_data[0], 0);
-// brw_MOV(&func, retype(reg, BRW_REGISTER_TYPE_F), reg);
-// reg = offset(texture_data[0], 2);
-// brw_MOV(&func, retype(reg, BRW_REGISTER_TYPE_F), reg);
-// reg = offset(texture_data[0], 4);
-// brw_MOV(&func, retype(reg, BRW_REGISTER_TYPE_F), reg);
-// reg = offset(texture_data[0], 6);
-// brw_MOV(&func, retype(reg, BRW_REGISTER_TYPE_F), reg);
+ const unsigned composite_register_type = (key->dst_texture_data_type << 16) |
+ key->src_texture_data_type;
+
+ switch (composite_register_type) {
+ /* destination source */
+ case (BRW_REGISTER_TYPE_F << 16) | BRW_REGISTER_TYPE_UD:
+ {
+ /* Translate UD samples to float writes. */
+ const struct brw_reg src_reg_base = texture_data[0];
+ texture_data[0] = retype(texture_data[0], BRW_REGISTER_TYPE_F);
+
+ if (1 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 0);
+ const struct brw_reg regf = offset(texture_data[0], 0);
+ brw_MOV(&func, regf, reg);
+ brw_MUL(&func, regf, regf, brw_imm_f(1.0f / 255.0f));
+ }
+
+ if (2 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 2);
+ const struct brw_reg regf = offset(texture_data[0], 2);
+ brw_MOV(&func, regf, reg);
+ brw_MUL(&func, regf, regf, brw_imm_f(1.0f / 255.0f));
+ }
+
+ if (4 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 4);
+ const struct brw_reg regf = offset(texture_data[0], 4);
+ brw_MOV(&func, regf, reg);
+ brw_MUL(&func, regf, regf, brw_imm_f(1.0f / 255.0f));
+ }
+
+ if (8 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 6);
+ const struct brw_reg regf = offset(texture_data[0], 6);
+ brw_MOV(&func, regf, reg);
+ brw_MUL(&func, regf, regf, brw_imm_f(1.0f / 255.0f));
+ }
+ break;
+ }
+ /* destination source */
+ case (BRW_REGISTER_TYPE_F << 16) | BRW_REGISTER_TYPE_D:
+ {
+ /* Translate UD samples to float writes. */
+ const struct brw_reg src_reg_base = texture_data[0];
+ texture_data[0] = retype(texture_data[0], BRW_REGISTER_TYPE_F);
+
+ if (1 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 0);
+ const struct brw_reg regf = offset(texture_data[0], 0);
+ brw_MOV(&func, regf, reg);
+ brw_ADD(&func, regf, regf, brw_imm_f(0.5f));
+ brw_MUL(&func, regf, regf, brw_imm_f(2.0f / 255.0f));
+ }
+
+ if (2 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 2);
+ const struct brw_reg regf = offset(texture_data[0], 2);
+ brw_MOV(&func, regf, reg);
+ brw_ADD(&func, regf, regf, brw_imm_f(0.5f));
+ brw_MUL(&func, regf, regf, brw_imm_f(2.0f / 255.0f));
+ }
+
+ if (4 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 4);
+ const struct brw_reg regf = offset(texture_data[0], 4);
+ brw_MOV(&func, regf, reg);
+ brw_ADD(&func, regf, regf, brw_imm_f(0.5f));
+ brw_MUL(&func, regf, regf, brw_imm_f(2.0f / 255.0f));
+ }
+
+ if (8 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(src_reg_base, 6);
+ const struct brw_reg regf = offset(texture_data[0], 6);
+ brw_MOV(&func, regf, reg);
+ brw_ADD(&func, regf, regf, brw_imm_f(0.5f));
+ brw_MUL(&func, regf, regf, brw_imm_f(2.0f / 255.0f));
+ }
+ break;
+ }
+ /* destination source */
+ case (BRW_REGISTER_TYPE_UD << 16) | BRW_REGISTER_TYPE_F:
+ {
+ /* Translate float samples to UD writes. */
+ if (1 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 0);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0));
+ }
+ if (2 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 2);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0));
+ }
+ if (4 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 4);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0));
+ }
+ if (8 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 6);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0));
+ }
+ break;
+ }
+ /* destination source */
+ case (BRW_REGISTER_TYPE_D << 16) | BRW_REGISTER_TYPE_F:
+ {
+ /* Translate float samples to UD writes. */
+ if (1 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 0);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0f / 2.0f));
+ brw_ADD(&func, reg, reg, brw_imm_f(-0.5f));
+ }
+ if (2 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 2);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0f / 2.0f));
+ brw_ADD(&func, reg, reg, brw_imm_f(-0.5f));
+ }
+ if (4 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 4);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0f / 2.0f));
+ brw_ADD(&func, reg, reg, brw_imm_f(-0.5f));
+ }
+ if (8 & key->dst_component_sel) {
+ const struct brw_reg reg = offset(texture_data[0], 6);
+ brw_MUL(&func, reg, reg, brw_imm_f(255.0f / 2.0f));
+ brw_ADD(&func, reg, reg, brw_imm_f(-0.5f));
+ }
+ break;
+ }
+ default:
+ break;
+ }
}
/**
@@ -2137,8 +2260,10 @@ brw_blorp_blit_program::render_target_write()
/* Copy texture data to MRFs */
for (int i = 0; i < 4; ++i) {
/* E.g. mov(16) m2.0<1>:f r2.0<8;8,1>:f { Align1, H1 } */
- brw_MOV(&func, offset(mrf_rt_write, mrf_offset),
- offset(vec8(texture_data[0]), 2*i));
+ if ((1 << i) & key->dst_component_sel) {
+ brw_MOV(&func, offset(mrf_rt_write, mrf_offset),
+ offset(vec8(texture_data[0]), 2*i));
+ }
mrf_offset += 2;
}
@@ -2704,6 +2829,27 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
src.x_offset *= 2;
src.y_offset /= 2;
}
+
+ if (0 != _mesa_get_format_bits(dst_mt->format, GL_RED_BITS)) {
+ wm_prog_key.dst_component_sel = 1;
+ if (0 != _mesa_get_format_bits(dst_mt->format, GL_GREEN_BITS)) {
+ wm_prog_key.dst_component_sel |= 2;
+ }
+ if (0 != _mesa_get_format_bits(dst_mt->format, GL_BLUE_BITS)) {
+ wm_prog_key.dst_component_sel |= 4;
+ }
+ if (0 != _mesa_get_format_bits(dst_mt->format, GL_ALPHA_BITS)) {
+ wm_prog_key.dst_component_sel |= 8;
+ }
+ } else if (0 != _mesa_get_format_bits(dst_mt->format, GL_TEXTURE_INTENSITY_SIZE)) {
+ wm_prog_key.dst_component_sel = 0x1;
+ } else if (0 != _mesa_get_format_bits(dst_mt->format, GL_TEXTURE_LUMINANCE_SIZE)) {
+ wm_prog_key.dst_component_sel = 0x1;
+ } else if (0 != _mesa_get_format_bits(dst_mt->format, GL_INDEX_BITS)) {
+ wm_prog_key.dst_component_sel = 0x1;
+ } else {
+ wm_prog_key.dst_component_sel = 0x3;
+ }
}
uint32_t