Graphics library for Mercury, including OpenGL bindings, TGA image reading, and X11, Win32, and SDL2 windowing and input.
リビジョン | b66b36f2487d0e3a19333992d0be262a9bdfee0e (tree) |
---|---|
日時 | 2022-06-14 08:04:06 |
作者 | AlaskanEmily <emily@alas...> |
コミッター | AlaskanEmily |
Make supports_extension a generic function on any GL context that has a gl_load_func_ctx.
This prevents the circular dependency on needing a gl_ctx for the context to test, and needing to test for extensions to create the context.
@@ -71,6 +71,7 @@ int SaffronGL_LoadBufferCtx(MR_Word gl_ctx, struct SaffronGL_BufferCtx **ctx_ptr | ||
71 | 71 | int SaffronGL_LoadBufferCtx(MR_Word gl_ctx, struct SaffronGL_BufferCtx **ctx_ptr){ |
72 | 72 | struct SaffronGL_BufferCtx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_BufferCtx)); |
73 | 73 | MR_Word maybe_func, func; |
74 | + MR_Bool have_ext; | |
74 | 75 | MR_String err = NULL; |
75 | 76 | MR_Integer major, minor; |
76 | 77 | SaffronGL_Version(gl_ctx, &major, &minor); |
@@ -80,7 +81,8 @@ int SaffronGL_LoadBufferCtx(MR_Word gl_ctx, struct SaffronGL_BufferCtx **ctx_ptr | ||
80 | 81 | return 0; |
81 | 82 | }while(0); |
82 | 83 | #define SAFFRON_GL_LOAD_FUNC_BUFFER_ARB(X) SAFFRON_GL_FUNC_LOAD(X, "ARB") |
83 | - if(SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_vertex_buffer_object")){ | |
84 | + SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_vertex_buffer_object", &have_ext); | |
85 | + if(have_ext){ | |
84 | 86 | do{ |
85 | 87 | SAFFRON_GL_BUFFER_FUNCS(SAFFRON_GL_LOAD_FUNC_BUFFER_ARB) |
86 | 88 | *ctx_ptr = ctx; |
@@ -41,8 +41,7 @@ | ||
41 | 41 | %-----------------------------------------------------------------------------% |
42 | 42 | |
43 | 43 | :- pred create_buffer_ctx(Ctx, maybe.maybe_error(buffer_ctx), io.io, io.io) |
44 | - <= (saffron.gl.context(Ctx), | |
45 | - saffron.gl.supports_extensions(Ctx)). | |
44 | + <= saffron.gl.context(Ctx). | |
46 | 45 | :- mode create_buffer_ctx(in, out, di, uo) is det. |
47 | 46 | |
48 | 47 | %-----------------------------------------------------------------------------% |
@@ -61,9 +61,9 @@ | ||
61 | 61 | |
62 | 62 | %-----------------------------------------------------------------------------% |
63 | 63 | |
64 | -:- typeclass supports_extensions(Ctx) where [ | |
65 | - pred supports_extension(Ctx::in, string::in) is semidet | |
66 | -]. | |
64 | +:- pred supports_extension(Ctx, string, bool.bool, io.io, io.io) | |
65 | + <= saffron.gl.context(Ctx). | |
66 | +:- mode supports_extension(in, in, uo, di, uo) is det. | |
67 | 67 | |
68 | 68 | %-----------------------------------------------------------------------------% |
69 | 69 |
@@ -153,6 +153,7 @@ typedef char SaffronGLchar; | ||
153 | 153 | #else |
154 | 154 | |
155 | 155 | # if (defined __linux__) || (defined __OpenBSD__) || (defined __FreeBSD__) |
156 | +# define SAFFRON_GL_EXPECT_GL3 | |
156 | 157 | # define SAFFRON_GL_EXPECT_BUFFER |
157 | 158 | # define SAFFRON_GL_EXPECT_SHADER |
158 | 159 | # define GL_GLEXT_PROTOTYPES |
@@ -208,7 +209,6 @@ typedef void(APIENTRY*SaffronGL_DrawTextureNV_PROC)( | ||
208 | 209 | # define SAFFRON_GL_RAW_INTS |
209 | 210 | #endif |
210 | 211 | |
211 | - | |
212 | 212 | "). |
213 | 213 | |
214 | 214 | %-----------------------------------------------------------------------------% |
@@ -242,6 +242,39 @@ primitive_type(saffron.geometry.triangle_fan, saffron.gl.triangle_fan). | ||
242 | 242 | |
243 | 243 | %-----------------------------------------------------------------------------% |
244 | 244 | |
245 | +:- pred supports_extension_inner(string, bool.bool, io.io, io.io). | |
246 | +:- mode supports_extension_inner(in, uo, di, uo) is det. | |
247 | + | |
248 | +supports_extension_inner(_, bool.no, !IO). | |
249 | +:- pragma foreign_proc("C", | |
250 | + supports_extension_inner(Ext::in, Supports::uo, IOi::di, IOo::uo), | |
251 | + [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, | |
252 | + may_duplicate, does_not_affect_liveness], | |
253 | + " | |
254 | + const MR_Integer len = strnlen(Ext, 512); | |
255 | + const char *str = (void*)glGetString(GL_EXTENSIONS); | |
256 | + Supports = MR_NO; | |
257 | + IOo = IOi; | |
258 | + if(str != NULL){ | |
259 | + do{ | |
260 | + if(strncmp(str, Ext, len) != 0 && | |
261 | + (str[len] == ' ' || str[len] == 0)){ | |
262 | + | |
263 | + Supports = MR_YES; | |
264 | + break; | |
265 | + } | |
266 | + }while((str = strchr(str, ' ')) != NULL && *(++str) != 0); | |
267 | + } | |
268 | + "). | |
269 | + | |
270 | +%-----------------------------------------------------------------------------% | |
271 | + | |
272 | +supports_extension(Ctx, Ext, Supports, !IO) :- | |
273 | + saffron.make_current(Ctx, !IO), | |
274 | + supports_extension_inner(Ext, Supports, !IO). | |
275 | + | |
276 | +%-----------------------------------------------------------------------------% | |
277 | + | |
245 | 278 | float_bytes = 8. |
246 | 279 | |
247 | 280 | :- pragma foreign_proc("C", float_bytes = (N::out), |
@@ -378,8 +411,7 @@ texture_upload_at(_Ctx, Tex, B, X, Y, W, H, !IO) :- | ||
378 | 411 | :- type gl_load_func_ctx ---> |
379 | 412 | some [Ctx] (gl_load_func_ctx(Ctx) |
380 | 413 | => (saffron.context(Ctx), |
381 | - saffron.gl.context(Ctx), | |
382 | - saffron.gl.supports_extensions(Ctx))). | |
414 | + saffron.gl.context(Ctx))). | |
383 | 415 | |
384 | 416 | %-----------------------------------------------------------------------------% |
385 | 417 | % A non-higher-typed version of load_function that takes gl_load_func_ctx. |
@@ -434,13 +466,22 @@ gl_version(gl_load_func_ctx(Ctx), Major, Minor, !IO) :- | ||
434 | 466 | gl_version(in, out, out, di, uo), |
435 | 467 | "SaffronGL_Version"). |
436 | 468 | |
437 | -:- pred gl_supports_extension(gl_load_func_ctx::in, string::in) is semidet. | |
469 | +:- pred gl_supports_extension( | |
470 | + gl_load_func_ctx, | |
471 | + string, | |
472 | + bool.bool, | |
473 | + io.io, io.io). | |
474 | +:- mode gl_supports_extension( | |
475 | + in, | |
476 | + in, | |
477 | + uo, | |
478 | + di, uo) is det. | |
438 | 479 | |
439 | -gl_supports_extension(gl_load_func_ctx(Ctx), Ext) :- | |
440 | - saffron.gl.supports_extension(Ctx, Ext). | |
480 | +gl_supports_extension(gl_load_func_ctx(Ctx), Ext, Supports, !IO) :- | |
481 | + supports_extension(Ctx, Ext, Supports, !IO). | |
441 | 482 | |
442 | 483 | :- pragma foreign_export("C", |
443 | - gl_supports_extension(in, in), | |
484 | + gl_supports_extension(in, in, uo, di, uo), | |
444 | 485 | "SaffronGL_SupportsExtension"). |
445 | 486 | |
446 | 487 | %-----------------------------------------------------------------------------% |
@@ -210,6 +210,7 @@ int SaffronGL_LoadShaderCoreCtx(MR_Word gl_ctx, struct SaffronGL_ShaderCoreCtx * | ||
210 | 210 | int SaffronGL_LoadShaderCoreCtx(MR_Word gl_ctx, struct SaffronGL_ShaderCoreCtx **ctx_ptr){ |
211 | 211 | struct SaffronGL_ShaderCoreCtx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_ShaderCoreCtx)); |
212 | 212 | MR_Word maybe_func, func; |
213 | + MR_Bool have_ext; | |
213 | 214 | MR_String err = NULL; |
214 | 215 | MR_Integer major, minor; |
215 | 216 | SaffronGL_Version(gl_ctx, &major, &minor); |
@@ -310,9 +311,11 @@ int SaffronGL_LoadShaderFP64Ctx(MR_Word gl_ctx, struct SaffronGL_ShaderFP64Ctx * | ||
310 | 311 | int SaffronGL_LoadShaderFP64Ctx(MR_Word gl_ctx, struct SaffronGL_ShaderFP64Ctx **ctx_ptr){ |
311 | 312 | struct SaffronGL_ShaderFP64Ctx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_ShaderFP64Ctx)); |
312 | 313 | MR_Word maybe_func, func; |
314 | + MR_Bool have_ext; | |
313 | 315 | MR_String err = NULL; |
314 | 316 | #define SAFFRON_GL_LOAD_FUNC_SHADERFP64_ARB(X) SAFFRON_GL_FUNC_LOAD(X, "ARB") |
315 | - if(SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_gpu_shader_fp64")){ | |
317 | + SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_gpu_shader_fp64", &have_ext); | |
318 | + if(have_ext){ | |
316 | 319 | do{ |
317 | 320 | SAFFRON_GL_SHADERFP64_FUNCS(SAFFRON_GL_LOAD_FUNC_SHADERFP64_ARB) |
318 | 321 | *ctx_ptr = ctx; |
@@ -370,6 +373,7 @@ int SaffronGL_LoadProgramBinaryCtx(MR_Word gl_ctx, struct SaffronGL_ProgramBinar | ||
370 | 373 | int SaffronGL_LoadProgramBinaryCtx(MR_Word gl_ctx, struct SaffronGL_ProgramBinaryCtx **ctx_ptr){ |
371 | 374 | struct SaffronGL_ProgramBinaryCtx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_ProgramBinaryCtx)); |
372 | 375 | MR_Word maybe_func, func; |
376 | + MR_Bool have_ext; | |
373 | 377 | MR_String err = NULL; |
374 | 378 | MR_Integer major, minor; |
375 | 379 | SaffronGL_Version(gl_ctx, &major, &minor); |
@@ -379,7 +383,8 @@ int SaffronGL_LoadProgramBinaryCtx(MR_Word gl_ctx, struct SaffronGL_ProgramBinar | ||
379 | 383 | return 0; |
380 | 384 | }while(0); |
381 | 385 | #define SAFFRON_GL_LOAD_FUNC_PROGRAMBINARY_ARB(X) SAFFRON_GL_FUNC_LOAD(X, "ARB") |
382 | - if(SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_get_program_binary")){ | |
386 | + SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_get_program_binary", &have_ext); | |
387 | + if(have_ext){ | |
383 | 388 | do{ |
384 | 389 | SAFFRON_GL_PROGRAMBINARY_FUNCS(SAFFRON_GL_LOAD_FUNC_PROGRAMBINARY_ARB) |
385 | 390 | *ctx_ptr = ctx; |
@@ -415,9 +420,11 @@ int SaffronGL_LoadSPIRVCtx(MR_Word gl_ctx, struct SaffronGL_SPIRVCtx **ctx_ptr); | ||
415 | 420 | int SaffronGL_LoadSPIRVCtx(MR_Word gl_ctx, struct SaffronGL_SPIRVCtx **ctx_ptr){ |
416 | 421 | struct SaffronGL_SPIRVCtx *ctx = MR_GC_malloc_atomic(sizeof(struct SaffronGL_SPIRVCtx)); |
417 | 422 | MR_Word maybe_func, func; |
423 | + MR_Bool have_ext; | |
418 | 424 | MR_String err = NULL; |
419 | 425 | #define SAFFRON_GL_LOAD_FUNC_SPIRV_ARB(X) SAFFRON_GL_FUNC_LOAD(X, "ARB") |
420 | - if(SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_gl_spirv")){ | |
426 | + SaffronGL_SupportsExtension(gl_ctx, (MR_String)"GL_ARB_gl_spirv", &have_ext); | |
427 | + if(have_ext){ | |
421 | 428 | do{ |
422 | 429 | SAFFRON_GL_SPIRV_FUNCS(SAFFRON_GL_LOAD_FUNC_SPIRV_ARB) |
423 | 430 | *ctx_ptr = ctx; |
@@ -27,8 +27,7 @@ | ||
27 | 27 | %-----------------------------------------------------------------------------% |
28 | 28 | |
29 | 29 | :- pred create_shader_ctx(Ctx, maybe.maybe_error(shader_ctx), io.io, io.io) |
30 | - <= (saffron.gl.context(Ctx), | |
31 | - saffron.gl.supports_extensions(Ctx)). | |
30 | + <= saffron.gl.context(Ctx). | |
32 | 31 | :- mode create_shader_ctx(in, out, di, uo) is det. |
33 | 32 | |
34 | 33 | %-----------------------------------------------------------------------------% |
@@ -35,11 +35,6 @@ | ||
35 | 35 | |
36 | 36 | %-----------------------------------------------------------------------------% |
37 | 37 | |
38 | -:- instance saffron.gl.supports_extensions(context(Ctx)) | |
39 | - <= saffron.gl.context(Ctx). | |
40 | - | |
41 | -%-----------------------------------------------------------------------------% | |
42 | - | |
43 | 38 | :- instance saffron.draw.basic_transform(context(Ctx)) |
44 | 39 | <= saffron.gl.context(Ctx). |
45 | 40 |
@@ -253,36 +248,6 @@ const char *Saffron_GL2_DebugError(void){ | ||
253 | 248 | |
254 | 249 | %-----------------------------------------------------------------------------% |
255 | 250 | |
256 | -:- pred supports_extension(_::in, string::in) is semidet. | |
257 | - | |
258 | -supports_extension(_, _) :- false. | |
259 | - | |
260 | -:- pragma foreign_proc("C", supports_extension(Ctx::in, Ext::in), | |
261 | - [will_not_call_mercury, promise_pure, thread_safe, will_not_throw_exception, | |
262 | - tabled_for_io, may_duplicate, does_not_affect_liveness], | |
263 | - " | |
264 | - const char *str = (void*)glGetString(GL_EXTENSIONS); | |
265 | - const MR_Integer len = strlen(Ext); | |
266 | - (void)Ctx; | |
267 | - SUCCESS_INDICATOR = 0; | |
268 | - while((str = strstr(str, Ext)) != NULL){ | |
269 | - if(str[len] == ' ' || str[len] == 0){ | |
270 | - SUCCESS_INDICATOR = 1; | |
271 | - break; | |
272 | - } | |
273 | - } | |
274 | - "). | |
275 | - | |
276 | -%-----------------------------------------------------------------------------% | |
277 | - | |
278 | -:- instance saffron.gl.supports_extensions(context(Ctx)) | |
279 | - <= saffron.gl.context(Ctx) where [ | |
280 | - | |
281 | - pred(saffron.gl.supports_extension/2) is saffron.gl2.supports_extension | |
282 | -]. | |
283 | - | |
284 | -%-----------------------------------------------------------------------------% | |
285 | - | |
286 | 251 | :- pragma foreign_export("C", |
287 | 252 | saffron.draw.raise_matrix_stack_error, |
288 | 253 | "Saffron_GL2_RaiseMatrixStackError"). |
@@ -859,8 +824,6 @@ init(Ctx, | ||
859 | 824 | !IO) :- |
860 | 825 | |
861 | 826 | saffron.make_current(Ctx, !IO), |
862 | - % Get the supports_extension implementation for GL 2 contexts. | |
863 | - TempCtx = context(Ctx, maybe.no, maybe.no), | |
864 | 827 | saffron.gl.shader_model_version(Ctx, MaybeGLSLVersion, !IO), |
865 | 828 | % TODO: Should this live inside create_shader_ctx? |
866 | 829 | ( if |
@@ -868,12 +831,12 @@ init(Ctx, | ||
868 | 831 | saffron.sem_ver_compare(GLSLCmp, GLSLVersion, saffron.sem_ver(1, 20)), |
869 | 832 | GLSLCmp \= (<) |
870 | 833 | then |
871 | - saffron.gl.shader.create_shader_ctx(TempCtx, MaybeErrShaderCtx, !IO), | |
834 | + saffron.gl.shader.create_shader_ctx(Ctx, MaybeErrShaderCtx, !IO), | |
872 | 835 | MaybeShaderCtx = complete_load_ctx("shader", MaybeErrShaderCtx) |
873 | 836 | else |
874 | 837 | MaybeShaderCtx = maybe.no |
875 | 838 | ), |
876 | - saffron.gl.buffer.create_buffer_ctx(TempCtx, MaybeErrBufferCtx, !IO), | |
839 | + saffron.gl.buffer.create_buffer_ctx(Ctx, MaybeErrBufferCtx, !IO), | |
877 | 840 | MaybeBufferCtx = complete_load_ctx("buffer", MaybeErrBufferCtx), |
878 | 841 | init(!IO). |
879 | 842 |
@@ -104,6 +104,7 @@ $1 == "load" { | ||
104 | 104 | print(sig "{\n\ |
105 | 105 | " struct " *ctx = MR_GC_malloc_atomic(sizeof(" struct "));\n\ |
106 | 106 | MR_Word maybe_func, func;\n\ |
107 | + MR_Bool have_ext;\n\ | |
107 | 108 | MR_String err = NULL;"); |
108 | 109 | if(core != 0){ |
109 | 110 | print("\ |
@@ -130,7 +131,8 @@ $1 == "load" { | ||
130 | 131 | macro = "SAFFRON_GL_LOAD_FUNC_" upper2 "_" sfx; |
131 | 132 | print("\ |
132 | 133 | #define " macro "(X) SAFFRON_GL_FUNC_LOAD(X, \"" sfx "\")\n\ |
133 | - if(SaffronGL_SupportsExtension(gl_ctx, (MR_String)\"" ext "\")){\n\ | |
134 | + SaffronGL_SupportsExtension(gl_ctx, (MR_String)\"" ext "\", &have_ext);\n\ | |
135 | + if(have_ext){\n\ | |
134 | 136 | do{\n\ |
135 | 137 | SAFFRON_GL_" upper2 "_FUNCS(" macro ")\n\ |
136 | 138 | *ctx_ptr = ctx;\n\ |