summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c2.cpp10
-rw-r--r--camera.cpp24
-rw-r--r--camera.hpp20
-rw-r--r--intermediate/surface.glsl68
-rw-r--r--lighting.cpp76
-rw-r--r--lighting.hpp30
-rw-r--r--maths.cpp28
-rw-r--r--maths.hpp1
-rw-r--r--model.cpp17
-rw-r--r--model.hpp7
-rw-r--r--renderer.cpp21
-rw-r--r--renderer.hpp15
-rw-r--r--sc/sc.cpp6
-rw-r--r--video.cpp26
-rw-r--r--video.hpp5
15 files changed, 292 insertions, 62 deletions
diff --git a/c2.cpp b/c2.cpp
index d5b262a..761d9de 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -754,7 +754,7 @@ struct C2 : public App {
auto sun = world->create_entity();
auto [light] = world->add<Sun_Light>(sun);
light.colour = v3f(1.0f, 0.95f, 0.80f);
- light.dir = v3f(0.57f, 0.57f, 0.57f);
+ light.dir = v3f(-0.57f, 0.57f, 0.57f);
light.brightness = 1.0f;
light.caster = true;
}
@@ -889,15 +889,15 @@ struct C2 : public App {
renderer.env_cubemap = eprobe.get_cubemap();
renderer.clamped_linear = clamped_linear;
- renderer.drawlists[FORWARD].camera = camera;
- renderer.drawlists[SHADOW_MAP_START].camera = camera;
+ renderer.setcam(FORWARD, camera);
Texture& bb = dev->get_texture(hdr_target);
pcam.asp = (float)bb.w / (float)bb.h;
orbit_cam.update_orbit(*this);
pcam.update();
- lighting.update(dev, ctx, *world);
+ lighting.update(dev, ctx, *world, renderer, scene);
update_scene(scene, dev, lighting, pcam, *world);
+ lr.add_box(scene.bound);
ctx.debug_push("scene");
renderer.render(
dev,
@@ -1004,7 +1004,7 @@ struct C2 : public App {
quad.destroy(dev);
scene.destroy(dev);
sky.destroy(dev);
- lighting.destroy(dev);
+ lighting.destroy(dev, renderer);
lr.destroy(dev);
eprobe.destroy(dev);
tonemap.destroy(dev);
diff --git a/camera.cpp b/camera.cpp
index 59a604e..a224fb3 100644
--- a/camera.cpp
+++ b/camera.cpp
@@ -9,6 +9,30 @@ void Camera::init(float vfov, const v3f& f, const v3f& p) {
asp = 1.0f;
}
+void Camera::init_shadow(
+ const v3f& dir,
+ const v3f& mic,
+ const v3f& mac
+) {
+ v3f up(0.0f, 1.0f, 0.0f);
+ AABB aabb = { mic, mac };
+ init(0.0f, dir, v3f(0.0f));
+ view = m4f::lookat(
+ dir,
+ v3f(0.0f),
+ up
+ );
+ aabb = m4f::transform(view, aabb);
+ proj = m4f::orth(
+ aabb.min.x,
+ aabb.max.x,
+ aabb.max.y,
+ aabb.min.y,
+ aabb.min.z,
+ aabb.max.z
+ );
+}
+
void Camera::update() {
v3f up(0.0f, 1.0f, 0.0f);
view = m4f::lookat(position, position + forward, up);
diff --git a/camera.hpp b/camera.hpp
index f88b4fe..15537f0 100644
--- a/camera.hpp
+++ b/camera.hpp
@@ -1,16 +1,36 @@
#ifndef camera_hpp
#define camera_hpp
+#include "hashmap.hpp"
#include "maths.hpp"
+#include "video.hpp"
struct Camera {
float fov, near, far, asp;
v3f forward, position;
m4f view, proj;
+ int type;
void init(float vfov, const v3f& f, const v3f& p);
+ void init_shadow(
+ const v3f& dir,
+ const v3f& mic,
+ const v3f& mac
+ );
void update();
const m4f& get_view() const;
const m4f& get_proj() const;
};
+struct Camera_Id : public Primitive_Id<uint32_t> {
+ using Primitive_Id<uint32_t>::Primitive_Id;
+};
+
+template<>
+struct Hash_Function<Camera_Id> {
+ size_t operator()(Camera_Id id) const {
+ return id.index;
+ }
+};
+
+
#endif
diff --git a/intermediate/surface.glsl b/intermediate/surface.glsl
index 9fc1c48..10944ae 100644
--- a/intermediate/surface.glsl
+++ b/intermediate/surface.glsl
@@ -74,6 +74,15 @@ type: float
[variable]
name: colour
type: vec3
+[variable]
+name: caster_id
+type: int
+
+[struct]
+name: Caster
+[variable]
+name: projection
+type: mat4
[cbuffer]
name: c_vp
@@ -95,6 +104,11 @@ name: lights
type: Light
stage: fragment
+[sbuffer]
+name: casters
+type: Caster
+stage: fragment
+
[texture]
name: albedo
stage: fragment
@@ -119,6 +133,10 @@ dimension: 2
name: env_cube
stage: fragment
dimension: cube
+[texture]
+name: shadowmaps
+stage: fragment
+dimension: shadowArray
[target]
name: colour
@@ -174,6 +192,51 @@ float specular_brdf(vec2 uv, vec3 ref, vec3 l, vec3 v, vec3 n) {
return (D * F * G) / (4.0 * ndl * ndv + 0.001);
}
+vec2 poissonDisk[16] = vec2[](
+ vec2(-0.94201624, -0.39906216),
+ vec2(0.94558609, -0.76890725),
+ vec2(-0.094184101, -0.92938870),
+ vec2(0.34495938, 0.29387760),
+ vec2(-0.91588581, 0.45771432),
+ vec2(-0.81544232, -0.87912464),
+ vec2(-0.38277543, 0.27676845),
+ vec2(0.97484398, 0.75648379),
+ vec2(0.44323325, -0.97511554),
+ vec2(0.53742981, -0.47373420),
+ vec2(-0.26496911, -0.41893023),
+ vec2(0.79197514, 0.19090188),
+ vec2(-0.24188840, 0.99706507),
+ vec2(-0.81409955, 0.91437590),
+ vec2(0.19984126, 0.78641367),
+ vec2(0.14383161, -0.14100790)
+);
+
+float random(vec3 seed, int i){
+ vec4 seed4 = vec4(seed,i);
+ float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
+ return fract(sin(dot_product) * 43758.5453);
+}
+
+float get_shadow(Light l, vec3 wpos) {
+ const int taps = 4;
+ const float w = 1.0 / float(taps);
+ const float m = 1.0 / 1000.0;
+ int i;
+ float d = 0.0f;
+ Caster caster = casters[l.caster_id];
+ vec4 surf = caster.projection * vec4(wpos, 1.0);
+ surf /= surf.w;
+ surf.xy = surf.xy * 0.5 + 0.5;
+ surf.z -= 0.005;
+ for (i = 0; i < taps; i++) {
+ int index = int(16.0 * random(floor(wpos.xyz * 1000.0), i)) % 16;
+ vec2 coord = surf.xy + poissonDisk[index] * m;
+ vec4 vec = vec4(coord, float(l.caster_id), surf.z);
+ d += texture(shadowmaps, vec).r * w;
+ }
+ return d;
+}
+
void main() {
int i;
vec2 uv = interpolator.uv;
@@ -210,7 +273,10 @@ void main() {
spec_col *
specular_brdf(uv, ref, light_dir, view_dir, nrm) *
cos_theta_i;
- light += (diffuse + spec) * l.brightness * l.colour;
+ float shadow = 1.0f;
+ if (l.caster_id >= 0)
+ shadow = get_shadow(l, p);
+ light += (diffuse + spec) * l.brightness * l.colour * shadow;
}
colour = vec4(ambient + light, 1.0);
diff --git a/lighting.cpp b/lighting.cpp
index 75ae7c2..0e41ddd 100644
--- a/lighting.cpp
+++ b/lighting.cpp
@@ -1,5 +1,6 @@
#include "lighting.hpp"
#include "model.hpp"
+#include "renderer.hpp"
#include "world.hpp"
extern "C" {
@@ -12,17 +13,28 @@ struct GPU_Light {
v3f dir;
float brightness;
v3f colour;
- float pad;
+ int caster_id;
+};
+
+struct GPU_Caster {
+ m4f projection;
};
void Lighting::init(Device* dev) {
int i;
+ Sampler_State ss{};
lights.init(
dev,
"Light buffer",
max_lights * sizeof(GPU_Light),
Buffer_Flags::storage_buffer
);
+ casters.init(
+ dev,
+ "Caster buffer",
+ max_shadows * sizeof(GPU_Caster),
+ Buffer_Flags::storage_buffer
+ );
shadows = dev->create_texture(
"Shadowmap Array",
texture_format_d16,
@@ -35,6 +47,7 @@ void Lighting::init(Device* dev) {
0
);
for (i = 0; i < max_shadows; i++) {
+ cameras[i] = 0;
shadow_slices[i] = dev->alias_texture(
shadows,
"Shadowmap Slice",
@@ -49,18 +62,40 @@ void Lighting::init(Device* dev) {
i
);
}
+ ss.min = Filter_Mode::linear;
+ ss.mag = Filter_Mode::linear;
+ ss.mip = Filter_Mode::linear;
+ ss.address_u = Address_Mode::border;
+ ss.address_v = Address_Mode::border;
+ ss.border[0] = 1.0f;
+ ss.border[1] = 1.0f;
+ ss.border[2] = 1.0f;
+ ss.border[3] = 1.0f;
+ ss.compare = Depth_Mode::less;
+ shadow_sampler = dev->create_sampler("shadow sampler", ss);
}
-void Lighting::destroy(Device* dev) {
+void Lighting::destroy(Device* dev, Renderer& r) {
int i;
lights.destroy(dev);
- for (i = 0; i < max_shadows; i++)
+ casters.destroy(dev);
+ dev->destroy_sampler(shadow_sampler);
+ for (i = 0; i < max_shadows; i++) {
dev->destroy_texture(shadow_slices[i]);
+ r.destroy_camera(cameras[i]);
+ }
dev->destroy_texture(shadows);
}
-void Lighting::write_buf(void* ptr, World& w) {
- GPU_Light* dst = (GPU_Light*)ptr;
+void Lighting::write_bufs(
+ void* lptr,
+ void* cptr,
+ World& w,
+ Renderer& r,
+ Model_Scene& s
+) {
+ GPU_Light* ldst = (GPU_Light*)lptr;
+ GPU_Caster* cdst = (GPU_Caster*)cptr;
int count = 0, ccount = 0;
for (auto v : w.view<Sun_Light>()) {
GPU_Light gl;
@@ -72,20 +107,37 @@ void Lighting::write_buf(void* ptr, World& w) {
gl.brightness = l.brightness;
gl.colour = l.colour;
gl.dir = l.dir;
- dst[count++] = gl;
- if (l.caster) {
- Caster& c = casters[ccount++];
- c.vp = m4f::identity();
- }
+ if (l.caster && ccount < max_shadows) {
+ int cid = ccount++;
+ GPU_Caster& c = cdst[cid];
+ Camera_Id camid = cameras[cid];
+ if (!camid)
+ camid = r.create_camera();
+ Camera& cam = r.get_camera(camid);
+ cam.init_shadow(l.dir, s.bound.min, s.bound.max);
+ c.projection = cam.get_proj() * cam.get_view();
+ cameras[cid] = camid;
+ gl.caster_id = cid;
+ } else
+ gl.caster_id = -1;
+ ldst[count++] = gl;
}
light_count = count;
caster_count = ccount;
}
-void Lighting::update(Device* dev, Context& ctx, World& w) {
+void Lighting::update(
+ Device* dev,
+ Context& ctx,
+ World& w,
+ Renderer& r,
+ Model_Scene& s
+) {
light_count = 0;
- write_buf(lights.map(dev), w);
+ write_bufs(lights.map(dev), casters.map(dev), w, r, s);
+ casters.unmap(dev);
lights.unmap(dev);
lights.update(ctx);
+ casters.update(ctx);
}
diff --git a/lighting.hpp b/lighting.hpp
index 627de66..ccd08d3 100644
--- a/lighting.hpp
+++ b/lighting.hpp
@@ -1,31 +1,43 @@
#ifndef lighting_hpp
#define lighting_hpp
+#include "camera.hpp"
#include "maths.hpp"
#include "video.hpp"
struct Arena;
struct Model_Resources;
struct Model_Scene;
+struct Renderer;
struct World;
-struct Caster {
- m4f vp;
-};
-
struct Lighting {
static constexpr int max_lights = 128;
static constexpr int max_shadows = 16;
- static constexpr int shadow_res = 512;
+ static constexpr int shadow_res = 2048;
Staged_Buffer lights;
+ Staged_Buffer casters;
Texture_Id shadows;
Texture_Id shadow_slices[max_shadows];
- Caster casters[max_shadows];
+ Sampler_Id shadow_sampler;
+ Camera_Id cameras[max_shadows];
int light_count, caster_count;
void init(Device* dev);
- void destroy(Device* dev);
- void update(Device* dev, Context& ctx, World& w);
- void write_buf(void* ptr, World& w);
+ void destroy(Device* dev, Renderer& r);
+ void update(
+ Device* dev,
+ Context& ctx,
+ World& w,
+ Renderer& r,
+ Model_Scene& s
+ );
+ void write_bufs(
+ void* lptr,
+ void* cptr,
+ World& w,
+ Renderer& r,
+ Model_Scene& s
+ );
};
struct Light {
diff --git a/maths.cpp b/maths.cpp
index 39a1163..bdda15b 100644
--- a/maths.cpp
+++ b/maths.cpp
@@ -2,6 +2,15 @@
#include <algorithm>
+void AABB::encompass(const AABB& other) {
+ min.x = std::min(min.x, other.min.x);
+ min.y = std::min(min.y, other.min.y);
+ min.z = std::min(min.z, other.min.z);
+ max.x = std::max(max.x, other.max.x);
+ max.y = std::max(max.y, other.max.y);
+ max.z = std::max(max.z, other.max.z);
+}
+
namespace quat {
v4f identity() {
return v4f(0.0f, 0.0f, 0.0f, 1.0f);
@@ -285,19 +294,12 @@ m4f m4f::pers(float fov, float asp, float n, float f) {
m4f m4f::orth(float l, float r, float b, float t, float n, float f) {
m4f res(1.0f);
- float* data = (float*)res.m;
-
- float lr = 1.0f / (l - r);
- float bt = 1.0f / (b - t);
- float nf = 1.0f / (n - f);
-
- data[0] = -2.0f * lr;
- data[5] = -2.0f * bt;
- data[10] = 2.0f * nf;
-
- data[12] = (l + r) * lr;
- data[13] = (t + b) * bt;
- data[14] = (f + n) * nf;
+ res.m[0][0] = 2.0f / (r - l);
+ res.m[1][1] = 2.0f / (b - t);
+ res.m[2][2] = 1.0f / (n - f);
+ res.m[3][0] = -(l + r) / (r - l);
+ res.m[3][1] = -(b + t) / (b - t);
+ res.m[3][2] = n / (n - f);
return res;
}
diff --git a/maths.hpp b/maths.hpp
index e432529..eeedec1 100644
--- a/maths.hpp
+++ b/maths.hpp
@@ -474,6 +474,7 @@ template struct v4<double>;
struct AABB {
v3f min, max;
+ void encompass(const AABB& other);
};
namespace quat {
diff --git a/model.cpp b/model.cpp
index caa1422..765da15 100644
--- a/model.cpp
+++ b/model.cpp
@@ -136,6 +136,8 @@ Asset* Model_Loader::load(
mesh.vp_binding_depth = depth_shader->descriptor_binding("c_vp");
mesh.mat_binding = shader->descriptor_binding("material");
mesh.light_binding = shader->descriptor_binding("lights");
+ mesh.casters_binding = shader->descriptor_binding("casters");
+ mesh.shadowmaps_binding = shader->descriptor_binding("shadowmaps");
mesh.env_cube_binding = shader->descriptor_binding("env_cube");
mesh.mesh_binding = shader->binding_index("mesh");
assert(mesh.model_binding >= 0);
@@ -144,6 +146,8 @@ Asset* Model_Loader::load(
assert(mesh.vp_binding_depth >= 0);
assert(mesh.mat_binding >= 0);
assert(mesh.light_binding >= 0);
+ assert(mesh.casters_binding >= 0);
+ assert(mesh.shadowmaps_binding >= 0);
assert(mesh.mesh_binding >= 0);
assert(mesh.env_cube_binding >= 0);
pack_read(f, &vertex_size, 4);
@@ -296,11 +300,15 @@ void Model_Instance::destroy(Device* dev, Heap* h) {
void Model_Instance::update() {
Mesh* meshes = m->get_meshes();
int i, c = m->mesh_count;
- for (i = 0; i < c; i++)
+ bound.min = v3f( INFINITY);
+ bound.max = v3f(-INFINITY);
+ for (i = 0; i < c; i++) {
bounds[i] = m4f::transform(
transform * meshes[i].world,
meshes[i].bound
);
+ bound.encompass(bounds[i]);
+ }
}
void Model_Instance::update_cbuffers(
@@ -388,6 +396,8 @@ void Model_Instance::render(
pb.depth(true, false, Depth_Mode::equal);
pb.shader(mesh.shader);
pb.sbuffer(mesh.light_binding, lighting->lights.gpuonly);
+ pb.sbuffer(mesh.casters_binding, lighting->casters.gpuonly);
+ pb.texture(mesh.shadowmaps_binding, lighting->shadows, lighting->shadow_sampler);
mesh.material->use(pb, res.sampler, dev->get_shader(mesh.shader));
pb.cbuffer(
mesh.mat_binding,
@@ -413,6 +423,8 @@ void Model_Instance::render(
}
pb.cull(Cull_Mode::back);
pb.vertex_format(shader.vf);
+ if (res.overrider)
+ res.overrider(pb);
Pipeline& pip = pb.build();
ctx.submit(draw, pip, pass);
}
@@ -465,9 +477,12 @@ void Model_Scene::update(
) {
int i;
Model_Instance* instance = instances;
+ bound.min = v3f( INFINITY);
+ bound.max = v3f(-INFINITY);
for (i = 0; i < count; i++, instance++) {
instance->update();
instance->update_cbuffers(dev, lighting, cam);
+ bound.encompass(instance->bound);
}
}
diff --git a/model.hpp b/model.hpp
index 23f3825..e7b07e6 100644
--- a/model.hpp
+++ b/model.hpp
@@ -38,7 +38,9 @@ struct Mesh {
vp_binding,
vp_binding_depth,
mat_binding,
- light_binding;
+ light_binding,
+ shadowmaps_binding,
+ casters_binding;
int env_cube_binding;
bool world_dirty;
m4f world, local;
@@ -96,6 +98,7 @@ struct Model_Resources {
Texture_Id env_cubemap;
Sampler_Id sampler;
Buffer_Id vp;
+ void (*overrider)(Pipeline_Builder&);
};
struct Model_Instance {
@@ -104,6 +107,7 @@ struct Model_Instance {
m4f transform;
Model* m;
AABB* bounds;
+ AABB bound;
void init(Device* dev, Heap* h, Model* model);
void destroy(Device* dev, Heap* h);
@@ -127,6 +131,7 @@ struct Model_Scene {
Model_Instance* instances;
int count, max;
Sampler_Id sampler;
+ AABB bound;
Model_Instance* instantiate(Device* dev, Model* model);
void uninstantiate(Device* dev, Model_Instance* model);
diff --git a/renderer.cpp b/renderer.cpp
index 2d28ceb..cc7cc6d 100644
--- a/renderer.cpp
+++ b/renderer.cpp
@@ -57,11 +57,12 @@ void Drawlist::render(
Device* dev,
Arena* a,
const Lighting* l,
- Render_Pass& pass
+ Render_Pass& pass,
+ void (*overrider)(Pipeline_Builder&)
) {
int i, c = count;
const Camera& cam = r.get_camera(camera);
- Model_Resources res;
+ Model_Resources res{};
VP_Cbuffer* vpc = (VP_Cbuffer*)vp.map(dev);
vpc->view_projection = cam.get_proj() * cam.get_view();
vp.unmap(dev);
@@ -69,6 +70,7 @@ void Drawlist::render(
res.sampler = r.clamped_linear;
res.env_cubemap = r.env_cubemap;
res.vp = vp.gpuonly;
+ res.overrider = overrider;
for (i = 0; i < c; i++) {
models[i]->render(dev, a, pass, l, res);
}
@@ -102,7 +104,7 @@ void Renderer::render(
}
ctx.debug_push("depth prepass");
- drawlists[FORWARD].render(*this, dev, a, l, depth_prepass);
+ drawlists[FORWARD].render(*this, dev, a, l, depth_prepass, 0);
ctx.debug_pop();
ctx.debug_push("shadow maps");
@@ -111,14 +113,18 @@ void Renderer::render(
i < SHADOW_MAP_END && j < l->caster_count;
i++, j++
) {
+ auto o = [](Pipeline_Builder& pb) {
+ pb.cull(Cull_Mode::front);
+ };
+ setcam(i, l->cameras[j]);
ctx.debug_push("shadow map");
- drawlists[i].render(*this, dev, a, l, *shadow_passes[j]);
+ drawlists[i].render(*this, dev, a, l, *shadow_passes[j], o);
ctx.debug_pop();
}
ctx.debug_pop();
ctx.debug_push("forward");
- drawlists[FORWARD].render(*this, dev, a, l, forward_pass);
+ drawlists[FORWARD].render(*this, dev, a, l, forward_pass, 0);
ctx.debug_pop();
}
@@ -167,3 +173,8 @@ const Camera& Renderer::get_camera(Camera_Id id) const {
void Renderer::destroy_camera(Camera_Id cam) {
cameras.remove(cam);
}
+
+void Renderer::setcam(int did, Camera_Id cam) {
+ assert(cam.index);
+ drawlists[did].camera = cam;
+}
diff --git a/renderer.hpp b/renderer.hpp
index 29a9dd0..ae638e0 100644
--- a/renderer.hpp
+++ b/renderer.hpp
@@ -12,17 +12,6 @@ enum {
SHADOW_MAP_END = SHADOW_MAP_START + Lighting::max_shadows,
drawlist_count = SHADOW_MAP_END };
-struct Camera_Id : public Primitive_Id<uint32_t> {
- using Primitive_Id<uint32_t>::Primitive_Id;
-};
-
-template<>
-struct Hash_Function<Camera_Id> {
- size_t operator()(Camera_Id id) const {
- return id.index;
- }
-};
-
struct Model_Instance;
struct Renderer;
@@ -38,7 +27,8 @@ struct Drawlist {
Device* dev,
Arena* a,
const Lighting* l,
- Render_Pass& pass
+ Render_Pass& pass,
+ void (*overrider)(Pipeline_Builder&)
);
};
@@ -69,6 +59,7 @@ struct Renderer {
Camera& get_camera(Camera_Id cam);
const Camera& get_camera(Camera_Id cam) const;
void destroy_camera(Camera_Id cam);
+ void setcam(int did, Camera_Id cam);
};
#endif
diff --git a/sc/sc.cpp b/sc/sc.cpp
index d7e9038..d801a68 100644
--- a/sc/sc.cpp
+++ b/sc/sc.cpp
@@ -289,6 +289,8 @@ struct Desc {
t.stage |= 1 << stage_from_string(sstage);
t.dimension =
sdem && string_equal(sdem, "cube")? -6:
+ sdem && string_equal(sdem, "array")? -20:
+ sdem && string_equal(sdem, "shadowArray")? -21:
find_int_default(desc, "dimension", 2);
}
cfg_Object* read_struct(cfg_Object* desc) {
@@ -495,6 +497,10 @@ struct Desc {
ss << "uniform sampler";
if (texture.dimension == -6)
ss << "Cube ";
+ else if (texture.dimension == -20)
+ ss << "2DArray ";
+ else if (texture.dimension == -21)
+ ss << "2DArrayShadow ";
else
ss << texture.dimension << "D ";
ss << it.first << ";\n";
diff --git a/video.cpp b/video.cpp
index 7fe26b1..fa98813 100644
--- a/video.cpp
+++ b/video.cpp
@@ -2347,6 +2347,22 @@ void Context::transition(Texture_Id id, Resource_State state) {
src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dst_stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
} else if (
+ src_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL &&
+ dst_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
+ ) {
+ b.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ b.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ src_stage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ dst_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ } else if (
+ src_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL &&
+ dst_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
+ ) {
+ b.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ b.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ src_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ dst_stage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ } else if (
src_layout == VK_IMAGE_LAYOUT_UNDEFINED &&
dst_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
) {
@@ -2386,7 +2402,11 @@ void Context::transition(Texture_Id id, Resource_State state) {
dst_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
} else {
print_err("Bad resource transition.\n");
- pbreak(389);
+ assert(0);
+ b.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ b.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ src_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ dst_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
}
vkCmdPipelineBarrier(
ctx->cb,
@@ -4071,6 +4091,10 @@ void Sampler_Vk::init(Device_Vk* dev, const Sampler_State& s) {
si.borderColor = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
si.maxLod = VK_LOD_CLAMP_NONE;
si.pNext = &bi;
+ if ((int)s.compare) {
+ si.compareEnable = VK_TRUE;
+ si.compareOp = Pipeline_Vk::get_compare_op(s.compare);
+ }
bi.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
bi.customBorderColor = col;
bi.format = VK_FORMAT_R32G32B32A32_SFLOAT;
diff --git a/video.hpp b/video.hpp
index 3bd756f..5aa25bc 100644
--- a/video.hpp
+++ b/video.hpp
@@ -75,13 +75,13 @@ static_assert(sizeof(Buffer_Descriptor) <= descriptor_payload_size);
#define pipeline_max_descriptors 16
enum class Depth_Mode {
+ never,
less,
less_equal,
equal,
greater,
greater_equal,
- always,
- never
+ always
};
enum class Blend_Factor {
@@ -410,6 +410,7 @@ struct Sampler_State {
Address_Mode address_u;
Address_Mode address_v;
Address_Mode address_w;
+ Depth_Mode compare;
float border[4];
float mip_bias;
bool aniso;