Entirely remove the rasteriser
This commit is contained in:
@@ -6,7 +6,7 @@ edition = "2024"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
vulkano = "0.35.1"
|
||||
vulkano = "0.35.2"
|
||||
vulkano-shaders = { version = "0.35.0", features = ["shaderc-debug"] }
|
||||
winit = "0.30"
|
||||
vulkano-util = "0.35.0"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef compute_prepass_include
|
||||
#define compute_prepass_include
|
||||
|
||||
#extension GL_GOOGLE_include_directive:require
|
||||
#include "include.glsl"
|
||||
|
||||
layout(set = 1, binding = 0) restrict buffer Object {
|
||||
uvec4 enable[(SPEC_MAXIMUM_SUBDIVISION * SPEC_MAXIMUM_SUBDIVISION * SPEC_MAXIMUM_SUBDIVISION) / (4 * 32)];
|
||||
vec3 dimensions;
|
||||
vec3 lowest_corner;
|
||||
uint material;
|
||||
uint subdivision_log2;
|
||||
float farplane;
|
||||
vec3 colour;
|
||||
float metallic;
|
||||
float roughness;
|
||||
} object_uniforms;
|
||||
|
||||
float scene(vec4 p) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
vec2 interval_scene(vec4 pl, vec4 ph) {
|
||||
return vec2(0.0);
|
||||
}
|
||||
|
||||
vec4 gradient_scene(vec4 p) {
|
||||
return vec4(0.0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -4,18 +4,6 @@
|
||||
#extension GL_GOOGLE_include_directive:require
|
||||
#include "include.glsl"
|
||||
|
||||
layout(set = 1, binding = 0) uniform Object {
|
||||
uvec4 enable[(SPEC_MAXIMUM_SUBDIVISION * SPEC_MAXIMUM_SUBDIVISION * SPEC_MAXIMUM_SUBDIVISION) / (4 * 32)];
|
||||
vec3 dimensions;
|
||||
vec3 lowest_corner;
|
||||
uint material;
|
||||
uint subdivision_log2;
|
||||
float farplane;
|
||||
vec3 colour;
|
||||
float metallic;
|
||||
float roughness;
|
||||
} object_uniforms;
|
||||
|
||||
float scene(vec4 p) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,6 @@ layout(constant_id = 10) const bool SPEC_USE_CPU_ENABLE_GEN = false;
|
||||
//layout(constant_id = 30) const uint SPEC_MAXIMUM_SUBDIVISION = 64;
|
||||
const uint SPEC_MAXIMUM_SUBDIVISION = 64;
|
||||
|
||||
layout(push_constant) uniform PushConstantData {
|
||||
mat4 world;
|
||||
mat4 inv_world;
|
||||
} pc;
|
||||
|
||||
layout(set = 0, binding = 0) uniform Lights {
|
||||
vec4[32] pos;
|
||||
vec4[32] col;
|
||||
@@ -33,33 +28,103 @@ layout(set = 0, binding = 1) uniform Camera {
|
||||
mat4 inv_proj;
|
||||
mat4 inv_view;
|
||||
vec4 campos_and_time;
|
||||
|
||||
float specular;
|
||||
float specular_tint;
|
||||
float sheen_tint;
|
||||
float sheen;
|
||||
float clear_coat_gloss;
|
||||
float subsurface;
|
||||
float clear_coat;
|
||||
} camera_uniforms;
|
||||
|
||||
/*
|
||||
struct RTGBuffer {
|
||||
uint normal; // 1010102
|
||||
uint base_color; //1010102
|
||||
float t;
|
||||
uint8_t roughness;
|
||||
uint8_t specular;
|
||||
uint8_t specular_tint;
|
||||
|
||||
uint8_t sheen_tint;
|
||||
uint8_t metallic;
|
||||
uint8_t sheen;
|
||||
|
||||
uint8_t clear_coat_gloss;
|
||||
uint8_t subsurface;
|
||||
uint8_t clear_coat;
|
||||
struct OVertex {
|
||||
vec4 pos;
|
||||
vec4 normal;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 2, std430) restrict readonly buffer Verts {
|
||||
OVertex verts[];
|
||||
} verts;
|
||||
|
||||
layout(set = 0, binding = 3, std430) restrict readonly buffer Indicies {
|
||||
uint indicies[];
|
||||
} indicies;
|
||||
|
||||
struct Object {
|
||||
vec3 dimensions;
|
||||
vec3 lowest_corner;
|
||||
uint subdivision_log2;
|
||||
|
||||
vec4 colour_and_roughness;
|
||||
float metallic;
|
||||
float subsurface;
|
||||
float specular;
|
||||
float specular_tint;
|
||||
float sheen;
|
||||
float sheen_tint;
|
||||
float clear_coat_gloss;
|
||||
float clear_coat;
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
uint vert_offset;
|
||||
uint index_offset;
|
||||
|
||||
vec4 colour_and_roughness;
|
||||
float metallic;
|
||||
float subsurface;
|
||||
float specular;
|
||||
float specular_tint;
|
||||
float sheen;
|
||||
float sheen_tint;
|
||||
float clear_coat_gloss;
|
||||
float clear_coat;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 4, std430) restrict readonly buffer Meshes {
|
||||
Mesh meshes[];
|
||||
} meshes;
|
||||
|
||||
layout(set = 0, binding = 5, std430) restrict readonly buffer Objects {
|
||||
Object objects[];
|
||||
} objects;
|
||||
|
||||
struct TenTenTenTwo {
|
||||
uint data;
|
||||
};
|
||||
|
||||
uint single_t_compress(float inp) {
|
||||
uint t = uint(clamp(abs(inp), 0.0, 1.0) * float(0x1FF));
|
||||
if (inp < 0.) {
|
||||
t |= 0x200;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
float single_t_uncompress(uint inp) {
|
||||
float t = float(inp & 0x1FF) / float(0x1FF);
|
||||
if ((inp & 0x200) > 0) {
|
||||
t = -t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
TenTenTenTwo tttt_compress(vec3 inp) {
|
||||
TenTenTenTwo outp;
|
||||
outp.data = single_t_compress(inp.x);
|
||||
outp.data |= (single_t_compress(inp.y) << 10);
|
||||
outp.data |= (single_t_compress(inp.z) << 20);
|
||||
return outp;
|
||||
}
|
||||
|
||||
vec3 tttt_uncompress(TenTenTenTwo inp) {
|
||||
vec3 outp;
|
||||
outp.x = single_t_uncompress(inp.data);
|
||||
outp.y = (single_t_uncompress(inp.data >> 10));
|
||||
outp.z = (single_t_uncompress(inp.data >> 20));
|
||||
return outp;
|
||||
}
|
||||
|
||||
struct RTGBuffer {
|
||||
TenTenTenTwo normal;
|
||||
TenTenTenTwo base_color;
|
||||
TenTenTenTwo roughness_specular_specular_tint;
|
||||
TenTenTenTwo sheen_tint_metallic_sheen;
|
||||
TenTenTenTwo clear_coat_gloss_subsurface_clear_coat;
|
||||
float t;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#version 460
|
||||
#extension GL_GOOGLE_include_directive:require
|
||||
#include "include.glsl"
|
||||
|
||||
layout(location = 0) out vec2 v_pos;
|
||||
|
||||
const vec2 full_screen_triangle[3] = {
|
||||
vec2(0., 0.),
|
||||
vec2(0., 2.),
|
||||
vec2(2, 0.)
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec2 tri = (full_screen_triangle[gl_VertexIndex - gl_BaseVertex] * 2.0) - 1.0;
|
||||
v_pos = tri;
|
||||
gl_Position = vec4(v_pos, gl_BaseVertex / 65536.0, 1.0);
|
||||
}
|
||||
@@ -6,24 +6,15 @@
|
||||
layout(location = 0) rayPayloadInEXT vec3 hit_value;
|
||||
hitAttributeEXT vec2 baryCoord;
|
||||
|
||||
struct OVertex {
|
||||
vec4 pos;
|
||||
vec4 normal;
|
||||
};
|
||||
|
||||
layout(set = 3, binding = 0, std430) restrict readonly buffer Verts {
|
||||
OVertex verts[];
|
||||
} verts;
|
||||
|
||||
layout(set = 3, binding = 1, std430) restrict readonly buffer Indicies {
|
||||
uint indicies[];
|
||||
} indicies;
|
||||
Mesh mesh;
|
||||
|
||||
OVertex load_vert(uint index) {
|
||||
return verts.verts[indicies.indicies[index]];
|
||||
return verts.verts[mesh.vert_offset + indicies.indicies[mesh.index_offset + index]];
|
||||
}
|
||||
|
||||
void main() {
|
||||
mesh = meshes.meshes[gl_InstanceID];
|
||||
|
||||
// get mesh vertex data in object space
|
||||
OVertex v0 = load_vert((gl_PrimitiveID * 3) + 0);
|
||||
OVertex v1 = load_vert((gl_PrimitiveID * 3) + 1);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#version 460
|
||||
#extension GL_GOOGLE_include_directive:require
|
||||
#include "include.glsl"
|
||||
#include "implicit_include.glsl"
|
||||
|
||||
layout(location = 0) in vec3 position;
|
||||
|
||||
layout(location = 0) out vec4 pos;
|
||||
|
||||
void main() {
|
||||
uint base_index = gl_InstanceIndex; //gl_BaseInstance;
|
||||
|
||||
if (SPEC_BRUTE_FORCE) {
|
||||
if (base_index > 0) {
|
||||
gl_Position = vec4(0.0 / 0.0);
|
||||
return;
|
||||
}
|
||||
pos = vec4((position * object_uniforms.dimensions) + object_uniforms.lowest_corner, 1.);
|
||||
} else {
|
||||
vec3 internal_pos = vec3(
|
||||
float((base_index >> (object_uniforms.subdivision_log2 * 2)) & ((1 << object_uniforms.subdivision_log2) - 1))
|
||||
/ float(1 << object_uniforms.subdivision_log2),
|
||||
float((base_index >> (object_uniforms.subdivision_log2 * 1)) & ((1 << object_uniforms.subdivision_log2) - 1))
|
||||
/ float(1 << object_uniforms.subdivision_log2),
|
||||
float((base_index >> (object_uniforms.subdivision_log2 * 0)) & ((1 << object_uniforms.subdivision_log2) - 1))
|
||||
/ float(1 << object_uniforms.subdivision_log2)
|
||||
);
|
||||
|
||||
bool enable;
|
||||
switch ((base_index >> 5) & 3) {
|
||||
default:
|
||||
case 0:
|
||||
enable = (object_uniforms.enable[base_index >> 7].x & (1 << (base_index & 31))) != 0;
|
||||
break;
|
||||
case 1:
|
||||
enable = (object_uniforms.enable[base_index >> 7].y & (1 << (base_index & 31))) != 0;
|
||||
break;
|
||||
case 2:
|
||||
enable = (object_uniforms.enable[base_index >> 7].z & (1 << (base_index & 31))) != 0;
|
||||
break;
|
||||
case 3:
|
||||
enable = (object_uniforms.enable[base_index >> 7].w & (1 << (base_index & 31))) != 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
gl_Position = vec4(0.0 / 0.0);
|
||||
return;
|
||||
}
|
||||
pos = vec4((((position / float(1 << object_uniforms.subdivision_log2)) + internal_pos)
|
||||
* object_uniforms.dimensions) + object_uniforms.lowest_corner, 1.);
|
||||
}
|
||||
|
||||
gl_Position = camera_uniforms.proj_view * pc.world * pos;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#version 460
|
||||
#extension GL_GOOGLE_include_directive:require
|
||||
#include "compute_prepass_include.glsl"
|
||||
#include "implicit_include.glsl"
|
||||
|
||||
struct AABB {
|
||||
float min_x;
|
||||
@@ -11,36 +11,44 @@ struct AABB {
|
||||
float max_z;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1, std430) restrict writeonly buffer AABBS {
|
||||
layout(set = 1, binding = 0, std430) restrict writeonly buffer AABBS {
|
||||
AABB aabbs[];
|
||||
} aabbs;
|
||||
|
||||
layout(push_constant, std430) uniform PushConstantData {
|
||||
uint object_index;
|
||||
} pc;
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
const float NAN = 0.0 / 0.0;
|
||||
|
||||
Object object;
|
||||
|
||||
void main() {
|
||||
if (SPEC_BRUTE_FORCE || SPEC_USE_CPU_ENABLE_GEN) {
|
||||
if (SPEC_BRUTE_FORCE) {
|
||||
return;
|
||||
}
|
||||
|
||||
object = objects.objects[pc.object_index];
|
||||
|
||||
uvec3 total_invocations = gl_NumWorkGroups * gl_WorkGroupSize;
|
||||
uint base_index = (gl_GlobalInvocationID.z * total_invocations.x * total_invocations.y) +
|
||||
(gl_GlobalInvocationID.y * total_invocations.x) + gl_GlobalInvocationID.x;
|
||||
|
||||
vec3 internal_pos = vec3(
|
||||
float((base_index >> (object_uniforms.subdivision_log2 * 2)) & ((1 << object_uniforms.subdivision_log2) - 1))
|
||||
/ float(1 << object_uniforms.subdivision_log2),
|
||||
float((base_index >> (object_uniforms.subdivision_log2 * 1)) & ((1 << object_uniforms.subdivision_log2) - 1))
|
||||
/ float(1 << object_uniforms.subdivision_log2),
|
||||
float((base_index >> (object_uniforms.subdivision_log2 * 0)) & ((1 << object_uniforms.subdivision_log2) - 1))
|
||||
/ float(1 << object_uniforms.subdivision_log2)
|
||||
float((base_index >> (object.subdivision_log2 * 2)) & ((1 << object.subdivision_log2) - 1))
|
||||
/ float(1 << object.subdivision_log2),
|
||||
float((base_index >> (object.subdivision_log2 * 1)) & ((1 << object.subdivision_log2) - 1))
|
||||
/ float(1 << object.subdivision_log2),
|
||||
float((base_index >> (object.subdivision_log2 * 0)) & ((1 << object.subdivision_log2) - 1))
|
||||
/ float(1 << object.subdivision_log2)
|
||||
);
|
||||
|
||||
vec3 low_corner = (((vec3(0.0) / float(1 << object_uniforms.subdivision_log2)) + internal_pos)
|
||||
* object_uniforms.dimensions) + object_uniforms.lowest_corner;
|
||||
vec3 high_corner = (((vec3(1.0) / float(1 << object_uniforms.subdivision_log2)) + internal_pos)
|
||||
* object_uniforms.dimensions) + object_uniforms.lowest_corner;
|
||||
vec3 low_corner = (((vec3(0.0) / float(1 << object.subdivision_log2)) + internal_pos)
|
||||
* object.dimensions) + object.lowest_corner;
|
||||
vec3 high_corner = (((vec3(1.0) / float(1 << object.subdivision_log2)) + internal_pos)
|
||||
* object.dimensions) + object.lowest_corner;
|
||||
|
||||
vec2 interval = interval_scene(
|
||||
vec4(low_corner, camera_uniforms.campos_and_time.w),
|
||||
@@ -59,36 +67,4 @@ void main() {
|
||||
} else {
|
||||
aabbs.aabbs[base_index].min_x = NAN;
|
||||
}
|
||||
|
||||
switch ((base_index >> 5) & 3) {
|
||||
default:
|
||||
case 0:
|
||||
if (enable) {
|
||||
atomicOr(object_uniforms.enable[base_index >> 7].x, (1 << (base_index & 31)));
|
||||
} else {
|
||||
atomicAnd(object_uniforms.enable[base_index >> 7].x, (~(1 << (base_index & 31))));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (enable) {
|
||||
atomicOr(object_uniforms.enable[base_index >> 7].y, (1 << (base_index & 31)));
|
||||
} else {
|
||||
atomicAnd(object_uniforms.enable[base_index >> 7].y, (~(1 << (base_index & 31))));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (enable) {
|
||||
atomicOr(object_uniforms.enable[base_index >> 7].z, (1 << (base_index & 31)));
|
||||
} else {
|
||||
atomicAnd(object_uniforms.enable[base_index >> 7].z, (~(1 << (base_index & 31))));
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (enable) {
|
||||
atomicOr(object_uniforms.enable[base_index >> 7].w, (1 << (base_index & 31)));
|
||||
} else {
|
||||
atomicAnd(object_uniforms.enable[base_index >> 7].w, (~(1 << (base_index & 31))));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#version 460
|
||||
#extension GL_GOOGLE_include_directive:require
|
||||
#include "include.glsl"
|
||||
#include "implicit_include.glsl"
|
||||
|
||||
layout(location = 0) in vec4 pos;
|
||||
|
||||
layout(depth_greater) out float gl_FragDepth;
|
||||
|
||||
layout(location = 0) out uint material;
|
||||
|
||||
const float EPSILON = .001;
|
||||
|
||||
const uint MAX_STEPS = 50;
|
||||
|
||||
void main() {
|
||||
if (SPEC_BOUNDING_BOXES) {
|
||||
material = object_uniforms.material;
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 raypos = pos.xyz;
|
||||
vec3 raydir = normalize(raypos - (pc.inv_world * vec4(camera_uniforms.campos_and_time.xyz, 1)).xyz);
|
||||
|
||||
float farplane = SPEC_BRUTE_FORCE ? length(object_uniforms.dimensions) : object_uniforms.farplane;
|
||||
|
||||
vec3 p = raypos;
|
||||
float total_dist = 0.;
|
||||
for (uint i = 0; i < MAX_STEPS; i++) {
|
||||
float dist = scene(vec4(p, camera_uniforms.campos_and_time.w));
|
||||
total_dist += dist;
|
||||
p = fma(raydir, vec3(total_dist), raypos);
|
||||
if (abs(dist) < EPSILON) {
|
||||
vec4 tpoint = camera_uniforms.proj_view * pc.world * vec4(p, 1);
|
||||
gl_FragDepth = (tpoint.z / tpoint.w);
|
||||
material = object_uniforms.material;
|
||||
return;
|
||||
} else if (total_dist > farplane) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
discard;
|
||||
}
|
||||
@@ -1,27 +1,21 @@
|
||||
use std::{sync::Arc, thread};
|
||||
use std::thread;
|
||||
|
||||
use vulkano::{
|
||||
buffer::{BufferContents, BufferWriteGuard, Subbuffer},
|
||||
command_buffer::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, CopyBufferInfo, PrimaryCommandBufferAbstract,
|
||||
allocator::CommandBufferAllocator,
|
||||
},
|
||||
device::Queue,
|
||||
sync::{AccessConflict, GpuFuture, HostAccessError},
|
||||
sync::HostAccessError,
|
||||
};
|
||||
|
||||
fn get_host_buffer_writer<'a, T>(host_visible: &'a Subbuffer<T>) -> BufferWriteGuard<'a, T>
|
||||
fn get_host_buffer_writer<'a, T>(device_local: &'a Subbuffer<T>) -> BufferWriteGuard<'a, T>
|
||||
where
|
||||
T: BufferContents + ?Sized,
|
||||
{
|
||||
let mut writer = host_visible.write();
|
||||
let mut writer = device_local.write();
|
||||
'writerloop: loop {
|
||||
match writer {
|
||||
Err(HostAccessError::AccessConflict(AccessConflict::DeviceRead))
|
||||
| Err(HostAccessError::AccessConflict(AccessConflict::DeviceWrite)) => {
|
||||
Err(HostAccessError::AccessConflict(_)) => {
|
||||
//warn!("WAITING FOR HOST BUFFER FREE");
|
||||
thread::yield_now();
|
||||
writer = host_visible.write();
|
||||
writer = device_local.write();
|
||||
},
|
||||
_ => break 'writerloop,
|
||||
}
|
||||
@@ -29,72 +23,22 @@ where
|
||||
writer.unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn gpu_upload<T>(
|
||||
input: T,
|
||||
device_local: Subbuffer<T>,
|
||||
host_visible: Subbuffer<T>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> Box<dyn GpuFuture + Send + Sync>
|
||||
pub(crate) fn gpu_upload<T>(input: T, device_local: Subbuffer<T>)
|
||||
where
|
||||
T: BufferContents,
|
||||
{
|
||||
{
|
||||
let mut writer = get_host_buffer_writer(&host_visible);
|
||||
let mut writer = get_host_buffer_writer(&device_local);
|
||||
*writer = input;
|
||||
}
|
||||
|
||||
gpu_upload_command_buffer(
|
||||
device_local,
|
||||
host_visible,
|
||||
command_allocator,
|
||||
transfer_queue,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn gpu_upload_slice<T>(
|
||||
input: &[T],
|
||||
device_local: Subbuffer<[T]>,
|
||||
host_visible: Subbuffer<[T]>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> Box<dyn GpuFuture + Send + Sync>
|
||||
pub(crate) fn gpu_upload_slice<T>(input: &[T], device_local: Subbuffer<[T]>)
|
||||
where
|
||||
T: BufferContents + Copy,
|
||||
{
|
||||
{
|
||||
let mut writer = get_host_buffer_writer(&host_visible);
|
||||
let mut writer = get_host_buffer_writer(&device_local);
|
||||
writer.copy_from_slice(input);
|
||||
}
|
||||
|
||||
gpu_upload_command_buffer(
|
||||
device_local,
|
||||
host_visible,
|
||||
command_allocator,
|
||||
transfer_queue,
|
||||
)
|
||||
}
|
||||
|
||||
fn gpu_upload_command_buffer<T>(
|
||||
device_local: Subbuffer<T>,
|
||||
host_visible: Subbuffer<T>,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
) -> Box<dyn GpuFuture + Send + Sync>
|
||||
where
|
||||
T: BufferContents + ?Sized,
|
||||
{
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
command_allocator,
|
||||
transfer_queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
builder
|
||||
.copy_buffer(CopyBufferInfo::buffers(host_visible, device_local))
|
||||
.unwrap();
|
||||
let commands = builder.build().unwrap();
|
||||
|
||||
commands.execute(transfer_queue).unwrap().boxed_send_sync()
|
||||
}
|
||||
|
||||
+35
-101
@@ -1,12 +1,12 @@
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use egui::{Color32, Frame, Id};
|
||||
use egui::{Color32, Frame, Id, Ui};
|
||||
use egui_plot::{Line, Plot, PlotPoints};
|
||||
use egui_winit_vulkano::Gui;
|
||||
|
||||
use crate::{
|
||||
MAXIMUM_SUBDIVISION, MINUMUM_SUBDIVISION,
|
||||
objects::{CSG, Light, Mesh},
|
||||
objects::{CSG, Light, Material, Mesh, Position},
|
||||
};
|
||||
|
||||
fn sized_text(ui: &mut egui::Ui, text: impl Into<String>, size: f32) {
|
||||
@@ -44,14 +44,6 @@ pub(crate) struct GState {
|
||||
|
||||
pub(crate) debug: PreviousDebug,
|
||||
|
||||
pub(crate) subsurface: f32,
|
||||
pub(crate) specular: f32,
|
||||
pub(crate) specular_tint: f32,
|
||||
pub(crate) sheen: f32,
|
||||
pub(crate) sheen_tint: f32,
|
||||
pub(crate) clear_coat_gloss: f32,
|
||||
pub(crate) clear_coat: f32,
|
||||
|
||||
pub(crate) recreate_pipelines: bool,
|
||||
pub(crate) reset_time: bool,
|
||||
}
|
||||
@@ -73,20 +65,41 @@ impl Default for GState {
|
||||
|
||||
debug: Default::default(),
|
||||
|
||||
specular: 0.73,
|
||||
specular_tint: 0.,
|
||||
sheen_tint: 0.,
|
||||
sheen: 0.58,
|
||||
clear_coat_gloss: 0.63,
|
||||
subsurface: 0.,
|
||||
clear_coat: 0.85,
|
||||
|
||||
recreate_pipelines: false,
|
||||
reset_time: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_position(ui: &mut Ui, position: &mut Position) {
|
||||
ui.heading("Position");
|
||||
ui.add(egui::Slider::new(&mut position.pos.x, -100.0..=100.0).text("Position.x"));
|
||||
ui.add(egui::Slider::new(&mut position.pos.y, -100.0..=100.0).text("Position.y"));
|
||||
ui.add(egui::Slider::new(&mut position.pos.z, -100.0..=100.0).text("Position.z"));
|
||||
ui.add(egui::Slider::new(&mut position.rot.x, 0.0..=360.0).text("Rotation.x"));
|
||||
ui.add(egui::Slider::new(&mut position.rot.y, 0.0..=360.0).text("Rotation.y"));
|
||||
ui.add(egui::Slider::new(&mut position.rot.z, 0.0..=360.0).text("Rotation.z"));
|
||||
ui.add(egui::Slider::new(&mut position.scale.x, 0.0..=2.0).text("Scale.x"));
|
||||
ui.add(egui::Slider::new(&mut position.scale.y, 0.0..=2.0).text("Scale.y"));
|
||||
ui.add(egui::Slider::new(&mut position.scale.z, 0.0..=2.0).text("Scale.z"));
|
||||
}
|
||||
|
||||
fn draw_material(ui: &mut Ui, material: &mut Material) {
|
||||
ui.heading("Material");
|
||||
ui.add(egui::Slider::new(&mut material.colour.x, 0.0..=1.0).text("Colour.r"));
|
||||
ui.add(egui::Slider::new(&mut material.colour.y, 0.0..=1.0).text("Colour.g"));
|
||||
ui.add(egui::Slider::new(&mut material.colour.z, 0.0..=1.0).text("Colour.b"));
|
||||
ui.add(egui::Slider::new(&mut material.roughness, 0.0..=1.0).text("Roughness"));
|
||||
ui.add(egui::Slider::new(&mut material.metallic, 0.0..=1.0).text("Metallic"));
|
||||
ui.add(egui::Slider::new(&mut material.subsurface, 0.0..=1.0).text("Subsurface"));
|
||||
ui.add(egui::Slider::new(&mut material.specular, 0.0..=1.0).text("Specular"));
|
||||
ui.add(egui::Slider::new(&mut material.specular_tint, 0.0..=1.0).text("Specular tint"));
|
||||
ui.add(egui::Slider::new(&mut material.sheen, 0.0..=1.0).text("Sheen"));
|
||||
ui.add(egui::Slider::new(&mut material.sheen_tint, 0.0..=1.0).text("Sheen tint"));
|
||||
ui.add(egui::Slider::new(&mut material.clear_coat, 0.0..=1.0).text("Clear Coat"));
|
||||
ui.add(egui::Slider::new(&mut material.clear_coat_gloss, 0.0..=1.0).text("Clear Coat Gloss"));
|
||||
}
|
||||
|
||||
pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
|
||||
gui.immediate_ui(|gui| {
|
||||
let ctx = gui.context();
|
||||
@@ -109,26 +122,6 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
|
||||
egui::Slider::new(&mut state.move_speed, 0.0..=2.0)
|
||||
.text("Movement Speed"),
|
||||
);
|
||||
ui.heading("Material");
|
||||
ui.add(
|
||||
egui::Slider::new(&mut state.subsurface, 0.0..=1.0).text("Subsurface"),
|
||||
);
|
||||
ui.add(egui::Slider::new(&mut state.specular, 0.0..=1.0).text("Specular"));
|
||||
ui.add(
|
||||
egui::Slider::new(&mut state.specular_tint, 0.0..=1.0)
|
||||
.text("Specular tint"),
|
||||
);
|
||||
ui.add(egui::Slider::new(&mut state.sheen, 0.0..=1.0).text("Sheen"));
|
||||
ui.add(
|
||||
egui::Slider::new(&mut state.sheen_tint, 0.0..=1.0).text("Sheen tint"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut state.clear_coat, 0.0..=1.0).text("Clear Coat"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut state.clear_coat_gloss, 0.0..=1.0)
|
||||
.text("Clear Coat Gloss"),
|
||||
);
|
||||
let meshes_len = state.meshes.len();
|
||||
let csg_len = state.csg.len();
|
||||
ui.heading(format!("Meshes ({})", meshes_len));
|
||||
@@ -138,30 +131,8 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
|
||||
if meshes_len > 1 || csg_len > 0 {
|
||||
meshdel.push(ui.small_button("remove mesh").clicked());
|
||||
}
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.pos.x, -100.0..=100.0)
|
||||
.text("Position.x"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.pos.y, -100.0..=100.0)
|
||||
.text("Position.y"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.pos.z, -100.0..=100.0)
|
||||
.text("Position.z"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.rot.x, 0.0..=360.0).text("Rotation.x"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.rot.y, 0.0..=360.0).text("Rotation.y"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut mesh.rot.z, 0.0..=360.0).text("Rotation.z"),
|
||||
);
|
||||
ui.add(egui::Slider::new(&mut mesh.scale.x, 0.0..=2.0).text("Scale.x"));
|
||||
ui.add(egui::Slider::new(&mut mesh.scale.y, 0.0..=2.0).text("Scale.y"));
|
||||
ui.add(egui::Slider::new(&mut mesh.scale.z, 0.0..=2.0).text("Scale.z"));
|
||||
draw_position(ui, &mut mesh.position);
|
||||
draw_material(ui, &mut mesh.material);
|
||||
}
|
||||
for i in meshdel
|
||||
.into_iter()
|
||||
@@ -178,45 +149,8 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
|
||||
if meshes_len > 0 || csg_len > 1 {
|
||||
csgdel.push(ui.small_button("remove csg").clicked());
|
||||
}
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.pos.x, -100.0..=100.0)
|
||||
.text("Position.x"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.pos.y, -100.0..=100.0)
|
||||
.text("Position.y"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.pos.z, -100.0..=100.0)
|
||||
.text("Position.z"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.rot.x, 0.0..=360.0).text("Rotation.x"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.rot.y, 0.0..=360.0).text("Rotation.y"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.rot.z, 0.0..=360.0).text("Rotation.z"),
|
||||
);
|
||||
ui.add(egui::Slider::new(&mut csg.scale.x, 0.0..=2.0).text("Scale.x"));
|
||||
ui.add(egui::Slider::new(&mut csg.scale.y, 0.0..=2.0).text("Scale.y"));
|
||||
ui.add(egui::Slider::new(&mut csg.scale.z, 0.0..=2.0).text("Scale.z"));
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.colour.x, 0.0..=1.0).text("Colour.r"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.colour.y, 0.0..=1.0).text("Colour.g"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.colour.z, 0.0..=1.0).text("Colour.b"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.roughness, 0.0..=1.0).text("Roughness"),
|
||||
);
|
||||
ui.add(
|
||||
egui::Slider::new(&mut csg.metallic, 0.0..=1.0).text("Metallic"),
|
||||
);
|
||||
draw_position(ui, &mut csg.position);
|
||||
draw_material(ui, &mut csg.material);
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Subdivision");
|
||||
for x in MINUMUM_SUBDIVISION.ilog2()..=MAXIMUM_SUBDIVISION.ilog2() {
|
||||
|
||||
+168
-655
File diff suppressed because it is too large
Load Diff
+104
-69
@@ -1,6 +1,9 @@
|
||||
use std::{
|
||||
io::Read,
|
||||
sync::{Arc, RwLock},
|
||||
sync::{
|
||||
Arc, RwLock,
|
||||
atomic::{AtomicU64, Ordering},
|
||||
},
|
||||
};
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
@@ -8,16 +11,14 @@ use foldhash::{HashMap, HashMapExt};
|
||||
use glam::{self, Vec3};
|
||||
use obj::{LoadConfig, ObjData, ObjError};
|
||||
use vulkano::{
|
||||
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
|
||||
DeviceSize,
|
||||
buffer::Subbuffer,
|
||||
descriptor_set::DescriptorSet,
|
||||
memory::allocator::{
|
||||
AllocationCreateInfo, MemoryAllocatePreference, MemoryAllocator, MemoryTypeFilter,
|
||||
},
|
||||
pipeline::{ComputePipeline, GraphicsPipeline, graphics::vertex_input::Vertex},
|
||||
pipeline::{ComputePipeline, graphics::vertex_input::Vertex},
|
||||
shader::ShaderModule,
|
||||
};
|
||||
|
||||
use crate::{ssa::SSATape, trace_vs::Object};
|
||||
use crate::ssa::SSATape;
|
||||
|
||||
pub(crate) const PLATONIC_SOLIDS: [(&str, &[u8]); 1] =
|
||||
[("Buny", include_bytes!("../data/bunny.obj"))];
|
||||
@@ -32,46 +33,92 @@ pub(crate) struct OVertex {
|
||||
normal: [f32; 4],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Position {
|
||||
pub(crate) pos: Vec3,
|
||||
pub(crate) rot: Vec3,
|
||||
pub(crate) scale: Vec3,
|
||||
pub(crate) transform_offset: DeviceSize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Material {
|
||||
pub(crate) colour: Vec3,
|
||||
pub(crate) roughness: f32,
|
||||
pub(crate) metallic: f32,
|
||||
pub(crate) subsurface: f32,
|
||||
pub(crate) specular: f32,
|
||||
pub(crate) specular_tint: f32,
|
||||
pub(crate) sheen: f32,
|
||||
pub(crate) sheen_tint: f32,
|
||||
pub(crate) clear_coat_gloss: f32,
|
||||
pub(crate) clear_coat: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Mesh {
|
||||
pub(crate) name: String,
|
||||
pub(crate) vertices: Subbuffer<[OVertex]>,
|
||||
pub(crate) indices: Subbuffer<[u32]>,
|
||||
pub(crate) pos: Vec3,
|
||||
pub(crate) rot: Vec3,
|
||||
pub(crate) scale: Vec3,
|
||||
pub(crate) name: String,
|
||||
pub(crate) position: Position,
|
||||
pub(crate) material: Material,
|
||||
pub(crate) vert_offset: DeviceSize,
|
||||
pub(crate) vert_len: DeviceSize,
|
||||
pub(crate) index_offset: DeviceSize,
|
||||
pub(crate) index_len: DeviceSize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct CSG {
|
||||
pub(crate) name: String,
|
||||
pub(crate) _seed: u64,
|
||||
pub(crate) parts: SSATape,
|
||||
pub(crate) pos: Vec3,
|
||||
pub(crate) rot: Vec3,
|
||||
pub(crate) scale: Vec3,
|
||||
pub(crate) colour: Vec3,
|
||||
pub(crate) roughness: f32,
|
||||
pub(crate) metallic: f32,
|
||||
pub(crate) replacement_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
|
||||
pub(crate) trace_pipeline: Arc<GraphicsPipeline>,
|
||||
pub(crate) normals_pipeline: Arc<GraphicsPipeline>,
|
||||
pub(crate) fuzz_pipeline: Arc<ComputePipeline>,
|
||||
pub(crate) enable_gen_pipeline: Arc<ComputePipeline>,
|
||||
pub(crate) name: String,
|
||||
pub(crate) position: Position,
|
||||
pub(crate) material: Material,
|
||||
|
||||
pub(crate) parts: SSATape,
|
||||
pub(crate) _seed: u64,
|
||||
pub(crate) subdivision: u32,
|
||||
pub(crate) enable_buffer: Vec<Subbuffer<Object>>,
|
||||
pub(crate) enable_buffer_host_visible: Vec<Subbuffer<Object>>,
|
||||
pub(crate) trace_descriptor_set: Vec<Arc<DescriptorSet>>,
|
||||
pub(crate) normals_descriptor_set: Vec<Arc<DescriptorSet>>,
|
||||
|
||||
pub(crate) replacement_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
|
||||
pub(crate) fuzz_pipeline: Arc<ComputePipeline>,
|
||||
pub(crate) enable_gen_pipeline: Arc<ComputePipeline>,
|
||||
pub(crate) aabb_buffer: Vec<Subbuffer<[u8]>>,
|
||||
pub(crate) enable_gen_descriptor_set: Vec<Arc<DescriptorSet>>,
|
||||
pub(crate) aabb_buffer: Vec<Subbuffer<[u8]>>,
|
||||
}
|
||||
|
||||
impl Default for Position {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
pos: Vec3::ZERO,
|
||||
rot: Vec3::ZERO,
|
||||
scale: Vec3::ONE,
|
||||
transform_offset: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Material {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
colour: Vec3::ONE,
|
||||
roughness: 1.0,
|
||||
metallic: 0.67,
|
||||
specular: 0.73,
|
||||
specular_tint: 0.,
|
||||
sheen_tint: 0.,
|
||||
sheen: 0.58,
|
||||
clear_coat_gloss: 0.63,
|
||||
subsurface: 0.,
|
||||
clear_coat: 0.85,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn load_obj(
|
||||
memory_allocator: &Arc<dyn MemoryAllocator>,
|
||||
input: &mut dyn Read,
|
||||
name: String,
|
||||
additional_usage: BufferUsage,
|
||||
vertex_buffer: Subbuffer<[OVertex]>,
|
||||
vertex_buffer_pointer: Arc<AtomicU64>,
|
||||
index_buffer: Subbuffer<[u32]>,
|
||||
index_buffer_pointer: Arc<AtomicU64>,
|
||||
transform_buffer_pointer: Arc<AtomicU64>,
|
||||
) -> Result<Vec<Mesh>, ObjError> {
|
||||
let object = ObjData::load_buf_with_config(input, LoadConfig::default())?;
|
||||
|
||||
@@ -108,45 +155,33 @@ pub(crate) fn load_obj(
|
||||
}
|
||||
}
|
||||
|
||||
let vertex_buffer = Buffer::from_iter(
|
||||
memory_allocator.clone(),
|
||||
BufferCreateInfo {
|
||||
usage: BufferUsage::STORAGE_BUFFER | additional_usage,
|
||||
..Default::default()
|
||||
},
|
||||
AllocationCreateInfo {
|
||||
memory_type_filter: MemoryTypeFilter::PREFER_HOST
|
||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||
allocate_preference: MemoryAllocatePreference::AlwaysAllocate,
|
||||
..Default::default()
|
||||
},
|
||||
vertices,
|
||||
)
|
||||
.unwrap();
|
||||
let vertex_offset =
|
||||
vertex_buffer_pointer.fetch_add(vertices.len() as u64, Ordering::Relaxed) as usize;
|
||||
let index_offset =
|
||||
index_buffer_pointer.fetch_add(indices.len() as u64, Ordering::Relaxed) as usize;
|
||||
let transform_offset = transform_buffer_pointer.fetch_add(1, Ordering::Relaxed) as usize;
|
||||
|
||||
let index_buffer = Buffer::from_iter(
|
||||
memory_allocator.clone(),
|
||||
BufferCreateInfo {
|
||||
usage: BufferUsage::STORAGE_BUFFER | additional_usage,
|
||||
..Default::default()
|
||||
},
|
||||
AllocationCreateInfo {
|
||||
memory_type_filter: MemoryTypeFilter::PREFER_HOST
|
||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||
allocate_preference: MemoryAllocatePreference::AlwaysAllocate,
|
||||
..Default::default()
|
||||
},
|
||||
indices,
|
||||
)
|
||||
.unwrap();
|
||||
{
|
||||
let mut write = vertex_buffer.write().unwrap();
|
||||
write[vertex_offset..(vertex_offset + vertices.len())].copy_from_slice(&vertices);
|
||||
}
|
||||
|
||||
{
|
||||
let mut write = index_buffer.write().unwrap();
|
||||
write[index_offset..(index_offset + indices.len())].copy_from_slice(&indices);
|
||||
}
|
||||
|
||||
Ok(vec![Mesh {
|
||||
vertices: vertex_buffer,
|
||||
indices: index_buffer,
|
||||
pos: Vec3::ZERO,
|
||||
rot: Vec3::ZERO,
|
||||
scale: Vec3::ONE,
|
||||
name,
|
||||
position: Position {
|
||||
transform_offset: transform_offset as _,
|
||||
..Default::default()
|
||||
},
|
||||
material: Default::default(),
|
||||
vert_offset: vertex_offset as _,
|
||||
vert_len: vertices.len() as u64,
|
||||
index_offset: index_offset as _,
|
||||
index_len: indices.len() as u64,
|
||||
}])
|
||||
}
|
||||
|
||||
|
||||
+80
-7
@@ -4,8 +4,9 @@ use std::{
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use glam::{EulerRot, Mat4};
|
||||
use vulkano::{
|
||||
Packed24_8,
|
||||
DeviceSize, Packed24_8,
|
||||
acceleration_structure::{
|
||||
AccelerationStructure, AccelerationStructureBuildGeometryInfo,
|
||||
AccelerationStructureBuildRangeInfo, AccelerationStructureBuildType,
|
||||
@@ -22,7 +23,11 @@ use vulkano::{
|
||||
memory::allocator::{AllocationCreateInfo, DeviceLayout, MemoryAllocator, MemoryTypeFilter},
|
||||
};
|
||||
|
||||
use crate::objects::{CSG, Mesh, OVertex};
|
||||
use crate::{
|
||||
enable_gen_cs,
|
||||
gpu_upload::gpu_upload,
|
||||
objects::{CSG, Mesh, OVertex, Position},
|
||||
};
|
||||
|
||||
pub struct Scene {
|
||||
// The bottom-level acceleration structure is required to be kept alive
|
||||
@@ -39,6 +44,10 @@ impl Scene {
|
||||
memory_allocator: &Arc<dyn MemoryAllocator>,
|
||||
meshes: &[Mesh],
|
||||
csgs: &[Arc<RwLock<CSG>>],
|
||||
vertex_buffer: &Subbuffer<[OVertex]>,
|
||||
index_buffer: &Subbuffer<[u32]>,
|
||||
transform_buffer: &Subbuffer<[[[f32; 4]; 3]]>,
|
||||
mesh_buffer: &Subbuffer<[enable_gen_cs::Mesh]>,
|
||||
image_index: usize,
|
||||
) -> Self {
|
||||
// Build the bottom-level acceleration structure and then the top-level
|
||||
@@ -50,12 +59,18 @@ impl Scene {
|
||||
// structure.
|
||||
let mesh_blases: Vec<Arc<AccelerationStructure>> = meshes
|
||||
.iter()
|
||||
.map(|mesh| unsafe {
|
||||
.enumerate()
|
||||
.map(|(i, mesh)| unsafe {
|
||||
build_acceleration_structure_triangles(
|
||||
mesh,
|
||||
vertex_buffer.clone(),
|
||||
index_buffer.clone(),
|
||||
transform_buffer.clone(),
|
||||
mesh_buffer.clone(),
|
||||
memory_allocator.clone(),
|
||||
device.clone(),
|
||||
builder,
|
||||
i,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -110,6 +125,49 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn upload_transform(position: &Position, transform_buffer: Subbuffer<[[[f32; 4]; 3]]>) {
|
||||
let world = Mat4::from_translation(position.pos * 0.01)
|
||||
* Mat4::from_euler(
|
||||
EulerRot::XYZ,
|
||||
position.rot.x.to_radians(),
|
||||
position.rot.y.to_radians(),
|
||||
position.rot.z.to_radians(),
|
||||
)
|
||||
* Mat4::from_scale(position.scale * 2.0);
|
||||
|
||||
gpu_upload(
|
||||
[
|
||||
world.row(0).to_array(),
|
||||
world.row(1).to_array(),
|
||||
world.row(2).to_array(),
|
||||
],
|
||||
transform_buffer.index(position.transform_offset),
|
||||
);
|
||||
}
|
||||
|
||||
fn upload_mesh_data(mesh: &Mesh, mesh_buffer: Subbuffer<[enable_gen_cs::Mesh]>, index: DeviceSize) {
|
||||
let mesh = enable_gen_cs::Mesh {
|
||||
vert_offset: (mesh.vert_offset as u32).into(),
|
||||
index_offset: (mesh.index_offset as u32).into(),
|
||||
colour_and_roughness: [
|
||||
mesh.material.colour[0],
|
||||
mesh.material.colour[1],
|
||||
mesh.material.colour[2],
|
||||
mesh.material.roughness,
|
||||
],
|
||||
metallic: mesh.material.metallic,
|
||||
subsurface: mesh.material.subsurface,
|
||||
specular: mesh.material.specular,
|
||||
specular_tint: mesh.material.specular_tint,
|
||||
sheen: mesh.material.sheen,
|
||||
sheen_tint: mesh.material.sheen_tint,
|
||||
clear_coat_gloss: mesh.material.clear_coat_gloss,
|
||||
clear_coat: mesh.material.clear_coat,
|
||||
};
|
||||
|
||||
gpu_upload(mesh, mesh_buffer.index(index));
|
||||
}
|
||||
|
||||
/// A helper function to build a acceleration structure and wait for its
|
||||
/// completion.
|
||||
///
|
||||
@@ -207,16 +265,31 @@ unsafe fn build_acceleration_structure_common(
|
||||
|
||||
unsafe fn build_acceleration_structure_triangles(
|
||||
mesh: &Mesh,
|
||||
vertex_buffer: Subbuffer<[OVertex]>,
|
||||
index_buffer: Subbuffer<[u32]>,
|
||||
transform_buffer: Subbuffer<[[[f32; 4]; 3]]>,
|
||||
mesh_buffer: Subbuffer<[enable_gen_cs::Mesh]>,
|
||||
memory_allocator: Arc<dyn MemoryAllocator>,
|
||||
device: Arc<Device>,
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
index: usize,
|
||||
) -> Arc<AccelerationStructure> {
|
||||
let primitive_count = (mesh.indices.len() / 3) as u32;
|
||||
upload_transform(&mesh.position, transform_buffer.clone());
|
||||
upload_mesh_data(&mesh, mesh_buffer, index as _);
|
||||
|
||||
let primitive_count = (mesh.index_len / 3) as u32;
|
||||
let as_geometry_triangles_data = AccelerationStructureGeometryTrianglesData {
|
||||
max_vertex: mesh.vertices.len() as _,
|
||||
vertex_data: Some(mesh.vertices.clone().into_bytes()),
|
||||
max_vertex: mesh.vert_len as _,
|
||||
vertex_data: Some(
|
||||
vertex_buffer
|
||||
.slice(mesh.vert_offset..(mesh.vert_offset + mesh.vert_len))
|
||||
.into_bytes(),
|
||||
),
|
||||
vertex_stride: size_of::<OVertex>() as _,
|
||||
index_data: Some(IndexBuffer::U32(mesh.indices.clone())),
|
||||
index_data: Some(IndexBuffer::U32(
|
||||
index_buffer.slice(mesh.index_offset..(mesh.index_offset + mesh.index_len)),
|
||||
)),
|
||||
transform_data: Some(transform_buffer.index(mesh.position.transform_offset)),
|
||||
..AccelerationStructureGeometryTrianglesData::new(Format::R32G32B32A32_SFLOAT)
|
||||
};
|
||||
|
||||
|
||||
+51
-421
@@ -1,12 +1,12 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::Write,
|
||||
simd::{StdFloat, cmp::SimdPartialOrd},
|
||||
simd::StdFloat,
|
||||
sync::{Arc, Mutex, RwLock, mpmc, mpsc},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use foldhash::{HashMap, HashMapExt, HashSet};
|
||||
use foldhash::{HashMap, HashMapExt};
|
||||
use glam::{EulerRot, Mat4, Vec3};
|
||||
use log::info;
|
||||
use rand::{Rng, SeedableRng, rngs::SmallRng};
|
||||
@@ -14,39 +14,24 @@ use rspirv::{binary::Assemble, dr::Module};
|
||||
use tape_load::interpreters;
|
||||
use vulkano::{
|
||||
buffer::{Subbuffer, allocator::SubbufferAllocator},
|
||||
command_buffer::allocator::CommandBufferAllocator,
|
||||
descriptor_set::{DescriptorSet, WriteDescriptorSet, allocator::DescriptorSetAllocator},
|
||||
device::{Device, Queue},
|
||||
device::Device,
|
||||
pipeline::{
|
||||
ComputePipeline, DynamicState, GraphicsPipeline, Pipeline, PipelineCreateFlags,
|
||||
PipelineLayout, PipelineShaderStageCreateInfo,
|
||||
cache::PipelineCache,
|
||||
compute::ComputePipelineCreateInfo,
|
||||
graphics::{
|
||||
GraphicsPipelineCreateInfo,
|
||||
color_blend::{ColorBlendAttachmentState, ColorBlendState},
|
||||
depth_stencil::{DepthState, DepthStencilState},
|
||||
input_assembly::InputAssemblyState,
|
||||
multisample::MultisampleState,
|
||||
rasterization::{CullMode, FrontFace, PolygonMode, RasterizationState},
|
||||
vertex_input::{Vertex, VertexDefinition, VertexInputState},
|
||||
},
|
||||
ComputePipeline, Pipeline, PipelineLayout, PipelineShaderStageCreateInfo,
|
||||
cache::PipelineCache, compute::ComputePipelineCreateInfo,
|
||||
layout::PipelineDescriptorSetLayoutCreateInfo,
|
||||
},
|
||||
render_pass::{RenderPass, Subpass},
|
||||
shader::{ShaderModule, ShaderModuleCreateInfo},
|
||||
sync::GpuFuture,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
DUMP_SPV_TO_FILE, IVertex, MAXIMUM_SUBDIVISION, MINUMUM_SUBDIVISION, get_spec_constants,
|
||||
DUMP_SPV_TO_FILE, MAXIMUM_SUBDIVISION, MINUMUM_SUBDIVISION, enable_gen_cs, get_spec_constants,
|
||||
gpu_upload,
|
||||
gui::PreviousDebug,
|
||||
interpreters::{VALUE_0, interval::IntervalInterpreter, point::PointInterpreter},
|
||||
interpreters::point::PointInterpreter,
|
||||
objects::CSG,
|
||||
scene::upload_transform,
|
||||
ssa::{SSAInput, SSAOpcode, SSAOpcodeSized, SSATape},
|
||||
trace_vs::{Object, PushConstantData},
|
||||
types::Interval,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -54,13 +39,9 @@ pub enum WorkItem {
|
||||
CreateCSG(
|
||||
Arc<Device>,
|
||||
Arc<RwLock<HashMap<String, Module>>>,
|
||||
Arc<RenderPass>,
|
||||
Arc<PipelineCache>,
|
||||
Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
|
||||
PreviousDebug,
|
||||
Arc<Mutex<SubbufferAllocator>>,
|
||||
Arc<Mutex<SubbufferAllocator>>,
|
||||
Arc<Mutex<SubbufferAllocator>>,
|
||||
Arc<dyn DescriptorSetAllocator>,
|
||||
u32,
|
||||
u32,
|
||||
@@ -70,10 +51,8 @@ pub enum WorkItem {
|
||||
GetPushConstants(
|
||||
Arc<RwLock<CSG>>,
|
||||
f32,
|
||||
usize,
|
||||
Arc<dyn CommandBufferAllocator>,
|
||||
Arc<Queue>,
|
||||
bool,
|
||||
Subbuffer<[[[f32; 4]; 3]]>,
|
||||
Subbuffer<[enable_gen_cs::Object]>,
|
||||
usize,
|
||||
),
|
||||
RecompileShaders(
|
||||
@@ -85,9 +64,7 @@ pub enum WorkItem {
|
||||
RecompilePipelines(
|
||||
Arc<RwLock<CSG>>,
|
||||
Arc<Device>,
|
||||
Arc<RenderPass>,
|
||||
Arc<PipelineCache>,
|
||||
Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
|
||||
PreviousDebug,
|
||||
usize,
|
||||
),
|
||||
@@ -95,7 +72,7 @@ pub enum WorkItem {
|
||||
|
||||
pub enum WorkComplete {
|
||||
CreateCSG(Arc<RwLock<CSG>>, isize),
|
||||
GetPushConstants(PushConstantData, Box<dyn GpuFuture + Send + Sync>, usize),
|
||||
GetPushConstants(usize),
|
||||
RecompileShaders(usize),
|
||||
RecompilePipelines(usize),
|
||||
}
|
||||
@@ -106,13 +83,9 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
WorkItem::CreateCSG(
|
||||
device,
|
||||
replacement_modules,
|
||||
render_pass,
|
||||
cache,
|
||||
normal_modules,
|
||||
debug,
|
||||
block_enable_allocator,
|
||||
aabb_allocator,
|
||||
host_visible_allocator,
|
||||
descriptor_set_allocator,
|
||||
frames,
|
||||
subdivision,
|
||||
@@ -132,34 +105,8 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
|
||||
let replacement_modules = Arc::new(RwLock::new(new_replacement_modules));
|
||||
|
||||
let (trace_pipeline, normals_pipeline, fuzz_pipeline, enable_gen_pipeline) =
|
||||
deferred_pipelines_recompile(
|
||||
device,
|
||||
render_pass,
|
||||
cache,
|
||||
normal_modules,
|
||||
replacement_modules.clone(),
|
||||
debug,
|
||||
);
|
||||
|
||||
let enable_buffer: Vec<Subbuffer<Object>> = (0..frames)
|
||||
.map(|_| {
|
||||
block_enable_allocator
|
||||
.lock()
|
||||
.unwrap()
|
||||
.allocate_sized()
|
||||
.unwrap()
|
||||
})
|
||||
.collect();
|
||||
let enable_buffer_host_visible: Vec<Subbuffer<Object>> = (0..frames)
|
||||
.map(|_| {
|
||||
host_visible_allocator
|
||||
.lock()
|
||||
.unwrap()
|
||||
.allocate_sized()
|
||||
.unwrap()
|
||||
})
|
||||
.collect();
|
||||
let (fuzz_pipeline, enable_gen_pipeline) =
|
||||
deferred_pipelines_recompile(device, cache, replacement_modules.clone(), debug);
|
||||
|
||||
let aabb_buffer: Vec<Subbuffer<[u8]>> = (0..frames)
|
||||
.map(|_| {
|
||||
@@ -175,48 +122,16 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
})
|
||||
.collect();
|
||||
|
||||
let trace_layout = trace_pipeline.layout().set_layouts()[1].clone();
|
||||
let trace_descriptor_set = (0..frames)
|
||||
.map(|f| {
|
||||
DescriptorSet::new(
|
||||
descriptor_set_allocator.clone(),
|
||||
trace_layout.clone(),
|
||||
[WriteDescriptorSet::buffer(
|
||||
0,
|
||||
enable_buffer[f as usize].clone(),
|
||||
)],
|
||||
[],
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let normals_layout = normals_pipeline.layout().set_layouts()[1].clone();
|
||||
let normals_descriptor_set = (0..frames)
|
||||
.map(|f| {
|
||||
DescriptorSet::new(
|
||||
descriptor_set_allocator.clone(),
|
||||
normals_layout.clone(),
|
||||
[WriteDescriptorSet::buffer(
|
||||
0,
|
||||
enable_buffer[f as usize].clone(),
|
||||
)],
|
||||
[],
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let enable_gen_layout = enable_gen_pipeline.layout().set_layouts()[1].clone();
|
||||
let enable_gen_descriptor_set = (0..frames)
|
||||
.map(|f| {
|
||||
DescriptorSet::new(
|
||||
descriptor_set_allocator.clone(),
|
||||
enable_gen_layout.clone(),
|
||||
[
|
||||
WriteDescriptorSet::buffer(0, enable_buffer[f as usize].clone()),
|
||||
WriteDescriptorSet::buffer(1, aabb_buffer[f as usize].clone()),
|
||||
],
|
||||
[WriteDescriptorSet::buffer(
|
||||
0,
|
||||
aabb_buffer[f as usize].clone(),
|
||||
)],
|
||||
[],
|
||||
)
|
||||
.unwrap()
|
||||
@@ -227,24 +142,14 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
name: "example".to_string(),
|
||||
_seed: seed,
|
||||
parts,
|
||||
pos: Vec3::ZERO,
|
||||
rot: Vec3::ZERO,
|
||||
scale: Vec3::ONE,
|
||||
position: Default::default(),
|
||||
material: Default::default(),
|
||||
replacement_modules,
|
||||
trace_pipeline,
|
||||
normals_pipeline,
|
||||
fuzz_pipeline,
|
||||
enable_gen_pipeline,
|
||||
subdivision,
|
||||
enable_buffer,
|
||||
aabb_buffer,
|
||||
enable_buffer_host_visible,
|
||||
trace_descriptor_set,
|
||||
normals_descriptor_set,
|
||||
enable_gen_descriptor_set,
|
||||
colour: Vec3::ONE,
|
||||
roughness: 1.0,
|
||||
metallic: 0.67,
|
||||
}));
|
||||
|
||||
send.send(WorkComplete::CreateCSG(csg, index)).unwrap();
|
||||
@@ -255,47 +160,14 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
(csg_end - csg_start).as_secs_f64() * 1000.0
|
||||
);
|
||||
},
|
||||
WorkItem::GetPushConstants(
|
||||
csg,
|
||||
time,
|
||||
frame_index,
|
||||
command_allocator,
|
||||
transfer_queue,
|
||||
use_cpu_enable_gen,
|
||||
index,
|
||||
) => {
|
||||
WorkItem::GetPushConstants(csg, time, transform_buffer, csg_buffer, index) => {
|
||||
let csg = csg.read().unwrap();
|
||||
|
||||
let world = Mat4::from_translation(csg.pos * 0.01)
|
||||
* Mat4::from_euler(
|
||||
EulerRot::XYZ,
|
||||
csg.rot.x.to_radians(),
|
||||
csg.rot.y.to_radians(),
|
||||
csg.rot.z.to_radians(),
|
||||
)
|
||||
* Mat4::from_scale(csg.scale * 2.0);
|
||||
upload_transform(&csg.position, transform_buffer);
|
||||
|
||||
let push_constants = PushConstantData {
|
||||
world: world.to_cols_array_2d(),
|
||||
inv_world: world.inverse().to_cols_array_2d(),
|
||||
};
|
||||
interval_check(&csg, time, csg_buffer, index);
|
||||
|
||||
let future = interval_check(
|
||||
&csg,
|
||||
index as u32 + 1,
|
||||
time,
|
||||
frame_index,
|
||||
command_allocator,
|
||||
transfer_queue,
|
||||
use_cpu_enable_gen,
|
||||
);
|
||||
|
||||
send.send(WorkComplete::GetPushConstants(
|
||||
push_constants,
|
||||
future,
|
||||
index,
|
||||
))
|
||||
.unwrap();
|
||||
send.send(WorkComplete::GetPushConstants(index)).unwrap();
|
||||
},
|
||||
WorkItem::RecompileShaders(csg, device, replacement_modules, index) => {
|
||||
let csg_start = Instant::now();
|
||||
@@ -319,27 +191,12 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
(csg_end - csg_start).as_secs_f64() * 1000.0
|
||||
);
|
||||
},
|
||||
WorkItem::RecompilePipelines(
|
||||
csg,
|
||||
device,
|
||||
render_pass,
|
||||
cache,
|
||||
normal_modules,
|
||||
debug,
|
||||
index,
|
||||
) => {
|
||||
WorkItem::RecompilePipelines(csg, device, cache, debug, index) => {
|
||||
let csg_start = Instant::now();
|
||||
let mut csg = csg.write().unwrap();
|
||||
(
|
||||
csg.trace_pipeline,
|
||||
csg.normals_pipeline,
|
||||
csg.fuzz_pipeline,
|
||||
csg.enable_gen_pipeline,
|
||||
) = deferred_pipelines_recompile(
|
||||
(csg.fuzz_pipeline, csg.enable_gen_pipeline) = deferred_pipelines_recompile(
|
||||
device,
|
||||
render_pass,
|
||||
cache,
|
||||
normal_modules,
|
||||
csg.replacement_modules.clone(),
|
||||
debug,
|
||||
);
|
||||
@@ -359,144 +216,14 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
|
||||
|
||||
fn deferred_pipelines_recompile(
|
||||
device: Arc<Device>,
|
||||
render_pass: Arc<RenderPass>,
|
||||
cache: Arc<PipelineCache>,
|
||||
shader_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
|
||||
replacement_modules: Arc<RwLock<HashMap<String, Arc<ShaderModule>>>>,
|
||||
debug: PreviousDebug,
|
||||
) -> (
|
||||
Arc<GraphicsPipeline>,
|
||||
Arc<GraphicsPipeline>,
|
||||
Arc<ComputePipeline>,
|
||||
Arc<ComputePipeline>,
|
||||
) {
|
||||
) -> (Arc<ComputePipeline>, Arc<ComputePipeline>) {
|
||||
let specs = get_spec_constants(&debug);
|
||||
|
||||
let dynamic_state = [DynamicState::Viewport].into_iter().collect::<HashSet<_>>();
|
||||
|
||||
let shader_modules = shader_modules.read().unwrap();
|
||||
let replacement_modules = replacement_modules.read().unwrap();
|
||||
|
||||
let trace_vs_entry = shader_modules["trace.vert"]
|
||||
.specialize(specs.clone())
|
||||
.unwrap()
|
||||
.single_entry_point()
|
||||
.unwrap();
|
||||
|
||||
let vertex_input_state = [IVertex::per_vertex()].definition(&trace_vs_entry).unwrap();
|
||||
|
||||
let trace_vs_info = PipelineShaderStageCreateInfo::new(trace_vs_entry);
|
||||
|
||||
let trace_fs_info = PipelineShaderStageCreateInfo::new(
|
||||
replacement_modules["trace.frag"]
|
||||
.specialize(specs.clone())
|
||||
.unwrap()
|
||||
.single_entry_point()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let layout = PipelineLayout::new(
|
||||
device.clone(),
|
||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([&trace_vs_info, &trace_fs_info])
|
||||
.into_pipeline_layout_create_info(device.clone())
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let stages = [trace_vs_info.clone(), trace_fs_info].into_iter().collect();
|
||||
|
||||
let trace_subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
|
||||
let trace_pipeline = GraphicsPipeline::new(
|
||||
device.clone(),
|
||||
Some(cache.clone()),
|
||||
GraphicsPipelineCreateInfo {
|
||||
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION,
|
||||
stages,
|
||||
vertex_input_state: Some(vertex_input_state.clone()),
|
||||
input_assembly_state: Some(InputAssemblyState::default()),
|
||||
dynamic_state: dynamic_state.clone(),
|
||||
viewport_state: Some(Default::default()),
|
||||
rasterization_state: Some(RasterizationState {
|
||||
front_face: FrontFace::Clockwise,
|
||||
cull_mode: CullMode::Back,
|
||||
polygon_mode: PolygonMode::Fill,
|
||||
..RasterizationState::default()
|
||||
}),
|
||||
depth_stencil_state: Some(DepthStencilState {
|
||||
depth: Some(DepthState::reverse()),
|
||||
..Default::default()
|
||||
}),
|
||||
multisample_state: Some(MultisampleState::default()),
|
||||
color_blend_state: Some(ColorBlendState::with_attachment_states(
|
||||
trace_subpass.num_color_attachments(),
|
||||
ColorBlendAttachmentState::default(),
|
||||
)),
|
||||
subpass: Some(trace_subpass.into()),
|
||||
..GraphicsPipelineCreateInfo::layout(layout.clone())
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let fullscreen_vs_entry = shader_modules["fullscreen.vert"]
|
||||
.specialize(specs.clone())
|
||||
.unwrap()
|
||||
.single_entry_point()
|
||||
.unwrap();
|
||||
|
||||
let vertex_input_state = VertexInputState::new();
|
||||
|
||||
let fullscreen_vs_info = PipelineShaderStageCreateInfo::new(fullscreen_vs_entry);
|
||||
|
||||
let normals_fs_info = PipelineShaderStageCreateInfo::new(
|
||||
replacement_modules["normals.frag"]
|
||||
.specialize(specs.clone())
|
||||
.unwrap()
|
||||
.single_entry_point()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let layout = PipelineLayout::new(
|
||||
device.clone(),
|
||||
PipelineDescriptorSetLayoutCreateInfo::from_stages([&fullscreen_vs_info, &normals_fs_info])
|
||||
.into_pipeline_layout_create_info(device.clone())
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let stages = [fullscreen_vs_info.clone(), normals_fs_info]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let normals_subpass = Subpass::from(render_pass.clone(), 1).unwrap();
|
||||
|
||||
let normals_pipeline = GraphicsPipeline::new(
|
||||
device.clone(),
|
||||
Some(cache.clone()),
|
||||
GraphicsPipelineCreateInfo {
|
||||
flags: PipelineCreateFlags::DISABLE_OPTIMIZATION,
|
||||
stages,
|
||||
vertex_input_state: Some(vertex_input_state.clone()),
|
||||
input_assembly_state: Some(InputAssemblyState::default()),
|
||||
dynamic_state: dynamic_state.clone(),
|
||||
viewport_state: Some(Default::default()),
|
||||
rasterization_state: Some(RasterizationState {
|
||||
front_face: FrontFace::Clockwise,
|
||||
cull_mode: CullMode::Back,
|
||||
polygon_mode: PolygonMode::Fill,
|
||||
..RasterizationState::default()
|
||||
}),
|
||||
depth_stencil_state: None,
|
||||
multisample_state: Some(MultisampleState::default()),
|
||||
color_blend_state: Some(ColorBlendState::with_attachment_states(
|
||||
normals_subpass.num_color_attachments(),
|
||||
ColorBlendAttachmentState::default(),
|
||||
)),
|
||||
subpass: Some(normals_subpass.into()),
|
||||
..GraphicsPipelineCreateInfo::layout(layout.clone())
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let fuzz_cs_info = PipelineShaderStageCreateInfo::new(
|
||||
replacement_modules["fuzz.comp"]
|
||||
.specialize(specs.clone())
|
||||
@@ -515,7 +242,7 @@ fn deferred_pipelines_recompile(
|
||||
|
||||
let fuzz_pipeline = ComputePipeline::new(
|
||||
device.clone(),
|
||||
None,
|
||||
Some(cache.clone()),
|
||||
ComputePipelineCreateInfo::stage_layout(fuzz_cs_info, fuzz_pipeline_layout.clone()),
|
||||
)
|
||||
.expect("failed to create fuzz pipeline");
|
||||
@@ -538,7 +265,7 @@ fn deferred_pipelines_recompile(
|
||||
|
||||
let enable_gen_pipeline = ComputePipeline::new(
|
||||
device.clone(),
|
||||
None,
|
||||
Some(cache.clone()),
|
||||
ComputePipelineCreateInfo::stage_layout(
|
||||
enable_gen_cs_info,
|
||||
enable_gen_pipeline_layout.clone(),
|
||||
@@ -546,12 +273,7 @@ fn deferred_pipelines_recompile(
|
||||
)
|
||||
.expect("failed to create enable_gen pipeline");
|
||||
|
||||
(
|
||||
trace_pipeline,
|
||||
normals_pipeline,
|
||||
fuzz_pipeline,
|
||||
enable_gen_pipeline,
|
||||
)
|
||||
(fuzz_pipeline, enable_gen_pipeline)
|
||||
}
|
||||
|
||||
fn create_csg(seed: u64) -> SSATape {
|
||||
@@ -720,13 +442,10 @@ fn create_csg(seed: u64) -> SSATape {
|
||||
|
||||
fn interval_check(
|
||||
csg: &CSG,
|
||||
material: u32,
|
||||
time: f32,
|
||||
frame_index: usize,
|
||||
command_allocator: Arc<dyn CommandBufferAllocator>,
|
||||
transfer_queue: Arc<Queue>,
|
||||
use_cpu_enable_gen: bool,
|
||||
) -> Box<dyn GpuFuture + Send + Sync> {
|
||||
csg_buffer: Subbuffer<[enable_gen_cs::Object]>,
|
||||
index: usize,
|
||||
) {
|
||||
const INTERPRET_INPUT_X: interpreters::Value =
|
||||
interpreters::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]);
|
||||
const INTERPRET_INPUT_Y: interpreters::Value =
|
||||
@@ -762,116 +481,27 @@ fn interval_check(
|
||||
assert!(csg.subdivision <= MAXIMUM_SUBDIVISION);
|
||||
assert!(csg.subdivision >= MINUMUM_SUBDIVISION);
|
||||
|
||||
let xdim = csg.subdivision as usize;
|
||||
let ydim = csg.subdivision as usize;
|
||||
let zdim = csg.subdivision as usize;
|
||||
|
||||
let mut obj = Object {
|
||||
dimensions: (highest_corner - lowest_corner).to_array().into(),
|
||||
lowest_corner: lowest_corner.into(),
|
||||
enable: [[0; 4];
|
||||
(MAXIMUM_SUBDIVISION * MAXIMUM_SUBDIVISION * MAXIMUM_SUBDIVISION) as usize / (32 * 4)],
|
||||
material,
|
||||
subdivision_log2: csg.subdivision.ilog2(),
|
||||
farplane: ((highest_corner - lowest_corner).length() / csg.subdivision as f32).into(),
|
||||
colour: csg.colour.to_array(),
|
||||
roughness: csg.roughness,
|
||||
metallic: csg.metallic,
|
||||
let obj = enable_gen_cs::Object {
|
||||
dimensions: (highest_corner - lowest_corner).to_array().into(),
|
||||
lowest_corner: lowest_corner.into(),
|
||||
subdivision_log2: csg.subdivision.ilog2(),
|
||||
colour_and_roughness: [
|
||||
csg.material.colour[0],
|
||||
csg.material.colour[1],
|
||||
csg.material.colour[2],
|
||||
csg.material.roughness,
|
||||
],
|
||||
metallic: csg.material.metallic,
|
||||
subsurface: csg.material.subsurface,
|
||||
specular: csg.material.specular,
|
||||
specular_tint: csg.material.specular_tint,
|
||||
sheen: csg.material.sheen,
|
||||
sheen_tint: csg.material.sheen_tint,
|
||||
clear_coat_gloss: csg.material.clear_coat_gloss,
|
||||
clear_coat: csg.material.clear_coat,
|
||||
};
|
||||
|
||||
if use_cpu_enable_gen {
|
||||
for x in 0..xdim {
|
||||
for y in 0..ydim {
|
||||
for z in 0..(zdim / 8) {
|
||||
let interval_input_z: Interval = Interval::new_unchecked(
|
||||
interpreters::Value::from_array([
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (0.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (1.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (2.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (3.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (4.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (5.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (6.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (7.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
]),
|
||||
interpreters::Value::from_array([
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (1.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (2.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (3.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (4.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (5.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (6.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (7.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
((((8.0 / (zdim as f32)) * z as f32) + (8.0 / (zdim as f32)))
|
||||
* obj.dimensions[2])
|
||||
+ obj.lowest_corner[2],
|
||||
]),
|
||||
);
|
||||
|
||||
let mut interpreter = IntervalInterpreter::new(&csg.parts);
|
||||
let output = interpreter.scene(
|
||||
Interval::const_splat2(
|
||||
(x as f32 / (xdim as f32)) * obj.dimensions[0] + obj.lowest_corner[0],
|
||||
((x + 1) as f32 / (xdim as f32)) * obj.dimensions[0]
|
||||
+ obj.lowest_corner[0],
|
||||
),
|
||||
Interval::const_splat2(
|
||||
(y as f32 / (ydim as f32)) * obj.dimensions[1] + obj.lowest_corner[1],
|
||||
((y + 1) as f32 / (ydim as f32)) * obj.dimensions[1]
|
||||
+ obj.lowest_corner[1],
|
||||
),
|
||||
interval_input_z,
|
||||
Interval::const_splat(time),
|
||||
);
|
||||
|
||||
let total_index = (x * zdim * ydim) + (y * zdim) + (z * 8);
|
||||
let output = ((output.lower().simd_le(VALUE_0)
|
||||
& output.upper().simd_ge(VALUE_0))
|
||||
.to_bitmask() as u32)
|
||||
<< (total_index & 31);
|
||||
obj.enable[total_index >> 7][(total_index >> 5) & 3] |= output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gpu_upload(
|
||||
obj,
|
||||
csg.enable_buffer[frame_index].clone(),
|
||||
csg.enable_buffer_host_visible[frame_index].clone(),
|
||||
command_allocator,
|
||||
transfer_queue,
|
||||
)
|
||||
gpu_upload(obj, csg_buffer.index(index as _))
|
||||
}
|
||||
|
||||
fn sdf_specialize_module(
|
||||
|
||||
Reference in New Issue
Block a user