load and draw texture
@ -5,6 +5,8 @@ struct Configuration {
|
||||
|
||||
@group(0) @binding(0) var<uniform> config: Configuration;
|
||||
@group(0) @binding(1) var<storage> nodeMatrix: array<mat4x4f>;
|
||||
@group(0) @binding(2) var linearSampler: sampler;
|
||||
@group(0) @binding(3) var colorTexture: texture_2d<f32>;
|
||||
|
||||
/*
|
||||
struct Imm {
|
||||
@ -24,11 +26,13 @@ struct VertexOutput {
|
||||
@builtin(position) position: vec4f,
|
||||
@location(0) positionWorld: vec3f,
|
||||
@location(1) normal: vec3f,
|
||||
@location(2) texture: vec2f,
|
||||
};
|
||||
|
||||
struct FragmentInput {
|
||||
@location(0) positionWorld: vec3f,
|
||||
@location(1) normal: vec3f,
|
||||
@location(2) texture: vec2f,
|
||||
};
|
||||
|
||||
@vertex
|
||||
@ -41,6 +45,7 @@ fn vertexMain(input: VertexInput) -> VertexOutput
|
||||
output.position = config.matrix * position;
|
||||
output.positionWorld = (config.matrixWorld * position).xyz;
|
||||
output.normal = (config.matrixWorld * normal).xyz;
|
||||
output.texture = input.texture;
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -88,5 +93,7 @@ fn lighting(position: vec3f, normal: vec3f) -> vec3f
|
||||
fn fragmentMain(input: FragmentInput) -> @location(0) vec4f
|
||||
{
|
||||
let intensity = lighting(input.positionWorld, normalize(input.normal));
|
||||
return vec4(intensity, 1.0);
|
||||
let color = textureSample(colorTexture, linearSampler, input.texture);
|
||||
|
||||
return vec4(color.xyz * intensity, 1.0);
|
||||
}
|
||||
|
||||
BIN
gltf/Image_0.png
|
Before Width: | Height: | Size: 4.3 MiB After Width: | Height: | Size: 4.1 MiB |
BIN
gltf/Image_1.png
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 1.5 MiB |
BIN
gltf/Image_2.png
|
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 2.3 MiB |
BIN
gltf/Image_3.png
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 95 KiB |
14
index.js
@ -256,12 +256,14 @@ const rotate = await WebAssembly.instantiateStreaming(fetch("rotate.wasm"), {
|
||||
env: { memory: memory }
|
||||
});
|
||||
|
||||
const memory2 = new WebAssembly.Memory({ initial: 2 });
|
||||
const mem = await WebAssembly.instantiateStreaming(fetch("memory.wasm"), {
|
||||
env: { memory: memory2 }
|
||||
const memory2 = new WebAssembly.Memory({ initial: 258 * 2 });
|
||||
const module = await WebAssembly.instantiateStreaming(fetch("src/module.wasm"), {
|
||||
env: {
|
||||
memory: memory2,
|
||||
log: console.log,
|
||||
}
|
||||
});
|
||||
console.log("mem");
|
||||
document.mem = mem;
|
||||
//document.module = module;
|
||||
|
||||
const uniformBuffer = device.createBuffer({
|
||||
label: "grid uniform",
|
||||
@ -439,7 +441,7 @@ function render()
|
||||
}
|
||||
//requestAnimationFrame(render);
|
||||
|
||||
const gltfRenderer = await loadGltf(device, canvasFormat, memory2, mem);
|
||||
const gltfRenderer = await loadGltf(device, canvasFormat, memory2, module);
|
||||
|
||||
function render2()
|
||||
{
|
||||
|
||||
126
index2.js
@ -2,7 +2,7 @@ import { getPath } from "./common.js";
|
||||
import { parseGltfChunks, vertexBufferLayouts, primitiveAccessors, splitGltf } from "./gltf.js";
|
||||
|
||||
|
||||
function loadGltfNode(mem, handle, gltf, nodeIndex)
|
||||
function loadGltfNode(module, handle, gltf, nodeIndex)
|
||||
{
|
||||
const node = gltf.json.nodes[nodeIndex];
|
||||
var translation = [0, 0, 0];
|
||||
@ -10,20 +10,20 @@ function loadGltfNode(mem, handle, gltf, nodeIndex)
|
||||
translation = node.translation;
|
||||
}
|
||||
console.log("init", nodeIndex, translation);
|
||||
mem.instance.exports.node_init_translation(handle, nodeIndex, translation[0], translation[1], translation[2]);
|
||||
module.instance.exports.node_init_translation(handle, nodeIndex, translation[0], translation[1], translation[2]);
|
||||
|
||||
if ("children" in node) {
|
||||
for (let childIndex in node.children) {
|
||||
loadGltfNode(mem, handle, gltf, childIndex);
|
||||
loadGltfNode(module, handle, gltf, childIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadGltfNodes(mem, gltf)
|
||||
function loadGltfNodes(module, gltf)
|
||||
{
|
||||
const nodesHandle = mem.instance.exports.node_alloc(gltf.json.nodes.length);
|
||||
const nodesHandle = module.instance.exports.node_alloc(gltf.json.nodes.length);
|
||||
for (let nodeIndex of gltf.json.scenes[0].nodes) {
|
||||
loadGltfNode(mem, nodesHandle, gltf, nodeIndex);
|
||||
loadGltfNode(module, nodesHandle, gltf, nodeIndex);
|
||||
}
|
||||
return nodesHandle;
|
||||
}
|
||||
@ -37,10 +37,17 @@ function printMatrix(m, o)
|
||||
}
|
||||
|
||||
class GltfRenderer {
|
||||
constructor(device, canvasFormat, shaderModule, gltf)
|
||||
constructor(device, canvasFormat, shaderModule, gltf, texture)
|
||||
{
|
||||
this.gltf = gltf;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// textures
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
this.sampler = device.createSampler();
|
||||
this.texture = texture;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// buffer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -75,6 +82,14 @@ class GltfRenderer {
|
||||
binding: 1,
|
||||
visibility: GPUShaderStage.VERTEX,
|
||||
buffer: { type: "read-only-storage" }
|
||||
}, {
|
||||
binding: 2,
|
||||
visibility: GPUShaderStage.FRAGMENT,
|
||||
sampler: {}
|
||||
}, {
|
||||
binding: 3,
|
||||
visibility: GPUShaderStage.FRAGMENT,
|
||||
texture: {},
|
||||
}]
|
||||
}),
|
||||
];
|
||||
@ -162,6 +177,12 @@ class GltfRenderer {
|
||||
}, {
|
||||
binding: 1,
|
||||
resource: { buffer: this.nodeBuffer },
|
||||
}, {
|
||||
binding: 2,
|
||||
resource: this.sampler,
|
||||
}, {
|
||||
binding: 3,
|
||||
resource: this.texture,
|
||||
}]
|
||||
}),
|
||||
];
|
||||
@ -244,17 +265,102 @@ class GltfRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadGltf(device, canvasFormat, memory, mem)
|
||||
function memoryString(memory, offset)
|
||||
{
|
||||
const u8 = new Uint8Array(memory.buffer, offset);
|
||||
|
||||
const s = [];
|
||||
var i = 0;
|
||||
while (u8[i] != 0 && (i - offset) < 256) {
|
||||
s.push(u8[i]);
|
||||
i++;
|
||||
}
|
||||
return new TextDecoder().decode(new Uint8Array(s));
|
||||
}
|
||||
|
||||
function pngComponents(colorType)
|
||||
{
|
||||
if (colorType == 2)
|
||||
return 3;
|
||||
if (colorType == 6)
|
||||
return 4;
|
||||
throw new Error("non-implemented png color type");
|
||||
}
|
||||
|
||||
async function loadTextures(device, memory, module, gltf)
|
||||
{
|
||||
const tempTable = module.instance.exports.mem_alloc(256 * 4);
|
||||
const tempHeader = module.instance.exports.mem_alloc(7 * 4);
|
||||
|
||||
const tempInputSize = 8 * 1024 * 1024;
|
||||
const tempInput = module.instance.exports.mem_alloc(tempInputSize);
|
||||
|
||||
const tempOutputSize = 2048 * 2048 * 4;
|
||||
const tempOutput = module.instance.exports.mem_alloc(tempOutputSize);
|
||||
|
||||
const tempError = module.instance.exports.mem_alloc(4);
|
||||
|
||||
module.instance.exports.png_build_crc_table(tempTable);
|
||||
|
||||
const tempInputU8 = new Uint8Array(memory.buffer, tempInput);
|
||||
const tempOutputU8 = new Uint8Array(memory.buffer, tempOutput);
|
||||
const tempErrorU32 = new Uint32Array(memory.buffer, tempError);
|
||||
const tempHeaderU32 = new Uint32Array(memory.buffer, tempHeader);
|
||||
|
||||
const textures = [];
|
||||
for (let image of gltf.json.images) {
|
||||
console.log(image.uri);
|
||||
const imageResponse = await fetch(`gltf/${image.uri}`);
|
||||
const imageBuffer = await imageResponse.arrayBuffer();
|
||||
const imageBufferU8 = new Uint8Array(imageBuffer)
|
||||
|
||||
tempInputU8.set(imageBufferU8);
|
||||
const ret = module.instance.exports.png_decode(tempTable, tempInput, imageBuffer.byteLength,
|
||||
tempHeader,
|
||||
tempOutput, tempOutputSize,
|
||||
tempError);
|
||||
if (ret < 0) {
|
||||
console.log("png ret", ret, memoryString(memory, tempErrorU32[0]));
|
||||
throw new Error("png error");
|
||||
}
|
||||
|
||||
const width = tempHeaderU32[0];
|
||||
const height = tempHeaderU32[1];
|
||||
const bitDepth = tempHeaderU32[2];
|
||||
const colorType = tempHeaderU32[3];
|
||||
const components = pngComponents(colorType);
|
||||
console.log(components);
|
||||
|
||||
const texture = device.createTexture({
|
||||
size: [width, height],
|
||||
format: 'rgba8unorm',
|
||||
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
||||
});
|
||||
|
||||
device.queue.writeTexture({ texture: texture },
|
||||
tempOutputU8,
|
||||
{ bytesPerRow: width * components },
|
||||
{ width: width, height: height });
|
||||
|
||||
textures.push(texture);
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
|
||||
async function loadGltf(device, canvasFormat, memory, module)
|
||||
{
|
||||
const gltf = await splitGltf("gltf/lamp.gltf", "gltf/lamp.bin");
|
||||
const nodesHandle = loadGltfNodes(mem, gltf);
|
||||
const nodesHandle = loadGltfNodes(module, gltf);
|
||||
|
||||
/*
|
||||
const nodesM = new Float32Array(memory.buffer, nodesHandle);
|
||||
for (let i = 0; i < gltf.json.nodes.length; i++) {
|
||||
console.log("[", i, "]");
|
||||
printMatrix(nodesM, i * 16);
|
||||
}
|
||||
*/
|
||||
|
||||
const textures = await loadTextures(device, memory, module, gltf);
|
||||
|
||||
const code = await getPath("gltf.wgsl");
|
||||
const shaderModule = device.createShaderModule({
|
||||
@ -262,7 +368,7 @@ async function loadGltf(device, canvasFormat, memory, mem)
|
||||
code: await code,
|
||||
});
|
||||
|
||||
const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, nodesHandle);
|
||||
const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, textures[2]);
|
||||
console.log(renderer.nodeBuffer);
|
||||
device.queue.writeBuffer(renderer.nodeBuffer, 0,
|
||||
memory.buffer, nodesHandle, (4 * 4 * 4) * gltf.json.nodes.length);
|
||||
|
||||
71
memory.cpp
@ -1,71 +0,0 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "directxmath/directxmath.h"
|
||||
|
||||
//size_t __builtin_wasm_memory_grow(int, size_t);
|
||||
//size_t __builtin_wasm_memory_size(int);
|
||||
|
||||
extern char __heap_base[];
|
||||
extern char __heap_end[];
|
||||
|
||||
static size_t heap_pages = 0;
|
||||
static size_t alloc_index = 0;
|
||||
|
||||
extern "C" {
|
||||
size_t mem_size();
|
||||
size_t mem_alloc(size_t length);
|
||||
size_t node_alloc(int count);
|
||||
|
||||
void node_init_translation(size_t handle, int index, float x, float y, float z);
|
||||
};
|
||||
|
||||
static inline size_t memory_heap_base()
|
||||
{
|
||||
return (size_t)&__heap_base[0];
|
||||
}
|
||||
|
||||
static inline size_t align(size_t n, size_t m)
|
||||
{
|
||||
return (n + (m - 1)) & (~(m - 1));
|
||||
}
|
||||
|
||||
static inline void memory_grow(size_t npages)
|
||||
{
|
||||
__builtin_wasm_memory_grow(0, npages);
|
||||
}
|
||||
|
||||
size_t mem_size()
|
||||
{
|
||||
return __builtin_wasm_memory_size(0);
|
||||
}
|
||||
|
||||
size_t mem_alloc(size_t length)
|
||||
{
|
||||
size_t base = memory_heap_base();
|
||||
|
||||
size_t heap_end = (heap_pages << 16);
|
||||
|
||||
size_t address = alloc_index;
|
||||
|
||||
alloc_index += align(length, 16);
|
||||
|
||||
if (heap_end < alloc_index) {
|
||||
size_t npages = align(alloc_index - heap_end, 65536) >> 16;
|
||||
memory_grow(npages);
|
||||
heap_pages += npages;
|
||||
}
|
||||
return base + address;
|
||||
}
|
||||
|
||||
size_t node_alloc(int count)
|
||||
{
|
||||
return mem_alloc((sizeof (XMFLOAT4X4)) * count);
|
||||
}
|
||||
|
||||
void node_init_translation(size_t handle, int index, float x, float y, float z)
|
||||
{
|
||||
XMFLOAT4X4 * nodes = reinterpret_cast<XMFLOAT4X4 *>(handle);
|
||||
//XMMATRIX XMLoadFloat4x4(&nodes[index]);
|
||||
XMMATRIX mat = XMMatrixTranslation(x, y, z);
|
||||
XMStoreFloat4x4(&nodes[index], mat);
|
||||
}
|
||||
27
src/Makefile
@ -3,14 +3,16 @@ MINIZ = $(HOME)/miniz
|
||||
CFLAGS = \
|
||||
--target=wasm32 \
|
||||
-g \
|
||||
-O0 \
|
||||
-O3 \
|
||||
-flto \
|
||||
-nostdlib \
|
||||
-I$(MINIZ) \
|
||||
-I.. \
|
||||
-I. \
|
||||
-Werror \
|
||||
-Wfatal-errors
|
||||
-Wfatal-errors \
|
||||
-D_XM_NO_INTRINSICS_
|
||||
|
||||
# -flto \
|
||||
|
||||
MFLAGS = \
|
||||
-DMINIZ_NO_STDIO \
|
||||
@ -19,15 +21,18 @@ MFLAGS = \
|
||||
-DMINIZ_NO_ZLIB_APIS \
|
||||
-DMINIZ_NO_MALLOC
|
||||
|
||||
# -Wl,--lto-O1 \
|
||||
|
||||
LDFLAGS = \
|
||||
-Wl,--no-entry \
|
||||
-Wl,--export=build_crc_table \
|
||||
-Wl,--export=decode \
|
||||
-Wl,--export=mem_size \
|
||||
-Wl,--export=mem_alloc \
|
||||
-Wl,--export=node_alloc \
|
||||
-Wl,--export=node_init_translation \
|
||||
-Wl,--export=png_build_crc_table \
|
||||
-Wl,--export=png_decode \
|
||||
-Wl,--import-undefined \
|
||||
-Wl,--print-map \
|
||||
-Wl,--import-memory \
|
||||
-Wl,-z,stack-size=1048576
|
||||
-Wl,--lto-O3
|
||||
|
||||
%.o: %.c
|
||||
clang $(CFLAGS) $(MFLAGS) -o $@ -c $<
|
||||
@ -38,7 +43,9 @@ LDFLAGS = \
|
||||
PNG_OBJ = \
|
||||
png.o \
|
||||
stdlib.o \
|
||||
$(MINIZ)/miniz_tinfl.o
|
||||
$(MINIZ)/miniz_tinfl.o \
|
||||
memory.o \
|
||||
node.o
|
||||
|
||||
png.wasm: $(PNG_OBJ)
|
||||
module.wasm: $(PNG_OBJ)
|
||||
clang++ $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
14
src/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WebGPU</title>
|
||||
<style>
|
||||
</style>
|
||||
<script src="index.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas width="256" height="256"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
124
src/index.js
Normal file
@ -0,0 +1,124 @@
|
||||
const canvas = document.querySelector("canvas");
|
||||
canvas.width = 480;
|
||||
canvas.height = 480;
|
||||
|
||||
const context = canvas.getContext("2d");
|
||||
const imageData = context.createImageData(canvas.width, canvas.height);
|
||||
|
||||
const cstride = canvas.width * 4;
|
||||
|
||||
for (let y = 0; y < canvas.height; y++) {
|
||||
for (let x = 0; x < canvas.width; x++) {
|
||||
imageData.data[y * cstride + x * 4 + 0] = x;
|
||||
imageData.data[y * cstride + x * 4 + 1] = y;
|
||||
imageData.data[y * cstride + x * 4 + 2] = 0;
|
||||
imageData.data[y * cstride + x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
context.putImageData(imageData, 0, 0);
|
||||
|
||||
const memoryBlocks = 129 + 128 * 10;
|
||||
const memorySize = memoryBlocks * (64 * 1024);
|
||||
const memory = new WebAssembly.Memory({ initial: memoryBlocks });
|
||||
const memoryU8 = new Uint8Array(memory.buffer);
|
||||
|
||||
function round(n, m)
|
||||
{
|
||||
return (n + (m - 1)) & ~(m - 1);
|
||||
}
|
||||
|
||||
class Allocator {
|
||||
constructor(size) {
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
alloc(size) {
|
||||
const address = this.offset;
|
||||
this.offset += round(size, 32);
|
||||
if (this.offset > this.size) {
|
||||
throw new Error(`allocator overflow: ${this.offset} > ${this.size}`);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
function memoryString(mem, offset)
|
||||
{
|
||||
const s = [];
|
||||
var i = offset;
|
||||
while (mem[i] != 0 && (i - offset) < 256) {
|
||||
s.push(mem[i]);
|
||||
i++;
|
||||
}
|
||||
return new TextDecoder().decode(new Uint8Array(s));
|
||||
}
|
||||
|
||||
const m = new Allocator(memorySize);
|
||||
m.offset = (129 + 64) * 64 * 1024;
|
||||
const crcTableA = m.alloc(256 * 4);
|
||||
|
||||
const png = await WebAssembly.instantiateStreaming(fetch("png.wasm"), {
|
||||
env: { memory: memory }
|
||||
});
|
||||
|
||||
/*
|
||||
const test = await WebAssembly.instantiateStreaming(fetch("test.wasm"), {
|
||||
env: { memory: memory }
|
||||
});
|
||||
const res = test.instance.exports.test();
|
||||
console.log("res", res);
|
||||
console.log(memoryString(memoryU8, res));
|
||||
*/
|
||||
|
||||
png.instance.exports.build_crc_table(crcTableA);
|
||||
/*
|
||||
const crcTable = new Uint32Array(memory.buffer, crcTableA);
|
||||
for (let i = 0; i < 256; i++) {
|
||||
console.log(crcTable[i].toString(16).padStart(8, '0'));
|
||||
}
|
||||
*/
|
||||
|
||||
const pngResponse = await fetch("../gltf/Image_0.png");
|
||||
const pngBuffer = await pngResponse.arrayBuffer();
|
||||
console.log(pngBuffer.byteLength);
|
||||
|
||||
const pngA = m.alloc(pngBuffer.byteLength);
|
||||
const pngBufferU8 = new Uint8Array(pngBuffer);
|
||||
memoryU8.set(pngBufferU8, pngA);
|
||||
console.log("a0", memoryU8[pngA], pngBufferU8[0]);
|
||||
|
||||
const headerA = m.alloc(7 * 4);
|
||||
|
||||
const obufSize = canvas.width * canvas.height * 3;
|
||||
const obufA = m.alloc(obufSize);
|
||||
console.log("obufA", obufA, obufSize);
|
||||
|
||||
const errorA = m.alloc(4);
|
||||
|
||||
const ret = png.instance.exports.decode(crcTableA, pngA, pngBuffer.byteLength,
|
||||
headerA,
|
||||
obufA, obufSize,
|
||||
errorA);
|
||||
if (ret < 0) {
|
||||
const address = new Uint32Array(memory.buffer, errorA);
|
||||
console.log("error3", ret, crcTableA, address[0], memoryString(memoryU8, address[0]));
|
||||
//for (let i = 0; i < 256; i++) {
|
||||
//console.log(memoryU8[(-ret) + i]);
|
||||
//}
|
||||
}
|
||||
console.log(ret);
|
||||
if (ret >= 0) {
|
||||
console.log("ret", ret);
|
||||
const pstride = canvas.width * 3;
|
||||
|
||||
for (let y = 0; y < canvas.height; y++) {
|
||||
for (let x = 0; x < canvas.width; x++) {
|
||||
imageData.data[y * cstride + x * 4 + 0] = memoryU8[obufA + pstride * y + x * 3 + 0];
|
||||
imageData.data[y * cstride + x * 4 + 1] = memoryU8[obufA + pstride * y + x * 3 + 1];
|
||||
imageData.data[y * cstride + x * 4 + 2] = memoryU8[obufA + pstride * y + x * 3 + 2];
|
||||
imageData.data[y * cstride + x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
context.putImageData(imageData, 0, 0);
|
||||
}
|
||||
47
src/memory.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
extern char __heap_base[];
|
||||
extern char __heap_end[];
|
||||
|
||||
static size_t heap_pages = 0;
|
||||
static size_t alloc_index = 0;
|
||||
|
||||
static inline size_t memory_heap_base()
|
||||
{
|
||||
return (size_t)&__heap_end[0];
|
||||
}
|
||||
|
||||
static inline size_t align(size_t n, size_t m)
|
||||
{
|
||||
return (n + (m - 1)) & (~(m - 1));
|
||||
}
|
||||
|
||||
static inline void memory_grow(size_t npages)
|
||||
{
|
||||
__builtin_wasm_memory_grow(0, npages);
|
||||
}
|
||||
|
||||
size_t mem_size()
|
||||
{
|
||||
return __builtin_wasm_memory_size(0);
|
||||
}
|
||||
|
||||
size_t mem_alloc(size_t length)
|
||||
{
|
||||
size_t base = memory_heap_base();
|
||||
|
||||
size_t heap_end = (heap_pages << 16);
|
||||
|
||||
alloc_index = align(alloc_index, 16);
|
||||
size_t address = alloc_index;
|
||||
alloc_index += length;
|
||||
|
||||
if (heap_end < alloc_index) {
|
||||
size_t npages = align(alloc_index - heap_end, 65536) >> 16;
|
||||
memory_grow(npages);
|
||||
heap_pages += npages;
|
||||
}
|
||||
return base + address;
|
||||
}
|
||||
6
src/memory.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
size_t mem_size();
|
||||
size_t mem_alloc(size_t length);
|
||||
};
|
||||
19
src/node.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "node.h"
|
||||
|
||||
#include "directxmath/directxmath.h"
|
||||
|
||||
size_t node_alloc(int count)
|
||||
{
|
||||
return mem_alloc((sizeof (XMFLOAT4X4)) * count);
|
||||
}
|
||||
|
||||
void node_init_translation(size_t handle, int index, float x, float y, float z)
|
||||
{
|
||||
XMFLOAT4X4 * nodes = reinterpret_cast<XMFLOAT4X4 *>(handle);
|
||||
//XMMATRIX XMLoadFloat4x4(&nodes[index]);
|
||||
XMMATRIX mat = XMMatrixTranslation(x, y, z);
|
||||
XMStoreFloat4x4(&nodes[index], mat);
|
||||
}
|
||||
6
src/node.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
size_t node_alloc(int count);
|
||||
void node_init_translation(size_t handle, int index, float x, float y, float z);
|
||||
};
|
||||
24
src/png.cpp
@ -9,6 +9,7 @@
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "png.h"
|
||||
#include "miniz_tinfl.h"
|
||||
|
||||
struct CT {
|
||||
@ -33,7 +34,7 @@ struct Header {
|
||||
int interlace_method;
|
||||
};
|
||||
|
||||
#define IBUF_SIZE ((1024 + 1) * 1024 * 4)
|
||||
#define IBUF_SIZE ((2048 + 1) * 2048 * 4)
|
||||
|
||||
struct png_state {
|
||||
tinfl_decompressor decomp;
|
||||
@ -45,9 +46,7 @@ struct png_state {
|
||||
|
||||
static png_state _png_state;
|
||||
|
||||
extern "C" void build_crc_table(uint32_t * crc_table);
|
||||
|
||||
void build_crc_table(uint32_t * crc_table)
|
||||
void png_build_crc_table(uint32_t * crc_table)
|
||||
{
|
||||
for (uint32_t i = 0; i < 256; i++) {
|
||||
uint32_t c = i;
|
||||
@ -269,8 +268,8 @@ static int decode_chunk(uint32_t const * crc_table, uint8_t const * mem, int & o
|
||||
offset += length;
|
||||
uint32_t e_crc = decode_int32be(mem, offset);
|
||||
if (e_crc != a_crc) {
|
||||
state->error = "chunk crc mismatch";
|
||||
return -5;
|
||||
state->error = "chunk crc mismatch2";
|
||||
return -offset;
|
||||
}
|
||||
offset += 4;
|
||||
|
||||
@ -285,12 +284,7 @@ static int decode_chunk(uint32_t const * crc_table, uint8_t const * mem, int & o
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int decode(uint32_t const * crc_table, uint8_t const * mem, int length,
|
||||
Header * header,
|
||||
uint8_t * obuf, int osize,
|
||||
char const ** error);
|
||||
|
||||
int decode(uint32_t const * crc_table, uint8_t const * mem, int length,
|
||||
int png_decode(uint32_t const * crc_table, uint8_t const * mem, int length,
|
||||
Header * header,
|
||||
uint8_t * obuf, int osize,
|
||||
char const ** error)
|
||||
@ -376,18 +370,18 @@ int main(int argc, char const ** argv)
|
||||
void * ibuf = read_file(argv[1], &isize);
|
||||
|
||||
uint32_t crc_table[256];
|
||||
build_crc_table(crc_table);
|
||||
png_build_crc_table(crc_table);
|
||||
|
||||
uint8_t mem[] = {0x49, 0x45, 0x4E, 0x44};
|
||||
uint32_t crc = calculate_crc(crc_table, mem, 0, 4);
|
||||
assert(crc == 0xae426082);
|
||||
|
||||
int osize = 8 * 1024 * 1024;
|
||||
int osize = 8 * 2048 * 2048;
|
||||
void * obuf = malloc(osize);
|
||||
|
||||
Header header{};
|
||||
char const * error;
|
||||
int ret = decode(crc_table,
|
||||
int ret = png_decode(crc_table,
|
||||
reinterpret_cast<uint8_t *>(ibuf), isize,
|
||||
&header,
|
||||
reinterpret_cast<uint8_t *>(obuf), osize,
|
||||
|
||||