r600g: fix "Fixed-Point Data Conversions"
[mesa.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 }