|
1 | 1 | from io import StringIO |
2 | 2 | import math |
| 3 | +import os |
3 | 4 | import pathlib |
| 5 | +import sys |
4 | 6 | import time |
5 | 7 |
|
6 | 8 | import bpy |
@@ -39,6 +41,27 @@ def materials_set_light_direction(scene): |
39 | 41 | return not (scene.gameEditorMode == "SM64" and scene.fast64.sm64.matstack_fix) |
40 | 42 |
|
41 | 43 |
|
| 44 | +def flag_enabled(flag_name: str) -> bool: |
| 45 | + true_values = {"1", "true", "yes", "on"} |
| 46 | + |
| 47 | + if os.environ.get(flag_name, "").lower() in true_values: |
| 48 | + return True |
| 49 | + |
| 50 | + return False |
| 51 | + |
| 52 | + |
| 53 | +def check_if_under_mesa(): |
| 54 | + vendor = gpu.platform.vendor_get() |
| 55 | + renderer = gpu.platform.renderer_get() |
| 56 | + version = gpu.platform.version_get() |
| 57 | + combined = (vendor + renderer + version).lower() |
| 58 | + return "mesa" in combined or "llvmpipe" in combined |
| 59 | + |
| 60 | + |
| 61 | +def show_mesa_warning(): |
| 62 | + bpy.ops.dialog.f64_mesa_warning("INVOKE_DEFAULT") |
| 63 | + |
| 64 | + |
42 | 65 | class Fast64RenderEngine(bpy.types.RenderEngine): |
43 | 66 | bl_idname = "FAST64_RENDER_ENGINE" |
44 | 67 | bl_label = "Fast64 Renderer" |
@@ -72,14 +95,37 @@ def __init__(self, *args, **kwargs): |
72 | 95 | # Create a 1x1 image |
73 | 96 | bpy.data.images.new("f64render_missing_texture", 1, 1).pixels = MISSING_TEXTURE_COLOR |
74 | 97 |
|
75 | | - ext_list = gpu.capabilities.extensions_get() |
| 98 | + self.is_mesa_driver = check_if_under_mesa() |
| 99 | + if self.is_mesa_driver: |
| 100 | + print("Mesa drivers detected!") |
| 101 | + self.allow_glsl_extension_directive_midshader = not self.is_mesa_driver or flag_enabled( |
| 102 | + "allow_glsl_extension_directive_midshader" |
| 103 | + ) |
| 104 | + if self.is_mesa_driver: |
| 105 | + if self.allow_glsl_extension_directive_midshader: |
| 106 | + print( |
| 107 | + 'Sucefully bypassed Mesa restriction on GLSL extensions via "allow_glsl_extension_directive_midshader"!' |
| 108 | + ) |
| 109 | + else: |
| 110 | + print("GLSL extension directives mid-shader are disabled!") |
| 111 | + |
| 112 | + if self.allow_glsl_extension_directive_midshader: |
| 113 | + ext_list = gpu.capabilities.extensions_get() |
| 114 | + else: |
| 115 | + ext_list = [] |
76 | 116 | self.shader_interlock_support = "GL_ARB_fragment_shader_interlock" in ext_list |
77 | 117 | if not self.shader_interlock_support: |
78 | | - print("\n\nWarning: GL_ARB_fragment_shader_interlock not supported!\n\n") |
| 118 | + print("Warning: GL_ARB_fragment_shader_interlock not supported!") |
| 119 | + self.shader_derivative_control_support = "GL_ARB_derivative_control" in ext_list |
| 120 | + if not self.shader_derivative_control_support: |
| 121 | + print("Warning: GL_ARB_derivative_control not supported!") |
79 | 122 | if bpy.app.version < (4, 1, 0): |
80 | | - print("\n\nWarning: Blender version too old! Expect limited blending emulation!\n\n") |
| 123 | + print("Warning: Blender version too old! Expect limited blending emulation!") |
81 | 124 | self.draw_range_impl = bpy.app.version >= (3, 6, 0) |
82 | 125 |
|
| 126 | + if not self.allow_glsl_extension_directive_midshader and self.is_mesa_driver: |
| 127 | + bpy.app.timers.register(show_mesa_warning) |
| 128 | + |
83 | 129 | def __del__(self): |
84 | 130 | def remove_handler(handler, func): |
85 | 131 | while func in handler: |
@@ -133,6 +179,8 @@ def init_shader(self, scene: bpy.types.Scene): |
133 | 179 | shader_info.define("depth_unchanged", "depth_any") |
134 | 180 | if self.shader_interlock_support: |
135 | 181 | shader_info.define("USE_SHADER_INTERLOCK", "1") |
| 182 | + if self.shader_derivative_control_support: |
| 183 | + shader_info.define("USE_DERIVATIVE_CONTROL", "1") |
136 | 184 | shader_info.define("BLEND_EMULATION", "1") |
137 | 185 | # Using the already calculated view space normals instead of transforming the light direction makes |
138 | 186 | # for cleaner and faster code |
@@ -279,7 +327,8 @@ def draw_scene(self, context, depsgraph): |
279 | 327 | f64render_rs: F64RenderSettings = depsgraph.scene.f64render.render_settings |
280 | 328 | always_set = f64render_rs.always_set |
281 | 329 | projection_matrix, view_matrix = context.region_data.perspective_matrix, context.region_data.view_matrix |
282 | | - self.use_atomic_rendering = bpy.app.version >= (4, 1, 0) and f64render_rs.use_atomic_rendering |
| 330 | + prefs = context.preferences.addons[__name__.split(".")[0]].preferences |
| 331 | + self.use_atomic_rendering = bpy.app.version >= (4, 1, 0) and prefs.use_atomic_rendering |
283 | 332 |
|
284 | 333 | if F64_GLOBALS.rebuild_shaders or self.shader is None: |
285 | 334 | F64_GLOBALS.rebuild_shaders = False |
@@ -364,6 +413,8 @@ class F64RenderSettingsPanel(bpy.types.Panel): |
364 | 413 | def draw(self, context): |
365 | 414 | f64render_rs: F64RenderSettings = context.scene.f64render.render_settings |
366 | 415 | f64render_rs.draw_props(self.layout, context.scene.gameEditorMode) |
| 416 | + prefs = context.preferences.addons[__name__.split(".")[0]].preferences |
| 417 | + prefs.draw_props(self.layout) |
367 | 418 |
|
368 | 419 |
|
369 | 420 | def draw_render_settings(self, context: bpy.types.Context): |
|
0 commit comments