Skip to content

Commit 07b6031

Browse files
authored
Fix mesa extension enabling (#24)
1 parent 21436de commit 07b6031

File tree

5 files changed

+138
-20
lines changed

5 files changed

+138
-20
lines changed

mesa_warning.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from bpy.types import Context, Event, Operator
2+
3+
4+
class MesaWarningPopup(Operator):
5+
bl_label = "Mesa Driver Limitations"
6+
bl_idname = "dialog.f64_mesa_warning"
7+
bl_description = "Update color management settings to help material preview accuracy"
8+
bl_options = {"UNDO"}
9+
10+
already_invoked = False # HACK: used to prevent multiple dialogs from popping up
11+
12+
def invoke(self, context: Context, event: Event):
13+
prefs = context.preferences.addons[__name__.split(".")[0]].preferences
14+
if prefs.dont_warn_about_mesa:
15+
return {"CANCELLED"}
16+
if MesaWarningPopup.already_invoked:
17+
return {"FINISHED"}
18+
MesaWarningPopup.already_invoked = True
19+
return context.window_manager.invoke_props_dialog(self, width=400)
20+
21+
def draw(self, context: Context):
22+
from fast64_internal.utility import multilineLabel
23+
24+
col = self.layout.column()
25+
col.label(text="You are using Mesa drivers!", icon="MEMORY")
26+
multilineLabel(
27+
col,
28+
(
29+
(
30+
"These are much more strict as opposed to commercial drivers\n"
31+
"and do not allow us to enable helpful extensions!"
32+
)
33+
),
34+
)
35+
col.alert = True
36+
col.label(text="This will hinder your accuracy and or performance.", icon="ERROR")
37+
col.alert = False
38+
multilineLabel(
39+
col,
40+
(
41+
(
42+
'You can add "allow_glsl_extension_directive_midshader=true" to your\n'
43+
"blender launch arguments to bypass this restriction, or change render\n"
44+
"device."
45+
)
46+
),
47+
icon="INFO",
48+
)
49+
50+
prefs = context.preferences.addons[__name__.split(".")[0]].preferences
51+
col.prop(prefs, "dont_warn_about_mesa", text="Don't warn me again")
52+
53+
def cancel(self, context: Context):
54+
MesaWarningPopup.already_invoked = False
55+
56+
def execute(self, context):
57+
return {"FINISHED"}

properties.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import bpy
2-
from bpy.types import PropertyGroup, Image
2+
from bpy.types import PropertyGroup, Image, AddonPreferences
3+
from bpy.props import BoolProperty
34

45
from .globals import F64_GLOBALS
56

@@ -163,13 +164,6 @@ def rebuild_shaders(_scene, _context):
163164

164165

165166
class F64RenderSettings(bpy.types.PropertyGroup):
166-
use_atomic_rendering: bpy.props.BoolProperty(
167-
name="Use Atomic Rendering",
168-
default=True,
169-
description="Atomic rendering will draw to a depth and color buffer seperately, which allows for proper blender and decal emulation.\n"
170-
"This may cause artifacts if your GPU does not support the interlock extension",
171-
update=rebuild_shaders,
172-
)
173167
sources_tab: bpy.props.BoolProperty(name="Default Sources")
174168
default_prim_color: bpy.props.FloatVectorProperty(
175169
description="Primitive Color",
@@ -268,8 +262,6 @@ def draw_props(self, layout: bpy.types.UILayout, gameEditorMode: str):
268262
prop_split(layout, self, "oot_specific_room", "Specific Room")
269263
layout.separator()
270264

271-
if bpy.app.version >= (4, 1, 0):
272-
layout.prop(self, "use_atomic_rendering")
273265
layout.prop(self, "always_set")
274266
layout.prop(self, "sources_tab", icon="TRIA_DOWN" if self.sources_tab else "TRIA_RIGHT")
275267
if self.sources_tab:
@@ -300,5 +292,23 @@ def draw_props(self, layout: bpy.types.UILayout, gameEditorMode: str):
300292
tex_prop.draw_default_ui(texture_box, i)
301293

302294

303-
class F64RenderProperties(bpy.types.PropertyGroup):
295+
class F64RenderProperties(PropertyGroup):
304296
render_settings: bpy.props.PointerProperty(type=F64RenderSettings)
297+
298+
299+
class F64AddonPreferences(AddonPreferences):
300+
bl_idname = __name__.split(".")[0]
301+
302+
use_atomic_rendering: bpy.props.BoolProperty(
303+
name="Use Atomic Rendering",
304+
default=True,
305+
description="Atomic rendering will draw to a depth and color buffer seperately, which allows for proper blender and decal emulation.\n"
306+
"This may cause artifacts if your GPU does not support the interlock extension",
307+
update=rebuild_shaders,
308+
)
309+
dont_warn_about_mesa: BoolProperty()
310+
311+
def draw_props(self, layout: bpy.types.UILayout):
312+
atomic_col = layout.column()
313+
atomic_col.prop(self, "use_atomic_rendering")
314+
atomic_col.enabled = bpy.app.version >= (4, 1, 0)

renderer.py

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from io import StringIO
22
import math
3+
import os
34
import pathlib
5+
import sys
46
import time
57

68
import bpy
@@ -39,6 +41,27 @@ def materials_set_light_direction(scene):
3941
return not (scene.gameEditorMode == "SM64" and scene.fast64.sm64.matstack_fix)
4042

4143

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+
4265
class Fast64RenderEngine(bpy.types.RenderEngine):
4366
bl_idname = "FAST64_RENDER_ENGINE"
4467
bl_label = "Fast64 Renderer"
@@ -72,14 +95,37 @@ def __init__(self, *args, **kwargs):
7295
# Create a 1x1 image
7396
bpy.data.images.new("f64render_missing_texture", 1, 1).pixels = MISSING_TEXTURE_COLOR
7497

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 = []
76116
self.shader_interlock_support = "GL_ARB_fragment_shader_interlock" in ext_list
77117
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!")
79122
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!")
81124
self.draw_range_impl = bpy.app.version >= (3, 6, 0)
82125

126+
if not self.allow_glsl_extension_directive_midshader and self.is_mesa_driver:
127+
bpy.app.timers.register(show_mesa_warning)
128+
83129
def __del__(self):
84130
def remove_handler(handler, func):
85131
while func in handler:
@@ -133,6 +179,8 @@ def init_shader(self, scene: bpy.types.Scene):
133179
shader_info.define("depth_unchanged", "depth_any")
134180
if self.shader_interlock_support:
135181
shader_info.define("USE_SHADER_INTERLOCK", "1")
182+
if self.shader_derivative_control_support:
183+
shader_info.define("USE_DERIVATIVE_CONTROL", "1")
136184
shader_info.define("BLEND_EMULATION", "1")
137185
# Using the already calculated view space normals instead of transforming the light direction makes
138186
# for cleaner and faster code
@@ -279,7 +327,8 @@ def draw_scene(self, context, depsgraph):
279327
f64render_rs: F64RenderSettings = depsgraph.scene.f64render.render_settings
280328
always_set = f64render_rs.always_set
281329
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
283332

284333
if F64_GLOBALS.rebuild_shaders or self.shader is None:
285334
F64_GLOBALS.rebuild_shaders = False
@@ -364,6 +413,8 @@ class F64RenderSettingsPanel(bpy.types.Panel):
364413
def draw(self, context):
365414
f64render_rs: F64RenderSettings = context.scene.f64render.render_settings
366415
f64render_rs.draw_props(self.layout, context.scene.gameEditorMode)
416+
prefs = context.preferences.addons[__name__.split(".")[0]].preferences
417+
prefs.draw_props(self.layout)
367418

368419

369420
def draw_render_settings(self, context: bpy.types.Context):

shader/main3d.frag.glsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
layout(pixel_interlock_unordered) in;
55
#endif
66

7+
#ifdef USE_DERIVATIVE_CONTROL
8+
#extension GL_ARB_derivative_control : enable
9+
#endif
10+
711
#define DECAL_DEPTH_DELTA 100
812

913
vec3 cc_fetchColor(in int val, in vec4 shade, in vec4 comb, in float lodFraction, in vec4 texData0, in vec4 texData1)
@@ -144,7 +148,7 @@ void main()
144148

145149
vec4 ccShade = geoModeSelect(G_SHADE_SMOOTH, cc_shade_flat, cc_shade);
146150

147-
#ifdef GL_ARB_derivative_control
151+
#ifdef USE_DERIVATIVE_CONTROL
148152
const vec2 dx = abs(vec2(dFdxCoarse(inputUV.x), dFdyCoarse(inputUV.x)));
149153
const vec2 dy = abs(vec2(dFdxCoarse(inputUV.y), dFdyCoarse(inputUV.y)));
150154
#else

shader/textures.glsl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
#ifdef GL_ARB_derivative_control
2-
#extension GL_ARB_derivative_control : enable
3-
#endif
4-
51
vec4 quantize3Bit(in vec4 color) {
62
return vec4(round(color.rgb * 8.0) / 8.0, step(0.5, color.a));
73
}

0 commit comments

Comments
 (0)