cub
This commit is contained in:
@@ -1,52 +0,0 @@
|
|||||||
use std::{
|
|
||||||
env, fs,
|
|
||||||
fs::File,
|
|
||||||
io,
|
|
||||||
io::{BufRead, BufReader},
|
|
||||||
path::Path,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
|
||||||
println!("cargo:rerun-if-changed=src/instructionset.glsl");
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
||||||
let dest_path = Path::new(&out_dir).join("instructionset.rs");
|
|
||||||
let f = File::open("src/instructionset.glsl")?;
|
|
||||||
let f = BufReader::new(f);
|
|
||||||
let mut out = "
|
|
||||||
#[repr(u8)]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub(crate) enum InstructionSet{
|
|
||||||
|
|
||||||
"
|
|
||||||
.to_owned();
|
|
||||||
|
|
||||||
for l in f.lines() {
|
|
||||||
let line = l?;
|
|
||||||
if line.starts_with("#") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let entries = line.split("//").map(str::trim).collect::<Vec<&str>>();
|
|
||||||
if entries[0].is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let before_equals = entries[0]
|
|
||||||
.split("=uint8_t")
|
|
||||||
.map(str::trim)
|
|
||||||
.collect::<Vec<&str>>();
|
|
||||||
let name = &before_equals[0][14..];
|
|
||||||
let value = &before_equals[1][..before_equals[1].len() - 1];
|
|
||||||
let comment = entries[1];
|
|
||||||
|
|
||||||
out += &format!(
|
|
||||||
"#[allow(non_snake_case)]\n#[allow(dead_code)]\n/// {comment}\n{name}={value},\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
out += "}";
|
|
||||||
|
|
||||||
fs::write(dest_path, out).unwrap();
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
nightly
|
||||||
-174
@@ -1,174 +0,0 @@
|
|||||||
// global fragment shader
|
|
||||||
|
|
||||||
#version 460
|
|
||||||
#extension GL_EXT_mesh_shader:require
|
|
||||||
#extension GL_GOOGLE_include_directive:require
|
|
||||||
#define DescriptionIndex gl_PrimitiveID>>11
|
|
||||||
#include "include.glsl"
|
|
||||||
|
|
||||||
#ifdef implicit
|
|
||||||
|
|
||||||
layout(location = 0) in VertexInput
|
|
||||||
{
|
|
||||||
vec4 position;
|
|
||||||
} vertexInput;
|
|
||||||
|
|
||||||
layout(depth_greater) out float gl_FragDepth;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 tri_normal;
|
|
||||||
layout(location = 1) in vec4 tri_pos;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 f_color;
|
|
||||||
|
|
||||||
/// SHARED CODE ///
|
|
||||||
vec3 shading(vec3 normal, vec4 position)
|
|
||||||
{
|
|
||||||
vec3 accum = vec3(0., 0., 0.);
|
|
||||||
mat3 rotation = mat3(pc.world[0].xyz, pc.world[1].xyz, pc.world[2].xyz);
|
|
||||||
//vec3 position=pc.world[3].xyz;
|
|
||||||
|
|
||||||
for (int i = 0; (i < light_uniforms.light_count) && (i < 32); i++)
|
|
||||||
{
|
|
||||||
accum += light_uniforms.col[i].xyz * ((dot(normalize(rotation * normal), normalize(light_uniforms.pos[i].xyz - position.xyz)) * .5) + .5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return accum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// IMPLICIT CODE ///
|
|
||||||
#ifdef implicit
|
|
||||||
|
|
||||||
//#define debug 1
|
|
||||||
|
|
||||||
#ifdef debug
|
|
||||||
const float EPSILON = .0001;
|
|
||||||
const uint MAX_STEPS = 1;
|
|
||||||
#define NEARPLANE 0.
|
|
||||||
#define FARPLANE length(vec3(10))
|
|
||||||
#define gl_GlobalInvocationID uvec3(1)
|
|
||||||
#else
|
|
||||||
const float EPSILON = .0001;
|
|
||||||
const uint MAX_STEPS = 50;
|
|
||||||
#define NEARPLANE 0.
|
|
||||||
float FARPLANE;
|
|
||||||
#define gl_GlobalInvocationID uvec3(1)
|
|
||||||
#endif
|
|
||||||
#define interval_frags
|
|
||||||
#include "interpreter.glsl"
|
|
||||||
|
|
||||||
#ifdef debug
|
|
||||||
vec3 getNormal(vec3 p, float dens) {
|
|
||||||
vec3 n;
|
|
||||||
n.x = scene(vec3(p.x + EPSILON, p.y, p.z), false).x;
|
|
||||||
n.y = scene(vec3(p.x, p.y + EPSILON, p.z), false).x;
|
|
||||||
n.z = scene(vec3(p.x, p.y, p.z + EPSILON), false).x;
|
|
||||||
return normalize(n - (scene(p, false).x));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 spheretracing(vec3 ori, vec3 dir, out vec3 p) {
|
|
||||||
vec2 td = vec2(NEARPLANE, 1.);
|
|
||||||
p = ori;
|
|
||||||
td.y = scene(p, false).x;
|
|
||||||
td.x += (td.y) * .9;
|
|
||||||
p = ori + dir * td.x;
|
|
||||||
for (int i = 0; i < MAX_STEPS && td.y > EPSILON && td.x < FARPLANE; i++) {
|
|
||||||
td.y = scene(p, false).x;
|
|
||||||
td.x += (td.y) * .9;
|
|
||||||
p = ori + dir * td.x;
|
|
||||||
}
|
|
||||||
return td;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
vec3 getNormal(vec3 p, float dens) {
|
|
||||||
vec3 n;
|
|
||||||
n.x = scene(vec3(p.x + EPSILON, p.y, p.z), false).x;
|
|
||||||
n.y = scene(vec3(p.x, p.y + EPSILON, p.z), false).x;
|
|
||||||
n.z = scene(vec3(p.x, p.y, p.z + EPSILON), false).x;
|
|
||||||
return normalize(n - (scene(p, false)));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 spheretracing(vec3 ori, vec3 dir, out vec3 p) {
|
|
||||||
vec2 td = vec2(NEARPLANE, 1.);
|
|
||||||
p = ori;
|
|
||||||
td.y = scene(p, false).x * .9;
|
|
||||||
td.x += td.y;
|
|
||||||
p = ori + dir * td.x;
|
|
||||||
for (int i = 0; i < MAX_STEPS && td.y > EPSILON && td.x < FARPLANE; i++) {
|
|
||||||
td.y = scene(p, false).x * .9;
|
|
||||||
td.x += td.y;
|
|
||||||
p = ori + dir * td.x;
|
|
||||||
}
|
|
||||||
return td;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Implicit Surface Entrypoint
|
|
||||||
void main() {
|
|
||||||
//default_mask();
|
|
||||||
if (BRUTE_FORCE)
|
|
||||||
{
|
|
||||||
default_mask();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mask = fragmentpassmasks.masks[gl_PrimitiveID];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef debug
|
|
||||||
desc = scene_description.desc[(DescriptionIndex) + 1];
|
|
||||||
vec3 bottomleft = vec3(desc.bounds[3], desc.bounds[4], desc.bounds[5]);
|
|
||||||
vec3 topright = vec3(desc.bounds[0], desc.bounds[1], desc.bounds[2]);
|
|
||||||
if (BRUTE_FORCE)
|
|
||||||
{
|
|
||||||
FARPLANE = length((topright - bottomleft));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
FARPLANE = length((topright - bottomleft) * vec3(0.25 * 0.25, 0.25 * 0.25, 0.25 * 0.5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec3 raypos = vertexInput.position.xyz;
|
|
||||||
vec3 p;
|
|
||||||
vec3 raydir = normalize(raypos - (inverse(pc.world) * vec4(camera_uniforms.campos, 1)).xyz);
|
|
||||||
|
|
||||||
//f_color=vec4(raydir,1.);
|
|
||||||
|
|
||||||
if (BOUNDING_BOXES) {
|
|
||||||
f_color = vertexInput.position;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef debug
|
|
||||||
f_color = vec4(scene(raypos, false), 1);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec2 td = spheretracing(raypos, raydir, p);
|
|
||||||
|
|
||||||
if (td.y < EPSILON)
|
|
||||||
{
|
|
||||||
vec3 n = getNormal(p, td.y);
|
|
||||||
//f_color=vec4(1.);
|
|
||||||
f_color = vec4(shading(n, inverse(pc.world) * vec4(p, 1.)), 1.);
|
|
||||||
|
|
||||||
vec4 tpoint = camera_uniforms.proj * camera_uniforms.view * pc.world * vec4(p, 1);
|
|
||||||
gl_FragDepth = (tpoint.z / tpoint.w);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
/// TRIANGLE CODE ///
|
|
||||||
|
|
||||||
//Mesh Surface Entrypoint
|
|
||||||
void main() {
|
|
||||||
f_color = vec4(shading(tri_normal, tri_pos), 1.);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#version 460
|
|
||||||
|
|
||||||
uint DescriptionIndex;
|
|
||||||
|
|
||||||
//#include "include.glsl"
|
|
||||||
//#include "intervals.glsl"
|
|
||||||
#include "interpreter.glsl"
|
|
||||||
struct Results {
|
|
||||||
uint code;
|
|
||||||
uint stat;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(set = 1, binding = 30, std430) buffer ResultsArray {
|
|
||||||
Results r[];
|
|
||||||
} results;
|
|
||||||
|
|
||||||
layout(local_size_x = 500, local_size_y = 1, local_size_z = 1) in;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
DescriptionIndex = 0;
|
|
||||||
default_mask();
|
|
||||||
|
|
||||||
program_counter = gl_LocalInvocationID.x;
|
|
||||||
|
|
||||||
desc = scene_description.desc[(DescriptionIndex) + 1];
|
|
||||||
|
|
||||||
results.r[program_counter].code = next_opcode();
|
|
||||||
//results.r[program_counter].stat = STATIC_OPCODE_ARRAY[program_counter];
|
|
||||||
}
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
// Implicit Mesh shader
|
|
||||||
|
|
||||||
#version 460
|
|
||||||
#extension GL_EXT_mesh_shader:require
|
|
||||||
|
|
||||||
uint DescriptionIndex;
|
|
||||||
|
|
||||||
#include "include.glsl"
|
|
||||||
#include "intervals.glsl"
|
|
||||||
|
|
||||||
layout(local_size_x=32,local_size_y=1,local_size_z=1)in;
|
|
||||||
layout(triangles,max_vertices=256,max_primitives=192)out;
|
|
||||||
|
|
||||||
layout(location=0)out VertexOutput
|
|
||||||
{
|
|
||||||
vec4 position;
|
|
||||||
}vertexOutput[];
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
//clear_stacks();
|
|
||||||
//default_mask();
|
|
||||||
|
|
||||||
mat4 mvp=camera_uniforms.proj*camera_uniforms.view*pc.world;
|
|
||||||
uint vindex = gl_LocalInvocationID.x*8;
|
|
||||||
uint pindex = gl_LocalInvocationID.x*6;
|
|
||||||
|
|
||||||
if (BRUTE_FORCE)
|
|
||||||
{
|
|
||||||
SetMeshOutputsEXT(8,6);
|
|
||||||
float[6]bounds=scene_description.desc[gl_WorkGroupID.x+1].bounds;
|
|
||||||
vec3 bottomleft = vec3(bounds[3],bounds[4],bounds[5]);
|
|
||||||
vec3 topright = vec3(bounds[0],bounds[1],bounds[2]);
|
|
||||||
|
|
||||||
vec4[8]positions={
|
|
||||||
vec4(bottomleft,1.),
|
|
||||||
vec4(bottomleft.x,bottomleft.y,topright.z,1.),
|
|
||||||
vec4(bottomleft.x,topright.y,bottomleft.z,1.),
|
|
||||||
vec4(bottomleft.x,topright.y,topright.z,1.),
|
|
||||||
vec4(topright.x,bottomleft.y,bottomleft.z,1.),
|
|
||||||
vec4(topright.x,bottomleft.y,topright.z,1.),
|
|
||||||
vec4(topright.x,topright.y,bottomleft.z,1.),
|
|
||||||
vec4(topright,1.),
|
|
||||||
};
|
|
||||||
|
|
||||||
bvec3 signingvec=greaterThan((inverse(pc.world)*vec4(camera_uniforms.campos,1)).xyz,(topright+bottomleft)/2);
|
|
||||||
|
|
||||||
gl_MeshVerticesEXT[0].gl_Position=mvp*(positions[0]);
|
|
||||||
gl_MeshVerticesEXT[1].gl_Position=mvp*(positions[1]);
|
|
||||||
gl_MeshVerticesEXT[2].gl_Position=mvp*(positions[2]);
|
|
||||||
gl_MeshVerticesEXT[3].gl_Position=mvp*(positions[3]);
|
|
||||||
gl_MeshVerticesEXT[4].gl_Position=mvp*(positions[4]);
|
|
||||||
gl_MeshVerticesEXT[5].gl_Position=mvp*(positions[5]);
|
|
||||||
gl_MeshVerticesEXT[6].gl_Position=mvp*(positions[6]);
|
|
||||||
gl_MeshVerticesEXT[7].gl_Position=mvp*(positions[7]);
|
|
||||||
vertexOutput[0].position=(positions[0]);
|
|
||||||
vertexOutput[1].position=(positions[1]);
|
|
||||||
vertexOutput[2].position=(positions[2]);
|
|
||||||
vertexOutput[3].position=(positions[3]);
|
|
||||||
vertexOutput[4].position=(positions[4]);
|
|
||||||
vertexOutput[5].position=(positions[5]);
|
|
||||||
vertexOutput[6].position=(positions[6]);
|
|
||||||
vertexOutput[7].position=(positions[7]);
|
|
||||||
|
|
||||||
if(signingvec.x){
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[0]=uvec3(4,5,6);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[1]=uvec3(5,6,7);
|
|
||||||
}else{
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[0]=uvec3(0,1,2);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[1]=uvec3(1,2,3);
|
|
||||||
}
|
|
||||||
if(signingvec.y){
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[2]=uvec3(2,3,6);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[3]=uvec3(7,3,6);
|
|
||||||
}else{
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[2]=uvec3(0,1,4);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[3]=uvec3(5,1,4);
|
|
||||||
}
|
|
||||||
if(signingvec.z){
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[4]=uvec3(1,3,5);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[5]=uvec3(3,5,7);
|
|
||||||
}else{
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[4]=uvec3(0,2,4);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[5]=uvec3(2,4,6);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This can be optimised
|
|
||||||
SetMeshOutputsEXT(256,192);
|
|
||||||
|
|
||||||
vec3 bottomleft = meshmasks.bottomleft;
|
|
||||||
vec3 topright = meshmasks.topright;
|
|
||||||
vec3 center = (topright + bottomleft) / 2.;
|
|
||||||
|
|
||||||
vec4[8]positions={
|
|
||||||
vec4(bottomleft,1.),
|
|
||||||
vec4(bottomleft.x,bottomleft.y,topright.z,1.),
|
|
||||||
vec4(bottomleft.x,topright.y,bottomleft.z,1.),
|
|
||||||
vec4(bottomleft.x,topright.y,topright.z,1.),
|
|
||||||
vec4(topright.x,bottomleft.y,bottomleft.z,1.),
|
|
||||||
vec4(topright.x,bottomleft.y,topright.z,1.),
|
|
||||||
vec4(topright.x,topright.y,bottomleft.z,1.),
|
|
||||||
vec4(topright,1.),
|
|
||||||
};
|
|
||||||
|
|
||||||
uint localindex = uint(meshmasks.enabled[gl_WorkGroupID.x]);
|
|
||||||
DescriptionIndex = meshmasks.globalindex/2;
|
|
||||||
|
|
||||||
mask = meshmasks.masks[gl_WorkGroupID.x];
|
|
||||||
|
|
||||||
int GlobalInvocationIndex = int((meshmasks.globalindex*32+localindex)*32+gl_LocalInvocationID.x);
|
|
||||||
|
|
||||||
//adjust scale and position
|
|
||||||
if (!DISABLE_MESHSCALING1) {
|
|
||||||
for (int i = 0; i<8; i++)
|
|
||||||
{
|
|
||||||
positions[i] *= vec4(0.25,0.25,0.5,1.);
|
|
||||||
positions[i].x += (topright.x-bottomleft.x)*0.25 * (mod(localindex,4.)-1.5) + (topright.x+bottomleft.x)*0.375;
|
|
||||||
positions[i].y += (topright.y-bottomleft.y)*0.25 * (mod(floor(localindex/4.),4.)-1.5) + (topright.y+bottomleft.y)*0.375;
|
|
||||||
positions[i].z += ((topright.z-bottomleft.z)*0.5 * (floor(localindex/16.)-0.5) + (topright.z+bottomleft.z)*0.25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 localtopright=positions[0];
|
|
||||||
vec4 localbottomleft=positions[7];
|
|
||||||
|
|
||||||
if (!DISABLE_MESHSCALING2) {
|
|
||||||
for (int i = 0; i<8; i++)
|
|
||||||
{
|
|
||||||
positions[i] *= vec4(0.25,0.25,0.5,1.);
|
|
||||||
positions[i].x += (localtopright.x-localbottomleft.x)*(0.25) * (mod(gl_LocalInvocationID.x,4.)-1.5) + (localtopright.x+localbottomleft.x)*0.375;
|
|
||||||
positions[i].y += (localtopright.y-localbottomleft.y)*(0.25) * (mod(floor(gl_LocalInvocationID.x/4.),4.)-1.5) + (localtopright.y+localbottomleft.y)*0.375;
|
|
||||||
positions[i].z += (localtopright.z-localbottomleft.z)*(0.5) * (floor(gl_LocalInvocationID.x/16.)-0.5) + (localtopright.z+localbottomleft.z)*0.25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec3 signingvec=greaterThan((inverse(pc.world)*vec4(camera_uniforms.campos,1)).xyz,(positions[0].xyz+positions[7].xyz)/2);
|
|
||||||
|
|
||||||
gl_MeshPrimitivesEXT[pindex+0].gl_PrimitiveID=GlobalInvocationIndex;
|
|
||||||
gl_MeshPrimitivesEXT[pindex+1].gl_PrimitiveID=GlobalInvocationIndex;
|
|
||||||
gl_MeshPrimitivesEXT[pindex+2].gl_PrimitiveID=GlobalInvocationIndex;
|
|
||||||
gl_MeshPrimitivesEXT[pindex+3].gl_PrimitiveID=GlobalInvocationIndex;
|
|
||||||
gl_MeshPrimitivesEXT[pindex+4].gl_PrimitiveID=GlobalInvocationIndex;
|
|
||||||
gl_MeshPrimitivesEXT[pindex+5].gl_PrimitiveID=GlobalInvocationIndex;
|
|
||||||
|
|
||||||
bool triangle_fine;
|
|
||||||
if (!DISABLE_MESHCULL) {
|
|
||||||
float[2] check = scene(vec3[2](vec3(positions[0].xyz),vec3(positions[7].xyz)), true);
|
|
||||||
triangle_fine = (check[0] <= 0) && (check[1] >= 0);
|
|
||||||
} else {
|
|
||||||
triangle_fine = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (triangle_fine)
|
|
||||||
{
|
|
||||||
fragmentpassmasks.masks[GlobalInvocationIndex]=mask;
|
|
||||||
|
|
||||||
gl_MeshVerticesEXT[vindex+0].gl_Position=mvp*(positions[0]);
|
|
||||||
gl_MeshVerticesEXT[vindex+1].gl_Position=mvp*(positions[1]);
|
|
||||||
gl_MeshVerticesEXT[vindex+2].gl_Position=mvp*(positions[2]);
|
|
||||||
gl_MeshVerticesEXT[vindex+3].gl_Position=mvp*(positions[3]);
|
|
||||||
gl_MeshVerticesEXT[vindex+4].gl_Position=mvp*(positions[4]);
|
|
||||||
gl_MeshVerticesEXT[vindex+5].gl_Position=mvp*(positions[5]);
|
|
||||||
gl_MeshVerticesEXT[vindex+6].gl_Position=mvp*(positions[6]);
|
|
||||||
gl_MeshVerticesEXT[vindex+7].gl_Position=mvp*(positions[7]);
|
|
||||||
vertexOutput[vindex+0].position=(positions[0]);
|
|
||||||
vertexOutput[vindex+1].position=(positions[1]);
|
|
||||||
vertexOutput[vindex+2].position=(positions[2]);
|
|
||||||
vertexOutput[vindex+3].position=(positions[3]);
|
|
||||||
vertexOutput[vindex+4].position=(positions[4]);
|
|
||||||
vertexOutput[vindex+5].position=(positions[5]);
|
|
||||||
vertexOutput[vindex+6].position=(positions[6]);
|
|
||||||
vertexOutput[vindex+7].position=(positions[7]);
|
|
||||||
|
|
||||||
if(signingvec.x){
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(4,5,6)+uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(5,6,7)+uvec3(vindex);
|
|
||||||
}else{
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(0,1,2)+uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(1,2,3)+uvec3(vindex);
|
|
||||||
}
|
|
||||||
if(signingvec.y){
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(2,3,6)+uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(7,3,6)+uvec3(vindex);
|
|
||||||
}else{
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(0,1,4)+uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(5,1,4)+uvec3(vindex);
|
|
||||||
}
|
|
||||||
if(signingvec.z){
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(1,3,5)+uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(3,5,7)+uvec3(vindex);
|
|
||||||
}else{
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(0,2,4)+uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(2,4,6)+uvec3(vindex);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
gl_MeshVerticesEXT[vindex+0].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+1].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+2].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+3].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+4].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+5].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+6].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
gl_MeshVerticesEXT[vindex+7].gl_Position=mvp*(vec4(0,0,0,1));
|
|
||||||
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(vindex);
|
|
||||||
gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(vindex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
// Implicit Mesh shader
|
|
||||||
|
|
||||||
#version 460
|
|
||||||
#extension GL_EXT_mesh_shader:require
|
|
||||||
|
|
||||||
#define DescriptionIndex gl_WorkGroupID.x
|
|
||||||
|
|
||||||
#include "include.glsl"
|
|
||||||
#include "intervals.glsl"
|
|
||||||
|
|
||||||
layout(local_size_x=32,local_size_y=1,local_size_z=1)in;
|
|
||||||
|
|
||||||
shared uint index;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
//clear_stacks();
|
|
||||||
default_mask();
|
|
||||||
meshmasks.masks[gl_LocalInvocationID.x] = mask;
|
|
||||||
|
|
||||||
if (gl_LocalInvocationID.x==0)
|
|
||||||
{
|
|
||||||
index=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float[6]bounds=scene_description.desc[gl_WorkGroupID.x+1].bounds;
|
|
||||||
|
|
||||||
vec3 bottomleft = vec3(bounds[3],bounds[4],bounds[5]);
|
|
||||||
vec3 topright = vec3(bounds[0],bounds[1],bounds[2]);
|
|
||||||
|
|
||||||
#define adjust(var) \
|
|
||||||
var *= vec3(0.25,0.25,0.25);\
|
|
||||||
var.x += ((bounds[0]-bounds[3]) * 0.25 * (mod(gl_LocalInvocationID.x,4.)-1.5)) + ((bounds[0]+bounds[3])*0.375) ;\
|
|
||||||
var.y += ((bounds[1]-bounds[4]) * 0.25 * (mod(floor(gl_LocalInvocationID.x/4.),4.)-1.5)) + ((bounds[1]+bounds[4])*0.375) ;\
|
|
||||||
var.z += ((bounds[2]-bounds[5]) * 0.25 * (floor(gl_LocalInvocationID.x/16.)-1.5+gl_WorkGroupID.z*2.)) + ((bounds[2]+bounds[5])*0.375) ;\
|
|
||||||
|
|
||||||
adjust(bottomleft);
|
|
||||||
adjust(topright);
|
|
||||||
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
bool triangle_fine;
|
|
||||||
if (!DISABLE_TASKCULL) {
|
|
||||||
float[2] check = scene(vec3[2](bottomleft,topright), true);
|
|
||||||
triangle_fine = (check[0] <= 0) && (check[1] >= 0);
|
|
||||||
} else {
|
|
||||||
triangle_fine = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (triangle_fine)
|
|
||||||
{
|
|
||||||
uint localindex = atomicAdd(index, 1);
|
|
||||||
meshmasks.masks[localindex]=mask;
|
|
||||||
meshmasks.enabled[localindex]=uint8_t(gl_LocalInvocationID.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gl_LocalInvocationID.x==0)
|
|
||||||
{
|
|
||||||
meshmasks.bottomleft = vec3(bounds[3],bounds[4],(bounds[5]*0.5) + ((bounds[2]-bounds[5])*0.5 * (-0.5+gl_WorkGroupID.z)) + ((bounds[2]+bounds[5])*0.25));
|
|
||||||
meshmasks.topright = vec3(bounds[0],bounds[1],(bounds[2]*0.5) + ((bounds[2]-bounds[5])*0.5 * (-0.5+gl_WorkGroupID.z)) + ((bounds[2]+bounds[5])*0.25));
|
|
||||||
meshmasks.globalindex = gl_WorkGroupID.x*2+gl_WorkGroupID.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
barrier();
|
|
||||||
if (gl_LocalInvocationID.x==0)
|
|
||||||
{
|
|
||||||
EmitMeshTasksEXT(index,1,1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,14 +2,11 @@
|
|||||||
#include "include.glsl"
|
#include "include.glsl"
|
||||||
|
|
||||||
layout(location=0)in vec3 position;
|
layout(location=0)in vec3 position;
|
||||||
layout(location=1)in vec3 normal;
|
|
||||||
|
|
||||||
layout(location=0)out vec3 v_normal;
|
|
||||||
layout(location=1)out vec4 pos;
|
layout(location=1)out vec4 pos;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
mat4 worldview=camera_uniforms.view*pc.world;
|
mat4 worldview=camera_uniforms.view*pc.world;
|
||||||
v_normal=normal;//normalize(transpose(inverse(mat3(worldview))) * normal);
|
|
||||||
pos = worldview*vec4(position,1.);
|
pos = worldview*vec4(position,1.);
|
||||||
gl_Position=camera_uniforms.proj*pos;
|
gl_Position=camera_uniforms.proj*pos;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub(crate) enum InstructionSet {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the input. Useful for copying registers.
|
||||||
|
OPCopy = (1),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Adds a vector to a vector component-wise.
|
||||||
|
OPAdd = (2),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Subtracts a vector from a vector component-wise.
|
||||||
|
OPSub = (3),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Multiplies a vector and a vector component-wise.
|
||||||
|
OPMul = (4),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Divides a vector by a vector component-wise.
|
||||||
|
OPDiv = (5),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates a vector Atan2 a vector component-wise.
|
||||||
|
OPAtan2 = (6),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates the minimum of a vector and a vector component-wise.
|
||||||
|
OPMin = (7),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates the maximum of a vector and a vector component-wise.
|
||||||
|
OPMax = (8),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Threeway comparison operator.
|
||||||
|
OPCompare = (9),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates a vector modulo a vector component-wise.
|
||||||
|
OPMod = (10),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// If both arguments are non-zero, returns the right-hand argument.
|
||||||
|
/// Otherwise, returns zero.
|
||||||
|
OPAnd = (11),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// If the left-hand argument is non-zero, it is returned. Otherwise, the
|
||||||
|
/// right-hand argument is returned.
|
||||||
|
OPOr = (12),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the negation of all components of a vector.
|
||||||
|
OPNegate = (13),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the absolute value of all components of a vector.
|
||||||
|
OPAbs = (14),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns 1 over all components of a vector.
|
||||||
|
OPRecip = (15),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the square root of all components of a vector.
|
||||||
|
OPSqrt = (16),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the square of all components of a vector.
|
||||||
|
OPSquare = (17),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the floor of all components of a vector.
|
||||||
|
OPFloor = (18),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the ceiling of all components of a vector.
|
||||||
|
OPCeil = (19),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns all components of a vector rounded to the nearest integer, 0.5
|
||||||
|
/// away from zero.
|
||||||
|
OPRound = (20),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the sine of all components of a vector.
|
||||||
|
OPSin = (21),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the cosine of all components of a vector.
|
||||||
|
OPCos = (22),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the tangent of all components of a vector.
|
||||||
|
OPTan = (23),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the arc sine of all components of a vector.
|
||||||
|
OPAsin = (24),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the arc cosine of all components of a vector.
|
||||||
|
OPAcos = (25),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the arc tangent of all components of a vector.
|
||||||
|
OPAtan = (26),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns e raised to all components of a vector.
|
||||||
|
OPExp = (27),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the natural logarithm of all components of a vector.
|
||||||
|
OPLog = (28),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// The output is 1 if the argument is 0, and 0 otherwise.
|
||||||
|
OPNot = (29),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the fractional part of all components of a vector.
|
||||||
|
OPFract = (30),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the cube of all components of a vector.
|
||||||
|
OPCube = (31),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the smooth minimum between a vector and a vector, varied by a
|
||||||
|
/// vector.
|
||||||
|
OPSmoothMin = (32),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the smooth maximum between a vector and a vector, varied by a
|
||||||
|
/// vector.
|
||||||
|
OPSmoothMax = (33),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Clamps a vector between a vector and a vector.
|
||||||
|
OPClamp = (34),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Mixes between a vector and a vector, varied by a vector.
|
||||||
|
OPMix = (35),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates a vector multiplied by a vector, then adds a vector.
|
||||||
|
OPFMA = (36),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the length (magnitude) of a vector.
|
||||||
|
OPLength = (37),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the normalised version of a vector.
|
||||||
|
OPNormalize = (38),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the dot product of two vectors.
|
||||||
|
OPDot = (39),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the length (magnitude) of the vector between two vectors.
|
||||||
|
OPDistance = (40),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// No operation.
|
||||||
|
OPNop = ((3 * 64) + 63),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Stops execution of the tape and returns a single value.
|
||||||
|
OPReturn = ((2 * 64) + 63),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the current position being sampled.
|
||||||
|
OPPosition = ((1 * 64) + 63),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates the minimum of two Vec1s, and also carries over the relevant
|
||||||
|
/// material metadata.
|
||||||
|
OPMinMaterial = ((0 * 64) + 63),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Calculates the maximum of two Vec1s, and also carries over the relevant
|
||||||
|
/// material metadata.
|
||||||
|
OPMaxMaterial = ((3 * 64) + 62),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the smooth minimum between a Vec1 and a Vec1, varied by a Vec1,
|
||||||
|
/// and also carries over the relevant material metadata.
|
||||||
|
OPSmoothMinMaterial = ((2 * 64) + 62),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the smooth maximum between a Vec1 and a Vec1, varied by a Vec1,
|
||||||
|
/// and also carries over the relevant material metadata.
|
||||||
|
OPSmoothMaxMaterial = ((1 * 64) + 62),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the cross product of two Vec3s.
|
||||||
|
OPCross = ((0 * 64) + 62),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the distance to a sphere.
|
||||||
|
OPSDFSphere = ((3 * 64) + 61),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the distance to a box.
|
||||||
|
OPSDFBox = ((2 * 64) + 61),
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Returns the distance to a torus.
|
||||||
|
OPSDFTorus = ((1 * 64) + 61),
|
||||||
|
}
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#ifndef instruction_set
|
|
||||||
#define instruction_set
|
|
||||||
|
|
||||||
// Element wise
|
|
||||||
const uint8_t OPCopy =uint8_t(1); // Returns the input. Useful for copying registers.
|
|
||||||
|
|
||||||
// Fidget VM compat
|
|
||||||
// Two parameter
|
|
||||||
const uint8_t OPAdd =uint8_t(2); // Adds a vector to a vector component-wise.
|
|
||||||
const uint8_t OPSub =uint8_t(3); // Subtracts a vector from a vector component-wise.
|
|
||||||
const uint8_t OPMul =uint8_t(4); // Multiplies a vector and a vector component-wise.
|
|
||||||
const uint8_t OPDiv =uint8_t(5); // Divides a vector by a vector component-wise.
|
|
||||||
const uint8_t OPAtan2 =uint8_t(6); // Calculates a vector Atan2 a vector component-wise.
|
|
||||||
const uint8_t OPMin =uint8_t(7); // Calculates the minimum of a vector and a vector component-wise.
|
|
||||||
const uint8_t OPMax =uint8_t(8); // Calculates the maximum of a vector and a vector component-wise.
|
|
||||||
const uint8_t OPCompare =uint8_t(9); // Threeway comparison operator.
|
|
||||||
const uint8_t OPMod =uint8_t(10); // Calculates a vector modulo a vector component-wise.
|
|
||||||
const uint8_t OPAnd =uint8_t(11); // If both arguments are non-zero, returns the right-hand argument. Otherwise, returns zero.
|
|
||||||
const uint8_t OPOr =uint8_t(12); // If the left-hand argument is non-zero, it is returned. Otherwise, the right-hand argument is returned.
|
|
||||||
// One parameter
|
|
||||||
const uint8_t OPNegate =uint8_t(13); // Returns the negation of all components of a vector.
|
|
||||||
const uint8_t OPAbs =uint8_t(14); // Returns the absolute value of all components of a vector.
|
|
||||||
const uint8_t OPRecip =uint8_t(15); // Returns 1 over all components of a vector.
|
|
||||||
const uint8_t OPSqrt =uint8_t(16); // Returns the square root of all components of a vector.
|
|
||||||
const uint8_t OPSquare =uint8_t(17); // Returns the square of all components of a vector.
|
|
||||||
const uint8_t OPFloor =uint8_t(18); // Returns the floor of all components of a vector.
|
|
||||||
const uint8_t OPCeil =uint8_t(19); // Returns the ceiling of all components of a vector.
|
|
||||||
const uint8_t OPRound =uint8_t(20); // Returns all components of a vector rounded to the nearest integer, 0.5 away from zero.
|
|
||||||
const uint8_t OPSin =uint8_t(21); // Returns the sine of all components of a vector.
|
|
||||||
const uint8_t OPCos =uint8_t(22); // Returns the cosine of all components of a vector.
|
|
||||||
const uint8_t OPTan =uint8_t(23); // Returns the tangent of all components of a vector.
|
|
||||||
const uint8_t OPAsin =uint8_t(24); // Returns the arc sine of all components of a vector.
|
|
||||||
const uint8_t OPAcos =uint8_t(25); // Returns the arc cosine of all components of a vector.
|
|
||||||
const uint8_t OPAtan =uint8_t(26); // Returns the arc tangent of all components of a vector.
|
|
||||||
const uint8_t OPExp =uint8_t(27); // Returns e raised to all components of a vector.
|
|
||||||
const uint8_t OPLog =uint8_t(28); // Returns the natural logarithm of all components of a vector.
|
|
||||||
const uint8_t OPNot =uint8_t(29); // The output is 1 if the argument is 0, and 0 otherwise.
|
|
||||||
|
|
||||||
// Additional
|
|
||||||
// One Parameter
|
|
||||||
const uint8_t OPFract =uint8_t(30); // Returns the fractional part of all components of a vector.
|
|
||||||
const uint8_t OPCube =uint8_t(31); // Returns the cube of all components of a vector.
|
|
||||||
// Three parameter
|
|
||||||
const uint8_t OPSmoothMin =uint8_t(32); // Returns the smooth minimum between a vector and a vector, varied by a vector.
|
|
||||||
const uint8_t OPSmoothMax =uint8_t(33); // Returns the smooth maximum between a vector and a vector, varied by a vector.
|
|
||||||
const uint8_t OPClamp =uint8_t(34); // Clamps a vector between a vector and a vector.
|
|
||||||
const uint8_t OPMix =uint8_t(35); // Mixes between a vector and a vector, varied by a vector.
|
|
||||||
const uint8_t OPFMA =uint8_t(36); // Calculates a vector multiplied by a vector, then adds a vector.
|
|
||||||
|
|
||||||
// Non-element wise
|
|
||||||
// One parameter
|
|
||||||
const uint8_t OPLength =uint8_t(37); // Returns the length (magnitude) of a vector.
|
|
||||||
const uint8_t OPNormalize =uint8_t(38); // Returns the normalised version of a vector.
|
|
||||||
// Two parameter
|
|
||||||
const uint8_t OPDot =uint8_t(39); // Returns the dot product of two vectors.
|
|
||||||
const uint8_t OPDistance =uint8_t(40); // Returns the length (magnitude) of the vector between two vectors.
|
|
||||||
|
|
||||||
// Bookkeeping
|
|
||||||
const uint8_t OPNop =uint8_t((3*64)+63); // No operation.
|
|
||||||
const uint8_t OPReturn =uint8_t((2*64)+63); // Stops execution of the tape and returns a single value.
|
|
||||||
const uint8_t OPPosition =uint8_t((1*64)+63); // Returns the current position being sampled.
|
|
||||||
|
|
||||||
// Special
|
|
||||||
const uint8_t OPMinMaterial =uint8_t((0*64)+63); // Calculates the minimum of two Vec1s, and also carries over the relevant material metadata.
|
|
||||||
const uint8_t OPMaxMaterial =uint8_t((3*64)+62); // Calculates the maximum of two Vec1s, and also carries over the relevant material metadata.
|
|
||||||
const uint8_t OPSmoothMinMaterial =uint8_t((2*64)+62); // Returns the smooth minimum between a Vec1 and a Vec1, varied by a Vec1, and also carries over the relevant material metadata.
|
|
||||||
const uint8_t OPSmoothMaxMaterial =uint8_t((1*64)+62); // Returns the smooth maximum between a Vec1 and a Vec1, varied by a Vec1, and also carries over the relevant material metadata.
|
|
||||||
const uint8_t OPCross =uint8_t((0*64)+62); // Returns the cross product of two Vec3s.
|
|
||||||
|
|
||||||
// SDFs
|
|
||||||
const uint8_t OPSDFSphere =uint8_t((3*64)+61); // Returns the distance to a sphere.
|
|
||||||
const uint8_t OPSDFBox =uint8_t((2*64)+61); // Returns the distance to a box.
|
|
||||||
const uint8_t OPSDFTorus =uint8_t((1*64)+61); // Returns the distance to a torus.
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -26,90 +26,3 @@ Steps:
|
|||||||
4. each subgroup outputs 4 verts and 2 triangles, for a total 16/8 per workgroup.
|
4. each subgroup outputs 4 verts and 2 triangles, for a total 16/8 per workgroup.
|
||||||
|
|
||||||
For a mesh that takes up 1024x1024 pixel on screen, each quad takes up 16x16 pixels.
|
For a mesh that takes up 1024x1024 pixel on screen, each quad takes up 16x16 pixels.
|
||||||
|
|
||||||
# instruction set
|
|
||||||
## arithmetic
|
|
||||||
### duo types
|
|
||||||
- VecXVecX (returns vecx)
|
|
||||||
- VecXVec1 (returns vecx)
|
|
||||||
- Vec1VecX (returns vecx)
|
|
||||||
### duo instructions
|
|
||||||
- Add
|
|
||||||
- Sub
|
|
||||||
- Mul
|
|
||||||
- Div
|
|
||||||
- Mod
|
|
||||||
- Rem
|
|
||||||
- Pow
|
|
||||||
- Atan2
|
|
||||||
- Min
|
|
||||||
- Max
|
|
||||||
### trio types
|
|
||||||
- VecXVecXVecX (returns vecx)
|
|
||||||
- VecXVecXVec1 (returns vecx)
|
|
||||||
- VecXVec1VecX (returns vecx)
|
|
||||||
- VecXVec1Vec1 (returns vecx)
|
|
||||||
- Vec1VecXVecX (returns vecx)
|
|
||||||
- Vec1VecXVec1 (returns vecx)
|
|
||||||
- Vec1Vec1VecX (returns vecx)
|
|
||||||
### trio instructions
|
|
||||||
- SmoothMin
|
|
||||||
- SmoothMax
|
|
||||||
- Clamp
|
|
||||||
- Mix
|
|
||||||
- Step
|
|
||||||
- SmoothStep
|
|
||||||
- FMA
|
|
||||||
### unary types
|
|
||||||
- VecX
|
|
||||||
### unary instructions
|
|
||||||
- negate
|
|
||||||
- round
|
|
||||||
- roundeven
|
|
||||||
- trunc
|
|
||||||
- abs
|
|
||||||
- sign
|
|
||||||
- floor
|
|
||||||
- ceil
|
|
||||||
- fract
|
|
||||||
- sin
|
|
||||||
- cos
|
|
||||||
- tan
|
|
||||||
- asin
|
|
||||||
- acos
|
|
||||||
- atan
|
|
||||||
- sinh
|
|
||||||
- cosh
|
|
||||||
- tanh
|
|
||||||
- asinh
|
|
||||||
- acosh
|
|
||||||
- atanh
|
|
||||||
- exp
|
|
||||||
- log
|
|
||||||
- exp2
|
|
||||||
- log2
|
|
||||||
- sqrt
|
|
||||||
- inversesqrt
|
|
||||||
- square
|
|
||||||
- cube
|
|
||||||
### Extra Matrix
|
|
||||||
- MulVec2Mat2 (returns vec2)
|
|
||||||
- MulVec3Mat3 (returns vec3)
|
|
||||||
- MulVec4Mat4 (returns vec4)
|
|
||||||
### Extra Vector
|
|
||||||
- CrossVec3Vec3 (returns vec3)
|
|
||||||
- DotVecX (returns vecx)
|
|
||||||
- LengthVecX (returns vec1)
|
|
||||||
- DistanceVecX (returns vec1)
|
|
||||||
- NormaliseVecX (returns vec1)
|
|
||||||
## Data manipulation
|
|
||||||
### Instructions
|
|
||||||
- CopyVecX
|
|
||||||
## SDF
|
|
||||||
- SDFSphere
|
|
||||||
- SDFBox
|
|
||||||
- SDFTorus
|
|
||||||
## Extra
|
|
||||||
- Stop
|
|
||||||
- Nop
|
|
||||||
- Position
|
|
||||||
@@ -1,743 +0,0 @@
|
|||||||
#extension GL_EXT_shader_explicit_arithmetic_types:require
|
|
||||||
#extension GL_EXT_shader_explicit_arithmetic_types_int8:require
|
|
||||||
|
|
||||||
#ifndef interpreter
|
|
||||||
#define interpreter 1
|
|
||||||
|
|
||||||
#include "instructionset.glsl"
|
|
||||||
#include "scene_bindings.glsl"
|
|
||||||
|
|
||||||
float registers[14] = float[14](0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
|
|
||||||
|
|
||||||
void clear_registers()
|
|
||||||
{
|
|
||||||
registers = float[14](0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.);
|
|
||||||
}
|
|
||||||
|
|
||||||
float load(uint8_t reg) {
|
|
||||||
if (reg == 0) {
|
|
||||||
return 0.;
|
|
||||||
} else if (reg == 15) {
|
|
||||||
return next_const();
|
|
||||||
} else {
|
|
||||||
return registers[reg - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void store(uint8_t reg, float value) {
|
|
||||||
if (reg > 0 && reg < 15) {
|
|
||||||
registers[reg - 1] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float input_float() {
|
|
||||||
return load(next_register());
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 input_vec2() {
|
|
||||||
return vec2(load(next_register()), load(next_register()));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 input_vec3() {
|
|
||||||
return vec3(load(next_register()), load(next_register()), load(next_register()));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 input_vec4() {
|
|
||||||
return vec4(load(next_register()), load(next_register()), load(next_register()), load(next_register()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_float(float v) {
|
|
||||||
store(next_register(), v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_vec2(vec2 v) {
|
|
||||||
store(next_register(), v.x);
|
|
||||||
store(next_register(), v.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_vec3(vec3 v) {
|
|
||||||
store(next_register(), v.x);
|
|
||||||
store(next_register(), v.y);
|
|
||||||
store(next_register(), v.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_vec4(vec4 v) {
|
|
||||||
store(next_register(), v.x);
|
|
||||||
store(next_register(), v.y);
|
|
||||||
store(next_register(), v.z);
|
|
||||||
store(next_register(), v.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define ewise_one(len, func) for (int i = 0; i < len; i++) { \
|
|
||||||
switch ((mask[program_counter] >> (i * 4)) & 3) { \
|
|
||||||
case MASK_EXECUTE: \
|
|
||||||
output_float(func(input_float())); \
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_LEFT: \
|
|
||||||
output_float(input_float()); \
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_RIGHT : \
|
|
||||||
case MASK_DO_NOTHING : \
|
|
||||||
jump_registers(2); \
|
|
||||||
jump_const(uint(mask[program_counter]>>((i*4)+2))&3); \
|
|
||||||
break ; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ewise_two(len, func) for (int i = 0; i < len; i++) { \
|
|
||||||
switch ((mask[program_counter] >> (i * 4)) & 3) { \
|
|
||||||
case MASK_EXECUTE: \
|
|
||||||
output_float(func(input_float(), input_float())); \
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_LEFT: \
|
|
||||||
float inp = input_float(); \
|
|
||||||
jump_registers(1); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
output_float(inp); \
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_RIGHT: \
|
|
||||||
jump_registers(1); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
output_float(input_float()); \
|
|
||||||
break; \
|
|
||||||
case MASK_DO_NOTHING: \
|
|
||||||
jump_registers(3); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ewise_three(len, func) for (int i = 0; i < len; i++) { \
|
|
||||||
switch ((mask[program_counter] >> (i * 4)) & 3) { \
|
|
||||||
case MASK_EXECUTE: \
|
|
||||||
output_float(func(input_float(), input_float(), input_float())); \
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_LEFT: {\
|
|
||||||
float inp = input_float(); \
|
|
||||||
jump_registers(2); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
output_float(inp); }\
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_RIGHT: {\
|
|
||||||
input_float(); \
|
|
||||||
float inp = input_float(); \
|
|
||||||
input_float(); \
|
|
||||||
output_float(inp); }\
|
|
||||||
break; \
|
|
||||||
case MASK_DO_NOTHING: \
|
|
||||||
jump_registers(4); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ewise_four(len, func) for (int i = 0; i < len; i++) { \
|
|
||||||
switch ((mask[program_counter] >> (i * 4)) & 3) { \
|
|
||||||
case MASK_EXECUTE: \
|
|
||||||
output_float(func(input_float(), input_float(), input_float(), input_float())); \
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_LEFT: {\
|
|
||||||
float inp = input_float(); \
|
|
||||||
jump_registers(3); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
output_float(inp); }\
|
|
||||||
break; \
|
|
||||||
case MASK_COPY_RIGHT: {\
|
|
||||||
input_float(); \
|
|
||||||
float inp = input_float(); \
|
|
||||||
input_float(); \
|
|
||||||
input_float(); \
|
|
||||||
output_float(inp); }\
|
|
||||||
break; \
|
|
||||||
case MASK_DO_NOTHING: \
|
|
||||||
jump_registers(5); \
|
|
||||||
jump_const(uint(mask[program_counter] >> ((i * 4) + 2)) & 3); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ewise_all(opcode, count, func) \
|
|
||||||
case opcode ## Vec1: {ewise_ ## count(1, func);} break; \
|
|
||||||
case opcode ## Vec2: {ewise_ ## count(2, func);} break; \
|
|
||||||
case opcode ## Vec3: {ewise_ ## count(3, func);} break; \
|
|
||||||
case opcode ## Vec4: {ewise_ ## count(4, func);} break; \
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float copyof(float in1)
|
|
||||||
{
|
|
||||||
return in1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float mulof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return in1 * in2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float divof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return in1 / in2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float addof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return in1 + in2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float subof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return in1 - in2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float modof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return mod(in1, in2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//always monotonic for x>0
|
|
||||||
float powof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return pow(in1, in2);
|
|
||||||
}
|
|
||||||
|
|
||||||
float opSmoothUnion(float d1, float d2, float k)
|
|
||||||
{
|
|
||||||
float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
|
|
||||||
return mix(d2, d1, h) - k * h * (1.0 - h);
|
|
||||||
}
|
|
||||||
|
|
||||||
float opSmoothSubtraction(float d1, float d2, float k)
|
|
||||||
{
|
|
||||||
float h = clamp(0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0);
|
|
||||||
return mix(d2, -d1, h) + k * h * (1.0 - h);
|
|
||||||
}
|
|
||||||
|
|
||||||
float opSmoothIntersection(float d1, float d2, float k)
|
|
||||||
{
|
|
||||||
float h = clamp(0.5 - 0.5 * (d2 - d1) / k, 0.0, 1.0);
|
|
||||||
return mix(d2, d1, h) + k * h * (1.0 - h);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float stepof(float d1, float d2)
|
|
||||||
{
|
|
||||||
return step(d1, d2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float smoothstepof(float d1, float d2, float k)
|
|
||||||
{
|
|
||||||
return smoothstep(d1, d2, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float clampof(float in1, float in2, float in3)
|
|
||||||
{
|
|
||||||
return clamp(in1, in2, in3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float mixof(float in1, float in2, float in3)
|
|
||||||
{
|
|
||||||
return mix(in1, in2, in3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float fmaof(float in1, float in2, float in3)
|
|
||||||
{
|
|
||||||
return fma(in1, in2, in3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//variable
|
|
||||||
float squareof(float in1)
|
|
||||||
{
|
|
||||||
return in1 * in1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float cubeof(float in1)
|
|
||||||
{
|
|
||||||
return in1 * in1 * in1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float absof(float in1)
|
|
||||||
{
|
|
||||||
return abs(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float signof(float in1)
|
|
||||||
{
|
|
||||||
return sign(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float floorof(float in1)
|
|
||||||
{
|
|
||||||
return floor(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float ceilof(float in1)
|
|
||||||
{
|
|
||||||
return ceil(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float fractof(float in1)
|
|
||||||
{
|
|
||||||
return fract(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float sqrtof(float in1)
|
|
||||||
{
|
|
||||||
return sqrt(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float inversesqrtof(float in1)
|
|
||||||
{
|
|
||||||
return inversesqrt(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float expof(float in1)
|
|
||||||
{
|
|
||||||
return exp(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float exp2of(float in1)
|
|
||||||
{
|
|
||||||
return exp2(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float logof(float in1)
|
|
||||||
{
|
|
||||||
return log(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float log2of(float in1)
|
|
||||||
{
|
|
||||||
return log2(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const float PI = 3.1415926536;
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float sinof(float in1)
|
|
||||||
{
|
|
||||||
return sin(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float cosof(float in1)
|
|
||||||
{
|
|
||||||
return cos(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float tanof(float in1)
|
|
||||||
{
|
|
||||||
return tan(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float asinof(float in1)
|
|
||||||
{
|
|
||||||
return asin(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//negatively monotonic
|
|
||||||
float acosof(float in1)
|
|
||||||
{
|
|
||||||
return acos(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float atanof(float in1)
|
|
||||||
{
|
|
||||||
return atan(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float atan2of(float in1, float in2)
|
|
||||||
{
|
|
||||||
return atan(in1, in2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float sinhof(float in1)
|
|
||||||
{
|
|
||||||
return sinh(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float coshof(float in1)
|
|
||||||
{
|
|
||||||
return cosh(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float tanhof(float in1)
|
|
||||||
{
|
|
||||||
return tanh(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float asinhof(float in1)
|
|
||||||
{
|
|
||||||
return asinh(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float acoshof(float in1)
|
|
||||||
{
|
|
||||||
return acosh(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float atanhof(float in1)
|
|
||||||
{
|
|
||||||
return atanh(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//obvious
|
|
||||||
float minof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return min(in1, in2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//obvious
|
|
||||||
float maxof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return max(in1, in2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//negatively monotonic
|
|
||||||
float negateof(float in1)
|
|
||||||
{
|
|
||||||
return -in1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float roundof(float in1)
|
|
||||||
{
|
|
||||||
return round(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//monotonic
|
|
||||||
float roundevenof(float in1)
|
|
||||||
{
|
|
||||||
return roundEven(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//truncate
|
|
||||||
float truncof(float in1)
|
|
||||||
{
|
|
||||||
return trunc(in1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float recipof(float in1)
|
|
||||||
{
|
|
||||||
return 1.0 / in1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float compareof(float in1, float in2)
|
|
||||||
{
|
|
||||||
if (isnan(in1)) {
|
|
||||||
return in1;
|
|
||||||
}
|
|
||||||
if (isnan(in2)) {
|
|
||||||
return in2;
|
|
||||||
}
|
|
||||||
if (in1 < in2) {
|
|
||||||
return -1.;
|
|
||||||
}
|
|
||||||
if (in1 > in2) {
|
|
||||||
return 1.;
|
|
||||||
}
|
|
||||||
return 0.;
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float orof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return mix(in2, in1, in1 == 0.);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float andof(float in1, float in2)
|
|
||||||
{
|
|
||||||
return mix(in1, in2, in1 == 0.);
|
|
||||||
}
|
|
||||||
|
|
||||||
//handled
|
|
||||||
float notof(float in1)
|
|
||||||
{
|
|
||||||
return mix(1., 0., in1 == 0.);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 scene(vec3 p, bool materials)
|
|
||||||
{
|
|
||||||
uint program_counter = 0;
|
|
||||||
uint io_counter = 0;
|
|
||||||
uint const_counter = 0;
|
|
||||||
|
|
||||||
desc = scene_description.desc[(DescriptionIndex) + 1];
|
|
||||||
|
|
||||||
clear_registers();
|
|
||||||
|
|
||||||
while (program_counter < EXECUTION_LIMIT) {
|
|
||||||
uint8_t code = next_opcode();
|
|
||||||
|
|
||||||
uint[2] elements = reg_elementwise(code);
|
|
||||||
if (elements[0] == 0 && (mask[program_counter] & 3) != MASK_EXECUTE) {
|
|
||||||
uint io = uint(reg_input(code) + reg_output(code));
|
|
||||||
jump_registers(io);
|
|
||||||
jump_const(uint(mask[program_counter] >> 2));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (uint32_t(code))
|
|
||||||
{
|
|
||||||
ewise_all(OPCopy, one, copyof);
|
|
||||||
|
|
||||||
ewise_all(OPAdd, two, addof);
|
|
||||||
ewise_all(OPSub, two, subof);
|
|
||||||
ewise_all(OPMul, two, mulof);
|
|
||||||
ewise_all(OPDiv, two, divof);
|
|
||||||
ewise_all(OPAtan2, two, atan2of);
|
|
||||||
ewise_all(OPMin, two, minof);
|
|
||||||
ewise_all(OPMax, two, maxof);
|
|
||||||
ewise_all(OPCompare, two, compareof);
|
|
||||||
ewise_all(OPMod, two, modof);
|
|
||||||
ewise_all(OPAnd, two, andof);
|
|
||||||
ewise_all(OPOr, two, orof);
|
|
||||||
|
|
||||||
ewise_all(OPNegate, one, negateof);
|
|
||||||
ewise_all(OPAbs, one, absof);
|
|
||||||
ewise_all(OPRecip, one, recipof);
|
|
||||||
ewise_all(OPSqrt, one, sqrtof);
|
|
||||||
ewise_all(OPSquare, one, squareof);
|
|
||||||
ewise_all(OPFloor, one, floorof);
|
|
||||||
ewise_all(OPCeil, one, ceilof);
|
|
||||||
ewise_all(OPRound, one, roundof);
|
|
||||||
ewise_all(OPSin, one, sinof);
|
|
||||||
ewise_all(OPCos, one, cosof);
|
|
||||||
ewise_all(OPTan, one, tanof);
|
|
||||||
ewise_all(OPAsin, one, asinof);
|
|
||||||
ewise_all(OPAcos, one, acosof);
|
|
||||||
ewise_all(OPAtan, one, atanof);
|
|
||||||
ewise_all(OPExp, one, expof);
|
|
||||||
ewise_all(OPLog, one, logof);
|
|
||||||
ewise_all(OPNot, one, notof);
|
|
||||||
|
|
||||||
ewise_all(OPFract, one, fractof);
|
|
||||||
ewise_all(OPCube, one, cubeof);
|
|
||||||
ewise_all(OPSmoothMin, three, opSmoothUnion);
|
|
||||||
ewise_all(OPSmoothMax, three, opSmoothIntersection);
|
|
||||||
ewise_all(OPClamp, three, clampof);
|
|
||||||
ewise_all(OPMix, three, mixof);
|
|
||||||
ewise_all(OPFMA, three, fmaof);
|
|
||||||
|
|
||||||
case OPDotVec1:
|
|
||||||
{
|
|
||||||
float in1 = input_float();
|
|
||||||
float in2 = input_float();
|
|
||||||
output_float(in1 * in2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPDotVec2:
|
|
||||||
{
|
|
||||||
vec2 in1 = input_vec2();
|
|
||||||
vec2 in2 = input_vec2();
|
|
||||||
output_float(dot(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPDotVec3:
|
|
||||||
{
|
|
||||||
vec3 in1 = input_vec3();
|
|
||||||
vec3 in2 = input_vec3();
|
|
||||||
output_float(dot(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPDotVec4:
|
|
||||||
{
|
|
||||||
vec4 in1 = input_vec4();
|
|
||||||
vec4 in2 = input_vec4();
|
|
||||||
output_float(dot(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPLengthVec1:
|
|
||||||
{
|
|
||||||
float in1 = input_float();
|
|
||||||
output_float(in1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPLengthVec2:
|
|
||||||
{
|
|
||||||
vec2 in1 = input_vec2();
|
|
||||||
output_float(length(in1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPLengthVec3:
|
|
||||||
{
|
|
||||||
vec3 in1 = input_vec3();
|
|
||||||
output_float(length(in1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPLengthVec4:
|
|
||||||
{
|
|
||||||
vec4 in1 = input_vec4();
|
|
||||||
output_float(length(in1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPDistanceVec1:
|
|
||||||
{
|
|
||||||
float in1 = input_float();
|
|
||||||
float in2 = input_float();
|
|
||||||
output_float(in2 - in1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPDistanceVec2:
|
|
||||||
{
|
|
||||||
vec2 in1 = input_vec2();
|
|
||||||
vec2 in2 = input_vec2();
|
|
||||||
output_float(distance(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPDistanceVec3:
|
|
||||||
{
|
|
||||||
vec3 in1 = input_vec3();
|
|
||||||
vec3 in2 = input_vec3();
|
|
||||||
output_float(distance(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPDistanceVec4:
|
|
||||||
{
|
|
||||||
vec4 in1 = input_vec4();
|
|
||||||
vec4 in2 = input_vec4();
|
|
||||||
output_float(distance(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPNormalizeVec1:
|
|
||||||
{
|
|
||||||
float in1 = input_float();
|
|
||||||
output_float(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPNormalizeVec2:
|
|
||||||
{
|
|
||||||
vec2 in1 = input_vec2();
|
|
||||||
output_vec2(normalize(in1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPNormalizeVec3:
|
|
||||||
{
|
|
||||||
vec3 in1 = input_vec3();
|
|
||||||
output_vec3(normalize(in1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPNormalizeVec4:
|
|
||||||
{
|
|
||||||
vec4 in1 = input_vec4();
|
|
||||||
output_vec4(normalize(in1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPCross:
|
|
||||||
{
|
|
||||||
vec3 in1 = input_vec3();
|
|
||||||
vec3 in2 = input_vec3();
|
|
||||||
output_vec3(cross(in1, in2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPSmoothMinMaterial:
|
|
||||||
{
|
|
||||||
ewise_three(1, opSmoothUnion);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPSmoothMaxMaterial:
|
|
||||||
{
|
|
||||||
ewise_three(1, opSmoothIntersection);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPMinMaterial:
|
|
||||||
{
|
|
||||||
ewise_two(1, minof);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPMaxMaterial:
|
|
||||||
{
|
|
||||||
ewise_two(1, maxof);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPSDFSphere:
|
|
||||||
{
|
|
||||||
vec3 in1 = input_vec3();
|
|
||||||
float in2 = input_float();
|
|
||||||
output_float(length(in1) - in2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPSDFTorus:
|
|
||||||
{
|
|
||||||
vec3 p = input_vec3();
|
|
||||||
vec2 t = input_vec2();
|
|
||||||
|
|
||||||
vec2 q = vec2(length(p.xz) - t.x, p.y);
|
|
||||||
output_float(length(q) - t.y);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//this doesn't work internally but it's probably fiiiine
|
|
||||||
case OPSDFBox:
|
|
||||||
{
|
|
||||||
vec3 p = input_vec3();
|
|
||||||
vec3 b = input_vec3();
|
|
||||||
|
|
||||||
vec3 q = abs(p) - b;
|
|
||||||
|
|
||||||
output_float(length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPNop:
|
|
||||||
break;
|
|
||||||
case OPReturn:
|
|
||||||
return vec3(input_float());
|
|
||||||
|
|
||||||
case OPPosition:
|
|
||||||
{
|
|
||||||
output_vec3(p);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
#ifdef debug
|
|
||||||
return vec3(float(code));
|
|
||||||
#else
|
|
||||||
return vec3(-1.);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vec3(input_float());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif//ifndef interpreter
|
|
||||||
-1439
File diff suppressed because it is too large
Load Diff
+88
-544
@@ -11,19 +11,18 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
const DYNAMIC_STATE: bool = true;
|
const DYNAMIC_STATE: bool = true;
|
||||||
const COMPUTE_FUZZING: bool = false;
|
|
||||||
const MSAA_ENABLE: bool = false;
|
const MSAA_ENABLE: bool = false;
|
||||||
const MSAA_SAMPLES: u32 = 4;
|
const MSAA_SAMPLES: u32 = 4;
|
||||||
const SAMPLE_RATE_SHADING: f32 = 1.0;
|
const SAMPLE_RATE_SHADING: f32 = 1.0;
|
||||||
|
|
||||||
const MSAA_SAMPLES_ACTUAL: u32 = if MSAA_ENABLE { MSAA_SAMPLES } else { 1 };
|
const MSAA_SAMPLES_ACTUAL: u32 = if MSAA_ENABLE { MSAA_SAMPLES } else { 1 };
|
||||||
|
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
use egui_winit_vulkano::{Gui, GuiConfig};
|
use egui_winit_vulkano::{Gui, GuiConfig};
|
||||||
use foldhash::{HashMap, HashMapExt, HashSet};
|
use foldhash::{HashMap, HashMapExt, HashSet};
|
||||||
use glam::{self, EulerRot, Mat3, Mat4, Vec3, vec3};
|
use glam::{self, EulerRot, Mat3, Mat4, Vec3, vec3};
|
||||||
use log::{error, info, trace};
|
use log::{error, info, trace};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use rspirv::binary::Disassemble;
|
|
||||||
use simplelog::{CombinedLogger, Config, TermLogger, WriteLogger};
|
use simplelog::{CombinedLogger, Config, TermLogger, WriteLogger};
|
||||||
use ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape};
|
use ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
@@ -51,10 +50,9 @@ use vulkano::{
|
|||||||
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
|
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
|
||||||
},
|
},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
ComputePipeline, DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint,
|
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
|
||||||
PipelineLayout, PipelineShaderStageCreateInfo,
|
PipelineShaderStageCreateInfo,
|
||||||
cache::{PipelineCache, PipelineCacheCreateInfo},
|
cache::{PipelineCache, PipelineCacheCreateInfo},
|
||||||
compute::ComputePipelineCreateInfo,
|
|
||||||
graphics::{
|
graphics::{
|
||||||
GraphicsPipelineCreateInfo,
|
GraphicsPipelineCreateInfo,
|
||||||
color_blend::{ColorBlendAttachmentState, ColorBlendState},
|
color_blend::{ColorBlendAttachmentState, ColorBlendState},
|
||||||
@@ -90,11 +88,7 @@ use crate::objects::*;
|
|||||||
|
|
||||||
mod ssa;
|
mod ssa;
|
||||||
|
|
||||||
mod instruction_set {
|
mod instruction_set;
|
||||||
include!(concat!(env!("OUT_DIR"), "/instructionset.rs"));
|
|
||||||
}
|
|
||||||
|
|
||||||
use crate::instruction_set::InstructionSet;
|
|
||||||
|
|
||||||
mod interpreter;
|
mod interpreter;
|
||||||
|
|
||||||
@@ -150,6 +144,31 @@ impl Default for CState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VERTEX_COUNT: usize = 3 * 2 * 6;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod, Vertex)]
|
||||||
|
pub(crate) struct IVertex {
|
||||||
|
#[format(R32G32B32_SFLOAT)]
|
||||||
|
position: [f32; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const CUBE_VERTEX: [IVertex; VERTEX_COUNT] = [
|
||||||
|
IVertex { position: [0.0, 1.0, 0.0]}, IVertex { position: [0.0, 0.0, 0.0]}, IVertex { position: [1.0, 0.0, 0.0]}, // s1 t1
|
||||||
|
IVertex { position: [1.0, 1.0, 0.0]}, IVertex { position: [0.0, 1.0, 0.0]}, IVertex { position: [1.0, 0.0, 0.0]}, // s1 t2
|
||||||
|
IVertex { position: [1.0, 1.0, 0.0]}, IVertex { position: [1.0, 0.0, 0.0]}, IVertex { position: [1.0, 0.0, 1.0]}, // s2 t1
|
||||||
|
IVertex { position: [1.0, 1.0, 1.0]}, IVertex { position: [1.0, 1.0, 0.0]}, IVertex { position: [1.0, 0.0, 1.0]}, // s2 t2
|
||||||
|
IVertex { position: [0.0, 0.0, 1.0]}, IVertex { position: [0.0, 1.0, 1.0]}, IVertex { position: [1.0, 0.0, 1.0]}, // s3 t1
|
||||||
|
IVertex { position: [0.0, 1.0, 1.0]}, IVertex { position: [1.0, 1.0, 1.0]}, IVertex { position: [1.0, 0.0, 1.0]}, // s3 t2
|
||||||
|
IVertex { position: [0.0, 0.0, 0.0]}, IVertex { position: [0.0, 1.0, 0.0]}, IVertex { position: [0.0, 0.0, 1.0]}, // s4 t1
|
||||||
|
IVertex { position: [0.0, 1.0, 0.0]}, IVertex { position: [0.0, 1.0, 1.0]}, IVertex { position: [0.0, 0.0, 1.0]}, // s4 t2
|
||||||
|
IVertex { position: [0.0, 0.0, 0.0]}, IVertex { position: [0.0, 0.0, 1.0]}, IVertex { position: [1.0, 0.0, 0.0]}, // s5 t1
|
||||||
|
IVertex { position: [0.0, 0.0, 1.0]}, IVertex { position: [1.0, 0.0, 1.0]}, IVertex { position: [1.0, 0.0, 0.0]}, // s5 t2
|
||||||
|
IVertex { position: [0.0, 1.0, 1.0]}, IVertex { position: [0.0, 1.0, 0.0]}, IVertex { position: [1.0, 1.0, 0.0]}, // s6 t1
|
||||||
|
IVertex { position: [1.0, 1.0, 1.0]}, IVertex { position: [0.0, 1.0, 1.0]}, IVertex { position: [1.0, 1.0, 0.0]}, // s6 t2
|
||||||
|
];
|
||||||
|
|
||||||
struct App {
|
struct App {
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
@@ -163,16 +182,13 @@ struct App {
|
|||||||
gstate: GState,
|
gstate: GState,
|
||||||
previous_debug: PreviousDebug,
|
previous_debug: PreviousDebug,
|
||||||
cstate: CState,
|
cstate: CState,
|
||||||
|
vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]>,
|
||||||
rcx: Option<RenderContext>,
|
rcx: Option<RenderContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ShaderModules {
|
struct ShaderModules {
|
||||||
mesh_vs: Arc<ShaderModule>,
|
implicit_vs: Arc<ShaderModule>,
|
||||||
mesh_fs: Arc<ShaderModule>,
|
implicit_fs: Arc<ShaderModule>,
|
||||||
implicit_ts: Arc<ShaderModule>,
|
|
||||||
implicit_ms: Arc<ShaderModule>,
|
|
||||||
implicit_fs: Arc<ShaderModule>,
|
|
||||||
compute_shader: Arc<ShaderModule>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderContext {
|
struct RenderContext {
|
||||||
@@ -181,8 +197,6 @@ struct RenderContext {
|
|||||||
render_pass: Arc<RenderPass>,
|
render_pass: Arc<RenderPass>,
|
||||||
framebuffers: Vec<Arc<Framebuffer>>,
|
framebuffers: Vec<Arc<Framebuffer>>,
|
||||||
shader_modules: ShaderModules,
|
shader_modules: ShaderModules,
|
||||||
compute_pipeline: Arc<ComputePipeline>,
|
|
||||||
mesh_pipeline: Arc<GraphicsPipeline>,
|
|
||||||
implicit_pipeline: Arc<GraphicsPipeline>,
|
implicit_pipeline: Arc<GraphicsPipeline>,
|
||||||
viewport: Viewport,
|
viewport: Viewport,
|
||||||
recreate_swapchain: bool,
|
recreate_swapchain: bool,
|
||||||
@@ -190,8 +204,6 @@ struct RenderContext {
|
|||||||
previous_frame_end: Option<Box<dyn GpuFuture>>,
|
previous_frame_end: Option<Box<dyn GpuFuture>>,
|
||||||
gui: Gui,
|
gui: Gui,
|
||||||
render_start: Instant,
|
render_start: Instant,
|
||||||
subbuffers: Subbuffers,
|
|
||||||
scene: Vec<[u32; 4]>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app_version() -> Version {
|
fn app_version() -> Version {
|
||||||
@@ -344,7 +356,9 @@ impl App {
|
|||||||
let uniform_buffer_allocator = SubbufferAllocator::new(
|
let uniform_buffer_allocator = SubbufferAllocator::new(
|
||||||
memory_allocator.clone(),
|
memory_allocator.clone(),
|
||||||
SubbufferAllocatorCreateInfo {
|
SubbufferAllocatorCreateInfo {
|
||||||
buffer_usage: BufferUsage::UNIFORM_BUFFER | BufferUsage::STORAGE_BUFFER,
|
buffer_usage: BufferUsage::UNIFORM_BUFFER
|
||||||
|
| BufferUsage::STORAGE_BUFFER
|
||||||
|
| BufferUsage::VERTEX_BUFFER,
|
||||||
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
|
||||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -437,6 +451,11 @@ impl App {
|
|||||||
.lights
|
.lights
|
||||||
.push(Light::new([-4., 6., -8.], [8., 4., 1.], 0.05));
|
.push(Light::new([-4., 6., -8.], [8., 4., 1.], 0.05));
|
||||||
|
|
||||||
|
let vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]> =
|
||||||
|
uniform_buffer_allocator.allocate_sized().unwrap();
|
||||||
|
|
||||||
|
*vertex_buffer.write().unwrap() = CUBE_VERTEX;
|
||||||
|
|
||||||
App {
|
App {
|
||||||
instance,
|
instance,
|
||||||
device,
|
device,
|
||||||
@@ -450,46 +469,16 @@ impl App {
|
|||||||
gstate,
|
gstate,
|
||||||
previous_debug: PreviousDebug::default(),
|
previous_debug: PreviousDebug::default(),
|
||||||
cstate,
|
cstate,
|
||||||
|
vertex_buffer,
|
||||||
rcx: None,
|
rcx: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod mesh_vs {
|
mod implicit_vs {
|
||||||
vulkano_shaders::shader! {
|
vulkano_shaders::shader! {
|
||||||
ty: "vertex",
|
ty: "vertex",
|
||||||
path: "src/triangle.vert.glsl",
|
path: "src/implicit.vert.glsl",
|
||||||
vulkan_version: "1.3",
|
|
||||||
spirv_version: "1.6",
|
|
||||||
custom_derives: [Debug, Clone, Copy],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod mesh_fs {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "fragment",
|
|
||||||
path: "src/frag.glsl",
|
|
||||||
vulkan_version: "1.3",
|
|
||||||
spirv_version: "1.6",
|
|
||||||
define: [("triangle","1")],
|
|
||||||
custom_derives: [Debug, Clone, Copy],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod implicit_ms {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "mesh",
|
|
||||||
path: "src/implicit.mesh.glsl",
|
|
||||||
vulkan_version: "1.3",
|
|
||||||
spirv_version: "1.6",
|
|
||||||
custom_derives: [Debug, Clone, Copy],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod implicit_ts {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "task",
|
|
||||||
path: "src/implicit.task.glsl",
|
|
||||||
vulkan_version: "1.3",
|
vulkan_version: "1.3",
|
||||||
spirv_version: "1.6",
|
spirv_version: "1.6",
|
||||||
custom_derives: [Debug, Clone, Copy],
|
custom_derives: [Debug, Clone, Copy],
|
||||||
@@ -499,18 +488,7 @@ mod implicit_ts {
|
|||||||
mod implicit_fs {
|
mod implicit_fs {
|
||||||
vulkano_shaders::shader! {
|
vulkano_shaders::shader! {
|
||||||
ty: "fragment",
|
ty: "fragment",
|
||||||
path: "src/frag.glsl",
|
path: "src/trace.frag.glsl",
|
||||||
vulkan_version: "1.3",
|
|
||||||
spirv_version: "1.6",
|
|
||||||
define: [("implicit","1")],
|
|
||||||
custom_derives: [Debug, Clone, Copy, Default],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod cs {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "compute",
|
|
||||||
path: "src/fuzz.comp.glsl",
|
|
||||||
vulkan_version: "1.3",
|
vulkan_version: "1.3",
|
||||||
spirv_version: "1.6",
|
spirv_version: "1.6",
|
||||||
custom_derives: [Debug, Clone, Copy],
|
custom_derives: [Debug, Clone, Copy],
|
||||||
@@ -603,28 +581,7 @@ impl ApplicationHandler for App {
|
|||||||
::vulkano::Validated<::vulkano::VulkanError>,
|
::vulkano::Validated<::vulkano::VulkanError>,
|
||||||
>,
|
>,
|
||||||
> = vec![
|
> = vec![
|
||||||
((mesh_vs::load)
|
((implicit_vs::load)
|
||||||
as fn(
|
|
||||||
::std::sync::Arc<::vulkano::device::Device>,
|
|
||||||
) -> Result<
|
|
||||||
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
|
||||||
::vulkano::Validated<::vulkano::VulkanError>,
|
|
||||||
>),
|
|
||||||
((mesh_fs::load)
|
|
||||||
as fn(
|
|
||||||
::std::sync::Arc<::vulkano::device::Device>,
|
|
||||||
) -> Result<
|
|
||||||
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
|
||||||
::vulkano::Validated<::vulkano::VulkanError>,
|
|
||||||
>),
|
|
||||||
((implicit_ms::load)
|
|
||||||
as fn(
|
|
||||||
::std::sync::Arc<::vulkano::device::Device>,
|
|
||||||
) -> Result<
|
|
||||||
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
|
||||||
::vulkano::Validated<::vulkano::VulkanError>,
|
|
||||||
>),
|
|
||||||
((implicit_ts::load)
|
|
||||||
as fn(
|
as fn(
|
||||||
::std::sync::Arc<::vulkano::device::Device>,
|
::std::sync::Arc<::vulkano::device::Device>,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
@@ -638,13 +595,6 @@ impl ApplicationHandler for App {
|
|||||||
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
||||||
::vulkano::Validated<::vulkano::VulkanError>,
|
::vulkano::Validated<::vulkano::VulkanError>,
|
||||||
>),
|
>),
|
||||||
((cs::load)
|
|
||||||
as fn(
|
|
||||||
::std::sync::Arc<::vulkano::device::Device>,
|
|
||||||
) -> Result<
|
|
||||||
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
|
||||||
::vulkano::Validated<::vulkano::VulkanError>,
|
|
||||||
>),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let pariter = loaders
|
let pariter = loaders
|
||||||
@@ -653,44 +603,12 @@ impl ApplicationHandler for App {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let shader_modules = ShaderModules {
|
let shader_modules = ShaderModules {
|
||||||
mesh_vs: pariter[0].clone(),
|
implicit_vs: pariter[0].clone(),
|
||||||
mesh_fs: pariter[1].clone(),
|
implicit_fs: pariter[1].clone(),
|
||||||
|
|
||||||
implicit_ms: pariter[2].clone(),
|
|
||||||
implicit_ts: pariter[3].clone(),
|
|
||||||
implicit_fs: pariter[4].clone(),
|
|
||||||
|
|
||||||
compute_shader: pariter[5].clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
drop(pariter);
|
drop(pariter);
|
||||||
|
|
||||||
let compute_stage = PipelineShaderStageCreateInfo::new(
|
|
||||||
shader_modules.compute_shader.entry_point("main").unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
use vulkano::pipeline::ComputePipeline;
|
|
||||||
|
|
||||||
let compute_pipeline_layout = PipelineLayout::new(
|
|
||||||
self.device.clone(),
|
|
||||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([&compute_stage])
|
|
||||||
.into_pipeline_layout_create_info(self.device.clone())
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
trace!(
|
|
||||||
"descriptor set: {:?}",
|
|
||||||
compute_pipeline_layout.set_layouts()
|
|
||||||
);
|
|
||||||
|
|
||||||
let compute_pipeline = ComputePipeline::new(
|
|
||||||
self.device.clone(),
|
|
||||||
None,
|
|
||||||
ComputePipelineCreateInfo::stage_layout(compute_stage, compute_pipeline_layout.clone()),
|
|
||||||
)
|
|
||||||
.expect("failed to create compute pipeline");
|
|
||||||
|
|
||||||
let render_pass = if MSAA_ENABLE {
|
let render_pass = if MSAA_ENABLE {
|
||||||
vulkano::ordered_passes_renderpass!(
|
vulkano::ordered_passes_renderpass!(
|
||||||
self.device.clone(),
|
self.device.clone(),
|
||||||
@@ -755,13 +673,6 @@ impl ApplicationHandler for App {
|
|||||||
}
|
}
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (subbuffers, scene) = object_size_dependent_setup(
|
|
||||||
self.memory_allocator.clone(),
|
|
||||||
&self.gstate.csg,
|
|
||||||
self.command_buffer_allocator.clone(),
|
|
||||||
self.transfer_queue.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
offset: [0.0, window_size.height as f32],
|
offset: [0.0, window_size.height as f32],
|
||||||
extent: [window_size.width as f32, window_size.height as f32 * -1.],
|
extent: [window_size.width as f32, window_size.height as f32 * -1.],
|
||||||
@@ -770,12 +681,11 @@ impl ApplicationHandler for App {
|
|||||||
|
|
||||||
let framebuffers = framebuffer_generation(&images, &render_pass, &self.memory_allocator);
|
let framebuffers = framebuffer_generation(&images, &render_pass, &self.memory_allocator);
|
||||||
|
|
||||||
let (mesh_pipeline, implicit_pipeline) = pipeline_recompile(
|
let implicit_pipeline = pipeline_recompile(
|
||||||
&render_pass,
|
&render_pass,
|
||||||
&self.pipeline_cache,
|
&self.pipeline_cache,
|
||||||
&shader_modules,
|
&shader_modules,
|
||||||
&self.gstate.debug,
|
&self.gstate.debug,
|
||||||
&scene,
|
|
||||||
if DYNAMIC_STATE { None } else { Some(&viewport) },
|
if DYNAMIC_STATE { None } else { Some(&viewport) },
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -801,8 +711,6 @@ impl ApplicationHandler for App {
|
|||||||
render_pass,
|
render_pass,
|
||||||
framebuffers,
|
framebuffers,
|
||||||
shader_modules,
|
shader_modules,
|
||||||
compute_pipeline,
|
|
||||||
mesh_pipeline,
|
|
||||||
implicit_pipeline,
|
implicit_pipeline,
|
||||||
viewport,
|
viewport,
|
||||||
recreate_swapchain: false,
|
recreate_swapchain: false,
|
||||||
@@ -810,8 +718,6 @@ impl ApplicationHandler for App {
|
|||||||
previous_frame_end,
|
previous_frame_end,
|
||||||
gui,
|
gui,
|
||||||
render_start: Instant::now(),
|
render_start: Instant::now(),
|
||||||
subbuffers,
|
|
||||||
scene,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,6 +792,9 @@ impl ApplicationHandler for App {
|
|||||||
PhysicalKey::Code(KeyCode::KeyD) => {
|
PhysicalKey::Code(KeyCode::KeyD) => {
|
||||||
self.cstate.keys.d = input.state == ElementState::Pressed;
|
self.cstate.keys.d = input.state == ElementState::Pressed;
|
||||||
},
|
},
|
||||||
|
PhysicalKey::Code(KeyCode::ShiftLeft) => {
|
||||||
|
self.cstate.looking = input.state == ElementState::Pressed;
|
||||||
|
}
|
||||||
_ => {},
|
_ => {},
|
||||||
},
|
},
|
||||||
WindowEvent::RedrawRequested => {
|
WindowEvent::RedrawRequested => {
|
||||||
@@ -949,12 +858,11 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rcx.recreate_pipelines {
|
if rcx.recreate_pipelines {
|
||||||
(rcx.mesh_pipeline, rcx.implicit_pipeline) = pipeline_recompile(
|
rcx.implicit_pipeline = pipeline_recompile(
|
||||||
&rcx.render_pass,
|
&rcx.render_pass,
|
||||||
&self.pipeline_cache,
|
&self.pipeline_cache,
|
||||||
&rcx.shader_modules,
|
&rcx.shader_modules,
|
||||||
&self.gstate.debug,
|
&self.gstate.debug,
|
||||||
&rcx.scene,
|
|
||||||
if DYNAMIC_STATE {
|
if DYNAMIC_STATE {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@@ -1016,11 +924,11 @@ impl App {
|
|||||||
//* Mat4::from_rotation_z(std::f32::consts::PI)
|
//* Mat4::from_rotation_z(std::f32::consts::PI)
|
||||||
* Mat4::from_translation(Vec3::ZERO - self.cstate.position);
|
* Mat4::from_translation(Vec3::ZERO - self.cstate.position);
|
||||||
|
|
||||||
let pc = mesh_vs::PushConstantData {
|
let pc = implicit_vs::PushConstantData {
|
||||||
world: Mat4::IDENTITY.to_cols_array_2d(),
|
world: Mat4::IDENTITY.to_cols_array_2d(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let uniform_data = implicit_fs::Camera {
|
let uniform_data = implicit_vs::Camera {
|
||||||
view: view.to_cols_array_2d(),
|
view: view.to_cols_array_2d(),
|
||||||
proj: proj.to_cols_array_2d(),
|
proj: proj.to_cols_array_2d(),
|
||||||
campos: self.cstate.position.to_array(),
|
campos: self.cstate.position.to_array(),
|
||||||
@@ -1052,7 +960,7 @@ impl App {
|
|||||||
col[i][2] = light.colour.z;
|
col[i][2] = light.colour.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
let uniform_data = mesh_fs::Lights {
|
let uniform_data = implicit_vs::Lights {
|
||||||
pos,
|
pos,
|
||||||
col,
|
col,
|
||||||
light_count: self.gstate.lights.len() as u32,
|
light_count: self.gstate.lights.len() as u32,
|
||||||
@@ -1063,10 +971,10 @@ impl App {
|
|||||||
sub
|
sub
|
||||||
};
|
};
|
||||||
|
|
||||||
let mesh_layout = &rcx.mesh_pipeline.layout().set_layouts()[0];
|
let implicit_layout = &rcx.implicit_pipeline.layout().set_layouts()[0];
|
||||||
let mesh_set = DescriptorSet::new(
|
let implicit_set = DescriptorSet::new(
|
||||||
self.descriptor_set_allocator.clone(),
|
self.descriptor_set_allocator.clone(),
|
||||||
mesh_layout.clone(),
|
implicit_layout.clone(),
|
||||||
[
|
[
|
||||||
WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()),
|
WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()),
|
||||||
WriteDescriptorSet::buffer(1, cam_set.clone()),
|
WriteDescriptorSet::buffer(1, cam_set.clone()),
|
||||||
@@ -1075,133 +983,6 @@ impl App {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let implicit_layout = &rcx.implicit_pipeline.layout().set_layouts()[0];
|
|
||||||
let implicit_set = DescriptorSet::new(
|
|
||||||
self.descriptor_set_allocator.clone(),
|
|
||||||
implicit_layout.clone(),
|
|
||||||
[
|
|
||||||
WriteDescriptorSet::buffer(0, rcx.subbuffers.desc.clone()),
|
|
||||||
WriteDescriptorSet::buffer(1, rcx.subbuffers.scene.clone()),
|
|
||||||
WriteDescriptorSet::buffer(2, rcx.subbuffers.masks.clone()),
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if COMPUTE_FUZZING {
|
|
||||||
let (compute_subbuffers, scene) = object_size_dependent_setup(
|
|
||||||
self.memory_allocator.clone(),
|
|
||||||
&self.gstate.csg,
|
|
||||||
self.command_buffer_allocator.clone(),
|
|
||||||
self.transfer_queue.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let compute_result_buffer: Subbuffer<[cs::Results]> = self
|
|
||||||
.uniform_buffer_allocator
|
|
||||||
.allocate_slice((scene.len() * 4) as u64)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
const EXECUTION_LIMIT: u32 = 900;
|
|
||||||
const STATIC_OPCODES: u32 = 901;
|
|
||||||
|
|
||||||
let mut spec_constants = HashMap::with_capacity(32);
|
|
||||||
|
|
||||||
spec_constants.insert(STATIC_OPCODES, SpecializationConstant::Bool(true));
|
|
||||||
spec_constants.insert(
|
|
||||||
EXECUTION_LIMIT,
|
|
||||||
SpecializationConstant::U32((scene.len() * 4) as u32),
|
|
||||||
);
|
|
||||||
for (i, val) in scene.iter().skip(1).take(32).enumerate() {
|
|
||||||
for (y, code) in val.iter().enumerate() {
|
|
||||||
spec_constants.insert(
|
|
||||||
(1000 + (i * 8) + (y * 2)) as u32,
|
|
||||||
SpecializationConstant::U32(code & 0xFFFF),
|
|
||||||
);
|
|
||||||
spec_constants.insert(
|
|
||||||
(1000 + (i * 8) + (y * 2) + 1) as u32,
|
|
||||||
SpecializationConstant::U32(code >> 16),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let compute_stage = PipelineShaderStageCreateInfo::new(
|
|
||||||
rcx.shader_modules
|
|
||||||
.compute_shader
|
|
||||||
.specialize(spec_constants)
|
|
||||||
.unwrap()
|
|
||||||
.single_entry_point()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
use vulkano::pipeline::ComputePipeline;
|
|
||||||
|
|
||||||
let compute_pipeline_layout = PipelineLayout::new(
|
|
||||||
self.device.clone(),
|
|
||||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([&compute_stage])
|
|
||||||
.into_pipeline_layout_create_info(self.device.clone())
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let compute_pipeline = ComputePipeline::new(
|
|
||||||
self.device.clone(),
|
|
||||||
None,
|
|
||||||
ComputePipelineCreateInfo::stage_layout(
|
|
||||||
compute_stage,
|
|
||||||
compute_pipeline_layout.clone(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("failed to create compute pipeline");
|
|
||||||
|
|
||||||
let compute_layout = &compute_pipeline.layout().set_layouts()[0];
|
|
||||||
let compute_set = DescriptorSet::new(
|
|
||||||
self.descriptor_set_allocator.clone(),
|
|
||||||
compute_layout.clone(),
|
|
||||||
[
|
|
||||||
WriteDescriptorSet::buffer(0, compute_subbuffers.desc.clone()),
|
|
||||||
WriteDescriptorSet::buffer(1, compute_subbuffers.scene.clone()),
|
|
||||||
WriteDescriptorSet::buffer(30, compute_result_buffer.clone()),
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
|
||||||
self.command_buffer_allocator.clone(),
|
|
||||||
self.graphics_queue.queue_family_index(),
|
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
builder
|
|
||||||
.bind_pipeline_compute(compute_pipeline.clone())
|
|
||||||
.unwrap()
|
|
||||||
.bind_descriptor_sets(
|
|
||||||
PipelineBindPoint::Compute,
|
|
||||||
compute_pipeline.layout().clone(),
|
|
||||||
1,
|
|
||||||
compute_set,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
unsafe { builder.dispatch([1, 1, 1]) }.unwrap();
|
|
||||||
|
|
||||||
let command_buffer = builder.build().unwrap();
|
|
||||||
|
|
||||||
let future = sync::now(self.device.clone())
|
|
||||||
.then_execute(self.graphics_queue.clone(), command_buffer)
|
|
||||||
.unwrap()
|
|
||||||
.then_signal_fence_and_flush()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
future.wait(None).unwrap();
|
|
||||||
|
|
||||||
let content = compute_result_buffer.read().unwrap();
|
|
||||||
for val in content.iter() {
|
|
||||||
trace!("{val:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (image_index, suboptimal, acquire_future) =
|
let (image_index, suboptimal, acquire_future) =
|
||||||
match acquire_next_image(rcx.swapchain.clone(), None).map_err(Validated::unwrap) {
|
match acquire_next_image(rcx.swapchain.clone(), None).map_err(Validated::unwrap) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
@@ -1258,37 +1039,6 @@ impl App {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder
|
|
||||||
.bind_pipeline_graphics(rcx.mesh_pipeline.clone())
|
|
||||||
.unwrap()
|
|
||||||
.bind_descriptor_sets(
|
|
||||||
PipelineBindPoint::Graphics,
|
|
||||||
rcx.mesh_pipeline.layout().clone(),
|
|
||||||
0,
|
|
||||||
mesh_set.clone(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for object in &self.gstate.meshes {
|
|
||||||
push_constants.world = (Mat4::from_translation(object.pos * 0.01)
|
|
||||||
* Mat4::from_euler(
|
|
||||||
EulerRot::XYZ,
|
|
||||||
object.rot.x.to_radians(),
|
|
||||||
object.rot.y.to_radians(),
|
|
||||||
object.rot.z.to_radians(),
|
|
||||||
)
|
|
||||||
* Mat4::from_scale(object.scale))
|
|
||||||
.to_cols_array_2d();
|
|
||||||
builder
|
|
||||||
.bind_vertex_buffers(0, object.vertices.clone())
|
|
||||||
.unwrap()
|
|
||||||
.bind_index_buffer(object.indices.clone())
|
|
||||||
.unwrap()
|
|
||||||
.push_constants(rcx.mesh_pipeline.layout().clone(), 0, push_constants)
|
|
||||||
.unwrap();
|
|
||||||
unsafe { builder.draw_indexed(object.indices.len() as u32, 1, 0, 0, 0) }.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.bind_pipeline_graphics(rcx.implicit_pipeline.clone())
|
.bind_pipeline_graphics(rcx.implicit_pipeline.clone())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -1296,8 +1046,10 @@ impl App {
|
|||||||
PipelineBindPoint::Graphics,
|
PipelineBindPoint::Graphics,
|
||||||
rcx.implicit_pipeline.layout().clone(),
|
rcx.implicit_pipeline.layout().clone(),
|
||||||
0,
|
0,
|
||||||
(mesh_set, implicit_set),
|
implicit_set,
|
||||||
)
|
)
|
||||||
|
.unwrap()
|
||||||
|
.bind_vertex_buffers(0, self.vertex_buffer.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
for csg in &self.gstate.csg {
|
for csg in &self.gstate.csg {
|
||||||
@@ -1314,7 +1066,7 @@ impl App {
|
|||||||
.push_constants(rcx.implicit_pipeline.layout().clone(), 0, push_constants)
|
.push_constants(rcx.implicit_pipeline.layout().clone(), 0, push_constants)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
unsafe { builder.draw_mesh_tasks([1, 1, 2]) }.unwrap();
|
unsafe { builder.draw(VERTEX_COUNT as u32, (VERTEX_COUNT / 3) as u32, 0, 0) }.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder
|
builder
|
||||||
@@ -1444,9 +1196,8 @@ fn pipeline_recompile(
|
|||||||
cache: &Arc<PipelineCache>,
|
cache: &Arc<PipelineCache>,
|
||||||
shader_modules: &ShaderModules,
|
shader_modules: &ShaderModules,
|
||||||
debug: &PreviousDebug,
|
debug: &PreviousDebug,
|
||||||
scene: &[[u32; 4]],
|
|
||||||
viewport: Option<&Viewport>,
|
viewport: Option<&Viewport>,
|
||||||
) -> (Arc<GraphicsPipeline>, Arc<GraphicsPipeline>) {
|
) -> Arc<GraphicsPipeline> {
|
||||||
let device = cache.device();
|
let device = cache.device();
|
||||||
|
|
||||||
const SPEC_BOUNDING_BOXES: u32 = 0;
|
const SPEC_BOUNDING_BOXES: u32 = 0;
|
||||||
@@ -1456,9 +1207,6 @@ fn pipeline_recompile(
|
|||||||
const SPEC_DISABLE_TASKCULL: u32 = 4;
|
const SPEC_DISABLE_TASKCULL: u32 = 4;
|
||||||
const SPEC_BRUTE_FORCE: u32 = 5;
|
const SPEC_BRUTE_FORCE: u32 = 5;
|
||||||
|
|
||||||
const EXECUTION_LIMIT: u32 = 900;
|
|
||||||
const STATIC_OPCODES: u32 = 901;
|
|
||||||
|
|
||||||
let mut spec_constants = HashMap::with_capacity(6);
|
let mut spec_constants = HashMap::with_capacity(6);
|
||||||
spec_constants.insert(
|
spec_constants.insert(
|
||||||
SPEC_BOUNDING_BOXES,
|
SPEC_BOUNDING_BOXES,
|
||||||
@@ -1489,40 +1237,18 @@ fn pipeline_recompile(
|
|||||||
|
|
||||||
let specs = spec_constants;
|
let specs = spec_constants;
|
||||||
|
|
||||||
let mesh_vs_entry = shader_modules
|
let implicit_vs_entry = shader_modules
|
||||||
.mesh_vs
|
.implicit_vs
|
||||||
.specialize(specs.clone())
|
.specialize(specs.clone())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.single_entry_point()
|
.single_entry_point()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let vertex_input_state = [OVertex::per_vertex()].definition(&mesh_vs_entry).unwrap();
|
let vertex_input_state = [IVertex::per_vertex()]
|
||||||
|
.definition(&implicit_vs_entry)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mesh_vs_info = PipelineShaderStageCreateInfo::new(mesh_vs_entry);
|
let implicit_vs_info = PipelineShaderStageCreateInfo::new(implicit_vs_entry);
|
||||||
let mesh_fs_info = PipelineShaderStageCreateInfo::new(
|
|
||||||
shader_modules
|
|
||||||
.mesh_fs
|
|
||||||
.specialize(specs.clone())
|
|
||||||
.unwrap()
|
|
||||||
.single_entry_point()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
let implicit_ts_info = PipelineShaderStageCreateInfo::new(
|
|
||||||
shader_modules
|
|
||||||
.implicit_ts
|
|
||||||
.specialize(specs.clone())
|
|
||||||
.unwrap()
|
|
||||||
.single_entry_point()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
let implicit_ms_info = PipelineShaderStageCreateInfo::new(
|
|
||||||
shader_modules
|
|
||||||
.implicit_ms
|
|
||||||
.specialize(specs.clone())
|
|
||||||
.unwrap()
|
|
||||||
.single_entry_point()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
let implicit_fs_info = PipelineShaderStageCreateInfo::new(
|
let implicit_fs_info = PipelineShaderStageCreateInfo::new(
|
||||||
shader_modules
|
shader_modules
|
||||||
.implicit_fs
|
.implicit_fs
|
||||||
@@ -1534,15 +1260,9 @@ fn pipeline_recompile(
|
|||||||
|
|
||||||
let layout = PipelineLayout::new(
|
let layout = PipelineLayout::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([
|
PipelineDescriptorSetLayoutCreateInfo::from_stages([&implicit_vs_info, &implicit_fs_info])
|
||||||
&mesh_vs_info,
|
.into_pipeline_layout_create_info(device.clone())
|
||||||
&mesh_fs_info,
|
.unwrap(),
|
||||||
&implicit_ts_info,
|
|
||||||
&implicit_ms_info,
|
|
||||||
&implicit_fs_info,
|
|
||||||
])
|
|
||||||
.into_pipeline_layout_create_info(device.clone())
|
|
||||||
.unwrap(),
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1565,11 +1285,15 @@ fn pipeline_recompile(
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mesh_pipeline = {
|
info!("Recompiling implicit pipeline... (may take up to 10 minutes)");
|
||||||
let stages = [mesh_vs_info, mesh_fs_info].into_iter().collect();
|
|
||||||
|
|
||||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
let stages = [implicit_vs_info, implicit_fs_info].into_iter().collect();
|
||||||
|
|
||||||
|
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||||
|
|
||||||
|
let render_start = Instant::now();
|
||||||
|
|
||||||
|
let implicit_pipeline = {
|
||||||
GraphicsPipeline::new(
|
GraphicsPipeline::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
Some(cache.clone()),
|
Some(cache.clone()),
|
||||||
@@ -1577,57 +1301,11 @@ fn pipeline_recompile(
|
|||||||
stages,
|
stages,
|
||||||
vertex_input_state: Some(vertex_input_state),
|
vertex_input_state: Some(vertex_input_state),
|
||||||
input_assembly_state: Some(InputAssemblyState::default()),
|
input_assembly_state: Some(InputAssemblyState::default()),
|
||||||
dynamic_state: dynamic_state.clone(),
|
|
||||||
viewport_state: Some(viewport_state.clone()),
|
|
||||||
rasterization_state: Some(RasterizationState {
|
|
||||||
front_face: FrontFace::CounterClockwise,
|
|
||||||
cull_mode: CullMode::Back,
|
|
||||||
..RasterizationState::default()
|
|
||||||
}),
|
|
||||||
depth_stencil_state: Some(DepthStencilState {
|
|
||||||
depth: Some(DepthState::simple()),
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
multisample_state: Some(MultisampleState {
|
|
||||||
rasterization_samples: subpass.num_samples().unwrap(),
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
color_blend_state: Some(ColorBlendState::with_attachment_states(
|
|
||||||
subpass.num_color_attachments(),
|
|
||||||
ColorBlendAttachmentState::default(),
|
|
||||||
)),
|
|
||||||
subpass: Some(subpass.into()),
|
|
||||||
..GraphicsPipelineCreateInfo::layout(layout.clone())
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
info!("Recompiling implicit pipeline... (may take up to 10 minutes)");
|
|
||||||
|
|
||||||
let implicit_pipeline = {
|
|
||||||
let stages = if debug.brute_force {
|
|
||||||
[implicit_ms_info, implicit_fs_info].into_iter().collect()
|
|
||||||
} else {
|
|
||||||
[implicit_ts_info, implicit_ms_info, implicit_fs_info]
|
|
||||||
.into_iter()
|
|
||||||
.collect()
|
|
||||||
};
|
|
||||||
|
|
||||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
|
||||||
|
|
||||||
GraphicsPipeline::new(
|
|
||||||
device.clone(),
|
|
||||||
Some(cache.clone()),
|
|
||||||
GraphicsPipelineCreateInfo {
|
|
||||||
stages,
|
|
||||||
vertex_input_state: None,
|
|
||||||
input_assembly_state: None,
|
|
||||||
dynamic_state,
|
dynamic_state,
|
||||||
viewport_state: Some(viewport_state),
|
viewport_state: Some(viewport_state),
|
||||||
rasterization_state: Some(RasterizationState {
|
rasterization_state: Some(RasterizationState {
|
||||||
//front_face: Clockwise,
|
front_face: FrontFace::Clockwise,
|
||||||
//cull_mode: CullMode::Back,
|
cull_mode: CullMode::Back,
|
||||||
..RasterizationState::default()
|
..RasterizationState::default()
|
||||||
}),
|
}),
|
||||||
depth_stencil_state: Some(DepthStencilState {
|
depth_stencil_state: Some(DepthStencilState {
|
||||||
@@ -1650,17 +1328,17 @@ fn pipeline_recompile(
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let render_end = Instant::now();
|
||||||
|
|
||||||
info!("Implicit pipeline compiled");
|
info!("Implicit pipeline compiled");
|
||||||
|
info!(
|
||||||
|
"Implicit pipeline took {} milliseconds",
|
||||||
|
(render_end - render_start).as_secs_f64() * 1000.0
|
||||||
|
);
|
||||||
|
|
||||||
dump_pipeline_cache(cache.clone());
|
dump_pipeline_cache(cache.clone());
|
||||||
|
|
||||||
(mesh_pipeline, implicit_pipeline)
|
implicit_pipeline
|
||||||
}
|
|
||||||
|
|
||||||
struct Subbuffers {
|
|
||||||
masks: Subbuffer<[[u8; 500]]>,
|
|
||||||
scene: Subbuffer<[[u32; 4]]>,
|
|
||||||
desc: Subbuffer<[implicit_fs::Description]>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gpu_buffer<T>(
|
fn gpu_buffer<T>(
|
||||||
@@ -1722,140 +1400,6 @@ where
|
|||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn object_size_dependent_setup(
|
|
||||||
allocator: Arc<StandardMemoryAllocator>,
|
|
||||||
state: &Vec<CSG>,
|
|
||||||
command_allocator: Arc<StandardCommandBufferAllocator>,
|
|
||||||
queue: Arc<Queue>,
|
|
||||||
) -> (Subbuffers, Vec<[u32; 4]>) {
|
|
||||||
let mut scene: Vec<[u32; 4]> = vec![];
|
|
||||||
let mut desc: Vec<implicit_fs::Description> = vec![Default::default()];
|
|
||||||
|
|
||||||
for csg in state {
|
|
||||||
let tape = csg.parts.compile_to_gpu();
|
|
||||||
let tape2 = csg.parts.compile_to_spirv();
|
|
||||||
|
|
||||||
let mut description = implicit_fs::Description::default();
|
|
||||||
|
|
||||||
description.scene = (scene.len() / 4) as u32;
|
|
||||||
|
|
||||||
let chunks = tape.instructions.array_chunks::<16>();
|
|
||||||
for opcode in chunks.clone() {
|
|
||||||
scene.push(
|
|
||||||
opcode
|
|
||||||
.array_chunks::<4>()
|
|
||||||
.map(|smol| u32::from_le_bytes(*smol))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if chunks.remainder().len() > 0 {
|
|
||||||
let mut remainder = [0; 4];
|
|
||||||
for (i, item) in chunks.remainder().iter().enumerate() {
|
|
||||||
remainder[i / 4] |= (*item as u32) << ((i % 4) * 8);
|
|
||||||
}
|
|
||||||
scene.push(remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
description.io = (scene.len() / 4) as u32;
|
|
||||||
|
|
||||||
let chunks = tape.io.array_chunks::<16>();
|
|
||||||
for reg in chunks.clone() {
|
|
||||||
scene.push(
|
|
||||||
reg.array_chunks::<4>()
|
|
||||||
.map(|smol| u32::from_le_bytes(*smol))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if chunks.remainder().len() > 0 {
|
|
||||||
let mut remainder = [0; 4];
|
|
||||||
for (i, item) in chunks.remainder().iter().enumerate() {
|
|
||||||
remainder[i / 4] |= (*item as u32) << ((i % 4) * 8);
|
|
||||||
}
|
|
||||||
scene.push(remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
description.constants = (scene.len() / 4) as u32;
|
|
||||||
|
|
||||||
let chunks = tape.constants.array_chunks::<4>();
|
|
||||||
for reg in chunks.clone() {
|
|
||||||
scene.push(reg.map(|f| f.to_bits()));
|
|
||||||
}
|
|
||||||
if chunks.remainder().len() > 0 {
|
|
||||||
let mut remainder = [0; 4];
|
|
||||||
for (i, item) in chunks.remainder().iter().enumerate() {
|
|
||||||
remainder[i] = item.to_bits();
|
|
||||||
}
|
|
||||||
scene.push(remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut interpret = interpreter::Interpreter::new(csg);
|
|
||||||
description.bounds[0] = interpret.scene(vec3(-10000., 0., 0.)) - 10000.0;
|
|
||||||
description.bounds[1] = interpret.scene(vec3(0., -10000., 0.)) - 10000.0;
|
|
||||||
description.bounds[2] = interpret.scene(vec3(0., 0., -10000.)) - 10000.0;
|
|
||||||
description.bounds[3] = 10000.0 - interpret.scene(vec3(10000., 0., 0.));
|
|
||||||
description.bounds[4] = 10000.0 - interpret.scene(vec3(0., 10000., 0.));
|
|
||||||
description.bounds[5] = 10000.0 - interpret.scene(vec3(0., 0., 10000.));
|
|
||||||
|
|
||||||
desc.push(description);
|
|
||||||
}
|
|
||||||
|
|
||||||
trace!("scene: {scene:?}");
|
|
||||||
trace!("desc: {desc:?}");
|
|
||||||
|
|
||||||
let fragment_masks_buffer = Buffer::new_slice(
|
|
||||||
allocator.clone(),
|
|
||||||
BufferCreateInfo {
|
|
||||||
usage: BufferUsage::STORAGE_BUFFER,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
AllocationCreateInfo {
|
|
||||||
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE,
|
|
||||||
allocate_preference: MemoryAllocatePreference::AlwaysAllocate,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
((desc.len() - 1) * (4 * 4 * 4) * (4 * 4 * 2) * 500) as u64,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let staging = SubbufferAllocator::new(
|
|
||||||
allocator.clone(),
|
|
||||||
SubbufferAllocatorCreateInfo {
|
|
||||||
buffer_usage: BufferUsage::TRANSFER_SRC,
|
|
||||||
memory_type_filter: MemoryTypeFilter::PREFER_HOST
|
|
||||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let csg_scene = gpu_buffer(
|
|
||||||
&[&scene],
|
|
||||||
allocator.clone(),
|
|
||||||
&staging,
|
|
||||||
command_allocator.clone(),
|
|
||||||
queue.clone(),
|
|
||||||
);
|
|
||||||
let csg_desc = gpu_buffer(
|
|
||||||
&[&desc],
|
|
||||||
allocator.clone(),
|
|
||||||
&staging,
|
|
||||||
command_allocator.clone(),
|
|
||||||
queue.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
(
|
|
||||||
Subbuffers {
|
|
||||||
masks: fragment_masks_buffer,
|
|
||||||
scene: csg_scene,
|
|
||||||
desc: csg_desc,
|
|
||||||
},
|
|
||||||
scene,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dump_pipeline_cache(cache: Arc<PipelineCache>) {
|
fn dump_pipeline_cache(cache: Arc<PipelineCache>) {
|
||||||
if let Ok(data) = cache.get_data() {
|
if let Ok(data) = cache.get_data() {
|
||||||
info!("Dumping pipeline cache...");
|
info!("Dumping pipeline cache...");
|
||||||
|
|||||||
@@ -1,415 +0,0 @@
|
|||||||
#ifndef scene_bindings
|
|
||||||
#define scene_bindings
|
|
||||||
|
|
||||||
#include "spec_constants.glsl"
|
|
||||||
|
|
||||||
struct Description {
|
|
||||||
uint scene;
|
|
||||||
uint constants;
|
|
||||||
uint io;
|
|
||||||
float[6] bounds;
|
|
||||||
} desc;
|
|
||||||
|
|
||||||
layout(set = 1, binding = 0, std430) restrict readonly buffer SceneDescription {
|
|
||||||
Description desc[];
|
|
||||||
} scene_description;
|
|
||||||
|
|
||||||
layout(set = 1, binding = 1, std430) restrict readonly buffer SceneBuf {
|
|
||||||
u32vec4 data[];
|
|
||||||
} scenes;
|
|
||||||
|
|
||||||
#ifdef interval_frags
|
|
||||||
#define fragmentmasks_layout readonly
|
|
||||||
#else
|
|
||||||
#define fragmentmasks_layout // writeonly
|
|
||||||
#endif
|
|
||||||
|
|
||||||
layout(set = 1, binding = 2, std430) restrict fragmentmasks_layout buffer fragmentMasks {
|
|
||||||
uint16_t masks[][MASK_ARRAY_LENGTH];
|
|
||||||
} fragmentpassmasks;
|
|
||||||
|
|
||||||
// each mask:
|
|
||||||
// CCPP CCPP CCPP CCPP
|
|
||||||
// CC = how many constants to skip
|
|
||||||
// PP = which input to return: execute, do nothing, copy left, copy right
|
|
||||||
|
|
||||||
const uint16_t MASK_EXECUTE = uint16_t(0);
|
|
||||||
const uint16_t MASK_COPY_LEFT = uint16_t(1);
|
|
||||||
const uint16_t MASK_COPY_RIGHT = uint16_t(2);
|
|
||||||
const uint16_t MASK_DO_NOTHING = uint16_t(3);
|
|
||||||
uint16_t mask[MASK_ARRAY_LENGTH];
|
|
||||||
|
|
||||||
void default_mask()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MASK_ARRAY_LENGTH; i++) {
|
|
||||||
mask[i] = uint16_t(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// increments once for each opcode
|
|
||||||
uint program_counter = 0;
|
|
||||||
/// increments once for each nibble
|
|
||||||
uint io_counter = 0;
|
|
||||||
/// increments for each constant
|
|
||||||
uint const_counter = 0;
|
|
||||||
|
|
||||||
u32vec4 major_opcode_unpack;
|
|
||||||
u32vec4 major_io_unpack;
|
|
||||||
u32vec4 major_const_unpack;
|
|
||||||
|
|
||||||
float load_const(bool reverse) {
|
|
||||||
if ((reverse && ((const_counter % 4) == 3)) || (!reverse && ((const_counter % 4) == 0))) {
|
|
||||||
major_const_unpack = scenes.data[desc.constants + (const_counter / 4)];
|
|
||||||
}
|
|
||||||
switch (const_counter % 4) {
|
|
||||||
case 0:
|
|
||||||
return uintBitsToFloat(major_const_unpack.x);
|
|
||||||
case 1:
|
|
||||||
return uintBitsToFloat(major_const_unpack.y);
|
|
||||||
case 2:
|
|
||||||
return uintBitsToFloat(major_const_unpack.z);
|
|
||||||
case 3:
|
|
||||||
return uintBitsToFloat(major_const_unpack.w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t load_opcode(bool reverse) {
|
|
||||||
if ((reverse && ((program_counter % 16) == 15)) || (!reverse && ((program_counter % 16) == 0))) {
|
|
||||||
major_opcode_unpack = scenes.data[desc.scene + (program_counter / 16)];
|
|
||||||
}
|
|
||||||
switch (program_counter % 16) {
|
|
||||||
case 0:
|
|
||||||
return uint8_t((major_opcode_unpack.x >> 0) & 255);
|
|
||||||
case 1:
|
|
||||||
return uint8_t((major_opcode_unpack.x >> 8) & 255);
|
|
||||||
case 2:
|
|
||||||
return uint8_t((major_opcode_unpack.x >> 16) & 255);
|
|
||||||
case 3:
|
|
||||||
return uint8_t((major_opcode_unpack.x >> 24) & 255);
|
|
||||||
case 4:
|
|
||||||
return uint8_t((major_opcode_unpack.y >> 0) & 255);
|
|
||||||
case 5:
|
|
||||||
return uint8_t((major_opcode_unpack.y >> 8) & 255);
|
|
||||||
case 6:
|
|
||||||
return uint8_t((major_opcode_unpack.y >> 16) & 255);
|
|
||||||
case 7:
|
|
||||||
return uint8_t((major_opcode_unpack.y >> 24) & 255);
|
|
||||||
case 8:
|
|
||||||
return uint8_t((major_opcode_unpack.z >> 0) & 255);
|
|
||||||
case 9:
|
|
||||||
return uint8_t((major_opcode_unpack.z >> 8) & 255);
|
|
||||||
case 10:
|
|
||||||
return uint8_t((major_opcode_unpack.z >> 16) & 255);
|
|
||||||
case 11:
|
|
||||||
return uint8_t((major_opcode_unpack.z >> 24) & 255);
|
|
||||||
case 12:
|
|
||||||
return uint8_t((major_opcode_unpack.w >> 0) & 255);
|
|
||||||
case 13:
|
|
||||||
return uint8_t((major_opcode_unpack.w >> 8) & 255);
|
|
||||||
case 14:
|
|
||||||
return uint8_t((major_opcode_unpack.w >> 16) & 255);
|
|
||||||
case 15:
|
|
||||||
return uint8_t((major_opcode_unpack.w >> 24) & 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t load_input(bool reverse) {
|
|
||||||
if ((reverse && ((io_counter % 32) == 31)) || (!reverse && ((io_counter % 32) == 0))) {
|
|
||||||
major_io_unpack = scenes.data[desc.io + (io_counter / 32)];
|
|
||||||
}
|
|
||||||
switch (io_counter % 32) {
|
|
||||||
case 0:
|
|
||||||
return uint8_t((major_io_unpack.x >> 0) & 15);
|
|
||||||
case 1:
|
|
||||||
return uint8_t((major_io_unpack.x >> 4) & 15);
|
|
||||||
case 2:
|
|
||||||
return uint8_t((major_io_unpack.x >> 8) & 15);
|
|
||||||
case 3:
|
|
||||||
return uint8_t((major_io_unpack.x >> 12) & 15);
|
|
||||||
case 4:
|
|
||||||
return uint8_t((major_io_unpack.x >> 16) & 15);
|
|
||||||
case 5:
|
|
||||||
return uint8_t((major_io_unpack.x >> 20) & 15);
|
|
||||||
case 6:
|
|
||||||
return uint8_t((major_io_unpack.x >> 24) & 15);
|
|
||||||
case 7:
|
|
||||||
return uint8_t((major_io_unpack.x >> 28) & 15);
|
|
||||||
case 8:
|
|
||||||
return uint8_t((major_io_unpack.y >> 0) & 15);
|
|
||||||
case 9:
|
|
||||||
return uint8_t((major_io_unpack.y >> 4) & 15);
|
|
||||||
case 10:
|
|
||||||
return uint8_t((major_io_unpack.y >> 8) & 15);
|
|
||||||
case 11:
|
|
||||||
return uint8_t((major_io_unpack.y >> 12) & 15);
|
|
||||||
case 12:
|
|
||||||
return uint8_t((major_io_unpack.y >> 16) & 15);
|
|
||||||
case 13:
|
|
||||||
return uint8_t((major_io_unpack.y >> 20) & 15);
|
|
||||||
case 14:
|
|
||||||
return uint8_t((major_io_unpack.y >> 24) & 15);
|
|
||||||
case 15:
|
|
||||||
return uint8_t((major_io_unpack.y >> 28) & 15);
|
|
||||||
case 16:
|
|
||||||
return uint8_t((major_io_unpack.z >> 0) & 15);
|
|
||||||
case 17:
|
|
||||||
return uint8_t((major_io_unpack.z >> 4) & 15);
|
|
||||||
case 18:
|
|
||||||
return uint8_t((major_io_unpack.z >> 8) & 15);
|
|
||||||
case 19:
|
|
||||||
return uint8_t((major_io_unpack.z >> 12) & 15);
|
|
||||||
case 20:
|
|
||||||
return uint8_t((major_io_unpack.z >> 16) & 15);
|
|
||||||
case 21:
|
|
||||||
return uint8_t((major_io_unpack.z >> 20) & 15);
|
|
||||||
case 22:
|
|
||||||
return uint8_t((major_io_unpack.z >> 24) & 15);
|
|
||||||
case 23:
|
|
||||||
return uint8_t((major_io_unpack.z >> 28) & 15);
|
|
||||||
case 24:
|
|
||||||
return uint8_t((major_io_unpack.w >> 0) & 15);
|
|
||||||
case 25:
|
|
||||||
return uint8_t((major_io_unpack.w >> 4) & 15);
|
|
||||||
case 26:
|
|
||||||
return uint8_t((major_io_unpack.w >> 8) & 15);
|
|
||||||
case 27:
|
|
||||||
return uint8_t((major_io_unpack.w >> 12) & 15);
|
|
||||||
case 28:
|
|
||||||
return uint8_t((major_io_unpack.w >> 16) & 15);
|
|
||||||
case 29:
|
|
||||||
return uint8_t((major_io_unpack.w >> 20) & 15);
|
|
||||||
case 30:
|
|
||||||
return uint8_t((major_io_unpack.w >> 24) & 15);
|
|
||||||
case 31:
|
|
||||||
return uint8_t((major_io_unpack.w >> 28) & 15);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t prev_opcode() {
|
|
||||||
program_counter -= 1;
|
|
||||||
return load_opcode(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t next_opcode() {
|
|
||||||
uint8_t t = load_opcode(true);
|
|
||||||
program_counter += 1;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t prev_register() {
|
|
||||||
io_counter -= 1;
|
|
||||||
return load_input(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t next_register() {
|
|
||||||
uint8_t t = load_input(true);
|
|
||||||
io_counter += 1;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void jump_registers(uint dist) {
|
|
||||||
bool reload_cache = (io_counter / 32) != ((io_counter + dist) / 32);
|
|
||||||
io_counter += dist;
|
|
||||||
if (reload_cache) {
|
|
||||||
major_io_unpack = scenes.data[desc.io + (io_counter / 32)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float prev_const() {
|
|
||||||
const_counter -= 1;
|
|
||||||
return load_const(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
float next_const() {
|
|
||||||
float t = load_const(true);
|
|
||||||
const_counter += 1;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void jump_const(uint dist) {
|
|
||||||
bool reload_cache = (const_counter / 4) != ((const_counter + dist) / 4);
|
|
||||||
const_counter += dist;
|
|
||||||
if (reload_cache) {
|
|
||||||
major_const_unpack = scenes.data[desc.constants + (const_counter / 4)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define unroll_instruction_set(index, name) \
|
|
||||||
const uint8_t OPCopy##name = uint8_t(OPCopy+(index<<6));\
|
|
||||||
const uint8_t OPAdd##name = uint8_t(OPAdd+(index<<6));\
|
|
||||||
const uint8_t OPSub##name = uint8_t(OPSub+(index<<6));\
|
|
||||||
const uint8_t OPMul##name = uint8_t(OPMul+(index<<6));\
|
|
||||||
const uint8_t OPDiv##name = uint8_t(OPDiv+(index<<6));\
|
|
||||||
const uint8_t OPAtan2##name = uint8_t(OPAtan2+(index<<6));\
|
|
||||||
const uint8_t OPMin##name = uint8_t(OPMin+(index<<6));\
|
|
||||||
const uint8_t OPMax##name = uint8_t(OPMax+(index<<6));\
|
|
||||||
const uint8_t OPCompare##name = uint8_t(OPCompare+(index<<6));\
|
|
||||||
const uint8_t OPMod##name = uint8_t(OPMod+(index<<6));\
|
|
||||||
const uint8_t OPAnd##name = uint8_t(OPAnd+(index<<6));\
|
|
||||||
const uint8_t OPOr##name = uint8_t(OPOr+(index<<6));\
|
|
||||||
const uint8_t OPNegate##name = uint8_t(OPNegate+(index<<6));\
|
|
||||||
const uint8_t OPAbs##name = uint8_t(OPAbs+(index<<6));\
|
|
||||||
const uint8_t OPRecip##name = uint8_t(OPRecip+(index<<6));\
|
|
||||||
const uint8_t OPSqrt##name = uint8_t(OPSqrt+(index<<6));\
|
|
||||||
const uint8_t OPSquare##name = uint8_t(OPSquare+(index<<6));\
|
|
||||||
const uint8_t OPFloor##name = uint8_t(OPFloor+(index<<6));\
|
|
||||||
const uint8_t OPCeil##name = uint8_t(OPCeil+(index<<6));\
|
|
||||||
const uint8_t OPRound##name = uint8_t(OPRound+(index<<6));\
|
|
||||||
const uint8_t OPSin##name = uint8_t(OPSin+(index<<6));\
|
|
||||||
const uint8_t OPCos##name = uint8_t(OPCos+(index<<6));\
|
|
||||||
const uint8_t OPTan##name = uint8_t(OPTan+(index<<6));\
|
|
||||||
const uint8_t OPAsin##name = uint8_t(OPAsin+(index<<6));\
|
|
||||||
const uint8_t OPAcos##name = uint8_t(OPAcos+(index<<6));\
|
|
||||||
const uint8_t OPAtan##name = uint8_t(OPAtan+(index<<6));\
|
|
||||||
const uint8_t OPExp##name = uint8_t(OPExp+(index<<6));\
|
|
||||||
const uint8_t OPLog##name = uint8_t(OPLog+(index<<6));\
|
|
||||||
const uint8_t OPNot##name = uint8_t(OPNot+(index<<6));\
|
|
||||||
const uint8_t OPFract##name = uint8_t(OPFract+(index<<6));\
|
|
||||||
const uint8_t OPCube##name = uint8_t(OPCube+(index<<6));\
|
|
||||||
const uint8_t OPSmoothMin##name = uint8_t(OPSmoothMin+(index<<6));\
|
|
||||||
const uint8_t OPSmoothMax##name = uint8_t(OPSmoothMax+(index<<6));\
|
|
||||||
const uint8_t OPClamp##name = uint8_t(OPClamp+(index<<6));\
|
|
||||||
const uint8_t OPMix##name = uint8_t(OPMix+(index<<6));\
|
|
||||||
const uint8_t OPFMA##name = uint8_t(OPFMA+(index<<6));\
|
|
||||||
const uint8_t OPLength##name = uint8_t(OPLength+(index<<6));\
|
|
||||||
const uint8_t OPNormalize##name = uint8_t(OPNormalize+(index<<6)); \
|
|
||||||
const uint8_t OPDot##name = uint8_t(OPDot+(index<<6));\
|
|
||||||
const uint8_t OPDistance##name = uint8_t(OPDistance+(index<<6));\
|
|
||||||
|
|
||||||
unroll_instruction_set(0, Vec1)
|
|
||||||
unroll_instruction_set(1, Vec2)
|
|
||||||
unroll_instruction_set(2, Vec3)
|
|
||||||
unroll_instruction_set(3, Vec4)
|
|
||||||
|
|
||||||
uint reg_output(uint8_t opcode) {
|
|
||||||
switch (uint(opcode)) {
|
|
||||||
case OPNop:
|
|
||||||
return 0;
|
|
||||||
case OPReturn:
|
|
||||||
return 0;
|
|
||||||
case OPPosition:
|
|
||||||
return 3;
|
|
||||||
case OPMinMaterial:
|
|
||||||
return 1;
|
|
||||||
case OPMaxMaterial:
|
|
||||||
return 1;
|
|
||||||
case OPSmoothMinMaterial:
|
|
||||||
return 1;
|
|
||||||
case OPSmoothMaxMaterial:
|
|
||||||
return 1;
|
|
||||||
case OPCross:
|
|
||||||
return 3;
|
|
||||||
case OPDistance:
|
|
||||||
return 1;
|
|
||||||
case OPLength:
|
|
||||||
return 1;
|
|
||||||
case OPDot:
|
|
||||||
return 1;
|
|
||||||
case OPSDFSphere:
|
|
||||||
return 1;
|
|
||||||
case OPSDFBox:
|
|
||||||
return 1;
|
|
||||||
case OPSDFTorus:
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return (opcode >> 6) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint reg_input(uint8_t opcode) {
|
|
||||||
switch (uint(opcode)) {
|
|
||||||
case OPNop:
|
|
||||||
return 0;
|
|
||||||
case OPReturn:
|
|
||||||
return 1;
|
|
||||||
case OPPosition:
|
|
||||||
return 0;
|
|
||||||
case OPMinMaterial:
|
|
||||||
return 2;
|
|
||||||
case OPMaxMaterial:
|
|
||||||
return 2;
|
|
||||||
case OPSmoothMinMaterial:
|
|
||||||
return 3;
|
|
||||||
case OPSmoothMaxMaterial:
|
|
||||||
return 3;
|
|
||||||
case OPCross:
|
|
||||||
return 3 + 3;
|
|
||||||
case OPSDFSphere:
|
|
||||||
return 3 + 1;
|
|
||||||
case OPSDFBox:
|
|
||||||
return 3 + 3;
|
|
||||||
case OPSDFTorus:
|
|
||||||
return 3 + 2;
|
|
||||||
|
|
||||||
case OPAdd:
|
|
||||||
case OPSub:
|
|
||||||
case OPMul:
|
|
||||||
case OPDiv:
|
|
||||||
case OPAtan2:
|
|
||||||
case OPMin:
|
|
||||||
case OPMax:
|
|
||||||
case OPCompare:
|
|
||||||
case OPMod:
|
|
||||||
case OPAnd:
|
|
||||||
case OPOr:
|
|
||||||
case OPDot:
|
|
||||||
case OPDistance:
|
|
||||||
return ((opcode >> 6) + 1) * 2;
|
|
||||||
|
|
||||||
case OPSmoothMin:
|
|
||||||
case OPSmoothMax:
|
|
||||||
case OPClamp:
|
|
||||||
case OPMix:
|
|
||||||
case OPFMA:
|
|
||||||
return ((opcode >> 6) + 1) * 3;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ((opcode >> 6) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint[2] reg_elementwise(uint8_t opcode) {
|
|
||||||
switch (uint(opcode)) {
|
|
||||||
case OPNop:
|
|
||||||
case OPReturn:
|
|
||||||
case OPPosition:
|
|
||||||
case OPMinMaterial:
|
|
||||||
case OPMaxMaterial:
|
|
||||||
case OPSmoothMinMaterial:
|
|
||||||
case OPSmoothMaxMaterial:
|
|
||||||
case OPCross:
|
|
||||||
case OPSDFSphere:
|
|
||||||
case OPSDFBox:
|
|
||||||
case OPSDFTorus:
|
|
||||||
case OPDot:
|
|
||||||
case OPDistance:
|
|
||||||
case OPLength:
|
|
||||||
case OPNormalize:
|
|
||||||
return uint[2](0, 0);
|
|
||||||
|
|
||||||
case OPAdd:
|
|
||||||
case OPSub:
|
|
||||||
case OPMul:
|
|
||||||
case OPDiv:
|
|
||||||
case OPAtan2:
|
|
||||||
case OPMin:
|
|
||||||
case OPCompare:
|
|
||||||
case OPMod:
|
|
||||||
case OPAnd:
|
|
||||||
case OPOr:
|
|
||||||
return uint[2](2, 1);
|
|
||||||
|
|
||||||
case OPSmoothMin:
|
|
||||||
case OPSmoothMax:
|
|
||||||
case OPClamp:
|
|
||||||
case OPMix:
|
|
||||||
case OPFMA:
|
|
||||||
return uint[2](3, 1);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return uint[2](1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef spec_constants
|
|
||||||
#define spec_constants
|
|
||||||
|
|
||||||
layout(constant_id = 0) const bool BOUNDING_BOXES = false;
|
|
||||||
layout(constant_id = 1) const bool DISABLE_MESHCULL = false;
|
|
||||||
layout(constant_id = 2) const bool DISABLE_MESHSCALING1 = false;
|
|
||||||
layout(constant_id = 3) const bool DISABLE_MESHSCALING2 = false;
|
|
||||||
layout(constant_id = 4) const bool DISABLE_TASKCULL = false;
|
|
||||||
layout(constant_id = 5) const bool BRUTE_FORCE = false;
|
|
||||||
const uint MASK_ARRAY_LENGTH = 500;
|
|
||||||
layout(constant_id = 7) const uint EXECUTION_LIMIT = 500;
|
|
||||||
|
|
||||||
//#include "static_opcode_array.glsl"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
// global fragment shader
|
||||||
|
|
||||||
|
#version 460
|
||||||
|
#extension GL_GOOGLE_include_directive:require
|
||||||
|
#include "include.glsl"
|
||||||
|
|
||||||
|
layout(location = 1) in vec4 pos;
|
||||||
|
|
||||||
|
layout(depth_greater) out float gl_FragDepth;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 f_color;
|
||||||
|
|
||||||
|
/// SHARED CODE ///
|
||||||
|
vec3 shading(vec3 normal, vec4 position)
|
||||||
|
{
|
||||||
|
vec3 accum = vec3(0., 0., 0.);
|
||||||
|
mat3 rotation = mat3(pc.world[0].xyz, pc.world[1].xyz, pc.world[2].xyz);
|
||||||
|
//vec3 position=pc.world[3].xyz;
|
||||||
|
|
||||||
|
for (int i = 0; (i < light_uniforms.light_count) && (i < 32); i++)
|
||||||
|
{
|
||||||
|
accum += light_uniforms.col[i].xyz * ((dot(normalize(rotation * normal), normalize(light_uniforms.pos[i].xyz - position.xyz)) * .5) + .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scene(vec3 p) {
|
||||||
|
return length(p) - 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float EPSILON = .0001;
|
||||||
|
const uint MAX_STEPS = 50;
|
||||||
|
#define NEARPLANE 0.
|
||||||
|
float FARPLANE;
|
||||||
|
#define gl_GlobalInvocationID uvec3(1)
|
||||||
|
|
||||||
|
vec3 getNormal(vec3 p, float dens) {
|
||||||
|
vec3 n;
|
||||||
|
n.x = scene(vec3(p.x + EPSILON, p.y, p.z)).x;
|
||||||
|
n.y = scene(vec3(p.x, p.y + EPSILON, p.z)).x;
|
||||||
|
n.z = scene(vec3(p.x, p.y, p.z + EPSILON)).x;
|
||||||
|
return normalize(n - (scene(p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 spheretracing(vec3 ori, vec3 dir, out vec3 p) {
|
||||||
|
vec2 td = vec2(NEARPLANE, 1.);
|
||||||
|
p = ori;
|
||||||
|
td.y = scene(p).x * .9;
|
||||||
|
td.x += td.y;
|
||||||
|
p = ori + dir * td.x;
|
||||||
|
for (int i = 0; i < MAX_STEPS && td.y > EPSILON && td.x < FARPLANE; i++) {
|
||||||
|
td.y = scene(p).x * .9;
|
||||||
|
td.x += td.y;
|
||||||
|
p = ori + dir * td.x;
|
||||||
|
}
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Implicit Surface Entrypoint
|
||||||
|
void main() {
|
||||||
|
vec3 raypos = pos.xyz;
|
||||||
|
|
||||||
|
vec3 p;
|
||||||
|
vec3 raydir = normalize(raypos - (inverse(pc.world) * vec4(camera_uniforms.campos, 1)).xyz);
|
||||||
|
|
||||||
|
vec2 td = spheretracing(raypos, raydir, p);
|
||||||
|
|
||||||
|
if (td.y < EPSILON)
|
||||||
|
{
|
||||||
|
vec3 n = getNormal(p, td.y);
|
||||||
|
//f_color=vec4(1.);
|
||||||
|
f_color = vec4(shading(n, inverse(pc.world) * vec4(p, 1.)), 1.);
|
||||||
|
|
||||||
|
vec4 tpoint = camera_uniforms.proj * camera_uniforms.view * pc.world * vec4(p, 1);
|
||||||
|
gl_FragDepth = (tpoint.z / tpoint.w);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_color = vec4(1.0, 0.0, 1.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user