Almost working compressed textures

This commit is contained in:
sergeypdev 2024-02-15 04:23:18 +04:00
parent a3c93ef8cf
commit d3f0664da6
8 changed files with 403 additions and 71 deletions

View File

@ -7,9 +7,9 @@ v 1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 1.000000 0.000000 -1.000000
vn -0.0000 1.0000 -0.0000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.999900 0.999900
vt 0.000100 0.999900
vt 0.000100 0.000100
vt 0.999900 0.000100
s 0
f 1/1/1 2/2/1 4/3/1 3/4/1

View File

@ -1,3 +1,4 @@
#extension GL_ARB_bindless_texture : enable
// Keep in sync with cpu
#define MAX_POINT_LIGHTS 8
@ -21,6 +22,7 @@ layout(std140, binding = 1) uniform Lights {
// Uniforms
layout(location = 1) uniform mat4 model;
layout(location = 2) uniform vec3 color;
layout(location = 3, bindless_sampler) uniform sampler2D diffuse;
// Input, output blocks
@ -50,7 +52,7 @@ void main() {
out vec4 FragColor;
void main() {
vec3 diffuseColor = color;
vec3 diffuseColor = texture(diffuse, VertexOut.uv).rgb;
vec3 finalColor = vec3(0);
for (int i = 0; i < lights_count; i++) {

View File

@ -22,6 +22,13 @@ pub fn build(b: *Build) void {
"Prioritize performance, safety, or binary size for build time tools",
) orelse .Debug;
const basisu_optimize = b.option(std.builtin.OptimizeMode, "basisu_optimize", "Optimization level for basisu. ReleaseSafe or faster is recommented, otherwise it's slow or can crash due to ubsan.") orelse .ReleaseFast;
const basisu_dep = b.dependency("mach-basisu", .{
.target = target,
.optimize = basisu_optimize,
});
const zalgebra_dep = b.dependency("zalgebra", .{});
const assets_mod = b.addModule("assets", .{ .root_source_file = .{ .path = "src/assets/root.zig" } });
@ -31,7 +38,7 @@ pub fn build(b: *Build) void {
const assets_step = b.step("assets", "Build and install assets");
b.getInstallStep().dependOn(assets_step);
const assetc = buildAssetCompiler(b, assets_step, buildOptimize);
const assetc = buildAssetCompiler(b, basisu_optimize, assets_step, buildOptimize);
assetc.root_module.addImport("assets", assets_mod);
assetc.root_module.addImport("asset_manifest", asset_manifest_mod);
@ -61,6 +68,8 @@ pub fn build(b: *Build) void {
l.root_module.addImport("zalgebra", zalgebra_dep.module("zalgebra"));
l.root_module.addImport("assets", assets_mod);
l.root_module.addImport("asset_manifest", asset_manifest_mod);
l.linkLibrary(basisu_dep.artifact("mach-basisu"));
l.root_module.addImport("mach-basisu", basisu_dep.module("mach-basisu"));
}
const install_lib = b.addInstallArtifact(lib, .{ .dest_dir = .{ .override = .prefix } });
@ -362,7 +371,7 @@ fn writeAssetManifest(
return manifest_path;
}
fn buildAssetCompiler(b: *Build, assets_step: *Step, optimize: std.builtin.OptimizeMode) *Step.Compile {
fn buildAssetCompiler(b: *Build, basisu_optimize: std.builtin.OptimizeMode, assets_step: *Step, optimize: std.builtin.OptimizeMode) *Step.Compile {
const assimp_dep = b.dependency("zig-assimp", .{
.target = b.host,
.optimize = optimize,
@ -370,7 +379,6 @@ fn buildAssetCompiler(b: *Build, assets_step: *Step, optimize: std.builtin.Optim
.formats = @as([]const u8, "Obj"),
});
const basisu_optimize = b.option(std.builtin.OptimizeMode, "basisu_optimize", "Optimization level for basisu. ReleaseSafe or faster is recommented, otherwise it's unbearable.") orelse .ReleaseFast;
const basisu_dep = b.dependency("mach-basisu", .{
.target = b.host,
.optimize = basisu_optimize,

View File

@ -20,20 +20,19 @@ const fs_utils = @import("fs/utils.zig");
const formats = @import("formats.zig");
const asset_manifest = @import("asset_manifest");
const assets = @import("assets");
const basisu = @import("mach-basisu");
pub const AssetId = assets.AssetId;
pub const Handle = assets.Handle;
pub const AssetManager = @This();
// const ShaderProgramHandle = struct { id: gl.GLuint };
// const handle: ShaderProgramHandle = assets.loadShaderProgram(.{ .vertex = "shaders/vertex.glsl", .fragment = "shaders/fragment.glsl" });
// assets.unloadShaderProgram(handle);
const AssetIdList = std.SegmentedList(AssetId, 4);
const PowerOfTwo = u16;
const SHADER_MAX_BYTES = 1024 * 1024 * 50;
const MESH_MAX_BYTES = 1024 * 1024 * 500;
const TEXTURE_MAX_BYTES = 1024 * 1024 * 500;
allocator: std.mem.Allocator,
frame_arena: std.mem.Allocator,
@ -49,6 +48,8 @@ dependees: std.AutoHashMapUnmanaged(AssetId, std.SegmentedList(AssetId, 4)) = .{
loaded_assets: std.AutoHashMapUnmanaged(AssetId, LoadedAsset) = .{},
pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator) AssetManager {
basisu.init_transcoder();
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const exe_dir_path = std.fs.selfExeDirPath(&buf) catch @panic("can't find self exe dir path");
const exe_dir = std.fs.openDirAbsolute(exe_dir_path, .{}) catch @panic("can't open self exe dir path");
@ -102,6 +103,19 @@ pub fn resolveMesh(self: *AssetManager, handle: Handle.Mesh) *const LoadedMesh {
return self.loadMesh(handle.id);
}
pub fn resolveTexture(self: *AssetManager, handle: Handle.Texture) *const LoadedTexture {
if (self.loaded_assets.getPtr(handle.id)) |asset| {
switch (asset.*) {
.texture => |*texture| {
return texture;
},
else => unreachable,
}
}
return self.loadTexture(handle.id);
}
// TODO: proper watching
pub fn watchChanges(self: *AssetManager) void {
var iter = self.loaded_assets.iterator();
@ -227,6 +241,12 @@ const NullMesh = LoadedMesh{
},
};
// TODO: create empty texture instead, this will crash
const NullTexture = LoadedTexture{
.name = 0,
.handle = 0,
};
pub fn loadMesh(self: *AssetManager, id: AssetId) *const LoadedMesh {
return self.loadMeshErr(id) catch |err| {
std.log.err("Error: {} loading mesh at path: {s}", .{ err, asset_manifest.getPath(id) });
@ -308,10 +328,90 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
return &self.loaded_assets.getPtr(id).?.mesh;
}
fn loadTexture(self: *AssetManager, id: AssetId) *const LoadedTexture {
return self.loadTextureErr(id) catch |err| {
std.log.err("Error: {} loading texture at path {s}\n", .{ err, asset_manifest.getPath(id) });
return &NullTexture;
};
}
fn loadTextureErr(self: *AssetManager, id: AssetId) !*const LoadedTexture {
const path = asset_manifest.getPath(id);
const data = try self.loadFile(self.frame_arena, path, TEXTURE_MAX_BYTES);
const transcoder = try basisu.Transcoder.init(data.bytes);
defer transcoder.deinit();
std.debug.assert(transcoder.getImageCount() == 1); // Not supporting multiple textures yet
const mip_level_count = transcoder.getImageLevelCount(0);
const mip_0_desc = transcoder.getImageLevelDescriptor(0, 0) catch unreachable;
var name: gl.GLuint = 0;
gl.createTextures(gl.TEXTURE_2D, 1, &name);
if (name == 0) {
return error.GLCreateTexture;
}
errdefer gl.deleteTextures(1, &name);
// TODO: query supported formats first in the future
const format = basisu.Transcoder.TextureFormat.bc7_rgba;
gl.textureStorage2D(
name,
@intCast(mip_level_count),
gl.COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
@intCast(mip_0_desc.original_width),
@intCast(mip_0_desc.original_height),
);
for (0..mip_level_count) |mip_level| {
const desc = transcoder.getImageLevelDescriptor(0, 0) catch unreachable;
const out_buf = try self.frame_arena.alloc(
u8,
@intCast(try transcoder.calcTranscodedSize(0, @intCast(mip_level), format)),
);
try transcoder.transcode(out_buf, 0, @intCast(mip_level), format, .{});
gl.compressedTextureSubImage2D(
name,
@intCast(mip_level),
0,
0,
@intCast(desc.original_width),
@intCast(desc.original_height),
gl.COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
@intCast(out_buf.len),
@ptrCast(out_buf.ptr),
);
}
const handle = gl.GL_ARB_bindless_texture.getTextureHandleARB(name);
gl.GL_ARB_bindless_texture.makeTextureHandleResidentARB(handle);
errdefer gl.GL_ARB_bindless_texture.makeTextureHandleNonResidentARB(handle);
try self.loaded_assets.put(
self.allocator,
id,
.{
.texture = LoadedTexture{
.name = name,
.handle = handle,
},
},
);
try self.modified_times.put(self.allocator, id, data.modified);
return &self.loaded_assets.getPtr(id).?.texture;
}
const LoadedAsset = union(enum) {
shader: LoadedShader,
shaderProgram: LoadedShaderProgram,
mesh: LoadedMesh,
texture: LoadedTexture,
};
const LoadedShader = struct {
@ -329,6 +429,11 @@ const LoadedMesh = struct {
indices: IndexSlice,
};
const LoadedTexture = struct {
name: gl.GLuint,
handle: gl.GLuint64,
};
pub const BufferSlice = struct {
buffer: gl.GLuint,
offset: gl.GLintptr,
@ -473,6 +578,10 @@ fn unloadAssetWithDependees(self: *AssetManager, id: AssetId) void {
.shaderProgram => |*program| {
gl.deleteProgram(program.program);
},
.texture => |*texture| {
gl.GL_ARB_bindless_texture.makeTextureHandleNonResidentARB(texture.handle);
gl.deleteTextures(1, &texture.name);
},
}
}
_ = self.loaded_assets.remove(id);

View File

@ -1,6 +1,5 @@
const std = @import("std");
const c = @import("sdl.zig");
const manymouse = @import("manymouse.zig");
const gl = @import("gl.zig");
const AssetManager = @import("AssetManager.zig");
const formats = @import("formats.zig");
@ -293,15 +292,20 @@ export fn game_init_window(global_allocator: *std.mem.Allocator) void {
}
fn loadGL() void {
gl.load(null, struct {
const getProcAddress = struct {
fn getProcAddress(ctx: @TypeOf(null), proc: [:0]const u8) ?gl.FunctionPointer {
_ = ctx;
return @ptrCast(c.SDL_GL_GetProcAddress(proc));
}
}.getProcAddress) catch |err| {
}.getProcAddress;
gl.load(null, getProcAddress) catch |err| {
std.log.debug("Failed to load gl funcs {}\n", .{err});
@panic("gl.load");
};
gl.GL_ARB_bindless_texture.load(null, getProcAddress) catch |err| {
std.log.debug("Failed to load gl funcs GL_ARB_bindless_texture {}\n", .{err});
@panic("gl.load");
};
}
fn checkGLError() void {
@ -377,15 +381,15 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
// normals
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
gl.enableVertexArrayAttrib(vao, Attrib.Normal.value());
gl.vertexArrayAttribBinding(vao, Attrib.Normal.value(), 1);
gl.vertexArrayAttribFormat(vao, Attrib.Normal.value(), 3, gl.FLOAT, gl.FALSE, 0);
gl.enableVertexArrayAttrib(vao, Attrib.Normal.value());
// uvs
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 1);
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
gl.enableVertexArrayAttrib(vao, Attrib.UV.value());
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 2);
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
const PERSISTENT_BUFFER_FLAGS: gl.GLbitfield = gl.MAP_PERSISTENT_BIT | gl.MAP_WRITE_BIT | gl.MAP_COHERENT_BIT;
@ -732,6 +736,10 @@ export fn game_update() bool {
const color = if (ent.flags.mesh) ent.mesh.color else ent.point_light.color();
gl.uniformMatrix4fv(1, 1, gl.FALSE, @ptrCast(&ent.transform.matrix().data));
gl.uniform3fv(2, 1, @ptrCast(&color.data));
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(
3,
g_assetman.resolveTexture(a.Textures.@"test").handle,
);
const mesh_handle = if (ent.flags.mesh) ent.mesh.handle else a.Meshes.sphere;
const mesh = g_assetman.resolveMesh(mesh_handle);

View File

@ -3,6 +3,7 @@ pub const manifest = @import("asset_manifest_gen");
pub const Meshes = manifest.Meshes;
pub const Shaders = manifest.Shaders;
pub const ShaderPrograms = manifest.ShaderPrograms;
pub const Textures = manifest.Textures;
pub fn getPath(asset_id: u32) []const u8 {
if (asset_id == 0) return "";

View File

@ -7,68 +7,68 @@
// Generation parameters:
// API: GL_VERSION_4_5
// Profile: core
// Extensions:
// Extensions: GL_ARB_bindless_texture
//
//
// This file was generated with the following command line:
// generator C:\Users\Серега\git\zig-opengl\bin\Debug\net7.0\generator.dll OpenGL-Registry/xml/gl.xml gl.zig GL_VERSION_4_5
// generator C:\git\zig-opengl\bin\Debug\net7.0\generator.dll OpenGL-Registry\xml\gl.xml gl.zig GL_VERSION_4_5 GL_ARB_bindless_texture
//
const std = @import("std");
const builtin = @import("builtin");
const log = std.log.scoped(.OpenGL);
pub const FunctionPointer: type = *align(@alignOf(fn (u32) callconv(.C) u32)) const anyopaque;
pub const GLenum = c_uint;
pub const GLboolean = u8;
pub const GLbitfield = c_uint;
pub const GLbyte = i8;
pub const GLubyte = u8;
pub const GLshort = i16;
pub const GLushort = u16;
pub const GLint = c_int;
pub const GLuint = c_uint;
pub const GLclampx = i32;
pub const GLsizei = c_int;
pub const GLfloat = f32;
pub const GLclampf = f32;
pub const GLdouble = f64;
pub const GLclampd = f64;
pub const GLeglClientBufferEXT = void;
pub const GLeglImageOES = void;
pub const GLchar = u8;
pub const GLcharARB = u8;
pub const GLhandleARB = if (builtin.os.tag == .macos) *anyopaque else c_uint;
pub const GLhalf = u16;
pub const GLhalfARB = u16;
pub const GLfixed = i32;
pub const GLintptr = usize;
pub const GLintptrARB = usize;
pub const GLsizeiptr = isize;
pub const GLsizeiptrARB = isize;
pub const GLint64 = i64;
pub const GLint64EXT = i64;
pub const GLuint64 = u64;
pub const GLuint64EXT = u64;
pub const GLsync = *opaque {};
pub const _cl_context = opaque {};
pub const _cl_event = opaque {};
pub const GLDEBUGPROC = *const fn (source: GLenum, _type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLDEBUGPROCARB = *const fn (source: GLenum, _type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLDEBUGPROCKHR = *const fn (source: GLenum, _type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLDEBUGPROCAMD = *const fn (id: GLuint, category: GLenum, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLhalfNV = u16;
pub const GLvdpauSurfaceNV = GLintptr;
pub const GLVULKANPROCNV = *const fn () callconv(.C) void;
pub const FunctionPointer: type = *align(@alignOf(fn (u32) callconv(.C) u32)) const anyopaque;
pub const GLenum = c_uint;
pub const GLboolean = u8;
pub const GLbitfield = c_uint;
pub const GLbyte = i8;
pub const GLubyte = u8;
pub const GLshort = i16;
pub const GLushort = u16;
pub const GLint = c_int;
pub const GLuint = c_uint;
pub const GLclampx = i32;
pub const GLsizei = c_int;
pub const GLfloat = f32;
pub const GLclampf = f32;
pub const GLdouble = f64;
pub const GLclampd = f64;
pub const GLeglClientBufferEXT = void;
pub const GLeglImageOES = void;
pub const GLchar = u8;
pub const GLcharARB = u8;
pub const GLhandleARB = if (builtin.os.tag == .macos) *anyopaque else c_uint;
pub const GLhalf = u16;
pub const GLhalfARB = u16;
pub const GLfixed = i32;
pub const GLintptr = usize;
pub const GLintptrARB = usize;
pub const GLsizeiptr = isize;
pub const GLsizeiptrARB = isize;
pub const GLint64 = i64;
pub const GLint64EXT = i64;
pub const GLuint64 = u64;
pub const GLuint64EXT = u64;
pub const GLsync = *opaque {};
pub const _cl_context = opaque {};
pub const _cl_event = opaque {};
pub const GLDEBUGPROC = *const fn (source: GLenum, _type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLDEBUGPROCARB = *const fn (source: GLenum, _type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLDEBUGPROCKHR = *const fn (source: GLenum, _type: GLenum, id: GLuint, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLDEBUGPROCAMD = *const fn (id: GLuint, category: GLenum, severity: GLenum, length: GLsizei, message: [*:0]const u8, userParam: ?*anyopaque) callconv(.C) void;
pub const GLhalfNV = u16;
pub const GLvdpauSurfaceNV = GLintptr;
pub const GLVULKANPROCNV = *const fn () callconv(.C) void;
pub const DEPTH_BUFFER_BIT = 0x00000100;
@ -4031,6 +4031,177 @@ pub fn textureBarrier() callconv(.C) void {
}
// Extensions:
pub const GL_ARB_bindless_texture = struct {
pub const UNSIGNED_INT64_ARB = 0x140F;
pub fn getTextureHandleARB(_texture: GLuint) callconv(.C) GLuint64 {
return @call(.always_tail, function_pointers.glGetTextureHandleARB, .{_texture});
}
pub fn getTextureSamplerHandleARB(_texture: GLuint, _sampler: GLuint) callconv(.C) GLuint64 {
return @call(.always_tail, function_pointers.glGetTextureSamplerHandleARB, .{_texture, _sampler});
}
pub fn makeTextureHandleResidentARB(_handle: GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glMakeTextureHandleResidentARB, .{_handle});
}
pub fn makeTextureHandleNonResidentARB(_handle: GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glMakeTextureHandleNonResidentARB, .{_handle});
}
pub fn getImageHandleARB(_texture: GLuint, _level: GLint, _layered: GLboolean, _layer: GLint, _format: GLenum) callconv(.C) GLuint64 {
return @call(.always_tail, function_pointers.glGetImageHandleARB, .{_texture, _level, _layered, _layer, _format});
}
pub fn makeImageHandleResidentARB(_handle: GLuint64, _access: GLenum) callconv(.C) void {
return @call(.always_tail, function_pointers.glMakeImageHandleResidentARB, .{_handle, _access});
}
pub fn makeImageHandleNonResidentARB(_handle: GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glMakeImageHandleNonResidentARB, .{_handle});
}
pub fn uniformHandleui64ARB(_location: GLint, _value: GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glUniformHandleui64ARB, .{_location, _value});
}
pub fn uniformHandleui64vARB(_location: GLint, _count: GLsizei, _value: [*c]const GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glUniformHandleui64vARB, .{_location, _count, _value});
}
pub fn programUniformHandleui64ARB(_program: GLuint, _location: GLint, _value: GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glProgramUniformHandleui64ARB, .{_program, _location, _value});
}
pub fn programUniformHandleui64vARB(_program: GLuint, _location: GLint, _count: GLsizei, _values: [*c]const GLuint64) callconv(.C) void {
return @call(.always_tail, function_pointers.glProgramUniformHandleui64vARB, .{_program, _location, _count, _values});
}
pub fn isTextureHandleResidentARB(_handle: GLuint64) callconv(.C) GLboolean {
return @call(.always_tail, function_pointers.glIsTextureHandleResidentARB, .{_handle});
}
pub fn isImageHandleResidentARB(_handle: GLuint64) callconv(.C) GLboolean {
return @call(.always_tail, function_pointers.glIsImageHandleResidentARB, .{_handle});
}
pub fn vertexAttribL1ui64ARB(_index: GLuint, _x: GLuint64EXT) callconv(.C) void {
return @call(.always_tail, function_pointers.glVertexAttribL1ui64ARB, .{_index, _x});
}
pub fn vertexAttribL1ui64vARB(_index: GLuint, _v: [*c]const GLuint64EXT) callconv(.C) void {
return @call(.always_tail, function_pointers.glVertexAttribL1ui64vARB, .{_index, _v});
}
pub fn getVertexAttribLui64vARB(_index: GLuint, _pname: GLenum, _params: [*c]GLuint64EXT) callconv(.C) void {
return @call(.always_tail, function_pointers.glGetVertexAttribLui64vARB, .{_index, _pname, _params});
}
pub fn load(load_ctx: anytype, get_proc_address: fn(@TypeOf(load_ctx), [:0]const u8) ?FunctionPointer) !void {
var success = true;
if(get_proc_address(load_ctx, "glGetTextureHandleARB")) |proc| {
function_pointers.glGetTextureHandleARB = @ptrCast(proc);
} else {
log.err("entry point glGetTextureHandleARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glGetTextureSamplerHandleARB")) |proc| {
function_pointers.glGetTextureSamplerHandleARB = @ptrCast(proc);
} else {
log.err("entry point glGetTextureSamplerHandleARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glMakeTextureHandleResidentARB")) |proc| {
function_pointers.glMakeTextureHandleResidentARB = @ptrCast(proc);
} else {
log.err("entry point glMakeTextureHandleResidentARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glMakeTextureHandleNonResidentARB")) |proc| {
function_pointers.glMakeTextureHandleNonResidentARB = @ptrCast(proc);
} else {
log.err("entry point glMakeTextureHandleNonResidentARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glGetImageHandleARB")) |proc| {
function_pointers.glGetImageHandleARB = @ptrCast(proc);
} else {
log.err("entry point glGetImageHandleARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glMakeImageHandleResidentARB")) |proc| {
function_pointers.glMakeImageHandleResidentARB = @ptrCast(proc);
} else {
log.err("entry point glMakeImageHandleResidentARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glMakeImageHandleNonResidentARB")) |proc| {
function_pointers.glMakeImageHandleNonResidentARB = @ptrCast(proc);
} else {
log.err("entry point glMakeImageHandleNonResidentARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glUniformHandleui64ARB")) |proc| {
function_pointers.glUniformHandleui64ARB = @ptrCast(proc);
} else {
log.err("entry point glUniformHandleui64ARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glUniformHandleui64vARB")) |proc| {
function_pointers.glUniformHandleui64vARB = @ptrCast(proc);
} else {
log.err("entry point glUniformHandleui64vARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glProgramUniformHandleui64ARB")) |proc| {
function_pointers.glProgramUniformHandleui64ARB = @ptrCast(proc);
} else {
log.err("entry point glProgramUniformHandleui64ARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glProgramUniformHandleui64vARB")) |proc| {
function_pointers.glProgramUniformHandleui64vARB = @ptrCast(proc);
} else {
log.err("entry point glProgramUniformHandleui64vARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glIsTextureHandleResidentARB")) |proc| {
function_pointers.glIsTextureHandleResidentARB = @ptrCast(proc);
} else {
log.err("entry point glIsTextureHandleResidentARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glIsImageHandleResidentARB")) |proc| {
function_pointers.glIsImageHandleResidentARB = @ptrCast(proc);
} else {
log.err("entry point glIsImageHandleResidentARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glVertexAttribL1ui64ARB")) |proc| {
function_pointers.glVertexAttribL1ui64ARB = @ptrCast(proc);
} else {
log.err("entry point glVertexAttribL1ui64ARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glVertexAttribL1ui64vARB")) |proc| {
function_pointers.glVertexAttribL1ui64vARB = @ptrCast(proc);
} else {
log.err("entry point glVertexAttribL1ui64vARB not found!", .{});
success = false;
}
if(get_proc_address(load_ctx, "glGetVertexAttribLui64vARB")) |proc| {
function_pointers.glGetVertexAttribLui64vARB = @ptrCast(proc);
} else {
log.err("entry point glGetVertexAttribLui64vARB not found!", .{});
success = false;
}
if(!success)
return error.EntryPointNotFound;
}
};
// Loader API:
pub fn load(load_ctx: anytype, get_proc_address: fn(@TypeOf(load_ctx), [:0]const u8) ?FunctionPointer) !void {
var success = true;
@ -8610,6 +8781,22 @@ const function_signatures = struct {
const glGetnUniformuiv = fn(_program: GLuint, _location: GLint, _bufSize: GLsizei, _params: [*c]GLuint) callconv(.C) void;
const glReadnPixels = fn(_x: GLint, _y: GLint, _width: GLsizei, _height: GLsizei, _format: GLenum, _type: GLenum, _bufSize: GLsizei, _data: ?*anyopaque) callconv(.C) void;
const glTextureBarrier = fn() callconv(.C) void;
const glGetTextureHandleARB = fn(_texture: GLuint) callconv(.C) GLuint64;
const glGetTextureSamplerHandleARB = fn(_texture: GLuint, _sampler: GLuint) callconv(.C) GLuint64;
const glMakeTextureHandleResidentARB = fn(_handle: GLuint64) callconv(.C) void;
const glMakeTextureHandleNonResidentARB = fn(_handle: GLuint64) callconv(.C) void;
const glGetImageHandleARB = fn(_texture: GLuint, _level: GLint, _layered: GLboolean, _layer: GLint, _format: GLenum) callconv(.C) GLuint64;
const glMakeImageHandleResidentARB = fn(_handle: GLuint64, _access: GLenum) callconv(.C) void;
const glMakeImageHandleNonResidentARB = fn(_handle: GLuint64) callconv(.C) void;
const glUniformHandleui64ARB = fn(_location: GLint, _value: GLuint64) callconv(.C) void;
const glUniformHandleui64vARB = fn(_location: GLint, _count: GLsizei, _value: [*c]const GLuint64) callconv(.C) void;
const glProgramUniformHandleui64ARB = fn(_program: GLuint, _location: GLint, _value: GLuint64) callconv(.C) void;
const glProgramUniformHandleui64vARB = fn(_program: GLuint, _location: GLint, _count: GLsizei, _values: [*c]const GLuint64) callconv(.C) void;
const glIsTextureHandleResidentARB = fn(_handle: GLuint64) callconv(.C) GLboolean;
const glIsImageHandleResidentARB = fn(_handle: GLuint64) callconv(.C) GLboolean;
const glVertexAttribL1ui64ARB = fn(_index: GLuint, _x: GLuint64EXT) callconv(.C) void;
const glVertexAttribL1ui64vARB = fn(_index: GLuint, _v: [*c]const GLuint64EXT) callconv(.C) void;
const glGetVertexAttribLui64vARB = fn(_index: GLuint, _pname: GLenum, _params: [*c]GLuint64EXT) callconv(.C) void;
};
const function_pointers = struct {
@ -9266,6 +9453,22 @@ const function_pointers = struct {
var glGetnUniformuiv: *const function_signatures.glGetnUniformuiv = undefined;
var glReadnPixels: *const function_signatures.glReadnPixels = undefined;
var glTextureBarrier: *const function_signatures.glTextureBarrier = undefined;
var glGetTextureHandleARB: *const function_signatures.glGetTextureHandleARB = undefined;
var glGetTextureSamplerHandleARB: *const function_signatures.glGetTextureSamplerHandleARB = undefined;
var glMakeTextureHandleResidentARB: *const function_signatures.glMakeTextureHandleResidentARB = undefined;
var glMakeTextureHandleNonResidentARB: *const function_signatures.glMakeTextureHandleNonResidentARB = undefined;
var glGetImageHandleARB: *const function_signatures.glGetImageHandleARB = undefined;
var glMakeImageHandleResidentARB: *const function_signatures.glMakeImageHandleResidentARB = undefined;
var glMakeImageHandleNonResidentARB: *const function_signatures.glMakeImageHandleNonResidentARB = undefined;
var glUniformHandleui64ARB: *const function_signatures.glUniformHandleui64ARB = undefined;
var glUniformHandleui64vARB: *const function_signatures.glUniformHandleui64vARB = undefined;
var glProgramUniformHandleui64ARB: *const function_signatures.glProgramUniformHandleui64ARB = undefined;
var glProgramUniformHandleui64vARB: *const function_signatures.glProgramUniformHandleui64vARB = undefined;
var glIsTextureHandleResidentARB: *const function_signatures.glIsTextureHandleResidentARB = undefined;
var glIsImageHandleResidentARB: *const function_signatures.glIsImageHandleResidentARB = undefined;
var glVertexAttribL1ui64ARB: *const function_signatures.glVertexAttribL1ui64ARB = undefined;
var glVertexAttribL1ui64vARB: *const function_signatures.glVertexAttribL1ui64vARB = undefined;
var glGetVertexAttribLui64vARB: *const function_signatures.glGetVertexAttribLui64vARB = undefined;
};
test {

View File

@ -195,9 +195,10 @@ fn processTexture(allocator: std.mem.Allocator, input: [*:0]const u8, output: []
const img = params.getImageSource(0);
img.fill(data, @intCast(x), @intCast(y), @intCast(FORCED_COMPONENTS));
// TODO: configure per-texture somehow
params.setQualityLevel(64);
params.setBasisFormat(basisu.BasisTextureFormat.etc1s);
// params.setColorSpace(basisu.ColorSpace.linear);
params.setColorSpace(basisu.ColorSpace.srgb);
params.setGenerateMipMaps(true);
var compressor = try basisu.Compressor.init(params);