X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fg3dvl%2Fvl_r16snorm_mc_buf.c;h=e7a070ef4df28a1c4f395cc6c097360ac0b5e3ce;hb=4af0d940a35536f096a9289470af0268a79402b3;hp=08aed4542e72c449da739baa18c5febe70474804;hpb=29f876cc90605ad7de1141443d3b242395eed5ee;p=mesa.git diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 08aed4542e7..e7a070ef4df 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -6,10 +6,10 @@ #include #include #include -#include #include #include #include +#include #include "vl_render.h" #include "vl_shader_build.h" #include "vl_surface.h" @@ -17,6 +17,15 @@ #include "vl_types.h" #include "vl_defs.h" +/* + * TODO: Dynamically determine number of buf sets to use, based on + * video size and available mem, since we can easily run out of memory + * for high res videos. + * Note: Destroying previous frame's buffers and creating new ones + * doesn't work, since the buffer are not actually destroyed until their + * fence is signalled, and if we render fast enough we will create faster + * than we destroy. + */ #define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */ enum vlMacroBlockTypeEx @@ -47,15 +56,16 @@ struct vlR16SnormBufferedMC { struct vlRender base; - unsigned int video_width, video_height; - enum vlFormat video_format; + unsigned int picture_width, picture_height; + enum vlFormat picture_format; unsigned int cur_buf; struct vlSurface *buffered_surface; struct vlSurface *past_surface, *future_surface; struct vlVertex2f surface_tex_inv_size; - unsigned int num_macroblocks[vlNumMacroBlockExTypes]; - unsigned int total_num_macroblocks; + struct vlVertex2f zero_block[3]; + unsigned int num_macroblocks; + struct vlMpeg2MacroBlock *macroblocks; struct pipe_context *pipe; struct pipe_viewport_state viewport; @@ -64,8 +74,8 @@ struct vlR16SnormBufferedMC struct pipe_texture *textures[NUM_BUF_SETS][5]; void *i_vs, *p_vs[2], *b_vs[2]; void *i_fs, *p_fs[2], *b_fs[2]; - struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][vlNumMacroBlockExTypes][3]; - struct pipe_vertex_element vertex_elems[5]; + struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][3]; + struct pipe_vertex_element vertex_elems[8]; struct pipe_constant_buffer vs_const_buf, fs_const_buf; }; @@ -98,17 +108,7 @@ static inline int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst { unsigned int y; - for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) - memcpy - ( - dst + y * dst_pitch * 2, - src + y * VL_BLOCK_WIDTH, - VL_BLOCK_WIDTH * 2 - ); - - dst += VL_BLOCK_HEIGHT * dst_pitch; - - for (; y < VL_BLOCK_HEIGHT; ++y) + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) memcpy ( dst + y * dst_pitch * 2, @@ -130,7 +130,7 @@ static inline int vlGrabNoBlock(short *dst, unsigned int dst_pitch) 0, VL_BLOCK_WIDTH * 2 ); - + return 0; } @@ -164,7 +164,7 @@ static inline int vlGrabBlocks tex_pitch = tex_surface->stride / tex_surface->block.size; texels += mbpy * tex_pitch + mbpx; - + for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x, ++tb) @@ -194,8 +194,13 @@ static inline int vlGrabBlocks ++sb; } - else + else if (mc->zero_block[0].x < 0.0f) + { vlGrabNoBlock(texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH, tex_pitch); + + mc->zero_block[0].x = (mbpx + x * 8) * mc->surface_tex_inv_size.x; + mc->zero_block[0].y = (mbpy + y * 8) * mc->surface_tex_inv_size.y; + } } } @@ -232,79 +237,175 @@ static inline int vlGrabBlocks ++sb; } - else + else if (mc->zero_block[tb + 1].x < 0.0f) + { vlGrabNoBlock(texels, tex_pitch); + mc->zero_block[tb + 1].x = (mbpx << 1) * mc->surface_tex_inv_size.x; + mc->zero_block[tb + 1].y = (mbpy << 1) * mc->surface_tex_inv_size.y; + } + pipe_surface_unmap(tex_surface); } return 0; } -static inline int vlGrabMacroBlock -( - struct vlR16SnormBufferedMC *mc, - struct vlMpeg2MacroBlock *macroblock -) +static inline enum vlMacroBlockTypeEx vlGetMacroBlockTypeEx(struct vlMpeg2MacroBlock *mb) { - const struct vlVertex2f unit = - { - mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, - mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT - }; - const struct vlVertex2f half = - { - mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), - mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) - }; + assert(mb); - struct vlVertex2f *vb; - enum vlMacroBlockTypeEx mb_type_ex; - struct vlVertex2f mo_vec[2]; - unsigned int i; - - assert(mc); - assert(macroblock); - - switch (macroblock->mb_type) + switch (mb->mb_type) { case vlMacroBlockTypeIntra: - { - mb_type_ex = vlMacroBlockExTypeIntra; - break; - } + return vlMacroBlockExTypeIntra; case vlMacroBlockTypeFwdPredicted: - { - mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? + return mb->mo_type == vlMotionTypeFrame ? vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField; - break; - } case vlMacroBlockTypeBkwdPredicted: - { - mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? + return mb->mo_type == vlMotionTypeFrame ? vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField; - break; - } case vlMacroBlockTypeBiPredicted: - { - mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? + return mb->mo_type == vlMotionTypeFrame ? vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField; - break; - } default: assert(0); } + /* Unreachable */ + return -1; +} + +static inline int vlGrabMacroBlock +( + struct vlR16SnormBufferedMC *mc, + struct vlMpeg2MacroBlock *macroblock +) +{ + assert(mc); + assert(macroblock); + + mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx; + mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby; + mc->macroblocks[mc->num_macroblocks].mb_type = macroblock->mb_type; + mc->macroblocks[mc->num_macroblocks].mo_type = macroblock->mo_type; + mc->macroblocks[mc->num_macroblocks].dct_type = macroblock->dct_type; + mc->macroblocks[mc->num_macroblocks].PMV[0][0][0] = macroblock->PMV[0][0][0]; + mc->macroblocks[mc->num_macroblocks].PMV[0][0][1] = macroblock->PMV[0][0][1]; + mc->macroblocks[mc->num_macroblocks].PMV[0][1][0] = macroblock->PMV[0][1][0]; + mc->macroblocks[mc->num_macroblocks].PMV[0][1][1] = macroblock->PMV[0][1][1]; + mc->macroblocks[mc->num_macroblocks].PMV[1][0][0] = macroblock->PMV[1][0][0]; + mc->macroblocks[mc->num_macroblocks].PMV[1][0][1] = macroblock->PMV[1][0][1]; + mc->macroblocks[mc->num_macroblocks].PMV[1][1][0] = macroblock->PMV[1][1][0]; + mc->macroblocks[mc->num_macroblocks].PMV[1][1][1] = macroblock->PMV[1][1][1]; + mc->macroblocks[mc->num_macroblocks].cbp = macroblock->cbp; + mc->macroblocks[mc->num_macroblocks].blocks = macroblock->blocks; + + vlGrabBlocks + ( + mc, + macroblock->mbx, + macroblock->mby, + macroblock->dct_type, + macroblock->cbp, + macroblock->blocks + ); + + mc->num_macroblocks++; + + return 0; +} + +#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \ + (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 ((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 ((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 ((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); \ + } + +static inline int vlGrabMacroBlockVB +( + struct vlR16SnormBufferedMC *mc, + struct vlMpeg2MacroBlock *macroblock, + unsigned int pos +) +{ + struct vlVertex2f mo_vec[2]; + unsigned int i; + + assert(mc); + assert(macroblock); + switch (macroblock->mb_type) { case vlMacroBlockTypeBiPredicted: { + struct vlVertex2f *vb; + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_type_ex] * 2 * 24; + ) + pos * 2 * 24; mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; @@ -331,19 +432,21 @@ static inline int vlGrabMacroBlock } } - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer); + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer); /* fall-through */ } case vlMacroBlockTypeFwdPredicted: case vlMacroBlockTypeBkwdPredicted: { + struct vlVertex2f *vb; + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_type_ex] * 2 * 24; + ) + pos * 2 * 24; if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted) { @@ -387,52 +490,71 @@ static inline int vlGrabMacroBlock } } - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer); + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer); /* fall-through */ } case vlMacroBlockTypeIntra: { - vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + const struct vlVertex2f unit = + { + mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, + mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT + }; + const struct vlVertex2f half = + { + mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), + mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) + }; + + struct vlMacroBlockVertexStream0 + { + struct vlVertex2f pos; + struct vlVertex2f luma_tc; + struct vlVertex2f cb_tc; + struct vlVertex2f cr_tc; + } *vb; + + vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_type_ex] * 24; - - vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; - vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y + half.y; - vb[2].x = macroblock->mbx * unit.x + half.x; vb[2].y = macroblock->mby * unit.y; - - vb[3].x = macroblock->mbx * unit.x + half.x; vb[3].y = macroblock->mby * unit.y; - vb[4].x = macroblock->mbx * unit.x; vb[4].y = macroblock->mby * unit.y + half.y; - vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y + half.y; - - vb[6].x = macroblock->mbx * unit.x + half.x; vb[6].y = macroblock->mby * unit.y; - vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y + half.y; - vb[8].x = macroblock->mbx * unit.x + unit.x; vb[8].y = macroblock->mby * unit.y; - - vb[9].x = macroblock->mbx * unit.x + unit.x; vb[9].y = macroblock->mby * unit.y; - vb[10].x = macroblock->mbx * unit.x + half.x; vb[10].y = macroblock->mby * unit.y + half.y; - vb[11].x = macroblock->mbx * unit.x + unit.x; vb[11].y = macroblock->mby * unit.y + half.y; + ) + pos * 24; - vb[12].x = macroblock->mbx * unit.x; vb[12].y = macroblock->mby * unit.y + half.y; - vb[13].x = macroblock->mbx * unit.x; vb[13].y = macroblock->mby * unit.y + unit.y; - vb[14].x = macroblock->mbx * unit.x + half.x; vb[14].y = macroblock->mby * unit.y + half.y; + SET_BLOCK + ( + vb, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, 0, 0, half.x, half.y, + 32, 2, 1, mc->zero_block + ); - vb[15].x = macroblock->mbx * unit.x + half.x; vb[15].y = macroblock->mby * unit.y + half.y; - vb[16].x = macroblock->mbx * unit.x; vb[16].y = macroblock->mby * unit.y + unit.y; - vb[17].x = macroblock->mbx * unit.x + half.x; vb[17].y = macroblock->mby * unit.y + unit.y; + SET_BLOCK + ( + vb + 6, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, half.x, 0, half.x, half.y, + 16, 2, 1, mc->zero_block + ); - vb[18].x = macroblock->mbx * unit.x + half.x; vb[18].y = macroblock->mby * unit.y + half.y; - vb[19].x = macroblock->mbx * unit.x + half.x; vb[19].y = macroblock->mby * unit.y + unit.y; - vb[20].x = macroblock->mbx * unit.x + unit.x; vb[20].y = macroblock->mby * unit.y + half.y; + SET_BLOCK + ( + vb + 12, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, 0, half.y, half.x, half.y, + 8, 2, 1, mc->zero_block + ); - vb[21].x = macroblock->mbx * unit.x + unit.x; vb[21].y = macroblock->mby * unit.y + half.y; - vb[22].x = macroblock->mbx * unit.x + half.x; vb[22].y = macroblock->mby * unit.y + unit.y; - vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + unit.y; + SET_BLOCK + ( + vb + 18, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, half.x, half.y, half.x, half.y, + 4, 2, 1, mc->zero_block + ); - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer); + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer); break; } @@ -440,19 +562,6 @@ static inline int vlGrabMacroBlock assert(0); } - vlGrabBlocks - ( - mc, - macroblock->mbx, - macroblock->mby, - macroblock->dct_type, - macroblock->cbp, - macroblock->blocks - ); - - mc->num_macroblocks[mb_type_ex]++; - mc->total_num_macroblocks++; - return 0; } @@ -464,12 +573,51 @@ static int vlFlush struct vlR16SnormBufferedMC *mc; struct pipe_context *pipe; struct vlVertexShaderConsts *vs_consts; + unsigned int num_macroblocks[vlNumMacroBlockExTypes] = {0}; + unsigned int offset[vlNumMacroBlockExTypes]; + unsigned int vb_start = 0; + unsigned int mbw; + unsigned int mbh; + unsigned int num_mb_per_frame; + unsigned int i; - assert(mc); + assert(render); mc = (struct vlR16SnormBufferedMC*)render; + + if (!mc->buffered_surface) + return 0; + + mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; + mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; + num_mb_per_frame = mbw * mbh; + + if (mc->num_macroblocks < num_mb_per_frame) + return 0; + pipe = mc->pipe; + for (i = 0; i < mc->num_macroblocks; ++i) + { + enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]); + + num_macroblocks[mb_type_ex]++; + } + + offset[0] = 0; + + for (i = 1; i < vlNumMacroBlockExTypes; ++i) + offset[i] = offset[i - 1] + num_macroblocks[i - 1]; + + for (i = 0; i < mc->num_macroblocks; ++i) + { + enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]); + + vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]); + + offset[mb_type_ex]++; + } + mc->render_target.cbufs[0] = pipe->screen->get_tex_surface ( pipe->screen, @@ -490,76 +638,82 @@ static int vlFlush vs_consts->denorm.y = mc->buffered_surface->texture->height[0]; pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf); pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf); - if (mc->num_macroblocks[vlMacroBlockExTypeIntra] > 0) + if (num_macroblocks[vlMacroBlockExTypeIntra] > 0) { - pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeIntra]); - pipe->set_vertex_elements(pipe, 1, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->i_vs); pipe->bind_fs_state(pipe, mc->i_fs); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeIntra] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeIntra] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeIntra] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) + if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedFrame]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->p_vs[0]); pipe->bind_fs_state(pipe, mc->p_fs[0]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) + if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedField]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->p_vs[1]); pipe->bind_fs_state(pipe, mc->p_fs[1]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) + if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedFrame]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->p_vs[0]); pipe->bind_fs_state(pipe, mc->p_fs[0]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) + if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedField]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->p_vs[1]); pipe->bind_fs_state(pipe, mc->p_fs[1]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) + if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) { - pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedFrame]); - pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 8, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -567,13 +721,14 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->b_vs[0]); pipe->bind_fs_state(pipe, mc->b_fs[0]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) + if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) { - pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedField]); - pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); + pipe->set_vertex_elements(pipe, 8, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -581,11 +736,17 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->b_vs[1]); pipe->bind_fs_state(pipe, mc->b_fs[1]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24; } - memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); - mc->total_num_macroblocks = 0; + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence); + + for (i = 0; i < 3; ++i) + mc->zero_block[i].x = -1.0f; + + mc->buffered_surface = NULL; + mc->num_macroblocks = 0; mc->cur_buf++; return 0; @@ -607,12 +768,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered if (mc->buffered_surface) { - if - ( - mc->buffered_surface != surface /*|| - mc->past_surface != batch->past_surface || - mc->future_surface != batch->future_surface*/ - ) + if (mc->buffered_surface != surface) { vlFlush(&mc->base); mc->buffered_surface = surface; @@ -654,7 +810,7 @@ static int vlDestroy { struct vlR16SnormBufferedMC *mc; struct pipe_context *pipe; - unsigned int g, h, i; + unsigned int h, i; assert(render); @@ -664,10 +820,9 @@ static int vlDestroy for (i = 0; i < 5; ++i) pipe->delete_sampler_state(pipe, mc->samplers[i]); - for (g = 0; g < NUM_BUF_SETS; ++g) - for (h = 0; h < 7; ++h) + for (h = 0; h < NUM_BUF_SETS; ++h) for (i = 0; i < 3; ++i) - pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[g][h][i].buffer); + pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer); /* Textures 3 & 4 are not created directly, no need to release them here */ for (i = 0; i < NUM_BUF_SETS; ++i) @@ -691,6 +846,7 @@ static int vlDestroy pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer); pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer); + free(mc->macroblocks); free(mc); return 0; @@ -742,9 +898,12 @@ static int vlCreateVertexShaderIMB ti = 3; /* - * decl i0 ; Vertex pos, luma & chroma texcoords + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords */ - for (i = 0; i < 3; i++) + 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); @@ -752,9 +911,11 @@ static int vlCreateVertexShaderIMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords */ - for (i = 0; i < 2; i++) + 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); @@ -762,11 +923,13 @@ static int vlCreateVertexShaderIMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords 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 < 2; ++i) + for (i = 0; i < 4; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + 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); } @@ -814,9 +977,16 @@ static int vlCreateFragmentShaderIMB ti = 3; - /* decl i0 ; Luma/chroma texcoords */ - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* + * 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); @@ -844,14 +1014,14 @@ static int vlCreateFragmentShaderIMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 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); @@ -860,7 +1030,6 @@ static int vlCreateFragmentShaderIMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } /* mul o0, t0, c0 ; Rescale texel to correct range */ @@ -912,11 +1081,14 @@ static int vlCreateVertexShaderFramePMB ti = 3; /* - * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; Ref surface top field texcoords - * decl i2 ; Ref surface bottom field texcoords (unused, packed in the same stream) + * 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 < 3; i++) + 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); @@ -924,10 +1096,12 @@ static int vlCreateVertexShaderFramePMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; Ref macroblock texcoords + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; Ref macroblock texcoords */ - for (i = 0; i < 3; i++) + 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); @@ -935,16 +1109,18 @@ static int vlCreateVertexShaderFramePMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords 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 < 2; ++i) + for (i = 0; i < 4; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + 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 o2, i0, i1 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 1); + /* 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); /* end */ @@ -992,55 +1168,62 @@ static int vlCreateVertexShaderFieldPMB ti = 3; /* - * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; Ref surface top field texcoords - * decl i2 ; Ref surface bottom field texcoords + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; Ref macroblock top field texcoords + * decl i5 ; Ref macroblock bottom field texcoords */ - for (i = 0; i < 3; i++) + 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); } - /* decl c0 ; Texcoord denorm coefficients */ + /* decl c0 ; Render target dimensions */ decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; Top field ref macroblock texcoords - * decl o3 ; Bottom field ref macroblock texcoords - * decl o4 ; Denormalized vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; Ref macroblock top field texcoords + * decl o5 ; Ref macroblock bottom field texcoords + * decl o6 ; Denormalized vertex pos */ - for (i = 0; i < 5; i++) + for (i = 0; i < 7; i++) { - decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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); } /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords 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 < 3; ++i) + for (i = 0; i < 4; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i == 0 ? 0 : i - 1); + 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 o2, i0, i1 ; Translate vertex pos by motion vec to form top field macroblock texcoords - * add o3, i0, i2 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords + * add o4, i0, i4 ; Translate vertex pos by motion vec to form top field macroblock texcoords + * add o5, i0, i5 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords */ for (i = 0; i < 2; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* mul o4, i0, c0 ; Denorm vertex pos */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + /* mul o6, i0, c0 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ @@ -1088,10 +1271,12 @@ static int vlCreateFragmentShaderFramePMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; Ref macroblock texcoords */ - for (i = 0; i < 2; ++i) + 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); @@ -1124,14 +1309,14 @@ static int vlCreateFragmentShaderFramePMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 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); @@ -1140,15 +1325,14 @@ static int vlCreateFragmentShaderFramePMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.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, i1, s3 ; Read texel from ref macroblock */ - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 1, TGSI_FILE_SAMPLER, 3); + /* 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 */ @@ -1200,12 +1384,14 @@ static int vlCreateFragmentShaderFieldPMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 - * decl i2 ; Texcoords for s3 - * decl i3 ; Denormalized vertex pos + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; Ref macroblock top field texcoords + * decl i4 ; Ref macroblock bottom field texcoords + * decl i5 ; Denormalized vertex pos */ - for (i = 0; i < 4; ++i) + for (i = 0; i < 6; ++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); @@ -1241,14 +1427,14 @@ static int vlCreateFragmentShaderFieldPMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 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); @@ -1257,7 +1443,6 @@ static int vlCreateFragmentShaderFieldPMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.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 */ @@ -1265,18 +1450,18 @@ static int vlCreateFragmentShaderFieldPMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t1, i1, s3 ; Read texel from ref macroblock top field - * tex2d t2, i2, s3 ; Read texel from ref macroblock bottom field + * tex2d t1, i3, s3 ; Read texel from ref macroblock top field + * tex2d t2, i4, s3 ; Read texel from ref macroblock bottom field */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* XXX: Pos values off by 0.5? */ - /* sub t4, i3.y, c1.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 3, TGSI_FILE_CONSTANT, 1); + /* sub t4, i5.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1365,13 +1550,16 @@ static int vlCreateVertexShaderFrameBMB ti = 3; /* - * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; First ref surface top field texcoords - * decl i2 ; First ref surface bottom field texcoords (unused, packed in the same stream) - * decl i3 ; Second ref surface top field texcoords - * decl i4 ; Second ref surface bottom field texcoords (unused, packed in the same stream) + * 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 < 5; i++) + 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); @@ -1379,11 +1567,13 @@ static int vlCreateVertexShaderFrameBMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; First ref macroblock texcoords - * decl o3 ; Second ref macroblock texcoords + * 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 < 4; i++) + 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); @@ -1391,21 +1581,23 @@ static int vlCreateVertexShaderFrameBMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords 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 < 2; ++i) + for (i = 0; i < 4; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + 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 o2, i0, i1 ; Translate vertex pos by motion vec to form first ref macroblock texcoords - * add o3, i0, i3 ; Translate vertex pos by motion vec to form second ref macroblock texcoords + * 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 */ for (i = 0; i < 2; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i * 2 + 1); + 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); } @@ -1454,34 +1646,39 @@ static int vlCreateVertexShaderFieldBMB ti = 3; /* - * decl i0 ; Vertex pos, Luma/chroma texcoords - * decl i1 ; First ref surface top field texcoords - * decl i2 ; First ref surface bottom field texcoords - * decl i3 ; Second ref surface top field texcoords - * decl i4 ; Second ref surface bottom field texcoords + * 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 + * decl i6 ; Second ref macroblock top field texcoords + * decl i7 ; Second ref macroblock bottom field texcoords */ - for (i = 0; i < 5; i++) + 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 c0 ; Denorm coefficients */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6); + /* decl c0 ; Render target dimensions */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; Top field past ref macroblock texcoords - * decl o3 ; Bottom field past ref macroblock texcoords - * decl o4 ; Top field future ref macroblock texcoords - * decl o5 ; Bottom field future ref macroblock texcoords - * decl o6 ; Denormalized vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; First ref macroblock top field texcoords + * decl o5 ; First ref macroblock Bottom field texcoords + * decl o6 ; Second ref macroblock top field texcoords + * decl o7 ; Second ref macroblock Bottom field texcoords + * decl o8 ; Denormalized vertex pos */ - for (i = 0; i < 7; i++) + for (i = 0; i < 9; i++) { - decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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); } @@ -1491,32 +1688,30 @@ static int vlCreateVertexShaderFieldBMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords to output - * mov o2, i1 ; Move past top field texcoords to output - * mov o3, i2 ; Move past bottom field texcoords to output - * mov o4, i3 ; Move future top field texcoords to output - * mov o5, i4 ; Move future bottom field texcoords 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 < 6; ++i) + for (i = 0; i < 4; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + 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 o2, i0, i1 ; Translate vertex pos by motion vec to form first top field macroblock texcoords - * add o3, i0, i2 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords - * add o4, i0, i3 ; Translate vertex pos by motion vec to form second top field macroblock texcoords - * add o5, i0, i4 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords + * add o4, i0, i4 ; Translate vertex pos by motion vec to form first top field macroblock texcoords + * add o5, i0, i5 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords + * add o6, i0, i6 ; Translate vertex pos by motion vec to form second top field macroblock texcoords + * add o7, i0, i7 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords */ for (i = 0; i < 4; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* mul o6, i0, c0 ; Denorm vertex pos */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + /* mul o8, i0, c0 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 8, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ @@ -1564,11 +1759,13 @@ static int vlCreateFragmentShaderFrameBMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 - * decl i2 ; Texcoords for s4 + * 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 < 3; ++i) + 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); @@ -1593,8 +1790,8 @@ static int vlCreateFragmentShaderFrameBMB * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for past ref surface texture - * decl s4 ; Sampler for future ref surface texture + * decl s3 ; Sampler for first ref surface texture + * decl s4 ; Sampler for second ref surface texture */ for (i = 0; i < 5; ++i) { @@ -1605,14 +1802,14 @@ static int vlCreateFragmentShaderFrameBMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 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); @@ -1621,7 +1818,6 @@ static int vlCreateFragmentShaderFrameBMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.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 */ @@ -1629,12 +1825,12 @@ static int vlCreateFragmentShaderFrameBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t1, i1, s3 ; Read texel from past ref macroblock - * tex2d t2, i2, s4 ; Read texel from future ref macroblock + * 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 + 1, TGSI_FILE_SAMPLER, i + 3); + 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); } @@ -1695,14 +1891,16 @@ static int vlCreateFragmentShaderFieldBMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 - * decl i2 ; Texcoords for s3 - * decl i3 ; Texcoords for s4 - * decl i4 ; Texcoords for s4 - * decl i5 ; Denormalized vertex pos + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; First ref macroblock top field texcoords + * decl i4 ; First ref macroblock bottom field texcoords + * decl i5 ; Second ref macroblock top field texcoords + * decl i6 ; Second ref macroblock bottom field texcoords + * decl i7 ; Denormalized vertex pos */ - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++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); @@ -1728,8 +1926,8 @@ static int vlCreateFragmentShaderFieldBMB * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for past ref surface texture - * decl s4 ; Sampler for future ref surface texture + * decl s3 ; Sampler for first ref surface texture + * decl s4 ; Sampler for second ref surface texture */ for (i = 0; i < 5; ++i) { @@ -1740,14 +1938,14 @@ static int vlCreateFragmentShaderFieldBMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 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); @@ -1756,7 +1954,6 @@ static int vlCreateFragmentShaderFieldBMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.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 */ @@ -1764,8 +1961,8 @@ static int vlCreateFragmentShaderFieldBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* XXX: Pos values off by 0.5? */ - /* sub t4, i5.y, c1.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1); + /* sub t4, i7.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 7, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1801,12 +1998,12 @@ static int vlCreateFragmentShaderFieldBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t1, i1, s3 ; Read texel from past ref macroblock top field - * tex2d t2, i2, s3 ; Read texel from past ref macroblock bottom field + * tex2d t1, i3, s3 ; Read texel from past ref macroblock top field + * tex2d t2, i4, s3 ; Read texel from past ref macroblock bottom field */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1816,12 +2013,12 @@ static int vlCreateFragmentShaderFieldBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t4, i3, s4 ; Read texel from future ref macroblock top field - * tex2d t5, i4, s4 ; Read texel from future ref macroblock bottom field + * tex2d t4, i5, s4 ; Read texel from future ref macroblock top field + * tex2d t5, i6, s4 ; Read texel from future ref macroblock bottom field */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 4); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 5, TGSI_FILE_SAMPLER, 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1858,85 +2055,94 @@ static int vlCreateDataBufs struct vlR16SnormBufferedMC *mc ) { - const unsigned int mbw = align(mc->video_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; - const unsigned int mbh = align(mc->video_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; + const unsigned int mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; + const unsigned int mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; const unsigned int num_mb_per_frame = mbw * mbh; struct pipe_context *pipe; - unsigned int g, h, i; + unsigned int h, i; assert(mc); pipe = mc->pipe; - for (g = 0; g < NUM_BUF_SETS; ++g) + /* Create our vertex buffers */ + for (h = 0; h < NUM_BUF_SETS; ++h) { - for (h = 0; h < 7; ++h) + mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f) * 4; + mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[h][0].buffer_offset = 0; + mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame + ); + + for (i = 1; i < 3; ++i) { - /* Create our vertex buffer and vertex buffer element */ - mc->vertex_bufs[g][h][0].pitch = sizeof(struct vlVertex2f); - mc->vertex_bufs[g][h][0].max_index = 24 * num_mb_per_frame - 1; - mc->vertex_bufs[g][h][0].buffer_offset = 0; - mc->vertex_bufs[g][h][0].buffer = pipe->winsys->buffer_create + mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2; + mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[h][i].buffer_offset = 0; + mc->vertex_bufs[h][i].buffer = pipe->winsys->buffer_create ( pipe->winsys, 1, PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct vlVertex2f) * 24 * num_mb_per_frame + sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame ); } } - /* Position & block luma, block chroma texcoord element */ + /* Position element */ mc->vertex_elems[0].src_offset = 0; mc->vertex_elems[0].vertex_buffer_index = 0; mc->vertex_elems[0].nr_components = 2; mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; - for (g = 0; g < NUM_BUF_SETS; ++g) - { - for (h = 0; h < 7; ++h) - { - for (i = 1; i < 3; ++i) - { - mc->vertex_bufs[g][h][i].pitch = sizeof(struct vlVertex2f) * 2; - mc->vertex_bufs[g][h][i].max_index = 24 * num_mb_per_frame - 1; - mc->vertex_bufs[g][h][i].buffer_offset = 0; - mc->vertex_bufs[g][h][i].buffer = pipe->winsys->buffer_create - ( - pipe->winsys, - 1, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame - ); - } - } - } - - /* First ref surface top field texcoord element */ - mc->vertex_elems[1].src_offset = 0; - mc->vertex_elems[1].vertex_buffer_index = 1; + /* Luma, texcoord element */ + mc->vertex_elems[1].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[1].vertex_buffer_index = 0; mc->vertex_elems[1].nr_components = 2; mc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* First ref surface bottom field texcoord element */ - mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f); - mc->vertex_elems[2].vertex_buffer_index = 1; + /* Chroma Cr texcoord element */ + mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f) * 2; + mc->vertex_elems[2].vertex_buffer_index = 0; mc->vertex_elems[2].nr_components = 2; mc->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Second ref surface top field texcoord element */ - mc->vertex_elems[3].src_offset = 0; - mc->vertex_elems[3].vertex_buffer_index = 2; + /* Chroma Cb texcoord element */ + mc->vertex_elems[3].src_offset = sizeof(struct vlVertex2f) * 3; + mc->vertex_elems[3].vertex_buffer_index = 0; mc->vertex_elems[3].nr_components = 2; mc->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Second ref surface bottom field texcoord element */ - mc->vertex_elems[4].src_offset = sizeof(struct vlVertex2f); - mc->vertex_elems[4].vertex_buffer_index = 2; + /* First ref surface top field texcoord element */ + mc->vertex_elems[4].src_offset = 0; + mc->vertex_elems[4].vertex_buffer_index = 1; mc->vertex_elems[4].nr_components = 2; mc->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT; + /* First ref surface bottom field texcoord element */ + mc->vertex_elems[5].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[5].vertex_buffer_index = 1; + mc->vertex_elems[5].nr_components = 2; + mc->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface top field texcoord element */ + mc->vertex_elems[6].src_offset = 0; + mc->vertex_elems[6].vertex_buffer_index = 2; + mc->vertex_elems[6].nr_components = 2; + mc->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface bottom field texcoord element */ + mc->vertex_elems[7].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[7].vertex_buffer_index = 2; + mc->vertex_elems[7].nr_components = 2; + mc->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT; + /* Create our constant buffer */ mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); mc->vs_const_buf.buffer = pipe->winsys->buffer_create @@ -1965,6 +2171,8 @@ static int vlCreateDataBufs pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer); + mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame); + return 0; } @@ -1984,8 +2192,8 @@ static int vlInit pipe = mc->pipe; /* For MC we render to textures, which are rounded up to nearest POT */ - mc->viewport.scale[0] = vlRoundUpPOT(mc->video_width); - mc->viewport.scale[1] = vlRoundUpPOT(mc->video_height); + mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width); + mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height); mc->viewport.scale[2] = 1; mc->viewport.scale[3] = 1; mc->viewport.translate[0] = 0; @@ -1993,16 +2201,16 @@ static int vlInit mc->viewport.translate[2] = 0; mc->viewport.translate[3] = 0; - mc->render_target.width = vlRoundUpPOT(mc->video_width); - mc->render_target.height = vlRoundUpPOT(mc->video_height); + mc->render_target.width = vlRoundUpPOT(mc->picture_width); + mc->render_target.height = vlRoundUpPOT(mc->picture_height); mc->render_target.num_cbufs = 1; /* FB for MC stage is a vlSurface created by the user, set at render time */ mc->render_target.zsbuf = NULL; filters[0] = PIPE_TEX_FILTER_NEAREST; /* FIXME: Linear causes discoloration around block edges */ - filters[1] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; - filters[2] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; + filters[1] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; + filters[2] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; filters[3] = PIPE_TEX_FILTER_LINEAR; filters[4] = PIPE_TEX_FILTER_LINEAR; @@ -2031,8 +2239,8 @@ static int vlInit template.target = PIPE_TEXTURE_2D; template.format = PIPE_FORMAT_R16_SNORM; template.last_level = 0; - template.width[0] = vlRoundUpPOT(mc->video_width); - template.height[0] = vlRoundUpPOT(mc->video_height); + template.width[0] = vlRoundUpPOT(mc->picture_width); + template.height[0] = vlRoundUpPOT(mc->picture_height); template.depth[0] = 1; template.compressed = 0; pf_get_block(template.format, &template.block); @@ -2040,13 +2248,13 @@ static int vlInit for (i = 0; i < NUM_BUF_SETS; ++i) mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template); - if (mc->video_format == vlFormatYCbCr420) + if (mc->picture_format == vlFormatYCbCr420) { - template.width[0] = vlRoundUpPOT(mc->video_width / 2); - template.height[0] = vlRoundUpPOT(mc->video_height / 2); + template.width[0] = vlRoundUpPOT(mc->picture_width / 2); + template.height[0] = vlRoundUpPOT(mc->picture_height / 2); } - else if (mc->video_format == vlFormatYCbCr422) - template.height[0] = vlRoundUpPOT(mc->video_height / 2); + else if (mc->picture_format == vlFormatYCbCr422) + template.height[0] = vlRoundUpPOT(mc->picture_height / 2); for (i = 0; i < NUM_BUF_SETS; ++i) { @@ -2074,13 +2282,14 @@ static int vlInit int vlCreateR16SNormBufferedMC ( struct pipe_context *pipe, - unsigned int video_width, - unsigned int video_height, - enum vlFormat video_format, + unsigned int picture_width, + unsigned int picture_height, + enum vlFormat picture_format, struct vlRender **render ) { - struct vlR16SnormBufferedMC *mc; + struct vlR16SnormBufferedMC *mc; + unsigned int i; assert(pipe); assert(render); @@ -2093,15 +2302,16 @@ int vlCreateR16SNormBufferedMC mc->base.vlFlush = &vlFlush; mc->base.vlDestroy = &vlDestroy; mc->pipe = pipe; - mc->video_width = video_width; - mc->video_height = video_height; + mc->picture_width = picture_width; + mc->picture_height = picture_height; mc->cur_buf = 0; mc->buffered_surface = NULL; mc->past_surface = NULL; mc->future_surface = NULL; - memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); - mc->total_num_macroblocks = 0; + for (i = 0; i < 3; ++i) + mc->zero_block[i].x = -1.0f; + mc->num_macroblocks = 0; vlInit(mc);