Vulkan depth
This commit is contained in:
parent
d95b9eefee
commit
a408a475f5
BIN
resource/content/shaders/Tris.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Tris.vs.spv (Stored with Git LFS)
Binary file not shown.
|
@ -7,7 +7,7 @@ layout(binding = 0) uniform UniformBufferObject {
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout(location = 0) in vec2 inPosition;
|
layout(location = 0) in vec3 inPosition;
|
||||||
layout(location = 1) in vec3 inColor;
|
layout(location = 1) in vec3 inColor;
|
||||||
layout(location = 2) in vec2 inTexCoord;
|
layout(location = 2) in vec2 inTexCoord;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ layout(location = 0) out vec3 fragColor;
|
||||||
layout(location = 1) out vec2 fragTexCoord;
|
layout(location = 1) out vec2 fragTexCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
|
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
||||||
fragColor = inColor;
|
fragColor = inColor;
|
||||||
fragTexCoord = inTexCoord;
|
fragTexCoord = inTexCoord;
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
BASEDIR=$(dirname "$0")
|
BASEDIR=$(dirname "$0")
|
||||||
TARGETDIR="$BASEDIR/../content/shaders"
|
TARGETDIR="$BASEDIR/../content/shaders"
|
||||||
GLSL="glslc"
|
GLSL=${GLSL:="glslc"}
|
||||||
|
|
||||||
rm $TARGETDIR/*.spv
|
rm $TARGETDIR/*.spv
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
BC2 = 136,
|
BC2 = 136,
|
||||||
/// DXT1 RGBA SRGB
|
/// DXT1 RGBA SRGB
|
||||||
BC3 = 138,
|
BC3 = 138,
|
||||||
// MAYBE: BMP RGBA SRGB ??
|
// MAYBE: R8G8B8A8
|
||||||
// MAYBE: For HDR BC6H_SFLOAT = 144,
|
// MAYBE: For HDR BC6H_SFLOAT = 144,
|
||||||
};
|
};
|
||||||
// NOTE: matches VkImageLayout
|
// NOTE: matches VkImageLayout
|
||||||
|
@ -58,6 +58,13 @@ public:
|
||||||
friend inline Usage operator|(Usage a, Usage b) {
|
friend inline Usage operator|(Usage a, Usage b) {
|
||||||
return static_cast<Usage>(static_cast<int>(a) | static_cast<int>(b));
|
return static_cast<Usage>(static_cast<int>(a) | static_cast<int>(b));
|
||||||
}
|
}
|
||||||
|
//NOTE: matches VkImageAspectFlags
|
||||||
|
enum class Aspect {
|
||||||
|
COLOR = 0x00000001,
|
||||||
|
DEPTH = 0x00000002,
|
||||||
|
STENCIL = 0x00000004,
|
||||||
|
METADATA = 0x00000008
|
||||||
|
};
|
||||||
|
|
||||||
struct properties {
|
struct properties {
|
||||||
frame size;
|
frame size;
|
||||||
|
@ -69,6 +76,7 @@ public:
|
||||||
Layout layout;
|
Layout layout;
|
||||||
Usage usage;
|
Usage usage;
|
||||||
bool linear = false;
|
bool linear = false;
|
||||||
|
Aspect aspect = Aspect::COLOR;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
|
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
|
||||||
|
|
|
@ -206,12 +206,21 @@ void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLay
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
|
||||||
barrier.image = image;
|
barrier.image = image;
|
||||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
barrier.subresourceRange.baseMipLevel = 0;
|
barrier.subresourceRange.baseMipLevel = 0;
|
||||||
barrier.subresourceRange.levelCount = 1;
|
barrier.subresourceRange.levelCount = 1;
|
||||||
barrier.subresourceRange.baseArrayLayer = 0;
|
barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
barrier.subresourceRange.layerCount = 1;
|
barrier.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||||
|
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
|
||||||
|
if (PhysicalDeviceInfo::HasStencilComponent(format)) {
|
||||||
|
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
VkPipelineStageFlags sourceStage;
|
VkPipelineStageFlags sourceStage;
|
||||||
VkPipelineStageFlags destinationStage;
|
VkPipelineStageFlags destinationStage;
|
||||||
|
|
||||||
|
@ -227,6 +236,12 @@ void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLay
|
||||||
|
|
||||||
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
|
} else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||||
|
barrier.srcAccessMask = 0;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
|
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||||
|
destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||||
} else {
|
} else {
|
||||||
FATAL("Unsupported layout transition!");
|
FATAL("Unsupported layout transition!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
|
||||||
FATAL("Failed to create texture sampler!");
|
FATAL("Failed to create texture sampler!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
depthFormat = info.findDepthFormat();
|
||||||
}
|
}
|
||||||
CommandCenter::~CommandCenter() {
|
CommandCenter::~CommandCenter() {
|
||||||
if(!freed)
|
if(!freed)
|
||||||
|
@ -45,16 +46,19 @@ CommandCenter::~CommandCenter() {
|
||||||
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent, const renderOptions& opt) {
|
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent, const renderOptions& opt) {
|
||||||
assert(freed);
|
assert(freed);
|
||||||
|
|
||||||
|
depthbuffer = Image::Create({{{extent.height, extent.width}, 1, (Image::Format)depthFormat},
|
||||||
|
Image::Layout::DEPTH_STENCIL_ATTACHMENT, Image::Usage::DEPTH_STENCIL_ATTACHMENT, false, Image::Aspect::DEPTH});
|
||||||
|
|
||||||
framebuffers.resize(views.size());
|
framebuffers.resize(views.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < views.size(); i++) {
|
for (size_t i = 0; i < views.size(); i++) {
|
||||||
VkImageView attachments[] = { views[i] };
|
std::array<VkImageView, 2> attachments = { views[i], depthbuffer->getView() };
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebufferInfo{};
|
VkFramebufferCreateInfo framebufferInfo{};
|
||||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
framebufferInfo.renderPass = pipe.getRenderPass();
|
framebufferInfo.renderPass = pipe.getRenderPass();
|
||||||
framebufferInfo.attachmentCount = 1;
|
framebufferInfo.attachmentCount = attachments.size();
|
||||||
framebufferInfo.pAttachments = attachments;
|
framebufferInfo.pAttachments = attachments.data();
|
||||||
framebufferInfo.width = extent.width;
|
framebufferInfo.width = extent.width;
|
||||||
framebufferInfo.height = extent.height;
|
framebufferInfo.height = extent.height;
|
||||||
framebufferInfo.layers = 1;
|
framebufferInfo.layers = 1;
|
||||||
|
@ -162,9 +166,11 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
|
||||||
renderPassInfo.renderArea.offset = {0, 0};
|
renderPassInfo.renderArea.offset = {0, 0};
|
||||||
renderPassInfo.renderArea.extent = extent;
|
renderPassInfo.renderArea.extent = extent;
|
||||||
|
|
||||||
VkClearValue clearColor = {opt.clear_color.x, opt.clear_color.y, opt.clear_color.z, opt.clear_color.a};
|
std::array<VkClearValue, 2> clearValues{};
|
||||||
renderPassInfo.clearValueCount = 1; //TODO: clear depth
|
clearValues[0].color = {opt.clear_color.x, opt.clear_color.y, opt.clear_color.z, opt.clear_color.a};
|
||||||
renderPassInfo.pClearValues = &clearColor;
|
clearValues[1].depthStencil = {1.0f, 0};
|
||||||
|
renderPassInfo.clearValueCount = clearValues.size();
|
||||||
|
renderPassInfo.pClearValues = clearValues.data();
|
||||||
|
|
||||||
vkCmdBeginRenderPass(graphicsBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(graphicsBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
vkCmdBindPipeline(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getPipeline());
|
vkCmdBindPipeline(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getPipeline());
|
||||||
|
@ -181,7 +187,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proj = glm::perspective(glm::radians(45.0f), extent.width / (float) extent.height, 0.1f, 10.0f);
|
proj = glm::perspectiveZO(glm::radians(45.0f), extent.width / (float) extent.height, 0.1f, 10.0f);
|
||||||
proj[1][1] *= -1;
|
proj[1][1] *= -1;
|
||||||
|
|
||||||
freed = false;
|
freed = false;
|
||||||
|
@ -192,6 +198,8 @@ void CommandCenter::free() {
|
||||||
|
|
||||||
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
||||||
|
|
||||||
|
depthbuffer.reset();
|
||||||
|
|
||||||
for (size_t i = 0; i < framebuffers.size(); i++) {
|
for (size_t i = 0; i < framebuffers.size(); i++) {
|
||||||
vkDestroyFramebuffer(device, framebuffers[i], nullptr);
|
vkDestroyFramebuffer(device, framebuffers[i], nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ private:
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
|
|
||||||
std::vector<VkFramebuffer> framebuffers;
|
std::vector<VkFramebuffer> framebuffers;
|
||||||
|
VkFormat depthFormat;
|
||||||
|
std::unique_ptr<Image> depthbuffer;
|
||||||
|
|
||||||
VkQueue graphicsQueue;
|
VkQueue graphicsQueue;
|
||||||
VkCommandPool graphicsPool;
|
VkCommandPool graphicsPool;
|
||||||
|
|
|
@ -56,7 +56,7 @@ QueueFamilyIndices QueueFamilyIndices::Query(VkPhysicalDevice device, VkSurfaceK
|
||||||
return queueIndices;
|
return queueIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceFormatKHR PhysicalDeviceInfo::getFormat() const {
|
VkSurfaceFormatKHR PhysicalDeviceInfo::getSurfaceFormat() const {
|
||||||
for(const auto& format: swapDetails.formats) {
|
for(const auto& format: swapDetails.formats) {
|
||||||
if (format.format == VK_FORMAT_B8G8R8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
if (format.format == VK_FORMAT_B8G8R8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
||||||
return format;
|
return format;
|
||||||
|
@ -66,6 +66,27 @@ VkSurfaceFormatKHR PhysicalDeviceInfo::getFormat() const {
|
||||||
LOG_W("Using suboptimal surface format");
|
LOG_W("Using suboptimal surface format");
|
||||||
return swapDetails.formats[0];
|
return swapDetails.formats[0];
|
||||||
}
|
}
|
||||||
|
std::optional<VkFormat> PhysicalDeviceInfo::findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) const {
|
||||||
|
for (VkFormat format : candidates) {
|
||||||
|
VkFormatProperties props;
|
||||||
|
vkGetPhysicalDeviceFormatProperties(device, format, &props);
|
||||||
|
|
||||||
|
if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {
|
||||||
|
return format;
|
||||||
|
} else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
VkFormat PhysicalDeviceInfo::findDepthFormat() const {
|
||||||
|
if (auto res = findSupportedFormat(
|
||||||
|
{VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT},
|
||||||
|
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||||
|
return res.value();
|
||||||
|
|
||||||
|
FATAL("Any compatible depth format");
|
||||||
|
}
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
bool PhysicalDeviceInfo::hasMemoryBudget() const {
|
bool PhysicalDeviceInfo::hasMemoryBudget() const {
|
||||||
for (auto extension: optionalExtensions) {
|
for (auto extension: optionalExtensions) {
|
||||||
|
|
|
@ -32,9 +32,15 @@ struct PhysicalDeviceInfo {
|
||||||
vkGetPhysicalDeviceFeatures(device, &features);
|
vkGetPhysicalDeviceFeatures(device, &features);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceFormatKHR getFormat() const;
|
VkSurfaceFormatKHR getSurfaceFormat() const;
|
||||||
|
std::optional<VkFormat> findSupportedFormat(const std::vector<VkFormat> &candidates, VkImageTiling tiling, VkFormatFeatureFlags features) const;
|
||||||
|
VkFormat findDepthFormat() const;
|
||||||
bool hasMemoryBudget() const;
|
bool hasMemoryBudget() const;
|
||||||
|
|
||||||
|
static bool HasStencilComponent(VkFormat format) {
|
||||||
|
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
VkPhysicalDevice device = VK_NULL_HANDLE;
|
VkPhysicalDevice device = VK_NULL_HANDLE;
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
|
|
|
@ -15,7 +15,7 @@ using namespace render::vk;
|
||||||
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
|
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
|
||||||
{ // Render pass
|
{ // Render pass
|
||||||
VkAttachmentDescription colorAttachment{};
|
VkAttachmentDescription colorAttachment{};
|
||||||
colorAttachment.format = info.getFormat().format;
|
colorAttachment.format = info.getSurfaceFormat().format;
|
||||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
@ -24,16 +24,31 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
||||||
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
//TODO: subpasses (world, entities, colors, sky, ui)
|
|
||||||
VkAttachmentReference colorAttachmentRef{};
|
VkAttachmentReference colorAttachmentRef{};
|
||||||
colorAttachmentRef.attachment = 0; //TODO: layouts bind
|
colorAttachmentRef.attachment = 0; //TODO: layouts bind
|
||||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentDescription depthAttachment{};
|
||||||
|
depthAttachment.format = info.findDepthFormat();
|
||||||
|
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference depthAttachmentRef{};
|
||||||
|
depthAttachmentRef.attachment = 1;
|
||||||
|
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
//TODO: subpasses (world, entities, colors, sky, ui)
|
||||||
|
|
||||||
VkSubpassDescription subpass{};
|
VkSubpassDescription subpass{};
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
|
||||||
subpass.colorAttachmentCount = 1;
|
subpass.colorAttachmentCount = 1;
|
||||||
subpass.pColorAttachments = &colorAttachmentRef;
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
|
subpass.pDepthStencilAttachment = &depthAttachmentRef;
|
||||||
|
|
||||||
VkSubpassDependency dependency{};
|
VkSubpassDependency dependency{};
|
||||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
@ -45,8 +60,9 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
||||||
|
|
||||||
VkRenderPassCreateInfo renderPassInfo{};
|
VkRenderPassCreateInfo renderPassInfo{};
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
renderPassInfo.attachmentCount = 1;
|
std::array<VkAttachmentDescription, 2> attachments = {colorAttachment, depthAttachment};
|
||||||
renderPassInfo.pAttachments = &colorAttachment;
|
renderPassInfo.attachmentCount = attachments.size();
|
||||||
|
renderPassInfo.pAttachments = attachments.data();
|
||||||
renderPassInfo.subpassCount = 1;
|
renderPassInfo.subpassCount = 1;
|
||||||
renderPassInfo.pSubpasses = &subpass;
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
renderPassInfo.dependencyCount = 1;
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
@ -185,8 +201,15 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
||||||
|
|
||||||
VkPipelineDepthStencilStateCreateInfo depthStencil{};
|
VkPipelineDepthStencilStateCreateInfo depthStencil{};
|
||||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||||
|
depthStencil.depthTestEnable = VK_TRUE;
|
||||||
|
depthStencil.depthWriteEnable = VK_TRUE;
|
||||||
|
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS; //FIXME: LEQUAL for skybox
|
||||||
|
depthStencil.depthBoundsTestEnable = VK_FALSE; // Restrict sub depth area
|
||||||
|
depthStencil.minDepthBounds = 0.0f;
|
||||||
|
depthStencil.maxDepthBounds = 1.0f;
|
||||||
|
|
||||||
depthStencil.stencilTestEnable = VK_FALSE;
|
depthStencil.stencilTestEnable = VK_FALSE;
|
||||||
depthStencil.depthTestEnable = VK_FALSE; // TODO: depth filter NOTE: set as null if create info
|
// Stencil options front/back
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
|
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.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
@ -233,7 +256,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
||||||
pipelineInfo.pViewportState = &viewportState;
|
pipelineInfo.pViewportState = &viewportState;
|
||||||
pipelineInfo.pRasterizationState = &rasterizer;
|
pipelineInfo.pRasterizationState = &rasterizer;
|
||||||
pipelineInfo.pMultisampleState = &multisampling;
|
pipelineInfo.pMultisampleState = &multisampling;
|
||||||
pipelineInfo.pDepthStencilState = nullptr; //FIXME: depthTest
|
pipelineInfo.pDepthStencilState = &depthStencil;
|
||||||
pipelineInfo.pColorBlendState = &colorBlending;
|
pipelineInfo.pColorBlendState = &colorBlending;
|
||||||
pipelineInfo.pDynamicState = nullptr;
|
pipelineInfo.pDynamicState = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@ SwapChain::SwapChain(VkDevice device, const PhysicalDeviceInfo& info): device(de
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
createInfo.surface = info.surface;
|
createInfo.surface = info.surface;
|
||||||
createInfo.minImageCount = imageCount;
|
createInfo.minImageCount = imageCount;
|
||||||
createInfo.imageFormat = info.getFormat().format;
|
createInfo.imageFormat = info.getSurfaceFormat().format;
|
||||||
createInfo.imageColorSpace = info.getFormat().colorSpace;
|
createInfo.imageColorSpace = info.getSurfaceFormat().colorSpace;
|
||||||
createInfo.imageExtent = info.swapDetails.capabilities.currentExtent;
|
createInfo.imageExtent = info.swapDetails.capabilities.currentExtent;
|
||||||
createInfo.imageArrayLayers = 1;
|
createInfo.imageArrayLayers = 1;
|
||||||
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; //VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; //VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||||
|
@ -67,7 +67,7 @@ SwapChain::SwapChain(VkDevice device, const PhysicalDeviceInfo& info): device(de
|
||||||
createInfo.image = images[i];
|
createInfo.image = images[i];
|
||||||
|
|
||||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
createInfo.format = info.getFormat().format;
|
createInfo.format = info.getSurfaceFormat().format;
|
||||||
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
|
|
@ -7,13 +7,13 @@ using namespace render::vk;
|
||||||
|
|
||||||
Image::~Image() {
|
Image::~Image() {
|
||||||
vkDestroyImage(Allocator::GetDefault()->getDevice(), ref, ALLOC);
|
vkDestroyImage(Allocator::GetDefault()->getDevice(), ref, ALLOC);
|
||||||
|
vkDestroyImageView(Allocator::GetDefault()->getDevice(), view, ALLOC);
|
||||||
}
|
}
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
vkDestroySampler(Allocator::GetDefault()->getDevice(), sampler, ALLOC);
|
vkDestroySampler(Allocator::GetDefault()->getDevice(), sampler, ALLOC);
|
||||||
vkDestroyImageView(Allocator::GetDefault()->getDevice(), view, ALLOC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags properties, const render::data_view view, Image::info& out) {
|
memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags properties, const render::data_view data, Image::info& out) {
|
||||||
auto alloc = Allocator::GetDefault();
|
auto alloc = Allocator::GetDefault();
|
||||||
auto device = alloc->getDevice();
|
auto device = alloc->getDevice();
|
||||||
|
|
||||||
|
@ -27,13 +27,12 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
|
||||||
info.arrayLayers = 1;
|
info.arrayLayers = 1;
|
||||||
info.format = static_cast<VkFormat>(req.props.format);
|
info.format = static_cast<VkFormat>(req.props.format);
|
||||||
info.tiling = req.linear ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
|
info.tiling = req.linear ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
|
||||||
info.initialLayout = static_cast<VkImageLayout>(req.layout);
|
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
info.usage = static_cast<VkImageUsageFlags>(req.usage);
|
info.usage = static_cast<VkImageUsageFlags>(req.usage);
|
||||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
info.flags = 0;
|
info.flags = 0;
|
||||||
if (view) {
|
if (data) {
|
||||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,21 +51,48 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
|
||||||
return memory::GetNull();
|
return memory::GetNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view) {
|
if (data) {
|
||||||
if(auto staging = WritableBuffer::Create(view.size)) {
|
if(auto staging = WritableBuffer::Create(data.size)) {
|
||||||
staging->write(view, 0);
|
staging->write(data, 0);
|
||||||
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
alloc->copyBufferToImage(staging->getRef(), out.ref, info.extent.width, info.extent.height);
|
alloc->copyBufferToImage(staging->getRef(), out.ref, info.extent.width, info.extent.height);
|
||||||
alloc->transitionImageLayout(out.ref, info.format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<VkImageLayout>(req.layout));
|
alloc->transitionImageLayout(out.ref, info.format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<VkImageLayout>(req.layout));
|
||||||
} else {
|
} else {
|
||||||
FATAL("Cannot allocate staging memory");
|
LOG_E("Cannot allocate staging memory");
|
||||||
return memory::GetNull();
|
return memory::GetNull();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
alloc->transitionImageLayout(out.ref, info.format, info.initialLayout, static_cast<VkImageLayout>(req.layout));
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageViewCreateInfo viewInfo{};
|
||||||
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
viewInfo.image = out.ref;
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
viewInfo.format = static_cast<VkFormat>(req.props.format);
|
||||||
|
viewInfo.subresourceRange.aspectMask = static_cast<VkImageAspectFlags>(req.aspect);
|
||||||
|
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
viewInfo.subresourceRange.levelCount = 1; //TODO: mipmap
|
||||||
|
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
viewInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
if (vkCreateImageView(device, &viewInfo, ALLOC, &out.view) != VK_SUCCESS) {
|
||||||
|
LOG_E("Failed to create texture image view!");
|
||||||
|
return memory::GetNull();
|
||||||
}
|
}
|
||||||
return memory;
|
return memory;
|
||||||
}
|
}
|
||||||
//TODO: createImages
|
//TODO: createImages
|
||||||
|
|
||||||
|
std::unique_ptr<Image> Image::Create(const requirement & req) {
|
||||||
|
vk::Image::info img;
|
||||||
|
auto mem = createImage(req, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, data_view(), img);
|
||||||
|
if(!mem) {
|
||||||
|
FATAL("Cannot create texture image");
|
||||||
|
}
|
||||||
|
return std::unique_ptr<Image>(new Image(img.ref, img.view, std::move(mem)));
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sampling& props) {
|
std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sampling& props) {
|
||||||
auto device = Allocator::GetDefault()->getDevice();
|
auto device = Allocator::GetDefault()->getDevice();
|
||||||
|
|
||||||
|
@ -85,22 +111,6 @@ std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sa
|
||||||
FATAL("Cannot create texture image");
|
FATAL("Cannot create texture image");
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageViewCreateInfo viewInfo{};
|
|
||||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
||||||
viewInfo.image = img.ref;
|
|
||||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
viewInfo.format = static_cast<VkFormat>(header.format);
|
|
||||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
|
||||||
viewInfo.subresourceRange.levelCount = 1;
|
|
||||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
|
||||||
viewInfo.subresourceRange.layerCount = 1;
|
|
||||||
|
|
||||||
VkImageView view;
|
|
||||||
if (vkCreateImageView(device, &viewInfo, ALLOC, &view) != VK_SUCCESS) {
|
|
||||||
FATAL("Failed to create texture image view!");
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerInfo{};
|
VkSamplerCreateInfo samplerInfo{};
|
||||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
samplerInfo.magFilter = props.magLinear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
samplerInfo.magFilter = props.magLinear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||||
|
@ -135,5 +145,5 @@ std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sa
|
||||||
FATAL("Failed to create texture sampler!");
|
FATAL("Failed to create texture sampler!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::unique_ptr<Texture>(new Texture(sampler, view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.ref, std::move(mem)));
|
return std::unique_ptr<Texture>(new Texture(sampler, img.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.ref, std::move(mem)));
|
||||||
}
|
}
|
|
@ -9,17 +9,23 @@ class Image: public render::Image {
|
||||||
public:
|
public:
|
||||||
virtual ~Image();
|
virtual ~Image();
|
||||||
|
|
||||||
|
const VkImageView &getView() const { return view; }
|
||||||
|
|
||||||
static void MakeDefault();
|
static void MakeDefault();
|
||||||
|
|
||||||
struct info {
|
struct info {
|
||||||
VkImage ref = nullptr;
|
VkImage ref = nullptr;
|
||||||
|
VkImageView view = nullptr;
|
||||||
VkDeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::unique_ptr<Image> Create(const requirement &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Image(VkImage ref, memory::ptr mem):
|
Image(VkImage ref, VkImageView view, memory::ptr mem):
|
||||||
ref(ref), memory(std::move(mem)) { }
|
ref(ref), view(view), memory(std::move(mem)) { }
|
||||||
VkImage ref;
|
VkImage ref;
|
||||||
|
VkImageView view;
|
||||||
memory::ptr memory;
|
memory::ptr memory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,9 +39,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Texture(VkSampler sampler, VkImageView view, VkImageLayout layout, VkImage ref, memory::ptr memory):
|
Texture(VkSampler sampler, VkImageView view, VkImageLayout layout, VkImage ref, memory::ptr memory):
|
||||||
vk::Image(ref, std::move(memory)), sampler(sampler), view(view), descriptor({sampler, view, layout}) { }
|
vk::Image(ref, view, std::move(memory)), sampler(sampler), descriptor({sampler, view, layout}) { }
|
||||||
VkSampler sampler;
|
VkSampler sampler;
|
||||||
VkImageView view;
|
|
||||||
const VkDescriptorImageInfo descriptor;
|
const VkDescriptorImageInfo descriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace buffer::vk {
|
namespace buffer::vk {
|
||||||
|
|
||||||
struct VertexData {
|
struct VertexData {
|
||||||
glm::vec2 pos;
|
glm::vec3 pos;
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
glm::vec2 uv;
|
glm::vec2 uv;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ struct VertexData {
|
||||||
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
|
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
|
||||||
attributeDescriptions[0].binding = 0;
|
attributeDescriptions[0].binding = 0;
|
||||||
attributeDescriptions[0].location = 0;
|
attributeDescriptions[0].location = 0;
|
||||||
attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
|
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
attributeDescriptions[0].offset = offsetof(VertexData, pos);
|
attributeDescriptions[0].offset = offsetof(VertexData, pos);
|
||||||
attributeDescriptions[1].binding = 0;
|
attributeDescriptions[1].binding = 0;
|
||||||
attributeDescriptions[1].location = 1;
|
attributeDescriptions[1].location = 1;
|
||||||
|
@ -38,15 +38,20 @@ struct VertexData {
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<VertexData> vertices = {
|
const std::vector<VertexData> vertices = {
|
||||||
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
||||||
{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
{{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
||||||
{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
{{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
||||||
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}
|
{{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
|
||||||
};
|
|
||||||
const std::vector<uint16_t> indices = {
|
|
||||||
0, 1, 2, 2, 3, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
|
{{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
||||||
|
{{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
||||||
|
{{0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
||||||
|
{{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}};
|
||||||
|
|
||||||
|
const std::vector<uint16_t> indices = {
|
||||||
|
0, 1, 2, 2, 3, 0,
|
||||||
|
4, 5, 6, 6, 7, 4
|
||||||
|
};
|
||||||
|
|
||||||
struct UniformBufferObject {
|
struct UniformBufferObject {
|
||||||
alignas(16) glm::mat4 model;
|
alignas(16) glm::mat4 model;
|
||||||
|
|
Loading…
Reference in New Issue