Create shader modules for output pipeline
This commit is contained in:
parent
f5a06e6ac1
commit
bfacea2bd4
@ -19,3 +19,26 @@ find_package(Git)
|
|||||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe OUTPUT_VARIABLE NFVERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND ${GIT_EXECUTABLE} describe OUTPUT_VARIABLE NFVERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
configure_file(src/version.h.in version.h)
|
configure_file(src/version.h.in version.h)
|
||||||
target_include_directories(NothinFancy PUBLIC "${PROJECT_BINARY_DIR}/NothinFancy")
|
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)
|
||||||
|
9
NothinFancy/res/shaders/output.frag.glsl
Normal file
9
NothinFancy/res/shaders/output.frag.glsl
Normal 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);
|
||||||
|
}
|
20
NothinFancy/res/shaders/output.vert.glsl
Normal file
20
NothinFancy/res/shaders/output.vert.glsl
Normal 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);
|
||||||
|
}
|
@ -26,11 +26,12 @@ namespace nf::client::render {
|
|||||||
m_window->setDisplay(m_display);
|
m_window->setDisplay(m_display);
|
||||||
|
|
||||||
createInstance();
|
createInstance();
|
||||||
createSurface(m_window->getHandle());
|
createSurface();
|
||||||
pickPhysicalDevice();
|
pickPhysicalDevice();
|
||||||
createDevice();
|
createDevice();
|
||||||
createSwapchain();
|
createSwapchain();
|
||||||
createRenderPass();
|
createOutputRenderPass();
|
||||||
|
createOutputPipeline();
|
||||||
|
|
||||||
m_window->show();
|
m_window->show();
|
||||||
}
|
}
|
||||||
@ -51,15 +52,15 @@ namespace nf::client::render {
|
|||||||
instanceCI.enabledExtensionCount = instanceExtNames.size();
|
instanceCI.enabledExtensionCount = instanceExtNames.size();
|
||||||
|
|
||||||
if (vkCreateInstance(&instanceCI, nullptr, &m_instance) != VK_SUCCESS)
|
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 };
|
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)
|
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() {
|
void RenderEngine::pickPhysicalDevice() {
|
||||||
@ -68,7 +69,7 @@ namespace nf::client::render {
|
|||||||
uint32_t numPhysicalDevices = 0;
|
uint32_t numPhysicalDevices = 0;
|
||||||
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, nullptr);
|
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, nullptr);
|
||||||
if (numPhysicalDevices == 0)
|
if (numPhysicalDevices == 0)
|
||||||
NFError("No Vulkan GPUs found");
|
NFError("No Vulkan GPUs found.");
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> physicalDevices(numPhysicalDevices);
|
std::vector<VkPhysicalDevice> physicalDevices(numPhysicalDevices);
|
||||||
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, physicalDevices.data());
|
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, physicalDevices.data());
|
||||||
@ -136,7 +137,7 @@ namespace nf::client::render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_physicalDevice == nullptr)
|
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() {
|
void RenderEngine::createDevice() {
|
||||||
@ -164,7 +165,7 @@ namespace nf::client::render {
|
|||||||
deviceCI.ppEnabledExtensionNames = &swapChainExtName;
|
deviceCI.ppEnabledExtensionNames = &swapChainExtName;
|
||||||
|
|
||||||
if (vkCreateDevice(m_physicalDevice, &deviceCI, nullptr, &m_device) != VK_SUCCESS)
|
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_queueFIGraphics, 0, &m_queueGraphics);
|
||||||
vkGetDeviceQueue(m_device, m_queueFIPresent, 0, &m_queuePresent);
|
vkGetDeviceQueue(m_device, m_queueFIPresent, 0, &m_queuePresent);
|
||||||
@ -177,7 +178,7 @@ namespace nf::client::render {
|
|||||||
uint32_t numSurfaceFormats = 0;
|
uint32_t numSurfaceFormats = 0;
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, nullptr);
|
vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, nullptr);
|
||||||
if (numSurfaceFormats == 0)
|
if (numSurfaceFormats == 0)
|
||||||
NFError("No Vulkan surface formats found");
|
NFError("No Vulkan surface formats found.");
|
||||||
|
|
||||||
std::vector<VkSurfaceFormatKHR> surfaceFormats(numSurfaceFormats);
|
std::vector<VkSurfaceFormatKHR> surfaceFormats(numSurfaceFormats);
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.data());
|
vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.data());
|
||||||
@ -189,7 +190,7 @@ namespace nf::client::render {
|
|||||||
uint32_t numPresentModes = 0;
|
uint32_t numPresentModes = 0;
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, nullptr);
|
vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, nullptr);
|
||||||
if (numPresentModes == 0)
|
if (numPresentModes == 0)
|
||||||
NFError("No Vulkan surface present modes found");
|
NFError("No Vulkan surface present modes found.");
|
||||||
|
|
||||||
std::vector<VkPresentModeKHR> presentModes(numPresentModes);
|
std::vector<VkPresentModeKHR> presentModes(numPresentModes);
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, presentModes.data());
|
vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, presentModes.data());
|
||||||
@ -228,7 +229,7 @@ namespace nf::client::render {
|
|||||||
swapchainCI.oldSwapchain = VK_NULL_HANDLE;
|
swapchainCI.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
if (vkCreateSwapchainKHR(m_device, &swapchainCI, nullptr, &m_swapchain) != VK_SUCCESS)
|
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;
|
uint32_t numSwapchainImages = 0;
|
||||||
vkGetSwapchainImagesKHR(m_device, m_swapchain, &numSwapchainImages, nullptr);
|
vkGetSwapchainImagesKHR(m_device, m_swapchain, &numSwapchainImages, nullptr);
|
||||||
@ -246,11 +247,11 @@ namespace nf::client::render {
|
|||||||
imageViewCI.subresourceRange.layerCount = 1;
|
imageViewCI.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
if (vkCreateImageView(m_device, &imageViewCI, nullptr, &m_swapchainImageViews[i]) != VK_SUCCESS)
|
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 = {};
|
VkAttachmentDescription outputColorAttachment = {};
|
||||||
outputColorAttachment.format = m_swapchainImageFormat;
|
outputColorAttachment.format = m_swapchainImageFormat;
|
||||||
outputColorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
outputColorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
@ -277,7 +278,29 @@ namespace nf::client::render {
|
|||||||
renderPassCI.pSubpasses = &subpassDescription;
|
renderPassCI.pSubpasses = &subpassDescription;
|
||||||
|
|
||||||
if (vkCreateRenderPass(m_device, &renderPassCI, nullptr, &m_renderPassOutput) != VK_SUCCESS)
|
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() {
|
RenderEngine::~RenderEngine() {
|
||||||
|
@ -12,11 +12,12 @@ namespace nf::client::render {
|
|||||||
~RenderEngine();
|
~RenderEngine();
|
||||||
private:
|
private:
|
||||||
void createInstance();
|
void createInstance();
|
||||||
void createSurface(HWND window);
|
void createSurface();
|
||||||
void pickPhysicalDevice();
|
void pickPhysicalDevice();
|
||||||
void createDevice();
|
void createDevice();
|
||||||
void createSwapchain();
|
void createSwapchain();
|
||||||
void createRenderPass();
|
void createOutputRenderPass();
|
||||||
|
void createOutputPipeline();
|
||||||
|
|
||||||
std::shared_ptr<Window> m_window;
|
std::shared_ptr<Window> m_window;
|
||||||
DisplayConfig m_display;
|
DisplayConfig m_display;
|
||||||
|
@ -15,3 +15,9 @@ endif()
|
|||||||
# Link to NF library
|
# Link to NF library
|
||||||
target_link_libraries(TestGame NothinFancy)
|
target_link_libraries(TestGame NothinFancy)
|
||||||
target_include_directories(TestGame PUBLIC "${CMAKE_SOURCE_DIR}/NothinFancy/src/include")
|
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"
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user