Add SMAA pass
This commit is contained in:
parent
5b035874ab
commit
57a2ae9c0a
17 changed files with 17394 additions and 10 deletions
1
3rdparty/CMakeLists.txt
vendored
1
3rdparty/CMakeLists.txt
vendored
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(imgui)
|
||||
add_subdirectory(nlohmann)
|
||||
add_subdirectory(stb)
|
||||
add_subdirectory(smaa)
|
||||
|
|
4
3rdparty/smaa/CMakeLists.txt
vendored
Executable file
4
3rdparty/smaa/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,4 @@
|
|||
add_library(SMAA INTERFACE)
|
||||
target_include_directories(SMAA INTERFACE include)
|
||||
|
||||
add_library(SMAA::SMAA ALIAS SMAA)
|
14980
3rdparty/smaa/include/AreaTex.h
vendored
Executable file
14980
3rdparty/smaa/include/AreaTex.h
vendored
Executable file
File diff suppressed because it is too large
Load diff
132
3rdparty/smaa/include/SearchTex.h
vendored
Executable file
132
3rdparty/smaa/include/SearchTex.h
vendored
Executable file
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com)
|
||||
* Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com)
|
||||
* Copyright (C) 2013 Belen Masia (bmasia@unizar.es)
|
||||
* Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com)
|
||||
* Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to
|
||||
* do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software. As clarification, there
|
||||
* is no requirement that the copyright notice and permission be included in
|
||||
* binary distributions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SEARCHTEX_H
|
||||
#define SEARCHTEX_H
|
||||
|
||||
#define SEARCHTEX_WIDTH 64
|
||||
#define SEARCHTEX_HEIGHT 16
|
||||
#define SEARCHTEX_PITCH SEARCHTEX_WIDTH
|
||||
#define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
|
||||
|
||||
/**
|
||||
* Stored in R8 format. Load it in the following format:
|
||||
* - DX9: D3DFMT_L8
|
||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||
*/
|
||||
static const unsigned char searchTexBytes[] = {
|
||||
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
|
||||
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
|
||||
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -57,7 +57,8 @@ set(GRAPH_SRC
|
|||
src/animationsystem.cpp
|
||||
src/worldmanager.cpp
|
||||
src/assetmanager.cpp
|
||||
src/entityparser.cpp)
|
||||
src/entityparser.cpp
|
||||
src/smaapass.cpp)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(GRAPH_SRC
|
||||
|
@ -77,7 +78,8 @@ target_link_libraries(Graph
|
|||
Vulkan::Vulkan
|
||||
assimp::assimp
|
||||
nlohmann::json
|
||||
stb::stb)
|
||||
stb::stb
|
||||
SMAA::SMAA)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_link_libraries(Graph
|
||||
|
@ -102,7 +104,11 @@ add_shaders(Graph
|
|||
shaders/imgui.frag
|
||||
shaders/sky.vert
|
||||
shaders/sky.frag
|
||||
shaders/shadow.vert)
|
||||
shaders/shadow.vert
|
||||
shaders/edge.vert
|
||||
shaders/edge.frag
|
||||
shaders/blend.vert
|
||||
shaders/blend.frag)
|
||||
|
||||
add_data(Graph
|
||||
data/suzanne.obj
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "imguipass.h"
|
||||
#include "skypass.h"
|
||||
#include "shadowpass.h"
|
||||
#include "smaapass.h"
|
||||
|
||||
constexpr int numFrameResources = 2;
|
||||
|
||||
|
@ -55,6 +56,19 @@ struct RenderTarget {
|
|||
VkSemaphore renderFinishedSemaphore = nullptr;
|
||||
VkFence* fences = nullptr;
|
||||
|
||||
// smaa
|
||||
VkImage* edgeImages = nullptr;
|
||||
VkDeviceMemory* edgeMemorys = nullptr;
|
||||
VkImageView* edgeImageViews = nullptr;
|
||||
VkFramebuffer* edgeFramebuffers = nullptr;
|
||||
VkDescriptorSet* edgeDescriptorSets = nullptr;
|
||||
|
||||
VkImage* blendImages = nullptr;
|
||||
VkDeviceMemory* blendMemorys = nullptr;
|
||||
VkImageView* blendImageViews = nullptr;
|
||||
VkFramebuffer* blendFramebuffers = nullptr;
|
||||
VkDescriptorSet* blendDescriptorSets = nullptr;
|
||||
|
||||
// imgui
|
||||
VkBuffer* imguiVertexBuffers = nullptr;
|
||||
VkDeviceMemory* imguiVertexMemorys = nullptr;
|
||||
|
@ -92,7 +106,7 @@ public:
|
|||
|
||||
VkShaderModule createShader(const char* path);
|
||||
|
||||
void uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src);
|
||||
void uploadImageData(VkImage image, int width, int height, VkDeviceSize size, const void* src);
|
||||
|
||||
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
||||
|
||||
|
@ -193,4 +207,5 @@ private:
|
|||
#endif
|
||||
SkyPass* skyPass_ = nullptr;
|
||||
ShadowPass* shadowPass_ = nullptr;
|
||||
SMAAPass* smaaPass_ = nullptr;
|
||||
};
|
||||
|
|
59
include/smaapass.h
Normal file
59
include/smaapass.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
class Renderer;
|
||||
struct RenderTarget;
|
||||
|
||||
class SMAAPass {
|
||||
public:
|
||||
SMAAPass(Renderer& renderer);
|
||||
~SMAAPass();
|
||||
|
||||
void render(VkCommandBuffer commandBuffer, RenderTarget* target);
|
||||
|
||||
void createDescriptorSets(RenderTarget* target);
|
||||
|
||||
VkRenderPass getEdgeRenderPass() const {
|
||||
return edgeRenderPass;
|
||||
}
|
||||
|
||||
VkRenderPass getBlendRenderPass() const {
|
||||
return blendRenderPass;
|
||||
}
|
||||
|
||||
private:
|
||||
void loadResources();
|
||||
|
||||
void setupDescriptorLayouts();
|
||||
void createOffscreenResources();
|
||||
void createRenderPasses();
|
||||
void createPipelines();
|
||||
|
||||
VkImage areaImage;
|
||||
VkDeviceMemory areaMemory;
|
||||
VkImageView areaImageView;
|
||||
VkSampler areaSampler;
|
||||
|
||||
VkImage searchImage;
|
||||
VkDeviceMemory searchMemory;
|
||||
VkImageView searchImageView;
|
||||
VkSampler searchSampler;
|
||||
|
||||
VkSampler edgeSampler;
|
||||
VkSampler blendSampler;
|
||||
|
||||
VkRenderPass edgeRenderPass, blendRenderPass;
|
||||
|
||||
// edge
|
||||
VkDescriptorSetLayout edgeDescriptorSetLayout;
|
||||
VkPipelineLayout edgePipelineLayout;
|
||||
VkPipeline edgePipeline;
|
||||
|
||||
// blend
|
||||
VkDescriptorSetLayout blendDescriptorSetLayout;
|
||||
VkPipelineLayout blendPipelineLayout;
|
||||
VkPipeline blendPipeline;
|
||||
|
||||
Renderer& renderer;
|
||||
};
|
27
shaders/blend.frag
Executable file
27
shaders/blend.frag
Executable file
|
@ -0,0 +1,27 @@
|
|||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||
|
||||
#define SMAA_PRESET_ULTRA 1
|
||||
#define SMAA_GLSL_4 1
|
||||
#define SMAA_INCLUDE_VS 0
|
||||
#define SMAA_INCLUDE_PS 1
|
||||
#define SMAA_PREDICATION 1
|
||||
#define SMAA_FLIP_Y 0
|
||||
|
||||
#include "smaa.glsl"
|
||||
|
||||
layout(location = 0) in vec2 inUV;
|
||||
layout(location = 1) in vec4 inOffset[3];
|
||||
layout(location = 5) in vec2 inPixUV;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(binding = 0) uniform sampler2D edgeSampler;
|
||||
layout(binding = 1) uniform sampler2D areaSampler;
|
||||
layout(binding = 2) uniform sampler2D searchSampler;
|
||||
|
||||
void main() {
|
||||
outColor = SMAABlendingWeightCalculationPS(inUV, inPixUV, inOffset, edgeSampler, areaSampler, searchSampler, ivec4(0));
|
||||
}
|
24
shaders/blend.vert
Executable file
24
shaders/blend.vert
Executable file
|
@ -0,0 +1,24 @@
|
|||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||
|
||||
#define SMAA_PRESET_ULTRA 1
|
||||
#define SMAA_GLSL_4 1
|
||||
#define SMAA_INCLUDE_VS 1
|
||||
#define SMAA_INCLUDE_PS 0
|
||||
#define SMAA_PREDICATION 1
|
||||
#define SMAA_FLIP_Y 0
|
||||
|
||||
#include "smaa.glsl"
|
||||
|
||||
layout(location = 0) out vec2 outUV;
|
||||
layout(location = 1) out vec4 outOffset[3];
|
||||
layout(location = 5) out vec2 outPixUV;
|
||||
|
||||
void main() {
|
||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
||||
|
||||
SMAABlendingWeightCalculationVS(outUV, outPixUV, outOffset);
|
||||
}
|
27
shaders/edge.frag
Executable file
27
shaders/edge.frag
Executable file
|
@ -0,0 +1,27 @@
|
|||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||
|
||||
#define SMAA_PRESET_ULTRA 1
|
||||
#define SMAA_GLSL_4 1
|
||||
#define SMAA_INCLUDE_VS 0
|
||||
#define SMAA_INCLUDE_PS 1
|
||||
#define SMAA_PREDICATION 1
|
||||
#define SMAA_FLIP_Y 0
|
||||
|
||||
#include "smaa.glsl"
|
||||
|
||||
layout(location = 0) in vec2 inUV;
|
||||
layout(location = 1) in vec4 inOffset[3];
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(binding = 0) uniform sampler2D imageSampler;
|
||||
layout(binding = 1) uniform sampler2D depthSampler;
|
||||
|
||||
void main() {
|
||||
vec2 edge = SMAALumaEdgeDetectionPS(inUV, inOffset, imageSampler, depthSampler);
|
||||
|
||||
outColor = vec4(edge, 0.0, 1.0);
|
||||
}
|
23
shaders/edge.vert
Executable file
23
shaders/edge.vert
Executable file
|
@ -0,0 +1,23 @@
|
|||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||
|
||||
#define SMAA_PRESET_ULTRA 1
|
||||
#define SMAA_GLSL_4 1
|
||||
#define SMAA_INCLUDE_VS 1
|
||||
#define SMAA_INCLUDE_PS 0
|
||||
#define SMAA_PREDICATION 1
|
||||
#define SMAA_FLIP_Y 0
|
||||
|
||||
#include "smaa.glsl"
|
||||
|
||||
layout(location = 0) out vec2 outUV;
|
||||
layout(location = 1) out vec4 outOffset[3];
|
||||
|
||||
void main() {
|
||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
||||
|
||||
SMAAEdgeDetectionVS(outUV, outOffset);
|
||||
}
|
|
@ -1,6 +1,19 @@
|
|||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||
|
||||
#define SMAA_PRESET_ULTRA 1
|
||||
#define SMAA_GLSL_4 1
|
||||
#define SMAA_INCLUDE_VS 0
|
||||
#define SMAA_INCLUDE_PS 1
|
||||
#define SMAA_PREDICATION 1
|
||||
#define SMAA_FLIP_Y 0
|
||||
|
||||
#include "smaa.glsl"
|
||||
|
||||
layout(location = 0) in vec2 inUV;
|
||||
layout(location = 1) in vec4 inOffset;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
|
@ -8,9 +21,11 @@ layout(binding = 0) uniform sampler2D sceneSampler;
|
|||
layout(binding = 1) uniform sampler2D depthSampler;
|
||||
layout(binding = 2) uniform sampler2D nearFieldSampler;
|
||||
layout(binding = 3) uniform sampler2D farFieldSampler;
|
||||
layout(binding = 4) uniform sampler2D blendSampler;
|
||||
|
||||
void main() {
|
||||
vec3 sceneColor = texture(sceneSampler, inUV).rgb;
|
||||
vec3 sceneColor = vec3(0);
|
||||
sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, sceneSampler, blendSampler).rgb;
|
||||
|
||||
// alpha divide reconstruction
|
||||
vec3 farColor = texture(farFieldSampler, inUV).rgb / max(texture(farFieldSampler, inUV).a, 0.0001) * 0.02;
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||
|
||||
#define SMAA_PRESET_ULTRA 1
|
||||
#define SMAA_GLSL_4 1
|
||||
#define SMAA_INCLUDE_VS 1
|
||||
#define SMAA_INCLUDE_PS 0
|
||||
#define SMAA_PREDICATION 1
|
||||
#define SMAA_FLIP_Y 0
|
||||
|
||||
#include "smaa.glsl"
|
||||
|
||||
layout(location = 0) out vec2 outUV;
|
||||
layout(location = 1) out vec4 outOffset;
|
||||
|
||||
void main() {
|
||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
||||
|
||||
SMAANeighborhoodBlendingVS(outUV, outOffset);
|
||||
}
|
||||
|
||||
|
|
1407
shaders/smaa.glsl
Executable file
1407
shaders/smaa.glsl
Executable file
File diff suppressed because it is too large
Load diff
|
@ -64,6 +64,11 @@ void PostPass::createDescriptorSet(RenderTarget* target) {
|
|||
farFieldImageInfo.imageView = target->farFieldImageViews[i];
|
||||
farFieldImageInfo.sampler = offscreenSampler_;
|
||||
|
||||
VkDescriptorImageInfo blendImageInfo = {};
|
||||
blendImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
blendImageInfo.imageView = target->blendImageViews[i];
|
||||
blendImageInfo.sampler = offscreenSampler_;
|
||||
|
||||
VkWriteDescriptorSet sceneDescriptorWrite = {};
|
||||
sceneDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
sceneDescriptorWrite.descriptorCount = 1;
|
||||
|
@ -95,11 +100,20 @@ void PostPass::createDescriptorSet(RenderTarget* target) {
|
|||
farFieldDescriptorWrite.dstSet = target->postSets[i];
|
||||
farFieldDescriptorWrite.pImageInfo = &farFieldImageInfo;
|
||||
|
||||
const std::array<VkWriteDescriptorSet, 4> descriptorWrites = {
|
||||
VkWriteDescriptorSet blendDescriptorWrite = {};
|
||||
blendDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
blendDescriptorWrite.descriptorCount = 1;
|
||||
blendDescriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
blendDescriptorWrite.dstBinding = 4;
|
||||
blendDescriptorWrite.dstSet = target->postSets[i];
|
||||
blendDescriptorWrite.pImageInfo = &blendImageInfo;
|
||||
|
||||
const std::array<VkWriteDescriptorSet, 5> descriptorWrites = {
|
||||
sceneDescriptorWrite,
|
||||
depthDescriptorWrite,
|
||||
nearFieldDescriptorWrite,
|
||||
farFieldDescriptorWrite
|
||||
farFieldDescriptorWrite,
|
||||
blendDescriptorWrite
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(renderer_.getDevice(), descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
|
||||
|
@ -130,11 +144,18 @@ void PostPass::createDescriptorSetLayout() {
|
|||
farFieldSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
farFieldSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
const std::array<VkDescriptorSetLayoutBinding, 4> bindings = {
|
||||
VkDescriptorSetLayoutBinding blendSamplerBinding = {};
|
||||
blendSamplerBinding.binding = 4;
|
||||
blendSamplerBinding.descriptorCount = 1;
|
||||
blendSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
blendSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
const std::array<VkDescriptorSetLayoutBinding, 5> bindings = {
|
||||
offscreenSamplerBinding,
|
||||
depthSamplerBinding,
|
||||
nearFieldSamplerBinding,
|
||||
farFieldSamplerBinding
|
||||
farFieldSamplerBinding,
|
||||
blendSamplerBinding
|
||||
};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo createInfo = {};
|
||||
|
|
131
src/renderer.cpp
131
src/renderer.cpp
|
@ -36,11 +36,13 @@ Renderer::Renderer(GraphicsConfig config) : config_(config) {
|
|||
imguiPass_ = new ImGuiPass(*this);
|
||||
#endif
|
||||
skyPass_ = new SkyPass(*this);
|
||||
smaaPass_ = new SMAAPass(*this);
|
||||
}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
vkDeviceWaitIdle(device_);
|
||||
|
||||
delete smaaPass_;
|
||||
delete skyPass_;
|
||||
#ifdef DEBUG
|
||||
delete imguiPass_;
|
||||
|
@ -150,6 +152,8 @@ void Renderer::render(World& world, RenderTarget* target) {
|
|||
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||
|
||||
smaaPass_->render(commandBuffer, target);
|
||||
|
||||
clearColor = {};
|
||||
|
||||
renderPassBeginInfo = {};
|
||||
|
@ -304,6 +308,16 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
|||
target->farFieldMemory = new VkDeviceMemory[numFrameResources];
|
||||
target->farFieldImageViews = new VkImageView[numFrameResources];
|
||||
target->farFieldFramebuffers = new VkFramebuffer[numFrameResources];
|
||||
target->edgeImages = new VkImage[numFrameResources];
|
||||
target->edgeMemorys = new VkDeviceMemory[numFrameResources];
|
||||
target->edgeImageViews = new VkImageView[numFrameResources];
|
||||
target->edgeFramebuffers = new VkFramebuffer[numFrameResources];
|
||||
target->edgeDescriptorSets = new VkDescriptorSet[numFrameResources];
|
||||
target->blendImages = new VkImage[numFrameResources];
|
||||
target->blendMemorys = new VkDeviceMemory[numFrameResources];
|
||||
target->blendImageViews = new VkImageView[numFrameResources];
|
||||
target->blendFramebuffers = new VkFramebuffer[numFrameResources];
|
||||
target->blendDescriptorSets = new VkDescriptorSet[numFrameResources];
|
||||
target->imguiVertexBuffers = new VkBuffer[numFrameResources];
|
||||
target->imguiVertexMemorys = new VkDeviceMemory[numFrameResources];
|
||||
target->imguiVertexBufferSizes = new size_t[numFrameResources];
|
||||
|
@ -530,6 +544,120 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
|||
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->farFieldFramebuffers[i]);
|
||||
}
|
||||
|
||||
// edge image
|
||||
{
|
||||
VkImageCreateInfo imageCreateInfo = {};
|
||||
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
imageCreateInfo.extent.width = target->extent.width;
|
||||
imageCreateInfo.extent.height = target->extent.height;
|
||||
imageCreateInfo.extent.depth = 1;
|
||||
imageCreateInfo.mipLevels = 1;
|
||||
imageCreateInfo.arrayLayers = 1;
|
||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->edgeImages[i]);
|
||||
|
||||
VkMemoryRequirements memoryRequirements = {};
|
||||
vkGetImageMemoryRequirements(device_, target->edgeImages[i], &memoryRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocateInfo = {};
|
||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocateInfo.allocationSize = memoryRequirements.size;
|
||||
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->edgeMemorys[i]);
|
||||
vkBindImageMemory(device_, target->edgeImages[i], target->edgeMemorys[i], 0);
|
||||
}
|
||||
|
||||
// edge image view
|
||||
{
|
||||
VkImageViewCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
createInfo.image = target->edgeImages[i];
|
||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
createInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
createInfo.subresourceRange.levelCount = 1;
|
||||
createInfo.subresourceRange.layerCount = 1;
|
||||
|
||||
vkCreateImageView(device_, &createInfo, nullptr, &target->edgeImageViews[i]);
|
||||
}
|
||||
|
||||
// edge framebuffer
|
||||
{
|
||||
VkFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferInfo.renderPass = smaaPass_->getEdgeRenderPass();
|
||||
framebufferInfo.attachmentCount = 1;
|
||||
framebufferInfo.pAttachments = &target->edgeImageViews[i];
|
||||
framebufferInfo.width = target->extent.width;
|
||||
framebufferInfo.height = target->extent.height;
|
||||
framebufferInfo.layers = 1;
|
||||
|
||||
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->edgeFramebuffers[i]);
|
||||
}
|
||||
|
||||
// blend image
|
||||
{
|
||||
VkImageCreateInfo imageCreateInfo = {};
|
||||
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
imageCreateInfo.extent.width = target->extent.width;
|
||||
imageCreateInfo.extent.height = target->extent.height;
|
||||
imageCreateInfo.extent.depth = 1;
|
||||
imageCreateInfo.mipLevels = 1;
|
||||
imageCreateInfo.arrayLayers = 1;
|
||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->blendImages[i]);
|
||||
|
||||
VkMemoryRequirements memoryRequirements = {};
|
||||
vkGetImageMemoryRequirements(device_, target->blendImages[i], &memoryRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocateInfo = {};
|
||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocateInfo.allocationSize = memoryRequirements.size;
|
||||
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->blendMemorys[i]);
|
||||
vkBindImageMemory(device_, target->blendImages[i], target->blendMemorys[i], 0);
|
||||
}
|
||||
|
||||
// blend image view
|
||||
{
|
||||
VkImageViewCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
createInfo.image = target->blendImages[i];
|
||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
createInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
createInfo.subresourceRange.levelCount = 1;
|
||||
createInfo.subresourceRange.layerCount = 1;
|
||||
|
||||
vkCreateImageView(device_, &createInfo, nullptr, &target->blendImageViews[i]);
|
||||
}
|
||||
|
||||
// blend framebuffer
|
||||
{
|
||||
VkFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferInfo.renderPass = smaaPass_->getBlendRenderPass();
|
||||
framebufferInfo.attachmentCount = 1;
|
||||
framebufferInfo.pAttachments = &target->blendImageViews[i];
|
||||
framebufferInfo.width = target->extent.width;
|
||||
framebufferInfo.height = target->extent.height;
|
||||
framebufferInfo.layers = 1;
|
||||
|
||||
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->blendFramebuffers[i]);
|
||||
}
|
||||
|
||||
// imgui
|
||||
{
|
||||
target->imguiVertexBuffers[i] = nullptr;
|
||||
|
@ -544,6 +672,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
|||
|
||||
postPass_->createDescriptorSet(target);
|
||||
dofPass_->createDescriptorSet(target);
|
||||
smaaPass_->createDescriptorSets(target);
|
||||
|
||||
VkCommandBufferAllocateInfo allocateInfo = {};
|
||||
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
|
@ -890,7 +1019,7 @@ VkShaderModule Renderer::createShader(const char* path) {
|
|||
return shaderModule;
|
||||
}
|
||||
|
||||
void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src) {
|
||||
void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, const void* src) {
|
||||
VkBuffer stagingBuffer;
|
||||
VkDeviceMemory stagingMemory;
|
||||
|
||||
|
|
499
src/smaapass.cpp
Normal file
499
src/smaapass.cpp
Normal file
|
@ -0,0 +1,499 @@
|
|||
#include "smaapass.h"
|
||||
|
||||
#include <AreaTex.h>
|
||||
#include <SearchTex.h>
|
||||
|
||||
#include "renderer.h"
|
||||
|
||||
SMAAPass::SMAAPass(Renderer& renderer) : renderer(renderer) {
|
||||
loadResources();
|
||||
|
||||
setupDescriptorLayouts();
|
||||
createOffscreenResources();
|
||||
createRenderPasses();
|
||||
createPipelines();
|
||||
}
|
||||
|
||||
SMAAPass::~SMAAPass() {
|
||||
vkDestroyPipeline(renderer.getDevice(), blendPipeline, nullptr);
|
||||
vkDestroyPipeline(renderer.getDevice(), edgePipeline, nullptr);
|
||||
|
||||
vkDestroyPipelineLayout(renderer.getDevice(), edgePipelineLayout, nullptr);
|
||||
vkDestroyPipelineLayout(renderer.getDevice(), blendPipelineLayout, nullptr);
|
||||
|
||||
vkDestroyRenderPass(renderer.getDevice(), edgeRenderPass, nullptr);
|
||||
vkDestroyRenderPass(renderer.getDevice(), blendRenderPass, nullptr);
|
||||
|
||||
vkDestroySampler(renderer.getDevice(), blendSampler, nullptr);
|
||||
vkDestroySampler(renderer.getDevice(), edgeSampler, nullptr);
|
||||
|
||||
vkDestroyDescriptorSetLayout(renderer.getDevice(), blendDescriptorSetLayout, nullptr);
|
||||
vkDestroyDescriptorSetLayout(renderer.getDevice(), edgeDescriptorSetLayout, nullptr);
|
||||
|
||||
vkDestroySampler(renderer.getDevice(), searchSampler, nullptr);
|
||||
vkDestroySampler(renderer.getDevice(), areaSampler, nullptr);
|
||||
|
||||
vkFreeMemory(renderer.getDevice(), searchMemory, nullptr);
|
||||
vkFreeMemory(renderer.getDevice(), areaMemory, nullptr);
|
||||
|
||||
vkDestroyImageView(renderer.getDevice(), searchImageView, nullptr);
|
||||
vkDestroyImageView(renderer.getDevice(), areaImageView, nullptr);
|
||||
|
||||
vkDestroyImage(renderer.getDevice(), searchImage, nullptr);
|
||||
vkDestroyImage(renderer.getDevice(), areaImage, nullptr);
|
||||
}
|
||||
|
||||
void SMAAPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) {
|
||||
vkCmdPipelineBarrier(commandBuffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_DEPENDENCY_BY_REGION_BIT,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr);
|
||||
|
||||
VkClearValue clearValue = {};
|
||||
clearValue.color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
VkRenderPassBeginInfo renderPassInfo = {};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassInfo.renderPass = edgeRenderPass;
|
||||
renderPassInfo.framebuffer = target->edgeFramebuffers[target->currentResource];
|
||||
renderPassInfo.renderArea.extent.width = 1280;
|
||||
renderPassInfo.renderArea.extent.height = 720;
|
||||
renderPassInfo.clearValueCount = 1;
|
||||
renderPassInfo.pClearValues = &clearValue;
|
||||
|
||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, edgePipeline);
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, edgePipelineLayout, 0, 1, &target->edgeDescriptorSets[target->currentResource],
|
||||
0, nullptr);
|
||||
|
||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(commandBuffer);
|
||||
|
||||
renderPassInfo.renderPass = blendRenderPass;
|
||||
renderPassInfo.framebuffer = target->blendFramebuffers[target->currentResource];
|
||||
|
||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
// TODO: add a pipeline barrier
|
||||
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, blendPipeline);
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, blendPipelineLayout, 0, 1,
|
||||
&target->blendDescriptorSets[target->currentResource], 0, nullptr);
|
||||
|
||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(commandBuffer);
|
||||
}
|
||||
|
||||
void SMAAPass::createDescriptorSets(RenderTarget* target) {
|
||||
// TODO: colmengate these
|
||||
VkDescriptorSetAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
allocInfo.descriptorPool = renderer.getDescriptorPool();
|
||||
allocInfo.descriptorSetCount = target->numImages;
|
||||
|
||||
// FIXME: lol what
|
||||
auto layouts = new VkDescriptorSetLayout[target->numImages];
|
||||
for(uint32_t i = 0; i < target->numImages; i++)
|
||||
layouts[i] = edgeDescriptorSetLayout;
|
||||
|
||||
allocInfo.pSetLayouts = layouts;
|
||||
|
||||
vkAllocateDescriptorSets(renderer.getDevice(), &allocInfo, target->edgeDescriptorSets);
|
||||
|
||||
for(uint32_t i = 0; i < target->numImages; i++)
|
||||
layouts[i] = blendDescriptorSetLayout;
|
||||
|
||||
vkAllocateDescriptorSets(renderer.getDevice(), &allocInfo, target->blendDescriptorSets);
|
||||
|
||||
for(int i = 0; i < target->numImages; i++) {
|
||||
// edge
|
||||
{
|
||||
VkDescriptorImageInfo imageInfo = {};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.imageView = target->offscreenColorImageViews[i];
|
||||
imageInfo.sampler = edgeSampler;
|
||||
|
||||
VkDescriptorImageInfo depthInfo = {};
|
||||
depthInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
depthInfo.imageView = target->offscreenDepthImageViews[i];
|
||||
depthInfo.sampler = edgeSampler;
|
||||
|
||||
VkWriteDescriptorSet descriptorWrites[2] = {};
|
||||
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrites[0].dstSet = target->edgeDescriptorSets[i];
|
||||
descriptorWrites[0].dstBinding = 0;
|
||||
descriptorWrites[0].dstArrayElement = 0;
|
||||
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptorWrites[0].descriptorCount = 1;
|
||||
descriptorWrites[0].pImageInfo = &imageInfo;
|
||||
|
||||
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrites[1].dstSet = target->edgeDescriptorSets[i];
|
||||
descriptorWrites[1].dstBinding = 1;
|
||||
descriptorWrites[1].dstArrayElement = 0;
|
||||
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptorWrites[1].descriptorCount = 1;
|
||||
descriptorWrites[1].pImageInfo = &depthInfo;
|
||||
|
||||
vkUpdateDescriptorSets(renderer.getDevice(), 2, descriptorWrites, 0, nullptr);
|
||||
}
|
||||
|
||||
// blend
|
||||
{
|
||||
VkDescriptorImageInfo edgeInfo = {};
|
||||
edgeInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
edgeInfo.imageView = target->edgeImageViews[i];
|
||||
edgeInfo.sampler = edgeSampler;
|
||||
|
||||
VkDescriptorImageInfo areaInfo = {};
|
||||
areaInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
areaInfo.imageView = areaImageView;
|
||||
areaInfo.sampler = areaSampler;
|
||||
|
||||
VkDescriptorImageInfo searchInfo = {};
|
||||
searchInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
searchInfo.imageView = searchImageView;
|
||||
searchInfo.sampler = searchSampler;
|
||||
|
||||
VkWriteDescriptorSet descriptorWrites[3] = {};
|
||||
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrites[0].dstSet = target->blendDescriptorSets[i];
|
||||
descriptorWrites[0].dstBinding = 0;
|
||||
descriptorWrites[0].dstArrayElement = 0;
|
||||
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptorWrites[0].descriptorCount = 1;
|
||||
descriptorWrites[0].pImageInfo = &edgeInfo;
|
||||
|
||||
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrites[1].dstSet = target->blendDescriptorSets[i];
|
||||
descriptorWrites[1].dstBinding = 1;
|
||||
descriptorWrites[1].dstArrayElement = 0;
|
||||
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptorWrites[1].descriptorCount = 1;
|
||||
descriptorWrites[1].pImageInfo = &areaInfo;
|
||||
|
||||
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrites[2].dstSet = target->blendDescriptorSets[i];
|
||||
descriptorWrites[2].dstBinding = 2;
|
||||
descriptorWrites[2].dstArrayElement = 0;
|
||||
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptorWrites[2].descriptorCount = 1;
|
||||
descriptorWrites[2].pImageInfo = &searchInfo;
|
||||
|
||||
vkUpdateDescriptorSets(renderer.getDevice(), 3, descriptorWrites, 0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SMAAPass::loadResources() {
|
||||
const auto loadResource = [this](const int size, const int width, const int height, const void* data, VkFormat format, VkImage& image, VkDeviceMemory& memory, VkImageView& view) {
|
||||
VkImageCreateInfo imageInfo = {};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.extent.width = width;
|
||||
imageInfo.extent.height = height;
|
||||
imageInfo.extent.depth = 1;
|
||||
imageInfo.mipLevels = 1;
|
||||
imageInfo.arrayLayers = 1;
|
||||
imageInfo.format = format;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
vkCreateImage(renderer.getDevice(), &imageInfo, nullptr, &image);
|
||||
|
||||
VkMemoryRequirements memRequirements = {};
|
||||
vkGetImageMemoryRequirements(renderer.getDevice(), image, &memRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = renderer.findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
vkAllocateMemory(renderer.getDevice(), &allocInfo, nullptr, &memory);
|
||||
|
||||
vkBindImageMemory(renderer.getDevice(), image, memory, 0);
|
||||
|
||||
renderer.uploadImageData(
|
||||
image,
|
||||
width,
|
||||
height,
|
||||
size,
|
||||
data);
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.image = image;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = imageInfo.format;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
|
||||
vkCreateImageView(renderer.getDevice(), &viewInfo, nullptr, &view);
|
||||
};
|
||||
|
||||
loadResource(AREATEX_SIZE, AREATEX_WIDTH, AREATEX_HEIGHT, areaTexBytes, VK_FORMAT_R8G8_UNORM, areaImage, areaMemory, areaImageView);
|
||||
loadResource(SEARCHTEX_SIZE, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, searchTexBytes, VK_FORMAT_R8_UNORM, searchImage, searchMemory, searchImageView);
|
||||
|
||||
VkSamplerCreateInfo samplerCreateInfo = {};
|
||||
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU;
|
||||
samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU;
|
||||
samplerCreateInfo.mipLodBias = 0.0f;
|
||||
samplerCreateInfo.maxAnisotropy = 0;
|
||||
samplerCreateInfo.minLod = 0.0f;
|
||||
samplerCreateInfo.maxLod = 1.0f;
|
||||
samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
|
||||
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &areaSampler);
|
||||
|
||||
samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
|
||||
samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
|
||||
|
||||
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &searchSampler);
|
||||
}
|
||||
|
||||
void SMAAPass::setupDescriptorLayouts() {
|
||||
// edge
|
||||
{
|
||||
VkDescriptorSetLayoutBinding imageSamplerLayoutBinding = {};
|
||||
imageSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
imageSamplerLayoutBinding.descriptorCount = 1;
|
||||
imageSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
VkDescriptorSetLayoutBinding depthSamplerLayoutBinding = {};
|
||||
depthSamplerLayoutBinding.binding = 1;
|
||||
depthSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
depthSamplerLayoutBinding.descriptorCount = 1;
|
||||
depthSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
const std::array<VkDescriptorSetLayoutBinding, 2> bindings = {imageSamplerLayoutBinding, depthSamplerLayoutBinding};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
||||
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
layoutInfo.bindingCount = bindings.size();
|
||||
layoutInfo.pBindings = bindings.data();
|
||||
|
||||
vkCreateDescriptorSetLayout(renderer.getDevice(), &layoutInfo, nullptr, &edgeDescriptorSetLayout);
|
||||
}
|
||||
|
||||
// blend
|
||||
{
|
||||
VkDescriptorSetLayoutBinding edgeSamplerLayoutBinding = {};
|
||||
edgeSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
edgeSamplerLayoutBinding.descriptorCount = 1;
|
||||
edgeSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
VkDescriptorSetLayoutBinding areaSamplerLayoutBinding = {};
|
||||
areaSamplerLayoutBinding.binding = 1;
|
||||
areaSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
areaSamplerLayoutBinding.descriptorCount = 1;
|
||||
areaSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
VkDescriptorSetLayoutBinding searchSamplerLayoutBinding = {};
|
||||
searchSamplerLayoutBinding.binding = 2;
|
||||
searchSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
searchSamplerLayoutBinding.descriptorCount = 1;
|
||||
searchSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
const std::array<VkDescriptorSetLayoutBinding, 3> bindings = {edgeSamplerLayoutBinding, areaSamplerLayoutBinding, searchSamplerLayoutBinding};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
||||
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
layoutInfo.bindingCount = bindings.size();
|
||||
layoutInfo.pBindings = bindings.data();
|
||||
|
||||
vkCreateDescriptorSetLayout(renderer.getDevice(), &layoutInfo, nullptr, &blendDescriptorSetLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void SMAAPass::createOffscreenResources() {
|
||||
const VkFormat colorFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
|
||||
VkSamplerCreateInfo samplerCreateInfo = {};
|
||||
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU;
|
||||
samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU;
|
||||
samplerCreateInfo.mipLodBias = 0.0f;
|
||||
samplerCreateInfo.maxAnisotropy = 0;
|
||||
samplerCreateInfo.minLod = 0.0f;
|
||||
samplerCreateInfo.maxLod = 1.0f;
|
||||
samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
|
||||
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &edgeSampler);
|
||||
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &blendSampler);
|
||||
}
|
||||
|
||||
void SMAAPass::createRenderPasses() {
|
||||
VkAttachmentDescription colorAttachment = {};
|
||||
colorAttachment.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
VkAttachmentReference colorAttachmentRef = {};
|
||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorAttachmentRef;
|
||||
|
||||
VkSubpassDependency dependency = {};
|
||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.dstSubpass = 0;
|
||||
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.srcAccessMask = 0;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
renderPassInfo.attachmentCount = 1;
|
||||
renderPassInfo.pAttachments = &colorAttachment;
|
||||
renderPassInfo.subpassCount = 1;
|
||||
renderPassInfo.pSubpasses = &subpass;
|
||||
renderPassInfo.dependencyCount = 1;
|
||||
renderPassInfo.pDependencies = &dependency;
|
||||
|
||||
// FIXME: wot
|
||||
vkCreateRenderPass(renderer.getDevice(), &renderPassInfo, nullptr, &edgeRenderPass);
|
||||
vkCreateRenderPass(renderer.getDevice(), &renderPassInfo, nullptr, &blendRenderPass);
|
||||
}
|
||||
|
||||
void SMAAPass::createPipelines() {
|
||||
VkShaderModule edgeVertexShader = renderer.createShader("shaders/edge.vert.spv");
|
||||
VkShaderModule edgeFragmentShader = renderer.createShader("shaders/edge.frag.spv");
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
|
||||
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
vertShaderStageInfo.module = edgeVertexShader;
|
||||
vertShaderStageInfo.pName = "main";
|
||||
|
||||
VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
|
||||
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
fragShaderStageInfo.module = edgeFragmentShader;
|
||||
fragShaderStageInfo.pName = "main";
|
||||
|
||||
VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
||||
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.width = 1280;
|
||||
viewport.height = 720;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
VkRect2D scissor = {};
|
||||
scissor.extent.width = 1280;
|
||||
scissor.extent.height = 720;
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportState = {};
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportState.viewportCount = 1;
|
||||
viewportState.pViewports = &viewport;
|
||||
viewportState.scissorCount = 1;
|
||||
viewportState.pScissors = &scissor;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizer = {};
|
||||
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterizer.depthClampEnable = VK_FALSE;
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
rasterizer.cullMode = VK_CULL_MODE_NONE;
|
||||
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
rasterizer.depthBiasEnable = VK_FALSE;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampling = {};
|
||||
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampling.sampleShadingEnable = VK_FALSE;
|
||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
|
||||
colorBlendAttachment.colorWriteMask =
|
||||
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
colorBlendAttachment.blendEnable = VK_FALSE;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo colorBlending = {};
|
||||
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
colorBlending.attachmentCount = 1;
|
||||
colorBlending.pAttachments = &colorBlendAttachment;
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipelineLayoutInfo.setLayoutCount = 1;
|
||||
pipelineLayoutInfo.pSetLayouts = &edgeDescriptorSetLayout;
|
||||
|
||||
vkCreatePipelineLayout(renderer.getDevice(), &pipelineLayoutInfo, nullptr, &edgePipelineLayout);
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
pipelineInfo.stageCount = 2;
|
||||
pipelineInfo.pStages = shaderStages;
|
||||
pipelineInfo.pVertexInputState = &vertexInputInfo;
|
||||
pipelineInfo.pInputAssemblyState = &inputAssembly;
|
||||
pipelineInfo.pViewportState = &viewportState;
|
||||
pipelineInfo.pRasterizationState = &rasterizer;
|
||||
pipelineInfo.pMultisampleState = &multisampling;
|
||||
pipelineInfo.pColorBlendState = &colorBlending;
|
||||
pipelineInfo.layout = edgePipelineLayout;
|
||||
pipelineInfo.renderPass = edgeRenderPass;
|
||||
|
||||
vkCreateGraphicsPipelines(renderer.getDevice(), nullptr, 1, &pipelineInfo, nullptr, &edgePipeline);
|
||||
|
||||
VkShaderModule blendVertexShader = renderer.createShader("shaders/blend.vert.spv");
|
||||
VkShaderModule blendFragmentShader = renderer.createShader("shaders/blend.frag.spv");
|
||||
|
||||
vertShaderStageInfo.module = blendVertexShader;
|
||||
fragShaderStageInfo.module = blendFragmentShader;
|
||||
|
||||
VkPipelineShaderStageCreateInfo newShaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
|
||||
pipelineInfo.pStages = newShaderStages;
|
||||
|
||||
pipelineLayoutInfo.pSetLayouts = &blendDescriptorSetLayout;
|
||||
|
||||
vkCreatePipelineLayout(renderer.getDevice(), &pipelineLayoutInfo, nullptr, &blendPipelineLayout);
|
||||
|
||||
pipelineInfo.layout = blendPipelineLayout;
|
||||
pipelineInfo.renderPass = blendRenderPass;
|
||||
|
||||
vkCreateGraphicsPipelines(renderer.getDevice(), nullptr, 1, &pipelineInfo, nullptr, &blendPipeline);
|
||||
|
||||
vkDestroyShaderModule(renderer.getDevice(), blendFragmentShader, nullptr);
|
||||
vkDestroyShaderModule(renderer.getDevice(), blendVertexShader, nullptr);
|
||||
|
||||
vkDestroyShaderModule(renderer.getDevice(), edgeFragmentShader, nullptr);
|
||||
vkDestroyShaderModule(renderer.getDevice(), edgeVertexShader, nullptr);
|
||||
}
|
Reference in a new issue