r300g: align the height of NPOT textures to POT
[mesa.git] / src / gallium / drivers / i965 / brw_screen_buffers.c
1
2 #include "util/u_memory.h"
3 #include "util/u_math.h"
4
5 #include "pipe/p_state.h"
6 #include "pipe/p_defines.h"
7 #include "util/u_inlines.h"
8
9 #include "brw_screen.h"
10 #include "brw_winsys.h"
11
12
13
14 static void *
15 brw_buffer_map_range( struct pipe_screen *screen,
16 struct pipe_buffer *buffer,
17 unsigned offset,
18 unsigned length,
19 unsigned usage )
20 {
21 struct brw_screen *bscreen = brw_screen(screen);
22 struct brw_winsys_screen *sws = bscreen->sws;
23 struct brw_buffer *buf = brw_buffer( buffer );
24
25 if (buf->user_buffer)
26 return buf->user_buffer;
27
28 return sws->bo_map( buf->bo,
29 BRW_DATA_OTHER,
30 offset,
31 length,
32 (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE,
33 (usage & PIPE_BUFFER_USAGE_DISCARD) ? TRUE : FALSE,
34 (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) ? TRUE : FALSE);
35 }
36
37 static void *
38 brw_buffer_map( struct pipe_screen *screen,
39 struct pipe_buffer *buffer,
40 unsigned usage )
41 {
42 struct brw_screen *bscreen = brw_screen(screen);
43 struct brw_winsys_screen *sws = bscreen->sws;
44 struct brw_buffer *buf = brw_buffer( buffer );
45
46 if (buf->user_buffer)
47 return buf->user_buffer;
48
49 return sws->bo_map( buf->bo,
50 BRW_DATA_OTHER,
51 0,
52 buf->base.size,
53 (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE,
54 FALSE,
55 FALSE);
56 }
57
58
59 static void
60 brw_buffer_flush_mapped_range( struct pipe_screen *screen,
61 struct pipe_buffer *buffer,
62 unsigned offset,
63 unsigned length )
64 {
65 struct brw_screen *bscreen = brw_screen(screen);
66 struct brw_winsys_screen *sws = bscreen->sws;
67 struct brw_buffer *buf = brw_buffer( buffer );
68
69 if (buf->user_buffer)
70 return;
71
72 sws->bo_flush_range( buf->bo,
73 offset,
74 length );
75 }
76
77
78 static void
79 brw_buffer_unmap( struct pipe_screen *screen,
80 struct pipe_buffer *buffer )
81 {
82 struct brw_screen *bscreen = brw_screen(screen);
83 struct brw_winsys_screen *sws = bscreen->sws;
84 struct brw_buffer *buf = brw_buffer( buffer );
85
86 if (buf->bo)
87 sws->bo_unmap(buf->bo);
88 }
89
90 static void
91 brw_buffer_destroy( struct pipe_buffer *buffer )
92 {
93 struct brw_buffer *buf = brw_buffer( buffer );
94
95 assert(!p_atomic_read(&buffer->reference.count));
96
97 bo_reference(&buf->bo, NULL);
98 FREE(buf);
99 }
100
101
102 static struct pipe_buffer *
103 brw_buffer_create(struct pipe_screen *screen,
104 unsigned alignment,
105 unsigned usage,
106 unsigned size)
107 {
108 struct brw_screen *bscreen = brw_screen(screen);
109 struct brw_winsys_screen *sws = bscreen->sws;
110 struct brw_buffer *buf;
111 unsigned buffer_type;
112 enum pipe_error ret;
113
114 buf = CALLOC_STRUCT(brw_buffer);
115 if (!buf)
116 return NULL;
117
118 pipe_reference_init(&buf->base.reference, 1);
119 buf->base.screen = screen;
120 buf->base.alignment = alignment;
121 buf->base.usage = usage;
122 buf->base.size = size;
123
124 switch (usage & (PIPE_BUFFER_USAGE_VERTEX |
125 PIPE_BUFFER_USAGE_INDEX |
126 PIPE_BUFFER_USAGE_PIXEL |
127 PIPE_BUFFER_USAGE_CONSTANT))
128 {
129 case PIPE_BUFFER_USAGE_VERTEX:
130 case PIPE_BUFFER_USAGE_INDEX:
131 case (PIPE_BUFFER_USAGE_VERTEX|PIPE_BUFFER_USAGE_INDEX):
132 buffer_type = BRW_BUFFER_TYPE_VERTEX;
133 break;
134
135 case PIPE_BUFFER_USAGE_PIXEL:
136 buffer_type = BRW_BUFFER_TYPE_PIXEL;
137 break;
138
139 case PIPE_BUFFER_USAGE_CONSTANT:
140 buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS;
141 break;
142
143 default:
144 buffer_type = BRW_BUFFER_TYPE_GENERIC;
145 break;
146 }
147
148 ret = sws->bo_alloc( sws, buffer_type,
149 size, alignment,
150 &buf->bo );
151 if (ret != PIPE_OK)
152 return NULL;
153
154 return &buf->base;
155 }
156
157
158 static struct pipe_buffer *
159 brw_user_buffer_create(struct pipe_screen *screen,
160 void *ptr,
161 unsigned bytes)
162 {
163 struct brw_buffer *buf;
164
165 buf = CALLOC_STRUCT(brw_buffer);
166 if (!buf)
167 return NULL;
168
169 buf->user_buffer = ptr;
170
171 pipe_reference_init(&buf->base.reference, 1);
172 buf->base.screen = screen;
173 buf->base.alignment = 1;
174 buf->base.usage = 0;
175 buf->base.size = bytes;
176
177 return &buf->base;
178 }
179
180
181 boolean brw_is_buffer_referenced_by_bo( struct brw_screen *brw_screen,
182 struct pipe_buffer *buffer,
183 struct brw_winsys_buffer *bo )
184 {
185 struct brw_buffer *buf = brw_buffer(buffer);
186 if (buf->bo == NULL)
187 return FALSE;
188
189 return brw_screen->sws->bo_references( bo, buf->bo );
190 }
191
192
193 void brw_screen_buffer_init(struct brw_screen *brw_screen)
194 {
195 brw_screen->base.buffer_create = brw_buffer_create;
196 brw_screen->base.user_buffer_create = brw_user_buffer_create;
197 brw_screen->base.buffer_map = brw_buffer_map;
198 brw_screen->base.buffer_map_range = brw_buffer_map_range;
199 brw_screen->base.buffer_flush_mapped_range = brw_buffer_flush_mapped_range;
200 brw_screen->base.buffer_unmap = brw_buffer_unmap;
201 brw_screen->base.buffer_destroy = brw_buffer_destroy;
202 }