• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /**************************************************************************
2   *
3   * Copyright 2010 Christian König
4   * All Rights Reserved.
5   *
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:
13   *
14   * The above copyright notice and this permission notice (including the
15   * next paragraph) shall be included in all copies or substantial portions
16   * of the Software.
17   *
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.
25   *
26   **************************************************************************/
27  
28  #include <assert.h>
29  #include "util/u_format.h"
30  #include "vl_vertex_buffers.h"
31  #include "vl_types.h"
32  
33  /* vertices for a quad covering a block */
34  static const struct vertex2f block_quad[4] = {
35     {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
36  };
37  
38  struct pipe_vertex_buffer
vl_vb_upload_quads(struct pipe_context * pipe)39  vl_vb_upload_quads(struct pipe_context *pipe)
40  {
41     struct pipe_vertex_buffer quad;
42     struct pipe_transfer *buf_transfer;
43     struct vertex2f *v;
44  
45     unsigned i;
46  
47     assert(pipe);
48  
49     /* create buffer */
50     quad.stride = sizeof(struct vertex2f);
51     quad.buffer_offset = 0;
52     quad.buffer = pipe_buffer_create
53     (
54        pipe->screen,
55        PIPE_BIND_VERTEX_BUFFER,
56        PIPE_USAGE_STATIC,
57        sizeof(struct vertex2f) * 4
58     );
59     quad.user_buffer = NULL;
60  
61     if(!quad.buffer)
62        return quad;
63  
64     /* and fill it */
65     v = pipe_buffer_map
66     (
67        pipe,
68        quad.buffer,
69        PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
70        &buf_transfer
71     );
72  
73     for (i = 0; i < 4; ++i, ++v) {
74        v->x = block_quad[i].x;
75        v->y = block_quad[i].y;
76     }
77  
78     pipe_buffer_unmap(pipe, buf_transfer);
79  
80     return quad;
81  }
82  
83  struct pipe_vertex_buffer
vl_vb_upload_pos(struct pipe_context * pipe,unsigned width,unsigned height)84  vl_vb_upload_pos(struct pipe_context *pipe, unsigned width, unsigned height)
85  {
86     struct pipe_vertex_buffer pos;
87     struct pipe_transfer *buf_transfer;
88     struct vertex2s *v;
89  
90     unsigned x, y;
91  
92     assert(pipe);
93  
94     /* create buffer */
95     pos.stride = sizeof(struct vertex2s);
96     pos.buffer_offset = 0;
97     pos.buffer = pipe_buffer_create
98     (
99        pipe->screen,
100        PIPE_BIND_VERTEX_BUFFER,
101        PIPE_USAGE_STATIC,
102        sizeof(struct vertex2s) * width * height
103     );
104     pos.user_buffer = NULL;
105  
106     if(!pos.buffer)
107        return pos;
108  
109     /* and fill it */
110     v = pipe_buffer_map
111     (
112        pipe,
113        pos.buffer,
114        PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
115        &buf_transfer
116     );
117  
118     for ( y = 0; y < height; ++y) {
119        for ( x = 0; x < width; ++x, ++v) {
120           v->x = x;
121           v->y = y;
122        }
123     }
124  
125     pipe_buffer_unmap(pipe, buf_transfer);
126  
127     return pos;
128  }
129  
130  static struct pipe_vertex_element
vl_vb_get_quad_vertex_element(void)131  vl_vb_get_quad_vertex_element(void)
132  {
133     struct pipe_vertex_element element;
134  
135     /* setup rectangle element */
136     element.src_offset = 0;
137     element.instance_divisor = 0;
138     element.vertex_buffer_index = 0;
139     element.src_format = PIPE_FORMAT_R32G32_FLOAT;
140  
141     return element;
142  }
143  
144  static void
vl_vb_element_helper(struct pipe_vertex_element * elements,unsigned num_elements,unsigned vertex_buffer_index)145  vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements,
146                       unsigned vertex_buffer_index)
147  {
148     unsigned i, offset = 0;
149  
150     assert(elements && num_elements);
151  
152     for ( i = 0; i < num_elements; ++i ) {
153        elements[i].src_offset = offset;
154        elements[i].instance_divisor = 1;
155        elements[i].vertex_buffer_index = vertex_buffer_index;
156        offset += util_format_get_blocksize(elements[i].src_format);
157     }
158  }
159  
160  void *
vl_vb_get_ves_ycbcr(struct pipe_context * pipe)161  vl_vb_get_ves_ycbcr(struct pipe_context *pipe)
162  {
163     struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
164  
165     assert(pipe);
166  
167     memset(&vertex_elems, 0, sizeof(vertex_elems));
168     vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element();
169  
170     /* Position element */
171     vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
172  
173     /* block num element */
174     vertex_elems[VS_I_BLOCK_NUM].src_format = PIPE_FORMAT_R32_FLOAT;
175  
176     vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 2, 1);
177  
178     return pipe->create_vertex_elements_state(pipe, 3, vertex_elems);
179  }
180  
181  void *
vl_vb_get_ves_mv(struct pipe_context * pipe)182  vl_vb_get_ves_mv(struct pipe_context *pipe)
183  {
184     struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
185  
186     assert(pipe);
187  
188     memset(&vertex_elems, 0, sizeof(vertex_elems));
189     vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element();
190  
191     /* Position element */
192     vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED;
193  
194     vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1);
195  
196     /* motion vector TOP element */
197     vertex_elems[VS_I_MV_TOP].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED;
198  
199     /* motion vector BOTTOM element */
200     vertex_elems[VS_I_MV_BOTTOM].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED;
201  
202     vl_vb_element_helper(&vertex_elems[VS_I_MV_TOP], 2, 2);
203  
204     return pipe->create_vertex_elements_state(pipe, NUM_VS_INPUTS, vertex_elems);
205  }
206  
207  bool
vl_vb_init(struct vl_vertex_buffer * buffer,struct pipe_context * pipe,unsigned width,unsigned height)208  vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe,
209             unsigned width, unsigned height)
210  {
211     unsigned i, size;
212  
213     assert(buffer);
214  
215     buffer->width = width;
216     buffer->height = height;
217  
218     size = width * height;
219  
220     for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
221        buffer->ycbcr[i].resource = pipe_buffer_create
222        (
223           pipe->screen,
224           PIPE_BIND_VERTEX_BUFFER,
225           PIPE_USAGE_STREAM,
226           sizeof(struct vl_ycbcr_block) * size * 4
227        );
228        if (!buffer->ycbcr[i].resource)
229           goto error_ycbcr;
230     }
231  
232     for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
233        buffer->mv[i].resource = pipe_buffer_create
234        (
235           pipe->screen,
236           PIPE_BIND_VERTEX_BUFFER,
237           PIPE_USAGE_STREAM,
238           sizeof(struct vl_motionvector) * size
239        );
240        if (!buffer->mv[i].resource)
241           goto error_mv;
242     }
243  
244     vl_vb_map(buffer, pipe);
245     return true;
246  
247  error_mv:
248     for (i = 0; i < VL_NUM_COMPONENTS; ++i)
249        pipe_resource_reference(&buffer->mv[i].resource, NULL);
250  
251  error_ycbcr:
252     for (i = 0; i < VL_NUM_COMPONENTS; ++i)
253        pipe_resource_reference(&buffer->ycbcr[i].resource, NULL);
254     return false;
255  }
256  
257  unsigned
vl_vb_attributes_per_plock(struct vl_vertex_buffer * buffer)258  vl_vb_attributes_per_plock(struct vl_vertex_buffer *buffer)
259  {
260     return 1;
261  }
262  
263  struct pipe_vertex_buffer
vl_vb_get_ycbcr(struct vl_vertex_buffer * buffer,int component)264  vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component)
265  {
266     struct pipe_vertex_buffer buf;
267  
268     assert(buffer);
269  
270     buf.stride = sizeof(struct vl_ycbcr_block);
271     buf.buffer_offset = 0;
272     buf.buffer = buffer->ycbcr[component].resource;
273     buf.user_buffer = NULL;
274  
275     return buf;
276  }
277  
278  struct pipe_vertex_buffer
vl_vb_get_mv(struct vl_vertex_buffer * buffer,int motionvector)279  vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector)
280  {
281     struct pipe_vertex_buffer buf;
282  
283     assert(buffer);
284  
285     buf.stride = sizeof(struct vl_motionvector);
286     buf.buffer_offset = 0;
287     buf.buffer = buffer->mv[motionvector].resource;
288     buf.user_buffer = NULL;
289  
290     return buf;
291  }
292  
293  void
vl_vb_map(struct vl_vertex_buffer * buffer,struct pipe_context * pipe)294  vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
295  {
296     unsigned i;
297  
298     assert(buffer && pipe);
299  
300     for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
301        buffer->ycbcr[i].vertex_stream = pipe_buffer_map
302        (
303           pipe,
304           buffer->ycbcr[i].resource,
305           PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
306           &buffer->ycbcr[i].transfer
307        );
308     }
309  
310     for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
311        buffer->mv[i].vertex_stream = pipe_buffer_map
312        (
313           pipe,
314           buffer->mv[i].resource,
315           PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
316           &buffer->mv[i].transfer
317        );
318     }
319  
320  }
321  
322  struct vl_ycbcr_block *
vl_vb_get_ycbcr_stream(struct vl_vertex_buffer * buffer,int component)323  vl_vb_get_ycbcr_stream(struct vl_vertex_buffer *buffer, int component)
324  {
325     assert(buffer);
326     assert(component < VL_NUM_COMPONENTS);
327  
328     return buffer->ycbcr[component].vertex_stream;
329  }
330  
331  unsigned
vl_vb_get_mv_stream_stride(struct vl_vertex_buffer * buffer)332  vl_vb_get_mv_stream_stride(struct vl_vertex_buffer *buffer)
333  {
334     assert(buffer);
335  
336     return buffer->width;
337  }
338  
339  struct vl_motionvector *
vl_vb_get_mv_stream(struct vl_vertex_buffer * buffer,int ref_frame)340  vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, int ref_frame)
341  {
342     assert(buffer);
343     assert(ref_frame < VL_MAX_REF_FRAMES);
344  
345     return buffer->mv[ref_frame].vertex_stream;
346  }
347  
348  void
vl_vb_unmap(struct vl_vertex_buffer * buffer,struct pipe_context * pipe)349  vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
350  {
351     unsigned i;
352  
353     assert(buffer && pipe);
354  
355     for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
356        pipe_buffer_unmap(pipe, buffer->ycbcr[i].transfer);
357     }
358  
359     for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
360        pipe_buffer_unmap(pipe, buffer->mv[i].transfer);
361     }
362  }
363  
364  void
vl_vb_cleanup(struct vl_vertex_buffer * buffer)365  vl_vb_cleanup(struct vl_vertex_buffer *buffer)
366  {
367     unsigned i;
368  
369     assert(buffer);
370  
371     for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
372        pipe_resource_reference(&buffer->ycbcr[i].resource, NULL);
373     }
374  
375     for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
376        pipe_resource_reference(&buffer->mv[i].resource, NULL);
377     }
378  }
379