Create shader modules for output pipeline

This commit is contained in:
Grayson Riffe 2025-02-11 16:46:18 -06:00
parent f5a06e6ac1
commit bfacea2bd4
6 changed files with 99 additions and 17 deletions

View File

@ -19,3 +19,26 @@ find_package(Git)
execute_process(COMMAND ${GIT_EXECUTABLE} describe OUTPUT_VARIABLE NFVERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
configure_file(src/version.h.in version.h)
target_include_directories(NothinFancy PUBLIC "${PROJECT_BINARY_DIR}/NothinFancy")
# Compile shaders
set(GLSLANG "$ENV{VULKAN_SDK}/Bin/glslang.exe")
set(SHADER_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/NothinFancy/shaders")
file(GLOB_RECURSE SHADER_SOURCES "res/shaders/*.glsl")
foreach(SHADER_SOURCE ${SHADER_SOURCES})
get_filename_component(FILENAME ${SHADER_SOURCE} NAME)
set(SHADER_BINARY "${SHADER_OUTPUT_DIRECTORY}/${FILENAME}.spv")
add_custom_command(
OUTPUT ${SHADER_BINARY}
COMMAND ${CMAKE_COMMAND} -E make_directory "${SHADER_OUTPUT_DIRECTORY}"
COMMAND ${GLSLANG} -V ${SHADER_SOURCE} -o ${SHADER_BINARY}
DEPENDS ${SHADER_SOURCE}
)
list(APPEND SHADER_BINARIES ${SHADER_BINARY})
endforeach(SHADER_SOURCE)
add_custom_target(
Shaders
DEPENDS ${SHADER_BINARIES}
)
add_dependencies(NothinFancy Shaders)

View File

@ -0,0 +1,9 @@
#version 450
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
}

View File

@ -0,0 +1,20 @@
#version 450
vec2 trianglePositions[3] = vec2[] (
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
vec3 triangleColors[3] = vec3[] (
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
);
layout(location = 0) out vec3 fragColor;
void main() {
fragColor = triangleColors[gl_VertexIndex];
gl_Position = vec4(trianglePositions[gl_VertexIndex], 0.0, 1.0);
}

View File

@ -26,11 +26,12 @@ namespace nf::client::render {
m_window->setDisplay(m_display);
createInstance();
createSurface(m_window->getHandle());
createSurface();
pickPhysicalDevice();
createDevice();
createSwapchain();
createRenderPass();
createOutputRenderPass();
createOutputPipeline();
m_window->show();
}
@ -51,15 +52,15 @@ namespace nf::client::render {
instanceCI.enabledExtensionCount = instanceExtNames.size();
if (vkCreateInstance(&instanceCI, nullptr, &m_instance) != VK_SUCCESS)
NFError("Could not create Vulkan instance");
NFError("Could not create Vulkan instance.");
}
void RenderEngine::createSurface(HWND window) {
void RenderEngine::createSurface() {
VkWin32SurfaceCreateInfoKHR surfaceCI = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
surfaceCI.hwnd = window;
surfaceCI.hwnd = m_window->getHandle();
if (vkCreateWin32SurfaceKHR(m_instance, &surfaceCI, nullptr, &m_surface) != VK_SUCCESS)
NFError("Could not create Vulkan surface");
NFError("Could not create Vulkan surface.");
}
void RenderEngine::pickPhysicalDevice() {
@ -68,7 +69,7 @@ namespace nf::client::render {
uint32_t numPhysicalDevices = 0;
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, nullptr);
if (numPhysicalDevices == 0)
NFError("No Vulkan GPUs found");
NFError("No Vulkan GPUs found.");
std::vector<VkPhysicalDevice> physicalDevices(numPhysicalDevices);
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, physicalDevices.data());
@ -136,7 +137,7 @@ namespace nf::client::render {
}
if (m_physicalDevice == nullptr)
NFError("No Vulkan GPUs were found to be compatible");
NFError("No Vulkan GPUs were found to be compatible.");
}
void RenderEngine::createDevice() {
@ -164,7 +165,7 @@ namespace nf::client::render {
deviceCI.ppEnabledExtensionNames = &swapChainExtName;
if (vkCreateDevice(m_physicalDevice, &deviceCI, nullptr, &m_device) != VK_SUCCESS)
NFError("Could not create Vulkan device");
NFError("Could not create Vulkan device.");
vkGetDeviceQueue(m_device, m_queueFIGraphics, 0, &m_queueGraphics);
vkGetDeviceQueue(m_device, m_queueFIPresent, 0, &m_queuePresent);
@ -177,7 +178,7 @@ namespace nf::client::render {
uint32_t numSurfaceFormats = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, nullptr);
if (numSurfaceFormats == 0)
NFError("No Vulkan surface formats found");
NFError("No Vulkan surface formats found.");
std::vector<VkSurfaceFormatKHR> surfaceFormats(numSurfaceFormats);
vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.data());
@ -189,7 +190,7 @@ namespace nf::client::render {
uint32_t numPresentModes = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, nullptr);
if (numPresentModes == 0)
NFError("No Vulkan surface present modes found");
NFError("No Vulkan surface present modes found.");
std::vector<VkPresentModeKHR> presentModes(numPresentModes);
vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, presentModes.data());
@ -228,7 +229,7 @@ namespace nf::client::render {
swapchainCI.oldSwapchain = VK_NULL_HANDLE;
if (vkCreateSwapchainKHR(m_device, &swapchainCI, nullptr, &m_swapchain) != VK_SUCCESS)
NFError("Could not create Vulkan swapchain");
NFError("Could not create Vulkan swapchain.");
uint32_t numSwapchainImages = 0;
vkGetSwapchainImagesKHR(m_device, m_swapchain, &numSwapchainImages, nullptr);
@ -246,11 +247,11 @@ namespace nf::client::render {
imageViewCI.subresourceRange.layerCount = 1;
if (vkCreateImageView(m_device, &imageViewCI, nullptr, &m_swapchainImageViews[i]) != VK_SUCCESS)
NFError("Could not create Vulkan swapchain image view");
NFError("Could not create Vulkan swapchain image view.");
}
}
void RenderEngine::createRenderPass() {
void RenderEngine::createOutputRenderPass() {
VkAttachmentDescription outputColorAttachment = {};
outputColorAttachment.format = m_swapchainImageFormat;
outputColorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
@ -277,7 +278,29 @@ namespace nf::client::render {
renderPassCI.pSubpasses = &subpassDescription;
if (vkCreateRenderPass(m_device, &renderPassCI, nullptr, &m_renderPassOutput) != VK_SUCCESS)
NFError("Could not create Vulkan render pass");
NFError("Could not create Vulkan output render pass.");
}
void RenderEngine::createOutputPipeline() {
// First, create shader modules
std::string outputShaderVertex, outputShaderFragment;
if (!util::readFile("shaders/output.vert.glsl.spv", outputShaderVertex) || !util::readFile("shaders/output.frag.glsl.spv", outputShaderFragment))
NFError("Could not read output shader binaries.");
VkShaderModule outputShaderVertexModule = VK_NULL_HANDLE, outputShaderFragmentModule = VK_NULL_HANDLE;
VkShaderModuleCreateInfo outputShaderModulesCI = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };
outputShaderModulesCI.codeSize = outputShaderVertex.size();
outputShaderModulesCI.pCode = reinterpret_cast<uint32_t*>(outputShaderVertex.data());
vkCreateShaderModule(m_device, &outputShaderModulesCI, nullptr, &outputShaderVertexModule);
outputShaderModulesCI.codeSize = outputShaderFragment.size();
outputShaderModulesCI.pCode = reinterpret_cast<uint32_t*>(outputShaderFragment.data());
vkCreateShaderModule(m_device, &outputShaderModulesCI, nullptr, &outputShaderFragmentModule);
if (!outputShaderVertexModule || !outputShaderFragmentModule)
NFError("Could not create output shader modules.");
// And cleanup shader modules
vkDestroyShaderModule(m_device, outputShaderVertexModule, nullptr);
vkDestroyShaderModule(m_device, outputShaderFragmentModule, nullptr);
}
RenderEngine::~RenderEngine() {

View File

@ -12,11 +12,12 @@ namespace nf::client::render {
~RenderEngine();
private:
void createInstance();
void createSurface(HWND window);
void createSurface();
void pickPhysicalDevice();
void createDevice();
void createSwapchain();
void createRenderPass();
void createOutputRenderPass();
void createOutputPipeline();
std::shared_ptr<Window> m_window;
DisplayConfig m_display;

View File

@ -15,3 +15,9 @@ endif()
# Link to NF library
target_link_libraries(TestGame NothinFancy)
target_include_directories(TestGame PUBLIC "${CMAKE_SOURCE_DIR}/NothinFancy/src/include")
# Copy shaders to executable directory
add_custom_command(TARGET TestGame POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/TestGame/shaders"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_BINARY_DIR}/NothinFancy/shaders" "${PROJECT_BINARY_DIR}/TestGame/shaders"
)