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"
|
||||
|
||||
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;
|
||||
|
||||
void main(){
|
||||
mat4 worldview=camera_uniforms.view*pc.world;
|
||||
v_normal=normal;//normalize(transpose(inverse(mat3(worldview))) * normal);
|
||||
pos = worldview*vec4(position,1.);
|
||||
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.
|
||||
|
||||
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 COMPUTE_FUZZING: bool = false;
|
||||
const MSAA_ENABLE: bool = false;
|
||||
const MSAA_SAMPLES: u32 = 4;
|
||||
const SAMPLE_RATE_SHADING: f32 = 1.0;
|
||||
|
||||
const MSAA_SAMPLES_ACTUAL: u32 = if MSAA_ENABLE { MSAA_SAMPLES } else { 1 };
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use egui_winit_vulkano::{Gui, GuiConfig};
|
||||
use foldhash::{HashMap, HashMapExt, HashSet};
|
||||
use glam::{self, EulerRot, Mat3, Mat4, Vec3, vec3};
|
||||
use log::{error, info, trace};
|
||||
use rayon::prelude::*;
|
||||
use rspirv::binary::Disassemble;
|
||||
use simplelog::{CombinedLogger, Config, TermLogger, WriteLogger};
|
||||
use ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape};
|
||||
use vulkano::{
|
||||
@@ -51,10 +50,9 @@ use vulkano::{
|
||||
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
|
||||
},
|
||||
pipeline::{
|
||||
ComputePipeline, DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
PipelineLayout, PipelineShaderStageCreateInfo,
|
||||
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
|
||||
PipelineShaderStageCreateInfo,
|
||||
cache::{PipelineCache, PipelineCacheCreateInfo},
|
||||
compute::ComputePipelineCreateInfo,
|
||||
graphics::{
|
||||
GraphicsPipelineCreateInfo,
|
||||
color_blend::{ColorBlendAttachmentState, ColorBlendState},
|
||||
@@ -90,11 +88,7 @@ use crate::objects::*;
|
||||
|
||||
mod ssa;
|
||||
|
||||
mod instruction_set {
|
||||
include!(concat!(env!("OUT_DIR"), "/instructionset.rs"));
|
||||
}
|
||||
|
||||
use crate::instruction_set::InstructionSet;
|
||||
mod instruction_set;
|
||||
|
||||
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 {
|
||||
instance: Arc<Instance>,
|
||||
device: Arc<Device>,
|
||||
@@ -163,16 +182,13 @@ struct App {
|
||||
gstate: GState,
|
||||
previous_debug: PreviousDebug,
|
||||
cstate: CState,
|
||||
vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]>,
|
||||
rcx: Option<RenderContext>,
|
||||
}
|
||||
|
||||
struct ShaderModules {
|
||||
mesh_vs: Arc<ShaderModule>,
|
||||
mesh_fs: Arc<ShaderModule>,
|
||||
implicit_ts: Arc<ShaderModule>,
|
||||
implicit_ms: Arc<ShaderModule>,
|
||||
implicit_fs: Arc<ShaderModule>,
|
||||
compute_shader: Arc<ShaderModule>,
|
||||
implicit_vs: Arc<ShaderModule>,
|
||||
implicit_fs: Arc<ShaderModule>,
|
||||
}
|
||||
|
||||
struct RenderContext {
|
||||
@@ -181,8 +197,6 @@ struct RenderContext {
|
||||
render_pass: Arc<RenderPass>,
|
||||
framebuffers: Vec<Arc<Framebuffer>>,
|
||||
shader_modules: ShaderModules,
|
||||
compute_pipeline: Arc<ComputePipeline>,
|
||||
mesh_pipeline: Arc<GraphicsPipeline>,
|
||||
implicit_pipeline: Arc<GraphicsPipeline>,
|
||||
viewport: Viewport,
|
||||
recreate_swapchain: bool,
|
||||
@@ -190,8 +204,6 @@ struct RenderContext {
|
||||
previous_frame_end: Option<Box<dyn GpuFuture>>,
|
||||
gui: Gui,
|
||||
render_start: Instant,
|
||||
subbuffers: Subbuffers,
|
||||
scene: Vec<[u32; 4]>,
|
||||
}
|
||||
|
||||
fn app_version() -> Version {
|
||||
@@ -344,7 +356,9 @@ impl App {
|
||||
let uniform_buffer_allocator = SubbufferAllocator::new(
|
||||
memory_allocator.clone(),
|
||||
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
|
||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||
..Default::default()
|
||||
@@ -437,6 +451,11 @@ impl App {
|
||||
.lights
|
||||
.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 {
|
||||
instance,
|
||||
device,
|
||||
@@ -450,46 +469,16 @@ impl App {
|
||||
gstate,
|
||||
previous_debug: PreviousDebug::default(),
|
||||
cstate,
|
||||
vertex_buffer,
|
||||
rcx: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod mesh_vs {
|
||||
mod implicit_vs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "vertex",
|
||||
path: "src/triangle.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",
|
||||
path: "src/implicit.vert.glsl",
|
||||
vulkan_version: "1.3",
|
||||
spirv_version: "1.6",
|
||||
custom_derives: [Debug, Clone, Copy],
|
||||
@@ -499,18 +488,7 @@ mod implicit_ts {
|
||||
mod implicit_fs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "fragment",
|
||||
path: "src/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",
|
||||
path: "src/trace.frag.glsl",
|
||||
vulkan_version: "1.3",
|
||||
spirv_version: "1.6",
|
||||
custom_derives: [Debug, Clone, Copy],
|
||||
@@ -603,28 +581,7 @@ impl ApplicationHandler for App {
|
||||
::vulkano::Validated<::vulkano::VulkanError>,
|
||||
>,
|
||||
> = vec![
|
||||
((mesh_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)
|
||||
((implicit_vs::load)
|
||||
as fn(
|
||||
::std::sync::Arc<::vulkano::device::Device>,
|
||||
) -> Result<
|
||||
@@ -638,13 +595,6 @@ impl ApplicationHandler for App {
|
||||
::std::sync::Arc<::vulkano::shader::ShaderModule>,
|
||||
::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
|
||||
@@ -653,44 +603,12 @@ impl ApplicationHandler for App {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let shader_modules = ShaderModules {
|
||||
mesh_vs: pariter[0].clone(),
|
||||
mesh_fs: pariter[1].clone(),
|
||||
|
||||
implicit_ms: pariter[2].clone(),
|
||||
implicit_ts: pariter[3].clone(),
|
||||
implicit_fs: pariter[4].clone(),
|
||||
|
||||
compute_shader: pariter[5].clone(),
|
||||
implicit_vs: pariter[0].clone(),
|
||||
implicit_fs: pariter[1].clone(),
|
||||
};
|
||||
|
||||
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 {
|
||||
vulkano::ordered_passes_renderpass!(
|
||||
self.device.clone(),
|
||||
@@ -755,13 +673,6 @@ impl ApplicationHandler for App {
|
||||
}
|
||||
.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 {
|
||||
offset: [0.0, window_size.height as f32],
|
||||
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 (mesh_pipeline, implicit_pipeline) = pipeline_recompile(
|
||||
let implicit_pipeline = pipeline_recompile(
|
||||
&render_pass,
|
||||
&self.pipeline_cache,
|
||||
&shader_modules,
|
||||
&self.gstate.debug,
|
||||
&scene,
|
||||
if DYNAMIC_STATE { None } else { Some(&viewport) },
|
||||
);
|
||||
|
||||
@@ -801,8 +711,6 @@ impl ApplicationHandler for App {
|
||||
render_pass,
|
||||
framebuffers,
|
||||
shader_modules,
|
||||
compute_pipeline,
|
||||
mesh_pipeline,
|
||||
implicit_pipeline,
|
||||
viewport,
|
||||
recreate_swapchain: false,
|
||||
@@ -810,8 +718,6 @@ impl ApplicationHandler for App {
|
||||
previous_frame_end,
|
||||
gui,
|
||||
render_start: Instant::now(),
|
||||
subbuffers,
|
||||
scene,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -886,6 +792,9 @@ impl ApplicationHandler for App {
|
||||
PhysicalKey::Code(KeyCode::KeyD) => {
|
||||
self.cstate.keys.d = input.state == ElementState::Pressed;
|
||||
},
|
||||
PhysicalKey::Code(KeyCode::ShiftLeft) => {
|
||||
self.cstate.looking = input.state == ElementState::Pressed;
|
||||
}
|
||||
_ => {},
|
||||
},
|
||||
WindowEvent::RedrawRequested => {
|
||||
@@ -949,12 +858,11 @@ impl App {
|
||||
}
|
||||
|
||||
if rcx.recreate_pipelines {
|
||||
(rcx.mesh_pipeline, rcx.implicit_pipeline) = pipeline_recompile(
|
||||
rcx.implicit_pipeline = pipeline_recompile(
|
||||
&rcx.render_pass,
|
||||
&self.pipeline_cache,
|
||||
&rcx.shader_modules,
|
||||
&self.gstate.debug,
|
||||
&rcx.scene,
|
||||
if DYNAMIC_STATE {
|
||||
None
|
||||
} else {
|
||||
@@ -1016,11 +924,11 @@ impl App {
|
||||
//* Mat4::from_rotation_z(std::f32::consts::PI)
|
||||
* 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(),
|
||||
};
|
||||
|
||||
let uniform_data = implicit_fs::Camera {
|
||||
let uniform_data = implicit_vs::Camera {
|
||||
view: view.to_cols_array_2d(),
|
||||
proj: proj.to_cols_array_2d(),
|
||||
campos: self.cstate.position.to_array(),
|
||||
@@ -1052,7 +960,7 @@ impl App {
|
||||
col[i][2] = light.colour.z;
|
||||
}
|
||||
|
||||
let uniform_data = mesh_fs::Lights {
|
||||
let uniform_data = implicit_vs::Lights {
|
||||
pos,
|
||||
col,
|
||||
light_count: self.gstate.lights.len() as u32,
|
||||
@@ -1063,10 +971,10 @@ impl App {
|
||||
sub
|
||||
};
|
||||
|
||||
let mesh_layout = &rcx.mesh_pipeline.layout().set_layouts()[0];
|
||||
let mesh_set = DescriptorSet::new(
|
||||
let implicit_layout = &rcx.implicit_pipeline.layout().set_layouts()[0];
|
||||
let implicit_set = DescriptorSet::new(
|
||||
self.descriptor_set_allocator.clone(),
|
||||
mesh_layout.clone(),
|
||||
implicit_layout.clone(),
|
||||
[
|
||||
WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()),
|
||||
WriteDescriptorSet::buffer(1, cam_set.clone()),
|
||||
@@ -1075,133 +983,6 @@ impl App {
|
||||
)
|
||||
.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) =
|
||||
match acquire_next_image(rcx.swapchain.clone(), None).map_err(Validated::unwrap) {
|
||||
Ok(r) => r,
|
||||
@@ -1258,37 +1039,6 @@ impl App {
|
||||
.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
|
||||
.bind_pipeline_graphics(rcx.implicit_pipeline.clone())
|
||||
.unwrap()
|
||||
@@ -1296,8 +1046,10 @@ impl App {
|
||||
PipelineBindPoint::Graphics,
|
||||
rcx.implicit_pipeline.layout().clone(),
|
||||
0,
|
||||
(mesh_set, implicit_set),
|
||||
implicit_set,
|
||||
)
|
||||
.unwrap()
|
||||
.bind_vertex_buffers(0, self.vertex_buffer.clone())
|
||||
.unwrap();
|
||||
|
||||
for csg in &self.gstate.csg {
|
||||
@@ -1314,7 +1066,7 @@ impl App {
|
||||
.push_constants(rcx.implicit_pipeline.layout().clone(), 0, push_constants)
|
||||
.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
|
||||
@@ -1444,9 +1196,8 @@ fn pipeline_recompile(
|
||||
cache: &Arc<PipelineCache>,
|
||||
shader_modules: &ShaderModules,
|
||||
debug: &PreviousDebug,
|
||||
scene: &[[u32; 4]],
|
||||
viewport: Option<&Viewport>,
|
||||
) -> (Arc<GraphicsPipeline>, Arc<GraphicsPipeline>) {
|
||||
) -> Arc<GraphicsPipeline> {
|
||||
let device = cache.device();
|
||||
|
||||
const SPEC_BOUNDING_BOXES: u32 = 0;
|
||||
@@ -1456,9 +1207,6 @@ fn pipeline_recompile(
|
||||
const SPEC_DISABLE_TASKCULL: u32 = 4;
|
||||
const SPEC_BRUTE_FORCE: u32 = 5;
|
||||
|
||||
const EXECUTION_LIMIT: u32 = 900;
|
||||
const STATIC_OPCODES: u32 = 901;
|
||||
|
||||
let mut spec_constants = HashMap::with_capacity(6);
|
||||
spec_constants.insert(
|
||||
SPEC_BOUNDING_BOXES,
|
||||
@@ -1489,40 +1237,18 @@ fn pipeline_recompile(
|
||||
|
||||
let specs = spec_constants;
|
||||
|
||||
let mesh_vs_entry = shader_modules
|
||||
.mesh_vs
|
||||
let implicit_vs_entry = shader_modules
|
||||
.implicit_vs
|
||||
.specialize(specs.clone())
|
||||
.unwrap()
|
||||
.single_entry_point()
|
||||
.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 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_vs_info = PipelineShaderStageCreateInfo::new(implicit_vs_entry);
|
||||
let implicit_fs_info = PipelineShaderStageCreateInfo::new(
|
||||
shader_modules
|
||||
.implicit_fs
|
||||
@@ -1534,15 +1260,9 @@ fn pipeline_recompile(
|
||||
|
||||
let layout = PipelineLayout::new(
|
||||
device.clone(),
|
||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([
|
||||
&mesh_vs_info,
|
||||
&mesh_fs_info,
|
||||
&implicit_ts_info,
|
||||
&implicit_ms_info,
|
||||
&implicit_fs_info,
|
||||
])
|
||||
.into_pipeline_layout_create_info(device.clone())
|
||||
.unwrap(),
|
||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([&implicit_vs_info, &implicit_fs_info])
|
||||
.into_pipeline_layout_create_info(device.clone())
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -1565,11 +1285,15 @@ fn pipeline_recompile(
|
||||
)
|
||||
};
|
||||
|
||||
let mesh_pipeline = {
|
||||
let stages = [mesh_vs_info, mesh_fs_info].into_iter().collect();
|
||||
info!("Recompiling implicit pipeline... (may take up to 10 minutes)");
|
||||
|
||||
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(
|
||||
device.clone(),
|
||||
Some(cache.clone()),
|
||||
@@ -1577,57 +1301,11 @@ fn pipeline_recompile(
|
||||
stages,
|
||||
vertex_input_state: Some(vertex_input_state),
|
||||
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,
|
||||
viewport_state: Some(viewport_state),
|
||||
rasterization_state: Some(RasterizationState {
|
||||
//front_face: Clockwise,
|
||||
//cull_mode: CullMode::Back,
|
||||
front_face: FrontFace::Clockwise,
|
||||
cull_mode: CullMode::Back,
|
||||
..RasterizationState::default()
|
||||
}),
|
||||
depth_stencil_state: Some(DepthStencilState {
|
||||
@@ -1650,17 +1328,17 @@ fn pipeline_recompile(
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let render_end = Instant::now();
|
||||
|
||||
info!("Implicit pipeline compiled");
|
||||
info!(
|
||||
"Implicit pipeline took {} milliseconds",
|
||||
(render_end - render_start).as_secs_f64() * 1000.0
|
||||
);
|
||||
|
||||
dump_pipeline_cache(cache.clone());
|
||||
|
||||
(mesh_pipeline, implicit_pipeline)
|
||||
}
|
||||
|
||||
struct Subbuffers {
|
||||
masks: Subbuffer<[[u8; 500]]>,
|
||||
scene: Subbuffer<[[u32; 4]]>,
|
||||
desc: Subbuffer<[implicit_fs::Description]>,
|
||||
implicit_pipeline
|
||||
}
|
||||
|
||||
fn gpu_buffer<T>(
|
||||
@@ -1722,140 +1400,6 @@ where
|
||||
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>) {
|
||||
if let Ok(data) = cache.get_data() {
|
||||
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