mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Get descriptor sets working
This commit is contained in:
parent
2bb75f4683
commit
bbf582d85f
@ -7,6 +7,14 @@
|
||||
|
||||
namespace engine::gfx {
|
||||
|
||||
// handles (incomplete types)
|
||||
struct Pipeline;
|
||||
struct Buffer;
|
||||
struct Texture;
|
||||
struct DrawBuffer;
|
||||
struct DescriptorSetLayout;
|
||||
struct DescriptorSet;
|
||||
|
||||
enum class MSAALevel {
|
||||
MSAA_OFF,
|
||||
MSAA_2X,
|
||||
@ -86,10 +94,13 @@ namespace engine::gfx {
|
||||
std::vector<VertexAttribDescription> attributeDescriptions;
|
||||
};
|
||||
|
||||
// handles (incomplete types)
|
||||
struct Pipeline;
|
||||
struct Buffer;
|
||||
struct Texture;
|
||||
struct DrawBuffer;
|
||||
struct PipelineInfo {
|
||||
const char* vertShaderPath;
|
||||
const char* fragShaderPath;
|
||||
gfx::VertexFormat vertexFormat;
|
||||
bool alphaBlending;
|
||||
bool backfaceCulling;
|
||||
std::vector<const DescriptorSetLayout*> descriptorSetLayouts;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -26,15 +26,21 @@ namespace engine {
|
||||
void cmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer);
|
||||
void cmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer);
|
||||
void cmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
|
||||
//void cmdBindDescriptorSetTexture(gfx::CommandBuffer* commandBuffer, uint32_t set, uint32_t binding, const gfx::Texture* texture);
|
||||
//void cmdBindDescriptorSetBuffer(gfx::CommandBuffer* commandBuffer, uint32_t set, uint32_t binding, const gfx::Texture* texture);
|
||||
void cmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber);
|
||||
|
||||
// creates the equivalent of an OpenGL shader program & vertex attrib configuration
|
||||
gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize, bool alphaBlending, bool backfaceCulling);
|
||||
gfx::Pipeline* createPipeline(const gfx::PipelineInfo& info);
|
||||
void destroyPipeline(const gfx::Pipeline* pipeline);
|
||||
|
||||
gfx::DescriptorSetLayout* createDescriptorSetLayout();
|
||||
void destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout);
|
||||
|
||||
gfx::DescriptorSet* allocateDescriptorSet(const gfx::DescriptorSetLayout* layout);
|
||||
void updateDescriptor(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Buffer* buffer);
|
||||
|
||||
void updateUniformBuffer(const gfx::Pipeline* pipeline, const void* data, size_t size, uint32_t offset);
|
||||
|
||||
// Tries to create it on the GPU. Cannot be directly updated by the CPU.
|
||||
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data);
|
||||
void destroyBuffer(const gfx::Buffer* buffer);
|
||||
|
||||
|
@ -27,8 +27,13 @@ public:
|
||||
|
||||
const gfx::Pipeline* getPipeline();
|
||||
|
||||
const gfx::DescriptorSet* getSetZero() { return m_setZero; }
|
||||
|
||||
private:
|
||||
GFXDevice* const m_gfx;
|
||||
const gfx::DescriptorSetLayout* m_setZeroLayout;
|
||||
const gfx::DescriptorSet* m_setZero;
|
||||
const gfx::Buffer* m_setZeroBuffer;
|
||||
const gfx::Pipeline* m_pipeline;
|
||||
|
||||
};
|
||||
|
@ -1,9 +1,12 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 fragUV;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
vec3 baseColor = vec3(fragUV, 0.0);
|
||||
outColor = vec4(baseColor, 1.0);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,16 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 2) in vec2 inUV;
|
||||
|
||||
layout(location = 0) out vec2 fragUV;
|
||||
|
||||
layout(set = 0, binding = 0) uniform MyUniform {
|
||||
vec4 someValue;
|
||||
} myUniform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(inPosition, 1.0);
|
||||
fragUV = inUV * myUniform.someValue.xy;
|
||||
}
|
||||
|
@ -83,6 +83,14 @@ namespace engine {
|
||||
uint32_t imageIndex; // for swapchain present
|
||||
};
|
||||
|
||||
struct gfx::DescriptorSetLayout {
|
||||
VkDescriptorSetLayout layout;
|
||||
};
|
||||
|
||||
struct gfx::DescriptorSet {
|
||||
VkDescriptorSet set;
|
||||
};
|
||||
|
||||
// enum converters
|
||||
|
||||
namespace vkinternal {
|
||||
@ -107,6 +115,8 @@ namespace engine {
|
||||
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
case gfx::BufferType::INDEX:
|
||||
return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
case gfx::BufferType::UNIFORM:
|
||||
return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
default:
|
||||
throw std::runtime_error("This buffer type does not have usage bits");
|
||||
}
|
||||
@ -170,7 +180,7 @@ namespace engine {
|
||||
throw std::runtime_error("PREPROCESS ERR " + preprocessed.GetErrorMessage());
|
||||
}
|
||||
|
||||
std::string shaderStr{preprocessed.cbegin(), preprocessed.cend()};
|
||||
std::string shaderStr{ preprocessed.cbegin(), preprocessed.cend() };
|
||||
|
||||
// compile
|
||||
shaderc::SpvCompilationResult compiledShader = compiler.CompileGlslToSpv(shaderStr.c_str(), kind, filename, options);
|
||||
@ -541,6 +551,8 @@ namespace engine {
|
||||
SwapchainInfo swapchainInfo{};
|
||||
Swapchain swapchain{};
|
||||
|
||||
VkDescriptorPool descriptorPool;
|
||||
|
||||
uint64_t FRAMECOUNT = 0;
|
||||
|
||||
FrameData frameData[FRAMES_IN_FLIGHT] = {};
|
||||
@ -600,7 +612,7 @@ namespace engine {
|
||||
pimpl->swapchainInfo.waitForPresent = pimpl->graphicsSettings.waitForPresent;
|
||||
createSwapchain(&pimpl->swapchain, pimpl->swapchainInfo);
|
||||
|
||||
/* the following is temporary setup */
|
||||
/* make synchronisation primitives for rendering and allocate command buffers */
|
||||
|
||||
for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||
VkFenceCreateInfo fenceInfo{
|
||||
@ -631,10 +643,27 @@ namespace engine {
|
||||
VKCHECK(vkAllocateCommandBuffers(pimpl->device.device, &cmdAllocInfo, &pimpl->frameData[i].drawBuf));
|
||||
}
|
||||
|
||||
/* create a global descriptor pool */
|
||||
|
||||
std::vector<VkDescriptorPoolSize> poolSizes{};
|
||||
poolSizes.emplace_back(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 5); // purposely low limit
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
};
|
||||
descriptorPoolInfo.flags = 0;
|
||||
descriptorPoolInfo.maxSets = 5; // purposely low limit
|
||||
descriptorPoolInfo.poolSizeCount = poolSizes.size();
|
||||
descriptorPoolInfo.pPoolSizes = poolSizes.data();
|
||||
VKCHECK(vkCreateDescriptorPool(pimpl->device.device, &descriptorPoolInfo, nullptr, &pimpl->descriptorPool));
|
||||
|
||||
}
|
||||
|
||||
GFXDevice::~GFXDevice()
|
||||
{
|
||||
vkDestroyDescriptorPool(pimpl->device.device, pimpl->descriptorPool, nullptr);
|
||||
|
||||
for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||
vkFreeCommandBuffers(pimpl->device.device, pimpl->device.commandPools.draw, 1, &pimpl->frameData[i].drawBuf);
|
||||
vkDestroySemaphore(pimpl->device.device, pimpl->frameData[i].renderSemaphore, nullptr);
|
||||
@ -649,7 +678,7 @@ namespace engine {
|
||||
destroyVulkanInstance(pimpl->instance);
|
||||
}
|
||||
|
||||
void GFXDevice::getViewportSize(uint32_t *w, uint32_t *h)
|
||||
void GFXDevice::getViewportSize(uint32_t* w, uint32_t* h)
|
||||
{
|
||||
int width, height;
|
||||
SDL_Vulkan_GetDrawableSize(pimpl->window, &width, &height);
|
||||
@ -833,28 +862,33 @@ namespace engine {
|
||||
vkCmdDrawIndexed(drawBuffer->frameData.drawBuf, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
|
||||
}
|
||||
|
||||
gfx::Pipeline* GFXDevice::createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize, bool alphaBlending, bool backfaceCulling)
|
||||
void GFXDevice::cmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber)
|
||||
{
|
||||
vkCmdBindDescriptorSets(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->layout, setNumber, 1, &set->set, 0, nullptr);
|
||||
}
|
||||
|
||||
gfx::Pipeline* GFXDevice::createPipeline(const gfx::PipelineInfo& info)
|
||||
{
|
||||
|
||||
[[maybe_unused]] VkResult res;
|
||||
|
||||
gfx::Pipeline* pipeline = new gfx::Pipeline;
|
||||
|
||||
auto vertShaderCode = util::readTextFile(vertShaderPath);
|
||||
auto fragShaderCode = util::readTextFile(fragShaderPath);
|
||||
auto vertShaderCode = util::readTextFile(info.vertShaderPath);
|
||||
auto fragShaderCode = util::readTextFile(info.fragShaderPath);
|
||||
|
||||
VkShaderModule vertShaderModule = compileShader(pimpl->device.device, shaderc_vertex_shader, vertShaderCode->data(), vertShaderPath);
|
||||
VkShaderModule fragShaderModule = compileShader(pimpl->device.device, shaderc_fragment_shader, fragShaderCode->data(), fragShaderPath);
|
||||
VkShaderModule vertShaderModule = compileShader(pimpl->device.device, shaderc_vertex_shader, vertShaderCode->data(), info.vertShaderPath);
|
||||
VkShaderModule fragShaderModule = compileShader(pimpl->device.device, shaderc_fragment_shader, fragShaderCode->data(), info.fragShaderPath);
|
||||
|
||||
// get vertex attrib layout:
|
||||
VkVertexInputBindingDescription bindingDescription{ };
|
||||
bindingDescription.binding = 0;
|
||||
bindingDescription.stride = vertexFormat.stride;
|
||||
bindingDescription.stride = info.vertexFormat.stride;
|
||||
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
std::vector<VkVertexInputAttributeDescription> attribDescs{};
|
||||
attribDescs.reserve(vertexFormat.attributeDescriptions.size());
|
||||
for (const auto& desc : vertexFormat.attributeDescriptions) {
|
||||
attribDescs.reserve(info.vertexFormat.attributeDescriptions.size());
|
||||
for (const auto& desc : info.vertexFormat.attributeDescriptions) {
|
||||
VkVertexInputAttributeDescription vulkanAttribDesc{};
|
||||
vulkanAttribDesc.binding = 0;
|
||||
vulkanAttribDesc.location = desc.location;
|
||||
@ -928,7 +962,7 @@ namespace engine {
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
if (backfaceCulling == true) {
|
||||
if (info.backfaceCulling == true) {
|
||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
}
|
||||
else {
|
||||
@ -955,7 +989,7 @@ namespace engine {
|
||||
VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT |
|
||||
VK_COLOR_COMPONENT_A_BIT;
|
||||
if (alphaBlending) {
|
||||
if (info.alphaBlending) {
|
||||
colorBlendAttachment.blendEnable = VK_TRUE;
|
||||
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
@ -996,10 +1030,15 @@ namespace engine {
|
||||
pushConstantRange.size = PUSH_CONSTANT_MAX_SIZE;
|
||||
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
std::vector<VkDescriptorSetLayout> descriptorSetLayouts(info.descriptorSetLayouts.size());
|
||||
for (size_t i = 0; i < descriptorSetLayouts.size(); i++) {
|
||||
descriptorSetLayouts[i] = info.descriptorSetLayouts[i]->layout;
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo layoutInfo{};
|
||||
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layoutInfo.setLayoutCount = 0;
|
||||
layoutInfo.pSetLayouts = nullptr;
|
||||
layoutInfo.setLayoutCount = descriptorSetLayouts.size();
|
||||
layoutInfo.pSetLayouts = descriptorSetLayouts.data();
|
||||
layoutInfo.pushConstantRangeCount = 1;
|
||||
layoutInfo.pPushConstantRanges = &pushConstantRange;
|
||||
|
||||
@ -1036,13 +1075,84 @@ namespace engine {
|
||||
|
||||
void GFXDevice::destroyPipeline(const gfx::Pipeline* pipeline)
|
||||
{
|
||||
|
||||
vkDestroyPipeline(pimpl->device.device, pipeline->handle, nullptr);
|
||||
vkDestroyPipelineLayout(pimpl->device.device, pipeline->layout, nullptr);
|
||||
|
||||
delete pipeline;
|
||||
}
|
||||
|
||||
gfx::DescriptorSetLayout* GFXDevice::createDescriptorSetLayout()
|
||||
{
|
||||
gfx::DescriptorSetLayout* out = new gfx::DescriptorSetLayout{};
|
||||
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings{};
|
||||
bindings.push_back({});
|
||||
bindings[0].binding = 0; // This should be as low as possible to avoid wasting memory
|
||||
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[0].descriptorCount = 1; // if > 1, accessible as an array in the shader
|
||||
bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // only accessible in vertex
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo info{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.pNext = nullptr
|
||||
};
|
||||
info.flags = 0;
|
||||
info.bindingCount = bindings.size();
|
||||
info.pBindings = bindings.data();
|
||||
VKCHECK(vkCreateDescriptorSetLayout(pimpl->device.device, &info, nullptr, &out->layout));
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void GFXDevice::destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout)
|
||||
{
|
||||
vkDestroyDescriptorSetLayout(pimpl->device.device, layout->layout, nullptr);
|
||||
delete layout;
|
||||
}
|
||||
|
||||
gfx::DescriptorSet* GFXDevice::allocateDescriptorSet(const gfx::DescriptorSetLayout* layout)
|
||||
{
|
||||
gfx::DescriptorSet* set = new gfx::DescriptorSet{};
|
||||
|
||||
VkDescriptorSetAllocateInfo allocInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.descriptorPool = pimpl->descriptorPool,
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = &layout->layout
|
||||
};
|
||||
|
||||
VkResult res;
|
||||
res = vkAllocateDescriptorSets(pimpl->device.device, &allocInfo, &set->set);
|
||||
if (res == VK_ERROR_FRAGMENTED_POOL) throw std::runtime_error("Descriptor pool is fragmented!");
|
||||
if (res == VK_ERROR_OUT_OF_POOL_MEMORY) throw std::runtime_error("Descriptor pool is out of memory!");
|
||||
VKCHECK(res);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
void GFXDevice::updateDescriptor(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Buffer* buffer)
|
||||
{
|
||||
VkDescriptorBufferInfo bufferInfo{
|
||||
.buffer = buffer->buffer,
|
||||
.offset = 0,
|
||||
.range = VK_WHOLE_SIZE
|
||||
};
|
||||
VkWriteDescriptorSet descriptorWrite{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = set->set,
|
||||
.dstBinding = binding,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.pImageInfo = nullptr,
|
||||
.pBufferInfo = &bufferInfo,
|
||||
.pTexelBufferView = nullptr
|
||||
};
|
||||
vkUpdateDescriptorSets(pimpl->device.device, 1, &descriptorWrite, 0, nullptr);
|
||||
}
|
||||
|
||||
void GFXDevice::updateUniformBuffer(const gfx::Pipeline* pipeline, const void* data, size_t size, uint32_t offset)
|
||||
{
|
||||
|
||||
@ -1149,8 +1259,9 @@ namespace engine {
|
||||
|
||||
if (mipmapSetting == gfx::MipmapSetting::OFF) {
|
||||
out->mipLevels = 1;
|
||||
} else {
|
||||
out->mipLevels = static_cast<uint32_t>(std::floor(std::log2( std::max(width, height) ))) + 1;
|
||||
}
|
||||
else {
|
||||
out->mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
||||
}
|
||||
|
||||
// first load image into staging buffer
|
||||
@ -1268,7 +1379,8 @@ namespace engine {
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
if (useAnisotropy) {
|
||||
samplerInfo.anisotropyEnable = VK_TRUE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
}
|
||||
samplerInfo.maxAnisotropy = pimpl->maxSamplerAnisotropy;
|
||||
@ -1278,7 +1390,8 @@ namespace engine {
|
||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
if (mipmapSetting == gfx::MipmapSetting::LINEAR) {
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
}
|
||||
samplerInfo.minLod = 0.0f;
|
||||
|
@ -11,6 +11,9 @@ namespace engine::resources {
|
||||
Shader::Shader(GFXDevice* gfx, const char* vertPath, const char* fragPath, const VertexParams& vertexParams, bool alphaBlending, bool cullBackFace)
|
||||
: m_gfx(gfx)
|
||||
{
|
||||
|
||||
m_setZeroLayout = m_gfx->createDescriptorSetLayout();
|
||||
|
||||
uint32_t index = 0;
|
||||
uint32_t stride = 0;
|
||||
gfx::VertexFormat vertFormat{};
|
||||
@ -36,14 +39,32 @@ namespace engine::resources {
|
||||
}
|
||||
vertFormat.stride = stride;
|
||||
|
||||
m_pipeline = m_gfx->createPipeline(vertPath, fragPath, vertFormat, sizeof(glm::mat4) * 2, alphaBlending, cullBackFace);
|
||||
gfx::PipelineInfo info{};
|
||||
info.vertShaderPath = vertPath;
|
||||
info.fragShaderPath = fragPath;
|
||||
info.vertexFormat = vertFormat;
|
||||
info.alphaBlending = alphaBlending;
|
||||
info.backfaceCulling = cullBackFace;
|
||||
info.descriptorSetLayouts.push_back(m_setZeroLayout);
|
||||
|
||||
m_pipeline = m_gfx->createPipeline(info);
|
||||
|
||||
LOG_INFO("Loaded shader: {}, vertex attribs: {}", vertPath, vertFormat.attributeDescriptions.size());
|
||||
|
||||
/* allocate uniform descriptor set */
|
||||
m_setZero = m_gfx->allocateDescriptorSet(m_setZeroLayout);
|
||||
/* fill with data */
|
||||
glm::vec4 myValue = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
m_setZeroBuffer = m_gfx->createBuffer(gfx::BufferType::UNIFORM, sizeof(glm::vec4), &myValue);
|
||||
m_gfx->updateDescriptor(m_setZero, 0, m_setZeroBuffer);
|
||||
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
m_gfx->destroyBuffer(m_setZeroBuffer);
|
||||
m_gfx->destroyPipeline(m_pipeline);
|
||||
m_gfx->destroyDescriptorSetLayout(m_setZeroLayout);
|
||||
}
|
||||
|
||||
const gfx::Pipeline* Shader::getPipeline()
|
||||
|
@ -78,6 +78,7 @@ namespace engine {
|
||||
pushConsts.view = viewMatrix;
|
||||
|
||||
gfx->cmdBindPipeline(drawBuffer, r->material->getShader()->getPipeline());
|
||||
gfx->cmdBindDescriptorSet(drawBuffer, r->material->getShader()->getPipeline(), r->material->getShader()->getSetZero(), 0);
|
||||
gfx->cmdBindVertexBuffer(drawBuffer, 0, r->mesh->getVB());
|
||||
gfx->cmdBindIndexBuffer(drawBuffer, r->mesh->getIB());
|
||||
gfx->cmdDrawIndexed(drawBuffer, r->mesh->getCount(), 1, 0, 0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user