added some basic loading model controls

This commit is contained in:
matthew 2025-08-05 12:59:20 +10:00
parent e324e47896
commit d4c86e7ac5
11 changed files with 382 additions and 218 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,6 +2,7 @@ import aliases;
import includes;
import renderer : Destroy;
import renderer;
import vulkan;
import util;
import alloc;
import platform;
@ -24,6 +25,9 @@ struct Game
Pipeline ui_pipeline;
Pipeline oit_pipeline;
ImageView draw_image, depth_image;
ImageView aux_image;
GlobalUniforms globals;
PushConst pc;
@ -31,9 +35,14 @@ struct Game
Camera camera;
Model model;
}
Model tree;
Model rock;
Model magic_rock;
Model log;
Model stump;
SLList!(Model) models;
}
Game
InitGame(PlatformWindow* window)
@ -50,14 +59,24 @@ InitGame(PlatformWindow* window)
},
};
Extent ext = GetExtent(&g.rd);
CreateImageView(&g.rd, &g.draw_image, ext.w, ext.h, GetDrawImageFormat(&g.rd), IU.Draw, false);
CreateImageView(&g.rd, &g.depth_image, ext.w, ext.h, FMT.D_SF32, IU.Depth, true);
CreateImageView(&g.rd, &g.aux_image, ext.w, ext.h, FMT.R_U32, IU.Storage);
GfxPipelineInfo triangle_info = {
vertex_shader: "shaders/triangle.vert.spv",
frag_shader: "shaders/triangle.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
};
GfxPipelineInfo ui_info = {
vertex_shader: "shaders/gui.vert.spv",
frag_shader: "shaders/gui.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
input_rate: IR.Instance,
input_rate_stride: UIVertex.sizeof,
vertex_attributes: [
@ -71,6 +90,8 @@ InitGame(PlatformWindow* window)
GfxPipelineInfo pbr_info = {
vertex_shader: "shaders/pbr.vert.spv",
frag_shader: "shaders/pbr.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
input_rate_stride: Vertex.sizeof,
vertex_attributes: [
{ binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 },
@ -84,36 +105,96 @@ InitGame(PlatformWindow* window)
GfxPipelineInfo oit_info = {
vertex_shader: "shaders/full_screen_triangle.vert.spv",
frag_shader: "shaders/oit.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
};
CompPipelineInfo gradient_info = {
shader: "shaders/gradient.comp.spv",
};
Logf("pbr");
g.pbr_pipeline = BuildGfxPipeline(&g.rd, &pbr_info);
Logf("triangle");
g.triangle_pipeline = BuildGfxPipeline(&g.rd, &triangle_info);
Logf("ui");
g.ui_pipeline = BuildGfxPipeline(&g.rd, &ui_info);
Logf("oit");
g.oit_pipeline = BuildGfxPipeline(&g.rd, &oit_info);
g.compute_pipeline = BuildCompPipeline(&g.rd, &gradient_info);
PrintShader(&g.rd, &g.pbr_pipeline, VK_SHADER_STAGE_VERTEX_BIT);
g.model = LoadModel(&g.rd, "models/Tree01.m3d");
g.rock = LoadModel(&g.rd, "models/BigRock01.m3d");
g.tree = LoadModel(&g.rd, "models/Tree01.m3d");
g.magic_rock = LoadModel(&g.rd, "models/MagicRock01.m3d");
g.log = LoadModel(&g.rd, "models/Log01.m3d");
g.stump = LoadModel(&g.rd, "models/Stump01.m3d");
SetClearColor(&g.rd, Vec4(0.3, 0.5, 0.9, 1.0));
ClearColorEnabled(&g.rd, true);
assert(g.aux_image.view != null);
UpdateAuxImage(&g.rd, &g.aux_image);
return g;
}
void
Copy(Model* dst, Model* src)
{
dst.vertex_buffer = src.vertex_buffer;
dst.index_buffer = src.index_buffer;
dst.parts = src.parts;
dst.materials = src.materials;
dst.textures = src.textures;
}
void
ProcessInputs(Game* g, Camera* cam)
{
foreach(i; 0 .. g.window.inputs.count)
{
InputEvent event = g.window.inputs.events[i];
switch(event.key)
{
case Input.One:
{
Node!(Model)* node = Alloc!(Node!(Model));
Copy(&node.value, &g.tree);
node.value.pos = cam.pos;
PushFront(&g.models, node, null);
} break;
case Input.Two:
{
Node!(Model)* node = Alloc!(Node!(Model));
Copy(&node.value, &g.rock);
node.value.pos = cam.pos;
PushFront(&g.models, node, null);
} break;
case Input.Three:
{
Node!(Model)* node = Alloc!(Node!(Model));
Copy(&node.value, &g.magic_rock);
node.value.pos = cam.pos;
PushFront(&g.models, node, null);
} break;
case Input.Four:
{
Node!(Model)* node = Alloc!(Node!(Model));
Copy(&node.value, &g.log);
node.value.pos = cam.pos;
PushFront(&g.models, node, null);
} break;
case Input.Five:
{
Node!(Model)* node = Alloc!(Node!(Model));
Copy(&node.value, &g.stump);
node.value.pos = cam.pos;
PushFront(&g.models, node, null);
} break;
default: break;
}
}
HandleInputs(cam, &g.window.inputs);
}
@ -126,6 +207,12 @@ Cycle(Game* g)
ProcessInputs(g, &g.camera);
ResizeDrawImageIfNeeded(&g.rd, &g.draw_image);
ResizeDrawImageIfNeeded(&g.rd, &g.depth_image);
ResizeDrawImageIfNeeded(&g.rd, &g.aux_image);
UpdateAuxImage(&g.rd, &g.aux_image);
//Sort(g, g.camera.pos, &g.model);
//Update(g, &g.camera);
@ -134,8 +221,14 @@ Cycle(Game* g)
BeginFrame(&g.rd);
PrepAuxImage(&g.rd.vk, &g.aux_image);
Bind(&g.rd, &g.compute_pipeline);
ClearColor(&g.rd, &g.aux_image, Vec4(0.0));
ImageBarrier(&g.rd);
Extent ext = GetExtent(&g.rd);
f32 aspect = (cast(f32)ext.x) / (cast(f32)ext.y);
Mat4 projection = Perspective(90.0, aspect, 10000.0, 0.1);
@ -146,36 +239,56 @@ Cycle(Game* g)
g.globals.res.y = ext.y;
SetUniform(&g.rd, &g.globals);
//DrawRect(&g.rd, 150.0, 300.0, 500.0, 700.0, Vec4(0.0, 0.0, 1.0, 1.0));
//PrepComputeDrawImage(&g.rd);
//Dispatch(&g.rd);
BeginRender(&g.rd);
BeginRendering(&g.rd, &g.draw_image, &g.depth_image);
Bind(&g.rd, &g.ui_pipeline);
BindUIBuffers(&g.rd);
//DrawUI(&g.rd);
Bind(&g.rd, &g.triangle_pipeline);
//Draw(&g.rd, 3, 1);
Bind(&g.rd, &g.pbr_pipeline);
g.pc.model_matrix = Mat4Identity();
DrawModel(g, &g.model);
FinishFrame(&g.rd);
Node!(Model)* model = g.models.first;
for(;;)
{
if (model == null)
{
break;
}
DrawModel(g, &model.value);
model = model.next;
}
/*
ImageBarrier(&g.rd);
Bind(&g.rd, &g.oit_pipeline);
Draw(&g.rd, 3, 1);
*/
FinishRendering(&g.rd);
//ImageBarrier(&g.rd);
//BeginRendering(&g.rd, &g.draw_image, &g.depth_image);
//FinishRendering(&g.rd);
Submit(&g.rd, &g.draw_image);
}
pragma(inline): void
DrawModel(Game* g, Model* model)
{
BindBuffers(&g.rd, &model.index_buffer, &model.vertex_buffer);
g.pc.model_matrix = Mat4Identity();
Translate(&g.pc.model_matrix, model.pos);
foreach(i, part; model.parts)
{
g.pc.mat_id = part.mat;
@ -192,7 +305,18 @@ Destroy(Game* g)
Destroy(&g.rd, &g.triangle_pipeline);
Destroy(&g.rd, &g.ui_pipeline);
Destroy(&g.rd, &g.compute_pipeline);
Destroy(&g.rd, &g.model);
Node!(Model)* model = g.models.first;
for(;;)
{
if (model == null)
{
break;
}
Destroy(&g.rd, &model.value);
model = model.next;
}
Destroy(&g.rd);
}

View File

@ -15,6 +15,8 @@ import core.stdc.string : memcpy;
// 3. Determine how to better handle inputs
// 4. Make assets loaded from the disk in debug mode
// 5. Set up multisampling
// 6. Remove renderer.d and just move the interface into vulkan.d
// 7. Remove dynamic rendering
void main(string[] argv)
{

View File

@ -4,7 +4,7 @@ import assets;
import util;
import alloc;
import vulkan;
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepComputeDrawImage, Dispatch, FinishFrame, BeginFrame, WaitIdle, PushConstants, BindBuffers, SetClearColor, ImageBarrier;
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRendering, SetUniform, PrepComputeDrawImage, Dispatch, SubmitAndPresent, BeginFrame, WaitIdle, PushConstants, BindBuffers, SetClearColor, ImageBarrier, CreateImageView, GetDrawImageFormat, FinishRendering, UpdateAuxImage, ClearColor, SubmitAndPresent;
import assets;
import std.math.traits : isNaN;
import util : Logf;
@ -25,6 +25,20 @@ enum InputRate : int
alias IR = InputRate;
enum ImageUsage : VkImageUsageFlagBits
{
None = cast(VkImageUsageFlagBits)0,
Draw = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
Depth = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
Texture = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
Convert = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
Storage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
Swapchain = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
}
alias IU = ImageUsage;
enum Format : VkFormat
{
UINT = VK_FORMAT_R32_UINT,
@ -37,13 +51,14 @@ enum Format : VkFormat
RG_U32 = VK_FORMAT_R32G32_UINT,
RGBA_UNORM = VK_FORMAT_R8G8B8A8_UNORM,
RGBA_SRGB = VK_FORMAT_R8G8B8A8_SRGB,
D_SF32 = VK_FORMAT_D32_SFLOAT,
}
alias FMT = Format;
enum BufferType : int
enum BufferType : VkBufferUsageFlagBits
{
None = 0,
None = cast(VkBufferUsageFlagBits)0,
Vertex = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
Index = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
Uniform = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
@ -54,6 +69,13 @@ enum BufferType : int
alias BT = BufferType;
enum ImageLayout : VkImageLayout
{
Undefined = VK_IMAGE_LAYOUT_UNDEFINED,
General = VK_IMAGE_LAYOUT_GENERAL,
ColorAttach = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
}
struct GlobalUniforms
{
Mat4 view_matrix = Mat4Identity();
@ -88,35 +110,24 @@ struct Specialization
struct GfxPipelineInfo
{
string vertex_shader;
string frag_shader;
InputRate input_rate;
u32 input_rate_stride;
Attribute[] vertex_attributes;
string vertex_shader;
string frag_shader;
InputRate input_rate;
u32 input_rate_stride;
Attribute[] vertex_attributes;
Specialization vert_spec;
Specialization frag_spec;
ImageView* draw_image;
ImageView* depth_image;
}
struct CompPipelineInfo
{
string shader;
Specialization spec;
string shader;
Specialization spec;
VkPipelineLayout *layout;
}
struct Renderer
{
Arena arena;
Arena temp_arena;
Vulkan vk;
PlatformWindow* window;
UIVertex[] ui_vertex_buf;
u32[] ui_index_buf;
u32 ui_count;
}
struct PushConst
{
Mat4 model_matrix;
@ -127,6 +138,8 @@ struct Extent
{
u32 x;
u32 y;
alias x w;
alias y h;
}
struct UIVertex
@ -170,6 +183,54 @@ struct Model
u32[] indices;
}
struct Image
{
VkImage image;
VmaAllocation alloc;
Format format;
VkImageLayout layout;
u32 w;
u32 h;
bool depth_image;
ImageUsage usage;
}
struct BufferView
{
Buffer base;
VkBufferView view;
alias base this;
}
struct ImageView
{
Image base;
VkImageView view;
alias base this;
}
struct Buffer
{
VkBuffer buffer;
VmaAllocation alloc;
u64 size;
}
struct Renderer
{
Arena arena;
Arena temp_arena;
Vulkan vk;
PlatformWindow* window;
UIVertex[] ui_vertex_buf;
u32[] ui_index_buf;
u32 ui_count;
}
Renderer
InitRenderer(PlatformWindow* window)
{
@ -213,12 +274,6 @@ DrawUI(Renderer* rd)
DrawIndexed(rd, 6, rd.ui_count, 0);
}
pragma(inline): void
FinishFrame(Renderer* rd)
{
FinishFrame(&rd.vk);
}
pragma(inline): void
Dispatch(Renderer* rd)
{
@ -238,9 +293,9 @@ SetUniform(Renderer* rd, GlobalUniforms* uniforms)
}
pragma(inline): void
BeginRender(Renderer* rd)
BeginRendering(Renderer* rd, ImageView* draw_image, ImageView* depth_image)
{
BeginRender(&rd.vk);
BeginRendering(&rd.vk, draw_image, depth_image);
}
pragma(inline): void
@ -645,6 +700,54 @@ ImageBarrier(Renderer* rd)
ImageBarrier(&rd.vk);
}
void
CreateImageView(Renderer* rd, ImageView* view, u32 w, u32 h, Format format, ImageUsage usage, bool depth_image = false)
{
CreateImageView(&rd.vk, view, w, h, format, usage, depth_image);
}
Format
GetDrawImageFormat(Renderer* rd)
{
return cast(Format)GetDrawImageFormat(&rd.vk);
}
pragma(inline): void
ResizeDrawImageIfNeeded(Renderer* rd, ImageView* view)
{
Extent ext = GetExtent(rd);
if (view.w != ext.w || view.h != ext.h)
{
Destroy(view, rd.vk.device, rd.vk.vma);
CreateImageView(&rd.vk, view, ext.w, ext.h, view.format, view.usage, view.depth_image);
}
}
void
FinishRendering(Renderer* rd)
{
FinishRendering(&rd.vk);
}
void
Submit(Renderer* rd, ImageView* view)
{
SubmitAndPresent(&rd.vk, view);
}
void
UpdateAuxImage(Renderer* rd, ImageView* view)
{
UpdateAuxImage(&rd.vk, view);
}
void
ClearColor(Renderer* rd, ImageView* view, Vec4 color)
{
ClearColor(&rd.vk, view, color);
}
void
Destroy(Renderer* rd, Model* model)
{

View File

@ -4,6 +4,7 @@ import aliases;
import std.stdio;
import std.algorithm.comparison;
import core.stdc.string : strcmp, memcpy;
import core.stdc.stdio : Printf = printf;
import std.format : sformat;
import util;
import alloc;
@ -52,6 +53,7 @@ const char*[] VK_BASE_DEVICE_EXTENSIONS = [
cast(char*)VK_KHR_SWAPCHAIN_EXTENSION_NAME,
cast(char*)VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME,
cast(char*)VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
cast(char*)"VK_KHR_dynamic_rendering_local_read",
];
const char*[] VK_AMD_DEVICE_EXTENSIONS = [
@ -75,15 +77,6 @@ const VkFormat[] VK_IMAGE_FORMATS = [
VK_FORMAT_R8G8B8A8_UNORM,
];
const VkImageUsageFlags VK_DRAW_IMAGE_USAGE_FLAGS = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
const VkImageUsageFlags TEXTURE_IMAGE_USAGE = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
const VkImageUsageFlags CONVERT_IMAGE_USAGE = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
const VkImageUsageFlags OIT_IMAGE_USAGE = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
enum StepInitialized : u32
{
Renderer = 1,
@ -113,30 +106,6 @@ enum DescType : u32
alias DT = DescType;
struct Image
{
VkImage image;
VmaAllocation alloc;
VkFormat format;
VkImageLayout layout;
}
struct BufferView
{
Buffer base;
VkBufferView view;
alias base this;
}
struct ImageView
{
Image base;
VkImageView view;
alias base this;
}
struct MappedBuffer(T)
{
Buffer base;
@ -146,13 +115,6 @@ struct MappedBuffer(T)
alias base this;
}
struct Buffer
{
VkBuffer buffer;
VmaAllocation alloc;
u64 size;
}
struct DescBindings
{
u32[] free;
@ -550,19 +512,19 @@ BeginFrame(Vulkan* vk)
}
void
BeginRender(Vulkan* vk)
BeginRendering(Vulkan* vk, ImageView* draw_image, ImageView* depth_image)
{
// TODO: probably get rid of these
Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Transition(vk.cmds[vk.frame_index], &vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
Transition(vk.cmds[vk.frame_index], draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Transition(vk.cmds[vk.frame_index], depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
VkImage image = CurrentImage(vk);
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkRenderingAttachmentInfo col_attach = {
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
imageView: vk.draw_image.view,
imageLayout: vk.draw_image.layout,
imageView: draw_image.view,
imageLayout: draw_image.layout,
loadOp: (vk.enable_clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD), // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever)
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
clearValue: {
@ -572,8 +534,8 @@ BeginRender(Vulkan* vk)
VkRenderingAttachmentInfo depth_attach = {
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
imageView: vk.depth_image.view,
imageLayout: vk.depth_image.layout,
imageView: depth_image.view,
imageLayout: depth_image.layout,
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
};
@ -604,6 +566,12 @@ SetClearColor(Vulkan* vk, Vec4 color)
vk.clear_color.float32[3] = color.a;
}
void
PrepAuxImage(Vulkan* vk, ImageView* view)
{
Transition(vk.cmds[vk.frame_index], view, VK_IMAGE_LAYOUT_GENERAL);
}
void
PrepComputeDrawImage(Vulkan* vk)
{
@ -611,7 +579,13 @@ PrepComputeDrawImage(Vulkan* vk)
}
void
FinishFrame(Vulkan* vk)
FinishRendering(Vulkan* vk)
{
vkCmdEndRendering(vk.cmds[vk.frame_index]);
}
void
SubmitAndPresent(Vulkan* vk, ImageView* draw_image)
{
scope(exit)
{
@ -623,9 +597,7 @@ FinishFrame(Vulkan* vk)
VkSemaphore acquire_sem = vk.acquire_sems[vk.frame_index];
VkSemaphore submit_sem = vk.submit_sems[vk.image_index];
vkCmdEndRendering(vk.cmds[vk.frame_index]);
Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
Transition(vk.cmds[vk.frame_index], draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VkExtent2D extent = {
width: vk.swapchain_extent.width,
@ -633,7 +605,7 @@ FinishFrame(Vulkan* vk)
};
// TODO: Find out how to copy from same dimension images (pretty sure its not blitting)
Copy(vk.cmds[vk.frame_index], &vk.draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent);
Copy(vk.cmds[vk.frame_index], &draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent);
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
@ -771,7 +743,7 @@ TransferAssets(Vulkan* vk)
pragma(inline): void
CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
{
CreateImageView(vk, view, w, h, FMT.RGBA_UNORM, TEXTURE_IMAGE_USAGE);
CreateImageView(vk, view, w, h, FMT.RGBA_UNORM, IU.Texture);
if (ch == 4)
{
@ -784,7 +756,7 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
assert(Transfer(vk, &buf, data), "CreateImageView failure: Buffer Transfer error");
ImageView conv_view;
CreateImageView(vk, &conv_view, w, h, FMT.RGBA_F32, CONVERT_IMAGE_USAGE);
CreateImageView(vk, &conv_view, w, h, FMT.RGBA_F32, IU.Convert);
WriteConvDescriptor(vk, &buf);
WriteConvDescriptor(vk, &conv_view);
@ -906,7 +878,7 @@ CreateBufferView(Vulkan* vk, BufferView* view, u64 size, Format format)
}
pragma(inline): void
CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.RGBA_UNORM, VkImageUsageFlags usage)
CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format, ImageUsage usage, bool depth_image = false)
{
VmaAllocationCreateInfo alloc_info = {
usage: VMA_MEMORY_USAGE_GPU_ONLY,
@ -937,9 +909,6 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.R
image_info.pQueueFamilyIndices = cast(const u32*)[vk.gfx_index, vk.tfer_index];
}
view.layout = VK_IMAGE_LAYOUT_UNDEFINED;
view.format = VK_FORMAT_R8G8B8A8_SRGB;
VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &view.image, &view.alloc, null);
// TODO: handle errors and realloc
assert(VkCheck("CreateImageView failure: vmaCreateImage error", result), "CreateImageView failure");
@ -950,7 +919,7 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.R
viewType: VK_IMAGE_VIEW_TYPE_2D,
format: format,
subresourceRange: {
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
aspectMask: (depth_image ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
levelCount: 1,
layerCount: 1,
},
@ -959,6 +928,13 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.R
result = vkCreateImageView(vk.device, &view_info, null, &view.view);
// TODO: also handle here
assert(VkCheck("CreateImageView failure: vkCreateImageView error", result), "CreateImageView failure");
view.layout = VK_IMAGE_LAYOUT_UNDEFINED;
view.format = format;
view.w = w;
view.h = h;
view.depth_image = depth_image;
view.usage = usage;
}
u32
@ -1378,7 +1354,7 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
VkPipelineDepthStencilStateCreateInfo depth_info = {
sType: VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
depthTestEnable: VK_TRUE,
depthWriteEnable: VK_FALSE,
depthWriteEnable: VK_TRUE,
depthCompareOp: VK_COMPARE_OP_GREATER_OR_EQUAL,
depthBoundsTestEnable: VK_FALSE,
stencilTestEnable: VK_FALSE,
@ -1389,8 +1365,8 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
VkPipelineRenderingCreateInfo rendering_info = {
sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
colorAttachmentCount: 1,
pColorAttachmentFormats: &vk.draw_image.format,
depthAttachmentFormat: vk.depth_image.format,
pColorAttachmentFormats: cast(VkFormat*)&build_info.draw_image.format,
depthAttachmentFormat: build_info.depth_image.format,
};
VkPipelineColorBlendAttachmentState blend_state = {
@ -1555,6 +1531,25 @@ CreateComputePipeline(Vulkan* vk, CompPipelineInfo* comp_info)
return pipeline;
}
void
ClearColor(Vulkan* vk, ImageView* view, Vec4 color)
{
VkImageSubresourceRange clear_range = {
aspectMask: (view.depth_image ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
levelCount: 1,
layerCount: 1,
};
vkCmdClearColorImage(
vk.cmds[vk.frame_index],
view.image,
view.layout,
cast(VkClearColorValue*)color.v,
1,
&clear_range
);
}
void
SetUniform(Vulkan* vk, GlobalUniforms* globals)
{
@ -1897,7 +1892,6 @@ InitDescriptors(Vulkan* vk)
// Also add samples/supersampling scaling
CreateBufferView(vk, &vk.a_buffer_view, (u32.sizeof * 2) * vk.swapchain_extent.width * vk.swapchain_extent.height, FMT.RG_U32);
CreateImageView(vk, &vk.aux_image, vk.swapchain_extent.width, vk.swapchain_extent.height, FMT.R_U32, OIT_IMAGE_USAGE);
VkDescriptorBufferInfo a_buffer_info = {
buffer: vk.a_buffer_view.buffer,
@ -1937,14 +1931,6 @@ InitDescriptors(Vulkan* vk)
pBufferInfo: &a_buffer_info,
pTexelBufferView: &vk.a_buffer_view.view,
},
{
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
dstSet: vk.desc_sets[DT.Shared],
dstBinding: 5,
descriptorCount: 1,
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
pImageInfo: &aux_info,
},
{
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
dstSet: vk.desc_sets[DT.Shared],
@ -1963,6 +1949,31 @@ InitDescriptors(Vulkan* vk)
return success;
}
// TODO: better descriptor updating
void
UpdateAuxImage(Vulkan* vk, ImageView* view)
{
VkDescriptorImageInfo aux_info = {
sampler: vk.oit_sampler,
imageView: view.view,
imageLayout: VK_IMAGE_LAYOUT_GENERAL,
};
assert(view.view != VK_NULL_HANDLE);
VkWriteDescriptorSet write = {
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
dstSet: vk.desc_sets[DT.Shared],
dstBinding: 5,
descriptorCount: 1,
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
pImageInfo: &aux_info,
};
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
}
void
WriteDrawImageDesc(Vulkan* vk)
{
@ -2243,7 +2254,7 @@ GetDrawImageFormat(Vulkan* vk)
format,
VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL,
VK_DRAW_IMAGE_USAGE_FLAGS,
IU.Draw,
0,
&props
);
@ -2269,91 +2280,14 @@ CreateDrawImages(Vulkan* vk)
bool success = true;
VkFormat draw_format = GetDrawImageFormat(vk);
VkFormat depth_format = VK_FORMAT_D32_SFLOAT;
Format draw_format = cast(Format)GetDrawImageFormat(vk);
Format depth_format = cast(Format)VK_FORMAT_D32_SFLOAT;
VmaAllocationCreateInfo alloc_info = {
usage: VMA_MEMORY_USAGE_GPU_ONLY,
requiredFlags: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
};
u32 w = vk.swapchain_extent.width;
u32 h = vk.swapchain_extent.height;
VkImageCreateInfo image_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
imageType: VK_IMAGE_TYPE_2D,
mipLevels: 1,
arrayLayers: 1,
samples: VK_SAMPLE_COUNT_1_BIT,
tiling: VK_IMAGE_TILING_OPTIMAL,
usage: VK_DRAW_IMAGE_USAGE_FLAGS,
extent: vk.swapchain_extent,
format: draw_format,
};
VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &vk.draw_image.image, &vk.draw_image.alloc, null);
success = VkCheck("vmaCreateImage failure", result);
if (success)
{
VkImageViewCreateInfo view_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
image: vk.draw_image.image,
format: draw_format,
viewType: VK_IMAGE_VIEW_TYPE_2D,
subresourceRange: {
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
baseMipLevel: 0,
levelCount: 1,
baseArrayLayer: 0,
layerCount: 1,
},
};
result = vkCreateImageView(vk.device, &view_info, null, &vk.draw_image.view);
success = VkCheck("vkCreateImageView failure", result);
}
if (success)
{
VkImageCreateInfo depth_image_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
imageType: VK_IMAGE_TYPE_2D,
mipLevels: 1,
arrayLayers: 1,
samples: VK_SAMPLE_COUNT_1_BIT,
tiling: VK_IMAGE_TILING_OPTIMAL,
format: depth_format,
usage: VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
extent: vk.swapchain_extent,
};
result = vmaCreateImage(vk.vma, &depth_image_info, &alloc_info, &vk.depth_image.image, &vk.depth_image.alloc, null);
success = VkCheck("vmaCreateImage failure", result);
}
if (success)
{
VkImageViewCreateInfo depth_view_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
image: vk.depth_image.image,
viewType: VK_IMAGE_VIEW_TYPE_2D,
format: depth_format,
subresourceRange: {
aspectMask: VK_IMAGE_ASPECT_DEPTH_BIT,
baseMipLevel: 0,
levelCount: 1,
baseArrayLayer: 0,
layerCount: 1,
},
};
result = vkCreateImageView(vk.device, &depth_view_info, null, &vk.depth_image.view);
success = VkCheck("vmaCreateImageView failure", result);
}
vk.draw_image.format = draw_format;
vk.draw_image.layout = VK_IMAGE_LAYOUT_UNDEFINED;
vk.depth_image.format = depth_format;
vk.depth_image.layout = VK_IMAGE_LAYOUT_UNDEFINED;
CreateImageView(vk, &vk.draw_image, w, h, draw_format, IU.Draw, false);
CreateImageView(vk, &vk.depth_image, w, h, depth_format, IU.Depth, true);
return success;
}
@ -2407,7 +2341,7 @@ CreateSwapchain(Vulkan* vk)
VkSwapchainCreateInfoKHR info = {
sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
imageArrayLayers: 1,
imageUsage: VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
imageUsage: IU.Swapchain,
compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
clipped: VK_TRUE,
imageSharingMode: VK_SHARING_MODE_EXCLUSIVE,

View File

@ -1,7 +1,6 @@
#version 460
#extension GL_EXT_shader_8bit_storage : require
#extension GL_EXT_debug_printf : require
layout (constant_id = 0) const int CHANNELS = 3;
@ -35,7 +34,6 @@ void main()
uint index = x + y * PC.x;
vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0);
debugPrintfEXT("col = %v4f", col);
imageStore(dst, ivec2(x, y), col);
}
else if (CHANNELS == 2)
@ -45,7 +43,6 @@ void main()
float f = uint(src[index]) / 255.0;
float a = uint(src[index+1]) / 255.0;
vec4 col = vec4(f, f, f, a);
debugPrintfEXT("col = %v4f", col);
imageStore(dst, ivec2(x, y), col);
}
else if (CHANNELS == 3)
@ -53,7 +50,6 @@ void main()
uint index = (x + y * PC.x) * 3;
vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0);
debugPrintfEXT("col = %v4f", col);
imageStore(dst, ivec2(x, y), col);
}
}

View File

@ -27,7 +27,7 @@ void BubbleSort(inout uvec2 array[OIT_LAYERS], int n)
float UnPreMultSRGBToLinear(float col)
{
return col < 0.04045f ? col / 12.92f : pow((col + 0.055f) / 1.055f, 2.4f);
return (col < 0.04045f) ? (col / 12.92f) : pow((col + 0.055f) / 1.055f, 2.4f);
}
vec4 UnPreMultSRGBToLinear(vec4 col)
@ -47,7 +47,7 @@ void DoBlend(inout vec4 color, vec4 base_color)
void DoBlendPacked(inout vec4 color, uint fragment)
{
vec4 unpacked_color = unpackUnorm4x8(fragment);
unpacked_color = UnPreMultSRGBToLinear(unpacked_color);
//unpacked_color = UnPreMultSRGBToLinear(unpacked_color);
unpacked_color.rgb *= unpacked_color.a;
DoBlend(color, unpacked_color);
}

View File

@ -50,7 +50,7 @@ void main()
vec4 tex_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].albedo_texture)], SamplerNearest), FragData.uv);
vec4 out_col = CalculateDirectionalLight(col, tex_col, G.light_color, G.light_direction, FragData.normal);
out_col.a = Materials[nonuniformEXT(PC.mat_id)].alpha;
out_col.a = 1.0;// Materials[nonuniformEXT(PC.mat_id)].alpha;
if (Materials[nonuniformEXT(PC.mat_id)].alpha_has_texture)
{
@ -58,7 +58,11 @@ void main()
out_col.a = alpha_col.a;
}
vec4 srgb_col = UnPreMultLinearToSRGB(out_col);
FragColor = out_col;
/*
TODO: set up OIT again
vec4 srgb_col = out_col;// UnPreMultLinearToSRGB(out_col);
uvec4 store_value = uvec4(packUnorm4x8(srgb_col), floatBitsToUint(gl_FragCoord.z), store_mask, 0);
@ -73,4 +77,5 @@ void main()
{
FragColor = vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending
}
*/
}

View File

@ -2,7 +2,7 @@
// **** STRUCTS MUST BE PACKED IN OPTIMAL PACKING ORDER TO MATCH D STRUCTS ****
// ****************************************************************************
#define OIT_LAYERS 64
#define OIT_LAYERS 8
layout (set = 0, binding = 0) uniform GlobalUniforms {
mat4 view_matrix;