0b38885f40c880899f54f6e6d7f91b5ca8637397
[profile/ivi/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 }