mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-8608 Vulkan: Cleanup capability checks
(cherry picked from commit 305cf4b2526dc6189e6715e7780ec9d8be44d1c6)
This commit is contained in:
committed by
Alexey Ushakov
parent
df366c74c1
commit
52b213d96c
@@ -546,7 +546,7 @@ final class VKSwToSurfaceBlit extends VKMultiplexedBlit {
|
||||
}
|
||||
|
||||
private static boolean hasCap(VKSurfaceData dst, int cap) {
|
||||
return (dst.getGraphicsConfig().getGPU().getCaps() & cap) != 0;
|
||||
return dst.getGraphicsConfig().getGPU().hasCap(cap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -80,7 +80,7 @@ public final class VKEnv {
|
||||
Options.deviceNumber : 0];
|
||||
// Check whether the presentation is supported.
|
||||
for (VKGPU device : devices) {
|
||||
if ((device.getCaps() & VKGPU.CAP_PRESENTABLE_BIT) != 0 &&
|
||||
if (device.hasCap(VKGPU.CAP_PRESENTABLE_BIT) &&
|
||||
device.getPresentableGraphicsConfigs().findAny().isPresent()) {
|
||||
newState |= PRESENT_BIT;
|
||||
break;
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.util.stream.Stream;
|
||||
public class VKGPU {
|
||||
|
||||
@Native public static final int CAP_PRESENTABLE_BIT = 0x80000000;
|
||||
@Native public static final int CAP_LOGIC_OP_BIT = 0x40000000;
|
||||
@Native public static final int CAP_SAMPLED_4BYTE_BIT = 0; // Considered always supported.
|
||||
@Native public static final int CAP_SAMPLED_3BYTE_BIT = 1;
|
||||
@Native public static final int CAP_SAMPLED_565_BIT = 2;
|
||||
@@ -98,6 +99,10 @@ public class VKGPU {
|
||||
return caps;
|
||||
}
|
||||
|
||||
public boolean hasCap(int cap) {
|
||||
return (caps & cap) == cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the device and return its native handle.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef VKCapabilityUtil_h_Included
|
||||
#define VKCapabilityUtil_h_Included
|
||||
#include "VKUtil.h"
|
||||
|
||||
#define VK_KHR_VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
|
||||
|
||||
// Named entries are layers or extensions, arragned into on-stack linked list.
|
||||
typedef struct VKNamedEntry {
|
||||
pchar name;
|
||||
const void* found; // Pointer to the found struct.
|
||||
struct VKNamedEntry* next; // Pointer to the next entry.
|
||||
} VKNamedEntry;
|
||||
|
||||
#define DEF_NAMED_ENTRY(LIST, NAME) VKNamedEntry NAME = { NAME ## _NAME, NULL, (LIST) }; \
|
||||
if (NAME.name != NULL) (LIST) = &(NAME)
|
||||
|
||||
static void VKNamedEntry_LogAll(pchar what, pchar all, uint32_t count, size_t stride) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " Supported %s:", what)
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (i == 0) J2dRlsTrace(J2D_TRACE_VERBOSE, " ")
|
||||
else J2dRlsTrace(J2D_TRACE_VERBOSE, ", ")
|
||||
J2dRlsTrace(J2D_TRACE_VERBOSE, all)
|
||||
all += stride;
|
||||
}
|
||||
J2dRlsTrace(J2D_TRACE_VERBOSE, "\n")
|
||||
}
|
||||
|
||||
static void VKNamedEntry_LogFound(const VKNamedEntry* list) {
|
||||
for (; list != NULL; list = list->next) {
|
||||
J2dRlsTraceLn2(J2D_TRACE_INFO, " %s = %s", list->name, list->found ? "true" : "false")
|
||||
}
|
||||
}
|
||||
|
||||
static void VKNamedEntry_Match(VKNamedEntry* list, pchar all, uint32_t count, size_t stride) {
|
||||
for (; list != NULL; list = list->next) {
|
||||
pchar check = all;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (strcmp(list->name, check) == 0) {
|
||||
list->found = check;
|
||||
break;
|
||||
}
|
||||
check += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ARRAY(pchar) VKNamedEntry_CollectNames(const VKNamedEntry* list) {
|
||||
ARRAY(pchar) result = NULL;
|
||||
for (; list != NULL; list = list->next) {
|
||||
if (list->found) ARRAY_PUSH_BACK(result) = list->name;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void VKCapabilityUtil_LogErrors(int level, ARRAY(pchar) errors) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(errors); i++) {
|
||||
J2dRlsTraceLn1(level, " %s", errors[i])
|
||||
}
|
||||
}
|
||||
|
||||
#endif //VKCapabilityUtil_h_Included
|
||||
@@ -27,11 +27,14 @@
|
||||
#include <string.h>
|
||||
#include "sun_java2d_vulkan_VKGPU.h"
|
||||
#include "VKUtil.h"
|
||||
#include "VKCapabilityUtil.h"
|
||||
#include "VKEnv.h"
|
||||
#include "VKAllocator.h"
|
||||
#include "VKRenderer.h"
|
||||
#include "VKTexturePool.h"
|
||||
|
||||
#define CAP_PRESENTABLE_BIT sun_java2d_vulkan_VKGPU_CAP_PRESENTABLE_BIT
|
||||
|
||||
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define VK_LITTLE_ENDIAN
|
||||
#endif
|
||||
@@ -71,7 +74,6 @@ static VkBool32 VKDevice_CheckAndAddFormat(VKEnv* vk, VkPhysicalDevice physicalD
|
||||
}
|
||||
|
||||
void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
jint caps = 0;
|
||||
// Query device properties.
|
||||
VkPhysicalDeviceVulkan12Features device12Features = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
||||
@@ -85,43 +87,58 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
VkPhysicalDeviceProperties2 deviceProperties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 };
|
||||
vk->vkGetPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
|
||||
|
||||
// Check features.
|
||||
J2dRlsTrace5(J2D_TRACE_INFO, "\t- %s (%d.%d.%d, %s) ",
|
||||
// Query supported layers.
|
||||
uint32_t layerCount;
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceLayerProperties(physicalDevice, &layerCount, NULL)) return;
|
||||
VkLayerProperties allLayers[layerCount];
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceLayerProperties(physicalDevice, &layerCount, allLayers)) return;
|
||||
|
||||
// Query supported extensions.
|
||||
uint32_t extensionCount;
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, NULL)) return;
|
||||
VkExtensionProperties allExtensions[extensionCount];
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, allExtensions)) return;
|
||||
|
||||
// Check API version.
|
||||
ARRAY(pchar) errors = NULL;
|
||||
jint caps = 0;
|
||||
J2dRlsTraceLn5(J2D_TRACE_INFO, "%s (%d.%d.%d, %s)",
|
||||
(const char *) deviceProperties2.properties.deviceName,
|
||||
VK_API_VERSION_MAJOR(deviceProperties2.properties.apiVersion),
|
||||
VK_API_VERSION_MINOR(deviceProperties2.properties.apiVersion),
|
||||
VK_API_VERSION_PATCH(deviceProperties2.properties.apiVersion),
|
||||
physicalDeviceTypeString(deviceProperties2.properties.deviceType))
|
||||
if (deviceProperties2.properties.apiVersion < REQUIRED_VULKAN_VERSION) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " - unsupported API version, skipped")
|
||||
return;
|
||||
ARRAY_PUSH_BACK(errors) = "Unsupported API version";
|
||||
}
|
||||
|
||||
if (!deviceFeatures2.features.logicOp) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " - hasLogicOp not supported, skipped")
|
||||
return;
|
||||
}
|
||||
if (!device12Features.timelineSemaphore) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " - hasTimelineSemaphore not supported, skipped")
|
||||
return;
|
||||
}
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, "")
|
||||
// Log layers and extensions.
|
||||
VKNamedEntry_LogAll("device layers", allLayers[0].layerName, layerCount, sizeof(VkLayerProperties));
|
||||
VKNamedEntry_LogAll("device extensions", allExtensions[0].extensionName, extensionCount, sizeof(VkExtensionProperties));
|
||||
|
||||
// Check layers.
|
||||
VKNamedEntry* layers = NULL;
|
||||
#ifdef DEBUG
|
||||
DEF_NAMED_ENTRY(layers, VK_KHR_VALIDATION_LAYER);
|
||||
#endif
|
||||
VKNamedEntry_Match(layers, allLayers[0].layerName, layerCount, sizeof(VkLayerProperties));
|
||||
|
||||
// Check extensions.
|
||||
VKNamedEntry* extensions = NULL;
|
||||
DEF_NAMED_ENTRY(extensions, VK_KHR_SWAPCHAIN_EXTENSION);
|
||||
VKNamedEntry_Match(extensions, allExtensions[0].extensionName, extensionCount, sizeof(VkExtensionProperties));
|
||||
|
||||
// Query queue family properties.
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vk->vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
physicalDevice, &queueFamilyCount, NULL);
|
||||
vk->vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, NULL);
|
||||
VkQueueFamilyProperties queueFamilies[queueFamilyCount];
|
||||
vk->vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
physicalDevice, &queueFamilyCount, queueFamilies);
|
||||
vk->vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies);
|
||||
|
||||
// Find a queue family.
|
||||
int64_t queueFamily = -1;
|
||||
for (uint32_t j = 0; j < queueFamilyCount; j++) {
|
||||
VkBool32 presentationSupported = VK_FALSE;
|
||||
if (vk->platformData != NULL && vk->platformData->checkPresentationSupport != NULL) {
|
||||
presentationSupported = vk->platformData->checkPresentationSupport(vk, physicalDevice, j);
|
||||
}
|
||||
VkBool32 presentationSupported = vk->presentationSupported && VK_KHR_SWAPCHAIN_EXTENSION.found &&
|
||||
vk->platformData->checkPresentationSupport(vk, physicalDevice, j);
|
||||
char logFlags[5] = {
|
||||
queueFamilies[j].queueFlags & VK_QUEUE_GRAPHICS_BIT ? 'G' : '-',
|
||||
queueFamilies[j].queueFlags & VK_QUEUE_COMPUTE_BIT ? 'C' : '-',
|
||||
@@ -134,9 +151,9 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
|
||||
// TODO use compute workloads? Separate transfer-only DMA queue?
|
||||
if (queueFamilies[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) { // Queue supports graphics operations.
|
||||
if (!(caps & sun_java2d_vulkan_VKGPU_CAP_PRESENTABLE_BIT) && presentationSupported) {
|
||||
if (!(caps & CAP_PRESENTABLE_BIT) && presentationSupported) {
|
||||
// Queue supports presentation, choose it.
|
||||
caps |= sun_java2d_vulkan_VKGPU_CAP_PRESENTABLE_BIT;
|
||||
caps |= CAP_PRESENTABLE_BIT;
|
||||
queueFamily = j;
|
||||
} else if (queueFamily == -1) {
|
||||
// We have chosen no queue so far, choose this for now.
|
||||
@@ -144,22 +161,20 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (queueFamily == -1) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " --------------------- Suitable queue not found, skipped")
|
||||
return;
|
||||
}
|
||||
if (queueFamily == -1) ARRAY_PUSH_BACK(errors) = "Suitable queue not found";
|
||||
|
||||
// Query supported layers.
|
||||
uint32_t layerCount;
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceLayerProperties(physicalDevice, &layerCount, NULL)) return;
|
||||
VkLayerProperties layers[layerCount];
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceLayerProperties(physicalDevice, &layerCount, layers)) return;
|
||||
// Check features.
|
||||
VKNamedEntry_LogFound(layers);
|
||||
VKNamedEntry_LogFound(extensions);
|
||||
|
||||
// Query supported extensions.
|
||||
uint32_t extensionCount;
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, NULL)) return;
|
||||
VkExtensionProperties extensions[extensionCount];
|
||||
VK_IF_ERROR(vk->vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, extensions)) return;
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, " presentable = %s", (caps & CAP_PRESENTABLE_BIT) ? "true" : "false")
|
||||
if (!(caps & CAP_PRESENTABLE_BIT)) VK_KHR_SWAPCHAIN_EXTENSION.found = NULL;
|
||||
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, " logicOp = %s", deviceFeatures2.features.logicOp ? "true" : "false")
|
||||
if (deviceFeatures2.features.logicOp) caps |= sun_java2d_vulkan_VKGPU_CAP_LOGIC_OP_BIT;
|
||||
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, " timelineSemaphore = %s", device12Features.timelineSemaphore ? "true" : "false")
|
||||
if (!device12Features.timelineSemaphore) ARRAY_PUSH_BACK(errors) = "timelineSemaphore not supported";
|
||||
|
||||
// Query supported formats.
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " Supported device formats:")
|
||||
@@ -171,7 +186,7 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
ARRAY(jint) supportedFormats = NULL;
|
||||
#define CHECK_AND_ADD_FORMAT(FORMAT) VKDevice_CheckAndAddFormat(vk, physicalDevice, &supportedFormats, FORMAT, #FORMAT)
|
||||
if (CHECK_AND_ADD_FORMAT(VK_FORMAT_B8G8R8A8_UNORM) && SRCTYPE_4BYTE->format == VK_FORMAT_UNDEFINED) {
|
||||
supportedFormats[0] |= sun_java2d_vulkan_VKGPU_CAP_PRESENTABLE_BIT; // TODO Check presentation support.
|
||||
supportedFormats[0] |= CAP_PRESENTABLE_BIT; // TODO Check presentation support.
|
||||
*SRCTYPE_4BYTE = (VKSampledSrcType) { VK_FORMAT_B8G8R8A8_UNORM, {
|
||||
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }};
|
||||
}
|
||||
@@ -208,11 +223,8 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
|
||||
// Check sampled formats capabilities.
|
||||
if (SRCTYPE_4BYTE->format == VK_FORMAT_UNDEFINED) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " - 4-byte sampled format not found, skipped")
|
||||
ARRAY_FREE(supportedFormats);
|
||||
return;
|
||||
}
|
||||
caps |= sun_java2d_vulkan_VKGPU_CAP_SAMPLED_4BYTE_BIT;
|
||||
ARRAY_PUSH_BACK(errors) = "4-byte sampled format not found";
|
||||
} else caps |= sun_java2d_vulkan_VKGPU_CAP_SAMPLED_4BYTE_BIT;
|
||||
if (SRCTYPE_3BYTE->format != VK_FORMAT_UNDEFINED) caps |= sun_java2d_vulkan_VKGPU_CAP_SAMPLED_3BYTE_BIT;
|
||||
if (SRCTYPE_565->format != VK_FORMAT_UNDEFINED) caps |= sun_java2d_vulkan_VKGPU_CAP_SAMPLED_565_BIT;
|
||||
if (SRCTYPE_555->format != VK_FORMAT_UNDEFINED) caps |= sun_java2d_vulkan_VKGPU_CAP_SAMPLED_555_BIT;
|
||||
@@ -222,61 +234,21 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
vk->vkGetPhysicalDeviceFormatProperties(physicalDevice, VK_FORMAT_S8_UINT, &formatProperties);
|
||||
if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, " %s", "VK_FORMAT_S8_UINT (stencil)")
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, " - VK_FORMAT_S8_UINT not supported, skipped")
|
||||
ARRAY_FREE(supportedFormats);
|
||||
return;
|
||||
}
|
||||
} else ARRAY_PUSH_BACK(errors) = "VK_FORMAT_S8_UINT not supported";
|
||||
}
|
||||
|
||||
// Log layers.
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " Supported device layers:")
|
||||
for (uint32_t j = 0; j < layerCount; j++) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " %s", (char *) layers[j].layerName)
|
||||
}
|
||||
|
||||
// Check extensions.
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " Supported device extensions:")
|
||||
VkBool32 hasSwapChain = VK_FALSE;
|
||||
for (uint32_t j = 0; j < extensionCount; j++) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " %s", (char *) extensions[j].extensionName)
|
||||
hasSwapChain = hasSwapChain || strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, extensions[j].extensionName) == 0;
|
||||
}
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "Vulkan: Found device extensions:")
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " " VK_KHR_SWAPCHAIN_EXTENSION_NAME " = %s", hasSwapChain ? "true" : "false")
|
||||
|
||||
if (!hasSwapChain) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO,
|
||||
" --------------------- Required " VK_KHR_SWAPCHAIN_EXTENSION_NAME " not found, skipped")
|
||||
ARRAY_FREE(supportedFormats);
|
||||
// Check found errors.
|
||||
if (errors != NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_WARNING, " Device is not supported:")
|
||||
VKCapabilityUtil_LogErrors(J2D_TRACE_WARNING, errors);
|
||||
ARRAY_FREE(errors);
|
||||
return;
|
||||
}
|
||||
|
||||
ARRAY(pchar) deviceEnabledLayers = NULL;
|
||||
ARRAY(pchar) deviceEnabledExtensions = NULL;
|
||||
ARRAY_PUSH_BACK(deviceEnabledExtensions) = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
|
||||
|
||||
// Check validation layer.
|
||||
#ifdef DEBUG
|
||||
int validationLayerNotSupported = 1;
|
||||
for (uint32_t j = 0; j < layerCount; j++) {
|
||||
if (strcmp("VK_LAYER_KHRONOS_validation", layers[j].layerName) == 0) {
|
||||
validationLayerNotSupported = 0;
|
||||
ARRAY_PUSH_BACK(deviceEnabledLayers) = "VK_LAYER_KHRONOS_validation";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (validationLayerNotSupported) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, " %s device layer is not supported", "VK_LAYER_KHRONOS_validation")
|
||||
}
|
||||
#endif
|
||||
|
||||
// Copy device name.
|
||||
char* deviceName = strdup(deviceProperties2.properties.deviceName);
|
||||
if (deviceName == NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "Vulkan: Cannot duplicate deviceName")
|
||||
ARRAY_FREE(deviceEnabledLayers);
|
||||
ARRAY_FREE(deviceEnabledExtensions);
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, " Cannot duplicate deviceName")
|
||||
ARRAY_FREE(supportedFormats);
|
||||
return;
|
||||
}
|
||||
@@ -288,8 +260,8 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice) {
|
||||
.handle = VK_NULL_HANDLE,
|
||||
.physicalDevice = physicalDevice,
|
||||
.queueFamily = queueFamily,
|
||||
.enabledLayers = deviceEnabledLayers,
|
||||
.enabledExtensions = deviceEnabledExtensions,
|
||||
.enabledLayers = VKNamedEntry_CollectNames(layers),
|
||||
.enabledExtensions = VKNamedEntry_CollectNames(extensions),
|
||||
.sampledSrcTypes = sampledSrcTypes,
|
||||
.supportedFormats = supportedFormats,
|
||||
.caps = caps
|
||||
@@ -304,11 +276,11 @@ void VKDevice_Reset(VKDevice* device) {
|
||||
ARRAY_FREE(device->enabledExtensions);
|
||||
ARRAY_FREE(device->enabledLayers);
|
||||
ARRAY_FREE(device->supportedFormats);
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, "VKDevice_Reset(%s)", device->name);
|
||||
free(device->name);
|
||||
if (device->vkDestroyDevice != NULL) {
|
||||
device->vkDestroyDevice(device->handle, NULL);
|
||||
}
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, "VKDevice_Reset(%s)", device->name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -348,7 +320,7 @@ Java_sun_java2d_vulkan_VKGPU_init(JNIEnv *env, jclass jClass, jlong jDevice) {
|
||||
.pQueuePriorities = &queuePriority
|
||||
};
|
||||
|
||||
VkPhysicalDeviceFeatures features10 = { .logicOp = VK_TRUE };
|
||||
VkPhysicalDeviceFeatures features10 = { .logicOp = device->caps & sun_java2d_vulkan_VKGPU_CAP_LOGIC_OP_BIT };
|
||||
VkPhysicalDeviceVulkan12Features features12 = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
||||
.timelineSemaphore = VK_TRUE
|
||||
@@ -377,17 +349,22 @@ Java_sun_java2d_vulkan_VKGPU_init(JNIEnv *env, jclass jClass, jlong jDevice) {
|
||||
|
||||
VkBool32 missingAPI = JNI_FALSE;
|
||||
DEVICE_FUNCTION_TABLE(CHECK_PROC_ADDR, missingAPI, vk->vkGetDeviceProcAddr, device->handle, device->)
|
||||
if (device->caps & CAP_PRESENTABLE_BIT) {
|
||||
SWAPCHAIN_DEVICE_FUNCTION_TABLE(CHECK_PROC_ADDR, missingAPI, vk->vkGetDeviceProcAddr, device->handle, device->)
|
||||
}
|
||||
if (missingAPI) {
|
||||
VKDevice_Reset(device);
|
||||
#define REQUIRED_API_MISSING_MESSAGE "Vulkan: Required API is missing: "
|
||||
size_t size = sizeof(REQUIRED_API_MISSING_MESSAGE);
|
||||
#define PFN_CALC_MISSING_NAMES_SIZE(_, NAME) if (device->NAME == NULL) size += sizeof(#NAME) + 1;
|
||||
DEVICE_FUNCTION_TABLE(PFN_CALC_MISSING_NAMES_SIZE)
|
||||
if (device->caps & CAP_PRESENTABLE_BIT) { SWAPCHAIN_DEVICE_FUNCTION_TABLE(PFN_CALC_MISSING_NAMES_SIZE) }
|
||||
char message[size];
|
||||
memcpy(message, REQUIRED_API_MISSING_MESSAGE, size = sizeof(REQUIRED_API_MISSING_MESSAGE) - 1);
|
||||
#define PFN_APPEND_MISSING_NAME(_, NAME) if (device->NAME == NULL) { \
|
||||
memcpy(message + size, #NAME ", ", sizeof(#NAME) + 1); size += sizeof(#NAME) + 1; }
|
||||
DEVICE_FUNCTION_TABLE(PFN_APPEND_MISSING_NAME)
|
||||
if (device->caps & CAP_PRESENTABLE_BIT) { SWAPCHAIN_DEVICE_FUNCTION_TABLE(PFN_APPEND_MISSING_NAME) }
|
||||
message[size - 2] = '\0';
|
||||
JNU_ThrowByName(env, "java/lang/RuntimeException", message);
|
||||
return;
|
||||
|
||||
@@ -61,6 +61,7 @@ struct VKDevice {
|
||||
VKTexturePool* texturePool;
|
||||
|
||||
DEVICE_FUNCTION_TABLE(DECL_PFN)
|
||||
SWAPCHAIN_DEVICE_FUNCTION_TABLE(DECL_PFN)
|
||||
};
|
||||
|
||||
#endif //VKDevice_h_Included
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include "VKUtil.h"
|
||||
#include "VKCapabilityUtil.h"
|
||||
#include "VKEnv.h"
|
||||
#include "VKDevice.h"
|
||||
|
||||
@@ -128,70 +129,67 @@ static VKEnv* VKEnv_Create(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VKPl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Query API version.
|
||||
uint32_t apiVersion = 0;
|
||||
|
||||
VK_IF_ERROR(vkEnumerateInstanceVersion(&apiVersion)) return NULL;
|
||||
|
||||
J2dRlsTraceLn3(J2D_TRACE_INFO, "Vulkan: Available (%d.%d.%d)",
|
||||
VK_API_VERSION_MAJOR(apiVersion),
|
||||
VK_API_VERSION_MINOR(apiVersion),
|
||||
VK_API_VERSION_PATCH(apiVersion))
|
||||
|
||||
if (apiVersion < REQUIRED_VULKAN_VERSION) {
|
||||
J2dRlsTraceLn3(J2D_TRACE_ERROR, "Vulkan: Unsupported version. Required at least (%d.%d.%d)",
|
||||
VK_API_VERSION_MAJOR(REQUIRED_VULKAN_VERSION),
|
||||
VK_API_VERSION_MINOR(REQUIRED_VULKAN_VERSION),
|
||||
VK_API_VERSION_PATCH(REQUIRED_VULKAN_VERSION))
|
||||
// Query supported layers.
|
||||
uint32_t layerCount;
|
||||
VK_IF_ERROR(vkEnumerateInstanceLayerProperties(&layerCount, NULL)) return NULL;
|
||||
VkLayerProperties allLayers[layerCount];
|
||||
VK_IF_ERROR(vkEnumerateInstanceLayerProperties(&layerCount, allLayers)) return NULL;
|
||||
|
||||
// Query supported extensions.
|
||||
uint32_t extensionCount;
|
||||
VK_IF_ERROR(vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL)) return NULL;
|
||||
VkExtensionProperties allExtensions[extensionCount];
|
||||
VK_IF_ERROR(vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, allExtensions)) return NULL;
|
||||
|
||||
// Log layers and extensions.
|
||||
VKNamedEntry_LogAll("instance layers", allLayers[0].layerName, layerCount, sizeof(VkLayerProperties));
|
||||
VKNamedEntry_LogAll("instance extensions", allExtensions[0].extensionName, extensionCount, sizeof(VkExtensionProperties));
|
||||
|
||||
// Check API version.
|
||||
ARRAY(pchar) errors = NULL;
|
||||
if (apiVersion < REQUIRED_VULKAN_VERSION) ARRAY_PUSH_BACK(errors) = "Unsupported API version";
|
||||
|
||||
// Check layers.
|
||||
VKNamedEntry* layers = NULL;
|
||||
#ifdef DEBUG
|
||||
DEF_NAMED_ENTRY(layers, VK_KHR_VALIDATION_LAYER);
|
||||
#endif
|
||||
VKNamedEntry_Match(layers, allLayers[0].layerName, layerCount, sizeof(VkLayerProperties));
|
||||
VKNamedEntry_LogFound(layers);
|
||||
|
||||
// Check extensions.
|
||||
pchar PLATFORM_SURFACE_EXTENSION_NAME = platformData != NULL ? platformData->surfaceExtensionName : NULL;
|
||||
VKNamedEntry* extensions = NULL;
|
||||
DEF_NAMED_ENTRY(extensions, PLATFORM_SURFACE_EXTENSION);
|
||||
DEF_NAMED_ENTRY(extensions, VK_KHR_SURFACE_EXTENSION);
|
||||
#ifdef DEBUG
|
||||
DEF_NAMED_ENTRY(extensions, VK_EXT_DEBUG_UTILS_EXTENSION);
|
||||
#endif
|
||||
VKNamedEntry_Match(extensions, allExtensions[0].extensionName, extensionCount, sizeof(VkExtensionProperties));
|
||||
VKNamedEntry_LogFound(extensions);
|
||||
|
||||
// Check found errors.
|
||||
if (errors != NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, " Vulkan is not supported:")
|
||||
VKCapabilityUtil_LogErrors(J2D_TRACE_ERROR, errors);
|
||||
ARRAY_FREE(errors);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t extensionsCount;
|
||||
// Get the number of extensions and layers
|
||||
VK_IF_ERROR(vkEnumerateInstanceExtensionProperties(NULL, &extensionsCount, NULL)) return NULL;
|
||||
VkExtensionProperties extensions[extensionsCount];
|
||||
VK_IF_ERROR(vkEnumerateInstanceExtensionProperties(NULL, &extensionsCount, extensions)) return NULL;
|
||||
|
||||
uint32_t layersCount;
|
||||
VK_IF_ERROR(vkEnumerateInstanceLayerProperties(&layersCount, NULL)) return NULL;
|
||||
VkLayerProperties layers[layersCount];
|
||||
VK_IF_ERROR(vkEnumerateInstanceLayerProperties(&layersCount, layers)) return NULL;
|
||||
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " Supported instance layers:")
|
||||
for (uint32_t i = 0; i < layersCount; i++) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " %s", (char *) layers[i].layerName)
|
||||
}
|
||||
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, " Supported instance extensions:")
|
||||
for (uint32_t i = 0; i < extensionsCount; i++) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " %s", (char *) extensions[i].extensionName)
|
||||
}
|
||||
|
||||
ARRAY(pchar) enabledLayers = NULL;
|
||||
ARRAY(pchar) enabledExtensions = NULL;
|
||||
void *pNext = NULL;
|
||||
ARRAY_PUSH_BACK(enabledExtensions) = VK_KHR_SURFACE_EXTENSION_NAME;
|
||||
if (platformData != NULL && platformData->surfaceExtensionName != NULL) {
|
||||
ARRAY_PUSH_BACK(enabledExtensions) = platformData->surfaceExtensionName;
|
||||
}
|
||||
|
||||
// Check required layers & extensions.
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(enabledExtensions); i++) {
|
||||
int notFound = 1;
|
||||
for (uint32_t j = 0; j < extensionsCount; j++) {
|
||||
if (strcmp(extensions[j].extensionName, enabledExtensions[i]) == 0) {
|
||||
notFound = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (notFound) {
|
||||
J2dRlsTraceLn1(J2D_TRACE_ERROR, "Vulkan: Required extension %s not found", enabledExtensions[i])
|
||||
ARRAY_FREE(enabledLayers);
|
||||
ARRAY_FREE(enabledExtensions);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Check presentation support.
|
||||
VkBool32 presentationSupported = PLATFORM_SURFACE_EXTENSION.found && VK_KHR_SURFACE_EXTENSION.found;
|
||||
if (!presentationSupported) PLATFORM_SURFACE_EXTENSION.found = VK_KHR_SURFACE_EXTENSION.found = NULL;
|
||||
|
||||
// Configure validation
|
||||
void *pNext = NULL;
|
||||
#ifdef DEBUG
|
||||
VkValidationFeatureEnableEXT enables[] = {
|
||||
// VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,
|
||||
@@ -200,51 +198,32 @@ static VKEnv* VKEnv_Create(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VKPl
|
||||
// VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,
|
||||
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT
|
||||
};
|
||||
|
||||
VkValidationFeaturesEXT features = {};
|
||||
features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
|
||||
features.enabledValidationFeatureCount = SARRAY_COUNT_OF(enables);
|
||||
features.pEnabledValidationFeatures = enables;
|
||||
|
||||
// Includes the validation features into the instance creation process
|
||||
|
||||
int foundDebugLayer = 0;
|
||||
for (uint32_t i = 0; i < layersCount; i++) {
|
||||
if (strcmp((char *) layers[i].layerName, "VK_LAYER_KHRONOS_validation") == 0) {
|
||||
foundDebugLayer = 1;
|
||||
break;
|
||||
}
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " %s", (char *) layers[i].layerName)
|
||||
}
|
||||
int foundDebugExt = 0;
|
||||
for (uint32_t i = 0; i < extensionsCount; i++) {
|
||||
if (strcmp((char *) extensions[i].extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
|
||||
foundDebugExt = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundDebugLayer && foundDebugExt) {
|
||||
ARRAY_PUSH_BACK(enabledLayers) = "VK_LAYER_KHRONOS_validation";
|
||||
ARRAY_PUSH_BACK(enabledExtensions) = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
|
||||
VkValidationFeaturesEXT features = {
|
||||
.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
|
||||
.enabledValidationFeatureCount = SARRAY_COUNT_OF(enables),
|
||||
.pEnabledValidationFeatures = enables
|
||||
};
|
||||
if (VK_KHR_VALIDATION_LAYER.found && VK_EXT_DEBUG_UTILS_EXTENSION.found) {
|
||||
pNext = &features;
|
||||
} else {
|
||||
J2dRlsTraceLn2(J2D_TRACE_WARNING, "Vulkan: %s and %s are not supported",
|
||||
"VK_LAYER_KHRONOS_validation", VK_EXT_DEBUG_UTILS_EXTENSION_NAME)
|
||||
VK_KHR_VALIDATION_LAYER.found = VK_EXT_DEBUG_UTILS_EXTENSION.found = NULL;
|
||||
J2dRlsTraceLn(J2D_TRACE_WARNING, " Vulkan validation is not supported")
|
||||
}
|
||||
#endif
|
||||
|
||||
VKEnv* vk = malloc(sizeof(VKEnv));
|
||||
if (vk == NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "Vulkan: Cannot allocate VKEnv")
|
||||
ARRAY_FREE(enabledLayers);
|
||||
ARRAY_FREE(enabledExtensions);
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, " Cannot allocate VKEnv")
|
||||
return NULL;
|
||||
}
|
||||
*vk = (VKEnv) {
|
||||
.platformData = platformData
|
||||
.platformData = platformData,
|
||||
.presentationSupported = presentationSupported
|
||||
};
|
||||
|
||||
ARRAY(pchar) enabledLayers = VKNamedEntry_CollectNames(layers);
|
||||
ARRAY(pchar) enabledExtensions = VKNamedEntry_CollectNames(extensions);
|
||||
|
||||
VkApplicationInfo applicationInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = NULL,
|
||||
@@ -284,17 +263,23 @@ static VKEnv* VKEnv_Create(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VKPl
|
||||
VKEnv_Destroy(vk);
|
||||
return NULL;
|
||||
}
|
||||
if (vk->platformData != NULL && vk->platformData->initFunctions != NULL &&
|
||||
!vk->platformData->initFunctions(vk, vkGetInstanceProcAddr)) {
|
||||
VKEnv_Destroy(vk);
|
||||
return NULL;
|
||||
if (presentationSupported) {
|
||||
SURFACE_INSTANCE_FUNCTION_TABLE(CHECK_PROC_ADDR, missingAPI, vkGetInstanceProcAddr, vk->instance, vk->)
|
||||
if (missingAPI) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "Vulkan: Required API is missing:")
|
||||
SURFACE_INSTANCE_FUNCTION_TABLE(LOG_MISSING_PFN, vk->)
|
||||
}
|
||||
if (missingAPI || !vk->platformData->initFunctions(vk, vkGetInstanceProcAddr)) {
|
||||
vk->presentationSupported = presentationSupported = VK_FALSE;
|
||||
}
|
||||
}
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, "Vulkan: Presentation supported = %s", presentationSupported ? "true" : "false")
|
||||
|
||||
vk->composites = VKComposites_Create();
|
||||
|
||||
// Create debug messenger
|
||||
#if defined(DEBUG)
|
||||
if (foundDebugLayer && foundDebugExt &&
|
||||
if (VK_KHR_VALIDATION_LAYER.found && VK_EXT_DEBUG_UTILS_EXTENSION.found &&
|
||||
vk->vkCreateDebugUtilsMessengerEXT != NULL && pNext) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
@@ -321,10 +306,10 @@ void VKDevice_CheckAndAdd(VKEnv* vk, VkPhysicalDevice physicalDevice);
|
||||
static VkBool32 VKEnv_FindDevices(VKEnv* vk) {
|
||||
uint32_t count;
|
||||
VK_IF_ERROR(vk->vkEnumeratePhysicalDevices(vk->instance, &count, NULL)) return JNI_FALSE;
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, "Vulkan: Found %d physical devices:", count)
|
||||
VkPhysicalDevice physicalDevices[count];
|
||||
VK_IF_ERROR(vk->vkEnumeratePhysicalDevices(vk->instance, &count, physicalDevices)) return JNI_FALSE;
|
||||
ARRAY_ENSURE_CAPACITY(vk->devices, count);
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, "Vulkan: Found %d physical devices:", count)
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
VKDevice_CheckAndAdd(vk, physicalDevices[i]);
|
||||
}
|
||||
|
||||
@@ -59,8 +59,10 @@ struct VKEnv {
|
||||
#endif
|
||||
|
||||
VKPlatformData* platformData;
|
||||
VkBool32 presentationSupported;
|
||||
|
||||
INSTANCE_FUNCTION_TABLE(DECL_PFN)
|
||||
SURFACE_INSTANCE_FUNCTION_TABLE(DECL_PFN)
|
||||
DEBUG_INSTANCE_FUNCTION_TABLE(DECL_PFN)
|
||||
};
|
||||
|
||||
|
||||
@@ -44,16 +44,18 @@ ENTRY(__VA_ARGS__, vkGetPhysicalDeviceMemoryProperties); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceFeatures2); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceProperties2); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceQueueFamilyProperties); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceSurfaceCapabilitiesKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceSurfaceFormatsKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceFormatProperties); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceSurfacePresentModesKHR); \
|
||||
ENTRY(__VA_ARGS__, vkEnumerateDeviceLayerProperties); \
|
||||
ENTRY(__VA_ARGS__, vkEnumerateDeviceExtensionProperties); \
|
||||
ENTRY(__VA_ARGS__, vkCreateDevice); \
|
||||
ENTRY(__VA_ARGS__, vkDestroySurfaceKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetDeviceProcAddr); \
|
||||
|
||||
#define SURFACE_INSTANCE_FUNCTION_TABLE(ENTRY, ...) \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceSurfaceCapabilitiesKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceSurfaceFormatsKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetPhysicalDeviceSurfacePresentModesKHR); \
|
||||
ENTRY(__VA_ARGS__, vkDestroySurfaceKHR); \
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define DEBUG_INSTANCE_FUNCTION_TABLE(ENTRY, ...) \
|
||||
ENTRY(__VA_ARGS__, vkCreateDebugUtilsMessengerEXT); \
|
||||
@@ -71,9 +73,6 @@ ENTRY(__VA_ARGS__, vkCreatePipelineLayout); \
|
||||
ENTRY(__VA_ARGS__, vkDestroyPipelineLayout); \
|
||||
ENTRY(__VA_ARGS__, vkCreateGraphicsPipelines); \
|
||||
ENTRY(__VA_ARGS__, vkDestroyPipeline); \
|
||||
ENTRY(__VA_ARGS__, vkCreateSwapchainKHR); \
|
||||
ENTRY(__VA_ARGS__, vkDestroySwapchainKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetSwapchainImagesKHR); \
|
||||
ENTRY(__VA_ARGS__, vkCreateImageView); \
|
||||
ENTRY(__VA_ARGS__, vkCreateFramebuffer); \
|
||||
ENTRY(__VA_ARGS__, vkCreateCommandPool); \
|
||||
@@ -88,11 +87,9 @@ ENTRY(__VA_ARGS__, vkCreateFence); \
|
||||
ENTRY(__VA_ARGS__, vkGetDeviceQueue); \
|
||||
ENTRY(__VA_ARGS__, vkWaitForFences); \
|
||||
ENTRY(__VA_ARGS__, vkResetFences); \
|
||||
ENTRY(__VA_ARGS__, vkAcquireNextImageKHR); \
|
||||
ENTRY(__VA_ARGS__, vkResetCommandBuffer); \
|
||||
ENTRY(__VA_ARGS__, vkQueueSubmit); \
|
||||
ENTRY(__VA_ARGS__, vkQueueWaitIdle); \
|
||||
ENTRY(__VA_ARGS__, vkQueuePresentKHR); \
|
||||
ENTRY(__VA_ARGS__, vkBeginCommandBuffer); \
|
||||
ENTRY(__VA_ARGS__, vkCmdBlitImage); \
|
||||
ENTRY(__VA_ARGS__, vkCmdPipelineBarrier); \
|
||||
@@ -141,6 +138,13 @@ ENTRY(__VA_ARGS__, vkCmdCopyBufferToImage); \
|
||||
ENTRY(__VA_ARGS__, vkCmdCopyImageToBuffer); \
|
||||
ENTRY(__VA_ARGS__, vkCmdCopyBuffer); \
|
||||
|
||||
#define SWAPCHAIN_DEVICE_FUNCTION_TABLE(ENTRY, ...) \
|
||||
ENTRY(__VA_ARGS__, vkCreateSwapchainKHR); \
|
||||
ENTRY(__VA_ARGS__, vkDestroySwapchainKHR); \
|
||||
ENTRY(__VA_ARGS__, vkGetSwapchainImagesKHR); \
|
||||
ENTRY(__VA_ARGS__, vkAcquireNextImageKHR); \
|
||||
ENTRY(__VA_ARGS__, vkQueuePresentKHR); \
|
||||
|
||||
// Utilities for working with function pointers.
|
||||
|
||||
#define DECL_PFN(_, NAME) PFN_ ## NAME NAME
|
||||
|
||||
Reference in New Issue
Block a user