mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
vulkan: implement msaa
This commit is contained in:
@@ -220,6 +220,8 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) {
|
bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) {
|
||||||
|
requestedMsaa = msaa;
|
||||||
|
|
||||||
cleanUpFunctions.clear();
|
cleanUpFunctions.clear();
|
||||||
cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT);
|
cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
|
|
||||||
@@ -232,6 +234,7 @@ bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int
|
|||||||
createSwapChain();
|
createSwapChain();
|
||||||
createImageViews();
|
createImageViews();
|
||||||
createSyncObjects();
|
createSyncObjects();
|
||||||
|
createColorResources();
|
||||||
createDepthResources();
|
createDepthResources();
|
||||||
createCommandPool();
|
createCommandPool();
|
||||||
createCommandBuffers();
|
createCommandBuffers();
|
||||||
@@ -324,7 +327,7 @@ void Graphics::initCapabilities() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::getAPIStats(int& shaderswitches) const {
|
void Graphics::getAPIStats(int& shaderswitches) const {
|
||||||
shaderswitches = Vulkan::getNumShaderSwitches();
|
shaderswitches = static_cast<int>(Vulkan::getNumShaderSwitches());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::unSetMode() {
|
void Graphics::unSetMode() {
|
||||||
@@ -340,6 +343,14 @@ void Graphics::setActive(bool enable) {
|
|||||||
active = enable;
|
active = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Graphics::getRequestedBackbufferMSAA() const {
|
||||||
|
return requestedMsaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Graphics::getBackbufferMSAA() const {
|
||||||
|
return actualMsaa;
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::setFrontFaceWinding(Winding winding) {
|
void Graphics::setFrontFaceWinding(Winding winding) {
|
||||||
const auto& currentState = states.back();
|
const auto& currentState = states.back();
|
||||||
|
|
||||||
@@ -555,19 +566,23 @@ 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();
|
endRenderPass();
|
||||||
|
|
||||||
if (rts.colors.size() == 0) {
|
if (rts.colors.empty()) {
|
||||||
startRenderPass(nullptr, swapChainExtent.width, swapChainExtent.height);
|
startRenderPass(nullptr, swapChainExtent.width, swapChainExtent.height);
|
||||||
} else {
|
} else {
|
||||||
// fixme: multi canvas render.
|
// fixme: multi canvas render.
|
||||||
auto& firstRenderTarget = rts.getFirstTarget();
|
auto& firstRenderTarget = rts.getFirstTarget();
|
||||||
startRenderPass(static_cast<Texture*>(firstRenderTarget.texture), pixelw, pixelh);
|
startRenderPass(dynamic_cast<Texture*>(firstRenderTarget.texture), pixelw, pixelh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
|
// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
|
||||||
|
|
||||||
void Graphics::initDynamicState() {
|
void Graphics::initDynamicState() {
|
||||||
setScissor();
|
if (states.back().scissor) {
|
||||||
|
setScissor(states.back().scissorRect);
|
||||||
|
} else {
|
||||||
|
setScissor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::startRecordingGraphicsCommands() {
|
void Graphics::startRecordingGraphicsCommands() {
|
||||||
@@ -804,6 +819,8 @@ void Graphics::pickPhysicalDevice() {
|
|||||||
VkPhysicalDeviceProperties properties;
|
VkPhysicalDeviceProperties properties;
|
||||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||||
minUniformBufferOffsetAlignment = properties.limits.minUniformBufferOffsetAlignment;
|
minUniformBufferOffsetAlignment = properties.limits.minUniformBufferOffsetAlignment;
|
||||||
|
|
||||||
|
getMaxUsableSampleCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::checkDeviceExtensionSupport(VkPhysicalDevice device) {
|
bool Graphics::checkDeviceExtensionSupport(VkPhysicalDevice device) {
|
||||||
@@ -1147,25 +1164,22 @@ VkPresentModeKHR Graphics::chooseSwapPresentMode(const std::vector<VkPresentMode
|
|||||||
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
[[fallthrough]];
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 1: {
|
case 0: {
|
||||||
auto it = std::find(availablePresentModes.begin(), availablePresentModes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
|
auto it = std::find(availablePresentModes.begin(), availablePresentModes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
|
||||||
if (it != availablePresentModes.end()) {
|
if (it != availablePresentModes.end()) {
|
||||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
auto it = std::find(availablePresentModes.begin(), availablePresentModes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR);
|
||||||
}
|
if (it != availablePresentModes.end()) {
|
||||||
}
|
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
case 0: {
|
}
|
||||||
auto it = std::find(availablePresentModes.begin(), availablePresentModes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR);
|
else {
|
||||||
if (it != availablePresentModes.end()) {
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1182,7 +1196,6 @@ VkExtent2D Graphics::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabiliti
|
|||||||
const void* handle = window->getHandle();
|
const void* handle = window->getHandle();
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
// is this the equivalent of glfwGetFramebufferSize ?
|
|
||||||
SDL_Vulkan_GetDrawableSize((SDL_Window*)handle, &width, &height);
|
SDL_Vulkan_GetDrawableSize((SDL_Window*)handle, &width, &height);
|
||||||
|
|
||||||
VkExtent2D actualExtent = {
|
VkExtent2D actualExtent = {
|
||||||
@@ -1237,9 +1250,10 @@ void Graphics::createImageViews() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkFramebuffer Graphics::createFramebuffer(FramebufferConfiguration configuration) {
|
VkFramebuffer Graphics::createFramebuffer(FramebufferConfiguration configuration) {
|
||||||
std::array<VkImageView, 2> attachments = {
|
std::array<VkImageView, 3> attachments = {
|
||||||
|
colorImageView,
|
||||||
|
depthImageView,
|
||||||
configuration.imageView,
|
configuration.imageView,
|
||||||
depthImageView
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo createInfo{};
|
VkFramebufferCreateInfo createInfo{};
|
||||||
@@ -1285,18 +1299,18 @@ void Graphics::createDefaultShaders() {
|
|||||||
|
|
||||||
VkRenderPass Graphics::createRenderPass(RenderPassConfiguration configuration) {
|
VkRenderPass Graphics::createRenderPass(RenderPassConfiguration configuration) {
|
||||||
VkAttachmentDescription colorDescription{};
|
VkAttachmentDescription colorDescription{};
|
||||||
colorDescription.format = configuration.frameBufferFormat;
|
colorDescription.format = swapChainImageFormat;
|
||||||
colorDescription.samples = VK_SAMPLE_COUNT_1_BIT;
|
colorDescription.samples = msaaSamples;
|
||||||
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
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 = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
VkAttachmentDescription depthStencilAttachment{};
|
VkAttachmentDescription depthStencilAttachment{};
|
||||||
depthStencilAttachment.format = findDepthFormat();
|
depthStencilAttachment.format = findDepthFormat();
|
||||||
depthStencilAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
depthStencilAttachment.samples = msaaSamples;
|
||||||
depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
depthStencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
depthStencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
@@ -1304,6 +1318,16 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration configuration) {
|
|||||||
depthStencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
depthStencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
depthStencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
depthStencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentDescription colorAttachmentResolve{};
|
||||||
|
colorAttachmentResolve.format = configuration.frameBufferFormat;
|
||||||
|
colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
VkAttachmentReference colorAttachmentRef{};
|
VkAttachmentReference colorAttachmentRef{};
|
||||||
colorAttachmentRef.attachment = 0;
|
colorAttachmentRef.attachment = 0;
|
||||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
@@ -1312,13 +1336,18 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration configuration) {
|
|||||||
depthStencilAttachmentRef.attachment = 1;
|
depthStencilAttachmentRef.attachment = 1;
|
||||||
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference colorAttachmentResolveRef{};
|
||||||
|
colorAttachmentResolveRef.attachment = 2;
|
||||||
|
colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
VkSubpassDescription subPass{};
|
VkSubpassDescription subPass{};
|
||||||
subPass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
subPass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
subPass.colorAttachmentCount = 1;
|
subPass.colorAttachmentCount = 1;
|
||||||
subPass.pColorAttachments = &colorAttachmentRef;
|
subPass.pColorAttachments = &colorAttachmentRef;
|
||||||
subPass.pDepthStencilAttachment = &depthStencilAttachmentRef;
|
subPass.pDepthStencilAttachment = &depthStencilAttachmentRef;
|
||||||
|
subPass.pResolveAttachments = &colorAttachmentResolveRef;
|
||||||
|
|
||||||
std::array<VkAttachmentDescription, 2> attachments = { colorDescription, depthStencilAttachment };
|
std::array<VkAttachmentDescription, 3> attachments = { colorDescription, depthStencilAttachment, colorAttachmentResolve };
|
||||||
|
|
||||||
VkSubpassDependency dependency{};
|
VkSubpassDependency dependency{};
|
||||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
@@ -1419,8 +1448,6 @@ 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) {
|
||||||
states.back().stencil;
|
|
||||||
|
|
||||||
GraphicsPipelineConfiguration configuration;
|
GraphicsPipelineConfiguration configuration;
|
||||||
configuration.renderPass = currentRenderPass;
|
configuration.renderPass = currentRenderPass;
|
||||||
configuration.vertexAttributes = attributes;
|
configuration.vertexAttributes = attributes;
|
||||||
@@ -1624,7 +1651,7 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration config
|
|||||||
VkPipelineMultisampleStateCreateInfo multisampling{};
|
VkPipelineMultisampleStateCreateInfo multisampling{};
|
||||||
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
multisampling.sampleShadingEnable = VK_FALSE;
|
multisampling.sampleShadingEnable = VK_FALSE;
|
||||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
multisampling.rasterizationSamples = msaaSamples;
|
||||||
multisampling.minSampleShading = 1.0f; // Optional
|
multisampling.minSampleShading = 1.0f; // Optional
|
||||||
multisampling.pSampleMask = nullptr; // Optional
|
multisampling.pSampleMask = nullptr; // Optional
|
||||||
multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
|
multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
|
||||||
@@ -1726,6 +1753,83 @@ void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::getMaxUsableSampleCount() {
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties;
|
||||||
|
vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
|
||||||
|
|
||||||
|
VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts;
|
||||||
|
|
||||||
|
if (counts & VK_SAMPLE_COUNT_64_BIT && requestedMsaa >= 64) {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_64_BIT;
|
||||||
|
actualMsaa = 64;
|
||||||
|
} else if (counts & VK_SAMPLE_COUNT_32_BIT && requestedMsaa >= 32) {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_32_BIT;
|
||||||
|
actualMsaa = 32;
|
||||||
|
}
|
||||||
|
else if (counts & VK_SAMPLE_COUNT_16_BIT && requestedMsaa >= 16) {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_16_BIT;
|
||||||
|
actualMsaa = 16;
|
||||||
|
}
|
||||||
|
else if (counts & VK_SAMPLE_COUNT_8_BIT && requestedMsaa >= 8) {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_8_BIT;
|
||||||
|
actualMsaa = 8;
|
||||||
|
}
|
||||||
|
else if (counts & VK_SAMPLE_COUNT_4_BIT && requestedMsaa >= 4) {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_4_BIT;
|
||||||
|
actualMsaa = 4;
|
||||||
|
}
|
||||||
|
else if (counts & VK_SAMPLE_COUNT_2_BIT && requestedMsaa >= 2) {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_2_BIT;
|
||||||
|
actualMsaa = 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
actualMsaa = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::createColorResources() {
|
||||||
|
VkFormat colorFormat = swapChainImageFormat;
|
||||||
|
|
||||||
|
VkImageCreateInfo imageInfo{};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageInfo.format = colorFormat;
|
||||||
|
imageInfo.extent.width = swapChainExtent.width;
|
||||||
|
imageInfo.extent.height = swapChainExtent.height;
|
||||||
|
imageInfo.extent.depth = 1;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.samples = msaaSamples;
|
||||||
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo allocationInfo{};
|
||||||
|
allocationInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
|
allocationInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
|
||||||
|
|
||||||
|
vmaCreateImage(vmaAllocator, &imageInfo, &allocationInfo, &colorImage, &colorImageAllocation, nullptr);
|
||||||
|
|
||||||
|
VkImageViewCreateInfo imageViewInfo{};
|
||||||
|
imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
imageViewInfo.image = colorImage;
|
||||||
|
imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
imageViewInfo.format = colorFormat;
|
||||||
|
imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
imageViewInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
imageViewInfo.subresourceRange.levelCount = 1;
|
||||||
|
imageViewInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
imageViewInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
vkCreateImageView(device, &imageViewInfo, nullptr, &colorImageView);
|
||||||
|
}
|
||||||
|
|
||||||
VkFormat Graphics::findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) {
|
VkFormat Graphics::findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) {
|
||||||
for (auto format : candidates) {
|
for (auto format : candidates) {
|
||||||
VkFormatProperties properties;
|
VkFormatProperties properties;
|
||||||
@@ -1741,7 +1845,6 @@ VkFormat Graphics::findSupportedFormat(const std::vector<VkFormat>& candidates,
|
|||||||
throw love::Exception("failed to find supported format");
|
throw love::Exception("failed to find supported format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkFormat Graphics::findDepthFormat() {
|
VkFormat Graphics::findDepthFormat() {
|
||||||
return findSupportedFormat(
|
return findSupportedFormat(
|
||||||
{ VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
|
{ VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
|
||||||
@@ -1762,7 +1865,7 @@ void Graphics::createDepthResources() {
|
|||||||
imageInfo.extent.depth = 1;
|
imageInfo.extent.depth = 1;
|
||||||
imageInfo.mipLevels = 1;
|
imageInfo.mipLevels = 1;
|
||||||
imageInfo.arrayLayers = 1;
|
imageInfo.arrayLayers = 1;
|
||||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
imageInfo.samples = msaaSamples;
|
||||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
@@ -1854,7 +1957,7 @@ void Graphics::createSyncObjects() {
|
|||||||
|
|
||||||
void Graphics::createDefaultTexture() {
|
void Graphics::createDefaultTexture() {
|
||||||
Texture::Settings settings;
|
Texture::Settings settings;
|
||||||
standardTexture.reset((Texture*)newTexture(settings));
|
standardTexture.reset((Texture*)newTexture(settings, nullptr));
|
||||||
uint8_t whitePixels[] = {255, 255, 255, 255};
|
uint8_t whitePixels[] = {255, 255, 255, 255};
|
||||||
standardTexture->replacePixels(whitePixels, sizeof(whitePixels), 0, 0, { 0, 0, 1, 1 }, false);
|
standardTexture->replacePixels(whitePixels, sizeof(whitePixels), 0, 0, { 0, 0, 1, 1 }, false);
|
||||||
}
|
}
|
||||||
@@ -1905,6 +2008,8 @@ void Graphics::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::cleanupSwapChain() {
|
void Graphics::cleanupSwapChain() {
|
||||||
|
vkDestroyImageView(device, colorImageView, nullptr);
|
||||||
|
vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation);
|
||||||
vkDestroyImageView(device, depthImageView, nullptr);
|
vkDestroyImageView(device, depthImageView, nullptr);
|
||||||
vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation);
|
vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation);
|
||||||
for (const auto& [key, val] : framebuffers) {
|
for (const auto& [key, val] : framebuffers) {
|
||||||
@@ -1925,6 +2030,7 @@ void Graphics::recreateSwapChain() {
|
|||||||
|
|
||||||
createSwapChain();
|
createSwapChain();
|
||||||
createImageViews();
|
createImageViews();
|
||||||
|
createColorResources();
|
||||||
createDepthResources();
|
createDepthResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public:
|
|||||||
const VmaAllocator getVmaAllocator() const;
|
const VmaAllocator getVmaAllocator() const;
|
||||||
|
|
||||||
// implementation for virtual functions
|
// implementation for virtual functions
|
||||||
love::graphics::Texture* newTexture(const love::graphics::Texture::Settings& settings, const love::graphics::Texture::Slices* data = nullptr) override;
|
love::graphics::Texture* newTexture(const love::graphics::Texture::Settings& settings, const love::graphics::Texture::Slices* data) override;
|
||||||
love::graphics::Buffer* newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override;
|
love::graphics::Buffer* newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override;
|
||||||
void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
|
void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
|
||||||
void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override;
|
void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override;
|
||||||
@@ -150,8 +150,8 @@ public:
|
|||||||
bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
|
bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
|
||||||
void unSetMode() override;
|
void unSetMode() override;
|
||||||
void setActive(bool active) override;
|
void setActive(bool active) override;
|
||||||
int getRequestedBackbufferMSAA() const override { return 0; }
|
int getRequestedBackbufferMSAA() const override;
|
||||||
int getBackbufferMSAA() const override { return 0; }
|
int getBackbufferMSAA() const override;
|
||||||
void setColor(Colorf c) override;
|
void setColor(Colorf c) override;
|
||||||
void setScissor(const Rect& rect) override;
|
void setScissor(const Rect& rect) override;
|
||||||
void setScissor() override;
|
void setScissor() override;
|
||||||
@@ -163,7 +163,7 @@ public:
|
|||||||
void setPointSize(float size) override;
|
void setPointSize(float size) override;
|
||||||
void setWireframe(bool enable) override;
|
void setWireframe(bool enable) override;
|
||||||
PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
|
PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
|
||||||
bool isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB = false) override;
|
bool isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB) override;
|
||||||
Renderer getRenderer() const override;
|
Renderer getRenderer() const override;
|
||||||
bool usesGLSLES() const override;
|
bool usesGLSLES() const override;
|
||||||
RendererInfo getRendererInfo() const override;
|
RendererInfo getRendererInfo() const override;
|
||||||
@@ -172,7 +172,7 @@ public:
|
|||||||
void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override;
|
void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override;
|
||||||
|
|
||||||
GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; };
|
GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; };
|
||||||
GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) { return nullptr; }
|
GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) override { return nullptr; }
|
||||||
|
|
||||||
VkCommandBuffer getDataTransferCommandBuffer();
|
VkCommandBuffer getDataTransferCommandBuffer();
|
||||||
void queueCleanUp(std::function<void()> cleanUp);
|
void queueCleanUp(std::function<void()> cleanUp);
|
||||||
@@ -199,6 +199,7 @@ private:
|
|||||||
void createVulkanInstance();
|
void createVulkanInstance();
|
||||||
bool checkValidationSupport();
|
bool checkValidationSupport();
|
||||||
void pickPhysicalDevice();
|
void pickPhysicalDevice();
|
||||||
|
void getMaxUsableSampleCount();
|
||||||
int rateDeviceSuitability(VkPhysicalDevice device);
|
int rateDeviceSuitability(VkPhysicalDevice device);
|
||||||
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
||||||
void createLogicalDevice();
|
void createLogicalDevice();
|
||||||
@@ -217,6 +218,7 @@ private:
|
|||||||
void createDefaultShaders();
|
void createDefaultShaders();
|
||||||
VkRenderPass createRenderPass(RenderPassConfiguration);
|
VkRenderPass createRenderPass(RenderPassConfiguration);
|
||||||
VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
|
VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
|
||||||
|
void createColorResources();
|
||||||
VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||||
VkFormat findDepthFormat();
|
VkFormat findDepthFormat();
|
||||||
void createDepthResources();
|
void createDepthResources();
|
||||||
@@ -245,12 +247,14 @@ private:
|
|||||||
|
|
||||||
VkInstance instance = VK_NULL_HANDLE;
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
|
int requestedMsaa = 0;
|
||||||
|
int actualMsaa = 0;
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
VkQueue graphicsQueue = VK_NULL_HANDLE;
|
VkQueue graphicsQueue = VK_NULL_HANDLE;
|
||||||
VkQueue presentQueue = VK_NULL_HANDLE;
|
VkQueue presentQueue = VK_NULL_HANDLE;
|
||||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||||
VkSwapchainKHR swapChain = VK_NULL_HANDLE;
|
VkSwapchainKHR swapChain = VK_NULL_HANDLE;
|
||||||
VkSurfaceTransformFlagBitsKHR preTransform;
|
VkSurfaceTransformFlagBitsKHR preTransform = {};
|
||||||
Matrix4 displayRotation;
|
Matrix4 displayRotation;
|
||||||
std::vector<VkImage> swapChainImages;
|
std::vector<VkImage> swapChainImages;
|
||||||
VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
|
VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
|
||||||
@@ -258,9 +262,13 @@ private:
|
|||||||
std::vector<VkImageView> swapChainImageViews;
|
std::vector<VkImageView> swapChainImageViews;
|
||||||
VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
|
VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
|
||||||
VkRenderPass currentRenderPass = VK_NULL_HANDLE;
|
VkRenderPass currentRenderPass = VK_NULL_HANDLE;
|
||||||
VkImage depthImage;
|
VkSampleCountFlagBits msaaSamples;
|
||||||
VkImageView depthImageView;
|
VkImage colorImage = VK_NULL_HANDLE;
|
||||||
VmaAllocation depthImageAllocation;
|
VkImageView colorImageView = VK_NULL_HANDLE;
|
||||||
|
VmaAllocation colorImageAllocation = VK_NULL_HANDLE;
|
||||||
|
VkImage depthImage = VK_NULL_HANDLE;
|
||||||
|
VkImageView depthImageView = VK_NULL_HANDLE;
|
||||||
|
VmaAllocation depthImageAllocation = VK_NULL_HANDLE;
|
||||||
std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
|
std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
|
||||||
std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
|
std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
|
||||||
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
|
std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
|
||||||
|
|||||||
Reference in New Issue
Block a user