Clean up whitespace and remove a few test files.

This commit is contained in:
BearOso 2023-01-23 15:02:56 -06:00
parent 259dfd07ae
commit ed37f930aa
12 changed files with 42 additions and 851 deletions

View File

@ -19,7 +19,7 @@ void trim(string_view &view)
{
while (view.length() > 0 && isspace(view.at(0)))
view.remove_prefix(1);
while (view.length() > 0 && isspace(view.at(view.length() - 1)))
view.remove_suffix(1);
}
@ -31,7 +31,7 @@ string trim(const string& str)
return string(sv);
}
int get_significant_digits(const string_view &view)
int get_significant_digits(const string_view &view)
{
auto pos = view.rfind('.');
if (pos == string_view::npos)
@ -58,13 +58,13 @@ vector<string> split_string_quotes(const string_view &view)
if (indexb == string::npos)
break;
}
else
else
{
indexb = view.find_first_of("\t\r\n ", indexa);
if (indexb == string::npos)
indexb = view.size();
}
if (indexb > indexa)
tokens.push_back(string{view.substr(indexa, indexb - indexa)});
pos = indexb + 1;
@ -78,7 +78,7 @@ vector<string> split_string(const string_view &str, unsigned char delim)
vector<string> tokens;
size_t pos = 0;
size_t index;
while (pos < str.length())
{
index = str.find(delim, pos);
@ -86,7 +86,7 @@ vector<string> split_string(const string_view &str, unsigned char delim)
{
if (pos < str.length())
{
tokens.push_back(string{str.substr(pos)});
tokens.push_back(string{str.substr(pos)});
}
break;
@ -97,7 +97,7 @@ vector<string> split_string(const string_view &str, unsigned char delim)
}
pos = index + 1;
}
}
return tokens;
}
@ -110,7 +110,7 @@ bool ends_with(const string &str, const string &ext)
auto icmp = [](const unsigned char a, const unsigned char b) -> bool {
return std::tolower(a) == std::tolower(b);
};
return std::equal(ext.crbegin(), ext.crend(), str.crbegin(), icmp);
}

View File

@ -259,7 +259,7 @@ void SlangPreset::gather_parameters()
map.insert({ p.id, p });
}
}
parameters.clear();
for (auto &p : map)
parameters.push_back(p.second);
@ -344,8 +344,8 @@ void SlangPreset::print()
printf(" Samplers: %zu\n", s.samplers.size());
for (auto &sampler : s.samplers)
{
const char *strings[] =
{
const char *strings[] =
{
"Previous Frame",
"Pass",
"Pass Feedback",
@ -426,7 +426,7 @@ bool SlangPreset::match_sampler_semantic(const string &name, int pass, SlangShad
specifier = -1;
return true;
}
else if (name == "Source")
else if (name == "Source")
{
type = SlangShader::Sampler::Type::Pass;
specifier = pass - 1;
@ -452,7 +452,7 @@ bool SlangPreset::match_sampler_semantic(const string &name, int pass, SlangShad
type = SlangShader::Sampler::Type::Lut;
return true;
}
else
else
{
for (size_t i = 0; i < passes.size(); i++)
{
@ -462,7 +462,7 @@ bool SlangPreset::match_sampler_semantic(const string &name, int pass, SlangShad
specifier = i;
return true;
}
else if (passes[i].alias + "Feedback" == name)
else if (passes[i].alias + "Feedback" == name)
{
type = SlangShader::Sampler::Type::PassFeedback;
specifier = i;
@ -491,7 +491,7 @@ bool SlangPreset::match_buffer_semantic(const string &name, int pass, SlangShade
type = SlangShader::Uniform::Type::MVP;
return true;
}
if (name == "FrameCount")
{
type = SlangShader::Uniform::Type::FrameCount;
@ -518,7 +518,7 @@ bool SlangPreset::match_buffer_semantic(const string &name, int pass, SlangShade
if (name.compare(prefix.length(), 4, "Size") != 0)
return false;
if (prefix.length() + 4 < name.length())
specifier = std::stoi(name.substr(prefix.length() + 4));
@ -530,7 +530,7 @@ bool SlangPreset::match_buffer_semantic(const string &name, int pass, SlangShade
type = SlangShader::Uniform::Type::PassSize;
specifier = -1;
return true;
}
}
else if (match("Source"))
{
type = SlangShader::Uniform::Type::PassSize;
@ -573,7 +573,7 @@ bool SlangPreset::match_buffer_semantic(const string &name, int pass, SlangShade
return true;
}
}
for (size_t i = 0; i < textures.size(); i++)
{
if (match(textures[i].id))
@ -636,7 +636,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
{
shader.push_constant_block_size = 0;
}
else
else
{
auto &pcb = res.push_constant_buffers[0];
auto &pcb_type = cross.get_type(pcb.base_type_id);
@ -659,7 +659,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
if (!exists(uniform))
shader.uniforms.push_back(uniform);
}
else
else
{
printf("%s: Failed to match push constant semantic: \"%s\"\n", shader.filename.c_str(), name.c_str());
}
@ -670,7 +670,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
{
shader.ubo_size = 0;
}
else
else
{
auto &ubo = res.uniform_buffers[0];
auto &ubo_type = cross.get_type(ubo.base_type_id);
@ -694,7 +694,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
if (!exists(uniform))
shader.uniforms.push_back(uniform);
}
else
else
{
printf("%s: Failed to match uniform buffer semantic: \"%s\"\n", shader.filename.c_str(), name.c_str());
}
@ -706,7 +706,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
printf("No sampled images found in fragment shader.\n");
return false;
}
if (res.sampled_images.size() > 0 && stage == SlangShader::Stage::Vertex)
{
printf("Sampled image found in vertex shader.\n");
@ -725,7 +725,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
int binding = cross.get_decoration(image.id, spv::DecorationBinding);
shader.samplers.push_back({ semantic_type, specifier, binding });
}
else
else
{
printf("%s: Failed to match sampler semantic: \"%s\"\n", shader.filename.c_str(), image.name.c_str());
return false;
@ -740,7 +740,7 @@ bool SlangPreset::introspect_shader(SlangShader &shader, int pass, SlangShader::
Introspect all of preset's shaders.
*/
bool SlangPreset::introspect()
{
{
for (size_t i = 0; i < passes.size(); i++)
{
if (!introspect_shader(passes[i], i, SlangShader::Stage::Vertex))
@ -752,7 +752,7 @@ bool SlangPreset::introspect()
oldest_previous_frame = 0;
uses_feedback = false;
last_pass_uses_feedback = false;
for (auto &p : passes)
{
for (auto &s : p.samplers)
@ -772,7 +772,7 @@ bool SlangPreset::introspect()
}
bool SlangPreset::save_to_file(std::string filename)
{
{
std::ofstream out(filename);
if (!out.is_open())
return false;
@ -837,6 +837,6 @@ bool SlangPreset::save_to_file(std::string filename)
}
out.close();
return true;
}

View File

@ -17,7 +17,7 @@ static std::string trim_comments(std::string str)
for (auto &comment : { "//", "#" })
{
auto location = str.rfind(comment);
if (location != std::string::npos)
str = str.substr(0, location);
}
@ -47,7 +47,7 @@ bool IniFile::load_file(std::string filename)
{
if (file.eof())
break;
std::getline(file, line);
line = trim(line);
@ -75,7 +75,7 @@ bool IniFile::load_file(std::string filename)
{
auto left_side = trim_quotes(trim(line.substr(0, equals)));
auto right_side = trim_quotes(trim(line.substr(equals + 1)));
keys.insert_or_assign(left_side, std::make_pair(right_side, filename));
}
}
@ -115,7 +115,7 @@ std::string IniFile::get_source(std::string key)
auto it = keys.find(key);
if (it == keys.end())
return "";
return it->second.second;
}
@ -128,7 +128,7 @@ bool IniFile::get_bool(std::string key, bool default_value = false)
std::string lower = it->second.first;
for (auto &c : lower)
c = tolower(c);
const char *true_strings[] = { "true", "1", "yes", "on"};
for (auto &s : true_strings)
if (lower == s)

View File

@ -16,10 +16,10 @@ int main(int argc, char **argv)
printf("Failed to load %s\n", argv[1]);
return -1;
}
preset.introspect();
preset.print();
return 0;
}

View File

@ -4,7 +4,7 @@
struct SlangShader
{
struct Parameter
struct Parameter
{
std::string name;
std::string id;
@ -58,7 +58,7 @@ struct SlangShader
int binding;
};
enum class Stage
enum class Stage
{
Vertex,
Fragment

View File

@ -1,80 +0,0 @@
#include <gtkmm.h>
#include <gdk/gdkx.h>
#include "vk2d.hpp"
int main(int argc, char *argv[])
{
XInitThreads();
auto application = Gtk::Application::create(argc, argv, "org.bearoso.vulkantest");
Gtk::Window window;
Gtk::Button button;
Gtk::DrawingArea drawingarea;
Gtk::VBox vbox;
window.set_title("Vulkan Test");
window.set_events(Gdk::EventMask::ALL_EVENTS_MASK);
button.set_label("Close");
vbox.pack_start(drawingarea, true, true, 0);
vbox.pack_start(button, false, false, 0);
vbox.set_spacing(5);
button.set_hexpand(false);
button.set_halign(Gtk::ALIGN_END);
window.add(vbox);
window.set_border_width(5);
vbox.show_all();
button.signal_clicked().connect([&] {
window.close();
});
window.resize(640, 480);
window.show_all();
Window xid = gdk_x11_window_get_xid(drawingarea.get_window()->gobj());
Display *dpy = gdk_x11_display_get_xdisplay(drawingarea.get_display()->gobj());
vk2d vk2d;
vk2d.init_xlib_instance();
vk2d.attach(dpy, xid);
vk2d.init_device();
drawingarea.signal_configure_event().connect([&](GdkEventConfigure *event) {
vk2d.recreate_swapchain();
return false;
});
window.signal_key_press_event().connect([&](GdkEventKey *key) -> bool {
printf ("Key press %d\n", key->keyval);
return false;
}, false);
window.signal_key_release_event().connect([&](GdkEventKey *key) -> bool {
printf ("Key release %d\n", key->keyval);
return false;
}, false);
drawingarea.set_app_paintable(true);
drawingarea.signal_draw().connect([&](const Cairo::RefPtr<Cairo::Context> &context) -> bool {
return true;
});
auto id = Glib::signal_idle().connect([&]{
vk2d.draw();
vk2d.wait_idle();
return true;
});
window.signal_delete_event().connect([&](GdkEventAny *event) {
id.disconnect();
return false;
});
application->run(window);
return 0;
}

View File

@ -1,641 +0,0 @@
#include "vk2d.hpp"
#include <glslang/Include/BaseTypes.h>
#include <glslang/Public/ShaderLang.h>
#include <glslang/SPIRV/GlslangToSpv.h>
#include <glslang/Include/ResourceLimits.h>
#include <vulkan/vulkan_core.h>
static const char *vertex_shader = R"(
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) out vec3 fragColor;
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
vec3 colors[3] = vec3[](
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
);
void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
fragColor = colors[gl_VertexIndex];
}
)";
static const char *fragment_shader = R"(
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
}
)";
bool vk2d::dispatcher_initialized = false;
vk2d::vk2d()
{
instance = nullptr;
surface = nullptr;
if (!dispatcher_initialized)
{
vk::DynamicLoader *dl = new vk::DynamicLoader;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl->getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
dispatcher_initialized = true;
}
}
vk2d::~vk2d()
{
deinit();
}
bool vk2d::init_device()
{
if (!instance || !surface)
return false;
choose_physical_device();
create_device();
create_sync_objects();
create_swapchain();
create_render_pass();
create_pipeline();
create_framebuffers();
create_command_buffers();
return true;
}
#ifdef VK_USE_PLATFORM_XLIB_KHR
bool vk2d::init_xlib_instance()
{
if (instance)
return true;
std::vector<const char *> extensions = { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME };
vk::ApplicationInfo ai({}, {}, {}, {}, VK_API_VERSION_1_0);
vk::InstanceCreateInfo ci({}, &ai, {}, extensions);
auto rv = vk::createInstance(ci);
if (rv.result != vk::Result::eSuccess)
return false;
instance = rv.value;
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
return true;
}
void vk2d::attach(Display *dpy, Window xid)
{
if (surface)
{
instance.destroySurfaceKHR(surface);
surface = nullptr;
}
vk::XlibSurfaceCreateInfoKHR sci({}, dpy, xid);
auto rv = instance.createXlibSurfaceKHR(sci);
VK_CHECK(rv.result);
surface = rv.value;
}
#endif // VK_USE_PLATFORM_XLIB_KHR
bool vk2d::create_instance()
{
std::vector<const char *> extensions = { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME };
vk::ApplicationInfo ai({}, {}, {}, {}, VK_API_VERSION_1_1);
vk::InstanceCreateInfo ci({}, &ai, {}, {}, extensions.size(), extensions.data());
auto rv = vk::createInstance(ci);
VK_CHECK(rv.result);
instance = rv.value;
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
return true;
}
void vk2d::deinit()
{
destroy_swapchain();
frame_queue.clear();
if (command_pool)
device.destroyCommandPool(command_pool);
if (device)
device.destroy();
if (surface)
instance.destroySurfaceKHR(surface);
if (instance)
instance.destroy();
}
void vk2d::destroy_swapchain()
{
if (device)
{
VK_CHECK(device.waitIdle());
}
swapchain.framebuffers.clear();
swapchain.views.clear();
device.freeCommandBuffers(command_pool, swapchain.command_buffers);
if (graphics_pipeline)
device.destroyPipeline(graphics_pipeline);
if (render_pass)
device.destroyRenderPass(render_pass);
if (pipeline_layout)
device.destroyPipelineLayout(pipeline_layout);
if (swapchain.obj)
{
device.destroySwapchainKHR(swapchain.obj);
swapchain.obj = nullptr;
}
}
void vk2d::recreate_swapchain()
{
frame_queue_index = 0;
destroy_swapchain();
create_swapchain();
create_render_pass();
create_pipeline();
create_framebuffers();
create_command_buffers();
}
void vk2d::choose_physical_device()
{
if (!surface)
assert(0);
auto devices = instance.enumeratePhysicalDevices();
VK_CHECK(devices.result);
std::vector<vk::PhysicalDevice> candidates;
for (auto &d : devices.value)
{
auto extension_properties = d.enumerateDeviceExtensionProperties();
VK_CHECK(extension_properties.result);
bool presentable = false;
for (auto &e : extension_properties.value)
{
std::string name = e.extensionName;
if (name == VK_KHR_SWAPCHAIN_EXTENSION_NAME)
{
presentable = true;
}
}
if (!presentable)
continue;
auto queue_families = d.getQueueFamilyProperties();
for (size_t q = 0; q < queue_families.size(); q++)
{
if (queue_families[q].queueFlags & vk::QueueFlagBits::eGraphics)
{
graphics_queue_index = q;
presentable = true;
break;
}
presentable = false;
}
presentable = presentable && d.getSurfaceSupportKHR(graphics_queue_index, surface).value;
if (presentable)
{
printf("Using %s\n", (char *)d.getProperties().deviceName);
physical_device = d;
return;
}
}
physical_device = nullptr;
graphics_queue_index = -1;
}
void vk2d::wait_idle()
{
if (device)
{
auto result = device.waitIdle();
VK_CHECK(result);
}
}
void vk2d::draw()
{
auto &frame = frame_queue[frame_queue_index];
uint32_t next;
VK_CHECK(device.waitForFences(1, &frame.fence.get(), true, UINT64_MAX));
vk::ResultValue resval = device.acquireNextImageKHR(swapchain.obj, UINT64_MAX, frame.image_ready.get(), nullptr);
if (resval.result != vk::Result::eSuccess)
{
if (resval.result == vk::Result::eErrorOutOfDateKHR)
{
printf("Recreating swapchain\n");
recreate_swapchain();
return;
}
VK_CHECK(resval.result);
exit(1);
}
next = resval.value;
if (swapchain.frame_fence[next] > -1)
{
VK_CHECK(device.waitForFences(1, &frame_queue[next].fence.get(), true, UINT64_MAX));
}
swapchain.frame_fence[next] = frame_queue_index;
VK_CHECK(device.resetFences(1, &frame.fence.get()));
vk::PipelineStageFlags flags = vk::PipelineStageFlagBits::eColorAttachmentOutput;
vk::SubmitInfo submit_info(frame.image_ready.get(),
flags,
swapchain.command_buffers[next],
frame.render_finished.get());
VK_CHECK(queue.submit(submit_info, frame.fence.get()));
vk::PresentInfoKHR present_info(frame.render_finished.get(), swapchain.obj, next, {});
VK_CHECK(queue.presentKHR(present_info));
frame_queue_index = (frame_queue_index + 1) % frame_queue_size;
}
void vk2d::create_device()
{
float queue_priority = 1.0f;
std::vector<const char *> extension_names = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
vk::DeviceQueueCreateInfo dqci({}, graphics_queue_index, 1, &queue_priority);
vk::DeviceCreateInfo dci;
dci.setPEnabledExtensionNames(extension_names);
std::vector<vk::DeviceQueueCreateInfo> pqci = {dqci};
dci.setQueueCreateInfos(pqci);
device = physical_device.createDevice(dci).value;
queue = device.getQueue(graphics_queue_index, 0);
vk::CommandPoolCreateInfo command_pool_info({}, graphics_queue_index);
command_pool = device.createCommandPool(command_pool_info).value;
}
void vk2d::create_swapchain()
{
if (!device || !surface)
assert(0);
vk::SurfaceCapabilitiesKHR surface_caps = physical_device.getSurfaceCapabilitiesKHR(surface).value;
swapchain.size = surface_caps.minImageCount;
vk::SwapchainCreateInfoKHR sci;
sci
.setSurface(surface)
.setMinImageCount(swapchain.size)
.setPresentMode(vk::PresentModeKHR::eFifo)
.setImageFormat(vk::Format::eB8G8R8A8Unorm)
.setImageExtent(surface_caps.currentExtent)
.setImageColorSpace(vk::ColorSpaceKHR::eSrgbNonlinear)
.setImageArrayLayers(1)
.setImageSharingMode(vk::SharingMode::eExclusive)
.setImageUsage(vk::ImageUsageFlagBits::eColorAttachment)
.setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
.setClipped(true);
if (swapchain.obj)
sci.setOldSwapchain(swapchain.obj);
swapchain.obj = device.createSwapchainKHR(sci).value;
swapchain.extents = surface_caps.currentExtent;
swapchain.images = device.getSwapchainImagesKHR(swapchain.obj).value;
swapchain.views.resize(swapchain.size);
for (size_t i = 0; i < swapchain.size; i++)
{
vk::ImageViewCreateInfo image_view_create_info;
image_view_create_info
.setImage(swapchain.images[i])
.setViewType(vk::ImageViewType::e2D)
.setFormat(vk::Format::eB8G8R8A8Unorm)
.setComponents(vk::ComponentMapping())
.setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
swapchain.views[i] = device.createImageViewUnique(image_view_create_info).value;
}
swapchain.frame_fence.resize(swapchain.size);
for (auto &f : swapchain.frame_fence)
f = -1;
}
void vk2d::create_sync_objects()
{
frame_queue.resize(frame_queue_size);
for (size_t i = 0; i < frame_queue_size; i++)
{
vk::SemaphoreCreateInfo semaphore_create_info;
frame_queue[i].image_ready = device.createSemaphoreUnique(semaphore_create_info).value;
frame_queue[i].render_finished = device.createSemaphoreUnique(semaphore_create_info).value;
vk::FenceCreateInfo fence_create_info(vk::FenceCreateFlagBits::eSignaled);
frame_queue[i].fence = device.createFenceUnique(fence_create_info).value;
}
frame_queue_index = 0;
}
namespace glslang
{
extern const TBuiltInResource DefaultTBuiltInResource;
}
void vk2d::create_shader_modules()
{
glslang::InitializeProcess();
EShMessages message_flags = (EShMessages)(EShMsgDefault | EShMsgVulkanRules | EShMsgSpvRules);
glslang::TShader vertex(EShLangVertex);
glslang::TShader fragment(EShLangFragment);
vertex.setStrings(&vertex_shader, 1);
fragment.setStrings(&fragment_shader, 1);
vertex.parse(&glslang::DefaultTBuiltInResource, 450, true, message_flags);
fragment.parse(&glslang::DefaultTBuiltInResource, 450, true, message_flags);
glslang::TProgram vertex_program;
glslang::TProgram fragment_program;
vertex_program.addShader(&vertex);
fragment_program.addShader(&fragment);
vertex_program.link(message_flags);
fragment_program.link(message_flags);
auto log = [](const char *msg)
{
if (msg != nullptr && msg[0] != '\0')
puts(msg);
};
log(vertex_program.getInfoLog());
log(vertex_program.getInfoDebugLog());
log(fragment_program.getInfoLog());
log(fragment_program.getInfoDebugLog());
std::vector<uint32_t> vertex_spirv;
std::vector<uint32_t> fragment_spirv;
glslang::GlslangToSpv(*vertex_program.getIntermediate(EShLangVertex), vertex_spirv);
glslang::GlslangToSpv(*fragment_program.getIntermediate(EShLangFragment), fragment_spirv);
vk::ShaderModuleCreateInfo smci;
smci.setCode(vertex_spirv);
vertex_module = device.createShaderModule(smci).value;
smci.setCode(fragment_spirv);
fragment_module = device.createShaderModule(smci).value;
}
void vk2d::create_pipeline()
{
create_shader_modules();
if (!vertex_module || !fragment_module)
assert(0);
vk::PipelineShaderStageCreateInfo vertex_ci;
vertex_ci
.setStage(vk::ShaderStageFlagBits::eVertex)
.setModule(vertex_module)
.setPName("main");
vk::PipelineShaderStageCreateInfo fragment_ci;
fragment_ci
.setStage(vk::ShaderStageFlagBits::eFragment)
.setModule(fragment_module)
.setPName("main");
std::vector<vk::PipelineShaderStageCreateInfo> stages = { vertex_ci, fragment_ci };
vk::PipelineVertexInputStateCreateInfo vertex_input_info;
vertex_input_info
.setVertexBindingDescriptionCount(0)
.setVertexAttributeDescriptionCount(0);
// Add Vertex attributes here
vk::PipelineInputAssemblyStateCreateInfo pipeline_input_assembly_info;
pipeline_input_assembly_info
.setTopology(vk::PrimitiveTopology::eTriangleList)
.setPrimitiveRestartEnable(false);
std::vector<vk::Viewport> viewports(1);
viewports[0]
.setX(0.0f)
.setY(0.0f)
.setWidth(swapchain.extents.width)
.setHeight(swapchain.extents.height)
.setMinDepth(0.0f)
.setMaxDepth(1.0f);
std::vector<vk::Rect2D> scissors(1);
scissors[0].extent = swapchain.extents;
scissors[0].offset = vk::Offset2D(0, 0);
vk::PipelineViewportStateCreateInfo pipeline_viewport_info;
pipeline_viewport_info
.setViewports(viewports)
.setScissors(scissors);
vk::PipelineRasterizationStateCreateInfo rasterizer_info;
rasterizer_info
.setCullMode(vk::CullModeFlagBits::eBack)
.setFrontFace(vk::FrontFace::eClockwise)
.setLineWidth(1.0f)
.setDepthClampEnable(false)
.setRasterizerDiscardEnable(false)
.setPolygonMode(vk::PolygonMode::eFill)
.setDepthBiasEnable(false)
.setRasterizerDiscardEnable(false);
vk::PipelineMultisampleStateCreateInfo multisample_info;
multisample_info
.setSampleShadingEnable(false)
.setRasterizationSamples(vk::SampleCountFlagBits::e1);
vk::PipelineDepthStencilStateCreateInfo depth_stencil_info;
depth_stencil_info.setDepthTestEnable(false);
vk::PipelineColorBlendAttachmentState blend_attachment_info;
blend_attachment_info
.setColorWriteMask(vk::ColorComponentFlagBits::eB |
vk::ColorComponentFlagBits::eG |
vk::ColorComponentFlagBits::eR |
vk::ColorComponentFlagBits::eA)
.setBlendEnable(true)
.setColorBlendOp(vk::BlendOp::eAdd)
.setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
.setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
.setAlphaBlendOp(vk::BlendOp::eAdd)
.setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
.setSrcAlphaBlendFactor(vk::BlendFactor::eZero);
vk::PipelineColorBlendStateCreateInfo blend_state_info;
blend_state_info
.setLogicOpEnable(false)
.setAttachmentCount(1)
.setPAttachments(&blend_attachment_info);
vk::PipelineDynamicStateCreateInfo dynamic_state_info;
dynamic_state_info.setDynamicStateCount(0);
vk::PipelineLayoutCreateInfo pipeline_layout_info;
pipeline_layout_info
.setSetLayoutCount(0)
.setPushConstantRangeCount(0);
pipeline_layout = device.createPipelineLayout(pipeline_layout_info).value;
vk::GraphicsPipelineCreateInfo pipeline_create_info;
pipeline_create_info
.setStageCount(2)
.setStages(stages)
.setPVertexInputState(&vertex_input_info)
.setPInputAssemblyState(&pipeline_input_assembly_info)
.setPViewportState(&pipeline_viewport_info)
.setPRasterizationState(&rasterizer_info)
.setPMultisampleState(&multisample_info)
.setPDepthStencilState(&depth_stencil_info)
.setPColorBlendState(&blend_state_info)
.setPDynamicState(&dynamic_state_info)
.setLayout(pipeline_layout)
.setRenderPass(render_pass)
.setSubpass(0);
vk::ResultValue<vk::Pipeline> result = device.createGraphicsPipeline(nullptr, pipeline_create_info);
graphics_pipeline = result.value;
device.destroyShaderModule(vertex_module);
device.destroyShaderModule(fragment_module);
}
void vk2d::create_render_pass()
{
vk::AttachmentDescription attachment_description(
{},
vk::Format::eB8G8R8A8Unorm,
vk::SampleCountFlagBits::e1,
vk::AttachmentLoadOp::eClear,
vk::AttachmentStoreOp::eStore,
vk::AttachmentLoadOp::eLoad,
vk::AttachmentStoreOp::eStore,
vk::ImageLayout::eUndefined,
vk::ImageLayout::ePresentSrcKHR);
vk::AttachmentReference attachment_reference(0, vk::ImageLayout::eColorAttachmentOptimal);
attachment_reference
.setAttachment(0)
.setLayout(vk::ImageLayout::eColorAttachmentOptimal);
vk::SubpassDependency subpass_dependency;
subpass_dependency
.setSrcSubpass(VK_SUBPASS_EXTERNAL)
.setDstSubpass(0)
.setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
.setSrcAccessMask(vk::AccessFlagBits(0))
.setDstStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
.setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite);
vk::SubpassDescription subpass_description;
subpass_description
.setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
.setColorAttachments(attachment_reference);
vk::RenderPassCreateInfo render_pass_info(
{},
attachment_description,
subpass_description,
subpass_dependency);
render_pass = device.createRenderPass(render_pass_info).value;
}
void vk2d::create_framebuffers()
{
swapchain.framebuffers.resize(swapchain.images.size());
for (size_t i = 0; i < swapchain.images.size(); i++)
{
vk::FramebufferCreateInfo fci;
std::vector<vk::ImageView> attachments = { swapchain.views[i].get() };
fci
.setAttachments(attachments)
.setLayers(1)
.setRenderPass(render_pass)
.setWidth(swapchain.extents.width)
.setHeight(swapchain.extents.height);
swapchain.framebuffers[i] = device.createFramebufferUnique(fci).value;
}
}
void vk2d::create_command_buffers()
{
vk::CommandBufferAllocateInfo allocate_info;
allocate_info.setCommandBufferCount(swapchain.images.size());
allocate_info.setCommandPool(command_pool);
swapchain.command_buffers = device.allocateCommandBuffers(allocate_info).value;
for (size_t i = 0; i < swapchain.command_buffers.size(); i++)
{
auto &cb = swapchain.command_buffers[i];
VK_CHECK(cb.begin(vk::CommandBufferBeginInfo{}));
vk::ClearColorValue color;
color.setFloat32({ 0.0f, 1.0f, 1.0f, 0.0f});
vk::ClearValue clear_value(color);
vk::RenderPassBeginInfo rpbi;
rpbi.setRenderPass(render_pass);
rpbi.setFramebuffer(swapchain.framebuffers[i].get());
rpbi.setPClearValues(&clear_value);
rpbi.setClearValueCount(1);
rpbi.renderArea.setExtent(swapchain.extents);
rpbi.renderArea.setOffset({0, 0});
cb.beginRenderPass(rpbi, vk::SubpassContents::eInline);
cb.bindPipeline(vk::PipelineBindPoint::eGraphics, graphics_pipeline);
cb.draw(3, 1, 0, 0);
cb.endRenderPass();
VK_CHECK(cb.end());
}
}

View File

@ -1,88 +0,0 @@
#pragma once
#include "vulkan/vulkan.hpp"
#include <fstream>
#ifdef VK_USE_PLATFORM_XLIB_KHR
#include <X11/Xlib.h>
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#include <wayland-client.h>
#endif
#define VK_CHECK(result) vk_check_result_function(result, __FILE__, __LINE__)
inline void vk_check_result_function(vk::Result result, const char *file, int line)
{
if (result != vk::Result::eSuccess)
{
printf("%s:%d Vulkan error: %s\n", file, line, vk::to_string(result).c_str());
}
}
class vk2d
{
public:
vk2d();
~vk2d();
#ifdef VK_USE_PLATFORM_XLIB_KHR
bool init_xlib_instance();
void attach(Display *dpy, Window xid);
#endif
bool init_device();
void deinit();
bool create_instance();
void choose_physical_device();
void create_device();
void create_swapchain();
void create_sync_objects();
void create_shader_modules();
void create_pipeline();
void create_render_pass();
void create_framebuffers();
void create_command_buffers();
void recreate_swapchain();
void destroy_swapchain();
void wait_idle();
void draw();
vk::Instance instance;
vk::PhysicalDevice physical_device;
vk::SurfaceKHR surface;
vk::Pipeline graphics_pipeline;
vk::PipelineLayout pipeline_layout;
vk::RenderPass render_pass;
vk::ShaderModule vertex_module;
vk::ShaderModule fragment_module;
vk::Device device;
vk::Queue queue;
vk::CommandPool command_pool;
size_t graphics_queue_index;
struct frame_t {
vk::UniqueSemaphore render_finished;
vk::UniqueSemaphore image_ready;
vk::UniqueFence fence;
};
static const size_t frame_queue_size = 3;
size_t frame_queue_index;
std::vector<frame_t> frame_queue;
struct {
vk::SwapchainKHR obj;
vk::Extent2D extents;
std::vector<vk::Image> images;
std::vector<vk::UniqueImageView> views;
std::vector<vk::UniqueFramebuffer> framebuffers;
std::vector<vk::CommandBuffer> command_buffers;
std::vector<int> frame_fence;
size_t size;
} swapchain;
static bool dispatcher_initialized;
};

View File

@ -202,7 +202,7 @@ void PipelineImage::clear(vk::CommandBuffer cmd)
vk::PipelineStageFlagBits::eFragmentShader,
{}, {}, {},
image_memory_barrier);
current_layout = vk::ImageLayout::eShaderReadOnlyOptimal;
}

View File

@ -330,7 +330,7 @@ void ShaderChain::update_descriptor_set(vk::CommandBuffer cmd, int pipe_num, int
{
assert(sampler.specifier < (int)pipelines.size());
assert(sampler.specifier >= 0);
if (!pipelines[sampler.specifier]->frame[last_frame_index].image.image)
update_framebuffers(cmd, last_frame_index);
auto &feedback_frame = pipelines[sampler.specifier]->frame[last_frame_index];

View File

@ -29,7 +29,7 @@ class SlangPipeline
vk::UniqueSemaphore semaphore;
vk::UniqueSampler sampler;
struct
struct
{
vk::UniqueDescriptorSet descriptor_set;
PipelineImage image;

View File

@ -140,7 +140,7 @@ void Texture::from_buffer(vk::CommandBuffer cmd,
.setSrcAccessMask(vk::AccessFlagBits::eTransferWrite)
.setDstAccessMask(vk::AccessFlagBits::eTransferRead)
.setSubresourceRange(srr(base_level));
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eTransfer,
{}, {}, {}, barrier);
@ -285,7 +285,7 @@ void Texture::create(int width, int height, vk::Format fmt, vk::SamplerAddressMo
sampler_create_info
.setMagFilter(vk::Filter::eLinear)
.setMinFilter(vk::Filter::eLinear);
if (mipmap)
sampler_create_info
.setMinLod(0.0f)