Texture creation and binding works!
This commit is contained in:
parent
4012425d35
commit
ef1bceb388
@ -2,7 +2,7 @@
|
|||||||
#include <Memory/Memory.hpp>
|
#include <Memory/Memory.hpp>
|
||||||
|
|
||||||
|
|
||||||
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image _image, vk::MemoryPropertyFlags memory_flags) : dev(dev), image(_image) {
|
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image _image, vk::MemoryPropertyFlags memory_flags, vk::Extent3D& extent) : dev(dev), image(_image) {
|
||||||
|
|
||||||
auto reqs = dev.getImageMemoryRequirements(image);
|
auto reqs = dev.getImageMemoryRequirements(image);
|
||||||
|
|
||||||
@ -12,13 +12,14 @@ Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image _image, vk::
|
|||||||
};
|
};
|
||||||
memory = dev.allocateMemory(alloc);
|
memory = dev.allocateMemory(alloc);
|
||||||
dev.bindImageMemory(image, memory, 0);
|
dev.bindImageMemory(image, memory, 0);
|
||||||
|
this->extent = extent;
|
||||||
|
Log::debug("Image memory: %p\n", memory);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::ImageCreateInfo info, vk::MemoryPropertyFlags memory_flags) : dev(dev) {
|
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::ImageCreateInfo info, vk::MemoryPropertyFlags memory_flags) : dev(dev) {
|
||||||
image = dev.createImage(info);
|
image = dev.createImage(info);
|
||||||
|
*this = Image(phys_dev, dev, image, memory_flags, info.extent);
|
||||||
*this = Image(phys_dev, dev, image, memory_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Extent3D extent, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memory_flags) : dev(dev) {
|
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Extent3D extent, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memory_flags) : dev(dev) {
|
||||||
|
|||||||
@ -12,9 +12,13 @@ struct Image {
|
|||||||
vk::Image image;
|
vk::Image image;
|
||||||
vk::DeviceMemory memory;
|
vk::DeviceMemory memory;
|
||||||
|
|
||||||
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image image, vk::MemoryPropertyFlags memory_flags);
|
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image image, vk::MemoryPropertyFlags memory_flags, vk::Extent3D& extent);
|
||||||
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::ImageCreateInfo info, vk::MemoryPropertyFlags memory_flags);
|
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::ImageCreateInfo info, vk::MemoryPropertyFlags memory_flags);
|
||||||
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Extent3D extent, vk::Format format, vk::ImageTiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memory_flags);
|
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Extent3D extent, vk::Format format, vk::ImageTiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memory_flags);
|
||||||
|
|
||||||
|
operator vk::Image&() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,5 +4,6 @@
|
|||||||
- Add more comments
|
- Add more comments
|
||||||
## Long Term Improvements
|
## Long Term Improvements
|
||||||
- ~~Properly query surface to find supported formats for surfaces~~
|
- ~~Properly query surface to find supported formats for surfaces~~
|
||||||
|
- Fix all this cleanup vs destructor NONSENSE (inconsistency)
|
||||||
- Add pipeline caching
|
- Add pipeline caching
|
||||||
- Make more robust solution to window minimization (flushing out Input system should provide candidates)
|
- Make more robust solution to window minimization (flushing out Input system should provide candidates)
|
||||||
@ -8,6 +8,7 @@
|
|||||||
#include <util/log.hpp>
|
#include <util/log.hpp>
|
||||||
|
|
||||||
CommandBuffer::CommandBuffer(vk::Device dev, u32 queue_family) {
|
CommandBuffer::CommandBuffer(vk::Device dev, u32 queue_family) {
|
||||||
|
Log::debug("Command Buffer created\n");
|
||||||
/* (For now) allow command buffers to be individually recycled */
|
/* (For now) allow command buffers to be individually recycled */
|
||||||
auto pool_info = vk::CommandPoolCreateInfo {
|
auto pool_info = vk::CommandPoolCreateInfo {
|
||||||
.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer
|
.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer
|
||||||
@ -49,7 +50,7 @@ void CommandBuffer::copy(Buffer& src, Image& dst, vk::ImageLayout layout) {
|
|||||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
.mipLevel = 0,
|
.mipLevel = 0,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = 0,
|
.layerCount = 1,
|
||||||
},
|
},
|
||||||
.imageOffset = { 0, 0, 0 },
|
.imageOffset = { 0, 0, 0 },
|
||||||
.imageExtent = dst.extent,
|
.imageExtent = dst.extent,
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <Renderer/RenderPass.hpp>
|
#include <Renderer/RenderPass.hpp>
|
||||||
#include <Renderer/UniformBuffer.hpp>
|
#include <Renderer/UniformBuffer.hpp>
|
||||||
#include <Renderer/VertexBuffer.hpp>
|
#include <Renderer/VertexBuffer.hpp>
|
||||||
|
#include <Resources/Texture.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -188,6 +189,22 @@ void GraphicsPipeline::update(uint32_t binding, const UniformBuffer& uni) {
|
|||||||
}, nullptr);
|
}, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsPipeline::update(uint32_t binding, const Texture& tex) {
|
||||||
|
auto tex_info = vk::DescriptorImageInfo {
|
||||||
|
.sampler = tex.sampler,
|
||||||
|
.imageView = tex.view,
|
||||||
|
.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
|
};
|
||||||
|
|
||||||
|
dev.updateDescriptorSets(vk::WriteDescriptorSet {
|
||||||
|
.dstSet = desc_set,
|
||||||
|
.dstBinding = binding,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.pImageInfo = &tex_info,
|
||||||
|
}, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsPipeline::~GraphicsPipeline() {
|
GraphicsPipeline::~GraphicsPipeline() {
|
||||||
dev.destroyDescriptorSetLayout(desc_layout);
|
dev.destroyDescriptorSetLayout(desc_layout);
|
||||||
dev.destroyPipelineLayout(layout);
|
dev.destroyPipelineLayout(layout);
|
||||||
|
|||||||
@ -7,6 +7,7 @@ struct Shader;
|
|||||||
struct UniformBuffer;
|
struct UniformBuffer;
|
||||||
struct VertexBuffer;
|
struct VertexBuffer;
|
||||||
struct RenderPass;
|
struct RenderPass;
|
||||||
|
struct Texture;
|
||||||
|
|
||||||
struct GraphicsPipeline {
|
struct GraphicsPipeline {
|
||||||
GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders,
|
GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders,
|
||||||
@ -26,6 +27,7 @@ struct GraphicsPipeline {
|
|||||||
|
|
||||||
/* create overload for every type of object we need to update */
|
/* create overload for every type of object we need to update */
|
||||||
void update(uint32_t binding, const UniformBuffer& uni);
|
void update(uint32_t binding, const UniformBuffer& uni);
|
||||||
|
void update(uint32_t binding, const Texture& tex);
|
||||||
|
|
||||||
~GraphicsPipeline();
|
~GraphicsPipeline();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
#include <Renderer/Renderer.hpp>
|
#include <Renderer/Renderer.hpp>
|
||||||
|
#include <Resources/Texture.hpp>
|
||||||
|
|
||||||
#include <Window/Window.hpp>
|
#include <Window/Window.hpp>
|
||||||
|
|
||||||
#include <util/log.hpp>
|
#include <util/log.hpp>
|
||||||
@ -16,12 +18,12 @@
|
|||||||
|
|
||||||
|
|
||||||
const static std::vector<Vertex> triangle = {
|
const static std::vector<Vertex> triangle = {
|
||||||
{{ 1.0, -1.0, 1.0 }, { 1.0, 0.0 }},
|
{{ 1.0, -1.0, -1.0 }, { 1.0, 0.0 }},
|
||||||
{{ 1.0, 1.0, 1.0 }, { 1.0, 1.0 }},
|
{{ 1.0, 1.0, -1.0 }, { 1.0, 1.0 }},
|
||||||
{{-1.0, 1.0, 1.0 }, { 0.0, 1.0 }},
|
{{-1.0, 1.0, -1.0 }, { 0.0, 1.0 }},
|
||||||
{{-1.0, 1.0, 1.0 }, { 0.0, 1.0 }},
|
{{-1.0, 1.0, -1.0 }, { 0.0, 1.0 }},
|
||||||
{{-1.0, -1.0, 1.0 }, { 0.0, 0.0 }},
|
{{-1.0, -1.0, -1.0 }, { 0.0, 0.0 }},
|
||||||
{{ 1.0, -1.0, 1.0 }, { 1.0, 0.0 }},
|
{{ 1.0, -1.0, -1.0 }, { 1.0, 0.0 }},
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
@ -101,7 +103,7 @@ Renderer::Renderer(Window& win) : win(win) {
|
|||||||
if (discrete_idx == -1)
|
if (discrete_idx == -1)
|
||||||
discrete_idx = 0;
|
discrete_idx = 0;
|
||||||
|
|
||||||
auto& phys_dev = phys_devs[discrete_idx];
|
phys_dev = phys_devs[discrete_idx];
|
||||||
Log::info("Selected device: \"%s\" (#%zu)\n", phys_dev.getProperties().deviceName.data(), discrete_idx);
|
Log::info("Selected device: \"%s\" (#%zu)\n", phys_dev.getProperties().deviceName.data(), discrete_idx);
|
||||||
|
|
||||||
/* find queue family */
|
/* find queue family */
|
||||||
@ -184,23 +186,65 @@ Renderer::Renderer(Window& win) : win(win) {
|
|||||||
|
|
||||||
vertex_buffer->upload(triangle);
|
vertex_buffer->upload(triangle);
|
||||||
|
|
||||||
|
textures = createTextures({
|
||||||
|
"assets/textures/oil.jpg",
|
||||||
|
});
|
||||||
|
|
||||||
std::vector<Shader> shaders = {
|
std::vector<Shader> shaders = {
|
||||||
{ dev, "assets/shaders/basic.vert.spv", vk::ShaderStageFlagBits::eVertex },
|
{ dev, "assets/shaders/basic.vert.spv", vk::ShaderStageFlagBits::eVertex },
|
||||||
{ dev, "assets/shaders/trace.frag.spv", vk::ShaderStageFlagBits::eFragment },
|
{ dev, "assets/shaders/basic.frag.spv", vk::ShaderStageFlagBits::eFragment },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<vk::DescriptorSetLayoutBinding> bindings = {
|
std::vector<vk::DescriptorSetLayoutBinding> bindings = {
|
||||||
uniform_buffer->binding(0),
|
uniform_buffer->binding(0),
|
||||||
|
textures[0].binding(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
pipeline = std::make_unique<GraphicsPipeline>(dev, shaders, swapchain->extent, *render_pass, bindings, *vertex_buffer);
|
pipeline = std::make_unique<GraphicsPipeline>(dev, shaders, swapchain->extent, *render_pass, bindings, *vertex_buffer);
|
||||||
|
|
||||||
pipeline->update(0, *uniform_buffer);
|
pipeline->update(0, *uniform_buffer);
|
||||||
|
pipeline->update(1, textures[0]);
|
||||||
|
|
||||||
shaders[0].cleanup();
|
shaders[0].cleanup();
|
||||||
shaders[1].cleanup();
|
shaders[1].cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Texture> Renderer::createTextures(const std::vector<std::string>& names) {
|
||||||
|
std::vector<Texture> ret;
|
||||||
|
|
||||||
|
CommandBuffer texture_cmd(dev, queue_family);
|
||||||
|
|
||||||
|
texture_cmd.begin();
|
||||||
|
|
||||||
|
for (const auto& name : names) {
|
||||||
|
ret.push_back({phys_dev, dev, texture_cmd, "assets/textures/oil.jpg"});
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_cmd.end();
|
||||||
|
|
||||||
|
auto texture_creation_fence = dev.createFence(vk::FenceCreateInfo {});
|
||||||
|
dev.resetFences(texture_creation_fence);
|
||||||
|
|
||||||
|
queue.submit(vk::SubmitInfo {
|
||||||
|
.commandBufferCount = 1,
|
||||||
|
.pCommandBuffers = texture_cmd,
|
||||||
|
}, texture_creation_fence);
|
||||||
|
|
||||||
|
if (dev.waitForFences(texture_creation_fence, vk::True, UINT64_MAX) != vk::Result::eSuccess) {
|
||||||
|
Log::error("Failed to create textures\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
dev.destroyFence(texture_creation_fence);
|
||||||
|
|
||||||
|
for (auto& tex : ret) {
|
||||||
|
tex.finishCreation();
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_cmd.cleanup(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::draw() {
|
void Renderer::draw() {
|
||||||
|
|
||||||
if(dev.waitForFences(render_fence, true, UINT64_MAX) != vk::Result::eSuccess) {
|
if(dev.waitForFences(render_fence, true, UINT64_MAX) != vk::Result::eSuccess) {
|
||||||
@ -270,7 +314,7 @@ void Renderer::draw() {
|
|||||||
const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(sz.width) / static_cast<float>(sz.height), 0.01f, 50.0f);
|
const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(sz.width) / static_cast<float>(sz.height), 0.01f, 50.0f);
|
||||||
|
|
||||||
uniform_buffer->upload(UniformData{
|
uniform_buffer->upload(UniformData{
|
||||||
//.mvp = p * glm::rotate(glm::mat4(1.0), glm::radians(static_cast<float>(frame)), glm::vec3(1.0, 1.0, 1.0)),
|
.mvp = p * glm::rotate(glm::mat4(1.0), glm::radians(static_cast<float>(frame)), glm::vec3(1.0, 1.0, 1.0)),
|
||||||
.time = static_cast<float>(frame) * 0.0167f,
|
.time = static_cast<float>(frame) * 0.0167f,
|
||||||
.aspect_ratio = static_cast<float>(sz.width)/static_cast<float>(sz.height),
|
.aspect_ratio = static_cast<float>(sz.width)/static_cast<float>(sz.height),
|
||||||
});
|
});
|
||||||
@ -331,6 +375,10 @@ Renderer::~Renderer() {
|
|||||||
vertex_buffer.reset();
|
vertex_buffer.reset();
|
||||||
pipeline.reset();
|
pipeline.reset();
|
||||||
|
|
||||||
|
for (auto& tex : textures) {
|
||||||
|
tex.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
swapchain.reset();
|
swapchain.reset();
|
||||||
|
|
||||||
dev.destroySemaphore(image_wait_semaphore);
|
dev.destroySemaphore(image_wait_semaphore);
|
||||||
|
|||||||
@ -12,18 +12,22 @@
|
|||||||
struct Window;
|
struct Window;
|
||||||
struct UniformBuffer;
|
struct UniformBuffer;
|
||||||
struct VertexBuffer;
|
struct VertexBuffer;
|
||||||
|
struct Texture;
|
||||||
|
|
||||||
/* Contains all of the Vulkan objects involved in rendering the scene */
|
/* Contains all of the Vulkan objects involved in rendering the scene */
|
||||||
struct Renderer {
|
struct Renderer {
|
||||||
Renderer(Window& win);
|
Renderer(Window& win);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
|
std::vector<Texture> createTextures(const std::vector<std::string>& names);
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
void present();
|
void present();
|
||||||
|
|
||||||
Window& win;
|
Window& win;
|
||||||
|
|
||||||
vk::Instance instance;
|
vk::Instance instance;
|
||||||
|
vk::PhysicalDevice phys_dev;
|
||||||
vk::Device dev;
|
vk::Device dev;
|
||||||
|
|
||||||
vk::Fence render_fence;
|
vk::Fence render_fence;
|
||||||
@ -42,6 +46,8 @@ struct Renderer {
|
|||||||
std::unique_ptr<VertexBuffer> vertex_buffer;
|
std::unique_ptr<VertexBuffer> vertex_buffer;
|
||||||
std::unique_ptr<UniformBuffer> uniform_buffer;
|
std::unique_ptr<UniformBuffer> uniform_buffer;
|
||||||
|
|
||||||
|
std::vector<Texture> textures;
|
||||||
|
|
||||||
uint32_t current_image_idx;
|
uint32_t current_image_idx;
|
||||||
uint64_t frame = 0;
|
uint64_t frame = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,32 +5,103 @@
|
|||||||
#include <Renderer/CommandBuffer.hpp>
|
#include <Renderer/CommandBuffer.hpp>
|
||||||
|
|
||||||
#include <util/file.hpp>
|
#include <util/file.hpp>
|
||||||
|
#include <util/log.hpp>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
/* externall synchonized, just writes to a command buffer, you still need to pull the trigger (allows bulk texture image preperation) */
|
||||||
|
Texture::Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer& command_buffer, const std::string& fname) : dev(dev) {
|
||||||
|
Log::debug("Starting texture creation for: %s\n", fname.c_str());
|
||||||
|
|
||||||
Texture::Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer command_buffer, const std::string& fname) {
|
|
||||||
int n_channels;
|
int n_channels;
|
||||||
vk::Extent3D extent;
|
vk::Extent3D extent;
|
||||||
|
|
||||||
auto image_data = stbi_load(fname.c_str(), reinterpret_cast<int*>(&extent.width), reinterpret_cast<int*>(&extent.height), &n_channels, STBI_rgb_alpha);
|
auto image_data = stbi_load(fname.c_str(), reinterpret_cast<int*>(&extent.width), reinterpret_cast<int*>(&extent.height), &n_channels, STBI_rgb_alpha);
|
||||||
extent.depth = 1;
|
extent.depth = 1;
|
||||||
|
|
||||||
image = std::make_unique<Image>(phys_dev, dev, extent, vk::Format::eR8G8B8A8Srgb,
|
image = std::make_unique<Image>(phys_dev, dev, extent, vk::Format::eR8G8B8A8Unorm,
|
||||||
vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eSampled,
|
vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
|
||||||
vk::DeviceSize sz = static_cast<vk::DeviceSize>(extent.width * extent.height) * sizeof(uint32_t);
|
vk::DeviceSize sz = static_cast<vk::DeviceSize>(extent.width * extent.height) * sizeof(uint32_t);
|
||||||
|
|
||||||
/* staging buffer to hold image data from the CPU */
|
/* staging buffer to hold image data from the CPU */
|
||||||
Buffer staging(phys_dev, dev, sz, vk::BufferUsageFlagBits::eTransferSrc,
|
staging = std::make_unique<Buffer>(phys_dev, dev, sz, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
|
||||||
staging.upload(image_data);
|
staging->upload(image_data);
|
||||||
stbi_image_free(image_data);
|
stbi_image_free(image_data);
|
||||||
|
|
||||||
command_buffer.copy(staging, *image);
|
/* pipeline memory barrier ensures this doesn't get reordered wrong */
|
||||||
|
|
||||||
/* TODO: Finish, also rethink if we want submission to happen internally or externally to the function for creation */
|
auto staging_buffer_trans_barrier = vk::ImageMemoryBarrier {
|
||||||
|
.srcAccessMask = vk::AccessFlagBits(0),
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eUndefined,
|
||||||
|
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.image = *image,
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange {
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* transfer optimal --> shader optimal */
|
||||||
|
auto shader_barrier = vk::ImageMemoryBarrier{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
|
||||||
|
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
|
.image = *image,
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange {
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
command_buffer.command_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlagBits(0), nullptr, nullptr, staging_buffer_trans_barrier);
|
||||||
|
command_buffer.copy(*staging, *image);
|
||||||
|
command_buffer.command_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, vk::DependencyFlagBits(0), nullptr, nullptr, shader_barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Texture::finishCreation() {
|
||||||
|
view = dev.createImageView(vk::ImageViewCreateInfo {
|
||||||
|
.image = *image,
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = vk::Format::eR8G8B8A8Unorm,
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
sampler = dev.createSampler(vk::SamplerCreateInfo {
|
||||||
|
.magFilter = vk::Filter::eLinear,
|
||||||
|
.minFilter = vk::Filter::eLinear,
|
||||||
|
.mipmapMode = vk::SamplerMipmapMode::eLinear,
|
||||||
|
.addressModeU = vk::SamplerAddressMode::eClampToEdge,
|
||||||
|
.addressModeV = vk::SamplerAddressMode::eClampToEdge,
|
||||||
|
.addressModeW = vk::SamplerAddressMode::eClampToEdge,
|
||||||
|
.mipLodBias = 0.0,
|
||||||
|
.anisotropyEnable = vk::False,
|
||||||
|
.maxAnisotropy = 0.0,
|
||||||
|
.compareEnable = vk::False,
|
||||||
|
.compareOp = vk::CompareOp::eAlways,
|
||||||
|
.minLod = 0.0,
|
||||||
|
.maxLod = 0.0,
|
||||||
|
.borderColor = vk::BorderColor::eIntOpaqueBlack,
|
||||||
|
.unnormalizedCoordinates = vk::False,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::cleanup() {
|
||||||
|
staging.reset();
|
||||||
|
image->cleanup();
|
||||||
|
dev.destroyImageView(view);
|
||||||
|
dev.destroySampler(sampler);
|
||||||
}
|
}
|
||||||
@ -7,8 +7,31 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
struct CommandBuffer;
|
struct CommandBuffer;
|
||||||
|
struct Buffer;
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
|
vk::Device dev;
|
||||||
std::unique_ptr<Image> image;
|
std::unique_ptr<Image> image;
|
||||||
Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer command_buffer, const std::string& fname);
|
vk::ImageView view;
|
||||||
|
vk::Sampler sampler;
|
||||||
|
|
||||||
|
std::unique_ptr<Buffer> staging;
|
||||||
|
|
||||||
|
Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer& command_buffer, const std::string& fname);
|
||||||
|
|
||||||
|
inline vk::DescriptorSetLayoutBinding binding(uint32_t binding, vk::ShaderStageFlags stages = vk::ShaderStageFlagBits::eAll) {
|
||||||
|
return vk::DescriptorSetLayoutBinding {
|
||||||
|
.binding = binding,
|
||||||
|
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
.pImmutableSamplers = nullptr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* seperates out steps that need to be taken *after* command buffer is submitted */
|
||||||
|
void finishCreation();
|
||||||
|
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
};
|
};
|
||||||
@ -8,6 +8,8 @@ layout (set = 0, binding = 0) uniform Matrices {
|
|||||||
float time;
|
float time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
FragColor = texture(tex, texCoord);
|
||||||
}
|
}
|
||||||
Binary file not shown.
@ -10,6 +10,6 @@ layout (set = 0, binding = 0) uniform Matrices {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(aPos, 1.0);
|
gl_Position = mpv*vec4(aPos, 1.0);
|
||||||
texCoord = aTexCoord;
|
texCoord = aTexCoord;
|
||||||
}
|
}
|
||||||
Binary file not shown.
Binary file not shown.
BIN
assets/textures/oil.jpg
Normal file
BIN
assets/textures/oil.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
@ -42,7 +42,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
ren.draw();
|
ren.draw();
|
||||||
ren.present();
|
ren.present();
|
||||||
Log::debug("Frame: %.2lf milliseconds (60fps ~ 16.67)\n", frame_timer.stop());
|
Log::debug("Frame: %.2lf milliseconds (60fps ~ 16.67)\r", frame_timer.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::string& e) {
|
} catch (const std::string& e) {
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace Log {
|
|||||||
return static_cast<MessageLevelBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
return static_cast<MessageLevelBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MessageLevelBit log_mask = ERROR | INFO;
|
static const MessageLevelBit log_mask = ERROR | INFO | DEBUG;
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
static void print(MessageLevelBit level, const std::string& fmt, Args... args) {
|
static void print(MessageLevelBit level, const std::string& fmt, Args... args) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user