summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c272
-rw-r--r--src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c64
2 files changed, 178 insertions, 158 deletions
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 1583673c5d8..337680a3063 100644
--- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c
+++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c
@@ -17,16 +17,7 @@
#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 = 256;
enum vlMacroBlockTypeEx
{
@@ -56,32 +47,67 @@ 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_surface *tex_surface[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];
- struct pipe_surface *tex_surface[3];
- short *texels[3];
+
+ 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
)
@@ -382,7 +408,7 @@ static inline int vlGrabMacroBlockVB
vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
(
mc->pipe->winsys,
- mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer,
+ mc->vertex_bufs.ref[1].buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
) + pos * 2 * 24;
@@ -411,7 +437,7 @@ static inline int vlGrabMacroBlockVB
}
}
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer);
+ mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ref[1].buffer);
/* fall-through */
}
@@ -423,7 +449,7 @@ static inline int vlGrabMacroBlockVB
vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
(
mc->pipe->winsys,
- mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer,
+ mc->vertex_bufs.ref[0].buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
) + pos * 2 * 24;
@@ -469,7 +495,7 @@ static inline int vlGrabMacroBlockVB
}
}
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer);
+ mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ref[0].buffer);
/* fall-through */
}
@@ -497,7 +523,7 @@ static inline int vlGrabMacroBlockVB
vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
(
mc->pipe->winsys,
- mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer,
+ mc->vertex_bufs.ycbcr.buffer,
PIPE_BUFFER_USAGE_CPU_WRITE
) + pos * 24;
@@ -533,7 +559,7 @@ static inline int vlGrabMacroBlockVB
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);
+ mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ycbcr.buffer);
break;
}
@@ -555,9 +581,6 @@ static int vlFlush
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);
@@ -567,11 +590,7 @@ static int vlFlush
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;
pipe = mc->pipe;
@@ -628,10 +647,10 @@ static int vlFlush
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);
@@ -641,11 +660,11 @@ static int vlFlush
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]);
@@ -655,11 +674,11 @@ static int vlFlush
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]);
@@ -669,11 +688,11 @@ static int vlFlush
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]);
@@ -683,11 +702,11 @@ static int vlFlush
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]);
@@ -697,12 +716,12 @@ static int vlFlush
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]);
@@ -712,12 +731,12 @@ static int vlFlush
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]);
@@ -732,7 +751,6 @@ static int vlFlush
mc->buffered_surface = NULL;
mc->num_macroblocks = 0;
- mc->cur_buf++;
return 0;
}
@@ -745,6 +763,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
)
{
struct vlR16SnormBufferedMC *mc;
+ bool new_surface = false;
unsigned int i;
assert(render);
@@ -756,39 +775,26 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
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];
-
- for (i = 0; i < 3; ++i)
- {
- mc->tex_surface[i] = mc->pipe->screen->get_tex_surface
- (
- mc->pipe->screen,
- mc->textures[mc->cur_buf % NUM_BUF_SETS][i],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
- );
-
- mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE);
- }
+ 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_surface[i] = mc->pipe->screen->get_tex_surface
(
mc->pipe->screen,
- mc->textures[mc->cur_buf % NUM_BUF_SETS][i],
+ mc->textures.all[i],
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
);
@@ -802,7 +808,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
return 0;
}
-static int vlEnd
+static inline int vlEnd
(
struct vlRender *render
)
@@ -819,7 +825,7 @@ static int vlDestroy
{
struct vlR16SnormBufferedMC *mc;
struct pipe_context *pipe;
- unsigned int h, i;
+ unsigned int i;
assert(render);
@@ -827,19 +833,14 @@ static int vlDestroy
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->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs.all[i].buffer);
/* 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_release(&mc->textures.all[i]);
pipe->delete_vs_state(pipe, mc->i_vs);
pipe->delete_fs_state(pipe, mc->i_fs);
@@ -882,42 +883,39 @@ 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.pitch = 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->winsys->buffer_create
+ (
+ pipe->winsys,
+ DEFAULT_BUF_ALIGNMENT,
+ PIPE_BUFFER_USAGE_VERTEX,
+ 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].pitch = 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->winsys->buffer_create
(
pipe->winsys,
- 1,
+ DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_VERTEX,
- sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame
+ 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 */
@@ -973,7 +971,7 @@ static int vlCreateDataBufs
mc->vs_const_buf.buffer = pipe->winsys->buffer_create
(
pipe->winsys,
- 1,
+ DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_CONSTANT,
mc->vs_const_buf.size
);
@@ -982,7 +980,7 @@ static int vlCreateDataBufs
mc->fs_const_buf.buffer = pipe->winsys->buffer_create
(
pipe->winsys,
- 1,
+ DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_CONSTANT,
mc->fs_const_buf.size
);
@@ -996,7 +994,7 @@ static int vlCreateDataBufs
pipe->winsys->buffer_unmap(pipe->winsys, 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;
}
@@ -1016,6 +1014,13 @@ static int vlInit
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);
@@ -1057,7 +1062,7 @@ static int vlInit
/*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));
@@ -1071,8 +1076,7 @@ static int vlInit
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)
{
@@ -1082,13 +1086,10 @@ static int vlInit
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);
@@ -1114,8 +1115,7 @@ int vlCreateR16SNormBufferedMC
struct vlRender **render
)
{
- struct vlR16SnormBufferedMC *mc;
- unsigned int i;
+ struct vlR16SnormBufferedMC *mc;
assert(pipe);
assert(render);
@@ -1131,14 +1131,6 @@ int vlCreateR16SNormBufferedMC
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;
diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c
index d841eb4a044..17c409e1ce5 100644
--- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c
@@ -89,25 +89,10 @@ nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s)
}
}
-static struct pipe_buffer *
-nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
- unsigned usage, unsigned size)
+static uint32_t
+nouveau_flags_from_usage(struct nouveau_context *nv, unsigned usage)
{
- struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
- struct nouveau_context *nv = nvpws->nv;
- struct nouveau_device *dev = nv->nv_screen->device;
- struct nouveau_pipe_buffer *nvbuf;
- uint32_t flags;
-
- nvbuf = calloc(1, sizeof(*nvbuf));
- if (!nvbuf)
- return NULL;
- nvbuf->base.refcount = 1;
- nvbuf->base.alignment = alignment;
- nvbuf->base.usage = usage;
- nvbuf->base.size = size;
-
- flags = NOUVEAU_BO_LOCAL;
+ uint32_t flags = NOUVEAU_BO_LOCAL;
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
@@ -126,6 +111,29 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
flags |= NOUVEAU_BO_GART;
}
+ return flags;
+}
+
+static struct pipe_buffer *
+nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
+ unsigned usage, unsigned size)
+{
+ struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
+ struct nouveau_context *nv = nvpws->nv;
+ struct nouveau_device *dev = nv->nv_screen->device;
+ struct nouveau_pipe_buffer *nvbuf;
+ uint32_t flags;
+
+ nvbuf = calloc(1, sizeof(*nvbuf));
+ if (!nvbuf)
+ return NULL;
+ nvbuf->base.refcount = 1;
+ nvbuf->base.alignment = alignment;
+ nvbuf->base.usage = usage;
+ nvbuf->base.size = size;
+
+ flags = nouveau_flags_from_usage(nv, usage);
+
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
free(nvbuf);
return NULL;
@@ -176,6 +184,26 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
map_flags |= NOUVEAU_BO_WR;
+ if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR &&
+ !nouveau_bo_busy(nvbuf->bo, map_flags)) {
+ /* XXX: Technically incorrect. If the client maps a buffer for write-only
+ * and leaves part of the buffer untouched it probably expects those parts
+ * to remain intact. This is violated because we allocate a whole new buffer
+ * and don't copy the previous buffer's contents, so this optimization is
+ * only valid if the client intends to overwrite the whole buffer.
+ */
+ struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
+ struct nouveau_context *nv = nvpws->nv;
+ struct nouveau_device *dev = nv->nv_screen->device;
+ struct nouveau_bo *rename;
+ uint32_t flags = nouveau_flags_from_usage(nv, buf->usage);
+
+ if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) {
+ nouveau_bo_del(&nvbuf->bo);
+ nvbuf->bo = rename;
+ }
+ }
+
if (nouveau_bo_map(nvbuf->bo, map_flags))
return NULL;
return nvbuf->bo->map;