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_ycbcr_vertex_stream
41 struct vl_mv_vertex_stream
43 struct vertex4s mv
[2];
46 /* vertices for a quad covering a block */
47 static const struct vertex2f block_quad
[4] = {
48 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
}
51 struct pipe_vertex_buffer
52 vl_vb_upload_quads(struct pipe_context
*pipe
)
54 struct pipe_vertex_buffer quad
;
55 struct pipe_transfer
*buf_transfer
;
63 quad
.stride
= sizeof(struct vertex2f
);
64 quad
.buffer_offset
= 0;
65 quad
.buffer
= pipe_buffer_create
68 PIPE_BIND_VERTEX_BUFFER
,
70 sizeof(struct vertex2f
) * 4
81 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
85 for (i
= 0; i
< 4; ++i
, ++v
) {
86 v
->x
= block_quad
[i
].x
;
87 v
->y
= block_quad
[i
].y
;
90 pipe_buffer_unmap(pipe
, buf_transfer
);
95 struct pipe_vertex_buffer
96 vl_vb_upload_pos(struct pipe_context
*pipe
, unsigned width
, unsigned height
)
98 struct pipe_vertex_buffer pos
;
99 struct pipe_transfer
*buf_transfer
;
107 pos
.stride
= sizeof(struct vertex2s
);
108 pos
.buffer_offset
= 0;
109 pos
.buffer
= pipe_buffer_create
112 PIPE_BIND_VERTEX_BUFFER
,
114 sizeof(struct vertex2s
) * width
* height
125 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
129 for ( y
= 0; y
< height
; ++y
) {
130 for ( x
= 0; x
< width
; ++x
, ++v
) {
136 pipe_buffer_unmap(pipe
, buf_transfer
);
141 static struct pipe_vertex_element
142 vl_vb_get_quad_vertex_element(void)
144 struct pipe_vertex_element element
;
146 /* setup rectangle element */
147 element
.src_offset
= 0;
148 element
.instance_divisor
= 0;
149 element
.vertex_buffer_index
= 0;
150 element
.src_format
= PIPE_FORMAT_R32G32_FLOAT
;
156 vl_vb_element_helper(struct pipe_vertex_element
* elements
, unsigned num_elements
,
157 unsigned vertex_buffer_index
)
159 unsigned i
, offset
= 0;
161 assert(elements
&& num_elements
);
163 for ( i
= 0; i
< num_elements
; ++i
) {
164 elements
[i
].src_offset
= offset
;
165 elements
[i
].instance_divisor
= 1;
166 elements
[i
].vertex_buffer_index
= vertex_buffer_index
;
167 offset
+= util_format_get_blocksize(elements
[i
].src_format
);
172 vl_vb_get_ves_ycbcr(struct pipe_context
*pipe
)
174 struct pipe_vertex_element vertex_elems
[NUM_VS_INPUTS
];
178 memset(&vertex_elems
, 0, sizeof(vertex_elems
));
179 vertex_elems
[VS_I_RECT
] = vl_vb_get_quad_vertex_element();
181 /* Position element */
182 vertex_elems
[VS_I_VPOS
].src_format
= PIPE_FORMAT_R8G8B8A8_USCALED
;
184 vl_vb_element_helper(&vertex_elems
[VS_I_VPOS
], 1, 1);
186 return pipe
->create_vertex_elements_state(pipe
, 2, vertex_elems
);
190 vl_vb_get_ves_mv(struct pipe_context
*pipe
)
192 struct pipe_vertex_element vertex_elems
[NUM_VS_INPUTS
];
196 memset(&vertex_elems
, 0, sizeof(vertex_elems
));
197 vertex_elems
[VS_I_RECT
] = vl_vb_get_quad_vertex_element();
199 /* Position element */
200 vertex_elems
[VS_I_VPOS
].src_format
= PIPE_FORMAT_R16G16_SSCALED
;
202 vl_vb_element_helper(&vertex_elems
[VS_I_VPOS
], 1, 1);
204 /* motion vector TOP element */
205 vertex_elems
[VS_I_MV_TOP
].src_format
= PIPE_FORMAT_R16G16B16A16_SSCALED
;
207 /* motion vector BOTTOM element */
208 vertex_elems
[VS_I_MV_BOTTOM
].src_format
= PIPE_FORMAT_R16G16B16A16_SSCALED
;
210 vl_vb_element_helper(&vertex_elems
[VS_I_MV_TOP
], 2, 2);
212 return pipe
->create_vertex_elements_state(pipe
, NUM_VS_INPUTS
, vertex_elems
);
216 vl_vb_init(struct vl_vertex_buffer
*buffer
, struct pipe_context
*pipe
,
217 unsigned width
, unsigned height
)
223 buffer
->width
= width
;
224 buffer
->height
= height
;
226 size
= width
* height
;
228 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
229 buffer
->ycbcr
[i
].num_instances
= 0;
230 buffer
->ycbcr
[i
].resource
= pipe_buffer_create
233 PIPE_BIND_VERTEX_BUFFER
,
235 sizeof(struct vl_ycbcr_vertex_stream
) * size
* 4
239 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
240 buffer
->mv
[i
].resource
= pipe_buffer_create
243 PIPE_BIND_VERTEX_BUFFER
,
245 sizeof(struct vl_mv_vertex_stream
) * size
249 vl_vb_map(buffer
, pipe
);
252 struct pipe_vertex_buffer
253 vl_vb_get_ycbcr(struct vl_vertex_buffer
*buffer
, int component
)
255 struct pipe_vertex_buffer buf
;
259 buf
.stride
= sizeof(struct vl_ycbcr_vertex_stream
);
260 buf
.buffer_offset
= 0;
261 buf
.buffer
= buffer
->ycbcr
[component
].resource
;
266 struct pipe_vertex_buffer
267 vl_vb_get_mv(struct vl_vertex_buffer
*buffer
, int motionvector
)
269 struct pipe_vertex_buffer buf
;
273 buf
.stride
= sizeof(struct vl_mv_vertex_stream
);
274 buf
.buffer_offset
= 0;
275 buf
.buffer
= buffer
->mv
[motionvector
].resource
;
281 vl_vb_map(struct vl_vertex_buffer
*buffer
, struct pipe_context
*pipe
)
285 assert(buffer
&& pipe
);
287 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
288 buffer
->ycbcr
[i
].vertex_stream
= pipe_buffer_map
291 buffer
->ycbcr
[i
].resource
,
292 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
293 &buffer
->ycbcr
[i
].transfer
297 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
298 buffer
->mv
[i
].vertex_stream
= pipe_buffer_map
301 buffer
->mv
[i
].resource
,
302 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
,
303 &buffer
->mv
[i
].transfer
309 void vl_vb_add_ycbcr(struct vl_vertex_buffer
*buffer
,
310 unsigned component
, unsigned x
, unsigned y
,
311 bool intra
, enum pipe_mpeg12_dct_type type
)
313 struct vl_ycbcr_vertex_stream
*stream
;
316 assert(buffer
->ycbcr
[component
].num_instances
< buffer
->width
* buffer
->height
* 4);
318 stream
= buffer
->ycbcr
[component
].vertex_stream
++;
321 stream
->intra
= intra
;
322 stream
->field
= type
== PIPE_MPEG12_DCT_TYPE_FIELD
;
324 buffer
->ycbcr
[component
].num_instances
++;
328 get_motion_vectors(enum pipe_mpeg12_motion_type mo_type
, struct pipe_motionvector
*src
, struct vertex4s dst
[2])
330 if (mo_type
== PIPE_MPEG12_MOTION_TYPE_FRAME
) {
331 dst
[0].x
= dst
[1].x
= src
->top
.x
;
332 dst
[0].y
= dst
[1].y
= src
->top
.y
;
333 dst
[0].z
= dst
[1].z
= 0;
336 dst
[0].x
= src
->top
.x
;
337 dst
[0].y
= src
->top
.y
;
338 dst
[0].z
= src
->top
.field_select
? 3 : 1;
340 dst
[1].x
= src
->bottom
.x
;
341 dst
[1].y
= src
->bottom
.y
;
342 dst
[1].z
= src
->bottom
.field_select
? 3 : 1;
345 dst
[0].w
= src
->top
.wheight
;
346 dst
[1].w
= src
->bottom
.wheight
;
350 vl_vb_add_block(struct vl_vertex_buffer
*buffer
, struct pipe_mpeg12_macroblock
*mb
)
357 mv_pos
= mb
->mbx
+ mb
->mby
* buffer
->width
;
358 get_motion_vectors(mb
->mo_type
, &mb
->mv
[0], buffer
->mv
[0].vertex_stream
[mv_pos
].mv
);
359 get_motion_vectors(mb
->mo_type
, &mb
->mv
[1], buffer
->mv
[1].vertex_stream
[mv_pos
].mv
);
363 vl_vb_unmap(struct vl_vertex_buffer
*buffer
, struct pipe_context
*pipe
)
367 assert(buffer
&& pipe
);
369 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
370 pipe_buffer_unmap(pipe
, buffer
->ycbcr
[i
].transfer
);
373 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
374 pipe_buffer_unmap(pipe
, buffer
->mv
[i
].transfer
);
379 vl_vb_restart(struct vl_vertex_buffer
*buffer
, int component
)
381 unsigned num_instances
;
385 num_instances
= buffer
->ycbcr
[component
].num_instances
;
386 buffer
->ycbcr
[component
].num_instances
= 0;
387 return num_instances
;
391 vl_vb_cleanup(struct vl_vertex_buffer
*buffer
)
397 for (i
= 0; i
< VL_MAX_PLANES
; ++i
) {
398 pipe_resource_reference(&buffer
->ycbcr
[i
].resource
, NULL
);
401 for (i
= 0; i
< VL_MAX_REF_FRAMES
; ++i
) {
402 pipe_resource_reference(&buffer
->mv
[i
].resource
, NULL
);