gpu backend uniform binding
This commit is contained in:
@@ -133,7 +133,7 @@ draw.slice9 = function slice9(image, rect = [0,0], slice = 0, info = slice9_info
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
draw.image = function image(image, rect, scale = {x:1,y:1}, anchor, shear, info = {mode:"nearest"}, material = {color:{r:1,g:1,b:1,a:1}}) {
|
draw.image = function image(image, rect, scale = {x:1,y:1}, anchor, shear, info, material) {
|
||||||
if (!rect) throw Error('Need rectangle to render image.')
|
if (!rect) throw Error('Need rectangle to render image.')
|
||||||
if (!image) throw Error('Need an image to render.')
|
if (!image) throw Error('Need an image to render.')
|
||||||
|
|
||||||
|
|||||||
@@ -193,32 +193,14 @@ shader_type = 'msl'
|
|||||||
var sampler_cache = {}
|
var sampler_cache = {}
|
||||||
|
|
||||||
function canonicalize_sampler(desc) {
|
function canonicalize_sampler(desc) {
|
||||||
if (desc == true)
|
return json.encode(desc)
|
||||||
return json.encode(default_sampler)
|
|
||||||
|
|
||||||
var sampler_obj = {}
|
|
||||||
sampler_obj.__proto__ = default_sampler
|
|
||||||
|
|
||||||
if (typeof desc == 'object') {
|
|
||||||
for (var key in desc) {
|
|
||||||
if (desc.hasOwnProperty(key)) {
|
|
||||||
sampler_obj[key] = desc[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var keys = Object.keys(sampler_obj).sort()
|
|
||||||
var canonical = {}
|
|
||||||
for (var i = 0; i < keys.length; i++)
|
|
||||||
canonical[keys[i]] = sampler_obj[keys[i]]
|
|
||||||
|
|
||||||
return json.encode(canonical)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_sampler(desc) {
|
function get_sampler(desc) {
|
||||||
var key = canonicalize_sampler(desc)
|
var key = canonicalize_sampler(desc)
|
||||||
|
|
||||||
if (!sampler_cache[key]) {
|
if (!sampler_cache[key]) {
|
||||||
|
|
||||||
var sampler_config = json.decode(key)
|
var sampler_config = json.decode(key)
|
||||||
sampler_cache[key] = new sdl_gpu.sampler(device, sampler_config)
|
sampler_cache[key] = new sdl_gpu.sampler(device, sampler_config)
|
||||||
}
|
}
|
||||||
@@ -296,7 +278,6 @@ function get_pipeline_for_material(mat = {}) {
|
|||||||
|
|
||||||
cfg.__proto__ = sprite_pipeline
|
cfg.__proto__ = sprite_pipeline
|
||||||
material_pipeline_cache[key] = load_pipeline(cfg)
|
material_pipeline_cache[key] = load_pipeline(cfg)
|
||||||
log.console(`created pipeline for ${json.encode(cfg)}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return material_pipeline_cache[key];
|
return material_pipeline_cache[key];
|
||||||
@@ -304,9 +285,95 @@ function get_pipeline_for_material(mat = {}) {
|
|||||||
|
|
||||||
function load_pipeline(config)
|
function load_pipeline(config)
|
||||||
{
|
{
|
||||||
config.vertex = make_shader(config.vertex)[GPU]
|
// pull back the JS shader objects (they have `.reflection`)
|
||||||
config.fragment = make_shader(config.fragment)[GPU]
|
def vertShader = make_shader(config.vertex);
|
||||||
return new sdl_gpu.graphics_pipeline(device, config)
|
def fragShader = make_shader(config.fragment);
|
||||||
|
|
||||||
|
// build the GPU pipeline
|
||||||
|
def gpuPipeline = new sdl_gpu.graphics_pipeline(device, {
|
||||||
|
vertex: vertShader[GPU],
|
||||||
|
fragment: fragShader[GPU],
|
||||||
|
// ...all the other config fields...
|
||||||
|
primitive: config.primitive,
|
||||||
|
blend: config.blend,
|
||||||
|
cull: config.cull,
|
||||||
|
face: config.face,
|
||||||
|
depth: config.depth,
|
||||||
|
stencil: config.stencil,
|
||||||
|
alpha_to_coverage: config.alpha_to_coverage,
|
||||||
|
multisample: config.multisample,
|
||||||
|
label: config.label,
|
||||||
|
target: config.target,
|
||||||
|
vertex_buffer_descriptions: config.vertex_buffer_descriptions,
|
||||||
|
vertex_attributes: config.vertex_attributes
|
||||||
|
});
|
||||||
|
|
||||||
|
// stash the reflection in the JS wrapper for easy access later
|
||||||
|
gpuPipeline._reflection = {
|
||||||
|
vertex: vertShader.reflection,
|
||||||
|
fragment: fragShader.reflection
|
||||||
|
};
|
||||||
|
|
||||||
|
return gpuPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to pack JavaScript objects into binary blob for UBOs
|
||||||
|
function pack_ubo(obj, ubo_type, reflection) {
|
||||||
|
var type_def = reflection.types[ubo_type];
|
||||||
|
if (!type_def) {
|
||||||
|
log.console(`Warning: No type definition found for ${ubo_type}`);
|
||||||
|
return geometry.array_blob([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result_blob = new blob();
|
||||||
|
|
||||||
|
// Process each member in the UBO structure
|
||||||
|
for (var member of type_def.members) {
|
||||||
|
var value = obj[member.name];
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
if (member.type == "vec4") {
|
||||||
|
result_blob.write_blob(geometry.array_blob([1, 1, 1, 1]));
|
||||||
|
} else if (member.type == "vec3") {
|
||||||
|
result_blob.write_blob(geometry.array_blob([1, 1, 1]));
|
||||||
|
} else if (member.type == "vec2") {
|
||||||
|
result_blob.write_blob(geometry.array_blob([1, 1]));
|
||||||
|
} else if (member.type == "float") {
|
||||||
|
result_blob.write_blob(geometry.array_blob([1]));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert value to appropriate format based on type
|
||||||
|
if (member.type == "vec4") {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result_blob.write_blob(geometry.array_blob(value));
|
||||||
|
} else if (typeof value == "object" && value.r != null) {
|
||||||
|
// Color object
|
||||||
|
result_blob.write_blob(geometry.array_blob([value.r, value.g, value.b, value.a || 1]));
|
||||||
|
} else {
|
||||||
|
// Single value, expand to vec4
|
||||||
|
result_blob.write_blob(geometry.array_blob([value, value, value, value]));
|
||||||
|
}
|
||||||
|
} else if (member.type == "vec3") {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result_blob.write_blob(geometry.array_blob(value));
|
||||||
|
} else if (typeof value == 'object' && value.r != null)
|
||||||
|
result_blob.write_blob(geometry.array_blob([value.r, value.g, value.b]));
|
||||||
|
else
|
||||||
|
result_blob.write_blob(geometry.array_blob([value, value, value]));
|
||||||
|
} else if (member.type == "vec2") {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result_blob.write_blob(geometry.array_blob(value));
|
||||||
|
} else {
|
||||||
|
result_blob.write_blob(geometry.array_blob([value, value]));
|
||||||
|
}
|
||||||
|
} else if (member.type == "float") {
|
||||||
|
result_blob.write_blob(geometry.array_blob([value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stone(result_blob)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize ImGui with the window and renderer
|
// Initialize ImGui with the window and renderer
|
||||||
@@ -513,10 +580,7 @@ cmd_fns.camera = function(cmd)
|
|||||||
{
|
{
|
||||||
if (cmd.camera.surface && !cmd.camera.surface[GPU]) {
|
if (cmd.camera.surface && !cmd.camera.surface[GPU]) {
|
||||||
cmd.camera.surface[GPU] = new sdl_gpu.texture(device, cmd.camera.surface)
|
cmd.camera.surface[GPU] = new sdl_gpu.texture(device, cmd.camera.surface)
|
||||||
// Store the sampler description on the texture for later use
|
// Don't store sampler on texture - samplers belong to materials
|
||||||
if (cmd.camera.surface.sampler != null) {
|
|
||||||
cmd.camera.surface[GPU].sampler_desc = cmd.camera.surface.sampler
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
draw_queue.push(cmd)
|
draw_queue.push(cmd)
|
||||||
}
|
}
|
||||||
@@ -536,15 +600,10 @@ function get_img_gpu(surface)
|
|||||||
samples: 0,
|
samples: 0,
|
||||||
type: "2d",
|
type: "2d",
|
||||||
format: "rgba8",
|
format: "rgba8",
|
||||||
sampler: surface.sampler != null ? surface.sampler : true,
|
sampler: surface.sampler != null ? surface.sampler : default_sampler,
|
||||||
color_target: true
|
color_target: true
|
||||||
})
|
})
|
||||||
|
|
||||||
// Store the sampler description on the texture for later use
|
|
||||||
if (surface.sampler != null) {
|
|
||||||
gpu.sampler_desc = surface.sampler
|
|
||||||
}
|
|
||||||
|
|
||||||
var tbuf = new sdl_gpu.transfer_buffer(device, {
|
var tbuf = new sdl_gpu.transfer_buffer(device, {
|
||||||
size: surface.pixels.length/8,
|
size: surface.pixels.length/8,
|
||||||
usage: "upload"
|
usage: "upload"
|
||||||
@@ -582,7 +641,7 @@ var draw_queue = []
|
|||||||
var index_count = 0
|
var index_count = 0
|
||||||
var vertex_count = 0
|
var vertex_count = 0
|
||||||
|
|
||||||
function render_geom(geom, img, pipeline = get_pipeline_for_material(null))
|
function render_geom(geom, img, pipeline = get_pipeline_for_material(null), material = null)
|
||||||
{
|
{
|
||||||
if (!img[GPU]) {
|
if (!img[GPU]) {
|
||||||
if (img.surface)
|
if (img.surface)
|
||||||
@@ -601,6 +660,7 @@ function render_geom(geom, img, pipeline = get_pipeline_for_material(null))
|
|||||||
draw_queue.push({
|
draw_queue.push({
|
||||||
pipeline,
|
pipeline,
|
||||||
texture: img[GPU],
|
texture: img[GPU],
|
||||||
|
material: material,
|
||||||
num_indices: geom.num_indices,
|
num_indices: geom.num_indices,
|
||||||
first_index: index_count,
|
first_index: index_count,
|
||||||
vertex_offset: vertex_count
|
vertex_offset: vertex_count
|
||||||
@@ -625,8 +685,12 @@ cmd_fns.draw_image = function(cmd)
|
|||||||
geom.indices = geometry.make_quad_indices(1)
|
geom.indices = geometry.make_quad_indices(1)
|
||||||
geom.num_indices = 6
|
geom.num_indices = 6
|
||||||
|
|
||||||
|
// Ensure material has diffuse property for dynamic binding
|
||||||
|
if (!cmd.material) cmd.material = {}
|
||||||
|
if (!cmd.material.diffuse) cmd.material.diffuse = img
|
||||||
|
|
||||||
var pipeline = get_pipeline_for_material(cmd.material)
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
render_geom(geom, img, pipeline)
|
render_geom(geom, img, pipeline, cmd.material)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.draw_text = function(cmd)
|
cmd_fns.draw_text = function(cmd)
|
||||||
@@ -644,36 +708,47 @@ cmd_fns.draw_text = function(cmd)
|
|||||||
font
|
font
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Ensure material has diffuse property for dynamic binding
|
||||||
|
if (!cmd.material) cmd.material = {}
|
||||||
|
if (!cmd.material.diffuse) cmd.material.diffuse = font
|
||||||
|
|
||||||
var pipeline = get_pipeline_for_material(cmd.material)
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
render_geom(mesh, font, pipeline)
|
render_geom(mesh, font, pipeline, cmd.material)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.tilemap = function(cmd)
|
cmd_fns.tilemap = function(cmd)
|
||||||
{
|
{
|
||||||
var geometryCommands = cmd.tilemap.draw()
|
var geometryCommands = cmd.tilemap.draw()
|
||||||
|
|
||||||
var pipeline = get_pipeline_for_material(cmd.material)
|
|
||||||
|
|
||||||
for (var geomCmd of geometryCommands) {
|
for (var geomCmd of geometryCommands) {
|
||||||
var img = graphics.texture(geomCmd.image)
|
var img = graphics.texture(geomCmd.image)
|
||||||
if (!img) continue
|
if (!img) continue
|
||||||
|
|
||||||
render_geom(geomCmd.geometry, img, pipeline)
|
// Create a new material for each tile image with diffuse property
|
||||||
|
var tileMaterial = Object.assign({}, cmd.material || {})
|
||||||
|
tileMaterial.diffuse = img
|
||||||
|
|
||||||
|
var pipeline = get_pipeline_for_material(tileMaterial)
|
||||||
|
render_geom(geomCmd.geometry, img, pipeline, tileMaterial)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.geometry = function(cmd)
|
cmd_fns.geometry = function(cmd)
|
||||||
{
|
{
|
||||||
var pipeline = get_pipeline_for_material(cmd.material)
|
var img
|
||||||
|
|
||||||
if (typeof cmd.image == 'object') {
|
if (typeof cmd.image == 'object') {
|
||||||
render_geom(cmd.geometry, cmd.image, pipeline)
|
img = cmd.image
|
||||||
return
|
} else {
|
||||||
|
img = graphics.texture(cmd.image)
|
||||||
|
if (!img) return
|
||||||
}
|
}
|
||||||
var img = graphics.texture(cmd.image)
|
|
||||||
if (!img) return
|
|
||||||
|
|
||||||
render_geom(cmd.geometry, img, pipeline)
|
// Ensure material has diffuse property for dynamic binding
|
||||||
|
if (!cmd.material) cmd.material = {}
|
||||||
|
if (!cmd.material.diffuse) cmd.material.diffuse = img
|
||||||
|
|
||||||
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
|
render_geom(cmd.geometry, img, pipeline, cmd.material)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.draw_slice9 = function(cmd)
|
cmd_fns.draw_slice9 = function(cmd)
|
||||||
@@ -704,8 +779,12 @@ cmd_fns.draw_slice9 = function(cmd)
|
|||||||
|
|
||||||
var mesh = geometry.slice9(img, cmd.rect, slice_lrtb, slice_info)
|
var mesh = geometry.slice9(img, cmd.rect, slice_lrtb, slice_info)
|
||||||
|
|
||||||
|
// Ensure material has diffuse property for dynamic binding
|
||||||
|
if (!cmd.material) cmd.material = {}
|
||||||
|
if (!cmd.material.diffuse) cmd.material.diffuse = img
|
||||||
|
|
||||||
var pipeline = get_pipeline_for_material(cmd.material)
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
render_geom(mesh, img, pipeline)
|
render_geom(mesh, img, pipeline, cmd.material)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.draw_rect = function(cmd)
|
cmd_fns.draw_rect = function(cmd)
|
||||||
@@ -720,7 +799,7 @@ cmd_fns.draw_rect = function(cmd)
|
|||||||
white_pixel[GPU] = get_img_gpu(white_pixel)
|
white_pixel[GPU] = get_img_gpu(white_pixel)
|
||||||
|
|
||||||
var pipeline = get_pipeline_for_material(cmd.material)
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
render_geom(geom, {[GPU]: white_pixel[GPU]}, pipeline)
|
render_geom(geom, {[GPU]: white_pixel[GPU]}, pipeline, cmd.material)
|
||||||
}
|
}
|
||||||
|
|
||||||
var copy_pass
|
var copy_pass
|
||||||
@@ -829,6 +908,56 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
|||||||
current_camera_blob = null
|
current_camera_blob = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic material binding - bind uniforms and textures from material
|
||||||
|
if (cmd.material && cmd.pipeline._reflection) {
|
||||||
|
def refl = cmd.pipeline._reflection;
|
||||||
|
|
||||||
|
// Bind UBOs (uniform buffer objects)
|
||||||
|
if (refl.fragment && refl.fragment.ubos) {
|
||||||
|
for (def ubo of refl.fragment.ubos) {
|
||||||
|
def name = ubo.name;
|
||||||
|
def ubo_type = ubo.type;
|
||||||
|
|
||||||
|
// For PSConstants or other UBOs, pack the material properties according to the UBO structure
|
||||||
|
def packed_blob = pack_ubo(cmd.material, ubo_type, refl.fragment);
|
||||||
|
|
||||||
|
if (packed_blob && packed_blob.length > 0) {
|
||||||
|
// Push uniform data to both vertex and fragment stages
|
||||||
|
// render_queue.push_vertex_uniform_data(ubo.binding, packed_blob);
|
||||||
|
render_queue.push_fragment_uniform_data(ubo.binding, packed_blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind textures for any separate_images
|
||||||
|
if (refl.fragment && refl.fragment.separate_images) {
|
||||||
|
for (def imgDesc of refl.fragment.separate_images) {
|
||||||
|
def name = imgDesc.name;
|
||||||
|
def binding = imgDesc.binding;
|
||||||
|
def img = cmd.material[name];
|
||||||
|
if (img) {
|
||||||
|
// Ensure texture is on GPU
|
||||||
|
if (!img[GPU]) {
|
||||||
|
if (img.surface) {
|
||||||
|
img[GPU] = get_img_gpu(img.surface);
|
||||||
|
} else if (img.cpu) {
|
||||||
|
img[GPU] = get_img_gpu(img.cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (img[GPU]) {
|
||||||
|
// Use material's sampler or default_sampler
|
||||||
|
def sampler_desc = cmd.material.sampler || default_sampler;
|
||||||
|
render_pass.bind_samplers(false, binding, [{
|
||||||
|
texture: img[GPU],
|
||||||
|
sampler: get_sampler(sampler_desc)
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only bind buffers if not already bound or pipeline changed
|
// Only bind buffers if not already bound or pipeline changed
|
||||||
if (!buffers_bound) {
|
if (!buffers_bound) {
|
||||||
render_pass.bind_buffers(0, [
|
render_pass.bind_buffers(0, [
|
||||||
@@ -850,12 +979,17 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
|||||||
current_camera_blob = cur_cam
|
current_camera_blob = cur_cam
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use texture's sampler if it has one, otherwise use standard sampler
|
// Bind default texture if material didn't already bind "diffuse"
|
||||||
var sampler_to_use = std_sampler
|
// Always bind the diffuse texture with material's sampler
|
||||||
if (cmd.texture && cmd.texture.sampler_desc) {
|
if (cmd.texture) {
|
||||||
sampler_to_use = get_sampler(cmd.texture.sampler_desc)
|
// Use material's sampler if specified, otherwise use default_sampler
|
||||||
|
var sampler_desc = (cmd.material && cmd.material.sampler)
|
||||||
|
? cmd.material.sampler
|
||||||
|
: default_sampler
|
||||||
|
|
||||||
|
var sampler_obj = get_sampler(sampler_desc)
|
||||||
|
render_pass.bind_samplers(false, 0, [{texture: cmd.texture, sampler: sampler_obj}])
|
||||||
}
|
}
|
||||||
render_pass.bind_samplers(false, 0, [{texture:cmd.texture, sampler: sampler_to_use}])
|
|
||||||
|
|
||||||
render_pass.draw_indexed(
|
render_pass.draw_indexed(
|
||||||
cmd.num_indices,
|
cmd.num_indices,
|
||||||
|
|||||||
@@ -13,11 +13,13 @@
|
|||||||
#define QJSCLASSGPUWRAPPER(WRAPPERTYPE, SDLTYPE) \
|
#define QJSCLASSGPUWRAPPER(WRAPPERTYPE, SDLTYPE) \
|
||||||
typedef struct { \
|
typedef struct { \
|
||||||
SDL_GPUDevice *device; \
|
SDL_GPUDevice *device; \
|
||||||
|
JSValue js_device; \
|
||||||
SDL_##SDLTYPE *type; \
|
SDL_##SDLTYPE *type; \
|
||||||
} WRAPPERTYPE; \
|
} WRAPPERTYPE; \
|
||||||
JSClassID js_SDL_##SDLTYPE##_id; \
|
JSClassID js_SDL_##SDLTYPE##_id; \
|
||||||
static void js_SDL_##SDLTYPE##_finalizer(JSRuntime *rt, JSValue val) { \
|
static void js_SDL_##SDLTYPE##_finalizer(JSRuntime *rt, JSValue val) { \
|
||||||
WRAPPERTYPE *wrapper = JS_GetOpaque(val, js_SDL_##SDLTYPE##_id); \
|
WRAPPERTYPE *wrapper = JS_GetOpaque(val, js_SDL_##SDLTYPE##_id); \
|
||||||
|
JS_FreeValueRT(rt, wrapper->js_device); \
|
||||||
if (wrapper && wrapper->device && wrapper->type) \
|
if (wrapper && wrapper->device && wrapper->type) \
|
||||||
SDL_Release##SDLTYPE(wrapper->device, wrapper->type); \
|
SDL_Release##SDLTYPE(wrapper->device, wrapper->type); \
|
||||||
free(wrapper); \
|
free(wrapper); \
|
||||||
@@ -31,9 +33,10 @@ SDL_##SDLTYPE *js2SDL_##SDLTYPE(JSContext *js, JSValue val) { \
|
|||||||
WRAPPERTYPE *wrapper = JS_GetOpaque(val, js_SDL_##SDLTYPE##_id); \
|
WRAPPERTYPE *wrapper = JS_GetOpaque(val, js_SDL_##SDLTYPE##_id); \
|
||||||
return wrapper ? wrapper->type : NULL; \
|
return wrapper ? wrapper->type : NULL; \
|
||||||
} \
|
} \
|
||||||
JSValue SDL_##SDLTYPE##2js(JSContext *js, SDL_GPUDevice *device, SDL_##SDLTYPE *member) { \
|
JSValue SDL_##SDLTYPE##2js(JSContext *js, JSValue device, SDL_##SDLTYPE *member) { \
|
||||||
WRAPPERTYPE *wrapper = malloc(sizeof(WRAPPERTYPE)); \
|
WRAPPERTYPE *wrapper = malloc(sizeof(WRAPPERTYPE)); \
|
||||||
wrapper->device = device; \
|
wrapper->js_device = JS_DupValue(js,device); \
|
||||||
|
wrapper->device = js2SDL_GPUDevice(js, device); \
|
||||||
wrapper->type = member; \
|
wrapper->type = member; \
|
||||||
JSValue j = JS_NewObjectClass(js, js_SDL_##SDLTYPE##_id); \
|
JSValue j = JS_NewObjectClass(js, js_SDL_##SDLTYPE##_id); \
|
||||||
JS_SetOpaque(j, wrapper); \
|
JS_SetOpaque(j, wrapper); \
|
||||||
@@ -719,7 +722,7 @@ static JSValue js_gpu_graphics_pipeline_constructor(JSContext *js, JSValueConst
|
|||||||
SDL_GPUGraphicsPipeline *pipeline = SDL_CreateGPUGraphicsPipeline(gpu, &info);
|
SDL_GPUGraphicsPipeline *pipeline = SDL_CreateGPUGraphicsPipeline(gpu, &info);
|
||||||
if (!pipeline) return JS_ThrowInternalError(js, "Failed to create GPU pipeline: %s", SDL_GetError());
|
if (!pipeline) return JS_ThrowInternalError(js, "Failed to create GPU pipeline: %s", SDL_GetError());
|
||||||
|
|
||||||
return SDL_GPUGraphicsPipeline2js(js, gpu, pipeline);
|
return SDL_GPUGraphicsPipeline2js(js, argv[0], pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standalone sampler constructor: new sdl_gpu.sampler(device, config)
|
// Standalone sampler constructor: new sdl_gpu.sampler(device, config)
|
||||||
@@ -750,7 +753,7 @@ static JSValue js_gpu_sampler_constructor(JSContext *js, JSValueConst self, int
|
|||||||
SDL_GPUSampler *sdl_sampler = SDL_CreateGPUSampler(gpu, &info);
|
SDL_GPUSampler *sdl_sampler = SDL_CreateGPUSampler(gpu, &info);
|
||||||
if (!sdl_sampler) return JS_ThrowInternalError(js, "Failed to create GPU sampler: %s", SDL_GetError());
|
if (!sdl_sampler) return JS_ThrowInternalError(js, "Failed to create GPU sampler: %s", SDL_GetError());
|
||||||
|
|
||||||
return SDL_GPUSampler2js(js, gpu, sdl_sampler);
|
return SDL_GPUSampler2js(js, argv[0], sdl_sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_CCALL(gpu_driver,
|
JSC_CCALL(gpu_driver,
|
||||||
@@ -807,7 +810,7 @@ static JSValue js_gpu_shader_constructor(JSContext *js, JSValueConst self, int a
|
|||||||
if (!shader)
|
if (!shader)
|
||||||
return JS_ThrowReferenceError(js, "Unable to create shader: %s", SDL_GetError());
|
return JS_ThrowReferenceError(js, "Unable to create shader: %s", SDL_GetError());
|
||||||
|
|
||||||
return SDL_GPUShader2js(js, gpu, shader);
|
return SDL_GPUShader2js(js, argv[0], shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_CCALL(gpu_acquire_cmd_buffer,
|
JSC_CCALL(gpu_acquire_cmd_buffer,
|
||||||
@@ -879,7 +882,7 @@ static JSValue js_gpu_compute_pipeline_constructor(JSContext *js, JSValueConst s
|
|||||||
SDL_GPUComputePipeline *pipeline = SDL_CreateGPUComputePipeline(gpu, &info);
|
SDL_GPUComputePipeline *pipeline = SDL_CreateGPUComputePipeline(gpu, &info);
|
||||||
JS_FreeCString(js,info.entrypoint);
|
JS_FreeCString(js,info.entrypoint);
|
||||||
if (!pipeline) return JS_ThrowReferenceError(js,"Could not create compute pipeline: %s", SDL_GetError());
|
if (!pipeline) return JS_ThrowReferenceError(js,"Could not create compute pipeline: %s", SDL_GetError());
|
||||||
return SDL_GPUComputePipeline2js(js, gpu, pipeline);
|
return SDL_GPUComputePipeline2js(js, argv[0], pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standalone buffer constructor: new sdl_gpu.buffer(device, config)
|
// Standalone buffer constructor: new sdl_gpu.buffer(device, config)
|
||||||
@@ -915,7 +918,7 @@ static JSValue js_gpu_buffer_constructor(JSContext *js, JSValueConst self, int a
|
|||||||
SDL_GPUBuffer *buffer = SDL_CreateGPUBuffer(gpu, &info);
|
SDL_GPUBuffer *buffer = SDL_CreateGPUBuffer(gpu, &info);
|
||||||
if (!buffer) return JS_ThrowReferenceError(js, "Unable to create buffer: %s", SDL_GetError());
|
if (!buffer) return JS_ThrowReferenceError(js, "Unable to create buffer: %s", SDL_GetError());
|
||||||
|
|
||||||
return SDL_GPUBuffer2js(js, gpu, buffer);
|
return SDL_GPUBuffer2js(js, argv[0], buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_gpu_transfer_buffer_constructor(JSContext *js, JSValueConst self, int argc, JSValueConst *argv) {
|
static JSValue js_gpu_transfer_buffer_constructor(JSContext *js, JSValueConst self, int argc, JSValueConst *argv) {
|
||||||
@@ -936,7 +939,7 @@ static JSValue js_gpu_transfer_buffer_constructor(JSContext *js, JSValueConst se
|
|||||||
SDL_GPUTransferBuffer *buffer = SDL_CreateGPUTransferBuffer(gpu, &info);
|
SDL_GPUTransferBuffer *buffer = SDL_CreateGPUTransferBuffer(gpu, &info);
|
||||||
if (!buffer) return JS_ThrowReferenceError(js, "Unable to create transfer buffer: %s", SDL_GetError());
|
if (!buffer) return JS_ThrowReferenceError(js, "Unable to create transfer buffer: %s", SDL_GetError());
|
||||||
|
|
||||||
return SDL_GPUTransferBuffer2js(js, gpu, buffer);
|
return SDL_GPUTransferBuffer2js(js, argv[0], buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standalone texture constructor: new sdl_gpu.texture(device, config)
|
// Standalone texture constructor: new sdl_gpu.texture(device, config)
|
||||||
@@ -974,7 +977,7 @@ static JSValue js_gpu_texture_constructor(JSContext *js, JSValueConst self, int
|
|||||||
SDL_GPUTexture *tex = SDL_CreateGPUTexture(gpu, &info);
|
SDL_GPUTexture *tex = SDL_CreateGPUTexture(gpu, &info);
|
||||||
if (!tex) return JS_ThrowReferenceError(js, "Unable to create texture: %s", SDL_GetError());
|
if (!tex) return JS_ThrowReferenceError(js, "Unable to create texture: %s", SDL_GetError());
|
||||||
|
|
||||||
JSValue jstex = SDL_GPUTexture2js(js, gpu, tex);
|
JSValue jstex = SDL_GPUTexture2js(js, argv[0], tex);
|
||||||
JS_SetPropertyStr(js, jstex, "width", number2js(js, info.width));
|
JS_SetPropertyStr(js, jstex, "width", number2js(js, info.width));
|
||||||
JS_SetPropertyStr(js, jstex, "height", number2js(js, info.height));
|
JS_SetPropertyStr(js, jstex, "height", number2js(js, info.height));
|
||||||
JS_SetPropertyStr(js, jstex, "dim", vec22js(js, (HMM_Vec2){info.width, info.height}));
|
JS_SetPropertyStr(js, jstex, "dim", vec22js(js, (HMM_Vec2){info.width, info.height}));
|
||||||
|
|||||||
@@ -789,22 +789,6 @@ JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
|
|||||||
JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
|
JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
|
||||||
JSValueConst replacer, JSValueConst space0);
|
JSValueConst replacer, JSValueConst space0);
|
||||||
|
|
||||||
typedef enum JSPromiseStateEnum {
|
|
||||||
JS_PROMISE_PENDING,
|
|
||||||
JS_PROMISE_FULFILLED,
|
|
||||||
JS_PROMISE_REJECTED,
|
|
||||||
} JSPromiseStateEnum;
|
|
||||||
|
|
||||||
JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
|
|
||||||
JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
|
|
||||||
JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
|
|
||||||
|
|
||||||
/* is_handled = TRUE means that the rejection is handled */
|
|
||||||
typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
|
|
||||||
JSValueConst reason,
|
|
||||||
JS_BOOL is_handled, void *opaque);
|
|
||||||
void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
|
|
||||||
|
|
||||||
/* return != 0 if the JS code needs to be interrupted */
|
/* return != 0 if the JS code needs to be interrupted */
|
||||||
typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
|
typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
|
||||||
void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
|
void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
|
||||||
|
|||||||
Reference in New Issue
Block a user