This commit is contained in:
luboslenco
2025-08-12 23:26:06 +02:00
parent fcd65a71cc
commit c427d9751a
11 changed files with 129 additions and 234 deletions
Binary file not shown.
+1 -1
View File
@@ -95,7 +95,7 @@ typedef struct gpu_texture {
typedef struct gpu_buffer {
int count;
int stride;
uint8_t *data;
uint8_t *data; // constant buffer data
gpu_buffer_impl_t impl;
} gpu_buffer_t;
+4 -14
View File
@@ -19,17 +19,9 @@ function material_data_create(raw: material_data_t, file: string = ""): material
let b: shader_data_t = data_get_shader(object_file, data_ref);
raw._.shader = b;
// Contexts have to be in the same order as in raw data for now
raw._.contexts = [];
while (raw._.contexts.length < raw.contexts.length) {
array_push(raw._.contexts, null);
}
for (let i: i32 = 0; i < raw.contexts.length; ++i) {
let c: material_context_t = raw.contexts[i];
let self: material_context_t = material_context_create(c);
raw._.contexts[i] = self;
material_context_load(c);
}
return raw;
}
@@ -57,8 +49,8 @@ function material_data_get_raw_by_name(datas: material_data_t[], name: string):
}
function material_data_get_context(raw: material_data_t, name: string): material_context_t {
for (let i: i32 = 0; i < raw._.contexts.length; ++i) {
let c: material_context_t = raw._.contexts[i];
for (let i: i32 = 0; i < raw.contexts.length; ++i) {
let c: material_context_t = raw.contexts[i];
if (c.name == name) {
return c;
}
@@ -66,7 +58,7 @@ function material_data_get_context(raw: material_data_t, name: string): material
return null;
}
function material_context_create(raw: material_context_t): material_context_t {
function material_context_load(raw: material_context_t) {
raw._ = {};
if (raw.bind_textures != null && raw.bind_textures.length > 0) {
raw._.textures = [];
@@ -79,6 +71,4 @@ function material_context_create(raw: material_context_t): material_context_t {
array_push(raw._.textures, image);
}
}
return raw;
}
+5 -7
View File
@@ -88,14 +88,12 @@ function mesh_data_build(raw: mesh_data_t) {
mesh_data_build_vertices(vertices, raw.vertex_arrays);
gpu_vertex_buffer_unlock(raw._.vertex_buffer);
let id: u32_array_t = raw.index_array;
let index_buffer: gpu_buffer_t = gpu_create_index_buffer(id.length);
let indices_array: u32_array_t = gpu_lock_index_buffer(index_buffer);
for (let i: i32 = 0; i < indices_array.length; ++i) {
indices_array[i] = id[i];
raw._.index_buffer = gpu_create_index_buffer(raw.index_array.length);
let ia: u32_array_t = gpu_lock_index_buffer(raw._.index_buffer);
for (let i: i32 = 0; i < ia.length; ++i) {
ia[i] = raw.index_array[i];
}
gpu_index_buffer_unlock(index_buffer);
raw._.index_buffer = index_buffer;
gpu_index_buffer_unlock(raw._.index_buffer);
}
function mesh_data_calculate_aabb(raw: mesh_data_t): vec4_t {
+26 -70
View File
@@ -4,19 +4,15 @@ type mesh_object_t = {
data?: mesh_data_t;
materials?: material_data_t[];
camera_dist?: f32;
screen_size?: f32;
frustum_culling?: bool;
skip_context?: string; // Do not draw this context
force_context?: string; // Draw only this context
};
let _mesh_object_last_pipeline: gpu_pipeline_t = null;
let _mesh_object_material_contexts: material_context_t[] = [];
let _mesh_object_shader_contexts: shader_context_t[] = [];
function mesh_object_create(data: mesh_data_t, materials: material_data_t[]): mesh_object_t {
let raw: mesh_object_t = {};
raw.screen_size = 0.0;
raw.frustum_culling = true;
raw.base = object_create(false);
raw.base.ext = raw;
@@ -47,66 +43,35 @@ function mesh_object_setup_animation(raw: mesh_object_t, oactions: scene_t[] = n
///end
}
function mesh_object_set_culled(raw: mesh_object_t, b: bool): bool {
raw.base.culled = b;
return b;
}
function mesh_object_cull_material(raw: mesh_object_t, context: string): bool {
// Skip render if material does not contain current context
if (!mesh_object_valid_context(raw, raw.materials, context)) {
raw.base.culled = true;
return true;
}
if (!raw.base.visible) {
return mesh_object_set_culled(raw, true);
}
if (raw.skip_context == context) {
return mesh_object_set_culled(raw, true);
raw.base.culled = true;
return true;
}
if (raw.force_context != null && raw.force_context != context) {
return mesh_object_set_culled(raw, true);
raw.base.culled = true;
return true;
}
return mesh_object_set_culled(raw, false);
raw.base.culled = false;
return false;
}
function mesh_object_cull_mesh(raw: mesh_object_t, context: string, camera: camera_object_t): bool {
if (camera == null) {
return false;
}
if (camera.data.frustum_culling && raw.frustum_culling) {
let radius_scale: f32 = 1.0;
let frustum_planes: frustum_plane_t[] = camera.frustum_planes;
if (!camera_object_sphere_in_frustum(frustum_planes, raw.base.transform, radius_scale)) {
return mesh_object_set_culled(raw, true);
raw.base.culled = true;
return true;
}
}
raw.base.culled = false;
return raw.base.culled;
}
function mesh_object_get_contexts(raw: mesh_object_t, context: string, materials: material_data_t[], material_contexts: material_context_t[], shader_contexts: shader_context_t[]) {
for (let i: i32 = 0; i < materials.length; ++i) {
let mat: material_data_t = materials[i];
let found: bool = false;
for (let j: i32 = 0; j < mat.contexts.length; ++j) {
if (substring(mat.contexts[j].name, 0, context.length) == context) {
array_push(material_contexts, mat._.contexts[j]);
array_push(shader_contexts, shader_data_get_context(mat._.shader, context));
found = true;
break;
}
}
if (!found) {
array_push(material_contexts, null);
array_push(shader_contexts, null);
}
}
return false;
}
function mesh_object_render(raw: mesh_object_t, context: string, bind_params: string[]) {
@@ -120,29 +85,30 @@ function mesh_object_render(raw: mesh_object_t, context: string, bind_params: st
return;
}
// Get context
let material_contexts: material_context_t[] = _mesh_object_material_contexts;
let shader_contexts: shader_context_t[] = _mesh_object_shader_contexts;
material_contexts.length = 0;
shader_contexts.length = 0;
mesh_object_get_contexts(raw, context, raw.materials, material_contexts, shader_contexts);
uniforms_pos_unpack = raw.data.scale_pos;
uniforms_tex_unpack = raw.data.scale_tex;
transform_update(raw.base.transform);
// Render mesh
let scontext: shader_context_t = shader_contexts[0];
let scontext: shader_context_t = null;
let mcontext: material_context_t = null;
for (let i: i32 = 0; i < raw.materials.length; ++i) {
let mat: material_data_t = raw.materials[i];
for (let j: i32 = 0; j < mat.contexts.length; ++j) {
if (mat.contexts[j].name == context) {
scontext = shader_data_get_context(mat._.shader, context);
mcontext = mat.contexts[j];
break;
}
}
}
// Uniforms
if (scontext._.pipe_state != _mesh_object_last_pipeline) {
gpu_set_pipeline(scontext._.pipe_state);
_mesh_object_last_pipeline = scontext._.pipe_state;
if (scontext._.pipe != _mesh_object_last_pipeline) {
gpu_set_pipeline(scontext._.pipe);
_mesh_object_last_pipeline = scontext._.pipe;
}
uniforms_set_context_consts(scontext, bind_params);
uniforms_set_obj_consts(scontext, raw.base);
uniforms_set_material_consts(scontext, material_contexts[0]);
uniforms_set_material_consts(scontext, mcontext);
gpu_set_vertex_buffer(raw.data._.vertex_buffer);
gpu_set_index_buffer(raw.data._.index_buffer);
gpu_draw();
@@ -162,13 +128,3 @@ function mesh_object_compute_camera_dist(raw: mesh_object_t, cam_x: f32, cam_y:
// Render path mesh sorting
raw.camera_dist = vec4_fdist(cam_x, cam_y, cam_z, transform_world_x(raw.base.transform), transform_world_y(raw.base.transform), transform_world_z(raw.base.transform));
}
function mesh_object_compute_screen_size(raw: mesh_object_t, camera: camera_object_t) {
// Approx..
// let rp = camera_render_path;
// let screen_volume = rp.current_w * rp.current_h;
let tr: transform_t = raw.base.transform;
let volume: f32 = tr.dim.x * tr.dim.y * tr.dim.z;
raw.screen_size = volume * (1.0 / raw.camera_dist);
raw.screen_size = raw.screen_size > 1.0 ? 1.0 : raw.screen_size;
}
+2 -2
View File
@@ -164,7 +164,7 @@ function render_path_draw_skydome(handle: string) {
if (cc.context == null) {
return; // World data not specified
}
gpu_set_pipeline(cc.context._.pipe_state);
gpu_set_pipeline(cc.context._.pipe);
uniforms_set_context_consts(cc.context, _render_path_bind_params);
uniforms_set_obj_consts(cc.context, null); // External hosek
gpu_set_vertex_buffer(const_data_skydome_vb);
@@ -190,7 +190,7 @@ function render_path_draw_shader(handle: string) {
if (const_data_screen_aligned_vb == null) {
const_data_create_screen_aligned_data();
}
gpu_set_pipeline(cc.context._.pipe_state);
gpu_set_pipeline(cc.context._.pipe);
uniforms_set_context_consts(cc.context, _render_path_bind_params);
uniforms_set_obj_consts(cc.context, null);
gpu_set_vertex_buffer(const_data_screen_aligned_vb);
+1 -7
View File
@@ -456,7 +456,6 @@ type material_data_t = {
type material_data_runtime_t = {
uid?: f32;
shader?: shader_data_t;
contexts?: material_context_t[];
};
type material_context_t = {
@@ -483,11 +482,6 @@ type bind_tex_t = {
type shader_data_t = {
name?: string;
contexts?: shader_context_t[];
_?: shader_data_runtime_t;
};
type shader_data_runtime_t = {
contexts?: shader_context_t[];
};
type shader_context_t = {
@@ -515,7 +509,7 @@ type shader_context_t = {
};
type shader_context_runtime_t = {
pipe_state?: gpu_pipeline_t;
pipe?: gpu_pipeline_t;
constants?: i32[];
tex_units?: i32[];
structure?: gpu_vertex_structure_t;
+46 -69
View File
@@ -1,11 +1,8 @@
function shader_data_create(raw: shader_data_t): shader_data_t {
raw._ = {};
raw._.contexts = [];
for (let i: i32 = 0; i < raw.contexts.length; ++i) {
let c: shader_context_t = raw.contexts[i];
let con: shader_context_t = shader_context_create(c);
array_push(raw._.contexts, con);
shader_context_load(c);
}
return raw;
}
@@ -43,15 +40,15 @@ function shader_data_get_raw_by_name(datas: shader_data_t[], name: string): shad
}
function shader_data_delete(raw: shader_data_t) {
for (let i: i32 = 0; i < raw._.contexts.length; ++i) {
let c: shader_context_t = raw._.contexts[i];
for (let i: i32 = 0; i < raw.contexts.length; ++i) {
let c: shader_context_t = raw.contexts[i];
shader_context_delete(c);
}
}
function shader_data_get_context(raw: shader_data_t, name: string): shader_context_t {
for (let i: i32 = 0; i < raw._.contexts.length; ++i) {
let c: shader_context_t = raw._.contexts[i];
for (let i: i32 = 0; i < raw.contexts.length; ++i) {
let c: shader_context_t = raw.contexts[i];
if (c.name == name) {
return c;
}
@@ -59,106 +56,90 @@ function shader_data_get_context(raw: shader_data_t, name: string): shader_conte
return null;
}
function shader_context_create(raw: shader_context_t): shader_context_t {
function shader_context_load(raw: shader_context_t) {
if (raw._ == null) {
raw._ = {};
}
shader_context_parse_vertex_struct(raw);
return shader_context_compile(raw);
shader_context_compile(raw);
}
function shader_context_compile(raw: shader_context_t): shader_context_t {
if (raw._.pipe_state != null) {
gpu_delete_pipeline(raw._.pipe_state);
function shader_context_compile(raw: shader_context_t) {
if (raw._.pipe != null) {
gpu_delete_pipeline(raw._.pipe);
}
raw._.pipe_state = gpu_create_pipeline();
raw._.pipe = gpu_create_pipeline();
raw._.constants = [];
raw._.tex_units = [];
raw._.pipe_state.input_layout = raw._.structure;
// Depth
raw._.pipe_state.depth_write = raw.depth_write;
raw._.pipe_state.depth_mode = shader_context_get_compare_mode(raw.compare_mode);
// Cull
raw._.pipe_state.cull_mode = shader_context_get_cull_mode(raw.cull_mode);
// Blending
raw._.pipe.input_layout = raw._.structure;
raw._.pipe.depth_write = raw.depth_write;
raw._.pipe.depth_mode = shader_context_get_compare_mode(raw.compare_mode);
raw._.pipe.cull_mode = shader_context_get_cull_mode(raw.cull_mode);
if (raw.blend_source != null) {
raw._.pipe_state.blend_source = shader_context_get_blend_fac(raw.blend_source);
raw._.pipe.blend_source = shader_context_get_blend_fac(raw.blend_source);
}
if (raw.blend_destination != null) {
raw._.pipe_state.blend_destination = shader_context_get_blend_fac(raw.blend_destination);
raw._.pipe.blend_destination = shader_context_get_blend_fac(raw.blend_destination);
}
if (raw.alpha_blend_source != null) {
raw._.pipe_state.alpha_blend_source = shader_context_get_blend_fac(raw.alpha_blend_source);
raw._.pipe.alpha_blend_source = shader_context_get_blend_fac(raw.alpha_blend_source);
}
if (raw.alpha_blend_destination != null) {
raw._.pipe_state.alpha_blend_destination = shader_context_get_blend_fac(raw.alpha_blend_destination);
raw._.pipe.alpha_blend_destination = shader_context_get_blend_fac(raw.alpha_blend_destination);
}
// Per-target color write mask
if (raw.color_writes_red != null) {
for (let i: i32 = 0; i < raw.color_writes_red.length; ++i) {
ARRAY_ACCESS(raw._.pipe_state.color_write_mask_red, i) = raw.color_writes_red[i];
ARRAY_ACCESS(raw._.pipe.color_write_mask_red, i) = raw.color_writes_red[i];
}
}
if (raw.color_writes_green != null) {
for (let i: i32 = 0; i < raw.color_writes_green.length; ++i) {
ARRAY_ACCESS(raw._.pipe_state.color_write_mask_green, i) = raw.color_writes_green[i];
ARRAY_ACCESS(raw._.pipe.color_write_mask_green, i) = raw.color_writes_green[i];
}
}
if (raw.color_writes_blue != null) {
for (let i: i32 = 0; i < raw.color_writes_blue.length; ++i) {
ARRAY_ACCESS(raw._.pipe_state.color_write_mask_blue, i) = raw.color_writes_blue[i];
ARRAY_ACCESS(raw._.pipe.color_write_mask_blue, i) = raw.color_writes_blue[i];
}
}
if (raw.color_writes_alpha != null) {
for (let i: i32 = 0; i < raw.color_writes_alpha.length; ++i) {
ARRAY_ACCESS(raw._.pipe_state.color_write_mask_alpha, i) = raw.color_writes_alpha[i];
ARRAY_ACCESS(raw._.pipe.color_write_mask_alpha, i) = raw.color_writes_alpha[i];
}
}
// Color attachment format
if (raw.color_attachments != null) {
raw._.pipe_state.color_attachment_count = raw.color_attachments.length;
raw._.pipe.color_attachment_count = raw.color_attachments.length;
for (let i: i32 = 0; i < raw.color_attachments.length; ++i) {
ARRAY_ACCESS(raw._.pipe_state.color_attachment, i) = shader_context_get_tex_format(raw.color_attachments[i]);
ARRAY_ACCESS(raw._.pipe.color_attachment, i) = shader_context_get_tex_format(raw.color_attachments[i]);
}
}
// Depth attachment format
if (raw.depth_attachment != null) {
raw._.pipe_state.depth_attachment_bits = raw.depth_attachment == "NONE" ? 0 : 32;
raw._.pipe.depth_attachment_bits = raw.depth_attachment == "NONE" ? 0 : 32;
}
// Shaders
if (raw.shader_from_source) {
raw._.pipe_state.vertex_shader = gpu_create_shader_from_source(raw.vertex_shader, raw._.vertex_shader_size, shader_type_t.VERTEX);
raw._.pipe_state.fragment_shader = gpu_create_shader_from_source(raw.fragment_shader, raw._.fragment_shader_size, shader_type_t.FRAGMENT);
// Shader compile error
if (raw._.pipe_state.vertex_shader == null || raw._.pipe_state.fragment_shader == null) {
return null;
raw._.pipe.vertex_shader = gpu_create_shader_from_source(raw.vertex_shader, raw._.vertex_shader_size, shader_type_t.VERTEX);
raw._.pipe.fragment_shader = gpu_create_shader_from_source(raw.fragment_shader, raw._.fragment_shader_size, shader_type_t.FRAGMENT);
if (raw._.pipe.vertex_shader == null || raw._.pipe.fragment_shader == null) {
return;
}
}
else {
///if arm_embed
raw._.pipe_state.fragment_shader = sys_get_shader(raw.fragment_shader);
raw._.pipe_state.vertex_shader = sys_get_shader(raw.vertex_shader);
raw._.pipe.fragment_shader = sys_get_shader(raw.fragment_shader);
raw._.pipe.vertex_shader = sys_get_shader(raw.vertex_shader);
///else // Load shaders manually
let vs_buffer: buffer_t = data_get_blob(raw.vertex_shader + shader_data_ext());
raw._.pipe_state.vertex_shader = gpu_create_shader(vs_buffer, shader_type_t.VERTEX);
raw._.pipe.vertex_shader = gpu_create_shader(vs_buffer, shader_type_t.VERTEX);
let fs_buffer: buffer_t = data_get_blob(raw.fragment_shader + shader_data_ext());
raw._.pipe_state.fragment_shader = gpu_create_shader(fs_buffer, shader_type_t.FRAGMENT);
raw._.pipe.fragment_shader = gpu_create_shader(fs_buffer, shader_type_t.FRAGMENT);
///end
}
return shader_context_finish_compile(raw);
shader_context_finish_compile(raw);
}
///if arm_direct3d12
@@ -217,28 +198,24 @@ function shader_context_type_pad(offset: i32, size: i32): i32 {
///end
function shader_context_finish_compile(raw: shader_context_t): shader_context_t {
gpu_pipeline_compile(raw._.pipe_state);
function shader_context_finish_compile(raw: shader_context_t) {
gpu_pipeline_compile(raw._.pipe);
if (raw.constants != null) {
let offset: i32 = 0;
for (let i: i32 = 0; i < raw.constants.length; ++i) {
let c: shader_const_t = raw.constants[i];
let size: i32 = shader_context_type_size(c.type);
offset += shader_context_type_pad(offset, size);
shader_context_add_const(raw, c, offset);
shader_context_add_const(raw, offset);
offset += size;
}
}
if (raw.texture_units != null) {
for (let i: i32 = 0; i < raw.texture_units.length; ++i) {
let tu: tex_unit_t = raw.texture_units[i];
shader_context_add_tex(raw, tu, i);
shader_context_add_tex(raw, i);
}
}
return raw;
}
function shader_context_parse_data(data: string): vertex_data_t {
@@ -274,13 +251,13 @@ function shader_context_parse_vertex_struct(raw: shader_context_t) {
}
function shader_context_delete(raw: shader_context_t) {
if (raw._.pipe_state.fragment_shader != null) {
gpu_shader_destroy(raw._.pipe_state.fragment_shader);
if (raw._.pipe.fragment_shader != null) {
gpu_shader_destroy(raw._.pipe.fragment_shader);
}
if (raw._.pipe_state.vertex_shader != null) {
gpu_shader_destroy(raw._.pipe_state.vertex_shader);
if (raw._.pipe.vertex_shader != null) {
gpu_shader_destroy(raw._.pipe.vertex_shader);
}
gpu_delete_pipeline(raw._.pipe_state);
gpu_delete_pipeline(raw._.pipe);
}
function shader_context_get_compare_mode(s: string): compare_mode_t {
@@ -350,10 +327,10 @@ function shader_context_get_tex_format(s: string): tex_format_t {
return tex_format_t.RGBA32;
}
function shader_context_add_const(raw: shader_context_t, c: shader_const_t, offset: i32) {
function shader_context_add_const(raw: shader_context_t, offset: i32) {
array_push(raw._.constants, offset);
}
function shader_context_add_tex(raw: shader_context_t, tu: tex_unit_t, i: i32) {
function shader_context_add_tex(raw: shader_context_t, i: i32) {
array_push(raw._.tex_units, i);
}
+1 -1
View File
@@ -396,7 +396,7 @@ function util_render_make_node_preview(canvas: ui_node_canvas_t, node: ui_node_t
transform_build_matrix(context_raw.paint_object.base.transform);
_gpu_begin(image);
gpu_set_pipeline(res.scon._.pipe_state);
gpu_set_pipeline(res.scon._.pipe);
let empty: string[] = [""];
uniforms_set_context_consts(res.scon, empty);
uniforms_set_obj_consts(res.scon, context_raw.paint_object.base);