use a shadow buffer for vertex data to optimize memory access
[mesa.git] / src / gallium / auxiliary / vl / vl_vertex_buffers.c
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 "vl_vertex_buffers.h"
34 #include "vl_types.h"
35
36 /* vertices for a quad covering a block */
37 static const struct quadf const_quad = {
38 {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}
39 };
40
41 struct pipe_vertex_buffer
42 vl_vb_upload_quads(struct pipe_context *pipe, unsigned max_blocks)
43 {
44 struct pipe_vertex_buffer quad;
45 struct pipe_transfer *buf_transfer;
46 struct quadf *v;
47
48 unsigned i;
49
50 assert(pipe);
51 assert(max_blocks);
52
53 /* create buffer */
54 quad.stride = sizeof(struct vertex2f);
55 quad.max_index = 4 * max_blocks - 1;
56 quad.buffer_offset = 0;
57 quad.buffer = pipe_buffer_create
58 (
59 pipe->screen,
60 PIPE_BIND_VERTEX_BUFFER,
61 sizeof(struct vertex2f) * 4 * max_blocks
62 );
63
64 if(!quad.buffer)
65 return quad;
66
67 /* and fill it */
68 v = pipe_buffer_map
69 (
70 pipe,
71 quad.buffer,
72 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
73 &buf_transfer
74 );
75
76 for ( i = 0; i < max_blocks; ++i)
77 memcpy(v + i, &const_quad, sizeof(const_quad));
78
79 pipe_buffer_unmap(pipe, quad.buffer, buf_transfer);
80
81 return quad;
82 }
83
84 bool
85 vl_vb_init(struct vl_vertex_buffer *buffer, unsigned max_blocks)
86 {
87 assert(buffer);
88
89 buffer->num_blocks = 0;
90 buffer->blocks = MALLOC(max_blocks * sizeof(struct quadf));
91 return buffer->blocks != NULL;
92 }
93
94 unsigned
95 vl_vb_upload(struct vl_vertex_buffer *buffer, struct quadf *dst)
96 {
97 unsigned todo;
98
99 assert(buffer);
100
101 todo = buffer->num_blocks;
102 buffer->num_blocks = 0;
103
104 if(todo)
105 memcpy(dst, buffer->blocks, sizeof(struct quadf) * todo);
106
107 return todo;
108 }
109
110 void
111 vl_vb_cleanup(struct vl_vertex_buffer *buffer)
112 {
113 assert(buffer);
114
115 FREE(buffer->blocks);
116 }