1 /**************************************************************************
3 * Copyright 2010 Christian König
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 #include <util/u_format.h>
30 #include "vl_vertex_buffers.h"
33 struct vl_vertex_stream
36 uint8_t mb_type_intra
;
37 uint8_t dct_type_field
;
42 struct vl_mv_vertex_stream
44 struct vertex4s mv
[2];
47 /* vertices for a quad covering a block */
48 static const struct vertex2f block_quad
[4] = {
49 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
}
52 struct pipe_vertex_buffer
53 vl_vb_upload_quads(struct pipe_context
*pipe
, unsigned blocks_x
, unsigned blocks_y
)
55 struct pipe_vertex_buffer quad
;
56 struct pipe_transfer
*buf_transfer
;
64 quad
.stride
= sizeof(struct vertex4f
);
65 quad
.buffer_offset
= 0;
66 quad
.buffer
= pipe_buffer_create
69 PIPE_BIND_VERTEX_BUFFER
,
71 sizeof(struct vertex4f
) * 4 * blocks_x
* blocks_y
82 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
86 for ( y
= 0; y
< blocks_y
; ++y
) {
87 for ( x
= 0; x
< blocks_x
; ++x
) {
88 for (i
= 0; i
< 4; ++i
, ++v
) {
89 v
->x
= block_quad
[i
].x
;
90 v
->y
= block_quad
[i
].y
;
98 pipe_buffer_unmap(pipe
, buf_transfer
);
103 struct pipe_vertex_buffer
104 vl_vb_upload_pos(struct pipe_context
*pipe
, unsigned width
, unsigned height
)
106 struct pipe_vertex_buffer pos
;
107 struct pipe_transfer
*buf_transfer
;
115 pos
.stride
= sizeof(struct vertex2s
);
116 pos
.buffer_offset
= 0;
117 pos
.buffer
= pipe_buffer_create
120 PIPE_BIND_VERTEX_BUFFER
,
122 sizeof(struct vertex2s
) * width
* height
133 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
137 for ( y
= 0; y
< height
; ++y
) {
138 for ( x
= 0; x
< width
; ++x
, ++v
) {
144 pipe_buffer_unmap(pipe
, buf_transfer
);
149 static struct pipe_vertex_element
150 vl_vb_get_quad_vertex_element(void)
152 struct pipe_vertex_element element
;
154 /* setup rectangle element */
155 element
.src_offset
= 0;
156 element
.instance_divisor
= 0;
157 element
.vertex_buffer_index
= 0;
158 element
.src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
164 vl_vb_element_helper(struct pipe_vertex_element
* elements
, unsigned num_elements
,
165 unsigned vertex_buffer_index
)
167 unsigned i
, offset
= 0;
169 assert(elements
&& num_elements
);
171 for ( i
= 0; i
< num_elements
; ++i
) {
172 if (elements
[i
].src_offset
)
173 offset
= elements
[i
].src_offset
;
175 elements
[i
].src_offset
= offset
;
176 elements
[i
].instance_divisor
= 1;
177 elements
[i
].vertex_buffer_index
= vertex_buffer_index
;
178 offset
+= util_format_get_blocksize(elements
[i
].src_format
);
183 vl_vb_get_ves_eb(struct pipe_context
*pipe
, int component
)
185 struct pipe_vertex_element vertex_elems
[NUM_VS_INPUTS
];
189 memset(&vertex_elems
, 0, sizeof(vertex_elems
));
190 vertex_elems
[VS_I_RECT
] = vl_vb_get_quad_vertex_element();
192 /* Position element */
193 vertex_elems
[VS_I_VPOS
].src_format
= PIPE_FORMAT_R16G16_SSCALED
;
196 vertex_elems
[VS_I_FLAGS
].src_format
= PIPE_FORMAT_R8G8B8A8_USCALED
;
198 /* empty block element of selected component */
199 vertex_elems
[VS_I_EB
].src_offset
= offsetof(struct vl_vertex_stream
, eb
[component
]);
200 vertex_elems
[VS_I_EB
].src_format
= PIPE_FORMAT_R8G8B8A8_USCALED
;
202 vl_vb_element_helper(&vertex_elems
[VS_I_VPOS
], NUM_VS_INPUTS
- 1, 1);
204 return pipe
->create_vertex_elements_state(pipe
, NUM_VS_INPUTS
, vertex_elems
);
208 vl_vb_get_ves_mv(struct pipe_context
*pipe
)
210 struct pipe_vertex_element vertex_elems
[NUM_VS_INPUTS
];
214 memset(&vertex_elems
, 0, sizeof(vertex_elems
));
215 vertex_elems
[VS_I_RECT
] = vl_vb_get_quad_vertex_element();
217 /* Position element */
218 vertex_elems
[VS_I_VPOS
].src_format
= PIPE_FORMAT_R16G16_SSCALED
;
220 vl_vb_element_helper(&vertex_elems
[VS_I_VPOS
], 1, 1);
222 /* motion vector TOP element */
223 vertex_elems
[VS_I_MV_TOP
].src_format
= PIPE_FORMAT_R16G16B16A16_SSCALED
;
225 /* motion vector BOTTOM element */
226 vertex_elems
[VS_I_MV_BOTTOM
].src_format
= PIPE_FORMAT_R16G16B16A16_SSCALED
;
228 vl_vb_element_helper(&vertex_elems
[VS_I_MV_TOP
], 2, 2);
230 return pipe
->create_vertex_elements_state(pipe
, NUM_VS_INPUTS
, vertex_elems
);
234 vl_vb_init(struct vl_vertex_buffer
*buffer
, struct pipe_context
*pipe
, unsigned width
, unsigned height
)
240 buffer
->width
= width
;
241 buffer
->height
= height
;
242 buffer
->num_instances
= 0;
244 buffer
->resource
= pipe_buffer_create
247 PIPE_BIND_VERTEX_BUFFER
,
249 sizeof(struct vl_vertex_stream
) * width
* height
252 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
253 buffer
->mv
[i
].resource
= pipe_buffer_create
256 PIPE_BIND_VERTEX_BUFFER
,
258 sizeof(struct vl_mv_vertex_stream
) * width
* height
262 vl_vb_map(buffer
, pipe
);
265 struct pipe_vertex_buffer
266 vl_vb_get_ycbcr(struct vl_vertex_buffer
*buffer
)
268 struct pipe_vertex_buffer buf
;
272 buf
.stride
= sizeof(struct vl_vertex_stream
);
273 buf
.buffer_offset
= 0;
274 buf
.buffer
= buffer
->resource
;
279 struct pipe_vertex_buffer
280 vl_vb_get_mv(struct vl_vertex_buffer
*buffer
, int motionvector
)
282 struct pipe_vertex_buffer buf
;
286 buf
.stride
= sizeof(struct vl_mv_vertex_stream
);
287 buf
.buffer_offset
= 0;
288 buf
.buffer
= buffer
->mv
[motionvector
].resource
;
294 vl_vb_map(struct vl_vertex_buffer
*buffer
, struct pipe_context
*pipe
)
298 assert(buffer
&& pipe
);
300 buffer
->buffer
= pipe_buffer_map
304 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
308 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
309 buffer
->mv
[i
].vertex_stream
= pipe_buffer_map
312 buffer
->mv
[i
].resource
,
313 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
314 &buffer
->mv
[i
].transfer
321 get_motion_vectors(enum pipe_mpeg12_motion_type mo_type
, struct pipe_motionvector
*src
, struct vertex4s dst
[2])
323 if (mo_type
== PIPE_MPEG12_MOTION_TYPE_FRAME
) {
324 dst
[0].x
= dst
[1].x
= src
->top
.x
;
325 dst
[0].y
= dst
[1].y
= src
->top
.y
;
326 dst
[0].z
= dst
[1].z
= 0;
329 dst
[0].x
= src
->top
.x
;
330 dst
[0].y
= src
->top
.y
;
331 dst
[0].z
= src
->top
.field_select
? 3 : 1;
333 dst
[1].x
= src
->bottom
.x
;
334 dst
[1].y
= src
->bottom
.y
;
335 dst
[1].z
= src
->bottom
.field_select
? 3 : 1;
338 dst
[0].w
= src
->top
.wheight
;
339 dst
[1].w
= src
->bottom
.wheight
;
343 vl_vb_add_block(struct vl_vertex_buffer
*buffer
, struct pipe_mpeg12_macroblock
*mb
,
344 const unsigned (*empty_block_mask
)[3][2][2])
351 assert(buffer
->num_instances
< buffer
->width
* buffer
->height
);
354 struct vl_vertex_stream
*stream
;
355 stream
= buffer
->buffer
+ buffer
->num_instances
++;
357 stream
->pos
.x
= mb
->mbx
;
358 stream
->pos
.y
= mb
->mby
;
360 for ( i
= 0; i
< 3; ++i
)
361 for ( j
= 0; j
< 2; ++j
)
362 for ( k
= 0; k
< 2; ++k
)
363 stream
->eb
[i
][j
][k
] = !(mb
->cbp
& (*empty_block_mask
)[i
][j
][k
]);
365 stream
->dct_type_field
= mb
->dct_type
== PIPE_MPEG12_DCT_TYPE_FIELD
;
366 stream
->mb_type_intra
= mb
->dct_intra
;
369 mv_pos
= mb
->mbx
+ mb
->mby
* buffer
->width
;
370 get_motion_vectors(mb
->mo_type
, &mb
->mv
[0], buffer
->mv
[0].vertex_stream
[mv_pos
].mv
);
371 get_motion_vectors(mb
->mo_type
, &mb
->mv
[1], buffer
->mv
[1].vertex_stream
[mv_pos
].mv
);
375 vl_vb_unmap(struct vl_vertex_buffer
*buffer
, struct pipe_context
*pipe
)
379 assert(buffer
&& pipe
);
381 pipe_buffer_unmap(pipe
, buffer
->transfer
);
382 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
383 pipe_buffer_unmap(pipe
, buffer
->mv
[i
].transfer
);
388 vl_vb_restart(struct vl_vertex_buffer
*buffer
)
390 unsigned num_instances
;
394 num_instances
= buffer
->num_instances
;
395 buffer
->num_instances
= 0;
396 return num_instances
;
400 vl_vb_cleanup(struct vl_vertex_buffer
*buffer
)
406 pipe_resource_reference(&buffer
->resource
, NULL
);
408 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
409 pipe_resource_reference(&buffer
->mv
[i
].resource
, NULL
);