metal: fix gpu hang during envmap filtering

This commit is contained in:
luboslenco
2026-01-23 13:58:39 +01:00
parent 8760df13f7
commit ec26d76efa
2 changed files with 28 additions and 19 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
#[set(everything)] #[set(everything)]
const constants: { const constants: {
params: float4; // level, constants.params.y params: float4; // level, samples, alpha, pass
}; };
#[set(everything)] #[set(everything)]
@@ -65,13 +65,13 @@ fun cos_weighted_hemisphere_direction(n: float3, co: float2, seed: float): float
} }
fun prefilter_envmap_frag(input: vert_out): float4 { fun prefilter_envmap_frag(input: vert_out): float4 {
var color: float4 = float4(0.0, 0.0, 0.0, 1.0); var color: float4 = float4(0.0, 0.0, 0.0, constants.params.z);
var n: float3 = reverse_equirect(input.tex); var n: float3 = reverse_equirect(input.tex);
//for (var i: int = 0; i < int(constants.params.y); i += 1) { //for (var i: int = 0; i < int(constants.params.y); i += 1) {
var i: int = 0; var i: int = 0;
while (i < int(constants.params.y)) { while (i < int(constants.params.y)) {
var dir: float3 = normalize(lerp3(n, cos_weighted_hemisphere_direction(n, input.tex, float(i)), constants.params.x)); var dir: float3 = normalize(lerp3(n, cos_weighted_hemisphere_direction(n, input.tex, float(i + constants.params.w * constants.params.y)), constants.params.x));
var sampled: float3 = sample(radiance, sampler_linear, equirect(dir)).rgb; var sampled: float3 = sample(radiance, sampler_linear, equirect(dir)).rgb;
sampled = min3(sampled, float3(10.0, 10.0, 10.0)); sampled = min3(sampled, float3(10.0, 10.0, 10.0));
color.rgb = color.rgb + sampled; color.rgb = color.rgb + sampled;
+25 -16
View File
@@ -11,9 +11,11 @@ let import_envmap_mips: gpu_texture_t[] = null;
function import_envmap_run(path: string, image: gpu_texture_t) { function import_envmap_run(path: string, image: gpu_texture_t) {
// Init // Init
if (import_envmap_pipeline == null) { if (import_envmap_pipeline == null) {
import_envmap_pipeline = gpu_create_pipeline(); import_envmap_pipeline = gpu_create_pipeline();
import_envmap_pipeline.vertex_shader = sys_get_shader("prefilter_envmap.vert"); import_envmap_pipeline.vertex_shader = sys_get_shader("prefilter_envmap.vert");
import_envmap_pipeline.fragment_shader = sys_get_shader("prefilter_envmap.frag"); import_envmap_pipeline.fragment_shader = sys_get_shader("prefilter_envmap.frag");
import_envmap_pipeline.blend_source = gpu_blend_t.SOURCE_ALPHA;
import_envmap_pipeline.blend_destination = gpu_blend_t.ONE;
let vs: gpu_vertex_structure_t = {}; let vs: gpu_vertex_structure_t = {};
gpu_vertex_struct_add(vs, "pos", gpu_vertex_data_t.F32_2X); gpu_vertex_struct_add(vs, "pos", gpu_vertex_data_t.F32_2X);
import_envmap_pipeline.input_layout = vs; import_envmap_pipeline.input_layout = vs;
@@ -68,22 +70,29 @@ function import_envmap_run(path: string, image: gpu_texture_t) {
} }
function import_envmap_get_radiance_mip(mip: gpu_texture_t, level: i32, radiance: gpu_texture_t) { function import_envmap_get_radiance_mip(mip: gpu_texture_t, level: i32, radiance: gpu_texture_t) {
_gpu_begin(mip); /// if arm_metal
gpu_set_vertex_buffer(const_data_screen_aligned_vb); let pass_count: i32 = 8; // 32;
gpu_set_index_buffer(const_data_screen_aligned_ib); import_envmap_params.y = 512;
gpu_set_pipeline(import_envmap_pipeline);
import_envmap_params.x = (level + 1) / 10;
/// if (arm_macos || arm_ios)
import_envmap_params.y = 1024 * 2; // Prevent gpu hang
/// else /// else
let pass_count: i32 = 1;
import_envmap_params.y = 1024 * 16; import_envmap_params.y = 1024 * 16;
/// end /// end
gpu_set_float4(import_envmap_params_loc, import_envmap_params.x, import_envmap_params.y, import_envmap_params.z, import_envmap_params.w); import_envmap_params.z = 1.0 / pass_count;
gpu_set_texture(import_envmap_radiance_loc, radiance); import_envmap_params.x = (level + 1) / 10;
let noise: gpu_texture_t = data_get_image("bnoise256.k");
gpu_set_texture(import_envmap_noise_loc, noise); for (let i: i32 = 0; i < pass_count; ++i) {
gpu_draw(); _gpu_begin(mip, null, null, i == 0 ? gpu_clear_t.COLOR : gpu_clear_t.NONE, 0x00000000);
gpu_end(); gpu_set_vertex_buffer(const_data_screen_aligned_vb);
gpu_set_index_buffer(const_data_screen_aligned_ib);
gpu_set_pipeline(import_envmap_pipeline);
import_envmap_params.w = i;
gpu_set_float4(import_envmap_params_loc, import_envmap_params.x, import_envmap_params.y, import_envmap_params.z, import_envmap_params.w);
gpu_set_texture(import_envmap_radiance_loc, radiance);
let noise: gpu_texture_t = data_get_image("bnoise256.k");
gpu_set_texture(import_envmap_noise_loc, noise);
gpu_draw();
gpu_end();
}
} }
function import_envmap_reverse_equirect(x: f32, y: f32): vec4_t { function import_envmap_reverse_equirect(x: f32, y: f32): vec4_t {