#define VL_INTERNAL
#include "vl_r16snorm_mc_buf.h"
#include <assert.h>
-#include <stdlib.h>
#include <pipe/p_context.h>
-#include <pipe/p_winsys.h>
#include <pipe/p_screen.h>
#include <pipe/p_state.h>
#include <pipe/p_inlines.h>
#include <tgsi/tgsi_parse.h>
#include <tgsi/tgsi_build.h>
#include <util/u_math.h>
+#include <util/u_memory.h>
#include "vl_render.h"
#include "vl_shader_build.h"
#include "vl_surface.h"
#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 */
+const unsigned int DEFAULT_BUF_ALIGNMENT = 1;
enum vlMacroBlockTypeEx
{
struct vlVertex4f div;
};
+struct vlMacroBlockVertexStream0
+{
+ struct vlVertex2f pos;
+ struct vlVertex2f luma_tc;
+ struct vlVertex2f cb_tc;
+ struct vlVertex2f cr_tc;
+};
+
struct vlR16SnormBufferedMC
{
struct vlRender base;
- unsigned int picture_width, picture_height;
+ unsigned int picture_width;
+ unsigned int picture_height;
enum vlFormat picture_format;
+ unsigned int macroblocks_per_picture;
- unsigned int cur_buf;
struct vlSurface *buffered_surface;
- struct vlSurface *past_surface, *future_surface;
+ struct vlSurface *past_surface;
+ struct vlSurface *future_surface;
struct vlVertex2f surface_tex_inv_size;
struct vlVertex2f zero_block[3];
unsigned int num_macroblocks;
struct vlMpeg2MacroBlock *macroblocks;
+ struct pipe_transfer *tex_transfer[3];
+ short *texels[3];
struct pipe_context *pipe;
struct pipe_viewport_state viewport;
struct pipe_framebuffer_state render_target;
- struct pipe_sampler_state *samplers[5];
- struct pipe_texture *textures[NUM_BUF_SETS][5];
+
+ union
+ {
+ void *all[5];
+ struct
+ {
+ void *y;
+ void *cb;
+ void *cr;
+ void *ref[2];
+ };
+ } samplers;
+
+ union
+ {
+ struct pipe_texture *all[5];
+ struct
+ {
+ struct pipe_texture *y;
+ struct pipe_texture *cb;
+ struct pipe_texture *cr;
+ struct pipe_texture *ref[2];
+ };
+ } textures;
+
+ union
+ {
+ struct pipe_vertex_buffer all[3];
+ struct
+ {
+ struct pipe_vertex_buffer ycbcr;
+ struct pipe_vertex_buffer ref[2];
+ };
+ } vertex_bufs;
+
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][3];
struct pipe_vertex_element vertex_elems[8];
- struct pipe_constant_buffer vs_const_buf, fs_const_buf;
+ struct pipe_constant_buffer vs_const_buf;
+ struct pipe_constant_buffer fs_const_buf;
};
-static int vlBegin
+static inline int vlBegin
(
struct vlRender *render
)
short *blocks
)
{
- struct pipe_surface *tex_surface;
short *texels;
unsigned int tex_pitch;
unsigned int x, y, tb = 0, sb = 0;
assert(mc);
assert(blocks);
- tex_surface = mc->pipe->screen->get_tex_surface
- (
- mc->pipe->screen,
- mc->textures[mc->cur_buf % NUM_BUF_SETS][0],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
- );
-
- texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE);
- tex_pitch = tex_surface->stride / tex_surface->block.size;
-
- texels += mbpy * tex_pitch + mbpx;
+ tex_pitch = mc->tex_transfer[0]->stride / mc->tex_transfer[0]->block.size;
+ texels = mc->texels[0] + mbpy * tex_pitch + mbpx;
for (y = 0; y < 2; ++y)
{
}
}
- pipe_surface_unmap(tex_surface);
-
/* TODO: Implement 422, 444 */
mbpx >>= 1;
mbpy >>= 1;
for (tb = 0; tb < 2; ++tb)
{
- tex_surface = mc->pipe->screen->get_tex_surface
- (
- mc->pipe->screen,
- mc->textures[mc->cur_buf % NUM_BUF_SETS][tb + 1],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
- );
-
- texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE);
- tex_pitch = tex_surface->stride / tex_surface->block.size;
-
- texels += mbpy * tex_pitch + mbpx;
+ tex_pitch = mc->tex_transfer[tb + 1]->stride / mc->tex_transfer[tb + 1]->block.size;
+ texels = mc->texels[tb + 1] + mbpy * tex_pitch + mbpx;
if ((coded_block_pattern >> (1 - tb)) & 1)
{
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;
{
assert(mc);
assert(macroblock);
+ assert(mc->num_macroblocks < mc->macroblocks_per_picture);
mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx;
mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby;
}
#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, 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].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 inline int vlGrabMacroBlockVB
+static inline int vlGenMacroblockVerts
(
struct vlR16SnormBufferedMC *mc,
struct vlMpeg2MacroBlock *macroblock,
- unsigned int pos
+ unsigned int pos,
+ struct vlMacroBlockVertexStream0 *ycbcr_vb,
+ struct vlVertex2f **ref_vb
)
{
struct vlVertex2f mo_vec[2];
assert(mc);
assert(macroblock);
+ assert(ycbcr_vb);
+ assert(pos < mc->macroblocks_per_picture);
switch (macroblock->mb_type)
{
{
struct vlVertex2f *vb;
- vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
- (
- mc->pipe->winsys,
- mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
- ) + pos * 2 * 24;
+ assert(ref_vb && ref_vb[1]);
+
+ vb = ref_vb[1] + 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;
}
}
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer);
-
/* fall-through */
}
case vlMacroBlockTypeFwdPredicted:
{
struct vlVertex2f *vb;
- vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
- (
- mc->pipe->winsys,
- mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
- ) + pos * 2 * 24;
+ assert(ref_vb && ref_vb[0]);
+
+ vb = ref_vb[0] + pos * 2 * 24;
if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted)
{
}
}
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer);
-
/* fall-through */
}
case vlMacroBlockTypeIntra:
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;
+ struct vlMacroBlockVertexStream0 *vb;
- vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
- (
- mc->pipe->winsys,
- mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
- ) + pos * 24;
+ vb = ycbcr_vb + pos * 24;
SET_BLOCK
(
4, 2, 1, mc->zero_block
);
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer);
-
break;
}
default:
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(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)
+ if (mc->num_macroblocks < mc->macroblocks_per_picture)
return 0;
+ assert(mc->num_macroblocks <= mc->macroblocks_per_picture);
+
pipe = mc->pipe;
for (i = 0; i < mc->num_macroblocks; ++i)
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]);
+ struct vlMacroBlockVertexStream0 *ycbcr_vb;
+ struct vlVertex2f *ref_vb[2];
+
+ ycbcr_vb = (struct vlMacroBlockVertexStream0*)pipe_buffer_map
+ (
+ pipe->screen,
+ mc->vertex_bufs.ycbcr.buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+ );
- vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]);
+ for (i = 0; i < 2; ++i)
+ ref_vb[i] = (struct vlVertex2f*)pipe_buffer_map
+ (
+ pipe->screen,
+ mc->vertex_bufs.ref[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+ );
- offset[mb_type_ex]++;
+ for (i = 0; i < mc->num_macroblocks; ++i)
+ {
+ enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
+
+ vlGenMacroblockVerts(mc, &mc->macroblocks[i], offset[mb_type_ex], ycbcr_vb, ref_vb);
+
+ offset[mb_type_ex]++;
+ }
+
+ pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ycbcr.buffer);
+ for (i = 0; i < 2; ++i)
+ pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ref[i].buffer);
+ }
+
+ for (i = 0; i < 3; ++i)
+ {
+ pipe->screen->transfer_unmap(pipe->screen, mc->tex_transfer[i]);
+ pipe->screen->tex_transfer_destroy(mc->tex_transfer[i]);
}
mc->render_target.cbufs[0] = pipe->screen->get_tex_surface
pipe->set_framebuffer_state(pipe, &mc->render_target);
pipe->set_viewport_state(pipe, &mc->viewport);
- vs_consts = pipe->winsys->buffer_map
+ vs_consts = pipe_buffer_map
(
- pipe->winsys,
+ pipe->screen,
mc->vs_const_buf.buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
vs_consts->denorm.x = mc->buffered_surface->texture->width[0];
vs_consts->denorm.y = mc->buffered_surface->texture->height[0];
- pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer);
+ pipe_buffer_unmap(pipe->screen, 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 (num_macroblocks[vlMacroBlockExTypeIntra] > 0)
{
- pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs.all);
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->set_sampler_textures(pipe, 3, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 3, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->i_vs);
pipe->bind_fs_state(pipe, mc->i_fs);
if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0)
{
- pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
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);
+ mc->textures.ref[0] = mc->past_surface->texture;
+ pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->p_vs[0]);
pipe->bind_fs_state(pipe, mc->p_fs[0]);
if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0)
{
- pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
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);
+ mc->textures.ref[0] = mc->past_surface->texture;
+ pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->p_vs[1]);
pipe->bind_fs_state(pipe, mc->p_fs[1]);
if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0)
{
- pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
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);
+ mc->textures.ref[0] = mc->future_surface->texture;
+ pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->p_vs[0]);
pipe->bind_fs_state(pipe, mc->p_fs[0]);
if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0)
{
- pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
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);
+ mc->textures.ref[0] = mc->future_surface->texture;
+ pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->p_vs[1]);
pipe->bind_fs_state(pipe, mc->p_fs[1]);
if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0)
{
- pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs.all);
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]);
- pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
+ mc->textures.ref[0] = mc->past_surface->texture;
+ mc->textures.ref[1] = mc->future_surface->texture;
+ pipe->set_sampler_textures(pipe, 5, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 5, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->b_vs[0]);
pipe->bind_fs_state(pipe, mc->b_fs[0]);
if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0)
{
- pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+ pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs.all);
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]);
- pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
+ mc->textures.ref[0] = mc->past_surface->texture;
+ mc->textures.ref[1] = mc->future_surface->texture;
+ pipe->set_sampler_textures(pipe, 5, mc->textures.all);
+ pipe->bind_sampler_states(pipe, 5, mc->samplers.all);
pipe->bind_vs_state(pipe, mc->b_vs[1]);
pipe->bind_fs_state(pipe, mc->b_fs[1]);
}
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
+ pipe_surface_reference(&mc->render_target.cbufs[0], NULL);
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;
}
)
{
struct vlR16SnormBufferedMC *mc;
+ bool new_surface = false;
unsigned int i;
assert(render);
if (mc->buffered_surface != surface)
{
vlFlush(&mc->base);
- mc->buffered_surface = surface;
- mc->past_surface = batch->past_surface;
- mc->future_surface = batch->future_surface;
- mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
- mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
+ new_surface = true;
}
}
else
+ new_surface = true;
+
+ if (new_surface)
{
mc->buffered_surface = surface;
mc->past_surface = batch->past_surface;
mc->future_surface = batch->future_surface;
mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
+
+ for (i = 0; i < 3; ++i)
+ {
+ mc->tex_transfer[i] = mc->pipe->screen->get_tex_transfer
+ (
+ mc->pipe->screen,
+ mc->textures.all[i],
+ 0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0,
+ surface->texture->width[0],
+ surface->texture->height[0]
+ );
+
+ mc->texels[i] = mc->pipe->screen->transfer_map(mc->pipe->screen, mc->tex_transfer[i]);
+ }
}
for (i = 0; i < batch->num_macroblocks; ++i)
return 0;
}
-static int vlEnd
+static inline int vlEnd
(
struct vlRender *render
)
{
struct vlR16SnormBufferedMC *mc;
struct pipe_context *pipe;
- unsigned int h, i;
+ unsigned int i;
assert(render);
pipe = mc->pipe;
for (i = 0; i < 5; ++i)
- pipe->delete_sampler_state(pipe, mc->samplers[i]);
+ pipe->delete_sampler_state(pipe, mc->samplers.all[i]);
- for (h = 0; h < NUM_BUF_SETS; ++h)
- for (i = 0; i < 3; ++i)
- pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer);
+ for (i = 0; i < 3; ++i)
+ pipe_buffer_reference(&mc->vertex_bufs.all[i].buffer, NULL);
/* Textures 3 & 4 are not created directly, no need to release them here */
- for (i = 0; i < NUM_BUF_SETS; ++i)
- {
- pipe_texture_release(&mc->textures[i][0]);
- pipe_texture_release(&mc->textures[i][1]);
- pipe_texture_release(&mc->textures[i][2]);
- }
+ for (i = 0; i < 3; ++i)
+ pipe_texture_reference(&mc->textures.all[i], NULL);
pipe->delete_vs_state(pipe, mc->i_vs);
pipe->delete_fs_state(pipe, mc->i_fs);
pipe->delete_fs_state(pipe, mc->b_fs[i]);
}
- pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
- pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
+ pipe_buffer_reference(&mc->vs_const_buf.buffer, NULL);
+ pipe_buffer_reference(&mc->fs_const_buf.buffer, NULL);
- free(mc->macroblocks);
- free(mc);
+ FREE(mc->macroblocks);
+ FREE(mc);
return 0;
}
{0.5f, 2.0f, 0.0f, 0.0f}
};
-static int vlCreateVertexShaderIMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 50;
-
- struct pipe_context *pipe;
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 3;
-
- /*
- * 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);
- }
-
- /*
- * 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);
- }
-
- /*
- * 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);
- }
-
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- vs.tokens = tokens;
- mc->i_vs = pipe->create_vs_state(pipe, &vs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateFragmentShaderIMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 3;
-
- /*
- * 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);
-
- /*
- * 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);
- }
-
- /*
- * 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
- */
- 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.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- 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 */
- 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);
-
- fs.tokens = tokens;
- mc->i_fs = pipe->create_fs_state(pipe, &fs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateVertexShaderFramePMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 3;
-
- /*
- * 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);
- }
-
- /*
- * 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);
- }
-
- /*
- * 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);
- }
-
- /* 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 */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- vs.tokens = tokens;
- mc->p_vs[0] = pipe->create_vs_state(pipe, &vs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateVertexShaderFieldPMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 3;
-
- /*
- * 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 < 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 ; 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 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 < 7; 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, 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);
- }
-
- /*
- * 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 + 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);
- 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);
-
- vs.tokens = tokens;
- mc->p_vs[1] = pipe->create_vs_state(pipe, &vs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateFragmentShaderFramePMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 3;
-
- /*
- * 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);
- }
-
- /* 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);
-
- /*
- * 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
- */
- 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.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- 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, 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);
-
- fs.tokens = tokens;
- mc->p_fs[0] = pipe->create_fs_state(pipe, &fs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateFragmentShaderFieldPMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 200;
-
- struct pipe_context *pipe;
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 3;
-
- /*
- * 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 < 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);
- }
-
- /*
- * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
- * decl c1 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection
- */
- 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-t4 */
- decl = vl_decl_temps(0, 4);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /*
- * 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
- */
- 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.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- 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, 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 + 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, 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;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */
- inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1);
- inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* floor t3, t3 ; Get rid of fractional part */
- inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* mul t3, t3, c1.y ; Multiply by 2 */
- inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1);
- inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */
- inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* TODO: Move to conditional tex fetch on t3 instead of lerp */
- /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
- 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);
-
- fs.tokens = tokens;
- mc->p_fs[1] = pipe->create_fs_state(pipe, &fs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateVertexShaderFrameBMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 3;
-
- /*
- * 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);
- }
-
- /*
- * 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);
- }
-
- /*
- * 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 + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2);
- 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);
-
- vs.tokens = tokens;
- mc->b_vs[0] = pipe->create_vs_state(pipe, &vs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateVertexShaderFieldBMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state vs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
- ti = 3;
-
- /*
- * 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 < 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 ; 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 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 < 9; 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);
- }
-
- /* decl t0, t1 */
- decl = vl_decl_temps(0, 1);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /*
- * 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);
- }
-
- /*
- * 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 + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
-
- /* 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 */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- vs.tokens = tokens;
- mc->b_vs[1] = pipe->create_vs_state(pipe, &vs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateFragmentShaderFrameBMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 100;
-
- struct pipe_context *pipe;
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 3;
-
- /*
- * 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);
-
- /*
- * 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);
- }
-
- /*
- * 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
- */
- 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.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- 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, 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);
- }
-
- /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
- inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.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);
-
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- fs.tokens = tokens;
- mc->b_fs[0] = pipe->create_fs_state(pipe, &fs);
- free(tokens);
-
- return 0;
-}
-
-static int vlCreateFragmentShaderFieldBMB
-(
- struct vlR16SnormBufferedMC *mc
-)
-{
- const unsigned int max_tokens = 200;
-
- struct pipe_context *pipe;
- struct pipe_shader_state fs;
- struct tgsi_token *tokens;
- struct tgsi_header *header;
-
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
-
- unsigned int ti;
- unsigned int i;
-
- assert(mc);
-
- pipe = mc->pipe;
- tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
- /* Version */
- *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
- /* Header */
- header = (struct tgsi_header*)&tokens[1];
- *header = tgsi_build_header();
- /* Processor */
- *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
- ti = 3;
-
- /*
- * 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 < 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);
- }
-
- /*
- * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
- * decl c1 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels
- * ; and for Y-mod-2 top/bottom field selection
- */
- 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-t5 */
- decl = vl_decl_temps(0, 5);
- ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
- /*
- * 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);
- }
-
- /*
- * 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
- */
- 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.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- 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);
-
- /* XXX: Pos values off by 0.5? */
- /* 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;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */
- inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1);
- inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* floor t3, t3 ; Get rid of fractional part */
- inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* mul t3, t3, c1.y ; Multiply by 2 */
- inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1);
- inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
- inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */
- inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /*
- * 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 + 3, TGSI_FILE_SAMPLER, 3);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
-
- /* TODO: Move to conditional tex fetch on t3 instead of lerp */
- /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /*
- * 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 + 5, TGSI_FILE_SAMPLER, 4);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
- }
-
- /* TODO: Move to conditional tex fetch on t3 instead of lerp */
- /* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5);
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
- inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
- inst.FullSrcRegisters[0].SrcRegister.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);
-
- /* end */
- inst = vl_end();
- ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
- fs.tokens = tokens;
- mc->b_fs[1] = pipe->create_fs_state(pipe, &fs);
- free(tokens);
-
- return 0;
-}
+#include "vl_r16snorm_mc_buf_shaders.inc"
static int vlCreateDataBufs
(
{
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 h, i;
+ unsigned int i;
assert(mc);
pipe = mc->pipe;
+ mc->macroblocks_per_picture = mbw * mbh;
/* Create our vertex buffers */
- for (h = 0; h < NUM_BUF_SETS; ++h)
+ mc->vertex_bufs.ycbcr.stride = sizeof(struct vlVertex2f) * 4;
+ mc->vertex_bufs.ycbcr.max_index = 24 * mc->macroblocks_per_picture - 1;
+ mc->vertex_bufs.ycbcr.buffer_offset = 0;
+ mc->vertex_bufs.ycbcr.buffer = pipe_buffer_create
+ (
+ pipe->screen,
+ DEFAULT_BUF_ALIGNMENT,
+ PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
+ sizeof(struct vlVertex2f) * 4 * 24 * mc->macroblocks_per_picture
+ );
+
+ for (i = 1; i < 3; ++i)
{
- 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
+ mc->vertex_bufs.all[i].stride = sizeof(struct vlVertex2f) * 2;
+ mc->vertex_bufs.all[i].max_index = 24 * mc->macroblocks_per_picture - 1;
+ mc->vertex_bufs.all[i].buffer_offset = 0;
+ mc->vertex_bufs.all[i].buffer = pipe_buffer_create
(
- pipe->winsys,
- 1,
- PIPE_BUFFER_USAGE_VERTEX,
- sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame
+ pipe->screen,
+ DEFAULT_BUF_ALIGNMENT,
+ PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
+ sizeof(struct vlVertex2f) * 2 * 24 * mc->macroblocks_per_picture
);
-
- for (i = 1; i < 3; ++i)
- {
- 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) * 2 * 24 * num_mb_per_frame
- );
- }
}
/* Position element */
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
+ mc->vs_const_buf.buffer = pipe_buffer_create
(
- pipe->winsys,
- 1,
- PIPE_BUFFER_USAGE_CONSTANT,
- mc->vs_const_buf.size
+ pipe->screen,
+ DEFAULT_BUF_ALIGNMENT,
+ PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
+ sizeof(struct vlVertexShaderConsts)
);
- mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
- mc->fs_const_buf.buffer = pipe->winsys->buffer_create
+ mc->fs_const_buf.buffer = pipe_buffer_create
(
- pipe->winsys,
- 1,
+ pipe->screen,
+ DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_CONSTANT,
- mc->fs_const_buf.size
+ sizeof(struct vlFragmentShaderConsts)
);
memcpy
(
- pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+ pipe_buffer_map(pipe->screen, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
&fs_consts,
sizeof(struct vlFragmentShaderConsts)
);
- pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
+ pipe_buffer_unmap(pipe->screen, mc->fs_const_buf.buffer);
- mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame);
+ mc->macroblocks = MALLOC(sizeof(struct vlMpeg2MacroBlock) * mc->macroblocks_per_picture);
return 0;
}
pipe = mc->pipe;
+ mc->buffered_surface = NULL;
+ mc->past_surface = NULL;
+ mc->future_surface = NULL;
+ for (i = 0; i < 3; ++i)
+ mc->zero_block[i].x = -1.0f;
+ mc->num_macroblocks = 0;
+
/* For MC we render to textures, which are rounded up to nearest POT */
mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width);
mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height);
mc->render_target.width = vlRoundUpPOT(mc->picture_width);
mc->render_target.height = vlRoundUpPOT(mc->picture_height);
- mc->render_target.num_cbufs = 1;
+ mc->render_target.nr_cbufs = 1;
/* FB for MC stage is a vlSurface created by the user, set at render time */
mc->render_target.zsbuf = NULL;
/*sampler.max_lod = ;*/
/*sampler.border_color[i] = ;*/
/*sampler.max_anisotropy = ;*/
- mc->samplers[i] = pipe->create_sampler_state(pipe, &sampler);
+ mc->samplers.all[i] = pipe->create_sampler_state(pipe, &sampler);
}
memset(&template, 0, sizeof(struct pipe_texture));
template.depth[0] = 1;
template.compressed = 0;
pf_get_block(template.format, &template.block);
+ template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC;
- for (i = 0; i < NUM_BUF_SETS; ++i)
- mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template);
+ mc->textures.y = pipe->screen->texture_create(pipe->screen, &template);
if (mc->picture_format == vlFormatYCbCr420)
{
else if (mc->picture_format == vlFormatYCbCr422)
template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
- for (i = 0; i < NUM_BUF_SETS; ++i)
- {
- mc->textures[i][1] = pipe->screen->texture_create(pipe->screen, &template);
- mc->textures[i][2] = pipe->screen->texture_create(pipe->screen, &template);
- }
+ mc->textures.cb = pipe->screen->texture_create(pipe->screen, &template);
+ mc->textures.cr = pipe->screen->texture_create(pipe->screen, &template);
- /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */
+ /* textures.all[3] & textures.all[4] are assigned from vlSurfaces for P and B macroblocks at render time */
vlCreateVertexShaderIMB(mc);
vlCreateFragmentShaderIMB(mc);
struct vlRender **render
)
{
- struct vlR16SnormBufferedMC *mc;
- unsigned int i;
+ struct vlR16SnormBufferedMC *mc;
assert(pipe);
assert(render);
- mc = calloc(1, sizeof(struct vlR16SnormBufferedMC));
+ mc = CALLOC_STRUCT(vlR16SnormBufferedMC);
mc->base.vlBegin = &vlBegin;
mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16SnormBuffered;
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;
- for (i = 0; i < 3; ++i)
- mc->zero_block[i].x = -1.0f;
- mc->num_macroblocks = 0;
-
vlInit(mc);
*render = &mc->base;