JBR-7461: Implement VKTexturePool for the linux vulkan pipeline:

- based on common AccelTexturePool
 - new VKTexturePool instance in VKLogicalDevice
 - fixed SIGSEGV in VKImage dispose
 - store device in TPI
 - indentation fixes
 - merged with latest changes for JBR-7460
 - use (ATexturePoolLock_init)(void)
 - fixed logs in lock implementations + fixed indentation
 - fixed MTLTexturePool to pre-processor conditions (not runtime) on USE_ACCEL_TEXTURE_POOL

(cherry picked from commit 5515b0fbfc)
This commit is contained in:
lbourges
2024-07-26 14:02:46 +02:00
committed by jbrbot
parent 4a3d2e08aa
commit 7877c8db3a
7 changed files with 262 additions and 6 deletions

View File

@@ -417,6 +417,7 @@ ifeq ($(call isTargetOs, windows macosx), false)
common/awt/debug \
common/awt/systemscale \
common/font \
common/java2d \
common/java2d/wl \
common/java2d/vulkan \
common/wayland \
@@ -500,6 +501,7 @@ ifeq ($(call isTargetOs, macosx), true)
$(LIBAWT_DEFAULT_HEADER_DIRS) \
libawt_lwawt/awt \
libawt_lwawt/font \
libawt_lwawt/java2d \
libawt_lwawt/java2d/opengl \
libawt_lwawt/java2d/metal \
include \

View File

@@ -63,7 +63,7 @@
#define TRACE_USE_API 0
#define TRACE_REUSE 0
#define INIT_TEST 0
#define INIT_TEST 1
#define INIT_TEST_STEP 1
#define INIT_TEST_MAX 1024

View File

@@ -24,18 +24,20 @@
* questions.
*/
#include <dlfcn.h>
#include <malloc.h>
#include <Trace.h>
#include <string.h>
#include <vulkan/vulkan.h>
#include "jlong_md.h"
#include "jvm_md.h"
#include "jni_util.h"
#include "CArrayUtil.h"
#include "VKBase.h"
#include "VKVertex.h"
#include "VKRenderer.h"
#include "CArrayUtil.h"
#include <vulkan/vulkan.h>
#include <dlfcn.h>
#include <string.h>
#include "VKTexturePool.h"
#include <Trace.h>
#define VULKAN_DLL JNI_LIB_NAME("vulkan")
#define VULKAN_1_DLL VERSIONED_JNI_LIB_NAME("vulkan", "1")
@@ -81,6 +83,9 @@ static void vulkanLibClose() {
if (geInstance->devices[i].name != NULL) {
free(geInstance->devices[i].name);
}
if (geInstance->devices[i].texturePool != NULL) {
VKTexturePool_Dispose(geInstance->devices[i].texturePool);
}
if (geInstance->devices[i].vkDestroyDevice != NULL && geInstance->devices[i].device != NULL) {
geInstance->devices[i].vkDestroyDevice(geInstance->devices[i].device, NULL);
}
@@ -802,6 +807,12 @@ static jboolean VK_InitLogicalDevice(VKLogicalDevice* logicalDevice) {
}
ARRAY_FREE(vertices);
logicalDevice->texturePool = VKTexturePool_initWithDevice(logicalDevice);
if (!logicalDevice->texturePool) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "Cannot create texture pool")
return JNI_FALSE;
}
geInstance->currentDevice = logicalDevice;
return JNI_TRUE;

View File

@@ -27,6 +27,7 @@
#ifndef VKBase_h_Included
#define VKBase_h_Included
#include "VKTypes.h"
#include "VKTexturePool.h"
struct VKLogicalDevice {
VkDevice device;
@@ -48,6 +49,7 @@ struct VKLogicalDevice {
VkSampler textureSampler;
VKBuffer* blitVertexBuffer;
VkRenderPass renderPass;
VKTexturePool* texturePool;
PFN_vkDestroyDevice vkDestroyDevice;
PFN_vkCreateShaderModule vkCreateShaderModule;

View File

@@ -90,6 +90,8 @@ VKImage* VKImage_Create(VKLogicalDevice* logicalDevice,
image->format = format;
image->extent = (VkExtent2D) {width, height};
image->framebuffer = VK_NULL_HANDLE;
image->noImageDealloc = VK_FALSE;
VkImageCreateInfo imageInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -202,18 +204,22 @@ void VKImage_dealloc(VKLogicalDevice* logicalDevice, VKImage* image) {
if (image->framebuffer != VK_NULL_HANDLE) {
logicalDevice->vkDestroyFramebuffer(logicalDevice->device, image->framebuffer, NULL);
image->framebuffer = VK_NULL_HANDLE;
}
if (image->view != VK_NULL_HANDLE) {
logicalDevice->vkDestroyImageView(logicalDevice->device, image->view, NULL);
image->view = VK_NULL_HANDLE;
}
if (image->memory != VK_NULL_HANDLE) {
logicalDevice->vkFreeMemory(logicalDevice->device, image->memory, NULL);
image->memory = VK_NULL_HANDLE;
}
if (image->image != VK_NULL_HANDLE && !image->noImageDealloc) {
logicalDevice->vkDestroyImage(logicalDevice->device, image->image, NULL);
image->image = VK_NULL_HANDLE;
}
}

View File

@@ -0,0 +1,176 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 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.
*/
#include <stdlib.h>
#include <pthread.h>
#include "VKBase.h"
#include "VKImage.h"
#include "VKTexturePool.h"
#include "jni.h"
#include "jni_util.h"
#include "Trace.h"
#define TRACE_LOCK 0
#define TRACE_TEX 0
/* lock API */
ATexturePoolLockPrivPtr* VKTexturePoolLock_initImpl(void) {
pthread_mutex_t *l = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
CHECK_NULL_LOG_RETURN(l, NULL, "VKTexturePoolLock_initImpl: could not allocate pthread_mutex_t");
int status = pthread_mutex_init(l, NULL);
if (status != 0) {
return NULL;
}
if (TRACE_LOCK) J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "VKTexturePoolLock_initImpl: lock=%p", l);
return (ATexturePoolLockPrivPtr*)l;
}
void VKTexturePoolLock_DisposeImpl(ATexturePoolLockPrivPtr *lock) {
pthread_mutex_t* l = (pthread_mutex_t*)lock;
if (TRACE_LOCK) J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "VKTexturePoolLock_DisposeImpl: lock=%p", l);
pthread_mutex_destroy(l);
free(l);
}
void VKTexturePoolLock_lockImpl(ATexturePoolLockPrivPtr *lock) {
pthread_mutex_t* l = (pthread_mutex_t*)lock;
if (TRACE_LOCK) J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "VKTexturePoolLock_lockImpl: lock=%p", l);
pthread_mutex_lock(l);
if (TRACE_LOCK) J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "VKTexturePoolLock_lockImpl: lock=%p - locked", l);
}
void VKTexturePoolLock_unlockImpl(ATexturePoolLockPrivPtr *lock) {
pthread_mutex_t* l = (pthread_mutex_t*)lock;
if (TRACE_LOCK) J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "VKTexturePoolLock_unlockImpl: lock=%p", l);
pthread_mutex_unlock(l);
if (TRACE_LOCK) J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "VKTexturePoolLock_unlockImpl: lock=%p - unlocked", l);
}
/* Texture allocate/free API */
static ATexturePrivPtr* VKTexturePool_createTexture(ADevicePrivPtr *device,
int width,
int height,
long format)
{
CHECK_NULL_RETURN(device, NULL);
VKImage* texture = VKImage_Create((VKLogicalDevice*)device, width, height,
(VkFormat)format,
VK_IMAGE_TILING_LINEAR,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
if IS_NULL(texture) {
J2dRlsTrace(J2D_TRACE_ERROR, "VKTexturePool_createTexture: Cannot create VKImage");
return NULL;
}
// usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
// storage = MTLStorageModeManaged
if (TRACE_TEX) J2dRlsTraceLn4(J2D_TRACE_VERBOSE, "VKTexturePool_createTexture: created texture: tex=%p, w=%d h=%d, pf=%d",
texture, width, height, format);
return texture;
}
static int VKTexturePool_bytesPerPixel(long format) {
switch ((VkFormat)format) {
case VK_FORMAT_R8G8B8A8_UNORM:
return 4;
case VK_FORMAT_R8_UNORM:
return 1;
default:
J2dRlsTraceLn1(J2D_TRACE_ERROR, "VKTexturePool_bytesPerPixel: format=%d not supported (4 bytes by default)", format);
return 4;
}
}
static void VKTexturePool_freeTexture(ADevicePrivPtr *device, ATexturePrivPtr *texture) {
CHECK_NULL(device);
CHECK_NULL(texture);
VKImage* tex = (VKImage*)texture;
if (TRACE_TEX) J2dRlsTraceLn4(J2D_TRACE_VERBOSE, "VKTexturePool_freeTexture: free texture: tex=%p, w=%d h=%d, pf=%d",
tex, tex->extent.width, tex->extent.height, tex->format);
VKImage_free((VKLogicalDevice*)device, tex);
}
/* VKTexturePoolHandle API */
void VKTexturePoolHandle_ReleaseTexture(VKTexturePoolHandle *handle) {
ATexturePoolHandle_ReleaseTexture(handle);
}
ATexturePrivPtr* VKTexturePoolHandle_GetTexture(VKTexturePoolHandle *handle) {
return ATexturePoolHandle_GetTexture(handle);
}
jint VKTexturePoolHandle_GetRequestedWidth(VKTexturePoolHandle *handle) {
return ATexturePoolHandle_GetRequestedWidth(handle);
}
jint VKTexturePoolHandle_GetRequestedHeight(VKTexturePoolHandle *handle) {
return ATexturePoolHandle_GetRequestedHeight(handle);
}
/* VKTexturePool API */
VKTexturePool* VKTexturePool_initWithDevice(VKLogicalDevice *device) {
CHECK_NULL_RETURN(device, NULL);
// TODO: get vulkan device memory information (1gb fixed here):
uint64_t maxDeviceMemory = 1024 * UNIT_MB;
ATexturePoolLockWrapper *lockWrapper = ATexturePoolLockWrapper_init(&VKTexturePoolLock_initImpl,
&VKTexturePoolLock_DisposeImpl,
&VKTexturePoolLock_lockImpl,
&VKTexturePoolLock_unlockImpl);
return ATexturePool_initWithDevice(device,
(jlong)maxDeviceMemory,
&VKTexturePool_createTexture,
&VKTexturePool_freeTexture,
&VKTexturePool_bytesPerPixel,
lockWrapper,
VK_FORMAT_R8G8B8A8_UNORM);
}
void VKTexturePool_Dispose(VKTexturePool *pool) {
ATexturePoolLockWrapper_Dispose(ATexturePool_getLockWrapper(pool));
ATexturePool_Dispose(pool);
}
ATexturePoolLockWrapper* VKTexturePool_getLockWrapper(VKTexturePool *pool) {
return ATexturePool_getLockWrapper(pool);
}
VKTexturePoolHandle* VKTexturePool_getTexture(VKTexturePool *pool,
jint width,
jint height,
jlong format)
{
return ATexturePool_getTexture(pool, width, height, format);
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 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 VKTexturePool_h_Included
#define VKTexturePool_h_Included
#include "AccelTexturePool.h"
#include "jni.h"
/* VKTexturePoolHandle API */
typedef ATexturePoolHandle VKTexturePoolHandle;
void VKTexturePoolHandle_ReleaseTexture(VKTexturePoolHandle *handle);
ATexturePrivPtr* VKTexturePoolHandle_GetTexture(VKTexturePoolHandle *handle);
jint VKTexturePoolHandle_GetRequestedWidth(VKTexturePoolHandle *handle);
jint VKTexturePoolHandle_GetRequestedHeight(VKTexturePoolHandle *handle);
/* VKTexturePool API */
typedef ATexturePool VKTexturePool;
VKTexturePool* VKTexturePool_initWithDevice(VKLogicalDevice *device) ;
void VKTexturePool_Dispose(VKTexturePool *pool);
ATexturePoolLockWrapper* VKTexturePool_getLockWrapper(VKTexturePool *pool);
VKTexturePoolHandle* VKTexturePool_getTexture(VKTexturePool *pool,
jint width,
jint height,
jlong format);
#endif /* VKTexturePool_h_Included */