Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vk: maintenance #1958

Merged
merged 16 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 67 additions & 28 deletions src/modules/graphics/vulkan/Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ void Graphics::present(void *screenshotCallbackdata)

void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight)
{
if (swapChain != VK_NULL_HANDLE && (pixelWidth != this->pixelWidth || pixelHeight != this->pixelHeight || width != this->width || height != this->height))
if (swapChain != VK_NULL_HANDLE && (pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight || width != this->width || height != this->height))
requestSwapchainRecreation();

this->width = width;
Expand Down Expand Up @@ -559,8 +559,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int

beginFrame();

uint8 whiteColor[] = { 255, 255, 255, 255 };

if (batchedDrawState.vb[0] == nullptr)
{
// Initial sizes that should be good enough for most cases. It will
Expand All @@ -570,9 +568,19 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
batchedDrawState.indexBuffer = new StreamBuffer(this, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
}

// sometimes the VertexTexCoord is not set, so we manually adjust it to (0, 0)
if (defaultConstantTexCoord == nullptr)
{
float zeroTexCoord[2] = { 0.0f, 0.0f };
Buffer::DataDeclaration format("ConstantTexCoord", DATAFORMAT_FLOAT_VEC2);
Buffer::Settings settings(BUFFERUSAGEFLAG_VERTEX, BUFFERDATAUSAGE_STATIC);
defaultConstantTexCoord = newBuffer(settings, { format }, zeroTexCoord, sizeof(zeroTexCoord), 1);
}

// sometimes the VertexColor is not set, so we manually adjust it to white color
if (defaultConstantColor == nullptr)
{
uint8 whiteColor[] = { 255, 255, 255, 255 };
Buffer::DataDeclaration format("ConstantColor", DATAFORMAT_UNORM8_VEC4);
Buffer::Settings settings(BUFFERUSAGEFLAG_VERTEX, BUFFERDATAUSAGE_STATIC);
defaultConstantColor = newBuffer(settings, { format }, whiteColor, sizeof(whiteColor), 1);
Expand Down Expand Up @@ -1173,7 +1181,6 @@ void Graphics::beginFrame()

if (frameCounter >= USAGES_POLL_INTERVAL)
{
vkDeviceWaitIdle(device);
cleanupUnusedObjects();
frameCounter = 0;
}
Expand Down Expand Up @@ -1263,11 +1270,6 @@ const VkDeviceSize Graphics::getMinUniformBufferOffsetAlignment() const
return minUniformBufferOffsetAlignment;
}

graphics::Texture *Graphics::getDefaultTexture() const
{
return defaultTexture;
}

VkCommandBuffer Graphics::getCommandBufferForDataTransfer()
{
if (renderPassState.active)
Expand Down Expand Up @@ -1653,10 +1655,11 @@ void Graphics::createLogicalDevice()

VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures{};
extendedDynamicStateFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT;
extendedDynamicStateFeatures.extendedDynamicState = Vulkan::getBool(optionalDeviceExtensions.extendedDynamicState);
extendedDynamicStateFeatures.extendedDynamicState = VK_TRUE;
extendedDynamicStateFeatures.pNext = nullptr;

createInfo.pNext = &extendedDynamicStateFeatures;
if (optionalDeviceExtensions.extendedDynamicState)
createInfo.pNext = &extendedDynamicStateFeatures;

if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS)
throw love::Exception("failed to create logical device");
Expand Down Expand Up @@ -1850,20 +1853,34 @@ void Graphics::createSwapChain()

VkSurfaceFormatKHR Graphics::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats)
{
std::vector<VkFormat> formatOrder;

// TODO: turn off GammaCorrect if a sRGB format can't be found?
// TODO: does every platform have these formats?
if (isGammaCorrect())
{
formatOrder = {
VK_FORMAT_B8G8R8A8_SRGB,
VK_FORMAT_R8G8B8A8_SRGB,
};
}
else
{
formatOrder = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_SNORM,
};
}

for (const auto format : formatOrder)
{
for (const auto &availableFormat : availableFormats)
// fixme: what if this format and colorspace is not available?
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
if (availableFormat.format == format && availableFormat.colorSpace == VK_COLORSPACE_SRGB_NONLINEAR_KHR)
return availableFormat;
}
}

for (const auto &availableFormat : availableFormats)
// fixme: what if this format and colorspace is not available?
if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return availableFormat;


return availableFormats[0];
}

Expand Down Expand Up @@ -2208,11 +2225,6 @@ VkRenderPass Graphics::getRenderPass(RenderPassConfiguration &configuration)
return renderPass;
}

bool Graphics::usesConstantVertexColor(const VertexAttributes &vertexAttributes)
{
return !!(vertexAttributes.enableBits & (1u << ATTRIB_COLOR));
}

void Graphics::createVulkanVertexFormat(
VertexAttributes vertexAttributes,
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
Expand All @@ -2224,6 +2236,7 @@ void Graphics::createVulkanVertexFormat(
auto allBits = enableBits;

bool usesColor = false;
bool usesTexCoord = false;

uint8_t highestBufferBinding = 0;

Expand All @@ -2233,6 +2246,8 @@ void Graphics::createVulkanVertexFormat(
uint32 bit = 1u << i;
if (enableBits & bit)
{
if (i == ATTRIB_TEXCOORD)
usesTexCoord = true;
if (i == ATTRIB_COLOR)
usesColor = true;

Expand Down Expand Up @@ -2267,11 +2282,31 @@ void Graphics::createVulkanVertexFormat(
allBits >>= 1;
}

if (!usesTexCoord)
{
// FIXME: is there a case where gaps happen between buffer bindings?
// then this doesn't work. We might need to enable null buffers again.
const auto constantTexCoordBufferBinding = ++highestBufferBinding;

VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = constantTexCoordBufferBinding;
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
bindingDescription.stride = 0; // no stride, will always read the same coord multiple times.
bindingDescriptions.push_back(bindingDescription);

VkVertexInputAttributeDescription attributeDescription{};
attributeDescription.binding = constantTexCoordBufferBinding;
attributeDescription.location = ATTRIB_TEXCOORD;
attributeDescription.offset = 0;
attributeDescription.format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions.push_back(attributeDescription);
}

if (!usesColor)
{
// FIXME: is there a case where gaps happen between buffer bindings?
// then this doesn't work. We might need to enable null buffers again.
const auto constantColorBufferBinding = highestBufferBinding + 1;
const auto constantColorBufferBinding = ++highestBufferBinding;

VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = constantColorBufferBinding;
Expand Down Expand Up @@ -2331,7 +2366,13 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
}
}

if (!usesConstantVertexColor(attributes))
if (!(attributes.enableBits & (1u << ATTRIB_TEXCOORD)))
{
bufferVector.push_back((VkBuffer)defaultConstantTexCoord->getHandle());
offsets.push_back((VkDeviceSize)0);
}

if (!(attributes.enableBits & (1u << ATTRIB_COLOR)))
{
bufferVector.push_back((VkBuffer)defaultConstantColor->getHandle());
offsets.push_back((VkDeviceSize)0);
Expand Down Expand Up @@ -2402,8 +2443,6 @@ void Graphics::setDefaultRenderPass()

void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
{
auto currentCommandBuffer = commandBuffers.at(currentFrame);

// fixme: hasSRGBtexture
RenderPassConfiguration renderPassConfiguration{};
for (const auto &color : rts.colors)
Expand Down
15 changes: 6 additions & 9 deletions src/modules/graphics/vulkan/Graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,12 @@ class Graphics final : public love::graphics::Graphics
Graphics();
~Graphics();

const char *getName() const override;
const VkDevice getDevice() const;
const VmaAllocator getVmaAllocator() const;

// implementation for virtual functions
const char *getName() const 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;
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;
void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
void clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth) override;
Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override;
Expand Down Expand Up @@ -299,17 +298,15 @@ class Graphics final : public love::graphics::Graphics
void draw(const DrawIndexedCommand &cmd) override;
void drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture) 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;

// internal functions.

const VkDevice getDevice() const;
const VmaAllocator getVmaAllocator() const;
VkCommandBuffer getCommandBufferForDataTransfer();
void queueCleanUp(std::function<void()> cleanUp);
void addReadbackCallback(std::function<void()> callback);
void submitGpuCommands(bool present, void *screenshotCallbackData = nullptr);
const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
graphics::Texture *getDefaultTexture() const;
VkSampler getCachedSampler(const SamplerState &sampler);
void setComputeShader(Shader *computeShader);
graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
Expand Down Expand Up @@ -369,7 +366,6 @@ class Graphics final : public love::graphics::Graphics
void startRecordingGraphicsCommands();
void endRecordingGraphicsCommands();
void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration);
bool usesConstantVertexColor(const VertexAttributes &attribs);
void createVulkanVertexFormat(
VertexAttributes vertexAttributes,
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
Expand Down Expand Up @@ -438,6 +434,7 @@ class Graphics final : public love::graphics::Graphics
VmaAllocator vmaAllocator = VK_NULL_HANDLE;
StrongRef<love::graphics::Texture> defaultTexture;
StrongRef<love::graphics::Buffer> defaultConstantColor;
StrongRef<love::graphics::Buffer> defaultConstantTexCoord;
// functions that need to be called to cleanup objects that were needed for rendering a frame.
// We need a vector for each frame in flight.
std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
Expand Down
Loading