mirror of
https://github.com/love2d/love.git
synced 2026-08-14 10:13:46 +02:00
vulkan: default renderpass and framebuffers
Since these objects basically get used every frame we shouldn't store them in a hashmap with potentially worse performance. Instead storing them in member variables should be better.
This commit is contained in:
@@ -21,15 +21,6 @@
|
||||
namespace love {
|
||||
namespace graphics {
|
||||
namespace vulkan {
|
||||
static VkIndexType getVulkanIndexBufferType(IndexDataType type) {
|
||||
switch (type) {
|
||||
case INDEX_UINT16: return VK_INDEX_TYPE_UINT16;
|
||||
case INDEX_UINT32: return VK_INDEX_TYPE_UINT32;
|
||||
default:
|
||||
throw love::Exception("unknown Index Data type");
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<const char*> validationLayers = {
|
||||
"VK_LAYER_KHRONOS_validation"
|
||||
};
|
||||
@@ -236,6 +227,8 @@ bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int
|
||||
createSyncObjects();
|
||||
createColorResources();
|
||||
createDepthResources();
|
||||
createDefaultRenderPass();
|
||||
createDefaultFramebuffers();
|
||||
createCommandPool();
|
||||
createCommandBuffers();
|
||||
startRecordingGraphicsCommands();
|
||||
@@ -408,7 +401,7 @@ void Graphics::draw(const DrawCommand& cmd) {
|
||||
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
||||
prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
|
||||
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType));
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), Vulkan::getVulkanIndexBufferType(cmd.indexType));
|
||||
vkCmdDrawIndexed(commandBuffers.at(currentFrame), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -418,7 +411,7 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes& attribute
|
||||
|
||||
prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES, CULL_BACK);
|
||||
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)quadIndexBuffer->getHandle(), 0, Vulkan::getVulkanIndexBufferType(INDEX_UINT16));
|
||||
|
||||
int baseVertex = start * 4;
|
||||
|
||||
@@ -431,6 +424,8 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes& attribute
|
||||
}
|
||||
|
||||
void Graphics::setColor(Colorf c) {
|
||||
flushBatchedDraws();
|
||||
|
||||
c.r = std::min(std::max(c.r, 0.0f), 1.0f);
|
||||
c.g = std::min(std::max(c.g, 0.0f), 1.0f);
|
||||
c.b = std::min(std::max(c.b, 0.0f), 1.0f);
|
||||
@@ -1249,6 +1244,25 @@ void Graphics::createImageViews() {
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::createDefaultRenderPass() {
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
renderPassConfiguration.frameBufferFormat = swapChainImageFormat;
|
||||
defaultRenderPass = createRenderPass(renderPassConfiguration);
|
||||
}
|
||||
|
||||
void Graphics::createDefaultFramebuffers() {
|
||||
defaultFramebuffers.clear();
|
||||
|
||||
for (const auto view : swapChainImageViews) {
|
||||
FramebufferConfiguration configuration{};
|
||||
configuration.renderPass = defaultRenderPass;
|
||||
configuration.width = swapChainExtent.width;
|
||||
configuration.height = swapChainExtent.height;
|
||||
configuration.imageView = view;
|
||||
defaultFramebuffers.push_back(createFramebuffer(configuration));
|
||||
}
|
||||
}
|
||||
|
||||
VkFramebuffer Graphics::createFramebuffer(FramebufferConfiguration configuration) {
|
||||
std::array<VkImageView, 3> attachments = {
|
||||
colorImageView,
|
||||
@@ -1494,41 +1508,39 @@ void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindi
|
||||
}
|
||||
|
||||
void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) {
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
|
||||
if (texture) {
|
||||
renderPassConfiguration.frameBufferFormat = Vulkan::getTextureFormat(texture->getPixelFormat()).internalFormat;
|
||||
renderTargetTexture = texture;
|
||||
} else {
|
||||
renderPassConfiguration.frameBufferFormat = swapChainImageFormat;
|
||||
renderTargetTexture = nullptr;
|
||||
}
|
||||
|
||||
VkRenderPass renderPass;
|
||||
VkFramebuffer framebuffer;
|
||||
|
||||
auto it = renderPasses.find(renderPassConfiguration);
|
||||
if (it != renderPasses.end()) {
|
||||
renderPass = it->second;
|
||||
} else {
|
||||
renderPass = createRenderPass(renderPassConfiguration);
|
||||
renderPasses[renderPassConfiguration] = renderPass;
|
||||
}
|
||||
if (texture == nullptr) {
|
||||
renderTargetTexture = nullptr;
|
||||
renderPass = defaultRenderPass;
|
||||
framebuffer = defaultFramebuffers[imageIndex];
|
||||
} else {
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
|
||||
FramebufferConfiguration configuration{};
|
||||
configuration.renderPass = renderPass;
|
||||
if (renderTargetTexture == nullptr) {
|
||||
configuration.imageView = swapChainImageViews.at(imageIndex);
|
||||
}
|
||||
else {
|
||||
renderPassConfiguration.frameBufferFormat = Vulkan::getTextureFormat(texture->getPixelFormat()).internalFormat;
|
||||
renderTargetTexture = texture;
|
||||
|
||||
auto it = renderPasses.find(renderPassConfiguration);
|
||||
if (it != renderPasses.end()) {
|
||||
renderPass = it->second;
|
||||
} else {
|
||||
renderPass = createRenderPass(renderPassConfiguration);
|
||||
renderPasses[renderPassConfiguration] = renderPass;
|
||||
}
|
||||
|
||||
FramebufferConfiguration configuration{};
|
||||
configuration.renderPass = renderPass;
|
||||
configuration.imageView = (VkImageView)texture->getRenderTargetHandle();
|
||||
configuration.width = w;
|
||||
configuration.height = h;
|
||||
framebuffer = getFramebuffer(configuration);
|
||||
}
|
||||
configuration.width = w;
|
||||
configuration.height = h;
|
||||
|
||||
VkRenderPassBeginInfo renderPassInfo{};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassInfo.renderPass = renderPass;
|
||||
renderPassInfo.framebuffer = getFramebuffer(configuration);
|
||||
renderPassInfo.framebuffer = framebuffer;
|
||||
renderPassInfo.renderArea.offset = {0, 0};
|
||||
renderPassInfo.renderArea.extent.width = static_cast<uint32_t>(w);
|
||||
renderPassInfo.renderArea.extent.height = static_cast<uint32_t>(h);
|
||||
@@ -2008,6 +2020,10 @@ void Graphics::cleanup() {
|
||||
}
|
||||
|
||||
void Graphics::cleanupSwapChain() {
|
||||
for (const auto& framebuffer : defaultFramebuffers) {
|
||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
||||
}
|
||||
vkDestroyRenderPass(device, defaultRenderPass, nullptr);
|
||||
vkDestroyImageView(device, colorImageView, nullptr);
|
||||
vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation);
|
||||
vkDestroyImageView(device, depthImageView, nullptr);
|
||||
@@ -2032,6 +2048,8 @@ void Graphics::recreateSwapChain() {
|
||||
createImageViews();
|
||||
createColorResources();
|
||||
createDepthResources();
|
||||
createDefaultRenderPass();
|
||||
createDefaultFramebuffers();
|
||||
}
|
||||
|
||||
love::graphics::Graphics* createInstance() {
|
||||
|
||||
@@ -213,6 +213,8 @@ private:
|
||||
VkCompositeAlphaFlagBitsKHR chooseCompositeAlpha(const VkSurfaceCapabilitiesKHR& capabilities);
|
||||
void createSwapChain();
|
||||
void createImageViews();
|
||||
void createDefaultRenderPass();
|
||||
void createDefaultFramebuffers();
|
||||
VkFramebuffer createFramebuffer(FramebufferConfiguration);
|
||||
VkFramebuffer getFramebuffer(FramebufferConfiguration);
|
||||
void createDefaultShaders();
|
||||
@@ -269,6 +271,8 @@ private:
|
||||
VkImage depthImage = VK_NULL_HANDLE;
|
||||
VkImageView depthImageView = VK_NULL_HANDLE;
|
||||
VmaAllocation depthImageAllocation = VK_NULL_HANDLE;
|
||||
VkRenderPass defaultRenderPass;
|
||||
std::vector<VkFramebuffer> defaultFramebuffers;
|
||||
std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
|
||||
std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
|
||||
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
|
||||
|
||||
@@ -606,6 +606,15 @@ VkStencilOp Vulkan::getStencilOp(StencilAction action) {
|
||||
}
|
||||
}
|
||||
|
||||
VkIndexType Vulkan::getVulkanIndexBufferType(IndexDataType type) {
|
||||
switch (type) {
|
||||
case INDEX_UINT16: return VK_INDEX_TYPE_UINT16;
|
||||
case INDEX_UINT32: return VK_INDEX_TYPE_UINT32;
|
||||
default:
|
||||
throw love::Exception("unknown Index Data type");
|
||||
}
|
||||
}
|
||||
|
||||
void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
|
||||
uint32_t baseLevel, uint32_t levelCount, uint32_t baseLayer, uint32_t layerCount) {
|
||||
VkImageMemoryBarrier barrier{};
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
static VkSamplerMipmapMode getMipMapMode(SamplerState::MipmapFilterMode);
|
||||
static VkDescriptorType getDescriptorType(graphics::Shader::UniformType);
|
||||
static VkStencilOp getStencilOp(StencilAction);
|
||||
static VkIndexType getVulkanIndexBufferType(IndexDataType type);
|
||||
|
||||
static void cmdTransitionImageLayout(
|
||||
VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout,
|
||||
|
||||
Reference in New Issue
Block a user