mirror of
https://github.com/love2d/love.git
synced 2026-08-20 12:40:20 +02:00
vulkan: correctly order gpu commands
This commit is contained in:
@@ -114,7 +114,7 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize)
|
|||||||
|
|
||||||
void Buffer::copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
|
void Buffer::copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
|
||||||
{
|
{
|
||||||
auto commandBuffer = vgfx->getReadbackCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
VkBufferCopy bufferCopy{};
|
VkBufferCopy bufferCopy{};
|
||||||
bufferCopy.srcOffset = sourceoffset;
|
bufferCopy.srcOffset = sourceoffset;
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ love::graphics::Buffer *Graphics::newBuffer(const love::graphics::Buffer::Settin
|
|||||||
|
|
||||||
void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth)
|
void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth)
|
||||||
{
|
{
|
||||||
|
if (!renderPassState.active)
|
||||||
|
startRenderPass();
|
||||||
|
|
||||||
VkClearAttachment attachment{};
|
VkClearAttachment attachment{};
|
||||||
|
|
||||||
if (color.hasValue)
|
if (color.hasValue)
|
||||||
@@ -120,8 +123,8 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d
|
|||||||
|
|
||||||
VkClearRect rect{};
|
VkClearRect rect{};
|
||||||
rect.layerCount = 1;
|
rect.layerCount = 1;
|
||||||
rect.rect.extent.width = static_cast<uint32_t>(currentViewportWidth);
|
rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
|
||||||
rect.rect.extent.height = static_cast<uint32_t>(currentViewportHeight);
|
rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
|
||||||
|
|
||||||
vkCmdClearAttachments(
|
vkCmdClearAttachments(
|
||||||
commandBuffers[currentFrame],
|
commandBuffers[currentFrame],
|
||||||
@@ -131,6 +134,9 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d
|
|||||||
|
|
||||||
void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
|
void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
|
||||||
{
|
{
|
||||||
|
if (!renderPassState.active)
|
||||||
|
startRenderPass();
|
||||||
|
|
||||||
std::vector<VkClearAttachment> attachments;
|
std::vector<VkClearAttachment> attachments;
|
||||||
for (const auto &color : colors)
|
for (const auto &color : colors)
|
||||||
{
|
{
|
||||||
@@ -163,8 +169,8 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
|
|||||||
|
|
||||||
VkClearRect rect{};
|
VkClearRect rect{};
|
||||||
rect.layerCount = 1;
|
rect.layerCount = 1;
|
||||||
rect.rect.extent.width = static_cast<uint32_t>(currentViewportWidth);
|
rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
|
||||||
rect.rect.extent.height = static_cast<uint32_t>(currentViewportHeight);
|
rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
|
||||||
|
|
||||||
vkCmdClearAttachments(commandBuffers[currentFrame], static_cast<uint32_t>(attachments.size()), attachments.data(), 1, &rect);
|
vkCmdClearAttachments(commandBuffers[currentFrame], static_cast<uint32_t>(attachments.size()), attachments.data(), 1, &rect);
|
||||||
}
|
}
|
||||||
@@ -179,11 +185,7 @@ void Graphics::submitGpuCommands(bool present)
|
|||||||
vkWaitForFences(device, 1, &imagesInFlight.at(imageIndex), VK_TRUE, UINT64_MAX);
|
vkWaitForFences(device, 1, &imagesInFlight.at(imageIndex), VK_TRUE, UINT64_MAX);
|
||||||
imagesInFlight[imageIndex] = inFlightFences[currentFrame];
|
imagesInFlight[imageIndex] = inFlightFences[currentFrame];
|
||||||
|
|
||||||
std::vector<VkCommandBuffer> submitCommandbuffers = {
|
std::array<VkCommandBuffer, 1> submitCommandbuffers = { commandBuffers.at(currentFrame) };
|
||||||
dataTransferCommandBuffers.at(currentFrame),
|
|
||||||
computeCommandBuffers.at(currentFrame),
|
|
||||||
commandBuffers.at(currentFrame),
|
|
||||||
readbackCommandBuffers.at(currentFrame)};
|
|
||||||
|
|
||||||
VkSubmitInfo submitInfo{};
|
VkSubmitInfo submitInfo{};
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
@@ -339,8 +341,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
|
|||||||
restoreState(states.back());
|
restoreState(states.back());
|
||||||
|
|
||||||
setViewportSize(width, height, pixelwidth, pixelheight);
|
setViewportSize(width, height, pixelwidth, pixelheight);
|
||||||
currentViewportWidth = 1.0f;
|
|
||||||
currentViewportHeight = 1.0f;
|
|
||||||
|
|
||||||
Vulkan::resetShaderSwitches();
|
Vulkan::resetShaderSwitches();
|
||||||
|
|
||||||
@@ -715,11 +715,14 @@ graphics::StreamBuffer *Graphics::newStreamBuffer(BufferUsage type, size_t size)
|
|||||||
|
|
||||||
bool Graphics::dispatch(int x, int y, int z)
|
bool Graphics::dispatch(int x, int y, int z)
|
||||||
{
|
{
|
||||||
vkCmdBindPipeline(computeCommandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE, computeShader->getComputePipeline());
|
if (renderPassState.active)
|
||||||
|
endRenderPass();
|
||||||
|
|
||||||
computeShader->cmdPushDescriptorSets(computeCommandBuffers.at(currentFrame), currentFrame, VK_PIPELINE_BIND_POINT_COMPUTE);
|
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE, computeShader->getComputePipeline());
|
||||||
|
|
||||||
vkCmdDispatch(computeCommandBuffers.at(currentFrame), static_cast<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(z));
|
computeShader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), currentFrame, VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||||
|
|
||||||
|
vkCmdDispatch(commandBuffers.at(currentFrame), static_cast<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(z));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -732,13 +735,14 @@ Matrix4 Graphics::computeDeviceProjection(const Matrix4 &projection, bool render
|
|||||||
|
|
||||||
void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
|
void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
|
||||||
{
|
{
|
||||||
endRenderPass();
|
if (renderPassState.active)
|
||||||
|
endRenderPass();
|
||||||
|
|
||||||
bool isWindow = rts.getFirstTarget().texture == nullptr;
|
bool isWindow = rts.getFirstTarget().texture == nullptr;
|
||||||
if (isWindow)
|
if (isWindow)
|
||||||
startDefaultRenderPass();
|
setDefaultRenderPass();
|
||||||
else
|
else
|
||||||
startRenderPass(rts, pixelw, pixelh, hasSRGBtexture);
|
setRenderPass(rts, pixelw, pixelh, hasSRGBtexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
|
// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
|
||||||
@@ -753,8 +757,8 @@ void Graphics::initDynamicState()
|
|||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
viewport.width = swapChainExtent.width;
|
viewport.width = static_cast<float>(swapChainExtent.width);
|
||||||
viewport.height = swapChainExtent.height;
|
viewport.height = static_cast<float>(swapChainExtent.height);
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
@@ -790,7 +794,8 @@ void Graphics::beginFrame()
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
|
{
|
||||||
recreateSwapChain();
|
recreateSwapChain();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -802,16 +807,22 @@ void Graphics::beginFrame()
|
|||||||
|
|
||||||
imageRequested = true;
|
imageRequested = true;
|
||||||
|
|
||||||
for (auto& readbackCallback : readbackCallbacks.at(currentFrame))
|
for (auto &readbackCallback : readbackCallbacks.at(currentFrame))
|
||||||
readbackCallback();
|
readbackCallback();
|
||||||
readbackCallbacks.at(currentFrame).clear();
|
readbackCallbacks.at(currentFrame).clear();
|
||||||
|
|
||||||
for (auto& cleanUpFn : cleanUpFunctions.at(currentFrame))
|
for (auto &cleanUpFn : cleanUpFunctions.at(currentFrame))
|
||||||
cleanUpFn();
|
cleanUpFn();
|
||||||
cleanUpFunctions.at(currentFrame).clear();
|
cleanUpFunctions.at(currentFrame).clear();
|
||||||
|
|
||||||
startRecordingGraphicsCommands(true);
|
startRecordingGraphicsCommands(true);
|
||||||
|
|
||||||
|
Vulkan::cmdTransitionImageLayout(
|
||||||
|
commandBuffers.at(currentFrame),
|
||||||
|
swapChainImages[imageIndex],
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
Vulkan::resetShaderSwitches();
|
Vulkan::resetShaderSwitches();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,35 +835,25 @@ void Graphics::startRecordingGraphicsCommands(bool newFrame)
|
|||||||
|
|
||||||
if (vkBeginCommandBuffer(commandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
|
if (vkBeginCommandBuffer(commandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
|
||||||
throw love::Exception("failed to begin recording command buffer");
|
throw love::Exception("failed to begin recording command buffer");
|
||||||
if (vkBeginCommandBuffer(dataTransferCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to begin recording data transfer command buffer");
|
|
||||||
if (vkBeginCommandBuffer(readbackCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to begin recording readback command buffer");
|
|
||||||
if (vkBeginCommandBuffer(computeCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to begin recording compute command buffer");
|
|
||||||
|
|
||||||
initDynamicState();
|
initDynamicState();
|
||||||
|
|
||||||
if (newFrame)
|
setDefaultRenderPass();
|
||||||
Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
|
||||||
|
|
||||||
startDefaultRenderPass();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::endRecordingGraphicsCommands(bool present) {
|
void Graphics::endRecordingGraphicsCommands(bool present) {
|
||||||
endRenderPass();
|
if (renderPassState.active)
|
||||||
|
endRenderPass();
|
||||||
|
|
||||||
if (present)
|
if (present)
|
||||||
Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
Vulkan::cmdTransitionImageLayout(
|
||||||
|
commandBuffers.at(currentFrame),
|
||||||
|
swapChainImages[imageIndex],
|
||||||
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
|
|
||||||
if (vkEndCommandBuffer(commandBuffers.at(currentFrame)) != VK_SUCCESS)
|
if (vkEndCommandBuffer(commandBuffers.at(currentFrame)) != VK_SUCCESS)
|
||||||
throw love::Exception("failed to record command buffer");
|
throw love::Exception("failed to record command buffer");
|
||||||
if (vkEndCommandBuffer(dataTransferCommandBuffers.at(currentFrame)) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to record data transfer command buffer");
|
|
||||||
if (vkEndCommandBuffer(readbackCommandBuffers.at(currentFrame)) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to record read back command buffer");
|
|
||||||
if (vkEndCommandBuffer(computeCommandBuffers.at(currentFrame)) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to record compute command buffer");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::updatedBatchedDrawBuffers()
|
void Graphics::updatedBatchedDrawBuffers()
|
||||||
@@ -880,52 +881,12 @@ graphics::Texture *Graphics::getDefaultTexture() const
|
|||||||
return dynamic_cast<graphics::Texture*>(standardTexture.get());
|
return dynamic_cast<graphics::Texture*>(standardTexture.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
VkCommandBuffer Graphics::getDataTransferCommandBuffer()
|
VkCommandBuffer Graphics::getCommandBufferForDataTransfer()
|
||||||
{
|
{
|
||||||
return dataTransferCommandBuffers.at(currentFrame);
|
if (renderPassState.active)
|
||||||
}
|
endRenderPass();
|
||||||
|
|
||||||
VkCommandBuffer Graphics::getReadbackCommandBuffer()
|
return commandBuffers.at(currentFrame);
|
||||||
{
|
|
||||||
return readbackCommandBuffers.at(currentFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::oneTimeCommand(std::function<void(VkCommandBuffer)> cmd)
|
|
||||||
{
|
|
||||||
VkCommandBufferAllocateInfo allocInfo{};
|
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
||||||
allocInfo.commandPool = commandPool;
|
|
||||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
allocInfo.commandBufferCount = 1;
|
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer;
|
|
||||||
if (vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to allocate one time command buffer");
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo{};
|
|
||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
||||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
||||||
|
|
||||||
if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to start recording one time command buffer");
|
|
||||||
|
|
||||||
cmd(commandBuffer);
|
|
||||||
|
|
||||||
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to end recording one time command buffer");
|
|
||||||
|
|
||||||
VkSubmitInfo submitInfo{};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &commandBuffer;
|
|
||||||
|
|
||||||
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to submit to queue");
|
|
||||||
|
|
||||||
if (vkQueueWaitIdle(graphicsQueue) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to wait for queue idle");
|
|
||||||
|
|
||||||
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::queueCleanUp(std::function<void()> cleanUp)
|
void Graphics::queueCleanUp(std::function<void()> cleanUp)
|
||||||
@@ -1381,7 +1342,7 @@ void Graphics::initVMA()
|
|||||||
void Graphics::createSurface()
|
void Graphics::createSurface()
|
||||||
{
|
{
|
||||||
auto window = Module::getInstance<love::window::Window>(M_WINDOW);
|
auto window = Module::getInstance<love::window::Window>(M_WINDOW);
|
||||||
const void* handle = window->getHandle();
|
const void *handle = window->getHandle();
|
||||||
if (SDL_Vulkan_CreateSurface((SDL_Window*)handle, instance, &surface) != SDL_TRUE)
|
if (SDL_Vulkan_CreateSurface((SDL_Window*)handle, instance, &surface) != SDL_TRUE)
|
||||||
throw love::Exception("failed to create window surface");
|
throw love::Exception("failed to create window surface");
|
||||||
}
|
}
|
||||||
@@ -1606,7 +1567,6 @@ void Graphics::createDefaultRenderPass()
|
|||||||
{
|
{
|
||||||
RenderPassConfiguration renderPassConfiguration{};
|
RenderPassConfiguration renderPassConfiguration{};
|
||||||
renderPassConfiguration.colorFormats.push_back(swapChainImageFormat);
|
renderPassConfiguration.colorFormats.push_back(swapChainImageFormat);
|
||||||
renderPassConfiguration.staticData.initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
renderPassConfiguration.staticData.msaaSamples = msaaSamples;
|
renderPassConfiguration.staticData.msaaSamples = msaaSamples;
|
||||||
renderPassConfiguration.staticData.depthFormat = findDepthFormat();
|
renderPassConfiguration.staticData.depthFormat = findDepthFormat();
|
||||||
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
||||||
@@ -1704,7 +1664,7 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
|
|||||||
std::vector<VkAttachmentReference> colorAttachmentRefs;
|
std::vector<VkAttachmentReference> colorAttachmentRefs;
|
||||||
|
|
||||||
uint32_t attachment = 0;
|
uint32_t attachment = 0;
|
||||||
for (const auto& colorFormat : configuration.colorFormats)
|
for (const auto &colorFormat : configuration.colorFormats)
|
||||||
{
|
{
|
||||||
VkAttachmentReference reference{};
|
VkAttachmentReference reference{};
|
||||||
reference.attachment = attachment++;
|
reference.attachment = attachment++;
|
||||||
@@ -1714,14 +1674,11 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
|
|||||||
VkAttachmentDescription colorDescription{};
|
VkAttachmentDescription colorDescription{};
|
||||||
colorDescription.format = colorFormat;
|
colorDescription.format = colorFormat;
|
||||||
colorDescription.samples = configuration.staticData.msaaSamples;
|
colorDescription.samples = configuration.staticData.msaaSamples;
|
||||||
if (configuration.staticData.initialColorImageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
|
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
||||||
else
|
|
||||||
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
colorDescription.initialLayout = configuration.staticData.initialColorImageLayout;
|
colorDescription.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
attachments.push_back(colorDescription);
|
attachments.push_back(colorDescription);
|
||||||
}
|
}
|
||||||
@@ -1880,16 +1837,19 @@ void Graphics::createVulkanVertexFormat(
|
|||||||
|
|
||||||
void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType primitiveType, CullMode cullmode)
|
void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType primitiveType, CullMode cullmode)
|
||||||
{
|
{
|
||||||
|
if (!renderPassState.active)
|
||||||
|
startRenderPass();
|
||||||
|
|
||||||
GraphicsPipelineConfiguration configuration{};
|
GraphicsPipelineConfiguration configuration{};
|
||||||
|
|
||||||
configuration.renderPass = currentRenderPass;
|
configuration.renderPass = renderPassState.renderPass;
|
||||||
configuration.vertexAttributes = attributes;
|
configuration.vertexAttributes = attributes;
|
||||||
configuration.shader = (Shader*)Shader::current;
|
configuration.shader = (Shader*)Shader::current;
|
||||||
configuration.wireFrame = states.back().wireframe;
|
configuration.wireFrame = states.back().wireframe;
|
||||||
configuration.blendState = states.back().blend;
|
configuration.blendState = states.back().blend;
|
||||||
configuration.colorChannelMask = states.back().colorMask;
|
configuration.colorChannelMask = states.back().colorMask;
|
||||||
configuration.msaaSamples = currentMsaaSamples;
|
configuration.msaaSamples = renderPassState.msaa;
|
||||||
configuration.numColorAttachments = currentNumColorAttachments;
|
configuration.numColorAttachments = renderPassState.numColorAttachments;
|
||||||
configuration.primitiveType = primitiveType;
|
configuration.primitiveType = primitiveType;
|
||||||
|
|
||||||
if (optionalDeviceFeatures.extendedDynamicState)
|
if (optionalDeviceFeatures.extendedDynamicState)
|
||||||
@@ -1933,37 +1893,35 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
|
|||||||
vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
|
vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::startDefaultRenderPass()
|
void Graphics::setDefaultRenderPass()
|
||||||
{
|
{
|
||||||
VkRenderPassBeginInfo renderPassInfo{};
|
renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassState.beginInfo.renderPass = defaultRenderPass;
|
||||||
renderPassInfo.renderPass = defaultRenderPass;
|
renderPassState.beginInfo.framebuffer = defaultFramebuffers[imageIndex];
|
||||||
renderPassInfo.framebuffer = defaultFramebuffers[imageIndex];
|
renderPassState.beginInfo.renderArea.offset = { 0, 0 };
|
||||||
renderPassInfo.renderArea.offset = { 0, 0 };
|
renderPassState.beginInfo.renderArea.extent = swapChainExtent;
|
||||||
renderPassInfo.renderArea.extent = swapChainExtent;
|
renderPassState.beginInfo.clearValueCount = 0;
|
||||||
|
|
||||||
vkCmdBeginRenderPass(commandBuffers.at(currentFrame), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
renderPassState.renderPass = defaultRenderPass;
|
||||||
|
renderPassState.pipeline = VK_NULL_HANDLE;
|
||||||
currentRenderPass = defaultRenderPass;
|
renderPassState.width = static_cast<float>(swapChainExtent.width);
|
||||||
currentGraphicsPipeline = VK_NULL_HANDLE;
|
renderPassState.height = static_cast<float>(swapChainExtent.height);
|
||||||
postRenderPass = std::nullopt;
|
renderPassState.msaa = msaaSamples;
|
||||||
currentViewportWidth = (float)swapChainExtent.width;
|
renderPassState.numColorAttachments = 1;
|
||||||
currentViewportHeight = (float)swapChainExtent.height;
|
renderPassState.transitionImages.clear();
|
||||||
currentMsaaSamples = msaaSamples;
|
|
||||||
currentNumColorAttachments = 1;
|
|
||||||
|
|
||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
viewport.width = currentViewportWidth;
|
viewport.width = renderPassState.width;
|
||||||
viewport.height = currentViewportHeight;
|
viewport.height = renderPassState.height;
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
vkCmdSetViewport(commandBuffers.at(currentFrame), 0, 1, &viewport);
|
vkCmdSetViewport(commandBuffers.at(currentFrame), 0, 1, &viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
|
void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
|
||||||
{
|
{
|
||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
@@ -1980,7 +1938,6 @@ void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh,
|
|||||||
// fixme: hasSRGBtexture
|
// fixme: hasSRGBtexture
|
||||||
// fixme: msaaSamples
|
// fixme: msaaSamples
|
||||||
RenderPassConfiguration renderPassConfiguration{};
|
RenderPassConfiguration renderPassConfiguration{};
|
||||||
renderPassConfiguration.staticData.initialColorImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
for (const auto &color : rts.colors)
|
for (const auto &color : rts.colors)
|
||||||
{
|
{
|
||||||
// fixme: use mipmap and slice.
|
// fixme: use mipmap and slice.
|
||||||
@@ -2009,13 +1966,12 @@ void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh,
|
|||||||
|
|
||||||
FramebufferConfiguration configuration{};
|
FramebufferConfiguration configuration{};
|
||||||
|
|
||||||
std::vector<VkImage> transitionBackImages;
|
std::vector<VkImage> transitionImages;
|
||||||
|
|
||||||
for (const auto& color : rts.colors)
|
for (const auto& color : rts.colors)
|
||||||
{
|
{
|
||||||
configuration.colorViews.push_back((VkImageView)color.texture->getRenderTargetHandle());
|
configuration.colorViews.push_back((VkImageView)color.texture->getRenderTargetHandle());
|
||||||
Vulkan::cmdTransitionImageLayout(currentCommandBuffer, (VkImage)color.texture->getHandle(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
transitionImages.push_back((VkImage) color.texture->getHandle());
|
||||||
transitionBackImages.push_back((VkImage) color.texture->getHandle());
|
|
||||||
}
|
}
|
||||||
if (rts.depthStencil.texture != nullptr)
|
if (rts.depthStencil.texture != nullptr)
|
||||||
// fixme: layout transition of depth stencil image?
|
// fixme: layout transition of depth stencil image?
|
||||||
@@ -2026,39 +1982,41 @@ void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh,
|
|||||||
configuration.staticData.height = static_cast<uint32_t>(pixelh);
|
configuration.staticData.height = static_cast<uint32_t>(pixelh);
|
||||||
VkFramebuffer framebuffer = getFramebuffer(configuration);
|
VkFramebuffer framebuffer = getFramebuffer(configuration);
|
||||||
|
|
||||||
VkRenderPassBeginInfo renderPassInfo{};
|
renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassState.beginInfo.renderPass = renderPass;
|
||||||
renderPassInfo.renderPass = renderPass;
|
renderPassState.beginInfo.framebuffer = framebuffer;
|
||||||
renderPassInfo.framebuffer = framebuffer;
|
renderPassState.beginInfo.renderArea.offset = {0, 0};
|
||||||
renderPassInfo.renderArea.offset = {0, 0};
|
renderPassState.beginInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw);
|
||||||
renderPassInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw);
|
renderPassState.beginInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh);
|
||||||
renderPassInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh);
|
renderPassState.beginInfo.clearValueCount = 0;
|
||||||
|
|
||||||
vkCmdBeginRenderPass(currentCommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
renderPassState.renderPass = renderPass;
|
||||||
|
renderPassState.pipeline = VK_NULL_HANDLE;
|
||||||
|
renderPassState.width = static_cast<float>(pixelw);
|
||||||
|
renderPassState.height = static_cast<float>(pixelh);
|
||||||
|
renderPassState.msaa = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
renderPassState.numColorAttachments = static_cast<uint32_t>(rts.colors.size());
|
||||||
|
renderPassState.transitionImages = std::move(transitionImages);
|
||||||
|
}
|
||||||
|
|
||||||
currentRenderPass = renderPass;
|
void Graphics::startRenderPass()
|
||||||
currentGraphicsPipeline = VK_NULL_HANDLE;
|
{
|
||||||
currentViewportWidth = (float)pixelw;
|
renderPassState.active = true;
|
||||||
currentViewportHeight = (float)pixelh;
|
|
||||||
currentMsaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
currentNumColorAttachments = static_cast<uint32_t>(rts.colors.size());
|
|
||||||
|
|
||||||
postRenderPass = [=]() {
|
for (const auto& image : renderPassState.transitionImages)
|
||||||
for (const auto& image : transitionBackImages)
|
Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
Vulkan::cmdTransitionImageLayout(currentCommandBuffer, image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
};
|
vkCmdBeginRenderPass(commandBuffers.at(currentFrame), &renderPassState.beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::endRenderPass()
|
void Graphics::endRenderPass()
|
||||||
{
|
{
|
||||||
vkCmdEndRenderPass(commandBuffers.at(currentFrame));
|
renderPassState.active = false;
|
||||||
currentRenderPass = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
if (postRenderPass)
|
vkCmdEndRenderPass(commandBuffers.at(currentFrame));
|
||||||
{
|
|
||||||
postRenderPass.value()();
|
for (const auto &image : renderPassState.transitionImages)
|
||||||
postRenderPass = std::nullopt;
|
Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSampler Graphics::createSampler(const SamplerState &samplerState)
|
VkSampler Graphics::createSampler(const SamplerState &samplerState)
|
||||||
@@ -2287,10 +2245,10 @@ void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration
|
|||||||
auto it = graphicsPipelines.find(configuration);
|
auto it = graphicsPipelines.find(configuration);
|
||||||
if (it != graphicsPipelines.end())
|
if (it != graphicsPipelines.end())
|
||||||
{
|
{
|
||||||
if (it->second != currentGraphicsPipeline)
|
if (it->second != renderPassState.pipeline)
|
||||||
{
|
{
|
||||||
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second);
|
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second);
|
||||||
currentGraphicsPipeline = it->second;
|
renderPassState.pipeline = it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2298,7 +2256,7 @@ void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration
|
|||||||
VkPipeline pipeline = createGraphicsPipeline(configuration);
|
VkPipeline pipeline = createGraphicsPipeline(configuration);
|
||||||
graphicsPipelines.insert({configuration, pipeline});
|
graphicsPipelines.insert({configuration, pipeline});
|
||||||
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
currentGraphicsPipeline = pipeline;
|
renderPassState.pipeline = pipeline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2459,9 +2417,6 @@ void Graphics::createCommandPool()
|
|||||||
void Graphics::createCommandBuffers()
|
void Graphics::createCommandBuffers()
|
||||||
{
|
{
|
||||||
commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
dataTransferCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
readbackCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
computeCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo allocInfo{};
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
@@ -2471,33 +2426,6 @@ void Graphics::createCommandBuffers()
|
|||||||
|
|
||||||
if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS)
|
if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS)
|
||||||
throw love::Exception("failed to allocate command buffers");
|
throw love::Exception("failed to allocate command buffers");
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo dataTransferAllocInfo{};
|
|
||||||
dataTransferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
||||||
dataTransferAllocInfo.commandPool = commandPool;
|
|
||||||
dataTransferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
dataTransferAllocInfo.commandBufferCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(device, &dataTransferAllocInfo, dataTransferCommandBuffers.data()) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to allocate data transfer command buffers");
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo readbackAllocInfo{};
|
|
||||||
readbackAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
||||||
readbackAllocInfo.commandPool = commandPool;
|
|
||||||
readbackAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
readbackAllocInfo.commandBufferCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(device, &readbackAllocInfo, readbackCommandBuffers.data()) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to allocate readback command buffers");
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo commandAllocInfo{};
|
|
||||||
commandAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
||||||
commandAllocInfo.commandPool = commandPool;
|
|
||||||
commandAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
commandAllocInfo.commandBufferCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(device, &commandAllocInfo, computeCommandBuffers.data()) != VK_SUCCESS)
|
|
||||||
throw love::Exception("failed to allocate compute command buffers");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::createSyncObjects()
|
void Graphics::createSyncObjects()
|
||||||
@@ -2548,9 +2476,6 @@ void Graphics::cleanup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, commandBuffers.data());
|
vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, commandBuffers.data());
|
||||||
vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, dataTransferCommandBuffers.data());
|
|
||||||
vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, readbackCommandBuffers.data());
|
|
||||||
vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, computeCommandBuffers.data());
|
|
||||||
|
|
||||||
for (auto const &p : samplers)
|
for (auto const &p : samplers)
|
||||||
vkDestroySampler(device, p.second, nullptr);
|
vkDestroySampler(device, p.second, nullptr);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ struct RenderPassConfiguration
|
|||||||
|
|
||||||
struct StaticRenderPassConfiguration
|
struct StaticRenderPassConfiguration
|
||||||
{
|
{
|
||||||
VkImageLayout initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
|
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
|
||||||
bool resolve = false;
|
bool resolve = false;
|
||||||
@@ -204,6 +203,19 @@ struct SwapChainSupportDetails
|
|||||||
std::vector<VkPresentModeKHR> presentModes;
|
std::vector<VkPresentModeKHR> presentModes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RenderpassState
|
||||||
|
{
|
||||||
|
bool active = false;
|
||||||
|
VkRenderPassBeginInfo beginInfo{};
|
||||||
|
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||||
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
|
std::vector<VkImage> transitionImages;
|
||||||
|
uint32_t numColorAttachments = 0;
|
||||||
|
float width = 0.0f;
|
||||||
|
float height = 0.0f;
|
||||||
|
VkSampleCountFlagBits msaa = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
};
|
||||||
|
|
||||||
class Graphics final : public love::graphics::Graphics
|
class Graphics final : public love::graphics::Graphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -261,10 +273,7 @@ public:
|
|||||||
graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
|
graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
|
||||||
graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty) override;
|
graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty) override;
|
||||||
|
|
||||||
VkCommandBuffer getDataTransferCommandBuffer();
|
VkCommandBuffer getCommandBufferForDataTransfer();
|
||||||
VkCommandBuffer getReadbackCommandBuffer();
|
|
||||||
|
|
||||||
void oneTimeCommand(std::function<void(VkCommandBuffer)> cmd);
|
|
||||||
|
|
||||||
void queueCleanUp(std::function<void()> cleanUp);
|
void queueCleanUp(std::function<void()> cleanUp);
|
||||||
void addReadbackCallback(std::function<void()> callback);
|
void addReadbackCallback(std::function<void()> callback);
|
||||||
@@ -339,8 +348,9 @@ private:
|
|||||||
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
|
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
|
||||||
std::vector<VkVertexInputAttributeDescription> &attributeDescriptions);
|
std::vector<VkVertexInputAttributeDescription> &attributeDescriptions);
|
||||||
void prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType, CullMode);
|
void prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType, CullMode);
|
||||||
void startRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture);
|
void setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture);
|
||||||
void startDefaultRenderPass();
|
void setDefaultRenderPass();
|
||||||
|
void startRenderPass();
|
||||||
void endRenderPass();
|
void endRenderPass();
|
||||||
VkSampler createSampler(const SamplerState&);
|
VkSampler createSampler(const SamplerState&);
|
||||||
|
|
||||||
@@ -361,8 +371,6 @@ private:
|
|||||||
VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
|
VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
|
||||||
VkExtent2D swapChainExtent = VkExtent2D();
|
VkExtent2D swapChainExtent = VkExtent2D();
|
||||||
std::vector<VkImageView> swapChainImageViews;
|
std::vector<VkImageView> swapChainImageViews;
|
||||||
VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
|
|
||||||
VkRenderPass currentRenderPass = VK_NULL_HANDLE;
|
|
||||||
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
VkImage colorImage = VK_NULL_HANDLE;
|
VkImage colorImage = VK_NULL_HANDLE;
|
||||||
VkImageView colorImageView = VK_NULL_HANDLE;
|
VkImageView colorImageView = VK_NULL_HANDLE;
|
||||||
@@ -377,10 +385,7 @@ private:
|
|||||||
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
|
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
|
||||||
std::unordered_map<SamplerState, VkSampler, SamplerStateHasher> samplers;
|
std::unordered_map<SamplerState, VkSampler, SamplerStateHasher> samplers;
|
||||||
VkCommandPool commandPool = VK_NULL_HANDLE;
|
VkCommandPool commandPool = VK_NULL_HANDLE;
|
||||||
std::vector<VkCommandBuffer> dataTransferCommandBuffers;
|
|
||||||
std::vector<VkCommandBuffer> computeCommandBuffers;
|
|
||||||
std::vector<VkCommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
std::vector<VkCommandBuffer> readbackCommandBuffers;
|
|
||||||
Shader* computeShader = nullptr;
|
Shader* computeShader = nullptr;
|
||||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
@@ -400,13 +405,7 @@ private:
|
|||||||
// just like batchedDrawBuffers we need a vector for each frame in flight.
|
// just like batchedDrawBuffers we need a vector for each frame in flight.
|
||||||
std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
|
std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
|
||||||
std::vector<std::vector<std::function<void()>>> readbackCallbacks;
|
std::vector<std::vector<std::function<void()>>> readbackCallbacks;
|
||||||
|
RenderpassState renderPassState;
|
||||||
// render pass variables.
|
|
||||||
std::optional<std::function<void()>> postRenderPass;
|
|
||||||
uint32_t currentNumColorAttachments = 0;
|
|
||||||
float currentViewportWidth = 0;
|
|
||||||
float currentViewportHeight = 0;
|
|
||||||
VkSampleCountFlagBits currentMsaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // vulkan
|
} // vulkan
|
||||||
|
|||||||
@@ -77,19 +77,17 @@ bool Texture::loadVolatile()
|
|||||||
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
|
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
|
||||||
throw love::Exception("failed to create image");
|
throw love::Exception("failed to create image");
|
||||||
|
|
||||||
auto commandBuffer = vgfx->getDataTransferCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
if (computeWrite)
|
if (computeWrite)
|
||||||
imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
else
|
else
|
||||||
imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
vgfx->oneTimeCommand([=](VkCommandBuffer commandBuffer) {
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage,
|
||||||
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage,
|
VK_IMAGE_LAYOUT_UNDEFINED, imageLayout,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED, imageLayout,
|
0, VK_REMAINING_MIP_LEVELS,
|
||||||
0, VK_REMAINING_MIP_LEVELS,
|
0, VK_REMAINING_ARRAY_LAYERS);
|
||||||
0, VK_REMAINING_ARRAY_LAYERS);
|
|
||||||
});
|
|
||||||
|
|
||||||
bool hasdata = slices.get(0, 0) != nullptr;
|
bool hasdata = slices.get(0, 0) != nullptr;
|
||||||
|
|
||||||
@@ -200,7 +198,7 @@ void Texture::createTextureImageView()
|
|||||||
|
|
||||||
void Texture::clear()
|
void Texture::clear()
|
||||||
{
|
{
|
||||||
auto commandBuffer = vgfx->getDataTransferCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
auto clearColor = getClearValue();
|
auto clearColor = getClearValue();
|
||||||
|
|
||||||
@@ -258,7 +256,7 @@ VkClearColorValue Texture::getClearValue()
|
|||||||
|
|
||||||
void Texture::generateMipmapsInternal()
|
void Texture::generateMipmapsInternal()
|
||||||
{
|
{
|
||||||
auto commandBuffer = vgfx->getDataTransferCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
|
if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
|
||||||
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage,
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage,
|
||||||
@@ -374,7 +372,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
|
|||||||
static_cast<uint32_t>(r.h), 1
|
static_cast<uint32_t>(r.h), 1
|
||||||
};
|
};
|
||||||
|
|
||||||
auto commandBuffer = vgfx->getDataTransferCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
|
|
||||||
if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
|
if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
|
||||||
@@ -414,7 +412,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
|
|||||||
|
|
||||||
void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect)
|
void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect)
|
||||||
{
|
{
|
||||||
auto commandBuffer = vgfx->getDataTransferCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
VkImageSubresourceLayers layers{};
|
VkImageSubresourceLayers layers{};
|
||||||
layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
@@ -444,7 +442,7 @@ void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int
|
|||||||
|
|
||||||
void Texture::copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size)
|
void Texture::copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size)
|
||||||
{
|
{
|
||||||
auto commandBuffer = vgfx->getReadbackCommandBuffer();
|
auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
|
||||||
|
|
||||||
VkImageSubresourceLayers layers{};
|
VkImageSubresourceLayers layers{};
|
||||||
layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|||||||
Reference in New Issue
Block a user