2 #include "intel_be_device.h"
4 #include "pipe/internal/p_winsys_screen.h"
5 #include "pipe/p_defines.h"
6 #include "pipe/p_state.h"
7 #include "pipe/p_inlines.h"
8 #include "util/u_memory.h"
9 #include "util/u_debug.h"
10 #include "util/u_math.h"
12 #include "intel_be_fence.h"
14 #include "i915simple/i915_winsys.h"
15 #include "softpipe/sp_winsys.h"
17 #include "intel_be_api.h"
20 #define I915_TILING_X 1
27 intel_be_buffer_map(struct pipe_winsys
*winsys
,
28 struct pipe_buffer
*buf
,
31 struct intel_be_buffer
*buffer
= intel_be_buffer(buf
);
32 drm_intel_bo
*bo
= intel_bo(buf
);
36 if (flags
& PIPE_BUFFER_USAGE_DONTBLOCK
) {
37 /* Remove this when drm_intel_bo_map supports DONTBLOCK
42 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
45 if (buffer
->map_count
)
49 ret
= drm_intel_gem_bo_map_gtt(bo
);
51 ret
= drm_intel_bo_map(bo
, write
);
53 buffer
->ptr
= bo
->virtual;
64 intel_be_buffer_unmap(struct pipe_winsys
*winsys
,
65 struct pipe_buffer
*buf
)
67 struct intel_be_buffer
*buffer
= intel_be_buffer(buf
);
69 if (--buffer
->map_count
)
73 drm_intel_gem_bo_unmap_gtt(intel_bo(buf
));
75 drm_intel_bo_unmap(intel_bo(buf
));
79 intel_be_buffer_destroy(struct pipe_buffer
*buf
)
81 drm_intel_bo_unreference(intel_bo(buf
));
85 static struct pipe_buffer
*
86 intel_be_buffer_create(struct pipe_winsys
*winsys
,
91 struct intel_be_buffer
*buffer
= CALLOC_STRUCT(intel_be_buffer
);
92 struct intel_be_device
*dev
= intel_be_device(winsys
);
93 drm_intel_bufmgr
*pool
;
99 pipe_reference_init(&buffer
->base
.reference
, 1);
100 buffer
->base
.alignment
= alignment
;
101 buffer
->base
.usage
= usage
;
102 buffer
->base
.size
= size
;
103 buffer
->flinked
= FALSE
;
105 buffer
->map_gtt
= FALSE
;
107 if (usage
& I915_BUFFER_USAGE_SCANOUT
) {
109 name
= "gallium3d_scanout";
110 pool
= dev
->pools
.gem
;
111 } else if (usage
& (PIPE_BUFFER_USAGE_VERTEX
| PIPE_BUFFER_USAGE_CONSTANT
)) {
113 name
= "gallium3d_local";
114 pool
= dev
->pools
.gem
;
115 } else if (usage
& PIPE_BUFFER_USAGE_CUSTOM
) {
116 /* For vertex buffers */
117 name
= "gallium3d_internal_vertex";
118 pool
= dev
->pools
.gem
;
120 /* Regular buffers */
121 name
= "gallium3d_regular";
122 pool
= dev
->pools
.gem
;
125 buffer
->bo
= drm_intel_bo_alloc(pool
, name
, size
, alignment
);
126 if (usage
& I915_BUFFER_USAGE_SCANOUT
) {
127 unsigned tiling
= I915_TILING_X
;
128 unsigned stride
= 2048 * 4; /* TODO do something smarter here */
129 drm_intel_bo_set_tiling(buffer
->bo
, &tiling
, stride
);
130 buffer
->map_gtt
= TRUE
;
136 return &buffer
->base
;
143 static struct pipe_buffer
*
144 intel_be_user_buffer_create(struct pipe_winsys
*winsys
, void *ptr
, unsigned bytes
)
146 struct intel_be_buffer
*buffer
= CALLOC_STRUCT(intel_be_buffer
);
147 struct intel_be_device
*dev
= intel_be_device(winsys
);
153 pipe_reference_init(&buffer
->base
.reference
, 1);
154 buffer
->base
.alignment
= 0;
155 buffer
->base
.usage
= 0;
156 buffer
->base
.size
= bytes
;
158 buffer
->bo
= drm_intel_bo_alloc(dev
->pools
.gem
,
159 "gallium3d_user_buffer",
165 ret
= drm_intel_bo_subdata(buffer
->bo
,
171 return &buffer
->base
;
178 static struct pipe_buffer
*
179 intel_be_surface_buffer_create(struct pipe_winsys
*winsys
,
180 unsigned width
, unsigned height
,
181 enum pipe_format format
,
186 struct pipe_format_block block
;
187 unsigned buf_usage
= 0;
188 unsigned buf_stride
= 0;
189 unsigned buf_size
= 0;
191 pf_get_block(format
, &block
);
192 buf_stride
= pf_get_stride(&block
, width
);
193 buf_stride
= align(buf_stride
, 64);
195 if (tex_usage
& PIPE_TEXTURE_USAGE_PRIMARY
) {
196 /* TODO more checks */
197 assert(buf_stride
<= 2048*4);
198 assert(height
% 8 == 0);
199 buf_stride
= 2048 * 4;
200 buf_usage
|= I915_BUFFER_USAGE_SCANOUT
;
203 buf_size
= buf_stride
* height
;
204 *stride
= buf_stride
;
206 return intel_be_buffer_create(winsys
,
212 static struct pipe_buffer
*
213 intel_be_buffer_from_handle(struct drm_api
*api
,
214 struct pipe_screen
*screen
,
215 const char* name
, unsigned handle
)
217 struct intel_be_device
*dev
= intel_be_device(screen
->winsys
);
218 struct intel_be_buffer
*buffer
= CALLOC_STRUCT(intel_be_buffer
);
223 buffer
->bo
= drm_intel_bo_gem_create_from_name(dev
->pools
.gem
, name
, handle
);
228 pipe_reference_init(&buffer
->base
.reference
, 1);
229 buffer
->base
.screen
= screen
;
230 buffer
->base
.alignment
= buffer
->bo
->align
;
231 buffer
->base
.usage
= PIPE_BUFFER_USAGE_GPU_READ
|
232 PIPE_BUFFER_USAGE_GPU_WRITE
|
233 PIPE_BUFFER_USAGE_CPU_READ
|
234 PIPE_BUFFER_USAGE_CPU_WRITE
;
235 buffer
->base
.size
= buffer
->bo
->size
;
237 return &buffer
->base
;
244 struct pipe_texture
*
245 intel_be_texture_from_shared_handle(struct drm_api
*api
,
246 struct pipe_screen
*screen
,
247 struct pipe_texture
*templ
,
252 struct pipe_buffer
*buffer
;
254 buffer
= intel_be_buffer_from_handle(api
,
261 return screen
->texture_blanket(screen
, templ
, &pitch
, buffer
);
265 intel_be_get_texture_buffer(struct drm_api
*api
,
266 struct pipe_texture
*texture
,
267 struct pipe_buffer
**buffer
,
270 struct intel_be_device
*dev
;
275 dev
= intel_be_device(texture
->screen
->winsys
);
277 return softpipe_get_texture_buffer(texture
, buffer
, stride
);
279 return i915_get_texture_buffer(texture
, buffer
, stride
);
283 intel_be_shared_handle_from_texture(struct drm_api
*api
,
284 struct pipe_screen
*screen
,
285 struct pipe_texture
*texture
,
289 struct pipe_buffer
*buffer
;
290 struct intel_be_buffer
*buf
;
291 if (!intel_be_get_texture_buffer(api
,
297 buf
= intel_be_buffer(buffer
);
299 if (drm_intel_bo_flink(intel_bo(buffer
), &buf
->flink
))
304 *handle
= buf
->flink
;
306 pipe_buffer_reference(&buffer
, NULL
);
312 intel_be_local_handle_from_texture(struct drm_api
*api
,
313 struct pipe_screen
*screen
,
314 struct pipe_texture
*texture
,
318 struct pipe_buffer
*buffer
;
319 if (!intel_be_get_texture_buffer(api
,
325 *handle
= intel_bo(buffer
)->handle
;
327 pipe_buffer_reference(&buffer
, NULL
);
337 intel_be_fence_refunref(struct pipe_winsys
*sws
,
338 struct pipe_fence_handle
**ptr
,
339 struct pipe_fence_handle
*fence
)
341 struct intel_be_fence
**p
= (struct intel_be_fence
**)ptr
;
342 struct intel_be_fence
*f
= (struct intel_be_fence
*)fence
;
344 intel_be_fence_reference(p
, f
);
348 intel_be_fence_signalled(struct pipe_winsys
*sws
,
349 struct pipe_fence_handle
*fence
,
358 intel_be_fence_finish(struct pipe_winsys
*sws
,
359 struct pipe_fence_handle
*fence
,
362 struct intel_be_fence
*f
= (struct intel_be_fence
*)fence
;
364 /* fence already expired */
368 drm_intel_bo_wait_rendering(f
->bo
);
369 drm_intel_bo_unreference(f
->bo
);
380 intel_be_destroy_winsys(struct pipe_winsys
*winsys
)
382 struct intel_be_device
*dev
= intel_be_device(winsys
);
384 drm_intel_bufmgr_destroy(dev
->pools
.gem
);
390 intel_be_init_device(struct intel_be_device
*dev
, int fd
, unsigned id
)
394 dev
->max_batch_size
= 16 * 4096;
395 dev
->max_vertex_size
= 128 * 4096;
397 dev
->base
.buffer_create
= intel_be_buffer_create
;
398 dev
->base
.user_buffer_create
= intel_be_user_buffer_create
;
399 dev
->base
.buffer_map
= intel_be_buffer_map
;
400 dev
->base
.buffer_unmap
= intel_be_buffer_unmap
;
401 dev
->base
.buffer_destroy
= intel_be_buffer_destroy
;
403 /* Used by softpipe */
404 dev
->base
.surface_buffer_create
= intel_be_surface_buffer_create
;
406 dev
->base
.fence_reference
= intel_be_fence_refunref
;
407 dev
->base
.fence_signalled
= intel_be_fence_signalled
;
408 dev
->base
.fence_finish
= intel_be_fence_finish
;
410 dev
->base
.destroy
= intel_be_destroy_winsys
;
412 dev
->pools
.gem
= drm_intel_bufmgr_gem_init(dev
->fd
, dev
->max_batch_size
);
414 dev
->softpipe
= debug_get_bool_option("INTEL_SOFTPIPE", FALSE
);
415 dev
->dump_cmd
= debug_get_bool_option("INTEL_DUMP_CMD", FALSE
);
421 intel_be_get_device_id(unsigned int *device_id
)
428 * FIXME: Fix this up to use a drm ioctl or whatever.
431 snprintf(path
, sizeof(path
), "/sys/class/drm/card0/device/device");
432 file
= fopen(path
, "r");
437 shutup_gcc
= fgets(path
, sizeof(path
), file
);
438 sscanf(path
, "%x", device_id
);
443 intel_be_create_screen(struct drm_api
*api
, int drmFD
,
444 struct drm_create_screen_arg
*arg
)
446 struct intel_be_device
*dev
;
447 struct pipe_screen
*screen
;
448 unsigned int deviceID
;
452 case DRM_CREATE_NORMAL
:
459 /* Allocate the private area */
460 dev
= malloc(sizeof(*dev
));
463 memset(dev
, 0, sizeof(*dev
));
465 intel_be_get_device_id(&deviceID
);
466 intel_be_init_device(dev
, drmFD
, deviceID
);
469 screen
= softpipe_create_screen(&dev
->base
);
471 screen
= i915_create_screen(&dev
->base
, deviceID
);