vl_vertex_buffers.c revision bfb4fb057d92869f98dc627d53d3e1b7d031d93f
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 <pipe/p_context.h>
30#include <pipe/p_screen.h>
31#include <util/u_memory.h>
32#include <util/u_inlines.h>
33#include <util/u_format.h>
34#include "vl_vertex_buffers.h"
35#include "vl_types.h"
36
37/* vertices for a quad covering a block */
38static const struct quadf const_quad = {
39   {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}
40};
41
42struct pipe_vertex_buffer
43vl_vb_upload_quads(struct pipe_context *pipe, unsigned max_blocks, struct pipe_vertex_element* element)
44{
45   struct pipe_vertex_buffer quad;
46   struct pipe_transfer *buf_transfer;
47   struct quadf *v;
48
49   unsigned i;
50
51   assert(pipe);
52   assert(max_blocks);
53   assert(element);
54
55   /* setup rectangle element */
56   element->src_offset = 0;
57   element->instance_divisor = 0;
58   element->vertex_buffer_index = 0;
59   element->src_format = PIPE_FORMAT_R32G32_FLOAT;
60
61   /* create buffer */
62   quad.stride = sizeof(struct vertex2f);
63   quad.max_index = 4 * max_blocks - 1;
64   quad.buffer_offset = 0;
65   quad.buffer = pipe_buffer_create
66   (
67      pipe->screen,
68      PIPE_BIND_VERTEX_BUFFER,
69      sizeof(struct vertex2f) * 4 * max_blocks
70   );
71
72   if(!quad.buffer)
73      return quad;
74
75   /* and fill it */
76   v = pipe_buffer_map
77   (
78      pipe,
79      quad.buffer,
80      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
81      &buf_transfer
82   );
83
84   for ( i = 0; i < max_blocks; ++i)
85     memcpy(v + i, &const_quad, sizeof(const_quad));
86
87   pipe_buffer_unmap(pipe, quad.buffer, buf_transfer);
88
89   return quad;
90}
91
92struct pipe_vertex_buffer
93vl_vb_create_buffer(struct pipe_context *pipe, unsigned max_blocks,
94                    struct pipe_vertex_element *elements, unsigned num_elements,
95                    unsigned vertex_buffer_index)
96{
97   struct pipe_vertex_buffer buf;
98   unsigned i, size = 0;
99
100   for ( i = 0; i < num_elements; ++i ) {
101      elements[i].src_offset = size;
102      elements[i].instance_divisor = 0;
103      elements[i].vertex_buffer_index = vertex_buffer_index;
104      size += util_format_get_blocksize(elements[i].src_format);
105   }
106
107   buf.stride = size;
108   buf.max_index = 4 * max_blocks - 1;
109   buf.buffer_offset = 0;
110   buf.buffer = pipe_buffer_create
111   (
112      pipe->screen,
113      PIPE_BIND_VERTEX_BUFFER,
114      size * 4 * max_blocks
115   );
116
117   return buf;
118}
119
120bool
121vl_vb_init(struct vl_vertex_buffer *buffer, unsigned max_blocks, unsigned num_elements)
122{
123   assert(buffer);
124
125   buffer->num_verts = 0;
126   buffer->num_elements = num_elements;
127   buffer->buffer = MALLOC(max_blocks * num_elements * sizeof(float) * 4);
128   return buffer->buffer != NULL;
129}
130
131unsigned
132vl_vb_upload(struct vl_vertex_buffer *buffer, void *dst)
133{
134   unsigned todo;
135
136   assert(buffer);
137
138   todo = buffer->num_verts;
139   buffer->num_verts = 0;
140
141   if(todo)
142      memcpy(dst, buffer->buffer, sizeof(float) * buffer->num_elements * todo);
143
144   return todo;
145}
146
147void
148vl_vb_cleanup(struct vl_vertex_buffer *buffer)
149{
150   assert(buffer);
151
152   FREE(buffer->buffer);
153}
154