Index: libraries/source/glad/README.md =================================================================== --- libraries/source/glad/README.md +++ libraries/source/glad/README.md @@ -18,23 +18,23 @@ Build the source files for all four backends with their respective extensions - GL ```sh - python -m glad --api="gl:core=2.1" --extensions="../extensions/gl.txt" --out-path="../" + python -m glad --api="gl:core=2.1" --extensions="../extensions/gl.txt" --out-path="../" c ``` - GLES2 ```sh - python -m glad --api="gles2=2.0" --extensions="../extensions/gles2.txt" --out-path="../" + python -m glad --api="gles2=2.0" --extensions="../extensions/gles2.txt" --out-path="../" c ``` - GLX ```sh - python -m glad --api="glx=1.4" --extensions="../extensions/glx.txt" --out-path="../" + python -m glad --api="glx=1.4" --extensions="../extensions/glx.txt" --out-path="../" c ``` - WGL ```sh - python -m glad --api="wgl=1.0" --extensions="../extensions/wgl.txt" --out-path="../" + python -m glad --api="wgl=1.0" --extensions="../extensions/wgl.txt" --out-path="../" c ``` - EGL ```sh - python -m glad --api="egl=1.5" --extensions="../extensions/egl.txt" --out-path="../" + python -m glad --api="egl=1.5" --extensions="../extensions/egl.txt" --out-path="../" c ``` Rename all files to .cpp to prevent compilation warnings Index: libraries/source/glad/extensions/gl.txt =================================================================== --- libraries/source/glad/extensions/gl.txt +++ libraries/source/glad/extensions/gl.txt @@ -5,6 +5,7 @@ GL_ARB_framebuffer_object GL_ARB_geometry_shader4 GL_ARB_instanced_arrays +GL_ARB_invalidate_subdata GL_ARB_map_buffer_range GL_ARB_multitexture GL_ARB_occlusion_query Index: libraries/source/glad/extensions/gles2.txt =================================================================== --- libraries/source/glad/extensions/gles2.txt +++ libraries/source/glad/extensions/gles2.txt @@ -1,3 +1,4 @@ +GL_EXT_discard_framebuffer GL_EXT_texture_compression_s3tc GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 Index: libraries/source/glad/include/glad/gl.h =================================================================== --- libraries/source/glad/include/glad/gl.h +++ libraries/source/glad/include/glad/gl.h @@ -1,27 +1,28 @@ /** - * Loader generated by glad 2.0.0-beta on Wed Mar 30 00:33:29 2022 + * Loader generated by glad 2.0.2 on 11/20/22 13:31:45 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: gl - * Extensions: 35 + * Extensions: 36 * * APIs: * - gl:core=2.1 * * Options: + * - ON_DEMAND = False + * - LOADER = False * - ALIAS = False - * - DEBUG = False * - HEADER_ONLY = False - * - LOADER = False + * - DEBUG = False * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False * * Commandline: - * --api='gl:core=2.1' --extensions='GL_ARB_draw_buffers,GL_ARB_draw_instanced,GL_ARB_fragment_program,GL_ARB_fragment_shader,GL_ARB_framebuffer_object,GL_ARB_geometry_shader4,GL_ARB_instanced_arrays,GL_ARB_map_buffer_range,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_shader_objects,GL_ARB_shading_language_100,GL_ARB_sync,GL_ARB_texture_compression,GL_ARB_texture_multisample,GL_ARB_texture_rectangle,GL_ARB_timer_query,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_EXT_bgra,GL_EXT_blend_color,GL_EXT_blend_minmax,GL_EXT_draw_range_elements,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_gpu_shader4,GL_EXT_packed_depth_stencil,GL_EXT_texture_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_lod_bias,GL_EXT_transform_feedback,GL_KHR_debug' c + * --api='gl:core=2.1' --extensions='GL_ARB_draw_buffers,GL_ARB_draw_instanced,GL_ARB_fragment_program,GL_ARB_fragment_shader,GL_ARB_framebuffer_object,GL_ARB_geometry_shader4,GL_ARB_instanced_arrays,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_range,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_shader_objects,GL_ARB_shading_language_100,GL_ARB_sync,GL_ARB_texture_compression,GL_ARB_texture_multisample,GL_ARB_texture_rectangle,GL_ARB_timer_query,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_EXT_bgra,GL_EXT_blend_color,GL_EXT_blend_minmax,GL_EXT_draw_range_elements,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_gpu_shader4,GL_EXT_packed_depth_stencil,GL_EXT_texture_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_lod_bias,GL_EXT_transform_feedback,GL_KHR_debug' c * * Online: - * http://glad.sh/#api=gl%3Acore%3D2.1&extensions=GL_ARB_draw_buffers%2CGL_ARB_draw_instanced%2CGL_ARB_fragment_program%2CGL_ARB_fragment_shader%2CGL_ARB_framebuffer_object%2CGL_ARB_geometry_shader4%2CGL_ARB_instanced_arrays%2CGL_ARB_map_buffer_range%2CGL_ARB_multitexture%2CGL_ARB_occlusion_query%2CGL_ARB_shader_objects%2CGL_ARB_shading_language_100%2CGL_ARB_sync%2CGL_ARB_texture_compression%2CGL_ARB_texture_multisample%2CGL_ARB_texture_rectangle%2CGL_ARB_timer_query%2CGL_ARB_vertex_buffer_object%2CGL_ARB_vertex_program%2CGL_ARB_vertex_shader%2CGL_EXT_bgra%2CGL_EXT_blend_color%2CGL_EXT_blend_minmax%2CGL_EXT_draw_range_elements%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_multisample%2CGL_EXT_framebuffer_object%2CGL_EXT_gpu_shader4%2CGL_EXT_packed_depth_stencil%2CGL_EXT_texture_array%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_lod_bias%2CGL_EXT_transform_feedback%2CGL_KHR_debug&generator=c&options= + * http://glad.sh/#api=gl%3Acore%3D2.1&extensions=GL_ARB_draw_buffers%2CGL_ARB_draw_instanced%2CGL_ARB_fragment_program%2CGL_ARB_fragment_shader%2CGL_ARB_framebuffer_object%2CGL_ARB_geometry_shader4%2CGL_ARB_instanced_arrays%2CGL_ARB_invalidate_subdata%2CGL_ARB_map_buffer_range%2CGL_ARB_multitexture%2CGL_ARB_occlusion_query%2CGL_ARB_shader_objects%2CGL_ARB_shading_language_100%2CGL_ARB_sync%2CGL_ARB_texture_compression%2CGL_ARB_texture_multisample%2CGL_ARB_texture_rectangle%2CGL_ARB_timer_query%2CGL_ARB_vertex_buffer_object%2CGL_ARB_vertex_program%2CGL_ARB_vertex_shader%2CGL_EXT_bgra%2CGL_EXT_blend_color%2CGL_EXT_blend_minmax%2CGL_EXT_draw_range_elements%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_multisample%2CGL_EXT_framebuffer_object%2CGL_EXT_gpu_shader4%2CGL_EXT_packed_depth_stencil%2CGL_EXT_texture_array%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_lod_bias%2CGL_EXT_transform_feedback%2CGL_KHR_debug&generator=c&options= * */ @@ -114,6 +115,8 @@ #define GLAD_GNUC_EXTENSION #endif +#define GLAD_UNUSED(x) (void)(x) + #ifndef GLAD_API_CALL #if defined(GLAD_API_CALL_EXPORT) #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) @@ -160,7 +163,7 @@ #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.0-beta" +#define GLAD_GENERATOR_VERSION "2.0.2" typedef void (*GLADapiproc)(void); @@ -1621,10 +1624,7 @@ typedef char GLchar; typedef char GLcharARB; #ifdef __APPLE__ -// See https://bugs.freedesktop.org/show_bug.cgi?id=66346 -// macOS considers those to be different. -// typedef void *GLhandleARB; -typedef GLuint GLhandleARB; +typedef void *GLhandleARB; #else typedef unsigned int GLhandleARB; #endif @@ -1697,6 +1697,8 @@ GLAD_API_CALL int GLAD_GL_ARB_geometry_shader4; #define GL_ARB_instanced_arrays 1 GLAD_API_CALL int GLAD_GL_ARB_instanced_arrays; +#define GL_ARB_invalidate_subdata 1 +GLAD_API_CALL int GLAD_GL_ARB_invalidate_subdata; #define GL_ARB_map_buffer_range 1 GLAD_API_CALL int GLAD_GL_ARB_map_buffer_range; #define GL_ARB_multitexture 1 @@ -2085,6 +2087,12 @@ typedef void (GLAD_API_PTR *PFNGLINDEXUBVPROC)(const GLubyte * c); typedef void (GLAD_API_PTR *PFNGLINITNAMESPROC)(void); typedef void (GLAD_API_PTR *PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERARBPROC)(GLuint buffer); typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); @@ -3249,6 +3257,18 @@ #define glInitNames glad_glInitNames GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; #define glInterleavedArrays glad_glInterleavedArrays +GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; +#define glInvalidateBufferData glad_glInvalidateBufferData +GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; +#define glInvalidateBufferSubData glad_glInvalidateBufferSubData +GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; +#define glInvalidateFramebuffer glad_glInvalidateFramebuffer +GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; +#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer +GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; +#define glInvalidateTexImage glad_glInvalidateTexImage +GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; +#define glInvalidateTexSubImage glad_glInvalidateTexSubImage GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; #define glIsBuffer glad_glIsBuffer GLAD_API_CALL PFNGLISBUFFERARBPROC glad_glIsBufferARB; Index: libraries/source/glad/include/glad/gles2.h =================================================================== --- libraries/source/glad/include/glad/gles2.h +++ libraries/source/glad/include/glad/gles2.h @@ -1,27 +1,28 @@ /** - * Loader generated by glad 2.0.0-beta on Tue Mar 29 08:49:05 2022 + * Loader generated by glad 2.0.2 on 11/20/22 13:31:47 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: gl - * Extensions: 8 + * Extensions: 9 * * APIs: * - gles2=2.0 * * Options: + * - ON_DEMAND = False + * - LOADER = False * - ALIAS = False - * - DEBUG = False * - HEADER_ONLY = False - * - LOADER = False + * - DEBUG = False * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False * * Commandline: - * --api='gles2=2.0' --extensions='GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_format_BGRA8888,GL_KHR_debug,GL_OES_depth32,GL_OES_mapbuffer,GL_OES_rgb8_rgba8,GL_OES_texture_border_clamp' c + * --api='gles2=2.0' --extensions='GL_EXT_discard_framebuffer,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_format_BGRA8888,GL_KHR_debug,GL_OES_depth32,GL_OES_mapbuffer,GL_OES_rgb8_rgba8,GL_OES_texture_border_clamp' c * * Online: - * http://glad.sh/#api=gles2%3D2.0&extensions=GL_EXT_texture_compression_s3tc%2CGL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_format_BGRA8888%2CGL_KHR_debug%2CGL_OES_depth32%2CGL_OES_mapbuffer%2CGL_OES_rgb8_rgba8%2CGL_OES_texture_border_clamp&generator=c&options= + * http://glad.sh/#api=gles2%3D2.0&extensions=GL_EXT_discard_framebuffer%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_format_BGRA8888%2CGL_KHR_debug%2CGL_OES_depth32%2CGL_OES_mapbuffer%2CGL_OES_rgb8_rgba8%2CGL_OES_texture_border_clamp&generator=c&options= * */ @@ -36,10 +37,18 @@ #error OpenGL ES 2 header already included (API: gles2), remove previous include! #endif #define __gl2_h_ 1 +#ifdef __gles2_gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl2_h_ 1 #ifdef __gl3_h_ #error OpenGL ES 3 header already included (API: gles2), remove previous include! #endif #define __gl3_h_ 1 +#ifdef __gles2_gl3_h_ + #error OpenGL ES 3 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl3_h_ 1 #ifdef __clang__ #pragma clang diagnostic pop #endif @@ -106,6 +115,8 @@ #define GLAD_GNUC_EXTENSION #endif +#define GLAD_UNUSED(x) (void)(x) + #ifndef GLAD_API_CALL #if defined(GLAD_API_CALL_EXPORT) #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) @@ -152,7 +163,7 @@ #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.0-beta" +#define GLAD_GENERATOR_VERSION "2.0.2" typedef void (*GLADapiproc)(void); @@ -206,6 +217,7 @@ #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_EXT 0x1800 #define GL_COLOR_WRITEMASK 0x0C23 #define GL_COMPILE_STATUS 0x8B81 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 @@ -257,6 +269,7 @@ #define GL_DEPTH_COMPONENT 0x1902 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH_EXT 0x1801 #define GL_DEPTH_FUNC 0x0B74 #define GL_DEPTH_RANGE 0x0B70 #define GL_DEPTH_TEST 0x0B71 @@ -436,6 +449,7 @@ #define GL_STENCIL_BITS 0x0D57 #define GL_STENCIL_BUFFER_BIT 0x00000400 #define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_EXT 0x1802 #define GL_STENCIL_FAIL 0x0B94 #define GL_STENCIL_FUNC 0x0B92 #define GL_STENCIL_INDEX8 0x8D48 @@ -592,6 +606,8 @@ #define GL_ES_VERSION_2_0 1 GLAD_API_CALL int GLAD_GL_ES_VERSION_2_0; +#define GL_EXT_discard_framebuffer 1 +GLAD_API_CALL int GLAD_GL_EXT_discard_framebuffer; #define GL_EXT_texture_compression_s3tc 1 GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc; #define GL_EXT_texture_filter_anisotropic 1 @@ -653,6 +669,7 @@ typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISCARDFRAMEBUFFEREXTPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); @@ -861,6 +878,8 @@ #define glDisable glad_glDisable GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; #define glDisableVertexAttribArray glad_glDisableVertexAttribArray +GLAD_API_CALL PFNGLDISCARDFRAMEBUFFEREXTPROC glad_glDiscardFramebufferEXT; +#define glDiscardFramebufferEXT glad_glDiscardFramebufferEXT GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; #define glDrawArrays glad_glDrawArrays GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; Index: libraries/source/glad/include/glad/glx.h =================================================================== --- libraries/source/glad/include/glad/glx.h +++ libraries/source/glad/include/glad/glx.h @@ -1,5 +1,7 @@ /** - * Loader generated by glad 2.0.0-beta on Tue Mar 29 08:49:06 2022 + * Loader generated by glad 2.0.2 on 11/20/22 13:31:48 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: glx @@ -9,13 +11,12 @@ * - glx=1.4 * * Options: + * - ON_DEMAND = False + * - LOADER = False * - ALIAS = False - * - DEBUG = False * - HEADER_ONLY = False - * - LOADER = False + * - DEBUG = False * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False * * Commandline: * --api='glx=1.4' --extensions='GLX_MESA_query_renderer,GLX_SGI_swap_control' c @@ -102,6 +103,8 @@ #define GLAD_GNUC_EXTENSION #endif +#define GLAD_UNUSED(x) (void)(x) + #ifndef GLAD_API_CALL #if defined(GLAD_API_CALL_EXPORT) #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) @@ -148,7 +151,7 @@ #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.0-beta" +#define GLAD_GENERATOR_VERSION "2.0.2" typedef void (*GLADapiproc)(void); Index: libraries/source/glad/include/glad/wgl.h =================================================================== --- libraries/source/glad/include/glad/wgl.h +++ libraries/source/glad/include/glad/wgl.h @@ -1,5 +1,7 @@ /** - * Loader generated by glad 2.0.0-beta on Tue Mar 29 08:49:07 2022 + * Loader generated by glad 2.0.2 on 11/20/22 13:31:49 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: wgl @@ -9,13 +11,12 @@ * - wgl=1.0 * * Options: + * - ON_DEMAND = False + * - LOADER = False * - ALIAS = False - * - DEBUG = False * - HEADER_ONLY = False - * - LOADER = False + * - DEBUG = False * - MX = False - * - MX_GLOBAL = False - * - ON_DEMAND = False * * Commandline: * --api='wgl=1.0' --extensions='WGL_ARB_extensions_string,WGL_EXT_extensions_string,WGL_EXT_swap_control' c @@ -93,6 +94,8 @@ #define GLAD_GNUC_EXTENSION #endif +#define GLAD_UNUSED(x) (void)(x) + #ifndef GLAD_API_CALL #if defined(GLAD_API_CALL_EXPORT) #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) @@ -139,7 +142,7 @@ #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.0-beta" +#define GLAD_GENERATOR_VERSION "2.0.2" typedef void (*GLADapiproc)(void); @@ -245,8 +248,8 @@ typedef int (GLAD_API_PTR *PFNCHOOSEPIXELFORMATPROC)(HDC hDc, const PIXELFORMATDESCRIPTOR * pPfd); -typedef int (GLAD_API_PTR *PFNDESCRIBEPIXELFORMATPROC)(HDC hdc, int ipfd, UINT cjpfd, const PIXELFORMATDESCRIPTOR * ppfd); -typedef UINT (GLAD_API_PTR *PFNGETENHMETAFILEPIXELFORMATPROC)(HENHMETAFILE hemf, const PIXELFORMATDESCRIPTOR * ppfd); +typedef int (GLAD_API_PTR *PFNDESCRIBEPIXELFORMATPROC)(HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR * ppfd); +typedef UINT (GLAD_API_PTR *PFNGETENHMETAFILEPIXELFORMATPROC)(HENHMETAFILE hemf, UINT cbBuffer, PIXELFORMATDESCRIPTOR * ppfd); typedef int (GLAD_API_PTR *PFNGETPIXELFORMATPROC)(HDC hdc); typedef BOOL (GLAD_API_PTR *PFNSETPIXELFORMATPROC)(HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR * ppfd); typedef BOOL (GLAD_API_PTR *PFNSWAPBUFFERSPROC)(HDC hdc); @@ -254,12 +257,12 @@ typedef HGLRC (GLAD_API_PTR *PFNWGLCREATECONTEXTPROC)(HDC hDc); typedef HGLRC (GLAD_API_PTR *PFNWGLCREATELAYERCONTEXTPROC)(HDC hDc, int level); typedef BOOL (GLAD_API_PTR *PFNWGLDELETECONTEXTPROC)(HGLRC oldContext); -typedef BOOL (GLAD_API_PTR *PFNWGLDESCRIBELAYERPLANEPROC)(HDC hDc, int pixelFormat, int layerPlane, UINT nBytes, const LAYERPLANEDESCRIPTOR * plpd); +typedef BOOL (GLAD_API_PTR *PFNWGLDESCRIBELAYERPLANEPROC)(HDC hDc, int pixelFormat, int layerPlane, UINT nBytes, LAYERPLANEDESCRIPTOR * plpd); typedef HGLRC (GLAD_API_PTR *PFNWGLGETCURRENTCONTEXTPROC)(void); typedef HDC (GLAD_API_PTR *PFNWGLGETCURRENTDCPROC)(void); typedef const char * (GLAD_API_PTR *PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc); typedef const char * (GLAD_API_PTR *PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void); -typedef int (GLAD_API_PTR *PFNWGLGETLAYERPALETTEENTRIESPROC)(HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF * pcr); +typedef int (GLAD_API_PTR *PFNWGLGETLAYERPALETTEENTRIESPROC)(HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF * pcr); typedef PROC (GLAD_API_PTR *PFNWGLGETPROCADDRESSPROC)(LPCSTR lpszProc); typedef int (GLAD_API_PTR *PFNWGLGETSWAPINTERVALEXTPROC)(void); typedef BOOL (GLAD_API_PTR *PFNWGLMAKECURRENTPROC)(HDC hDc, HGLRC newContext); Index: libraries/source/glad/src/gl.cpp =================================================================== --- libraries/source/glad/src/gl.cpp +++ libraries/source/glad/src/gl.cpp @@ -1,3 +1,6 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ #include #include #include @@ -35,6 +38,7 @@ int GLAD_GL_ARB_framebuffer_object = 0; int GLAD_GL_ARB_geometry_shader4 = 0; int GLAD_GL_ARB_instanced_arrays = 0; +int GLAD_GL_ARB_invalidate_subdata = 0; int GLAD_GL_ARB_map_buffer_range = 0; int GLAD_GL_ARB_multitexture = 0; int GLAD_GL_ARB_occlusion_query = 0; @@ -396,6 +400,12 @@ PFNGLINDEXUBVPROC glad_glIndexubv = NULL; PFNGLINITNAMESPROC glad_glInitNames = NULL; PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; +PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL; +PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; +PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL; +PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL; PFNGLISBUFFERPROC glad_glIsBuffer = NULL; PFNGLISBUFFERARBPROC glad_glIsBufferARB = NULL; PFNGLISENABLEDPROC glad_glIsEnabled = NULL; @@ -1541,6 +1551,15 @@ if(!GLAD_GL_ARB_instanced_arrays) return; glad_glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC) load(userptr, "glVertexAttribDivisorARB"); } +static void glad_gl_load_GL_ARB_invalidate_subdata( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ARB_invalidate_subdata) return; + glad_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load(userptr, "glInvalidateBufferData"); + glad_glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load(userptr, "glInvalidateBufferSubData"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load(userptr, "glInvalidateTexImage"); + glad_glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load(userptr, "glInvalidateTexSubImage"); +} static void glad_gl_load_GL_ARB_map_buffer_range( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_GL_ARB_map_buffer_range) return; glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); @@ -1915,9 +1934,9 @@ #if GLAD_GL_IS_SOME_NEW_VERSION if(GLAD_VERSION_MAJOR(version) < 3) { #else - (void) version; - (void) out_num_exts_i; - (void) out_exts_i; + GLAD_UNUSED(version); + GLAD_UNUSED(out_num_exts_i); + GLAD_UNUSED(out_exts_i); #endif if (glad_glGetString == NULL) { return 0; @@ -2016,6 +2035,7 @@ GLAD_GL_ARB_framebuffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_framebuffer_object"); GLAD_GL_ARB_geometry_shader4 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_geometry_shader4"); GLAD_GL_ARB_instanced_arrays = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_instanced_arrays"); + GLAD_GL_ARB_invalidate_subdata = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_invalidate_subdata"); GLAD_GL_ARB_map_buffer_range = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_map_buffer_range"); GLAD_GL_ARB_multitexture = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_multitexture"); GLAD_GL_ARB_occlusion_query = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_occlusion_query"); @@ -2110,6 +2130,7 @@ glad_gl_load_GL_ARB_framebuffer_object(load, userptr); glad_gl_load_GL_ARB_geometry_shader4(load, userptr); glad_gl_load_GL_ARB_instanced_arrays(load, userptr); + glad_gl_load_GL_ARB_invalidate_subdata(load, userptr); glad_gl_load_GL_ARB_map_buffer_range(load, userptr); glad_gl_load_GL_ARB_multitexture(load, userptr); glad_gl_load_GL_ARB_occlusion_query(load, userptr); Index: libraries/source/glad/src/gles2.cpp =================================================================== --- libraries/source/glad/src/gles2.cpp +++ libraries/source/glad/src/gles2.cpp @@ -1,3 +1,6 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ #include #include #include @@ -21,6 +24,7 @@ int GLAD_GL_ES_VERSION_2_0 = 0; +int GLAD_GL_EXT_discard_framebuffer = 0; int GLAD_GL_EXT_texture_compression_s3tc = 0; int GLAD_GL_EXT_texture_filter_anisotropic = 0; int GLAD_GL_EXT_texture_format_BGRA8888 = 0; @@ -75,6 +79,7 @@ PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; PFNGLDISABLEPROC glad_glDisable = NULL; PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDISCARDFRAMEBUFFEREXTPROC glad_glDiscardFramebufferEXT = NULL; PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; PFNGLENABLEPROC glad_glEnable = NULL; @@ -343,6 +348,10 @@ glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); } +static void glad_gl_load_GL_EXT_discard_framebuffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_discard_framebuffer) return; + glad_glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC) load(userptr, "glDiscardFramebufferEXT"); +} static void glad_gl_load_GL_KHR_debug( GLADuserptrloadfunc load, void* userptr) { if(!GLAD_GL_KHR_debug) return; glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC) load(userptr, "glDebugMessageCallbackKHR"); @@ -387,9 +396,9 @@ #if GLAD_GL_IS_SOME_NEW_VERSION if(GLAD_VERSION_MAJOR(version) < 3) { #else - (void) version; - (void) out_num_exts_i; - (void) out_exts_i; + GLAD_UNUSED(version); + GLAD_UNUSED(out_num_exts_i); + GLAD_UNUSED(out_exts_i); #endif if (glad_glGetString == NULL) { return 0; @@ -481,6 +490,7 @@ char **exts_i = NULL; if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0; + GLAD_GL_EXT_discard_framebuffer = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_discard_framebuffer"); GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_compression_s3tc"); GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_filter_anisotropic"); GLAD_GL_EXT_texture_format_BGRA8888 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_format_BGRA8888"); @@ -535,6 +545,7 @@ glad_gl_load_GL_ES_VERSION_2_0(load, userptr); if (!glad_gl_find_extensions_gles2(version)) return 0; + glad_gl_load_GL_EXT_discard_framebuffer(load, userptr); glad_gl_load_GL_KHR_debug(load, userptr); glad_gl_load_GL_OES_mapbuffer(load, userptr); glad_gl_load_GL_OES_texture_border_clamp(load, userptr); Index: libraries/source/glad/src/glx.cpp =================================================================== --- libraries/source/glad/src/glx.cpp +++ libraries/source/glad/src/glx.cpp @@ -1,3 +1,6 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ #include #include #include @@ -146,9 +149,9 @@ static int glad_glx_has_extension(Display *display, int screen, const char *ext) { #ifndef GLX_VERSION_1_1 - (void) display; - (void) screen; - (void) ext; + GLAD_UNUSED(display); + GLAD_UNUSED(screen); + GLAD_UNUSED(ext); #else const char *terminator; const char *loc; @@ -195,7 +198,7 @@ int major = 0, minor = 0; if(*display == NULL) { #ifdef GLAD_GLX_NO_X11 - (void) screen; + GLAD_UNUSED(screen); return 0; #else *display = XOpenDisplay(0); @@ -229,6 +232,7 @@ if (!glad_glx_find_extensions(display, screen)) return 0; glad_glx_load_GLX_MESA_query_renderer(load, userptr); glad_glx_load_GLX_SGI_swap_control(load, userptr); + return version; } Index: libraries/source/glad/src/wgl.cpp =================================================================== --- libraries/source/glad/src/wgl.cpp +++ libraries/source/glad/src/wgl.cpp @@ -1,3 +1,6 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ #include #include #include @@ -111,6 +114,7 @@ glad_wgl_load_WGL_ARB_extensions_string(load, userptr); glad_wgl_load_WGL_EXT_extensions_string(load, userptr); glad_wgl_load_WGL_EXT_swap_control(load, userptr); + return version; } Index: libraries/source/glad/update-headers.cmd =================================================================== --- libraries/source/glad/update-headers.cmd +++ libraries/source/glad/update-headers.cmd @@ -1,9 +1,9 @@ @echo off cd glad -python -m glad --api="gl:core=2.1" --extensions="../extensions/gl.txt" --out-path="../" -python -m glad --api="gles2=2.0" --extensions="../extensions/gles2.txt" --out-path="../" -python -m glad --api="glx=1.4" --extensions="../extensions/glx.txt" --out-path="../" -python -m glad --api="wgl=1.0" --extensions="../extensions/wgl.txt" --out-path="../" +python -m glad --api="gl:core=2.1" --extensions="../extensions/gl.txt" --out-path="../" c +python -m glad --api="gles2=2.0" --extensions="../extensions/gles2.txt" --out-path="../" c +python -m glad --api="glx=1.4" --extensions="../extensions/glx.txt" --out-path="../" c +python -m glad --api="wgl=1.0" --extensions="../extensions/wgl.txt" --out-path="../" c cd .. MOVE src\gl.c src\gl.cpp MOVE src\gles2.c src\gles2.cpp Index: libraries/source/glad/update-headers.sh =================================================================== --- libraries/source/glad/update-headers.sh +++ libraries/source/glad/update-headers.sh @@ -1,10 +1,10 @@ #!/bin/sh cd glad -python -m glad --api="gl:core=2.1" --extensions="../extensions/gl.txt" --out-path="../" -python -m glad --api="gles2=2.0" --extensions="../extensions/gles2.txt" --out-path="../" -python -m glad --api="glx=1.4" --extensions="../extensions/glx.txt" --out-path="../" -python -m glad --api="wgl=1.0" --extensions="../extensions/wgl.txt" --out-path="../" -python -m glad --api="egl=1.5" --extensions="../extensions/egl.txt" --out-path="../" +python -m glad --api="gl:core=2.1" --extensions="../extensions/gl.txt" --out-path="../" c +python -m glad --api="gles2=2.0" --extensions="../extensions/gles2.txt" --out-path="../" c +python -m glad --api="glx=1.4" --extensions="../extensions/glx.txt" --out-path="../" c +python -m glad --api="wgl=1.0" --extensions="../extensions/wgl.txt" --out-path="../" c +python -m glad --api="egl=1.5" --extensions="../extensions/egl.txt" --out-path="../" c cd .. mv src/gl.c src/gl.cpp mv src/gles2.c src/gles2.cpp Index: source/graphics/LOSTexture.cpp =================================================================== --- source/graphics/LOSTexture.cpp +++ source/graphics/LOSTexture.cpp @@ -282,9 +282,19 @@ usage, m_TextureFormat, textureSize, textureSize, defaultSamplerDesc); m_SmoothFramebuffers[0] = backendDevice->CreateFramebuffer( - "LOSSmoothFramebuffer0", m_SmoothTextures[0].get(), nullptr); + "LOSSmoothFramebuffer0", m_SmoothTextures[0].get(), + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), nullptr, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); m_SmoothFramebuffers[1] = backendDevice->CreateFramebuffer( - "LOSSmoothFramebuffer1", m_SmoothTextures[1].get(), nullptr); + "LOSSmoothFramebuffer1", m_SmoothTextures[1].get(), + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), nullptr, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); if (!m_SmoothFramebuffers[0] || !m_SmoothFramebuffers[1]) { LOGERROR("Failed to create LOS framebuffers"); Index: source/graphics/MiniMapTexture.cpp =================================================================== --- source/graphics/MiniMapTexture.cpp +++ source/graphics/MiniMapTexture.cpp @@ -355,8 +355,13 @@ Renderer::Backend::Format::R8G8B8A8_UNORM, FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, defaultSamplerDesc)); - m_FinalTextureFramebuffer = backendDevice->CreateFramebuffer("MiniMapFinalFramebuffer", - m_FinalTexture->GetBackendTexture(), nullptr); + m_FinalTextureFramebuffer = backendDevice->CreateFramebuffer( + "MiniMapFinalFramebuffer", m_FinalTexture->GetBackendTexture(), + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), nullptr, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); ENSURE(m_FinalTextureFramebuffer); } Index: source/renderer/PostprocManager.h =================================================================== --- source/renderer/PostprocManager.h +++ source/renderer/PostprocManager.h @@ -74,10 +74,13 @@ void ApplyPostproc( Renderer::Backend::IDeviceCommandContext* deviceCommandContext); - // Blits the final postprocessed texture to the system framebuffer. The system framebuffer - // is selected as the output buffer. Should be called before silhouette rendering. + // Blits the final postprocessed texture to the system framebuffer. The system + // framebuffer is selected as the output buffer. Should be called before + // silhouette rendering. // @note CPostprocManager must be initialized first - void ReleaseRenderOutput(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); + void ReleaseRenderOutput( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + Renderer::Backend::IFramebuffer* destination); // Returns true if we render main scene in the MSAA framebuffer. bool IsMultisampleEnabled() const; Index: source/renderer/PostprocManager.cpp =================================================================== --- source/renderer/PostprocManager.cpp +++ source/renderer/PostprocManager.cpp @@ -148,8 +148,13 @@ for (BlurScale::Step& step : scale.steps) { GEN_BUFFER_RGBA(step.texture, width, height); - step.framebuffer = backendDevice->CreateFramebuffer("BlurScaleSteoFramebuffer", - step.texture.get(), nullptr); + step.framebuffer = backendDevice->CreateFramebuffer( + "BlurScaleSteoFramebuffer", step.texture.get(), + Renderer::Backend::AttachmentLoadOp::LOAD, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), nullptr, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); } width /= 2; height /= 2; @@ -168,12 +173,27 @@ // Set up the framebuffers with some initial textures. m_CaptureFramebuffer = backendDevice->CreateFramebuffer("PostprocCaptureFramebuffer", - m_ColorTex1.get(), m_DepthTex.get(), CColor(0.0f, 0.0f, 0.0f, 0.0f)); + m_ColorTex1.get(), + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), m_DepthTex.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE); m_PingFramebuffer = backendDevice->CreateFramebuffer("PostprocPingFramebuffer", - m_ColorTex1.get(), nullptr); + m_ColorTex1.get(), + Renderer::Backend::AttachmentLoadOp::LOAD, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), nullptr, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); m_PongFramebuffer = backendDevice->CreateFramebuffer("PostprocPongFramebuffer", - m_ColorTex2.get(), nullptr); + m_ColorTex2.get(), + Renderer::Backend::AttachmentLoadOp::LOAD, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), nullptr, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); if (!m_CaptureFramebuffer || !m_PingFramebuffer || !m_PongFramebuffer) { @@ -403,7 +423,8 @@ void CPostprocManager::ReleaseRenderOutput( - Renderer::Backend::IDeviceCommandContext* deviceCommandContext) + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + Renderer::Backend::IFramebuffer* destination) { ENSURE(m_IsInitialized); @@ -411,8 +432,7 @@ // We blit to the backbuffer from the previous active buffer. deviceCommandContext->BlitFramebuffer( - deviceCommandContext->GetDevice()->GetCurrentBackbuffer(), - (m_WhichBuffer ? m_PingFramebuffer : m_PongFramebuffer).get()); + destination, (m_WhichBuffer ? m_PingFramebuffer : m_PongFramebuffer).get()); } void CPostprocManager::ApplyEffect( @@ -675,8 +695,13 @@ Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, m_MultisampleCount); // Set up the framebuffers with some initial textures. - m_MultisampleFramebuffer = backendDevice->CreateFramebuffer("PostprocMultisampleFramebuffer", - m_MultisampleColorTex.get(), m_MultisampleDepthTex.get(), CColor(0.0f, 0.0f, 0.0f, 0.0f)); + m_MultisampleFramebuffer = backendDevice->CreateFramebuffer( + "PostprocMultisampleFramebuffer", m_MultisampleColorTex.get(), + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), m_MultisampleDepthTex.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE); if (!m_MultisampleFramebuffer) { Index: source/renderer/Renderer.cpp =================================================================== --- source/renderer/Renderer.cpp +++ source/renderer/Renderer.cpp @@ -482,8 +482,14 @@ } else { + // We don't need to clear the color attachment of the framebuffer as the sky + // is going to be rendered anyway. m->deviceCommandContext->BeginFramebufferPass( - m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::DONT_CARE)); } g_Game->GetView()->Render(m->deviceCommandContext.get()); @@ -496,29 +502,41 @@ postprocManager.ResolveMultisampleFramebuffer(m->deviceCommandContext.get()); postprocManager.ApplyPostproc(m->deviceCommandContext.get()); - postprocManager.ReleaseRenderOutput(m->deviceCommandContext.get()); - m->deviceCommandContext->BeginFramebufferPass( - m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + Renderer::Backend::IFramebuffer* backbuffer = + m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::LOAD, + Renderer::Backend::AttachmentStoreOp::STORE, + Renderer::Backend::AttachmentLoadOp::LOAD, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); + postprocManager.ReleaseRenderOutput( + m->deviceCommandContext.get(), backbuffer); + + m->deviceCommandContext->BeginFramebufferPass(backbuffer); } g_Game->GetView()->RenderOverlays(m->deviceCommandContext.get()); + + g_Game->GetView()->GetCinema()->Render(); } else { + // We have a fullscreen background in our UI so we don't need + // to clear the color attachment. + // We don't need a depth test to render so we don't care about the + // depth-stencil attachment content. m->deviceCommandContext->BeginFramebufferPass( - m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE)); } // If we're in Atlas game view, render special tools if (g_AtlasGameLoop && g_AtlasGameLoop->view) { g_AtlasGameLoop->view->DrawCinemaPathTool(); - } - - if (g_Game && g_Game->IsGameStarted()) - { - g_Game->GetView()->GetCinema()->Render(); } RenderFrame2D(renderGUI, renderLogger); Index: source/renderer/SceneRenderer.cpp =================================================================== --- source/renderer/SceneRenderer.cpp +++ source/renderer/SceneRenderer.cpp @@ -589,7 +589,6 @@ deviceCommandContext->SetGraphicsPipelineState( Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc()); deviceCommandContext->BeginFramebufferPass(wm.m_ReflectionFramebuffer.get()); - deviceCommandContext->ClearFramebuffer(); CShaderDefines reflectionsContext = context; reflectionsContext.Add(str_PASS_REFLECTIONS, str_1); @@ -665,7 +664,6 @@ deviceCommandContext->SetGraphicsPipelineState( Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc()); deviceCommandContext->BeginFramebufferPass(wm.m_RefractionFramebuffer.get()); - deviceCommandContext->ClearFramebuffer(); // Render terrain and models RenderPatches(deviceCommandContext, context, CULL_REFRACTIONS); @@ -840,13 +838,6 @@ CShaderDefines context = m->globalContext; constexpr int cullGroup = CULL_DEFAULT; - - { - PROFILE3_GPU("clear buffers"); - // We don't need to clear the color attachment of the framebuffer if the sky - // is going to be rendered. Because it covers the whole view. - deviceCommandContext->ClearFramebuffer(!m->skyManager.IsSkyVisible(), true, true); - } m->skyManager.RenderSky(deviceCommandContext); Index: source/renderer/ShadowMap.cpp =================================================================== --- source/renderer/ShadowMap.cpp +++ source/renderer/ShadowMap.cpp @@ -510,7 +510,7 @@ const char* formatName; Renderer::Backend::Format backendFormat = Renderer::Backend::Format::UNDEFINED; #if CONFIG2_GLES - formatName = "DEPTH_COMPONENT"; + formatName = "Format::D24"; backendFormat = Renderer::Backend::Format::D24; #else switch (DepthTextureBits) @@ -556,8 +556,19 @@ Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, backendFormat, Width, Height, samplerDesc); + const bool useDummyTexture = g_RenderingOptions.GetShadowAlphaFix(); Framebuffer = backendDevice->CreateFramebuffer("ShadowMapFramebuffer", - g_RenderingOptions.GetShadowAlphaFix() ? DummyTexture.get() : nullptr, Texture.get()); + useDummyTexture ? DummyTexture.get() : nullptr, + // In case we used m_ShadowAlphaFix, we ought to clear the unused + // color buffer too, else Mali 400 drivers get confused. + // Might as well clear stencil too for completeness. + useDummyTexture + ? Renderer::Backend::AttachmentLoadOp::CLEAR + : Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), Texture.get(), + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE); if (!Framebuffer) { @@ -574,20 +585,8 @@ deviceCommandContext->SetGraphicsPipelineState( Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc()); - { - PROFILE("bind framebuffer"); - ENSURE(m->Framebuffer); - deviceCommandContext->BeginFramebufferPass(m->Framebuffer.get()); - } - - // clear buffers - { - PROFILE("clear depth texture"); - // In case we used m_ShadowAlphaFix, we ought to clear the unused - // color buffer too, else Mali 400 drivers get confused. - // Might as well clear stencil too for completeness. - deviceCommandContext->ClearFramebuffer(); - } + ENSURE(m->Framebuffer); + deviceCommandContext->BeginFramebufferPass(m->Framebuffer.get()); m->SavedViewCamera = g_Renderer.GetSceneRenderer().GetViewCamera(); } Index: source/renderer/SkyManager.cpp =================================================================== --- source/renderer/SkyManager.cpp +++ source/renderer/SkyManager.cpp @@ -212,12 +212,10 @@ { GPU_SCOPED_LABEL(deviceCommandContext, "Render sky"); - if (!m_SkyVisible) - return; - - // Do nothing unless SetSkySet was called - if (m_SkySet.empty() || !m_SkyTextureCube) - return; + const CTexturePtr& skyTextureCube = + !m_SkyVisible || m_SkySet.empty() || !m_SkyTextureCube + ? g_Renderer.GetTextureManager().GetBlackTextureCube() + : m_SkyTextureCube; const CCamera& camera = g_Renderer.GetSceneRenderer().GetViewCamera(); @@ -228,7 +226,7 @@ deviceCommandContext->BeginPass(); Renderer::Backend::IShaderProgram* shader = skytech->GetShader(); deviceCommandContext->SetTexture( - shader->GetBindingSlot(str_baseTex), m_SkyTextureCube->GetBackendTexture()); + shader->GetBindingSlot(str_baseTex), skyTextureCube->GetBackendTexture()); // Translate so the sky center is at the camera space origin. CMatrix3D translate; Index: source/renderer/WaterManager.cpp =================================================================== --- source/renderer/WaterManager.cpp +++ source/renderer/WaterManager.cpp @@ -218,13 +218,18 @@ m_ReflFboDepthTexture = backendDevice->CreateTexture2D("WaterReflectionDepthTexture", Renderer::Backend::ITexture::Usage::SAMPLED | Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, - Renderer::Backend::Format::D32, m_RefTextureSize, m_RefTextureSize, + Renderer::Backend::Format::D24, m_RefTextureSize, m_RefTextureSize, Renderer::Backend::Sampler::MakeDefaultSampler( Renderer::Backend::Sampler::Filter::NEAREST, Renderer::Backend::Sampler::AddressMode::REPEAT)); m_ReflectionFramebuffer = backendDevice->CreateFramebuffer("ReflectionFramebuffer", - m_ReflectionTexture.get(), m_ReflFboDepthTexture.get(), CColor(0.5f, 0.5f, 1.0f, 0.0f)); + m_ReflectionTexture.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.5f, 0.5f, 1.0f, 0.0f), m_ReflFboDepthTexture.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE); if (!m_ReflectionFramebuffer) { g_RenderingOptions.SetWaterReflection(false); @@ -249,13 +254,18 @@ m_RefrFboDepthTexture = backendDevice->CreateTexture2D("WaterRefractionDepthTexture", Renderer::Backend::ITexture::Usage::SAMPLED | Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, - Renderer::Backend::Format::D32, m_RefTextureSize, m_RefTextureSize, + Renderer::Backend::Format::D24, m_RefTextureSize, m_RefTextureSize, Renderer::Backend::Sampler::MakeDefaultSampler( Renderer::Backend::Sampler::Filter::NEAREST, Renderer::Backend::Sampler::AddressMode::REPEAT)); m_RefractionFramebuffer = backendDevice->CreateFramebuffer("RefractionFramebuffer", - m_RefractionTexture.get(), m_RefrFboDepthTexture.get(), CColor(1.0f, 0.0f, 0.0f, 0.0f)); + m_RefractionTexture.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(1.0f, 0.0f, 0.0f, 0.0f), m_RefrFboDepthTexture.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE); if (!m_RefractionFramebuffer) { g_RenderingOptions.SetWaterRefraction(false); @@ -288,13 +298,18 @@ m_FancyTextureDepth = backendDevice->CreateTexture2D("WaterFancyDepthTexture", Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, - Renderer::Backend::Format::D32, g_Renderer.GetWidth(), g_Renderer.GetHeight(), + Renderer::Backend::Format::D24, g_Renderer.GetWidth(), g_Renderer.GetHeight(), Renderer::Backend::Sampler::MakeDefaultSampler( Renderer::Backend::Sampler::Filter::LINEAR, Renderer::Backend::Sampler::AddressMode::REPEAT)); m_FancyEffectsFramebuffer = backendDevice->CreateFramebuffer("FancyEffectsFramebuffer", - m_FancyTexture.get(), m_FancyTextureDepth.get()); + m_FancyTexture.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::STORE, + CColor(0.0f, 0.0f, 0.0f, 0.0f), m_FancyTextureDepth.get(), + Renderer::Backend::AttachmentLoadOp::CLEAR, + Renderer::Backend::AttachmentStoreOp::DONT_CARE); if (!m_FancyEffectsFramebuffer) { g_RenderingOptions.SetWaterRefraction(false); @@ -810,7 +825,6 @@ deviceCommandContext->SetGraphicsPipelineState( Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc()); deviceCommandContext->BeginFramebufferPass(m_FancyEffectsFramebuffer.get()); - deviceCommandContext->ClearFramebuffer(); CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_water_waves); deviceCommandContext->SetGraphicsPipelineState( Index: source/renderer/backend/IDevice.h =================================================================== --- source/renderer/backend/IDevice.h +++ source/renderer/backend/IDevice.h @@ -72,8 +72,6 @@ virtual void Report(const ScriptRequest& rq, JS::HandleValue settings) = 0; - virtual IFramebuffer* GetCurrentBackbuffer() = 0; - virtual std::unique_ptr CreateCommandContext() = 0; virtual std::unique_ptr CreateTexture( @@ -86,13 +84,23 @@ const Format format, const uint32_t width, const uint32_t height, const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) = 0; + /** + * @see IFramebuffer + * + * The color attachment and the depth-stencil attachment should not be + * nullptr at the same time. There should not be many different clear + * colors along all color attachments for all framebuffers created for + * the device. + * + * @return A valid framebuffer if it was created successfully else nullptr. + */ virtual std::unique_ptr CreateFramebuffer( const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment) = 0; - - virtual std::unique_ptr CreateFramebuffer( - const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment, const CColor& clearColor) = 0; + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, ITexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) = 0; virtual std::unique_ptr CreateBuffer( const char* name, const IBuffer::Type type, const uint32_t size, const bool dynamic) = 0; @@ -100,7 +108,36 @@ virtual std::unique_ptr CreateShaderProgram( const CStr& name, const CShaderDefines& defines) = 0; + /** + * Acquires a backbuffer for rendering a frame. + * + * @return True if it was successfully acquired and we can render to it. + */ virtual bool AcquireNextBackbuffer() = 0; + + /** + * Returns a framebuffer for the current backbuffer with the required + * attachment operations. It should not be called if the last + * AcquireNextBackbuffer call returned false. + * + * It's guaranteed that for the same acquired backbuffer this function returns + * a framebuffer with the same attachments and properties except load and + * store operations. + * + * @return The last successfully acquired framebuffer that wasn't + * presented. + */ + virtual IFramebuffer* GetCurrentBackbuffer( + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) = 0; + + /** + * Presents the backbuffer to the swapchain queue to be flipped on a + * screen. Should be called only if the last AcquireNextBackbuffer call + * returned true. + */ virtual void Present() = 0; virtual bool IsTextureFormatSupported(const Format format) const = 0; Index: source/renderer/backend/IDeviceCommandContext.h =================================================================== --- source/renderer/backend/IDeviceCommandContext.h +++ source/renderer/backend/IDeviceCommandContext.h @@ -45,10 +45,25 @@ virtual void BlitFramebuffer( IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) = 0; - virtual void ClearFramebuffer() = 0; - virtual void ClearFramebuffer(const bool color, const bool depth, const bool stencil) = 0; + /** + * Starts a framebuffer pass, performs attachment load operations. + * It should be called as rarely as possible. + * + * @see IFramebuffer + */ virtual void BeginFramebufferPass(IFramebuffer* framebuffer) = 0; + + /** + * Finishes a framebuffer pass, performs attachment store operations. + */ virtual void EndFramebufferPass() = 0; + + /** + * Clears all mentioned attachments. Prefer to use attachment load operations over + * this function. It should be called only inside a framebuffer pass. + */ + virtual void ClearFramebuffer(const bool color, const bool depth, const bool stencil) = 0; + virtual void ReadbackFramebufferSync( const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height, void* data) = 0; Index: source/renderer/backend/IFramebuffer.h =================================================================== --- source/renderer/backend/IFramebuffer.h +++ source/renderer/backend/IFramebuffer.h @@ -27,9 +27,50 @@ namespace Backend { +/** + * Load operation is set for each attachment, what should be done with its + * content on BeginFramebufferPass. + */ +enum class AttachmentLoadOp +{ + // Loads the attachment content. + LOAD, + // Clears the attachment content without loading. Prefer to use that + // operation over manual ClearFramebuffer. + CLEAR, + // After BeginFramebufferPass the attachment content is undefined. + DONT_CARE +}; + +/** + * Store operation is set for each attachment, what should be done with its + * content on EndFramebufferPass. + */ +enum class AttachmentStoreOp +{ + // Stores the attachment content. + STORE, + // After EndFramebufferPass the attachment content is undefined. + DONT_CARE +}; + +/** + * IFramebuffer stores attachments which should be used by backend as rendering + * destinations. That combining allows to set these destinations at once. + * IFramebuffer doesn't own its attachments so clients must keep them alive. + * The number of framebuffers ever created for a device during its lifetime + * should be as small as possible. + * + * Framebuffer is a term from OpenGL/Vulkan worlds (D3D synonym is a render + * target). + */ class IFramebuffer : public IDeviceObject { public: + /** + * Returns a clear color for all color attachments of the framebuffer. + * @see IDevice::CreateFramebuffer() + */ virtual const CColor& GetClearColor() const = 0; }; Index: source/renderer/backend/dummy/Device.h =================================================================== --- source/renderer/backend/dummy/Device.h +++ source/renderer/backend/dummy/Device.h @@ -49,8 +49,6 @@ void Report(const ScriptRequest& rq, JS::HandleValue settings) override; - IFramebuffer* GetCurrentBackbuffer() override { return m_Backbuffer.get(); } - std::unique_ptr CreateCommandContext() override; std::unique_ptr CreateTexture( @@ -65,11 +63,11 @@ std::unique_ptr CreateFramebuffer( const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment) override; - - std::unique_ptr CreateFramebuffer( - const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment, const CColor& clearColor) override; + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, ITexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) override; std::unique_ptr CreateBuffer( const char* name, const IBuffer::Type type, const uint32_t size, const bool dynamic) override; @@ -78,6 +76,11 @@ const CStr& name, const CShaderDefines& defines) override; bool AcquireNextBackbuffer() override; + + IFramebuffer* GetCurrentBackbuffer( + const AttachmentLoadOp, const AttachmentStoreOp, + const AttachmentLoadOp, const AttachmentStoreOp) override; + void Present() override; bool IsTextureFormatSupported(const Format format) const override; Index: source/renderer/backend/dummy/Device.cpp =================================================================== --- source/renderer/backend/dummy/Device.cpp +++ source/renderer/backend/dummy/Device.cpp @@ -91,13 +91,9 @@ } std::unique_ptr CDevice::CreateFramebuffer( - const char*, ITexture*, ITexture*) -{ - return CFramebuffer::Create(this); -} - -std::unique_ptr CDevice::CreateFramebuffer( - const char*, ITexture*, ITexture*, const CColor&) + const char*, ITexture*, const AttachmentLoadOp, + const AttachmentStoreOp, const CColor&, ITexture*, + const AttachmentLoadOp, const AttachmentStoreOp) { return CFramebuffer::Create(this); } @@ -118,6 +114,13 @@ { // We have nothing to acquire. return true; +} + +IFramebuffer* CDevice::GetCurrentBackbuffer( + const AttachmentLoadOp, const AttachmentStoreOp, + const AttachmentLoadOp, const AttachmentStoreOp) +{ + return m_Backbuffer.get(); } void CDevice::Present() Index: source/renderer/backend/dummy/DeviceCommandContext.h =================================================================== --- source/renderer/backend/dummy/DeviceCommandContext.h +++ source/renderer/backend/dummy/DeviceCommandContext.h @@ -50,7 +50,6 @@ void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override; - void ClearFramebuffer() override; void ClearFramebuffer(const bool color, const bool depth, const bool stencil) override; void BeginFramebufferPass(IFramebuffer* framebuffer) override; void EndFramebufferPass() override; Index: source/renderer/backend/dummy/DeviceCommandContext.cpp =================================================================== --- source/renderer/backend/dummy/DeviceCommandContext.cpp +++ source/renderer/backend/dummy/DeviceCommandContext.cpp @@ -103,10 +103,6 @@ { } -void CDeviceCommandContext::ClearFramebuffer() -{ -} - void CDeviceCommandContext::ClearFramebuffer(const bool, const bool, const bool) { } Index: source/renderer/backend/gl/Device.h =================================================================== --- source/renderer/backend/gl/Device.h +++ source/renderer/backend/gl/Device.h @@ -29,6 +29,8 @@ #include #include +#include +#include #include typedef struct SDL_Window SDL_Window; @@ -64,8 +66,6 @@ void Report(const ScriptRequest& rq, JS::HandleValue settings) override; - IFramebuffer* GetCurrentBackbuffer() override { return m_Backbuffer.get(); } - std::unique_ptr CreateCommandContext() override; CDeviceCommandContext* GetActiveCommandContext() { return m_ActiveCommandContext; } @@ -82,11 +82,11 @@ std::unique_ptr CreateFramebuffer( const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment) override; - - std::unique_ptr CreateFramebuffer( - const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment, const CColor& clearColor) override; + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, ITexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) override; std::unique_ptr CreateBuffer( const char* name, const IBuffer::Type type, const uint32_t size, const bool dynamic) override; @@ -95,8 +95,17 @@ const CStr& name, const CShaderDefines& defines) override; bool AcquireNextBackbuffer() override; + + IFramebuffer* GetCurrentBackbuffer( + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) override; + void Present() override; + bool UseFramebufferInvalidating() const { return m_UseFramebufferInvalidating; } + bool IsTextureFormatSupported(const Format format) const override; bool IsFramebufferFormatSupported(const Format format) const override; @@ -121,8 +130,17 @@ // it's used only as a helper for transition. CDeviceCommandContext* m_ActiveCommandContext = nullptr; - std::unique_ptr m_Backbuffer; + using BackbufferKey = std::tuple< + AttachmentLoadOp, AttachmentStoreOp, + AttachmentLoadOp, AttachmentStoreOp>; + struct BackbufferKeyHash + { + size_t operator()(const BackbufferKey& key) const; + }; + std::unordered_map< + BackbufferKey, std::unique_ptr, BackbufferKeyHash> m_Backbuffers; bool m_BackbufferAcquired = false; + bool m_UseFramebufferInvalidating = false; Capabilities m_Capabilities{}; }; Index: source/renderer/backend/gl/Device.cpp =================================================================== --- source/renderer/backend/gl/Device.cpp +++ source/renderer/backend/gl/Device.cpp @@ -20,6 +20,7 @@ #include "Device.h" #include "lib/external_libraries/libsdl.h" +#include "lib/hash.h" #include "lib/ogl.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" @@ -358,7 +359,11 @@ #endif } - device->m_Backbuffer = CFramebuffer::CreateBackbuffer(device.get()); +#if CONFIG2_GLES + device->m_UseFramebufferInvalidating = ogl_HaveExtension("GL_EXT_discard_framebuffer"); +#else + device->m_UseFramebufferInvalidating = !arb && ogl_HaveExtension("GL_ARB_invalidate_subdata"); +#endif Capabilities& capabilities = device->m_Capabilities; capabilities.ARBShaders = !ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", nullptr); @@ -881,17 +886,17 @@ std::unique_ptr CDevice::CreateFramebuffer( const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment) -{ - return CreateFramebuffer(name, colorAttachment, depthStencilAttachment, CColor(0.0f, 0.0f, 0.0f, 0.0f)); -} - -std::unique_ptr CDevice::CreateFramebuffer( - const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment, const CColor& clearColor) + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, ITexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) { return CFramebuffer::Create( - this, name, colorAttachment->As(), depthStencilAttachment->As(), clearColor); + this, name, colorAttachment->As(), + colorAttachmentLoadOp, colorAttachmentStoreOp, + clearColor, depthStencilAttachment->As(), + depthStencilAttachmentLoadOp, depthStencilAttachmentStoreOp); } std::unique_ptr CDevice::CreateBuffer( @@ -911,6 +916,35 @@ ENSURE(!m_BackbufferAcquired); m_BackbufferAcquired = true; return true; +} + +size_t CDevice::BackbufferKeyHash::operator()(const BackbufferKey& key) const +{ + size_t seed = 0; + hash_combine(seed, std::get<0>(key)); + hash_combine(seed, std::get<1>(key)); + hash_combine(seed, std::get<2>(key)); + hash_combine(seed, std::get<3>(key)); + return seed; +} + +IFramebuffer* CDevice::GetCurrentBackbuffer( + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) +{ + const BackbufferKey key{ + colorAttachmentLoadOp, colorAttachmentStoreOp, + depthStencilAttachmentLoadOp, depthStencilAttachmentStoreOp}; + auto it = m_Backbuffers.find(key); + if (it == m_Backbuffers.end()) + { + it = m_Backbuffers.emplace(key, CFramebuffer::CreateBackbuffer( + this, colorAttachmentLoadOp, colorAttachmentStoreOp, + depthStencilAttachmentLoadOp, depthStencilAttachmentStoreOp)).first; + } + return it->second.get(); } void CDevice::Present() Index: source/renderer/backend/gl/DeviceCommandContext.h =================================================================== --- source/renderer/backend/gl/DeviceCommandContext.h +++ source/renderer/backend/gl/DeviceCommandContext.h @@ -57,10 +57,9 @@ void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override; - void ClearFramebuffer() override; - void ClearFramebuffer(const bool color, const bool depth, const bool stencil) override; void BeginFramebufferPass(IFramebuffer* framebuffer) override; void EndFramebufferPass() override; + void ClearFramebuffer(const bool color, const bool depth, const bool stencil) override; void ReadbackFramebufferSync( const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height, void* data) override; Index: source/renderer/backend/gl/DeviceCommandContext.cpp =================================================================== --- source/renderer/backend/gl/DeviceCommandContext.cpp +++ source/renderer/backend/gl/DeviceCommandContext.cpp @@ -150,13 +150,76 @@ } } +/** + * In case we don't need a framebuffer content (because of the following clear + * or overwriting by a shader) we might give a hint to a driver via + * glInvalidateFramebuffer. + */ +void InvalidateFramebuffer( + CFramebuffer* framebuffer, const bool color, const bool depthStencil) +{ + GLsizei numberOfAttachments = 0; + GLenum attachments[8]; + const bool isBackbuffer = framebuffer->GetHandle() == 0; + if (color && (framebuffer->GetAttachmentMask() & GL_COLOR_BUFFER_BIT)) + { + if (isBackbuffer) +#if CONFIG2_GLES + attachments[numberOfAttachments++] = GL_COLOR_EXT; +#else + attachments[numberOfAttachments++] = GL_COLOR; +#endif + else + attachments[numberOfAttachments++] = GL_COLOR_ATTACHMENT0; + } + if (depthStencil) + { + if (isBackbuffer) + { + if (framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) +#if CONFIG2_GLES + attachments[numberOfAttachments++] = GL_DEPTH_EXT; +#else + attachments[numberOfAttachments++] = GL_DEPTH; +#endif + if (framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) +#if CONFIG2_GLES + attachments[numberOfAttachments++] = GL_STENCIL_EXT; +#else + attachments[numberOfAttachments++] = GL_STENCIL; +#endif + } + else + { + if (framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) + attachments[numberOfAttachments++] = GL_DEPTH_ATTACHMENT; + if (framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) + attachments[numberOfAttachments++] = GL_STENCIL_ATTACHMENT; + } + } + + if (numberOfAttachments > 0) + { +#if CONFIG2_GLES + glDiscardFramebufferEXT(GL_FRAMEBUFFER_EXT, numberOfAttachments, attachments); +#else + glInvalidateFramebuffer(GL_FRAMEBUFFER_EXT, numberOfAttachments, attachments); +#endif + ogl_WarnIfError(); + } +} + } // anonymous namespace // static std::unique_ptr CDeviceCommandContext::Create(CDevice* device) { std::unique_ptr deviceCommandContext(new CDeviceCommandContext(device)); - deviceCommandContext->m_Framebuffer = static_cast(device->GetCurrentBackbuffer()); + deviceCommandContext->m_Framebuffer = device->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE)->As(); deviceCommandContext->ResetStates(); return deviceCommandContext; } @@ -483,7 +546,11 @@ { SetGraphicsPipelineStateImpl(MakeDefaultGraphicsPipelineStateDesc(), true); SetScissors(0, nullptr); - m_Framebuffer = static_cast(m_Device->GetCurrentBackbuffer()); + m_Framebuffer = m_Device->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE)->As(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); ogl_WarnIfError(); } @@ -761,13 +828,9 @@ #endif } -void CDeviceCommandContext::ClearFramebuffer() -{ - ClearFramebuffer(true, true, true); -} - void CDeviceCommandContext::ClearFramebuffer(const bool color, const bool depth, const bool stencil) { + ENSURE(m_InsideFramebufferPass); const bool needsColor = color && (m_Framebuffer->GetAttachmentMask() & GL_COLOR_BUFFER_BIT) != 0; const bool needsDepth = depth && (m_Framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) != 0; const bool needsStencil = stencil && (m_Framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) != 0; @@ -811,15 +874,46 @@ ENSURE(m_Framebuffer->GetHandle() == 0 || (m_Framebuffer->GetWidth() > 0 && m_Framebuffer->GetHeight() > 0)); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); ogl_WarnIfError(); + if (m_Device->UseFramebufferInvalidating()) + { + InvalidateFramebuffer( + m_Framebuffer, + m_Framebuffer->GetColorAttachmentLoadOp() != AttachmentLoadOp::LOAD, + m_Framebuffer->GetDepthStencilAttachmentLoadOp() != AttachmentLoadOp::LOAD); + } + const bool needsClearColor = + m_Framebuffer->GetColorAttachmentLoadOp() == AttachmentLoadOp::CLEAR; + const bool needsClearDepthStencil = + m_Framebuffer->GetDepthStencilAttachmentLoadOp() == AttachmentLoadOp::CLEAR; + if (needsClearColor || needsClearDepthStencil) + { + ClearFramebuffer( + needsClearColor, needsClearDepthStencil, needsClearDepthStencil); + } } void CDeviceCommandContext::EndFramebufferPass() { + if (m_Device->UseFramebufferInvalidating()) + { + InvalidateFramebuffer( + m_Framebuffer, + m_Framebuffer->GetColorAttachmentStoreOp() != AttachmentStoreOp::STORE, + m_Framebuffer->GetDepthStencilAttachmentStoreOp() != AttachmentStoreOp::STORE); + } ENSURE(m_InsideFramebufferPass); m_InsideFramebufferPass = false; - m_Framebuffer = static_cast(m_Device->GetCurrentBackbuffer()); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); - ogl_WarnIfError(); + CFramebuffer* framebuffer = m_Device->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE)->As(); + if (framebuffer->GetHandle() != m_Framebuffer->GetHandle()) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer->GetHandle()); + ogl_WarnIfError(); + } + m_Framebuffer = framebuffer; } void CDeviceCommandContext::ReadbackFramebufferSync( Index: source/renderer/backend/gl/Framebuffer.h =================================================================== --- source/renderer/backend/gl/Framebuffer.h +++ source/renderer/backend/gl/Framebuffer.h @@ -49,6 +49,11 @@ GLuint GetHandle() const { return m_Handle; } GLbitfield GetAttachmentMask() const { return m_AttachmentMask; } + AttachmentLoadOp GetColorAttachmentLoadOp() const { return m_ColorAttachmentLoadOp; } + AttachmentStoreOp GetColorAttachmentStoreOp() const { return m_ColorAttachmentStoreOp; } + AttachmentLoadOp GetDepthStencilAttachmentLoadOp() const { return m_DepthStencilAttachmentLoadOp; } + AttachmentStoreOp GetDepthStencilAttachmentStoreOp() const { return m_DepthStencilAttachmentStoreOp; } + uint32_t GetWidth() const { return m_Width; } uint32_t GetHeight() const { return m_Height; } @@ -56,17 +61,33 @@ friend class CDevice; static std::unique_ptr Create( - CDevice* device, const char* name, - CTexture* colorAttachment, CTexture* depthStencilAttachment, const CColor& clearColor); - static std::unique_ptr CreateBackbuffer(CDevice* device); + CDevice* device, const char* name, CTexture* colorAttachment, + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, CTexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp); + static std::unique_ptr CreateBackbuffer( + CDevice* device, + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp); CFramebuffer(); CDevice* m_Device = nullptr; + GLuint m_Handle = 0; uint32_t m_Width = 0, m_Height = 0; GLbitfield m_AttachmentMask = 0; + CColor m_ClearColor; + + AttachmentLoadOp m_ColorAttachmentLoadOp = AttachmentLoadOp::DONT_CARE; + AttachmentStoreOp m_ColorAttachmentStoreOp = AttachmentStoreOp::DONT_CARE; + AttachmentLoadOp m_DepthStencilAttachmentLoadOp = AttachmentLoadOp::DONT_CARE; + AttachmentStoreOp m_DepthStencilAttachmentStoreOp = AttachmentStoreOp::DONT_CARE; }; } // namespace GL Index: source/renderer/backend/gl/Framebuffer.cpp =================================================================== --- source/renderer/backend/gl/Framebuffer.cpp +++ source/renderer/backend/gl/Framebuffer.cpp @@ -36,15 +36,22 @@ // static std::unique_ptr CFramebuffer::Create( - CDevice* device, const char* name, - CTexture* colorAttachment, CTexture* depthStencilAttachment, - const CColor& clearColor) + CDevice* device, const char* name, CTexture* colorAttachment, + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, CTexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) { ENSURE(colorAttachment || depthStencilAttachment); std::unique_ptr framebuffer(new CFramebuffer()); framebuffer->m_Device = device; framebuffer->m_ClearColor = clearColor; + framebuffer->m_ColorAttachmentLoadOp = colorAttachmentLoadOp; + framebuffer->m_ColorAttachmentStoreOp = colorAttachmentStoreOp; + framebuffer->m_DepthStencilAttachmentLoadOp = depthStencilAttachmentLoadOp; + framebuffer->m_DepthStencilAttachmentStoreOp = depthStencilAttachmentStoreOp; glGenFramebuffersEXT(1, &framebuffer->m_Handle); if (!framebuffer->m_Handle) @@ -68,7 +75,7 @@ const GLenum textureTarget = colorAttachment->GetType() == CTexture::Type::TEXTURE_2D_MULTISAMPLE ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; #endif - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, textureTarget, colorAttachment->GetHandle(), 0); } if (depthStencilAttachment) @@ -120,7 +127,7 @@ glDrawBuffer(GL_NONE); } else - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glDrawBuffer(GL_COLOR_ATTACHMENT0); #endif ogl_WarnIfError(); @@ -151,13 +158,21 @@ // static std::unique_ptr CFramebuffer::CreateBackbuffer( - CDevice* device) + CDevice* device, + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) { // Backbuffer for GL is a special case with a zero framebuffer. std::unique_ptr framebuffer(new CFramebuffer()); framebuffer->m_Device = device; framebuffer->m_AttachmentMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; framebuffer->m_ClearColor = CColor(0.0f, 0.0f, 0.0f, 0.0f); + framebuffer->m_ColorAttachmentLoadOp = colorAttachmentLoadOp; + framebuffer->m_ColorAttachmentStoreOp = colorAttachmentStoreOp; + framebuffer->m_DepthStencilAttachmentLoadOp = depthStencilAttachmentLoadOp; + framebuffer->m_DepthStencilAttachmentStoreOp = depthStencilAttachmentStoreOp; return framebuffer; } Index: source/renderer/backend/vulkan/Device.h =================================================================== --- source/renderer/backend/vulkan/Device.h +++ source/renderer/backend/vulkan/Device.h @@ -54,8 +54,6 @@ void Report(const ScriptRequest& rq, JS::HandleValue settings) override; - IFramebuffer* GetCurrentBackbuffer() override; - std::unique_ptr CreateCommandContext() override; std::unique_ptr CreateTexture( @@ -70,11 +68,11 @@ std::unique_ptr CreateFramebuffer( const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment) override; - - std::unique_ptr CreateFramebuffer( - const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment, const CColor& clearColor) override; + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, ITexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) override; std::unique_ptr CreateBuffer( const char* name, const IBuffer::Type type, const uint32_t size, const bool dynamic) override; @@ -83,6 +81,13 @@ const CStr& name, const CShaderDefines& defines) override; bool AcquireNextBackbuffer() override; + + IFramebuffer* GetCurrentBackbuffer( + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) override; + void Present() override; bool IsTextureFormatSupported(const Format format) const override; Index: source/renderer/backend/vulkan/Device.cpp =================================================================== --- source/renderer/backend/vulkan/Device.cpp +++ source/renderer/backend/vulkan/Device.cpp @@ -74,11 +74,6 @@ Script::SetProperty(rq, settings, "status", vulkanSupport); } -IFramebuffer* CDevice::GetCurrentBackbuffer() -{ - return nullptr; -} - std::unique_ptr CDevice::CreateCommandContext() { return nullptr; @@ -113,22 +108,20 @@ std::unique_ptr CDevice::CreateFramebuffer( const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment) + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const CColor& clearColor, ITexture* depthStencilAttachment, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) { UNUSED2(name); UNUSED2(colorAttachment); - UNUSED2(depthStencilAttachment); - return nullptr; -} - -std::unique_ptr CDevice::CreateFramebuffer( - const char* name, ITexture* colorAttachment, - ITexture* depthStencilAttachment, const CColor& clearColor) -{ - UNUSED2(name); - UNUSED2(colorAttachment); - UNUSED2(depthStencilAttachment); + UNUSED2(colorAttachmentLoadOp); + UNUSED2(colorAttachmentStoreOp); UNUSED2(clearColor); + UNUSED2(depthStencilAttachment); + UNUSED2(depthStencilAttachmentLoadOp); + UNUSED2(depthStencilAttachmentStoreOp); return nullptr; } @@ -153,6 +146,15 @@ bool CDevice::AcquireNextBackbuffer() { return false; +} + +IFramebuffer* CDevice::GetCurrentBackbuffer( + const AttachmentLoadOp colorAttachmentLoadOp, + const AttachmentStoreOp colorAttachmentStoreOp, + const AttachmentLoadOp depthStencilAttachmentLoadOp, + const AttachmentStoreOp depthStencilAttachmentStoreOp) +{ + return nullptr; } void CDevice::Present() Index: source/tools/atlas/GameInterface/ActorViewer.cpp =================================================================== --- source/tools/atlas/GameInterface/ActorViewer.cpp +++ source/tools/atlas/GameInterface/ActorViewer.cpp @@ -540,7 +540,11 @@ sceneRenderer.PrepareScene(deviceCommandContext, m); deviceCommandContext->BeginFramebufferPass( - deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + deviceCommandContext->GetDevice()->GetCurrentBackbuffer( + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::STORE, + Renderer::Backend::AttachmentLoadOp::DONT_CARE, + Renderer::Backend::AttachmentStoreOp::DONT_CARE)); sceneRenderer.RenderScene(deviceCommandContext); sceneRenderer.RenderSceneOverlays(deviceCommandContext);