set up nogc
This commit is contained in:
parent
48493f91bb
commit
f601729468
Binary file not shown.
Binary file not shown.
6
dub.json
6
dub.json
@ -9,13 +9,13 @@
|
||||
"targetPath": "build",
|
||||
"sourceFiles-linux": ["build/libvma.a", "build/libstb_image.a", "build/libm3d.a", "build/libcglm.a"],
|
||||
"sourceFiles-windows": [],
|
||||
"importPaths": ["src/gears", "src/codegen", "src/shared", "external/xxhash", "external/inteli"],
|
||||
"sourcePaths": ["src/gears", "src/codegen", "src/shared", "external/xxhash", "external/inteli"],
|
||||
"importPaths": ["src/gears", "src/shared", "external/xxhash", "external/inteli"],
|
||||
"sourcePaths": ["src/gears", "src/shared", "external/xxhash", "external/inteli"],
|
||||
"libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes", "freetype"],
|
||||
"libs-windows": [],
|
||||
"preGenerateCommands-linux": ["./build.sh"],
|
||||
"preGenerateCommands-windows": [],
|
||||
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2"],
|
||||
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-vgc"],
|
||||
"dflags-dmd": ["-P=-DSTBI_NO_SIMD"]
|
||||
},
|
||||
{
|
||||
|
||||
@ -83,6 +83,12 @@ struct Game
|
||||
|
||||
UIPushConst ui_pc;
|
||||
|
||||
u8[] font_data;
|
||||
FontAtlasBuf atlas_buf;
|
||||
FontFace font;
|
||||
|
||||
Buffer temp_buffer;
|
||||
|
||||
Timer timer;
|
||||
}
|
||||
|
||||
@ -99,8 +105,9 @@ InitGame(PlatformWindow* window)
|
||||
|
||||
UVec2 ext = GetExtent(&g.rd);
|
||||
|
||||
DescLayoutBinding[] layout_bindings = [
|
||||
DescLayoutBinding[2] layout_bindings = [
|
||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
];
|
||||
|
||||
g.ui_desc_layout = CreateDescSetLayout(&g.rd, layout_bindings);
|
||||
@ -110,11 +117,13 @@ InitGame(PlatformWindow* window)
|
||||
u8[16*16*4] white_tex;
|
||||
white_tex[] = u8.max;
|
||||
|
||||
CreateImageView(&g.rd, &g.font_tex, FONT_ATLAS_TEST.atlas.width, FONT_ATLAS_TEST.atlas.height, 4, FONT_ATLAS_TEST.data);
|
||||
// TODO: fix buffer overflow between two textures
|
||||
//CreateImageView(&g.rd, &g.default_tex, 16, 16, 4, white_tex);
|
||||
|
||||
WriteGUI(&g.rd, g.ui_desc_set, &g.font_tex);
|
||||
Attribute[5] attributes = [
|
||||
{ binding: 0, location: 0, format: FMT.RG_F32, offset: UIVertex.dst_start.offsetof },
|
||||
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.dst_end.offsetof },
|
||||
{ binding: 0, location: 2, format: FMT.RG_F32, offset: UIVertex.src_start.offsetof },
|
||||
{ binding: 0, location: 3, format: FMT.RG_F32, offset: UIVertex.src_end.offsetof },
|
||||
{ binding: 0, location: 4, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
|
||||
];
|
||||
|
||||
GfxPipelineInfo ui_info = {
|
||||
vertex_shader: "shaders/gui.vert.spv",
|
||||
@ -122,13 +131,7 @@ InitGame(PlatformWindow* window)
|
||||
input_rate: IR.Instance,
|
||||
input_rate_stride: UIVertex.sizeof,
|
||||
layout: g.ui_layout,
|
||||
vertex_attributes: [
|
||||
{ binding: 0, location: 0, format: FMT.RG_F32, offset: UIVertex.dst_start.offsetof },
|
||||
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.dst_end.offsetof },
|
||||
{ binding: 0, location: 2, format: FMT.RG_F32, offset: UIVertex.src_start.offsetof },
|
||||
{ binding: 0, location: 3, format: FMT.RG_F32, offset: UIVertex.src_end.offsetof },
|
||||
{ binding: 0, location: 4, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
|
||||
],
|
||||
vertex_attributes: attributes,
|
||||
};
|
||||
|
||||
g.ui_pipeline = CreateGraphicsPipeline(&g.rd, &ui_info);
|
||||
@ -139,7 +142,16 @@ InitGame(PlatformWindow* window)
|
||||
g.ui_vertex_buf = GetUIVertexBuffer(&g.rd);
|
||||
g.ui_index_buf = GetUIIndexBuffer(&g.rd);
|
||||
|
||||
WaitForTransfers(&g.rd);
|
||||
u8[] font_data = LoadAssetData(&g.arena, "fonts/NuberNextCondensed-DemiBold.otf");
|
||||
g.font = OpenFont(font_data);
|
||||
g.atlas_buf = CreateAtlas(&g.arena, g.font, 32, 256);
|
||||
|
||||
CreateImageView(&g.rd, &g.font_tex, g.atlas_buf.atlas.width, g.atlas_buf.atlas.height, 4, g.atlas_buf.data);
|
||||
CreateImageView(&g.rd, &g.default_tex, 16, 16, 4, white_tex);
|
||||
|
||||
CreateBuffer(&g.rd, &g.temp_buffer, BT.Uniform, f32.sizeof*2, false, false);
|
||||
|
||||
WriteGUI(&g.rd, g.ui_desc_set, &g.font_tex, &g.temp_buffer);
|
||||
|
||||
Reset(&g.frame_arena);
|
||||
|
||||
@ -171,8 +183,22 @@ Cycle(Game* g)
|
||||
|
||||
Reset(&g.frame_arena);
|
||||
|
||||
static bool alt = false;
|
||||
if (alt)
|
||||
{
|
||||
f32[2] scale = [2.0, 2.0];
|
||||
assert(Transfer(&g.rd, &g.temp_buffer, scale), "Cycle Transfer failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
f32[2] scale = [1.0, 1.0];
|
||||
assert(Transfer(&g.rd, &g.temp_buffer, scale), "Cycle Transfer failed");
|
||||
}
|
||||
|
||||
alt = !alt;
|
||||
|
||||
DrawRect(g, 500.0, 500.0, 800.0, 800.0, Vec4(0.2, 0.3, 0.7, 1.0));
|
||||
DrawText(g, 200.0, 200.0, 128.0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
DrawText(g, 200.0, 200.0, 16.0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
|
||||
BeginFrame(&g.rd);
|
||||
|
||||
@ -318,10 +344,10 @@ void
|
||||
DrawText(Game* g, f32 x, f32 y, f32 px, string str)
|
||||
{
|
||||
f32 x_pos = x;
|
||||
f32 scale = px / FONT_ATLAS_TEST.atlas.size;
|
||||
f32 scale = px / g.atlas_buf.atlas.size;
|
||||
foreach(ch; str)
|
||||
{
|
||||
foreach(glyph; FONT_ATLAS_TEST.atlas.glyphs)
|
||||
foreach(glyph; g.atlas_buf.atlas.glyphs)
|
||||
{
|
||||
if (ch == glyph.ch)
|
||||
{
|
||||
|
||||
@ -8,6 +8,7 @@ import util;
|
||||
import core.simd;
|
||||
import math;
|
||||
import core.stdc.string : memcpy;
|
||||
import fonts;
|
||||
|
||||
// TODO:
|
||||
// 1. Determine how to better handle inputs
|
||||
@ -16,11 +17,7 @@ import core.stdc.string : memcpy;
|
||||
|
||||
void main(string[] argv)
|
||||
{
|
||||
Arena arena = CreateArena(MB(32));
|
||||
InitFreeType();
|
||||
u8[] font_data = LoadAssetData(&arena, "fonts/NuberNextCondensed-DemiBold.otf");
|
||||
FontFace font = OpenFont(font_data);
|
||||
FONT_ATLAS_TEST = CreateAtlas(&arena, font, 128.0, 2048);
|
||||
|
||||
PlatformWindow window = CreateWindow("Video Game", 1920, 1080);
|
||||
Game g = InitGame(&window);
|
||||
|
||||
@ -5,6 +5,8 @@ import core.memory;
|
||||
import core.thread.osthread;
|
||||
import core.time;
|
||||
|
||||
@nogc:
|
||||
|
||||
const WINDOW_EDGE_BUFFER = 50;
|
||||
|
||||
enum Input
|
||||
@ -40,6 +42,7 @@ alias KBI = Input;
|
||||
version(linux)
|
||||
{
|
||||
import core.sys.posix.dlfcn;
|
||||
import core.sys.posix.sys.mman;
|
||||
|
||||
struct InputEvent
|
||||
{
|
||||
@ -130,7 +133,7 @@ CreateWindow(string name, u16 width, u16 height)
|
||||
XCB_EVENT_MASK_POINTER_MOTION |
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
|
||||
i32[] val_win = [window.screen.black_pixel, event_mask];
|
||||
i32[2] val_win = [window.screen.black_pixel, event_mask];
|
||||
i32 val_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
||||
|
||||
window.window = xcb_generate_id(window.conn);
|
||||
@ -599,6 +602,18 @@ case XK_g:
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
MemAlloc(u64 size)
|
||||
{
|
||||
return mmap(null, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
MemFree(void* ptr, u64 size)
|
||||
{
|
||||
assert(munmap(ptr, size) == 0, "MemFree failure");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
version(Windows)
|
||||
|
||||
@ -535,7 +535,7 @@ InitConversionPipeline(Vulkan* vk)
|
||||
{
|
||||
Push(vk, SI.Pipelines);
|
||||
|
||||
VkDescriptorSetLayoutBinding[] layout_bindings = [
|
||||
VkDescriptorSetLayoutBinding[2] layout_bindings = [
|
||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
||||
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
||||
];
|
||||
@ -545,19 +545,20 @@ InitConversionPipeline(Vulkan* vk)
|
||||
vk.conv_pipeline_layout = CreatePipelineLayout(vk, vk.conv_desc_layout, ConvPushConst.sizeof, true);
|
||||
|
||||
u32 channels = 1;
|
||||
SpecEntry[1] entries = [
|
||||
{
|
||||
constantID: 0,
|
||||
size: u32.sizeof,
|
||||
offset: 0,
|
||||
}
|
||||
];
|
||||
CompPipelineInfo conv_info = {
|
||||
shader: "shaders/convert.comp.spv",
|
||||
layout: vk.conv_pipeline_layout,
|
||||
spec: {
|
||||
data: &channels,
|
||||
size: u32.sizeof,
|
||||
entries: [
|
||||
{
|
||||
constantID: 0,
|
||||
size: u32.sizeof,
|
||||
offset: 0,
|
||||
}
|
||||
],
|
||||
entries: entries,
|
||||
},
|
||||
};
|
||||
|
||||
@ -599,11 +600,12 @@ CreateBuffer(Vulkan* vk, Buffer* buf, BufferType type, u64 size, bool host_visib
|
||||
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
}
|
||||
|
||||
u32[2] indices = [vk.queues.gfx_index, vk.queues.tfer_index];
|
||||
if (vk.queues.gfx_index != vk.queues.tfer_index)
|
||||
{
|
||||
buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||
buffer_info.queueFamilyIndexCount = 2;
|
||||
buffer_info.pQueueFamilyIndices = cast(const u32*)[vk.queues.gfx_index, vk.queues.tfer_index];
|
||||
buffer_info.pQueueFamilyIndices = indices.ptr;
|
||||
}
|
||||
|
||||
VmaAllocationInfo vma_info;
|
||||
@ -731,7 +733,7 @@ BeginRendering(Vulkan* vk)
|
||||
VkImage image = CurrentImage(vk);
|
||||
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
VkClearValue[] clear_color = [
|
||||
VkClearValue[2] clear_color = [
|
||||
{
|
||||
color: {
|
||||
float32: [0.0, 0.0, 0.0, 1.0],
|
||||
@ -900,7 +902,7 @@ DrawIndexed(Vulkan* vk, u32 index_count, u32 instance_count, u32 index_offset)
|
||||
}
|
||||
|
||||
bool
|
||||
ImmSubmit(Vulkan* vk, void delegate() fn)
|
||||
ImmSubmitStart(Vulkan* vk)
|
||||
{
|
||||
VkResult result = vkWaitForFences(vk.device, 1, &vk.imm_fence, true, 999999999);
|
||||
bool success = VkCheck("ImmSubmit failure: vkWaitForFences error", result);
|
||||
@ -917,7 +919,6 @@ ImmSubmit(Vulkan* vk, void delegate() fn)
|
||||
success = VkCheck("ImmSubmit failure: vkResetCommandBuffer error", result);
|
||||
}
|
||||
|
||||
bool imm_started;
|
||||
if (success)
|
||||
{
|
||||
VkCommandBufferBeginInfo cmd_info = {
|
||||
@ -926,19 +927,15 @@ ImmSubmit(Vulkan* vk, void delegate() fn)
|
||||
};
|
||||
|
||||
result = vkBeginCommandBuffer(vk.imm_cmd, &cmd_info);
|
||||
imm_started = success = VkCheck("ImmSubmit failure: vkBeginCommandBuffer error", result);
|
||||
success = VkCheck("ImmSubmit failure: vkBeginCommandBuffer error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
fn();
|
||||
return success;
|
||||
}
|
||||
|
||||
result = vkEndCommandBuffer(vk.imm_cmd);
|
||||
success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
bool
|
||||
ImmSubmitFinish(Vulkan* vk)
|
||||
{
|
||||
VkCommandBufferSubmitInfo cmd_info = {
|
||||
sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
|
||||
commandBuffer: vk.imm_cmd,
|
||||
@ -950,13 +947,54 @@ ImmSubmit(Vulkan* vk, void delegate() fn)
|
||||
pCommandBufferInfos: &cmd_info,
|
||||
};
|
||||
|
||||
result = vkQueueSubmit2(vk.tfer_queue, 1, &submit_info, vk.imm_fence);
|
||||
success = VkCheck("ImmSubmit failure: vkQueueSubmit2 error", result);
|
||||
VkResult result = vkQueueSubmit2(vk.tfer_queue, 1, &submit_info, vk.imm_fence);
|
||||
return VkCheck("ImmSubmit failure: vkQueueSubmit2 error", result);
|
||||
}
|
||||
|
||||
bool
|
||||
ImmSubmit(Vulkan* vk, Image* image, VkBufferImageCopy copy, void function(Vulkan*, Image*, VkBufferImageCopy) fn)
|
||||
{
|
||||
bool success = ImmSubmitStart(vk);
|
||||
|
||||
if (success)
|
||||
{
|
||||
fn(vk, image, copy);
|
||||
|
||||
VkResult result = vkEndCommandBuffer(vk.imm_cmd);
|
||||
success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = ImmSubmitFinish(vk);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
ImmSubmit(Vulkan* vk, Buffer* buf, VkBufferCopy copy, void function(Vulkan*, Buffer*, VkBufferCopy) fn)
|
||||
{
|
||||
bool success = ImmSubmitStart(vk);
|
||||
|
||||
if (success)
|
||||
{
|
||||
fn(vk, buf, copy);
|
||||
|
||||
VkResult result = vkEndCommandBuffer(vk.imm_cmd);
|
||||
success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = ImmSubmitFinish(vk);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
TransferAssets(Vulkan* vk)
|
||||
{
|
||||
@ -1120,11 +1158,12 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format, ImageU
|
||||
},
|
||||
};
|
||||
|
||||
u32[2] indices = [vk.gfx_index, vk.tfer_index];
|
||||
if (vk.gfx_index != vk.tfer_index)
|
||||
{
|
||||
image_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||
image_info.queueFamilyIndexCount = 2;
|
||||
image_info.pQueueFamilyIndices = cast(const u32*)[vk.gfx_index, vk.tfer_index];
|
||||
image_info.pQueueFamilyIndices = indices.ptr;
|
||||
}
|
||||
|
||||
VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &view.image, &view.alloc, null);
|
||||
@ -1225,22 +1264,24 @@ Transfer(Vulkan* vk, Buffer* buf, u8[] data)
|
||||
|
||||
vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];
|
||||
|
||||
auto fn = delegate()
|
||||
auto fn = function(Vulkan* vk, Buffer* buf, VkBufferCopy copy)
|
||||
{
|
||||
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, ©);
|
||||
};
|
||||
|
||||
VkBufferCopy copy = {
|
||||
srcOffset: 0,
|
||||
dstOffset: copied,
|
||||
size: copy_length,
|
||||
};
|
||||
|
||||
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, ©);
|
||||
};
|
||||
|
||||
success = ImmSubmit(vk, fn);
|
||||
success = ImmSubmit(vk, buf, copy, fn);
|
||||
|
||||
copied += copy_length;
|
||||
}
|
||||
|
||||
WaitForTransfers(vk);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -1254,20 +1295,22 @@ Transfer(T)(Vulkan* vk, Buffer* buf, T* ptr)
|
||||
{
|
||||
memcpy(vk.transfer_buf.data.ptr, ptr, T.sizeof);
|
||||
|
||||
auto fn = delegate()
|
||||
auto fn = function(Vulkan* vk, Buffer* buf, VkBufferCopy copy)
|
||||
{
|
||||
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, ©);
|
||||
};
|
||||
|
||||
VkBufferCopy copy = {
|
||||
srcOffset: 0,
|
||||
dstOffset: 0,
|
||||
size: T.sizeof,
|
||||
};
|
||||
|
||||
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, ©);
|
||||
};
|
||||
|
||||
success = ImmSubmit(vk, fn);
|
||||
success = ImmSubmit(vk, buf, copy, fn);
|
||||
}
|
||||
|
||||
WaitForTransfers(vk);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -1299,8 +1342,15 @@ Transfer(Vulkan* vk, Image* image, u8[] data, u32 w, u32 h)
|
||||
|
||||
vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];
|
||||
|
||||
auto fn = delegate()
|
||||
auto fn = function(Vulkan* vk, Image* image, VkBufferImageCopy copy)
|
||||
{
|
||||
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
vkCmdCopyBufferToImage(vk.imm_cmd, vk.transfer_buf.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||
|
||||
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
};
|
||||
|
||||
VkBufferImageCopy copy = {
|
||||
bufferRowLength: w,
|
||||
bufferImageHeight: h,
|
||||
@ -1316,18 +1366,13 @@ Transfer(Vulkan* vk, Image* image, u8[] data, u32 w, u32 h)
|
||||
bufferOffset: copied,
|
||||
};
|
||||
|
||||
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
vkCmdCopyBufferToImage(vk.imm_cmd, vk.transfer_buf.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||
|
||||
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
};
|
||||
|
||||
success = ImmSubmit(vk, fn);
|
||||
success = ImmSubmit(vk, image, copy, fn);
|
||||
|
||||
copied += copy_length;
|
||||
}
|
||||
|
||||
WaitForTransfers(vk);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -1577,7 +1622,7 @@ BuildShader(Vulkan* vk, u8[] bytes)
|
||||
void
|
||||
InitFramebufferAndRenderPass(Vulkan* vk)
|
||||
{
|
||||
VkAttachmentDescription[] attach_descriptions = [
|
||||
VkAttachmentDescription[2] attach_descriptions = [
|
||||
{
|
||||
format: vk.draw_image.format,
|
||||
samples: VK_SAMPLE_COUNT_1_BIT,
|
||||
@ -1666,7 +1711,7 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
||||
pipeline.type = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
pipeline.layout = build_info.layout;
|
||||
|
||||
VkDynamicState[] dyn_state = [ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR ];
|
||||
VkDynamicState[2] dyn_state = [ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR ];
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dyn_info = {
|
||||
sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
@ -1753,7 +1798,7 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
||||
scissorCount: 1,
|
||||
};
|
||||
|
||||
VkPipelineShaderStageCreateInfo[] shader_info = [
|
||||
VkPipelineShaderStageCreateInfo[2] shader_info = [
|
||||
{
|
||||
sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
stage: VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
@ -2047,7 +2092,7 @@ InitDescriptors(Vulkan* vk)
|
||||
void
|
||||
PushDescriptorPool(Vulkan* vk)
|
||||
{
|
||||
VkDescriptorPoolSize[] pool_sizes = [
|
||||
VkDescriptorPoolSize[7] pool_sizes = [
|
||||
{ type: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 4096 },
|
||||
{ type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 4096 },
|
||||
{ type: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, descriptorCount: 4096 },
|
||||
@ -2104,7 +2149,7 @@ InitGlobalDescSet(Vulkan* vk)
|
||||
|
||||
if (success)
|
||||
{
|
||||
DescLayoutBinding[] layout_bindings = [
|
||||
DescLayoutBinding[2] layout_bindings = [
|
||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
];
|
||||
@ -2135,14 +2180,20 @@ InitGlobalDescSet(Vulkan* vk)
|
||||
}
|
||||
|
||||
void
|
||||
WriteGUI(Vulkan* vk, DescSet set, ImageView* atlas)
|
||||
WriteGUI(Vulkan* vk, DescSet set, ImageView* atlas, Buffer* buf)
|
||||
{
|
||||
VkDescriptorImageInfo image_info = {
|
||||
imageView: atlas.view,
|
||||
imageLayout: atlas.layout,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet[] writes = [
|
||||
VkDescriptorBufferInfo buf_info = {
|
||||
buffer: buf.buffer,
|
||||
range: buf.size,
|
||||
offset: 0,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet[2] writes = [
|
||||
{
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: set.handle,
|
||||
@ -2150,6 +2201,14 @@ WriteGUI(Vulkan* vk, DescSet set, ImageView* atlas)
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
pImageInfo: &image_info,
|
||||
},
|
||||
{
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: set.handle,
|
||||
dstBinding: 1,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
pBufferInfo: &buf_info,
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@ public import includes;
|
||||
import platform;
|
||||
import vulkan : Vulkan, VULKAN_LIBS;
|
||||
|
||||
@nogc:
|
||||
|
||||
// Global Functions
|
||||
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = null;
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
layout (set = 1, binding = 0) uniform texture2D SpriteAtlas;
|
||||
|
||||
layout (set = 1, binding = 1) uniform Scale {
|
||||
vec2 factor;
|
||||
} S;
|
||||
|
||||
layout (push_constant) uniform Constants {
|
||||
vec2 res;
|
||||
} PC;
|
||||
|
||||
@ -50,8 +50,8 @@ void main()
|
||||
FragData.color = in_col;
|
||||
FragData.uv = uvs[gl_VertexIndex] / tex_size;
|
||||
|
||||
gl_Position = vec4(2 * dst_pos.x / PC.res.x - 1,
|
||||
2 * dst_pos.y / PC.res.y - 1,
|
||||
gl_Position = vec4((2 * dst_pos.x / PC.res.x - 1) * S.factor.x,
|
||||
(2 * dst_pos.y / PC.res.y - 1) * S.factor.y,
|
||||
0,
|
||||
1);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import math;
|
||||
import std.stdio;
|
||||
import core.stdc.string : memset;
|
||||
import core.memory;
|
||||
import platform;
|
||||
|
||||
const DEFAULT_ALIGNMENT = (void *).sizeof * 2;
|
||||
|
||||
@ -13,6 +14,32 @@ struct Arena
|
||||
u64 pos;
|
||||
};
|
||||
|
||||
T*
|
||||
MAlloc(T)()
|
||||
{
|
||||
void* mem = MemAlloc(T.sizeof);
|
||||
return cast(T*)mem;
|
||||
}
|
||||
|
||||
T[]
|
||||
MAllocArray(T)(u64 count)
|
||||
{
|
||||
void* mem = MemAlloc(T.sizeof * count);
|
||||
return cast(T*)(mem)[0 .. count];
|
||||
}
|
||||
|
||||
void
|
||||
MFree(T)(T* ptr)
|
||||
{
|
||||
MemFree(cast(void*)ptr, T.sizeof);
|
||||
}
|
||||
|
||||
void
|
||||
MFreeArray(T)(T[] slice)
|
||||
{
|
||||
MemFree(cast(void*)slice.ptr, cast(u64)slice.length);
|
||||
}
|
||||
|
||||
T*
|
||||
Alloc(T)()
|
||||
{
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#pragma attribute(push, nogc, nothrow)
|
||||
|
||||
#ifdef __linux__
|
||||
# include <xcb/xcb.h>
|
||||
# include <xcb/xfixes.h>
|
||||
|
||||
@ -8,63 +8,38 @@ import core.simd;
|
||||
import std.conv;
|
||||
import std.string;
|
||||
|
||||
enum AtlasType
|
||||
struct DynSlice(T)
|
||||
{
|
||||
None = 0,
|
||||
SoftMask,
|
||||
T[][] slices;
|
||||
u32 length;
|
||||
u32 capacity;
|
||||
u32 grow_size;
|
||||
}
|
||||
|
||||
enum YOrigin
|
||||
DynSlice!(T)
|
||||
CreateDynSlice(T)(u32 size)
|
||||
{
|
||||
None = 0,
|
||||
Bottom,
|
||||
DynSlice!(T) dslice = {
|
||||
slices: MAllocArray!(T[])(size),
|
||||
length: 0,
|
||||
capacity: size,
|
||||
grow_size: size,
|
||||
};
|
||||
|
||||
dslice.slices[0] = MAllocArray!(T)(size);
|
||||
|
||||
return dslice;
|
||||
}
|
||||
|
||||
struct FontAtlas
|
||||
u32
|
||||
Next(T)(DynSlice!(T)* slice)
|
||||
{
|
||||
AtlasType type;
|
||||
f32 size;
|
||||
u32 width;
|
||||
u32 height;
|
||||
YOrigin y_origin;
|
||||
f32 em_size;
|
||||
f32 line_height;
|
||||
f32 ascender;
|
||||
f32 descender;
|
||||
f32 underline_y;
|
||||
f32 underline_thickness;
|
||||
Glyph[] glyphs;
|
||||
}
|
||||
if (slice.length < slice.capacity)
|
||||
{
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
dchar ch;
|
||||
f32 advance;
|
||||
f32 plane_left;
|
||||
f32 plane_bottom;
|
||||
f32 plane_right;
|
||||
f32 plane_top;
|
||||
f32 atlas_left;
|
||||
f32 atlas_bottom;
|
||||
f32 atlas_right;
|
||||
f32 atlas_top;
|
||||
}
|
||||
}
|
||||
|
||||
struct TrackedSlice(T)
|
||||
{
|
||||
T[] slice;
|
||||
u32 free_index;
|
||||
}
|
||||
|
||||
alias TSlice = TrackedSlice;
|
||||
|
||||
TSlice!(T)
|
||||
InitTrackedSlice(T)(u32 length)
|
||||
{
|
||||
TSlice!(T) tslice;
|
||||
tslice.slice = AllocArray!(T[])(length);
|
||||
|
||||
return tslice;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user