self define descriptors
This commit is contained in:
parent
b6438c6779
commit
76bae46dbc
6 changed files with 166 additions and 113 deletions
0
engine/xe_input.cpp
Normal file
0
engine/xe_input.cpp
Normal file
15
engine/xe_input.hpp
Normal file
15
engine/xe_input.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "xe_window.hpp"
|
||||
|
||||
namespace xe {
|
||||
|
||||
class XeInput {
|
||||
|
||||
private:
|
||||
|
||||
XeWindow &xeWindow;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -19,19 +19,20 @@ namespace xe {
|
|||
XeRenderSystem::XeRenderSystem(
|
||||
XeEngine &xeEngine,
|
||||
std::string vert,
|
||||
std::string frag,
|
||||
uint32_t pushCunstantDataSize,
|
||||
uint32_t uniformBufferDataSize,
|
||||
XeImage *image
|
||||
std::string frag,
|
||||
std::map<uint32_t, uint32_t> uniformBindings,
|
||||
std::map<uint32_t, XeImage*> imageBindings,
|
||||
uint32_t pushCunstantDataSize
|
||||
) : xeDevice{xeEngine.xeDevice},
|
||||
xeRenderer{xeEngine.xeRenderer},
|
||||
xeDescriptorPool{xeEngine.xeDescriptorPool},
|
||||
pushCunstantDataSize{pushCunstantDataSize},
|
||||
uniformBufferDataSize{uniformBufferDataSize},
|
||||
textureSamplerBinding{image != nullptr} {
|
||||
uniformBindings{uniformBindings},
|
||||
imageBindings{imageBindings} {
|
||||
createTextureSampler();
|
||||
createDescriptorSetLayout();
|
||||
createUniformBuffers();
|
||||
createDescriptorSets(image);
|
||||
createDescriptorSets();
|
||||
createPipelineLayout();
|
||||
createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag);
|
||||
}
|
||||
|
@ -39,99 +40,96 @@ XeRenderSystem::XeRenderSystem(
|
|||
|
||||
XeRenderSystem::~XeRenderSystem() {
|
||||
vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr);
|
||||
if ( textureSamplerBinding ) {
|
||||
vkDestroySampler(xeDevice.device(), textureSampler, nullptr);
|
||||
}
|
||||
vkDestroySampler(xeDevice.device(), textureSampler, nullptr);
|
||||
};
|
||||
|
||||
void XeRenderSystem::createTextureSampler() {
|
||||
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.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(xeDevice.device(), &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create texture sampler!");
|
||||
}
|
||||
}
|
||||
|
||||
void XeRenderSystem::createDescriptorSetLayout() {
|
||||
XeDescriptorSetLayout::Builder builder{xeDevice};
|
||||
int binding = 0;
|
||||
|
||||
if (uniformBufferDataSize > 0) {
|
||||
|
||||
for ( const auto &[binding, size]: uniformBindings) {
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr);
|
||||
binding += 1;
|
||||
}
|
||||
if (textureSamplerBinding) {
|
||||
|
||||
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.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(xeDevice.device(), &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create texture sampler!");
|
||||
}
|
||||
|
||||
for ( const auto &[binding, image]: imageBindings) {
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &textureSampler);
|
||||
binding += 1;
|
||||
}
|
||||
|
||||
xeDescriptorSetLayout = builder.build();
|
||||
}
|
||||
|
||||
void XeRenderSystem::createUniformBuffers() {
|
||||
if(uniformBufferDataSize == 0) return;
|
||||
|
||||
uboBuffers = std::vector<std::unique_ptr<XeBuffer>>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||
for (int i = 0; i < uboBuffers.size(); i++) {
|
||||
uboBuffers[i] = std::make_unique<XeBuffer>(
|
||||
xeDevice,
|
||||
uniformBufferDataSize,
|
||||
XeSwapChain::MAX_FRAMES_IN_FLIGHT,
|
||||
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
uboBuffers[i]->map();
|
||||
for ( const auto &[binding, bufferSize]: uniformBindings) {
|
||||
uboBuffers[binding] = std::vector<std::unique_ptr<XeBuffer>>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||
for (int i = 0; i < uboBuffers[binding].size(); i++) {
|
||||
uboBuffers[binding][i] = std::make_unique<XeBuffer>(
|
||||
xeDevice,
|
||||
bufferSize,
|
||||
XeSwapChain::MAX_FRAMES_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
uboBuffers[binding][i]->map();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void XeRenderSystem::createDescriptorSets(XeImage *image) {
|
||||
void XeRenderSystem::createDescriptorSets() {
|
||||
|
||||
descriptorSets = std::vector<VkDescriptorSet>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||
for (int i = 0; i < descriptorSets.size(); i++) {
|
||||
updateDescriptorSet(image, i, true);
|
||||
updateDescriptorSet(i, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void XeRenderSystem::updateDescriptorSet(XeImage *image, int frameIndex, bool allocate) {
|
||||
auto bufferInfo = uboBuffers[frameIndex]->descriptorInfo();
|
||||
XeDescriptorWriter writer{*xeDescriptorSetLayout, *xeDescriptorPool};
|
||||
|
||||
int binding = 0;
|
||||
void XeRenderSystem::updateDescriptorSet(int frameIndex, bool allocate) {
|
||||
|
||||
if (uniformBufferDataSize > 0) {
|
||||
writer.writeBuffer(binding, &bufferInfo);
|
||||
binding += 1;
|
||||
}
|
||||
|
||||
if (textureSamplerBinding) {
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.imageView = image->textureImageView;
|
||||
imageInfo.sampler = textureSampler;
|
||||
writer.writeImage(binding, &imageInfo);
|
||||
binding += 1;
|
||||
}
|
||||
if (allocate) {
|
||||
writer.build(descriptorSets[frameIndex]);
|
||||
} else {
|
||||
writer.overwrite(descriptorSets[frameIndex]);
|
||||
}
|
||||
XeDescriptorWriter writer{*xeDescriptorSetLayout, *xeDescriptorPool};
|
||||
|
||||
std::vector<VkDescriptorBufferInfo> bufferInfos{};
|
||||
|
||||
int i = 0;
|
||||
for ( const auto &[binding, size]: uniformBindings) {
|
||||
bufferInfos.push_back(uboBuffers[binding][frameIndex]->descriptorInfo());
|
||||
writer.writeBuffer(binding, &bufferInfos[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
for ( const auto &[binding, image]: imageBindings) {
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.imageView = image->textureImageView;
|
||||
imageInfo.sampler = textureSampler;
|
||||
writer.writeImage(binding, &imageInfo);
|
||||
}
|
||||
|
||||
if (allocate) {
|
||||
writer.build(descriptorSets[frameIndex]);
|
||||
} else {
|
||||
writer.overwrite(descriptorSets[frameIndex]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -143,8 +141,12 @@ void XeRenderSystem::createPipelineLayout() {
|
|||
pushConstantRange.offset = 0;
|
||||
pushConstantRange.size = pushCunstantDataSize;
|
||||
|
||||
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{xeDescriptorSetLayout->getDescriptorSetLayout()};
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipelineLayoutInfo.setLayoutCount = static_cast<uint32_t>(descriptorSetLayouts.size());
|
||||
pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
|
||||
|
||||
if (pushCunstantDataSize > 0) {
|
||||
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||
|
@ -154,17 +156,6 @@ void XeRenderSystem::createPipelineLayout() {
|
|||
pipelineLayoutInfo.pPushConstantRanges = nullptr;
|
||||
}
|
||||
|
||||
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{xeDescriptorSetLayout->getDescriptorSetLayout()};
|
||||
|
||||
if (uniformBufferDataSize > 0) {
|
||||
pipelineLayoutInfo.setLayoutCount = static_cast<uint32_t>(descriptorSetLayouts.size());
|
||||
pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
|
||||
} else {
|
||||
|
||||
pipelineLayoutInfo.setLayoutCount = 0;
|
||||
pipelineLayoutInfo.pSetLayouts = nullptr;
|
||||
}
|
||||
|
||||
if(vkCreatePipelineLayout(xeDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
||||
std::runtime_error("failed to create pipeline layout!");
|
||||
}
|
||||
|
@ -215,12 +206,13 @@ void XeRenderSystem::loadPushConstant(void *pushConstantData) {
|
|||
pushConstantData);
|
||||
}
|
||||
|
||||
void XeRenderSystem::loadUniformObject(void *uniformBufferData) {
|
||||
uboBuffers[xeRenderer.getFrameIndex()]->writeToBuffer(uniformBufferData);
|
||||
void XeRenderSystem::loadUniformObject(uint32_t binding, void *uniformBufferData) {
|
||||
uboBuffers[binding][xeRenderer.getFrameIndex()]->writeToBuffer(uniformBufferData);
|
||||
}
|
||||
|
||||
void XeRenderSystem::loadTexture(XeImage *image) {
|
||||
updateDescriptorSet(image, xeRenderer.getFrameIndex(), false);
|
||||
void XeRenderSystem::loadTexture(uint32_t binding, XeImage *image) {
|
||||
imageBindings[binding] = image;
|
||||
updateDescriptorSet(xeRenderer.getFrameIndex(), false);
|
||||
}
|
||||
|
||||
void XeRenderSystem::render(XeGameObject &gameObject) {
|
||||
|
|
|
@ -10,19 +10,55 @@
|
|||
#include "xe_image.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace xe {
|
||||
|
||||
class XeRenderSystem {
|
||||
public:
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder(XeEngine &xeEngine, std::string vert, std::string frag) : xeEngine{xeEngine}, vert{vert}, frag{frag} {}
|
||||
|
||||
Builder& addPushConstant(uint32_t size) {
|
||||
pushCunstantDataSize = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& addUniformBinding(uint32_t binding, uint32_t size) {
|
||||
uniformBindings[binding] = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& addTextureBinding(uint32_t binding, XeImage* image) {
|
||||
imageBindings[binding] = image;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::unique_ptr<XeRenderSystem> build() {
|
||||
return std::make_unique<XeRenderSystem>(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(pushCunstantDataSize));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::map<uint32_t, uint32_t> uniformBindings{};
|
||||
std::map<uint32_t, XeImage*> imageBindings{};
|
||||
uint32_t pushCunstantDataSize{0};
|
||||
|
||||
std::string vert;
|
||||
std::string frag;
|
||||
|
||||
XeEngine &xeEngine;
|
||||
};
|
||||
|
||||
XeRenderSystem(
|
||||
XeEngine &xeEngine,
|
||||
std::string vert,
|
||||
std::string frag,
|
||||
uint32_t pushCunstantDataSize,
|
||||
uint32_t uniformBufferDataSize,
|
||||
XeImage *image
|
||||
std::string frag,
|
||||
std::map<uint32_t, uint32_t> uniformBindings,
|
||||
std::map<uint32_t, XeImage*> imageBindings,
|
||||
uint32_t pushCunstantDataSize
|
||||
);
|
||||
|
||||
~XeRenderSystem();
|
||||
|
@ -32,37 +68,39 @@ class XeRenderSystem {
|
|||
|
||||
void start();
|
||||
void loadPushConstant(void *pushConstantData);
|
||||
void loadUniformObject(void *uniformBufferData);
|
||||
void loadTexture(XeImage *image);
|
||||
void loadUniformObject(uint32_t binding, void *uniformBufferData);
|
||||
void loadTexture(uint32_t binding, XeImage *image);
|
||||
void render(XeGameObject &gameObject);
|
||||
void stop();
|
||||
|
||||
private:
|
||||
|
||||
void createTextureSampler();
|
||||
void createDescriptorSetLayout();
|
||||
void createUniformBuffers();
|
||||
void createDescriptorSets(XeImage *image);
|
||||
void updateDescriptorSet(XeImage *image, int frameIndex, bool allocate);
|
||||
void createDescriptorSets();
|
||||
void updateDescriptorSet(int frameIndex, bool allocate);
|
||||
void createPipelineLayout();
|
||||
void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag);
|
||||
|
||||
bool boundPipeline{false};
|
||||
bool boundDescriptor{false};
|
||||
|
||||
uint32_t uniformBufferDataSize;
|
||||
uint32_t pushCunstantDataSize;
|
||||
bool textureSamplerBinding;
|
||||
|
||||
|
||||
XeDevice& xeDevice;
|
||||
XeRenderer& xeRenderer;
|
||||
|
||||
std::unique_ptr<XePipeline> xePipeline;
|
||||
std::vector<std::unique_ptr<XeBuffer>> uboBuffers;
|
||||
std::map<uint32_t, std::vector<std::unique_ptr<XeBuffer>>> uboBuffers{};
|
||||
std::map<uint32_t, uint32_t> uniformBindings;
|
||||
std::map<uint32_t, XeImage*> imageBindings;
|
||||
std::vector<VkDescriptorSet> descriptorSets;
|
||||
|
||||
uint32_t pushCunstantDataSize;
|
||||
|
||||
VkSampler textureSampler;
|
||||
|
||||
VkPipelineLayout pipelineLayout;
|
||||
std::unique_ptr<XePipeline> xePipeline;
|
||||
std::unique_ptr<XeDescriptorPool> &xeDescriptorPool;
|
||||
std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout;
|
||||
|
||||
|
|
|
@ -1,29 +1,37 @@
|
|||
#include "simple_renderer.hpp"
|
||||
#include "xe_render_system.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace app {
|
||||
|
||||
SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine, xe::XeImage *xeImage)
|
||||
: xeRenderSystem{xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv", sizeof(PushConstant), sizeof(UniformBuffer), xeImage} {};
|
||||
SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine, xe::XeImage *xeImage) {
|
||||
xeRenderSystem = xe::XeRenderSystem::Builder(xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv")
|
||||
.addPushConstant(sizeof(PushConstant))
|
||||
.addUniformBinding(0, sizeof(UniformBuffer))
|
||||
.addTextureBinding(1, xeImage)
|
||||
.build();
|
||||
}
|
||||
|
||||
void SimpleRenderer::render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage) {
|
||||
|
||||
xeRenderSystem.loadTexture(xeImage);
|
||||
xeRenderSystem->loadTexture(1, xeImage);
|
||||
|
||||
xeRenderSystem.start();
|
||||
xeRenderSystem->start();
|
||||
|
||||
UniformBuffer ubo{};
|
||||
ubo.projectionView = xeCamera.getProjection() * xeCamera.getView();
|
||||
xeRenderSystem.loadUniformObject(&ubo);
|
||||
xeRenderSystem->loadUniformObject(0, &ubo);
|
||||
|
||||
for(auto &obj : gameObjects) {
|
||||
PushConstant pc{};
|
||||
pc.modelMatrix = obj.transform.mat4();
|
||||
pc.normalMatrix = obj.transform.normalMatrix();
|
||||
xeRenderSystem.loadPushConstant(&pc);
|
||||
xeRenderSystem.render(obj);
|
||||
xeRenderSystem->loadPushConstant(&pc);
|
||||
xeRenderSystem->render(obj);
|
||||
}
|
||||
|
||||
xeRenderSystem.stop();
|
||||
xeRenderSystem->stop();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ class SimpleRenderer {
|
|||
void render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage);
|
||||
|
||||
private:
|
||||
xe::XeRenderSystem xeRenderSystem;
|
||||
std::unique_ptr<xe::XeRenderSystem> xeRenderSystem;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue