How does "Hello triangle" look in your abstraction layer?
Here is mine (~100 LOC)
link: lum-al
Renderer render = {};
int main(){
Settings settings = {};
settings.vsync = false;
settings.fullscreen = false;
settings.debug = false; //Validation Layers
settings.timestampCount = 128;
settings.profile = false; //timestamps
settings.fif = 2;
render.init(settings);
RasterPipe simple_raster_pipe = {};
RasterPipe simple_posteffect_pipe = {};
ring<Image> simple_inter_image;
render.createImageStorages(&simple_inter_image,
VK_IMAGE_TYPE_2D,
VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
{render.swapChainExtent.width, render.swapChainExtent.height, 1});
for(auto img : simple_inter_image){
render.transitionImageLayoutSingletime(&img, VK_IMAGE_LAYOUT_GENERAL);
}
render.descriptorBuilder
.setLayout(&simple_raster_pipe.setLayout)
.setDescriptorSets(&simple_raster_pipe.sets)
.defer();
render.descriptorBuilder
.setLayout(&simple_posteffect_pipe.setLayout)
.setDescriptorSets(&simple_posteffect_pipe.sets)
.setDescriptions({
{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, RD_FIRST, {/*empty*/}, {simple_inter_image}, NO_SAMPLER, VK_IMAGE_LAYOUT_GENERAL, VK_SHADER_STAGE_FRAGMENT_BIT}
})
.defer();
render.flushDescriptorSetup();
RenderPass simple_rpass = {};
render.renderPassBuilder.setAttachments({
{&simple_inter_image, DontCare, DontCare, DontCare, DontCare, {}, VK_IMAGE_LAYOUT_GENERAL},
{&render.swapchainImages, DontCare, Store, DontCare, DontCare, {}, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR},
}).setSubpasses({
{{&simple_raster_pipe}, {}, {&simple_inter_image}, {}},
{{&simple_posteffect_pipe}, {&simple_inter_image}, {&render.swapchainImages}, {}}
}).build(&simple_rpass);
render.pipeBuilder.setStages({
{"examples/vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"examples/frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
}).setExtent(render.swapChainExtent).setBlends({NO_BLEND})
.buildRaster(&simple_raster_pipe);
render.pipeBuilder.setStages({
{"examples/vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"examples/posteffect.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
}).setExtent(render.swapChainExtent).setBlends({NO_BLEND})
.buildRaster(&simple_posteffect_pipe);
ring<VkCommandBuffer> mainCommandBuffers;
ring<VkCommandBuffer> extraCommandBuffers; //runtime copies. Also does first frame resources
//you typically want to have FIF'count command buffers in their ring
//but if you only need like 1 "baked" command buffer, just use 1
render.createCommandBuffers ( &mainCommandBuffers, render.settings.fif);
render.createCommandBuffers (&extraCommandBuffers, render.settings.fif);
//you have to set this if you want to use builtin profiler
render.mainCommandBuffers = &mainCommandBuffers;
while(!glfwWindowShouldClose(render.window.pointer) && (glfwGetKey(render.window.pointer, GLFW_KEY_ESCAPE) != GLFW_PRESS)){
glfwPollEvents();
render.start_frame({mainCommandBuffers.current()});
render.cmdBeginRenderPass(mainCommandBuffers.current(), &simple_rpass);
render.cmdBindPipe(mainCommandBuffers.current(), simple_raster_pipe);
render.cmdDraw(mainCommandBuffers.current(), 3, 1, 0, 0);
render.cmdNextSubpass(mainCommandBuffers.current(), &simple_rpass);
render.cmdBindPipe(mainCommandBuffers.current(), simple_posteffect_pipe);
render.cmdDraw(mainCommandBuffers.current(), 3, 1, 0, 0);
render.cmdEndRenderPass(mainCommandBuffers.current(), &simple_rpass);
render.end_frame({mainCommandBuffers.current()});
//you are the one responsible for this, because using "previous" command buffer is quite common
mainCommandBuffers.move();
}
render.deviceWaitIdle();
render.destroyRenderPass(&simple_rpass);
render.destroyRasterPipeline(&simple_raster_pipe);
render.destroyRasterPipeline(&simple_posteffect_pipe);
render.deleteImages(&simple_inter_image);
render.cleanup();
}