/**************************************************************************
- *
+ *
* Copyright 2009 Younes Manton.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
#include "vl_mpeg12_mc_renderer.h"
+#include "util/u_draw.h"
#include <assert.h>
#include <pipe/p_context.h>
#include <util/u_inlines.h>
#include <util/u_format.h>
#include <util/u_math.h>
#include <util/u_memory.h>
-#include <tgsi/tgsi_parse.h>
-#include <tgsi/tgsi_build.h>
-#include "vl_shader_build.h"
+#include <util/u_keymap.h>
+#include <util/u_sampler.h>
+#include <util/u_draw.h>
+#include <tgsi/tgsi_ureg.h>
#define DEFAULT_BUF_ALIGNMENT 1
#define MACROBLOCK_WIDTH 16
#define BLOCK_HEIGHT 8
#define ZERO_BLOCK_NIL -1.0f
#define ZERO_BLOCK_IS_NIL(zb) ((zb).x < 0.0f)
-
-struct vertex2f
-{
- float x, y;
-};
-
-struct vertex4f
-{
- float x, y, z, w;
-};
+#define SCALE_FACTOR_16_TO_9 (32767.0f / 255.0f)
struct vertex_shader_consts
{
struct vertex4f div;
};
-/*
- * Muliplier renormalizes block samples from 16 bits to 12 bits.
- * Divider is used when calculating Y % 2 for choosing top or bottom
- * field for P or B macroblocks.
- * TODO: Use immediates.
- */
-static const struct fragment_shader_consts fs_consts = {
- {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f},
- {0.5f, 2.0f, 0.0f, 0.0f}
-};
-
struct vert_stream_0
{
struct vertex2f pos;
NUM_MACROBLOCK_TYPES
};
-static void
+static bool
create_intra_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
- const unsigned max_tokens = 50;
-
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned ti;
-
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[3];
+ struct ureg_dst o_vpos, o_vtex[3];
unsigned i;
- assert(r);
-
- tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
- header = (struct tgsi_header *) &tokens[0];
- *header = tgsi_build_header();
- *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 2;
-
- /*
- * decl i0 ; Vertex pos
- * decl i1 ; Luma texcoords
- * decl i2 ; Chroma Cb texcoords
- * decl i3 ; Chroma Cr texcoords
- */
- for (i = 0; i < 4; i++) {
- decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
- /*
- * decl o0 ; Vertex pos
- * decl o1 ; Luma texcoords
- * decl o2 ; Chroma Cb texcoords
- * decl o3 ; Chroma Cr texcoords
- */
- for (i = 0; i < 4; i++) {
- decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 3; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 3; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
/*
- * mov o0, i0 ; Move input vertex pos to output
- * mov o1, i1 ; Move input luma texcoords to output
- * mov o2, i2 ; Move input chroma Cb texcoords to output
- * mov o3, i3 ; Move input chroma Cr texcoords to output
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
*/
- for (i = 0; i < 4; ++i) {
- inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_END(shader);
- assert(ti <= max_tokens);
+ r->i_vs = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->i_vs)
+ return false;
- vs.tokens = tokens;
- r->i_vs = r->pipe->create_vs_state(r->pipe, &vs);
- free(tokens);
+ return true;
}
-static void
+static bool
create_intra_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
- const unsigned max_tokens = 100;
-
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned ti;
-
+ struct ureg_program *shader;
+ struct ureg_src tc[3];
+ struct ureg_src sampler[3];
+ struct ureg_dst texel, temp;
+ struct ureg_dst fragment;
unsigned i;
- assert(r);
-
- tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
- header = (struct tgsi_header *) &tokens[0];
- *header = tgsi_build_header();
- *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 2;
-
- /*
- * decl i0 ; Luma texcoords
- * decl i1 ; Chroma Cb texcoords
- * decl i2 ; Chroma Cr texcoords
- */
- for (i = 0; i < 3; ++i) {
- decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
-
- /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */
- decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /* decl o0 ; Fragment color */
- decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /* decl t0, t1 */
- decl = vl_decl_temps(0, 1);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
- /*
- * decl s0 ; Sampler for luma texture
- * decl s1 ; Sampler for chroma Cb texture
- * decl s2 ; Sampler for chroma Cr texture
- */
- for (i = 0; i < 3; ++i) {
- decl = vl_decl_samplers(i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+ for (i = 0; i < 3; ++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);
+ temp = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
/*
- * tex2d t1, i0, s0 ; Read texel from luma texture
- * mov t0.x, t1.x ; Move luma sample into .x component
- * tex2d t1, i1, s1 ; Read texel from chroma Cb texture
- * mov t0.y, t1.x ; Move Cb sample into .y component
- * tex2d t1, i2, s2 ; Read texel from chroma Cr texture
- * mov t0.z, t1.x ; Move Cr sample into .z component
+ * texel.r = tex(tc[0], sampler[0])
+ * texel.g = tex(tc[1], sampler[1])
+ * texel.b = tex(tc[2], sampler[2])
+ * fragment = texel * scale
*/
for (i = 0; i < 3; ++i) {
- inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
- inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
- inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ /* Nouveau can't writemask tex dst regs (yet?), do in two steps */
+ ureg_TEX(shader, temp, TGSI_TEXTURE_2D, tc[i], sampler[i]);
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), ureg_scalar(ureg_src(temp), TGSI_SWIZZLE_X));
}
+ ureg_MUL(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X));
- /* mul o0, t0, c0 ; Rescale texel to correct range */
- inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, temp);
+ ureg_END(shader);
- assert(ti <= max_tokens);
+ r->i_fs = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->i_fs)
+ return false;
- fs.tokens = tokens;
- r->i_fs = r->pipe->create_fs_state(r->pipe, &fs);
- free(tokens);
+ return true;
}
-static void
+static bool
create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
- const unsigned max_tokens = 100;
-
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned ti;
-
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[4];
+ struct ureg_dst o_vpos, o_vtex[4];
unsigned i;
- assert(r);
-
- tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
- header = (struct tgsi_header *) &tokens[0];
- *header = tgsi_build_header();
- *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 2;
-
- /*
- * decl i0 ; Vertex pos
- * decl i1 ; Luma texcoords
- * decl i2 ; Chroma Cb texcoords
- * decl i3 ; Chroma Cr texcoords
- * decl i4 ; Ref surface top field texcoords
- * decl i5 ; Ref surface bottom field texcoords (unused, packed in the same stream)
- */
- for (i = 0; i < 6; i++) {
- decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
- /*
- * decl o0 ; Vertex pos
- * decl o1 ; Luma texcoords
- * decl o2 ; Chroma Cb texcoords
- * decl o3 ; Chroma Cr texcoords
- * decl o4 ; Ref macroblock texcoords
- */
- for (i = 0; i < 5; i++) {
- decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 4; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 4; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
/*
- * mov o0, i0 ; Move input vertex pos to output
- * mov o1, i1 ; Move input luma texcoords to output
- * mov o2, i2 ; Move input chroma Cb texcoords to output
- * mov o3, i3 ; Move input chroma Cr texcoords to output
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ * o_vtex[3] = vpos + vtex[3] // Apply motion vector
*/
- for (i = 0; i < 4; ++i) {
- inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
-
- /* add o4, i0, i4 ; Translate vertex pos by motion vec to form ref macroblock texcoords */
- inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 4);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ 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]);
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_END(shader);
- assert(ti <= max_tokens);
+ r->p_vs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->p_vs[0])
+ return false;
- vs.tokens = tokens;
- r->p_vs[0] = r->pipe->create_vs_state(r->pipe, &vs);
- free(tokens);
+ return true;
}
#if 0
}
#endif
-static void
+static bool
create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
- const unsigned max_tokens = 100;
-
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned ti;
-
+ struct ureg_program *shader;
+ struct ureg_src tc[4];
+ struct ureg_src sampler[4];
+ struct ureg_dst texel, ref;
+ struct ureg_dst fragment;
unsigned i;
- assert(r);
-
- tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
- header = (struct tgsi_header *) &tokens[0];
- *header = tgsi_build_header();
- *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 2;
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
- /*
- * decl i0 ; Luma texcoords
- * decl i1 ; Chroma Cb texcoords
- * decl i2 ; Chroma Cr texcoords
- * decl i3 ; Ref macroblock texcoords
- */
- for (i = 0; i < 4; ++i) {
- decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+ for (i = 0; i < 4; ++i) {
+ tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, i + 1, TGSI_INTERPOLATE_LINEAR);
+ sampler[i] = ureg_DECL_sampler(shader, i);
}
-
- /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */
- decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /* decl o0 ; Fragment color */
- decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /* decl t0, t1 */
- decl = vl_decl_temps(0, 1);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+ texel = ureg_DECL_temporary(shader);
+ ref = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
/*
- * decl s0 ; Sampler for luma texture
- * decl s1 ; Sampler for chroma Cb texture
- * decl s2 ; Sampler for chroma Cr texture
- * decl s3 ; Sampler for ref surface texture
- */
- for (i = 0; i < 4; ++i) {
- decl = vl_decl_samplers(i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
-
- /*
- * tex2d t1, i0, s0 ; Read texel from luma texture
- * mov t0.x, t1.x ; Move luma sample into .x component
- * tex2d t1, i1, s1 ; Read texel from chroma Cb texture
- * mov t0.y, t1.x ; Move Cb sample into .y component
- * tex2d t1, i2, s2 ; Read texel from chroma Cr texture
- * mov t0.z, t1.x ; Move Cr sample into .z component
+ * 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) {
- inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
- inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
- inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ /* 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_TEX(shader, ref, TGSI_TEXTURE_2D, tc[3], 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));
- /* mul t0, t0, c0 ; Rescale texel to correct range */
- inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* tex2d t1, i3, s3 ; Read texel from ref macroblock */
- inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 3, TGSI_FILE_SAMPLER, 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* add o0, t0, t1 ; Add ref and differential to form final output */
- inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, ref);
+ ureg_END(shader);
- assert(ti <= max_tokens);
+ r->p_fs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->p_fs[0])
+ return false;
- fs.tokens = tokens;
- r->p_fs[0] = r->pipe->create_fs_state(r->pipe, &fs);
- free(tokens);
+ return true;
}
#if 0
}
#endif
-static void
+static bool
create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
- const unsigned max_tokens = 100;
-
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned ti;
-
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[5];
+ struct ureg_dst o_vpos, o_vtex[5];
unsigned i;
- assert(r);
-
- tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
- header = (struct tgsi_header *) &tokens[0];
- *header = tgsi_build_header();
- *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 2;
-
- /*
- * decl i0 ; Vertex pos
- * decl i1 ; Luma texcoords
- * decl i2 ; Chroma Cb texcoords
- * decl i3 ; Chroma Cr texcoords
- * decl i4 ; First ref macroblock top field texcoords
- * decl i5 ; First ref macroblock bottom field texcoords (unused, packed in the same stream)
- * decl i6 ; Second ref macroblock top field texcoords
- * decl i7 ; Second ref macroblock bottom field texcoords (unused, packed in the same stream)
- */
- for (i = 0; i < 8; i++) {
- decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
-
- /*
- * decl o0 ; Vertex pos
- * decl o1 ; Luma texcoords
- * decl o2 ; Chroma Cb texcoords
- * decl o3 ; Chroma Cr texcoords
- * decl o4 ; First ref macroblock texcoords
- * decl o5 ; Second ref macroblock texcoords
- */
- for (i = 0; i < 6; i++) {
- decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
- /*
- * mov o0, i0 ; Move input vertex pos to output
- * mov o1, i1 ; Move input luma texcoords to output
- * mov o2, i2 ; Move input chroma Cb texcoords to output
- * mov o3, i3 ; Move input chroma Cr texcoords to output
- */
- for (i = 0; i < 4; ++i) {
- inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 4; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ /* Skip input 5 */
+ ureg_DECL_vs_input(shader, 5);
+ vtex[4] = ureg_DECL_vs_input(shader, 6);
+ 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);
/*
- * add o4, i0, i4 ; Translate vertex pos by motion vec to form first ref macroblock texcoords
- * add o5, i0, i6 ; Translate vertex pos by motion vec to form second ref macroblock texcoords
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ * o_vtex[3..4] = vpos + vtex[3..4] // Apply motion vector
*/
- for (i = 0; i < 2; ++i) {
- inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
+ for (i = 3; i < 5; ++i)
+ ureg_ADD(shader, o_vtex[i], vpos, vtex[i]);
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_END(shader);
- assert(ti <= max_tokens);
+ r->b_vs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->b_vs[0])
+ return false;
- vs.tokens = tokens;
- r->b_vs[0] = r->pipe->create_vs_state(r->pipe, &vs);
- free(tokens);
+ return true;
}
#if 0
}
#endif
-static void
+static bool
create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
- const unsigned max_tokens = 100;
-
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned ti;
-
+ 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;
- assert(r);
-
- tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
- header = (struct tgsi_header *) &tokens[0];
- *header = tgsi_build_header();
- *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 2;
-
- /*
- * decl i0 ; Luma texcoords
- * decl i1 ; Chroma Cb texcoords
- * decl i2 ; Chroma Cr texcoords
- * decl i3 ; First ref macroblock texcoords
- * decl i4 ; Second ref macroblock texcoords
- */
- for (i = 0; i < 5; ++i) {
- decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
- }
-
- /*
- * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
- * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels
- */
- decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /* decl o0 ; Fragment color */
- decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /* decl t0-t2 */
- decl = vl_decl_temps(0, 2);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
- /*
- * decl s0 ; Sampler for luma texture
- * decl s1 ; Sampler for chroma Cb texture
- * decl s2 ; Sampler for chroma Cr texture
- * decl s3 ; Sampler for first ref surface texture
- * decl s4 ; Sampler for second ref surface texture
- */
- for (i = 0; i < 5; ++i) {
- decl = vl_decl_samplers(i, i);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+ 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);
/*
- * tex2d t1, i0, s0 ; Read texel from luma texture
- * mov t0.x, t1.x ; Move luma sample into .x component
- * tex2d t1, i1, s1 ; Read texel from chroma Cb texture
- * mov t0.y, t1.x ; Move Cb sample into .y component
- * tex2d t1, i2, s2 ; Read texel from chroma Cr texture
- * mov t0.z, t1.x ; Move Cr sample into .z component
+ * 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) {
- inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
- inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
- inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
-
- /* mul t0, t0, c0 ; Rescale texel to correct range */
- inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /*
- * tex2d t1, i3, s3 ; Read texel from first ref macroblock
- * tex2d t2, i4, s4 ; Read texel from second ref macroblock
- */
- for (i = 0; i < 2; ++i) {
- inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, i + 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ /* 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]));
- /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
- inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
- inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
- inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* add o0, t0, t1 ; Add past/future ref and differential to form final output */
- inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_MAD(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X), ureg_src(ref[0]));
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, ref[0]);
+ ureg_release_temporary(shader, ref[1]);
+ ureg_END(shader);
- assert(ti <= max_tokens);
+ r->b_fs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->b_fs[0])
+ return false;
- fs.tokens = tokens;
- r->b_fs[0] = r->pipe->create_fs_state(r->pipe, &fs);
- free(tokens);
+ return true;
}
#if 0
assert(r);
for (i = 0; i < 3; ++i) {
- r->tex_transfer[i] = r->pipe->get_tex_transfer
+ struct pipe_box rect =
+ {
+ 0, 0, 0,
+ r->textures.all[i]->width0,
+ r->textures.all[i]->height0,
+ 1
+ };
+
+ r->tex_transfer[i] = r->pipe->get_transfer
(
r->pipe, r->textures.all[i],
- 0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0,
- r->textures.all[i]->width0, r->textures.all[i]->height0
+ u_subresource(0, 0),
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &rect
);
r->texels[i] = r->pipe->transfer_map(r->pipe, r->tex_transfer[i]);
for (i = 0; i < 3; ++i) {
r->pipe->transfer_unmap(r->pipe, r->tex_transfer[i]);
- r->pipe->tex_transfer_destroy(r->pipe, r->tex_transfer[i]);
+ r->pipe->transfer_destroy(r->pipe, r->tex_transfer[i]);
}
}
init_pipe_state(struct vl_mpeg12_mc_renderer *r)
{
struct pipe_sampler_state sampler;
- struct pipe_vertex_element vertex_elems[8];
unsigned filters[5];
unsigned i;
r->viewport.translate[2] = 0;
r->viewport.translate[3] = 0;
- r->scissor.maxx = r->pot_buffers ?
- util_next_power_of_two(r->picture_width) : r->picture_width;
- r->scissor.maxy = r->pot_buffers ?
- util_next_power_of_two(r->picture_height) : r->picture_height;
-
r->fb_state.width = r->pot_buffers ?
util_next_power_of_two(r->picture_width) : r->picture_width;
r->fb_state.height = r->pot_buffers ?
filters[4] = PIPE_TEX_FILTER_LINEAR;
for (i = 0; i < 5; ++i) {
+ memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
}
- /* Position element */
- vertex_elems[0].src_offset = 0;
- vertex_elems[0].instance_divisor = 0;
- vertex_elems[0].vertex_buffer_index = 0;
- vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Luma, texcoord element */
- vertex_elems[1].src_offset = sizeof(struct vertex2f);
- vertex_elems[1].instance_divisor = 0;
- vertex_elems[1].vertex_buffer_index = 0;
- vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Chroma Cr texcoord element */
- vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
- vertex_elems[2].instance_divisor = 0;
- vertex_elems[2].vertex_buffer_index = 0;
- vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Chroma Cb texcoord element */
- vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
- vertex_elems[3].instance_divisor = 0;
- vertex_elems[3].vertex_buffer_index = 0;
- vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* First ref surface top field texcoord element */
- vertex_elems[4].src_offset = 0;
- vertex_elems[4].instance_divisor = 0;
- vertex_elems[4].vertex_buffer_index = 1;
- vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* First ref surface bottom field texcoord element */
- vertex_elems[5].src_offset = sizeof(struct vertex2f);
- vertex_elems[5].instance_divisor = 0;
- vertex_elems[5].vertex_buffer_index = 1;
- vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Second ref surface top field texcoord element */
- vertex_elems[6].src_offset = 0;
- vertex_elems[6].instance_divisor = 0;
- vertex_elems[6].vertex_buffer_index = 2;
- vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Second ref surface bottom field texcoord element */
- vertex_elems[7].src_offset = sizeof(struct vertex2f);
- vertex_elems[7].instance_divisor = 0;
- vertex_elems[7].vertex_buffer_index = 2;
- vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* need versions with 4,6 and 8 vertex elems */
- r->vertex_elems[0] = r->pipe->create_vertex_elements_state(r->pipe, 4, vertex_elems);
- r->vertex_elems[1] = r->pipe->create_vertex_elements_state(r->pipe, 6, vertex_elems);
- r->vertex_elems[2] = r->pipe->create_vertex_elements_state(r->pipe, 8, vertex_elems);
-
return true;
}
for (i = 0; i < 5; ++i)
r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]);
- for (i = 0; i < 3; i++)
- r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems[i]);
}
static bool
static bool
init_buffers(struct vl_mpeg12_mc_renderer *r)
{
- struct pipe_texture template;
+ struct pipe_resource template;
+ struct pipe_vertex_element vertex_elems[8];
+ struct pipe_sampler_view sampler_view;
const unsigned mbw =
align(r->picture_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
r->num_macroblocks = 0;
r->macroblock_buf = MALLOC(r->macroblocks_per_batch * sizeof(struct pipe_mpeg12_macroblock));
- memset(&template, 0, sizeof(struct pipe_texture));
+ memset(&template, 0, sizeof(struct pipe_resource));
template.target = PIPE_TEXTURE_2D;
/* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
template.format = PIPE_FORMAT_R16_SNORM;
template.height0 = r->pot_buffers ?
util_next_power_of_two(r->picture_height) : r->picture_height;
template.depth0 = 1;
- template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC;
+ template.usage = PIPE_USAGE_DYNAMIC;
+ template.bind = PIPE_BIND_SAMPLER_VIEW;
+ template.flags = 0;
- r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template);
+ r->textures.individual.y = r->pipe->screen->resource_create(r->pipe->screen, &template);
if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
template.width0 = r->pot_buffers ?
r->picture_height / 2;
r->textures.individual.cb =
- r->pipe->screen->texture_create(r->pipe->screen, &template);
+ r->pipe->screen->resource_create(r->pipe->screen, &template);
r->textures.individual.cr =
- r->pipe->screen->texture_create(r->pipe->screen, &template);
+ r->pipe->screen->resource_create(r->pipe->screen, &template);
+
+ for (i = 0; i < 3; ++i) {
+ u_sampler_view_default_template(&sampler_view,
+ r->textures.all[i],
+ r->textures.all[i]->format);
+ r->sampler_views.all[i] = r->pipe->create_sampler_view(r->pipe, r->textures.all[i], &sampler_view);
+ }
r->vertex_bufs.individual.ycbcr.stride = sizeof(struct vertex2f) * 4;
r->vertex_bufs.individual.ycbcr.max_index = 24 * r->macroblocks_per_batch - 1;
r->vertex_bufs.individual.ycbcr.buffer_offset = 0;
+ /* XXX: Create with usage DYNAMIC or STREAM */
r->vertex_bufs.individual.ycbcr.buffer = pipe_buffer_create
(
r->pipe->screen,
- DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
+ PIPE_BIND_VERTEX_BUFFER,
sizeof(struct vertex2f) * 4 * 24 * r->macroblocks_per_batch
);
r->vertex_bufs.all[i].stride = sizeof(struct vertex2f) * 2;
r->vertex_bufs.all[i].max_index = 24 * r->macroblocks_per_batch - 1;
r->vertex_bufs.all[i].buffer_offset = 0;
+ /* XXX: Create with usage DYNAMIC or STREAM */
r->vertex_bufs.all[i].buffer = pipe_buffer_create
(
r->pipe->screen,
- DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
+ PIPE_BIND_VERTEX_BUFFER,
sizeof(struct vertex2f) * 2 * 24 * r->macroblocks_per_batch
);
}
+ memset(&vertex_elems, 0, sizeof(vertex_elems));
+
+ /* Position element */
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Luma, texcoord element */
+ vertex_elems[1].src_offset = sizeof(struct vertex2f);
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 0;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cr texcoord element */
+ vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
+ vertex_elems[2].instance_divisor = 0;
+ vertex_elems[2].vertex_buffer_index = 0;
+ vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cb texcoord element */
+ vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
+ vertex_elems[3].instance_divisor = 0;
+ vertex_elems[3].vertex_buffer_index = 0;
+ vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface top field texcoord element */
+ vertex_elems[4].src_offset = 0;
+ vertex_elems[4].instance_divisor = 0;
+ vertex_elems[4].vertex_buffer_index = 1;
+ vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface bottom field texcoord element */
+ vertex_elems[5].src_offset = sizeof(struct vertex2f);
+ vertex_elems[5].instance_divisor = 0;
+ vertex_elems[5].vertex_buffer_index = 1;
+ vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface top field texcoord element */
+ vertex_elems[6].src_offset = 0;
+ vertex_elems[6].instance_divisor = 0;
+ vertex_elems[6].vertex_buffer_index = 2;
+ vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface bottom field texcoord element */
+ vertex_elems[7].src_offset = sizeof(struct vertex2f);
+ vertex_elems[7].instance_divisor = 0;
+ vertex_elems[7].vertex_buffer_index = 2;
+ vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ r->vertex_elems_state.individual.i = r->pipe->create_vertex_elements_state(r->pipe, 4, vertex_elems);
+ r->vertex_elems_state.individual.p = r->pipe->create_vertex_elements_state(r->pipe, 6, vertex_elems);
+ r->vertex_elems_state.individual.b = r->pipe->create_vertex_elements_state(r->pipe, 8, vertex_elems);
+
r->vs_const_buf = pipe_buffer_create
(
r->pipe->screen,
- DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
+ PIPE_BIND_CONSTANT_BUFFER,
sizeof(struct vertex_shader_consts)
);
- r->fs_const_buf = pipe_buffer_create
- (
- r->pipe->screen,
- DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_CONSTANT, sizeof(struct fragment_shader_consts)
- );
-
- memcpy
- (
- pipe_buffer_map(r->pipe->screen, r->fs_const_buf, PIPE_BUFFER_USAGE_CPU_WRITE),
- &fs_consts, sizeof(struct fragment_shader_consts)
- );
-
- pipe_buffer_unmap(r->pipe->screen, r->fs_const_buf);
-
return true;
}
assert(r);
- pipe_buffer_reference(&r->vs_const_buf, NULL);
- pipe_buffer_reference(&r->fs_const_buf, NULL);
+ pipe_resource_reference(&r->vs_const_buf, NULL);
- for (i = 0; i < 3; ++i)
- pipe_buffer_reference(&r->vertex_bufs.all[i].buffer, NULL);
-
- for (i = 0; i < 3; ++i)
- pipe_texture_reference(&r->textures.all[i], NULL);
+ for (i = 0; i < 3; ++i) {
+ pipe_sampler_view_reference(&r->sampler_views.all[i], NULL);
+ r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems_state.all[i]);
+ pipe_resource_reference(&r->vertex_bufs.all[i].buffer, NULL);
+ pipe_resource_reference(&r->textures.all[i], NULL);
+ }
FREE(r->macroblock_buf);
}
return -1;
}
-/* XXX: One of these days this will have to be killed with fire */
-#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, use_zb, zb) \
- do { \
- (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \
- (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \
- (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].pos.y = (mby) * (unity) + (ofsy); \
- (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \
- \
- if (!use_zb || (cbp) & (lm)) \
- { \
- (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- } \
- else \
- { \
- (vb)[0].luma_tc.x = (zb)[0].x; (vb)[0].luma_tc.y = (zb)[0].y; \
- (vb)[1].luma_tc.x = (zb)[0].x; (vb)[1].luma_tc.y = (zb)[0].y + (hy); \
- (vb)[2].luma_tc.x = (zb)[0].x + (hx); (vb)[2].luma_tc.y = (zb)[0].y; \
- (vb)[3].luma_tc.x = (zb)[0].x + (hx); (vb)[3].luma_tc.y = (zb)[0].y; \
- (vb)[4].luma_tc.x = (zb)[0].x; (vb)[4].luma_tc.y = (zb)[0].y + (hy); \
- (vb)[5].luma_tc.x = (zb)[0].x + (hx); (vb)[5].luma_tc.y = (zb)[0].y + (hy); \
- } \
- \
- if (!use_zb || (cbp) & (cbm)) \
- { \
- (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- } \
- else \
- { \
- (vb)[0].cb_tc.x = (zb)[1].x; (vb)[0].cb_tc.y = (zb)[1].y; \
- (vb)[1].cb_tc.x = (zb)[1].x; (vb)[1].cb_tc.y = (zb)[1].y + (hy); \
- (vb)[2].cb_tc.x = (zb)[1].x + (hx); (vb)[2].cb_tc.y = (zb)[1].y; \
- (vb)[3].cb_tc.x = (zb)[1].x + (hx); (vb)[3].cb_tc.y = (zb)[1].y; \
- (vb)[4].cb_tc.x = (zb)[1].x; (vb)[4].cb_tc.y = (zb)[1].y + (hy); \
- (vb)[5].cb_tc.x = (zb)[1].x + (hx); (vb)[5].cb_tc.y = (zb)[1].y + (hy); \
- } \
- \
- if (!use_zb || (cbp) & (crm)) \
- { \
- (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \
- (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
- } \
- else \
- { \
- (vb)[0].cr_tc.x = (zb)[2].x; (vb)[0].cr_tc.y = (zb)[2].y; \
- (vb)[1].cr_tc.x = (zb)[2].x; (vb)[1].cr_tc.y = (zb)[2].y + (hy); \
- (vb)[2].cr_tc.x = (zb)[2].x + (hx); (vb)[2].cr_tc.y = (zb)[2].y; \
- (vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \
- (vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \
- (vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
- } \
- } while (0)
+static void
+gen_block_verts(struct vert_stream_0 *vb, unsigned cbp, unsigned mbx, unsigned mby,
+ const struct vertex2f *unit, const struct vertex2f *half, const struct vertex2f *offset,
+ unsigned luma_mask, unsigned cb_mask, unsigned cr_mask,
+ bool use_zeroblocks, struct vertex2f *zero_blocks)
+{
+ struct vertex2f v;
+
+ assert(vb);
+ assert(unit && half && offset);
+ assert(zero_blocks || !use_zeroblocks);
+
+ /* Generate vertices for two triangles covering a block */
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+
+ vb[0].pos.x = v.x;
+ vb[0].pos.y = v.y;
+ vb[1].pos.x = v.x;
+ vb[1].pos.y = v.y + half->y;
+ vb[2].pos.x = v.x + half->x;
+ vb[2].pos.y = v.y;
+ vb[3].pos.x = v.x + half->x;
+ vb[3].pos.y = v.y;
+ vb[4].pos.x = v.x;
+ vb[4].pos.y = v.y + half->y;
+ vb[5].pos.x = v.x + half->x;
+ vb[5].pos.y = v.y + half->y;
+
+ /* Generate texcoords for the triangles, either pointing to the correct area on the luma/chroma texture
+ or if zero blocks are being used, to the zero block if the appropriate CBP bits aren't set (i.e. no data
+ for this channel is defined for this block) */
+
+ if (!use_zeroblocks || cbp & luma_mask) {
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+ }
+ else {
+ v.x = zero_blocks[0].x;
+ v.y = zero_blocks[0].y;
+ }
+
+ vb[0].luma_tc.x = v.x;
+ vb[0].luma_tc.y = v.y;
+ vb[1].luma_tc.x = v.x;
+ vb[1].luma_tc.y = v.y + half->y;
+ vb[2].luma_tc.x = v.x + half->x;
+ vb[2].luma_tc.y = v.y;
+ vb[3].luma_tc.x = v.x + half->x;
+ vb[3].luma_tc.y = v.y;
+ vb[4].luma_tc.x = v.x;
+ vb[4].luma_tc.y = v.y + half->y;
+ vb[5].luma_tc.x = v.x + half->x;
+ vb[5].luma_tc.y = v.y + half->y;
+
+ if (!use_zeroblocks || cbp & cb_mask) {
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+ }
+ else {
+ v.x = zero_blocks[1].x;
+ v.y = zero_blocks[1].y;
+ }
+
+ vb[0].cb_tc.x = v.x;
+ vb[0].cb_tc.y = v.y;
+ vb[1].cb_tc.x = v.x;
+ vb[1].cb_tc.y = v.y + half->y;
+ vb[2].cb_tc.x = v.x + half->x;
+ vb[2].cb_tc.y = v.y;
+ vb[3].cb_tc.x = v.x + half->x;
+ vb[3].cb_tc.y = v.y;
+ vb[4].cb_tc.x = v.x;
+ vb[4].cb_tc.y = v.y + half->y;
+ vb[5].cb_tc.x = v.x + half->x;
+ vb[5].cb_tc.y = v.y + half->y;
+
+ if (!use_zeroblocks || cbp & cr_mask) {
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+ }
+ else {
+ v.x = zero_blocks[2].x;
+ v.y = zero_blocks[2].y;
+ }
+
+ vb[0].cr_tc.x = v.x;
+ vb[0].cr_tc.y = v.y;
+ vb[1].cr_tc.x = v.x;
+ vb[1].cr_tc.y = v.y + half->y;
+ vb[2].cr_tc.x = v.x + half->x;
+ vb[2].cr_tc.y = v.y;
+ vb[3].cr_tc.x = v.x + half->x;
+ vb[3].cr_tc.y = v.y;
+ vb[4].cr_tc.x = v.x;
+ vb[4].cr_tc.y = v.y + half->y;
+ vb[5].cr_tc.x = v.x + half->x;
+ vb[5].cr_tc.y = v.y + half->y;
+}
static void
gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r,
}
}
- if (mb->mb_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+ if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
for (i = 0; i < 24 * 2; i += 2) {
vb[i].x = mo_vec[0].x;
vb[i].y = mo_vec[0].y;
r->surface_tex_inv_size.x * (MACROBLOCK_WIDTH / 2),
r->surface_tex_inv_size.y * (MACROBLOCK_HEIGHT / 2)
};
+ const struct vertex2f offsets[2][2] =
+ {
+ {
+ {0, 0}, {0, half.y}
+ },
+ {
+ {half.x, 0}, {half.x, half.y}
+ }
+ };
const bool use_zb = r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE;
struct vert_stream_0 *vb = ycbcr_vb + pos * 24;
- SET_BLOCK(vb, mb->cbp, mb->mbx, mb->mby,
- unit.x, unit.y, 0, 0, half.x, half.y,
- 32, 2, 1, use_zb, r->zero_block);
+ gen_block_verts(vb, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[0][0],
+ 32, 2, 1, use_zb, r->zero_block);
- SET_BLOCK(vb + 6, mb->cbp, mb->mbx, mb->mby,
- unit.x, unit.y, half.x, 0, half.x, half.y,
- 16, 2, 1, use_zb, r->zero_block);
+ gen_block_verts(vb + 6, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[1][0],
+ 16, 2, 1, use_zb, r->zero_block);
- SET_BLOCK(vb + 12, mb->cbp, mb->mbx, mb->mby,
- unit.x, unit.y, 0, half.y, half.x, half.y,
- 8, 2, 1, use_zb, r->zero_block);
+ gen_block_verts(vb + 12, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[0][1],
+ 8, 2, 1, use_zb, r->zero_block);
- SET_BLOCK(vb + 18, mb->cbp, mb->mbx, mb->mby,
- unit.x, unit.y, half.x, half.y, half.x, half.y,
- 4, 2, 1, use_zb, r->zero_block);
+ gen_block_verts(vb + 18, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[1][1],
+ 4, 2, 1, use_zb, r->zero_block);
break;
}
unsigned offset[NUM_MACROBLOCK_TYPES];
struct vert_stream_0 *ycbcr_vb;
struct vertex2f *ref_vb[2];
+ struct pipe_transfer *buf_transfer[3];
unsigned i;
assert(r);
ycbcr_vb = (struct vert_stream_0 *)pipe_buffer_map
(
- r->pipe->screen,
+ r->pipe,
r->vertex_bufs.individual.ycbcr.buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer[0]
);
for (i = 0; i < 2; ++i)
ref_vb[i] = (struct vertex2f *)pipe_buffer_map
(
- r->pipe->screen,
+ r->pipe,
r->vertex_bufs.individual.ref[i].buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer[i + 1]
);
for (i = 0; i < r->num_macroblocks; ++i) {
++offset[mb_type];
}
- pipe_buffer_unmap(r->pipe->screen, r->vertex_bufs.individual.ycbcr.buffer);
+ pipe_buffer_unmap(r->pipe, r->vertex_bufs.individual.ycbcr.buffer, buf_transfer[0]);
for (i = 0; i < 2; ++i)
- pipe_buffer_unmap(r->pipe->screen, r->vertex_bufs.individual.ref[i].buffer);
+ pipe_buffer_unmap(r->pipe, r->vertex_bufs.individual.ref[i].buffer, buf_transfer[i + 1]);
+}
+
+static struct pipe_sampler_view
+*find_or_create_sampler_view(struct vl_mpeg12_mc_renderer *r, struct pipe_surface *surface)
+{
+ struct pipe_sampler_view *sampler_view;
+ assert(r);
+ assert(surface);
+
+ sampler_view = (struct pipe_sampler_view*)util_keymap_lookup(r->texview_map, &surface);
+ if (!sampler_view) {
+ struct pipe_sampler_view templat;
+ boolean added_to_map;
+
+ u_sampler_view_default_template(&templat, surface->texture,
+ surface->texture->format);
+ sampler_view = r->pipe->create_sampler_view(r->pipe, surface->texture,
+ &templat);
+ if (!sampler_view)
+ return NULL;
+
+ added_to_map = util_keymap_insert(r->texview_map, &surface,
+ sampler_view, r->pipe);
+ assert(added_to_map);
+ }
+
+ return sampler_view;
}
static void
unsigned num_macroblocks[NUM_MACROBLOCK_TYPES] = { 0 };
unsigned vb_start = 0;
struct vertex_shader_consts *vs_consts;
+ struct pipe_transfer *buf_transfer;
+
unsigned i;
assert(r);
gen_macroblock_stream(r, num_macroblocks);
- r->fb_state.cbufs[0] = r->pipe->screen->get_tex_surface
- (
- r->pipe->screen, r->surface,
- 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE
- );
+ r->fb_state.cbufs[0] = r->surface;
r->pipe->set_framebuffer_state(r->pipe, &r->fb_state);
r->pipe->set_viewport_state(r->pipe, &r->viewport);
- r->pipe->set_scissor_state(r->pipe, &r->scissor);
vs_consts = pipe_buffer_map
(
- r->pipe->screen, r->vs_const_buf,
- PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+ r->pipe, r->vs_const_buf,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer
);
- vs_consts->denorm.x = r->surface->width0;
- vs_consts->denorm.y = r->surface->height0;
+ vs_consts->denorm.x = r->surface->width;
+ vs_consts->denorm.y = r->surface->height;
- pipe_buffer_unmap(r->pipe->screen, r->vs_const_buf);
+ pipe_buffer_unmap(r->pipe, r->vs_const_buf, buf_transfer);
r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_VERTEX, 0,
r->vs_const_buf);
- r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_FRAGMENT, 0,
- r->fs_const_buf);
+
if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
- r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[0]);
- r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.i);
+ r->pipe->set_fragment_sampler_views(r->pipe, 3, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->i_vs);
r->pipe->bind_fs_state(r->pipe, r->i_fs);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24);
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24);
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24;
}
if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_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[1]);
- r->textures.individual.ref[0] = r->past;
- r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24);
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24);
+
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24;
}
if (false /*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[1]);
- r->textures.individual.ref[0] = r->past;
- r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24);
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24);
+
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24;
}
if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_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[1]);
- r->textures.individual.ref[0] = r->future;
- r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24);
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24);
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24;
}
- if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) {
+ if (false /*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[1]);
- r->textures.individual.ref[0] = r->future;
- r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24);
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24);
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24;
}
if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_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[2]);
- r->textures.individual.ref[0] = r->past;
- r->textures.individual.ref[1] = r->future;
- r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->textures.individual.ref[1] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->b_vs[0]);
r->pipe->bind_fs_state(r->pipe, r->b_fs[0]);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24);
+
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24);
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24;
}
if (false /*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[2]);
- r->textures.individual.ref[0] = r->past;
- r->textures.individual.ref[1] = r->future;
- r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->textures.individual.ref[1] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->b_vs[1]);
r->pipe->bind_fs_state(r->pipe, r->b_fs[1]);
- r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
- num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24);
+ util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24);
+
vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24;
}
r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, r->fence);
- pipe_surface_reference(&r->fb_state.cbufs[0], NULL);
if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE)
for (i = 0; i < 3; ++i)
assert(r);
assert(blocks);
- tex_pitch = r->tex_transfer[0]->stride / util_format_get_blocksize(r->tex_transfer[0]->texture->format);
+ tex_pitch = r->tex_transfer[0]->stride / util_format_get_blocksize(r->tex_transfer[0]->resource->format);
texels = r->texels[0] + mbpy * tex_pitch + mbpx;
for (y = 0; y < 2; ++y) {
mbpy /= 2;
for (tb = 0; tb < 2; ++tb) {
- tex_pitch = r->tex_transfer[tb + 1]->stride / util_format_get_blocksize(r->tex_transfer[tb + 1]->texture->format);
+ tex_pitch = r->tex_transfer[tb + 1]->stride / util_format_get_blocksize(r->tex_transfer[tb + 1]->resource->format);
texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx;
if ((cbp >> (1 - tb)) & 1) {
{
assert(r);
assert(mb);
+ assert(mb->blocks);
assert(r->num_macroblocks < r->macroblocks_per_batch);
memcpy(&r->macroblock_buf[r->num_macroblocks], mb,
++r->num_macroblocks;
}
+static void
+texview_map_delete(const struct keymap *map,
+ const void *key, void *data,
+ void *user)
+{
+ struct pipe_sampler_view *sv = (struct pipe_sampler_view*)data;
+
+ assert(map);
+ assert(key);
+ assert(data);
+ assert(user);
+
+ pipe_sampler_view_reference(&sv, NULL);
+}
+
bool
vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
struct pipe_context *pipe,
renderer->eb_handling = eb_handling;
renderer->pot_buffers = pot_buffers;
- if (!init_pipe_state(renderer))
+ renderer->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
+ texview_map_delete);
+ if (!renderer->texview_map)
return false;
+
+ if (!init_pipe_state(renderer)) {
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
+ return false;
+ }
if (!init_shaders(renderer)) {
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
cleanup_pipe_state(renderer);
return false;
}
if (!init_buffers(renderer)) {
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
cleanup_shaders(renderer);
cleanup_pipe_state(renderer);
return false;
xfer_buffers_unmap(renderer);
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
cleanup_pipe_state(renderer);
cleanup_shaders(renderer);
cleanup_buffers(renderer);
+
+ pipe_surface_reference(&renderer->surface, NULL);
+ pipe_surface_reference(&renderer->past, NULL);
+ pipe_surface_reference(&renderer->future, NULL);
}
void
vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer
*renderer,
- struct pipe_texture *surface,
- struct pipe_texture *past,
- struct pipe_texture *future,
+ struct pipe_surface *surface,
+ struct pipe_surface *past,
+ struct pipe_surface *future,
unsigned num_macroblocks,
struct pipe_mpeg12_macroblock
*mpeg12_macroblocks,
xfer_buffers_unmap(renderer);
flush(renderer);
}
-
+
new_surface = true;
}
new_surface = true;
if (new_surface) {
- renderer->surface = surface;
- renderer->past = past;
- renderer->future = future;
+ pipe_surface_reference(&renderer->surface, surface);
+ pipe_surface_reference(&renderer->past, past);
+ pipe_surface_reference(&renderer->future, future);
renderer->fence = fence;
- renderer->surface_tex_inv_size.x = 1.0f / surface->width0;
- renderer->surface_tex_inv_size.y = 1.0f / surface->height0;
+ renderer->surface_tex_inv_size.x = 1.0f / surface->width;
+ renderer->surface_tex_inv_size.y = 1.0f / surface->height;
}
while (num_macroblocks) {
flush(renderer);
xfer_buffers_map(renderer);
/* Next time we get this surface it may have new ref frames */
- renderer->surface = NULL;
+ pipe_surface_reference(&renderer->surface, NULL);
+ pipe_surface_reference(&renderer->past, NULL);
+ pipe_surface_reference(&renderer->future, NULL);
}
}
}