Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Mesa
mesa
Commits
55bce22d
Commit
55bce22d
authored
Apr 10, 2017
by
Jason Ekstrand
Browse files
anv: Use DRM sync objects for external semaphores when available
Reviewed-by:
Lionel Landwerlin
<
lionel.g.landwerlin@intel.com
>
parent
f41a0e4b
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/intel/vulkan/anv_batch_chain.c
View file @
55bce22d
...
...
@@ -957,6 +957,11 @@ struct anv_execbuf {
/* Allocated length of the 'objects' and 'bos' arrays */
uint32_t
array_length
;
uint32_t
fence_count
;
uint32_t
fence_array_length
;
struct
drm_i915_gem_exec_fence
*
fences
;
struct
anv_syncobj
**
syncobjs
;
};
static
void
...
...
@@ -971,6 +976,8 @@ anv_execbuf_finish(struct anv_execbuf *exec,
{
vk_free
(
alloc
,
exec
->
objects
);
vk_free
(
alloc
,
exec
->
bos
);
vk_free
(
alloc
,
exec
->
fences
);
vk_free
(
alloc
,
exec
->
syncobjs
);
}
static
VkResult
...
...
@@ -1061,6 +1068,35 @@ anv_execbuf_add_bo(struct anv_execbuf *exec,
return
VK_SUCCESS
;
}
static
VkResult
anv_execbuf_add_syncobj
(
struct
anv_execbuf
*
exec
,
uint32_t
handle
,
uint32_t
flags
,
const
VkAllocationCallbacks
*
alloc
)
{
assert
(
flags
!=
0
);
if
(
exec
->
fence_count
>=
exec
->
fence_array_length
)
{
uint32_t
new_len
=
MAX2
(
exec
->
fence_array_length
*
2
,
64
);
exec
->
fences
=
vk_realloc
(
alloc
,
exec
->
fences
,
new_len
*
sizeof
(
*
exec
->
fences
),
8
,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND
);
if
(
exec
->
fences
==
NULL
)
return
vk_error
(
VK_ERROR_OUT_OF_HOST_MEMORY
);
exec
->
fence_array_length
=
new_len
;
}
exec
->
fences
[
exec
->
fence_count
]
=
(
struct
drm_i915_gem_exec_fence
)
{
.
handle
=
handle
,
.
flags
=
flags
,
};
exec
->
fence_count
++
;
return
VK_SUCCESS
;
}
static
void
anv_cmd_buffer_process_relocs
(
struct
anv_cmd_buffer
*
cmd_buffer
,
struct
anv_reloc_list
*
list
)
...
...
@@ -1448,6 +1484,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
impl
->
fd
=
-
1
;
break
;
case
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
:
result
=
anv_execbuf_add_syncobj
(
&
execbuf
,
impl
->
syncobj
,
I915_EXEC_FENCE_WAIT
,
&
device
->
alloc
);
if
(
result
!=
VK_SUCCESS
)
return
result
;
break
;
default:
break
;
}
...
...
@@ -1484,6 +1528,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
need_out_fence
=
true
;
break
;
case
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
:
result
=
anv_execbuf_add_syncobj
(
&
execbuf
,
impl
->
syncobj
,
I915_EXEC_FENCE_SIGNAL
,
&
device
->
alloc
);
if
(
result
!=
VK_SUCCESS
)
return
result
;
break
;
default:
break
;
}
...
...
@@ -1497,6 +1549,13 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
setup_empty_execbuf
(
&
execbuf
,
device
);
}
if
(
execbuf
.
fence_count
>
0
)
{
assert
(
device
->
instance
->
physicalDevice
.
has_syncobj
);
execbuf
.
execbuf
.
flags
|=
I915_EXEC_FENCE_ARRAY
;
execbuf
.
execbuf
.
num_cliprects
=
execbuf
.
fence_count
;
execbuf
.
execbuf
.
cliprects_ptr
=
(
uintptr_t
)
execbuf
.
fences
;
}
if
(
in_fence
!=
-
1
)
{
execbuf
.
execbuf
.
flags
|=
I915_EXEC_FENCE_IN
;
execbuf
.
execbuf
.
rsvd2
|=
(
uint32_t
)
in_fence
;
...
...
src/intel/vulkan/anv_device.c
View file @
55bce22d
...
...
@@ -338,6 +338,7 @@ anv_physical_device_init(struct anv_physical_device *device,
device
->
has_exec_async
=
anv_gem_get_param
(
fd
,
I915_PARAM_HAS_EXEC_ASYNC
);
device
->
has_exec_fence
=
anv_gem_get_param
(
fd
,
I915_PARAM_HAS_EXEC_FENCE
);
device
->
has_syncobj
=
anv_gem_get_param
(
fd
,
I915_PARAM_HAS_EXEC_FENCE_ARRAY
);
bool
swizzled
=
anv_gem_get_bit6_swizzle
(
fd
,
I915_TILING_X
);
...
...
src/intel/vulkan/anv_private.h
View file @
55bce22d
...
...
@@ -653,6 +653,7 @@ struct anv_physical_device {
int
cmd_parser_version
;
bool
has_exec_async
;
bool
has_exec_fence
;
bool
has_syncobj
;
uint32_t
eu_total
;
uint32_t
subslice_total
;
...
...
@@ -1742,6 +1743,7 @@ enum anv_semaphore_type {
ANV_SEMAPHORE_TYPE_DUMMY
,
ANV_SEMAPHORE_TYPE_BO
,
ANV_SEMAPHORE_TYPE_SYNC_FILE
,
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
,
};
struct
anv_semaphore_impl
{
...
...
@@ -1760,6 +1762,12 @@ struct anv_semaphore_impl {
* created or because it has been used for a wait, fd will be -1.
*/
int
fd
;
/* Sync object handle when type == AKV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
* Unlike GEM BOs, DRM sync objects aren't deduplicated by the kernel on
* import so we don't need to bother with a userspace cache.
*/
uint32_t
syncobj
;
};
};
...
...
src/intel/vulkan/anv_queue.c
View file @
55bce22d
...
...
@@ -558,19 +558,27 @@ VkResult anv_CreateSemaphore(
semaphore
->
permanent
.
type
=
ANV_SEMAPHORE_TYPE_DUMMY
;
}
else
if
(
handleTypes
&
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
)
{
assert
(
handleTypes
==
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
);
if
(
device
->
instance
->
physicalDevice
.
has_syncobj
)
{
semaphore
->
permanent
.
type
=
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
;
semaphore
->
permanent
.
syncobj
=
anv_gem_syncobj_create
(
device
);
if
(
!
semaphore
->
permanent
.
syncobj
)
{
vk_free2
(
&
device
->
alloc
,
pAllocator
,
semaphore
);
return
vk_error
(
VK_ERROR_OUT_OF_HOST_MEMORY
);
}
}
else
{
semaphore
->
permanent
.
type
=
ANV_SEMAPHORE_TYPE_BO
;
VkResult
result
=
anv_bo_cache_alloc
(
device
,
&
device
->
bo_cache
,
4096
,
&
semaphore
->
permanent
.
bo
);
if
(
result
!=
VK_SUCCESS
)
{
vk_free2
(
&
device
->
alloc
,
pAllocator
,
semaphore
);
return
result
;
}
semaphore
->
permanent
.
type
=
ANV_SEMAPHORE_TYPE_BO
;
VkResult
result
=
anv_bo_cache_alloc
(
device
,
&
device
->
bo_cache
,
4096
,
&
semaphore
->
permanent
.
bo
);
if
(
result
!=
VK_SUCCESS
)
{
vk_free2
(
&
device
->
alloc
,
pAllocator
,
semaphore
);
return
result
;
/* If we're going to use this as a fence, we need to *not* have the
* EXEC_OBJECT_ASYNC bit set.
*/
assert
(
!
(
semaphore
->
permanent
.
bo
->
flags
&
EXEC_OBJECT_ASYNC
));
}
/* If we're going to use this as a fence, we need to *not* have the
* EXEC_OBJECT_ASYNC bit set.
*/
assert
(
!
(
semaphore
->
permanent
.
bo
->
flags
&
EXEC_OBJECT_ASYNC
));
}
else
if
(
handleTypes
&
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
)
{
assert
(
handleTypes
==
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
);
...
...
@@ -606,6 +614,10 @@ anv_semaphore_impl_cleanup(struct anv_device *device,
case
ANV_SEMAPHORE_TYPE_SYNC_FILE
:
close
(
impl
->
fd
);
return
;
case
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
:
anv_gem_syncobj_destroy
(
device
,
impl
->
syncobj
);
return
;
}
unreachable
(
"Invalid semaphore type"
);
...
...
@@ -691,21 +703,38 @@ VkResult anv_ImportSemaphoreFdKHR(
};
switch
(
pImportSemaphoreFdInfo
->
handleType
)
{
case
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
:
{
new_impl
.
type
=
ANV_SEMAPHORE_TYPE_BO
;
VkResult
result
=
anv_bo_cache_import
(
device
,
&
device
->
bo_cache
,
fd
,
4096
,
&
new_impl
.
bo
);
if
(
result
!=
VK_SUCCESS
)
return
result
;
case
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
:
if
(
device
->
instance
->
physicalDevice
.
has_syncobj
)
{
new_impl
.
type
=
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
;
new_impl
.
syncobj
=
anv_gem_syncobj_fd_to_handle
(
device
,
fd
);
if
(
!
new_impl
.
syncobj
)
return
vk_error
(
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR
);
/* From the Vulkan spec:
*
* "Importing semaphore state from a file descriptor transfers
* ownership of the file descriptor from the application to the
* Vulkan implementation. The application must not perform any
* operations on the file descriptor after a successful import."
*
* If the import fails, we leave the file descriptor open.
*/
close
(
pImportSemaphoreFdInfo
->
fd
);
}
else
{
new_impl
.
type
=
ANV_SEMAPHORE_TYPE_BO
;
/* If we're going to use this as a fence, we need to *not* have t
he
* EXEC_OBJECT_ASYNC bit set.
*/
assert
(
!
(
new_impl
.
bo
->
flags
&
EXEC_OBJECT_ASYNC
))
;
VkResult
result
=
anv_bo_cache_import
(
device
,
&
device
->
bo_cac
he
,
fd
,
4096
,
&
new_impl
.
bo
);
if
(
result
!=
VK_SUCCESS
)
return
result
;
/* If we're going to use this as a fence, we need to *not* have the
* EXEC_OBJECT_ASYNC bit set.
*/
assert
(
!
(
new_impl
.
bo
->
flags
&
EXEC_OBJECT_ASYNC
));
}
break
;
}
case
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
:
new_impl
=
(
struct
anv_semaphore_impl
)
{
...
...
@@ -740,6 +769,7 @@ VkResult anv_GetSemaphoreFdKHR(
ANV_FROM_HANDLE
(
anv_device
,
device
,
_device
);
ANV_FROM_HANDLE
(
anv_semaphore
,
semaphore
,
pGetFdInfo
->
semaphore
);
VkResult
result
;
int
fd
;
assert
(
pGetFdInfo
->
sType
==
VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR
);
...
...
@@ -782,6 +812,13 @@ VkResult anv_GetSemaphoreFdKHR(
impl
->
fd
=
-
1
;
return
VK_SUCCESS
;
case
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ
:
fd
=
anv_gem_syncobj_handle_to_fd
(
device
,
impl
->
syncobj
);
if
(
fd
<
0
)
return
vk_error
(
VK_ERROR_TOO_MANY_OBJECTS
);
*
pFd
=
fd
;
break
;
default:
return
vk_error
(
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR
);
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment