Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / i965 / brw_resource_buffer.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_resource.h"
10 #include "brw_context.h"
11 #include "brw_batchbuffer.h"
12 #include "brw_winsys.h"
13
14 static boolean
15 brw_buffer_get_handle(struct pipe_screen *screen,
16                       struct pipe_resource *resource,
17                       struct winsys_handle *handle)
18 {
19    return FALSE;
20 }
21
22
23 static void
24 brw_buffer_destroy(struct pipe_screen *screen,
25                     struct pipe_resource *resource)
26 {
27    struct brw_buffer *buf = brw_buffer( resource );
28
29    bo_reference(&buf->bo, NULL);
30    FREE(buf);
31 }
32
33
34 static void *
35 brw_buffer_transfer_map( struct pipe_context *pipe,
36                          struct pipe_transfer *transfer)
37 {
38    struct brw_screen *bscreen = brw_screen(pipe->screen); 
39    struct brw_winsys_screen *sws = bscreen->sws;
40    struct brw_buffer *buf = brw_buffer(transfer->resource);
41    unsigned offset = transfer->box.x;
42    unsigned length = transfer->box.width;
43    unsigned usage = transfer->usage;
44    uint8_t *map;
45
46    if (buf->user_buffer)
47       map = buf->user_buffer;
48    else
49       map = sws->bo_map( buf->bo, 
50                          BRW_DATA_OTHER,
51                          offset,
52                          length,
53                          (usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE,
54                          (usage & PIPE_TRANSFER_DISCARD) ? TRUE : FALSE,
55                          (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) ? TRUE : FALSE);
56
57    return map + offset;
58 }
59
60
61 static void
62 brw_buffer_transfer_flush_region( struct pipe_context *pipe,
63                                   struct pipe_transfer *transfer,
64                                   const struct pipe_box *box)
65 {
66    struct brw_screen *bscreen = brw_screen(pipe->screen); 
67    struct brw_winsys_screen *sws = bscreen->sws;
68    struct brw_buffer *buf = brw_buffer(transfer->resource);
69    unsigned offset = box->x;
70    unsigned length = box->width;
71
72    if (buf->user_buffer)
73       return;
74
75    sws->bo_flush_range( buf->bo, 
76                         offset,
77                         length );
78 }
79
80
81 static void
82 brw_buffer_transfer_unmap( struct pipe_context *pipe,
83                            struct pipe_transfer *transfer)
84 {
85    struct brw_screen *bscreen = brw_screen(pipe->screen); 
86    struct brw_winsys_screen *sws = bscreen->sws;
87    struct brw_buffer *buf = brw_buffer( transfer->resource );
88    
89    if (buf->bo)
90       sws->bo_unmap(buf->bo);
91 }
92
93
94 struct u_resource_vtbl brw_buffer_vtbl = 
95 {
96    brw_buffer_get_handle,            /* get_handle */
97    brw_buffer_destroy,               /* resource_destroy */
98    u_default_get_transfer,           /* get_transfer */
99    u_default_transfer_destroy,       /* transfer_destroy */
100    brw_buffer_transfer_map,          /* transfer_map */
101    brw_buffer_transfer_flush_region,  /* transfer_flush_region */
102    brw_buffer_transfer_unmap,        /* transfer_unmap */
103    u_default_transfer_inline_write   /* transfer_inline_write */
104 };
105
106
107 struct pipe_resource *
108 brw_buffer_create(struct pipe_screen *screen,
109                   const struct pipe_resource *template)
110 {
111    struct brw_screen *bscreen = brw_screen(screen);
112    struct brw_winsys_screen *sws = bscreen->sws;
113    struct brw_buffer *buf;
114    unsigned buffer_type;
115    enum pipe_error ret;
116    
117    buf = CALLOC_STRUCT(brw_buffer);
118    if (!buf)
119       return NULL;
120       
121    buf->b.b = *template;
122    buf->b.vtbl = &brw_buffer_vtbl;
123    pipe_reference_init(&buf->b.b.reference, 1);
124    buf->b.b.screen = screen;
125
126    switch (template->bind & (PIPE_BIND_VERTEX_BUFFER |
127                               PIPE_BIND_INDEX_BUFFER |
128                               PIPE_BIND_CONSTANT_BUFFER))
129    {
130    case PIPE_BIND_VERTEX_BUFFER:
131    case PIPE_BIND_INDEX_BUFFER:
132    case (PIPE_BIND_VERTEX_BUFFER|PIPE_BIND_INDEX_BUFFER):
133       buffer_type = BRW_BUFFER_TYPE_VERTEX;
134       break;
135       
136    case PIPE_BIND_CONSTANT_BUFFER:
137       buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS;
138       break;
139
140    default:
141       buffer_type = BRW_BUFFER_TYPE_GENERIC;
142       break;
143    }
144    
145    ret = sws->bo_alloc( sws, buffer_type,
146                         template->width0,
147                         64,     /* alignment */
148                         &buf->bo );
149    if (ret != PIPE_OK)
150       return NULL;
151       
152    return &buf->b.b; 
153 }
154
155
156 struct pipe_resource *
157 brw_user_buffer_create(struct pipe_screen *screen,
158                        void *ptr,
159                        unsigned bytes,
160                        unsigned bind)
161 {
162    struct brw_buffer *buf;
163    
164    buf = CALLOC_STRUCT(brw_buffer);
165    if (!buf)
166       return NULL;
167    
168    pipe_reference_init(&buf->b.b.reference, 1);
169    buf->b.vtbl = &brw_buffer_vtbl;
170    buf->b.b.screen = screen;
171    buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
172    buf->b.b.usage = PIPE_USAGE_IMMUTABLE;
173    buf->b.b.bind = bind;
174    buf->b.b.width0 = bytes;
175    buf->b.b.height0 = 1;
176    buf->b.b.depth0 = 1;
177    buf->b.b.array_size = 1;
178
179    buf->user_buffer = ptr;
180    
181    return &buf->b.b; 
182 }