summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorChristian König <[email protected]>2010-10-30 01:42:16 +0200
committerChristian König <[email protected]>2010-10-30 01:42:16 +0200
commit0b75203c5962475a9cbe27e31373750465f9d949 (patch)
treeb53ccf4b086b5b6291be0c940964788cf1b7dd27 /src/gallium/auxiliary
parent41ed47d6b8fb6c032e2907ef2e49e414c26f35c1 (diff)
First try of field based mc
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c209
1 files changed, 190 insertions, 19 deletions
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index 977c8d67b55..0973d5e2fc4 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -198,13 +198,45 @@ create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
return true;
}
-#if 0
-static void
+static bool
create_field_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
- assert(false);
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[5];
+ struct ureg_dst o_vpos, o_vtex[5];
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
+
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 5; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 5; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
+
+ /*
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ * o_vtex[3] = vpos + vtex[3] // Apply motion vector
+ * o_vtex[4] = vpos + vtex[4] // Apply motion vector
+ */
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
+ ureg_ADD(shader, o_vtex[3], vpos, vtex[3]);
+ ureg_ADD(shader, o_vtex[4], vpos, vtex[4]);
+
+ ureg_END(shader);
+
+ r->p_vs[1] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->p_vs[1])
+ return false;
+
+ return true;
}
-#endif
static bool
create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
@@ -254,13 +286,67 @@ create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
return true;
}
-#if 0
-static void
+static bool
create_field_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
- assert(false);
+ struct ureg_program *shader;
+ struct ureg_src tc[5];
+ struct ureg_src sampler[4];
+ struct ureg_dst texel, ref, tmp;
+ struct ureg_dst fragment;
+ unsigned i, label;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ for (i = 0; i < 5; ++i)
+ tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, i + 1, TGSI_INTERPOLATE_LINEAR);
+ for (i = 0; i < 4; ++i)
+ sampler[i] = ureg_DECL_sampler(shader, i);
+
+ texel = ureg_DECL_temporary(shader);
+ ref = ureg_DECL_temporary(shader);
+ tmp = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel.r = tex(tc[0], sampler[0])
+ * texel.g = tex(tc[1], sampler[1])
+ * texel.b = tex(tc[2], sampler[2])
+ * ref = tex(tc[3], sampler[3])
+ * fragment = texel * scale + ref
+ */
+ for (i = 0; i < 3; ++i) {
+ /* Nouveau can't writemask tex dst regs (yet?), do in two steps */
+ ureg_TEX(shader, ref, TGSI_TEXTURE_2D, tc[i], sampler[i]);
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_X));
+ }
+
+ /*
+ ureg_MOD(shader, tmp, ureg_scalar(tc[4], TGSI_SWIZZLE_Y), ureg_scalar(ureg_imm1f(shader, 2), TGSI_SWIZZLE_Y));
+ ureg_IF(shader, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), &label);
+ ureg_TEX(shader, ref, TGSI_TEXTURE_2D, tc[3], sampler[3]);
+ ureg_ELSE(shader, &label);
+ ureg_MOV(shader, ref, ureg_scalar(ureg_imm1f(shader, 0xFF), TGSI_SWIZZLE_X));
+ ureg_TEX(shader, ref, TGSI_TEXTURE_2D, tc[4], sampler[3]);
+ ureg_ENDIF(shader);
+ */
+
+ ureg_TEX(shader, ref, TGSI_TEXTURE_2D, tc[4], sampler[3]);
+ ureg_MAD(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X), ureg_src(ref));
+
+ ureg_release_temporary(shader, tmp);
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, ref);
+ ureg_END(shader);
+
+ r->p_fs[1] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->p_fs[1])
+ return false;
+
+ return true;
}
-#endif
static bool
create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
@@ -304,13 +390,44 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
return true;
}
-#if 0
-static void
+static bool
create_field_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
- assert(false);
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[7];
+ struct ureg_dst o_vpos, o_vtex[7];
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
+
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 7; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 7; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
+
+ /*
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ * o_vtex[3..6] = vpos + vtex[3..6] // Apply motion vector
+ */
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
+ for (i = 3; i < 7; ++i)
+ ureg_ADD(shader, o_vtex[i], vpos, vtex[i]);
+
+ ureg_END(shader);
+
+ r->b_vs[1] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->b_vs[1])
+ return false;
+
+ return true;
}
-#endif
static bool
create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
@@ -366,13 +483,59 @@ create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
return true;
}
-#if 0
-static void
+static bool
create_field_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
- assert(false);
+ struct ureg_program *shader;
+ struct ureg_src tc[5];
+ struct ureg_src sampler[5];
+ struct ureg_dst texel, ref[2];
+ struct ureg_dst fragment;
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ for (i = 0; i < 5; ++i) {
+ tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, i + 1, TGSI_INTERPOLATE_LINEAR);
+ sampler[i] = ureg_DECL_sampler(shader, i);
+ }
+ texel = ureg_DECL_temporary(shader);
+ ref[0] = ureg_DECL_temporary(shader);
+ ref[1] = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel.r = tex(tc[0], sampler[0])
+ * texel.g = tex(tc[1], sampler[1])
+ * texel.b = tex(tc[2], sampler[2])
+ * ref[0..1 = tex(tc[3..4], sampler[3..4])
+ * ref[0] = lerp(ref[0], ref[1], 0.5)
+ * fragment = texel * scale + ref[0]
+ */
+ for (i = 0; i < 3; ++i) {
+ /* Nouveau can't writemask tex dst regs (yet?), do in two steps */
+ ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, tc[i], sampler[i]);
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), ureg_scalar(ureg_src(ref[0]), TGSI_SWIZZLE_X));
+ }
+ ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, tc[3], sampler[3]);
+ ureg_TEX(shader, ref[1], TGSI_TEXTURE_2D, tc[4], sampler[4]);
+ ureg_LRP(shader, ref[0], ureg_scalar(ureg_imm1f(shader, 0.5f), TGSI_SWIZZLE_X), ureg_src(ref[0]), ureg_src(ref[1]));
+
+ ureg_MAD(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X), ureg_src(ref[0]));
+
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, ref[0]);
+ ureg_release_temporary(shader, ref[1]);
+ ureg_END(shader);
+
+ r->b_fs[1] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->b_fs[1])
+ return false;
+
+ return true;
}
-#endif
static void
xfer_buffers_map(struct vl_mpeg12_mc_renderer *r)
@@ -500,9 +663,13 @@ init_shaders(struct vl_mpeg12_mc_renderer *r)
create_intra_vert_shader(r);
create_intra_frag_shader(r);
create_frame_pred_vert_shader(r);
+ create_field_pred_vert_shader(r);
create_frame_pred_frag_shader(r);
+ create_field_pred_frag_shader(r);
create_frame_bi_pred_vert_shader(r);
+ create_field_bi_pred_vert_shader(r);
create_frame_bi_pred_frag_shader(r);
+ create_field_bi_pred_frag_shader(r);
return true;
}
@@ -515,9 +682,13 @@ cleanup_shaders(struct vl_mpeg12_mc_renderer *r)
r->pipe->delete_vs_state(r->pipe, r->i_vs);
r->pipe->delete_fs_state(r->pipe, r->i_fs);
r->pipe->delete_vs_state(r->pipe, r->p_vs[0]);
+ r->pipe->delete_vs_state(r->pipe, r->p_vs[1]);
r->pipe->delete_fs_state(r->pipe, r->p_fs[0]);
+ r->pipe->delete_fs_state(r->pipe, r->p_fs[1]);
r->pipe->delete_vs_state(r->pipe, r->b_vs[0]);
+ r->pipe->delete_vs_state(r->pipe, r->b_vs[1]);
r->pipe->delete_fs_state(r->pipe, r->b_fs[0]);
+ r->pipe->delete_fs_state(r->pipe, r->b_fs[1]);
}
static bool
@@ -1099,7 +1270,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24;
}
- if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) {
+ if (num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
r->textures.individual.ref[0] = r->past->texture;
@@ -1129,7 +1300,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24;
}
- if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0*/ ) {
+ if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
r->textures.individual.ref[0] = r->future->texture;
@@ -1161,7 +1332,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24;
}
- if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) {
+ if (num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
r->textures.individual.ref[0] = r->past->texture;