render targeting random texture
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
// #define VALIDATION_LAYERS_ENABLED 1
|
||||
#define VALIDATION_LAYERS_ENABLED 1
|
||||
#ifdef VALIDATION_LAYERS_ENABLED
|
||||
const std::vector<const char*> VALIDATION_LAYERS = {
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "rendertarget.hpp"
|
||||
|
||||
#include "device.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
#include "yolo/yolo.hpp"
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
RenderTarget* rendertarget_create(
|
||||
GraphicsDevice* device, VkExtent2D extent, VkFormat format)
|
||||
{
|
||||
RenderTarget* target = new RenderTarget();
|
||||
target->Device = device;
|
||||
target->Format = format;
|
||||
target->Extent = extent;
|
||||
|
||||
VkSamplerCreateInfo samplerInfo {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
samplerInfo.maxAnisotropy = 1.0f;
|
||||
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
samplerInfo.compareEnable = VK_FALSE;
|
||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.mipLodBias = 0.0f;
|
||||
samplerInfo.minLod = 0.0f;
|
||||
samplerInfo.maxLod = 0.0f;
|
||||
|
||||
if (vkCreateSampler(device->VulkanDevice, &samplerInfo, nullptr, &target->Sampler)
|
||||
!= VK_SUCCESS) {
|
||||
yolo::error("failed to create texture sampler!");
|
||||
}
|
||||
|
||||
create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory);
|
||||
|
||||
target->ImageView
|
||||
= create_image_view(device, target->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(
|
||||
target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void rendertarget_cleanup(RenderTarget* target)
|
||||
{
|
||||
vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr);
|
||||
|
||||
rendertarget_destroy_depth(target);
|
||||
|
||||
delete target;
|
||||
}
|
||||
|
||||
void rendertarget_create_depth(RenderTarget* target)
|
||||
{
|
||||
VkFormat depthFormat = find_depth_format(target->Device);
|
||||
target->DepthFormat = depthFormat;
|
||||
|
||||
create_image(target->Device, target->Extent.width, target->Extent.height, depthFormat,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->DepthImage.value(),
|
||||
target->DepthMemory.value());
|
||||
|
||||
target->DepthImageView = create_image_view(target->Device, target->DepthImage.value(),
|
||||
depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
}
|
||||
|
||||
void rendertarget_destroy_depth(RenderTarget* target)
|
||||
{
|
||||
if (target->DepthImageView.has_value()) {
|
||||
vkDestroyImageView(
|
||||
target->Device->VulkanDevice, target->DepthImageView.value(), nullptr);
|
||||
}
|
||||
if (target->DepthImage.has_value()) {
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->DepthImage.value(), nullptr);
|
||||
}
|
||||
if (target->DepthMemory.has_value()) {
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->DepthMemory.value(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat format)
|
||||
{
|
||||
vkDeviceWaitIdle(target->Device->VulkanDevice);
|
||||
|
||||
bool doDepth = target->DepthImage.has_value();
|
||||
|
||||
rendertarget_cleanup(target);
|
||||
|
||||
target->Extent = extent;
|
||||
target->Format = format;
|
||||
|
||||
if (doDepth)
|
||||
rendertarget_create_depth(target);
|
||||
|
||||
create_image(target->Device, extent.width, extent.height, format,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory);
|
||||
|
||||
target->ImageView = create_image_view(
|
||||
target->Device, target->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,13 @@ typedef struct RenderTarget {
|
||||
std::optional<VkImageView> DepthImageView;
|
||||
|
||||
VkFormat Format;
|
||||
VkFormat DepthFormat;
|
||||
VkExtent2D Extent;
|
||||
|
||||
// NOTE: This is for the ImGui renderer.. it needs a descriptor set of a sampler of an image
|
||||
VkSampler Sampler;
|
||||
VkDescriptorSet DescriptorSet;
|
||||
|
||||
GraphicsDevice* Device;
|
||||
} RenderTarget;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "device.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include "pipeline.hpp"
|
||||
#include "rendertarget.hpp"
|
||||
#include "swapchain.hpp"
|
||||
|
||||
#include "gui/gui.hpp"
|
||||
@@ -196,7 +197,62 @@ bool renderer_begin_frame(VulkanRenderer* renderer)
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderer_begin_pass(VulkanRenderer* renderer, VkRect2D renderArea, bool depth)
|
||||
void renderer_begin_pass(
|
||||
VulkanRenderer* renderer, RenderTarget* target, VkRect2D renderArea)
|
||||
{
|
||||
VkImageMemoryBarrier imageMemoryBarrier {};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.image = target->Image;
|
||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
|
||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
|
||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCmdPipelineBarrier(renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex],
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
|
||||
|
||||
VkClearValue clearColor = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
VkRenderingAttachmentInfo attachmentInfo {};
|
||||
attachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||
attachmentInfo.imageView = target->ImageView;
|
||||
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachmentInfo.clearValue = clearColor;
|
||||
|
||||
VkRenderingAttachmentInfo depthAttachmentInfo;
|
||||
if (target->DepthImage.has_value()) {
|
||||
depthAttachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||
depthAttachmentInfo.imageView = target->DepthImageView.value();
|
||||
depthAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
depthAttachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
depthAttachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depthAttachmentInfo.clearValue.depthStencil = { 1.0f, 0 };
|
||||
depthAttachmentInfo.resolveMode = VK_RESOLVE_MODE_NONE;
|
||||
depthAttachmentInfo.resolveImageView = VK_NULL_HANDLE;
|
||||
depthAttachmentInfo.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
depthAttachmentInfo.pNext = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
VkRenderingInfo renderingInfo {};
|
||||
renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR;
|
||||
renderingInfo.renderArea = renderArea;
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &attachmentInfo;
|
||||
if (target->DepthImage.has_value())
|
||||
renderingInfo.pDepthAttachment = &depthAttachmentInfo;
|
||||
|
||||
vkCmdBeginRendering(
|
||||
renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex], &renderingInfo);
|
||||
}
|
||||
|
||||
void renderer_begin_pass(VulkanRenderer* renderer, VkRect2D renderArea)
|
||||
{
|
||||
VkImageMemoryBarrier imageMemoryBarrier {};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
@@ -241,8 +297,7 @@ void renderer_begin_pass(VulkanRenderer* renderer, VkRect2D renderArea, bool dep
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &attachmentInfo;
|
||||
if (depth)
|
||||
renderingInfo.pDepthAttachment = &depthAttachmentInfo;
|
||||
renderingInfo.pDepthAttachment = &depthAttachmentInfo;
|
||||
|
||||
vkCmdBeginRendering(
|
||||
renderer->CommandBuffersInFlight[renderer->CurrentFrameIndex], &renderingInfo);
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
#include "graphics.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
struct GraphicsDevice;
|
||||
struct Pipeline;
|
||||
struct SwapChain;
|
||||
struct RenderPass;
|
||||
struct RenderTarget;
|
||||
struct GenBuffer;
|
||||
struct Shader;
|
||||
|
||||
@@ -65,7 +65,11 @@ void renderer_submit_now(VulkanRenderer* renderer,
|
||||
|
||||
bool renderer_begin_frame(VulkanRenderer* renderer);
|
||||
|
||||
void renderer_begin_pass(VulkanRenderer* renderer, VkRect2D renderArea, bool depth = true);
|
||||
void renderer_begin_pass(VulkanRenderer* renderer, RenderTarget* target,
|
||||
VkRect2D renderArea);
|
||||
// this is for rendering to the swapchain / present image
|
||||
void renderer_begin_pass(VulkanRenderer* renderer, VkRect2D renderArea);
|
||||
|
||||
void renderer_end_pass(VulkanRenderer* renderer);
|
||||
|
||||
bool renderer_draw_frame(VulkanRenderer* renderer);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <graphics.hpp>
|
||||
#include <version.hpp>
|
||||
|
||||
#include "graphics/rendertarget.hpp"
|
||||
#include "gui/gui.hpp"
|
||||
// #include "renderer/renderer.hpp"
|
||||
// #include "scene/scene.hpp"
|
||||
@@ -95,9 +96,13 @@ InfernoApp* inferno_create()
|
||||
graphics::window_create("Inferno v" INFERNO_VERSION, 1920, 1080);
|
||||
app->Device = graphics::device_create();
|
||||
app->Renderer = graphics::renderer_create(app->Device);
|
||||
|
||||
graphics::renderer_configure_command_buffer(app->Renderer);
|
||||
graphics::renderer_configure_gui(app->Renderer);
|
||||
|
||||
app->PreviewTarget = graphics::rendertarget_create(
|
||||
app->Device, { 1920, 1080 }, VK_FORMAT_R8G8B8A8_UNORM);
|
||||
|
||||
graphics::renderer_submit_repeat(
|
||||
app->Renderer,
|
||||
[](graphics::VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) {
|
||||
@@ -106,11 +111,10 @@ InfernoApp* inferno_create()
|
||||
false);
|
||||
graphics::renderer_submit_repeat(
|
||||
app->Renderer,
|
||||
[](graphics::VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) {
|
||||
[&](graphics::VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) {
|
||||
graphics::renderer_begin_pass(renderer,
|
||||
{ 0, 0, (uint32_t)graphics::window_get_size().x,
|
||||
(uint32_t)graphics::window_get_size().y },
|
||||
false);
|
||||
(uint32_t)graphics::window_get_size().y });
|
||||
gui::imgui_render_frame(*commandBuffer);
|
||||
graphics::renderer_end_pass(renderer);
|
||||
},
|
||||
@@ -321,10 +325,10 @@ int inferno_run(InfernoApp* app)
|
||||
{ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
|
||||
// graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera);
|
||||
{
|
||||
graphics::renderer_begin_pass(app->Renderer,
|
||||
graphics::renderer_begin_pass(app->Renderer, app->PreviewTarget,
|
||||
{ 0, 0, (uint32_t)ImGui::GetWindowSize().x,
|
||||
(uint32_t)ImGui::GetWindowSize().y },
|
||||
false);
|
||||
(uint32_t)ImGui::GetWindowSize().y });
|
||||
|
||||
graphics::shader_use(app->Shader, commandBuffer);
|
||||
scene::GlobalUniformObject globalUniformObject {
|
||||
.Projection = graphics::camera_get_projection(app->Scene->Camera),
|
||||
@@ -347,12 +351,9 @@ int inferno_run(InfernoApp* app)
|
||||
graphics::renderer_end_pass(app->Renderer);
|
||||
}
|
||||
|
||||
// ImTextureID texture = (ImTextureID)graphics::preview_get_rendered_texture(
|
||||
// app->PreviewRenderer);
|
||||
// ImGui::Image(texture, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y
|
||||
// },
|
||||
// ImVec2(0, 1), ImVec2(1, 0));
|
||||
|
||||
ImTextureID texture = (ImTextureID)app->PreviewTarget->DescriptorSet;
|
||||
ImGui::Image(texture, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
|
||||
ImVec2(0, 1), ImVec2(1, 0));
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace graphics {
|
||||
struct Camera;
|
||||
struct GraphicsDevice;
|
||||
struct VulkanRenderer;
|
||||
struct RenderTarget;
|
||||
struct Buffer;
|
||||
struct Shader;
|
||||
}
|
||||
@@ -55,6 +56,7 @@ typedef struct InfernoApp {
|
||||
InfernoInput* Input;
|
||||
scene::Scene* Scene;
|
||||
|
||||
graphics::RenderTarget* PreviewTarget;
|
||||
graphics::Buffer* VBuffer;
|
||||
graphics::Buffer* IBuffer;
|
||||
graphics::Shader* Shader;
|
||||
|
||||
Reference in New Issue
Block a user