Merge branch 'master' into r300-compiler
[mesa.git] / src / gallium / winsys / drm / intel / gem / intel_drm_buffer.c
1
2 #include "intel_drm_winsys.h"
3 #include "util/u_memory.h"
4
5 #include "i915_drm.h"
6
7 static struct intel_buffer *
8 intel_drm_buffer_create(struct intel_winsys *iws,
9 unsigned size, unsigned alignment,
10 enum intel_buffer_type type)
11 {
12 struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
13 struct intel_drm_winsys *idws = intel_drm_winsys(iws);
14 drm_intel_bufmgr *pool;
15 char *name;
16
17 if (!buf)
18 return NULL;
19
20 buf->magic = 0xDEAD1337;
21 buf->flinked = FALSE;
22 buf->flink = 0;
23 buf->map_gtt = FALSE;
24
25 if (type == INTEL_NEW_TEXTURE) {
26 name = "gallium3d_texture";
27 pool = idws->pools.gem;
28 } else if (type == INTEL_NEW_VERTEX) {
29 name = "gallium3d_vertex";
30 pool = idws->pools.gem;
31 buf->map_gtt = TRUE;
32 } else if (type == INTEL_NEW_SCANOUT) {
33 name = "gallium3d_scanout";
34 pool = idws->pools.gem;
35 buf->map_gtt = TRUE;
36 } else {
37 assert(0);
38 name = "gallium3d_unknown";
39 pool = idws->pools.gem;
40 }
41
42 buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
43
44 if (!buf->bo)
45 goto err;
46
47 return (struct intel_buffer *)buf;
48
49 err:
50 assert(0);
51 FREE(buf);
52 return NULL;
53 }
54
55 static int
56 intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
57 struct intel_buffer *buffer,
58 unsigned stride,
59 enum intel_buffer_tile tile)
60 {
61 assert(I915_TILING_NONE == INTEL_TILE_NONE);
62 assert(I915_TILING_X == INTEL_TILE_X);
63 assert(I915_TILING_Y == INTEL_TILE_Y);
64
65 return drm_intel_bo_set_tiling(intel_bo(buffer), &tile, stride);
66 }
67
68 static void *
69 intel_drm_buffer_map(struct intel_winsys *iws,
70 struct intel_buffer *buffer,
71 boolean write)
72 {
73 struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
74 drm_intel_bo *bo = intel_bo(buffer);
75 int ret = 0;
76
77 assert(bo);
78
79 if (buf->map_count)
80 goto out;
81
82 if (buf->map_gtt)
83 ret = drm_intel_gem_bo_map_gtt(bo);
84 else
85 ret = drm_intel_bo_map(bo, write);
86
87 buf->ptr = bo->virtual;
88
89 assert(ret == 0);
90 out:
91 if (ret)
92 return NULL;
93
94 buf->map_count++;
95 return buf->ptr;
96 }
97
98 static void
99 intel_drm_buffer_unmap(struct intel_winsys *iws,
100 struct intel_buffer *buffer)
101 {
102 struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
103
104 if (--buf->map_count)
105 return;
106
107 if (buf->map_gtt)
108 drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
109 else
110 drm_intel_bo_unmap(intel_bo(buffer));
111 }
112
113 static int
114 intel_drm_buffer_write(struct intel_winsys *iws,
115 struct intel_buffer *buffer,
116 const void *data,
117 size_t size,
118 size_t offset)
119 {
120 struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
121
122 return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
123 }
124
125 static void
126 intel_drm_buffer_destroy(struct intel_winsys *iws,
127 struct intel_buffer *buffer)
128 {
129 drm_intel_bo_unreference(intel_bo(buffer));
130
131 #ifdef DEBUG
132 intel_drm_buffer(buffer)->magic = 0;
133 intel_drm_buffer(buffer)->bo = NULL;
134 #endif
135
136 FREE(buffer);
137 }
138
139 void
140 intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws)
141 {
142 idws->base.buffer_create = intel_drm_buffer_create;
143 idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg;
144 idws->base.buffer_map = intel_drm_buffer_map;
145 idws->base.buffer_unmap = intel_drm_buffer_unmap;
146 idws->base.buffer_write = intel_drm_buffer_write;
147 idws->base.buffer_destroy = intel_drm_buffer_destroy;
148 }