Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angle vulkan #143

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 46 additions & 31 deletions src/intel/vulkan/anv_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ anv_hal_close(struct hw_device_t *dev)
#include <vndk/hardware_buffer.h>
/* See i915_private_android_types.h in minigbm. */
#define HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL 0x100
#define HAL_PIXEL_FORMAT_NV12_LINEAR_CAMERA_INTEL 0x10F

enum {
/* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
Expand All @@ -114,10 +115,9 @@ inline VkFormat
vk_format_from_android(unsigned android_format, unsigned android_usage)
{
switch (android_format) {
case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
return VK_FORMAT_R8G8B8_UNORM;
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
case HAL_PIXEL_FORMAT_NV12_LINEAR_CAMERA_INTEL:
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
case AHARDWAREBUFFER_FORMAT_YV12:
return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
Expand Down Expand Up @@ -318,6 +318,30 @@ anv_import_ahw_memory(VkDevice device_h,
#endif
}

VkResult
anv_android_get_tiling(struct anv_device *device,
struct u_gralloc_buffer_handle *gr_handle,
enum isl_tiling *tiling_out)
{
assert(device->u_gralloc);

struct u_gralloc_buffer_basic_info buf_info;
if (u_gralloc_get_buffer_basic_info(device->u_gralloc, gr_handle, &buf_info))
return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"failed to get tiling from gralloc buffer info");

const struct isl_drm_modifier_info *mod_info =
isl_drm_modifier_get_info(buf_info.modifier);
if (!mod_info) {
return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"invalid drm modifier from VkNativeBufferANDROID "
"gralloc buffer info 0x%"PRIx64"", buf_info.modifier);
}

*tiling_out = mod_info->tiling;
return VK_SUCCESS;
}

VkResult
anv_image_init_from_gralloc(struct anv_device *device,
struct anv_image *image,
Expand All @@ -338,19 +362,13 @@ anv_image_init_from_gralloc(struct anv_device *device,
*/
int dma_buf = gralloc_info->handle->data[0];

/* We need to set the WRITE flag on window system buffers so that GEM will
* know we're writing to them and synchronize uses on other rings (for
* example, if the display server uses the blitter ring).
*
* If this function fails and if the imported bo was resident in the cache,
/* If this function fails and if the imported bo was resident in the cache,
* we should avoid updating the bo's flags. Therefore, we defer updating
* the flags until success is certain.
*
*/
result = anv_device_import_bo(device, dma_buf,
ANV_BO_ALLOC_EXTERNAL |
ANV_BO_ALLOC_IMPLICIT_SYNC |
ANV_BO_ALLOC_IMPLICIT_WRITE,
ANV_BO_ALLOC_EXTERNAL,
0 /* client_address */,
&bo);
if (result != VK_SUCCESS) {
Expand All @@ -360,21 +378,14 @@ anv_image_init_from_gralloc(struct anv_device *device,

enum isl_tiling tiling;
if (device->u_gralloc) {
struct u_gralloc_buffer_basic_info buf_info;
struct u_gralloc_buffer_handle gr_handle = {
.handle = gralloc_info->handle,
.hal_format = gralloc_info->format,
.pixel_stride = gralloc_info->stride,
};
u_gralloc_get_buffer_basic_info(device->u_gralloc, &gr_handle, &buf_info);
const struct isl_drm_modifier_info *mod_info =
isl_drm_modifier_get_info(buf_info.modifier);
if (mod_info) {
tiling = mod_info->tiling;
} else {
return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"unknown modifier of BO from VkNativeBufferANDROID");
}
result = anv_android_get_tiling(device, &gr_handle, &tiling);
if (result != VK_SUCCESS)
return result;
} else {
/* Fallback to get_tiling API. */
result = anv_device_get_bo_tiling(device, bo, &tiling);
Expand Down Expand Up @@ -440,33 +451,37 @@ anv_image_bind_from_gralloc(struct anv_device *device,
*/
int dma_buf = gralloc_info->handle->data[0];

/* We need to set the WRITE flag on window system buffers so that GEM will
* know we're writing to them and synchronize uses on other rings (for
* example, if the display server uses the blitter ring).
*
* If this function fails and if the imported bo was resident in the cache,
/* If this function fails and if the imported bo was resident in the cache,
* we should avoid updating the bo's flags. Therefore, we defer updating
* the flags until success is certain.
*
*/
struct anv_bo *bo = NULL;
VkResult result = anv_device_import_bo(device, dma_buf,
ANV_BO_ALLOC_EXTERNAL |
ANV_BO_ALLOC_IMPLICIT_SYNC |
ANV_BO_ALLOC_IMPLICIT_WRITE,
ANV_BO_ALLOC_EXTERNAL,
0 /* client_address */,
&bo);
if (result != VK_SUCCESS) {
return vk_errorf(device, result,
"failed to import dma-buf from VkNativeBufferANDROID");
}

uint64_t img_size = image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].memory_range.size;
if (img_size < bo->size) {
VkMemoryRequirements2 mem_reqs = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
};

anv_image_get_memory_requirements(device, image, image->vk.aspects,
&mem_reqs);

VkDeviceSize aligned_image_size =
align64(mem_reqs.memoryRequirements.size,
mem_reqs.memoryRequirements.alignment);

if (bo->size < aligned_image_size) {
result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"dma-buf from VkNativeBufferANDROID is too small for "
"VkImage: %"PRIu64"B < %"PRIu64"B",
bo->size, img_size);
bo->size, aligned_image_size);
anv_device_release_bo(device, bo);
return result;
}
Expand Down
7 changes: 7 additions & 0 deletions src/intel/vulkan/anv_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
struct anv_device_memory;
struct anv_device;
struct anv_image;
struct u_gralloc_buffer_handle;
enum isl_tiling;

VkResult
anv_android_get_tiling(struct anv_device *device,
struct u_gralloc_buffer_handle *gr_handle,
enum isl_tiling *tiling_out);

VkResult anv_image_init_from_gralloc(struct anv_device *device,
struct anv_image *image,
Expand Down
8 changes: 8 additions & 0 deletions src/intel/vulkan/anv_android_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@

#include "anv_android.h"

VkResult
anv_android_get_tiling(struct anv_device *device,
struct u_gralloc_buffer_handle *gr_handle,
enum isl_tiling *tiling_out)
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}

VkResult
anv_image_init_from_gralloc(struct anv_device *device,
struct anv_image *image,
Expand Down
6 changes: 3 additions & 3 deletions src/intel/vulkan/anv_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1968,12 +1968,12 @@ anv_override_engine_counts(int *gc_count, int *g_count, int *c_count, int *v_cou
int g_override = -1;
int c_override = -1;
int v_override = -1;
char *env = getenv("ANV_QUEUE_OVERRIDE");
const char *env_ = os_get_option("ANV_QUEUE_OVERRIDE");

if (env == NULL)
if (env_ == NULL)
return;

env = strdup(env);
char *env = strdup(env_);
char *save = NULL;
char *next = strtok_r(env, ",", &save);
while (next != NULL) {
Expand Down
56 changes: 52 additions & 4 deletions src/intel/vulkan/anv_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,15 @@ anv_image_init(struct anv_device *device, struct anv_image *image,

image->n_planes = anv_get_format_planes(image->vk.format);

#ifdef VK_USE_PLATFORM_ANDROID_KHR
/* In the case of gralloc-backed swap chain image, we don't know the
* layout yet.
*/
if (vk_find_struct_const(pCreateInfo->pNext,
IMAGE_SWAPCHAIN_CREATE_INFO_KHR) != NULL)
return VK_SUCCESS;
#endif

image->from_wsi =
vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA) != NULL;

Expand Down Expand Up @@ -1863,9 +1872,9 @@ VkResult anv_CreateImage(
__LINE__, pCreateInfo->flags);

#ifndef VK_USE_PLATFORM_ANDROID_KHR
/* Ignore swapchain creation info on Android. Since we don't have an
* implementation in Mesa, we're guaranteed to access an Android object
* incorrectly.
/* Skip the WSI common swapchain creation here on Android. Similar to ahw,
* this case is handled by a partial image init and then resolved when the
* image is bound and gralloc info is passed.
*/
const VkImageSwapchainCreateInfoKHR *swapchain_info =
vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
Expand Down Expand Up @@ -1928,7 +1937,14 @@ resolve_ahw_image(struct anv_device *device,

/* Check tiling. */
enum isl_tiling tiling;
result = anv_device_get_bo_tiling(device, mem->bo, &tiling);
const native_handle_t *handle =
AHardwareBuffer_getNativeHandle(mem->vk.ahardware_buffer);
struct u_gralloc_buffer_handle gr_handle = {
.handle = handle,
.hal_format = desc.format,
.pixel_stride = desc.stride,
};
result = anv_android_get_tiling(device, &gr_handle, &tiling);
assert(result == VK_SUCCESS);
isl_tiling_flags_t isl_tiling_flags = (1u << tiling);

Expand All @@ -1949,6 +1965,36 @@ resolve_ahw_image(struct anv_device *device,
#endif
}

static void
resolve_anb_image(struct anv_device *device,
struct anv_image *image,
const VkNativeBufferANDROID *gralloc_info)
{
#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 29
VkResult result;

/* Check tiling. */
enum isl_tiling tiling;
struct u_gralloc_buffer_handle gr_handle = {
.handle = gralloc_info->handle,
.hal_format = gralloc_info->format,
.pixel_stride = gralloc_info->stride,
};
result = anv_android_get_tiling(device, &gr_handle, &tiling);
assert(result == VK_SUCCESS);

isl_tiling_flags_t isl_tiling_flags = (1u << tiling);

/* Now we are able to fill anv_image fields properly and create
* isl_surface for it.
*/
result = add_all_surfaces_implicit_layout(device, image, NULL, gralloc_info->stride,
isl_tiling_flags,
ISL_SURF_USAGE_DISABLE_AUX_BIT);
assert(result == VK_SUCCESS);
#endif
}

void
anv_image_get_memory_requirements(struct anv_device *device,
struct anv_image *image,
Expand Down Expand Up @@ -2359,6 +2405,8 @@ anv_bind_image_memory(struct anv_device *device,
gralloc_info);
if (result != VK_SUCCESS)
return result;

resolve_anb_image(device, image, gralloc_info);
did_bind = true;
break;
}
Expand Down
6 changes: 3 additions & 3 deletions src/intel/vulkan_hasvk/anv_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,12 +875,12 @@ anv_override_engine_counts(int *gc_count, int *g_count, int *c_count)
int gc_override = -1;
int g_override = -1;
int c_override = -1;
char *env = getenv("ANV_QUEUE_OVERRIDE");
const char *env_ = os_get_option("ANV_QUEUE_OVERRIDE");

if (env == NULL)
if (env_ == NULL)
return;

env = strdup(env);
char *env = strdup(env_);
char *save = NULL;
char *next = strtok_r(env, ",", &save);
while (next != NULL) {
Expand Down
18 changes: 14 additions & 4 deletions src/util/os_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ os_log_message(const char *message)
*
* 1) convert to lowercase
* 2) replace '_' with '.'
* 3) if necessary, prepend "mesa."
* 3) replace "MESA_" or prepend with "mesa."
* 4) look for "debug.mesa." prefix
* 5) look for "vendor.mesa." prefix
* 6) look for "mesa." prefix
*
* For example:
* - MESA_EXTENSION_OVERRIDE -> mesa.extension.override
Expand All @@ -167,9 +170,16 @@ os_get_android_option(const char *name)
}
}

int len = property_get(key, os_android_option_value, NULL);
if (len > 1) {
return os_android_option_value;
/* prefixes to search sorted by preference */
const char *prefices[] = { "debug.", "vendor.", "" };
char full_key[PROPERTY_KEY_MAX];
int len = 0;
for (int i = 0; i < ARRAY_SIZE(prefices); i++) {
strlcpy(full_key, prefices[i], PROPERTY_KEY_MAX);
strlcat(full_key, key, PROPERTY_KEY_MAX);
len = property_get(full_key, os_android_option_value, NULL);
if (len > 0)
return os_android_option_value;
}
return NULL;
}
Expand Down
Loading