From 221d1a82bf3601be793678a9962a86d36f0fc1a0 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Tue, 8 Apr 2025 16:53:23 +0200 Subject: [PATCH] fixing opengl --- Sources/Backends/OpenGL/OpenGLDevice.c | 5 +- Sources/Backends/OpenGL/OpenGLImage.c | 59 ++++++++++++++++--- Sources/PulseDefs.h | 2 +- Sources/PulseImage.c | 5 ++ Tests/Image.c | 3 +- .../Vulkan-OpenGL/ReadWriteBindings.nzsl | 2 +- .../Vulkan-OpenGL/WriteOnlyBindings.nzsl | 4 +- 7 files changed, 66 insertions(+), 14 deletions(-) diff --git a/Sources/Backends/OpenGL/OpenGLDevice.c b/Sources/Backends/OpenGL/OpenGLDevice.c index a795823..b6d07af 100644 --- a/Sources/Backends/OpenGL/OpenGLDevice.c +++ b/Sources/Backends/OpenGL/OpenGLDevice.c @@ -214,11 +214,12 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic const char* core_extensions[] = { }; + uint32_t core_extensions_count = 0; const char* es_extensions[] = { "GL_EXT_texture_norm16", - "GL_EXT_texture_snorm", }; + uint32_t es_extensions_count = 1; bool is_core = backend->backend == PULSE_BACKEND_OPENGL; @@ -242,7 +243,7 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic device->context_type = OPENGL_CONTEXT_EGL; } #else - if(!EGLLoadInstance(&device->egl_instance, is_core ? core_extensions : es_extensions, PULSE_SIZEOF_ARRAY(is_core ? core_extensions : es_extensions), forbiden_devices, forbiden_devices_count, !is_core)) + if(!EGLLoadInstance(&device->egl_instance, is_core ? core_extensions : es_extensions, is_core ? core_extensions_count : es_extensions_count, forbiden_devices, forbiden_devices_count, !is_core)) { if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(backend)) PulseLogError(backend, "could not load EGL instance"); diff --git a/Sources/Backends/OpenGL/OpenGLImage.c b/Sources/Backends/OpenGL/OpenGLImage.c index c70e331..5be9dc8 100644 --- a/Sources/Backends/OpenGL/OpenGLImage.c +++ b/Sources/Backends/OpenGL/OpenGLImage.c @@ -85,23 +85,55 @@ PulseImage OpenGLCreateImageTryAndFail(PulseDevice device, const PulseImageCreat OpenGLImage* opengl_image = (OpenGLImage*)calloc(1, sizeof(OpenGLImage)); PULSE_CHECK_ALLOCATION_RETVAL(opengl_image, PULSE_NULL_HANDLE); - GLenum image_type = PulseImageTypeToGLTextureType[create_infos->type]; + image->driver_data = opengl_image; - // TODO error message if image_type is invalid + GLenum image_type = PulseImageTypeToGLTextureType[create_infos->type]; + GLenum image_format = PulseImageFormatToGLInternalFormat[create_infos->format]; + + if(image_type == GL_INVALID_ENUM) + { + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + PulseLogErrorFmt(device->backend, "%s image type is not supported", device->backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)"); + PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED); + free(opengl_image); + free(image); + return PULSE_NULL_HANDLE; + } + if(image_format == GL_INVALID_ENUM) + { + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + PulseLogErrorFmt(device->backend, "%s image format is not supported", device->backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)"); + PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT); + free(opengl_image); + free(image); + return PULSE_NULL_HANDLE; + } + + bool is_3D = create_infos->type == PULSE_IMAGE_TYPE_3D || create_infos->type == PULSE_IMAGE_TYPE_2D_ARRAY || create_infos->type == PULSE_IMAGE_TYPE_CUBE_ARRAY; opengl_device->glGenTextures(device, 1, &opengl_image->image); opengl_device->glBindTexture(device, image_type, opengl_image->image); if(try_and_fail) { while(((PFNGLGETERRORPROC)opengl_device->original_function_ptrs[glGetError])() != GL_NO_ERROR); // Clear errors - ((PFNGLTEXSTORAGE2DPROC)opengl_device->original_function_ptrs[glTexStorage2D])(); + if(is_3D) + ((PFNGLTEXSTORAGE3DPROC)opengl_device->original_function_ptrs[glTexStorage3D])(image_type, 1, image_format, create_infos->width, create_infos->height, create_infos->layer_count_or_depth); + else + ((PFNGLTEXSTORAGE2DPROC)opengl_device->original_function_ptrs[glTexStorage2D])(image_type, 1, image_format, create_infos->width, create_infos->height); + if(((PFNGLGETERRORPROC)opengl_device->original_function_ptrs[glGetError])() != GL_NO_ERROR) + { + while(((PFNGLGETERRORPROC)opengl_device->original_function_ptrs[glGetError])() != GL_NO_ERROR); // Clear errors + OpenGLDestroyImage(device, image); + opengl_device->glBindTexture(device, image_type, 0); // Unbind + return PULSE_NULL_HANDLE; + } } else { - if(create_infos->type == PULSE_IMAGE_TYPE_3D) - opengl_device->glTexStorage3D(device, image_type, 1, PulseImageFormatToGLInternalFormat[create_infos->format], create_infos->width, create_infos->width, create_infos->layer_count_or_depth); + if(is_3D) + opengl_device->glTexStorage3D(device, image_type, 1, image_format, create_infos->width, create_infos->height, create_infos->layer_count_or_depth); else - opengl_device->glTexStorage2D(device, image_type, 1, PulseImageFormatToGLInternalFormat[create_infos->format], create_infos->width, create_infos->height); + opengl_device->glTexStorage2D(device, image_type, 1, image_format, create_infos->width, create_infos->height); } if(create_infos->format == PULSE_IMAGE_FORMAT_A8_UNORM) { @@ -130,7 +162,18 @@ PulseImage OpenGLCreateImage(PulseDevice device, const PulseImageCreateInfo* cre bool OpenGLIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage) { - OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + PulseImageCreateInfo image_create_info = { 0 }; + image_create_info.type = type; + image_create_info.format = format; + image_create_info.usage = usage; + image_create_info.width = 1; + image_create_info.height = 1; + image_create_info.layer_count_or_depth = 12; + PulseImage image = OpenGLCreateImageTryAndFail(device, &image_create_info, true); + if(image == PULSE_NULL_HANDLE) + return false; + OpenGLDestroyImage(device, image); + return true; } bool OpenGLCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst) @@ -143,7 +186,9 @@ bool OpenGLBlitImage(PulseCommandList cmd, const PulseImageRegion* src, const Pu void OpenGLDestroyImage(PulseDevice device, PulseImage image) { + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); OpenGLImage* opengl_image = OPENGL_RETRIEVE_DRIVER_DATA_AS(image, OpenGLImage*); + opengl_device->glDeleteTextures(device, 1, &opengl_image->image); free(opengl_image); free(image); } diff --git a/Sources/PulseDefs.h b/Sources/PulseDefs.h index de3e5df..b2dcfca 100644 --- a/Sources/PulseDefs.h +++ b/Sources/PulseDefs.h @@ -60,7 +60,7 @@ for(size_t defrag_i = start; defrag_i < size - 1; defrag_i++) \ array[defrag_i] = array[defrag_i + 1]; \ -#define PULSE_SIZEOF_ARRAY(x) ((sizeof(x) / sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) +#define PULSE_SIZEOF_ARRAY(x) (sizeof(x) / sizeof(0[x])) #define PULSE_CHECK_COMMAND_LIST_STATE_RETVAL(cmd, retval) \ do { \ diff --git a/Sources/PulseImage.c b/Sources/PulseImage.c index b948faa..e2dd15f 100644 --- a/Sources/PulseImage.c +++ b/Sources/PulseImage.c @@ -89,6 +89,11 @@ PULSE_API PulseImage PulseCreateImage(PulseDevice device, const PulseImageCreate } else { + if(create_infos->width > MAX_2D_DIMENSION || create_infos->height > MAX_2D_DIMENSION) + { + PulseLogError(device->backend, "2D images: width and height must be <= 16384"); + failed = true; + } if(!PulseIsImageFormatValid(device, create_infos->format, PULSE_IMAGE_TYPE_2D, create_infos->usage)) { PulseLogError(device->backend, "2D images: the format is unsupported for the given usage"); diff --git a/Tests/Image.c b/Tests/Image.c index d3974c8..cebfd8a 100644 --- a/Tests/Image.c +++ b/Tests/Image.c @@ -39,6 +39,7 @@ void TestImageCreation() * This test may crash some Nouveau NVK drivers (wtf ???). * It seems to be comming exclusively from 3D read-only images */ + #ifndef VULKAN_ENABLED { PulseImageCreateInfo image_create_info = { 0 }; image_create_info.type = PULSE_IMAGE_TYPE_3D; @@ -51,7 +52,7 @@ void TestImageCreation() TEST_ASSERT_NOT_EQUAL_MESSAGE(image, PULSE_NULL_HANDLE, PulseVerbaliseErrorType(PulseGetLastErrorType())); PulseDestroyImage(device, image); } - + #endif { PulseImageCreateInfo image_create_info = { 0 }; diff --git a/Tests/Shaders/Vulkan-OpenGL/ReadWriteBindings.nzsl b/Tests/Shaders/Vulkan-OpenGL/ReadWriteBindings.nzsl index a84408b..89e1546 100644 --- a/Tests/Shaders/Vulkan-OpenGL/ReadWriteBindings.nzsl +++ b/Tests/Shaders/Vulkan-OpenGL/ReadWriteBindings.nzsl @@ -22,7 +22,7 @@ external [set(1)] external { - [binding(0)] write_texture: texture2D[f32, rgba8], + [binding(0)] write_texture: texture2D[f32, writeonly, rgba8], [binding(1)] write_ssbo: storage[SSBO, writeonly], } diff --git a/Tests/Shaders/Vulkan-OpenGL/WriteOnlyBindings.nzsl b/Tests/Shaders/Vulkan-OpenGL/WriteOnlyBindings.nzsl index 0c27c9d..a99c9f4 100644 --- a/Tests/Shaders/Vulkan-OpenGL/WriteOnlyBindings.nzsl +++ b/Tests/Shaders/Vulkan-OpenGL/WriteOnlyBindings.nzsl @@ -12,10 +12,10 @@ struct SSBO data: dyn_array[u32] } -[set(0)] +[set(1)] external { - [binding(0)] write_texture: texture2D[f32, readwrite, rgba8], + [binding(0)] write_texture: texture2D[f32, writeonly, rgba8], [binding(1)] write_ssbo: storage[SSBO], }