vulkan: implement compute shaders

A lot of stuff probably isn't implemented yet, however the
following code already works:

```lua
local shader = love.graphics.newComputeShader [[
    layout (local_size_x = 1, local_size_y = 1) in;

    layout(r32f) uniform highp image2D out_tex;

    uniform float time;

    void computemain() {
        imageStore(out_tex, ivec2(love_GlobalThreadID.xy), vec4(time, 1.0, 1.0, 1.0));
    }
]]

local tex = love.graphics.newTexture(64, 64, {computewrite = true,format = "r32f"})

function love.draw()
    shader:send("out_tex", tex)
    shader:send("time", love.timer.getTime() % 1)
    love.graphics.dispatchThreadgroups(shader, 64, 64, 1)

    love.graphics.print("compute shader test")
    love.graphics.draw(tex, 25, 25)
end
```
This commit is contained in:
niki
2022-08-31 02:07:46 +02:00
parent e409770be1
commit a0ee9f7b9b
7 changed files with 380 additions and 157 deletions
+9 -3
View File
@@ -156,7 +156,7 @@ struct QueueFamilyIndices {
std::optional<uint32_t> graphicsFamily;
std::optional<uint32_t> presentFamily;
bool isComplete() {
bool isComplete() const {
return graphicsFamily.has_value() && presentFamily.has_value();
}
};
@@ -226,8 +226,10 @@ public:
VkCommandBuffer getDataTransferCommandBuffer();
VkCommandBuffer getReadbackCommandBuffer();
void oneTimeCommand(std::function<void(VkCommandBuffer)> cmd);
void queueCleanUp(std::function<void()> cleanUp);
void addReadbackCallback(const std::function<void()> &callback);
void addReadbackCallback(std::function<void()> callback);
void submitGpuCommands(bool present);
@@ -236,11 +238,13 @@ public:
graphics::Texture* getDefaultTexture() const;
VkSampler getCachedSampler(const SamplerState&);
void setComputeShader(Shader*);
protected:
graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override;
graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
graphics::StreamBuffer* newStreamBuffer(BufferUsage type, size_t size) override;
bool dispatch(int x, int y, int z) override { return false; }
bool dispatch(int x, int y, int z) override;
void initCapabilities() override;
void getAPIStats(int& shaderswitches) const override;
void setRenderTargetsInternal(const RenderTargets& rts, int pixelw, int pixelh, bool hasSRGBtexture) override;
@@ -333,8 +337,10 @@ private:
std::unordered_map<SamplerState, VkSampler, SamplerStateHasher> samplers;
VkCommandPool commandPool = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> dataTransferCommandBuffers;
std::vector<VkCommandBuffer> computeCommandBuffers;
std::vector<VkCommandBuffer> commandBuffers;
std::vector<VkCommandBuffer> readbackCommandBuffers;
Shader* computeShader = nullptr;
std::vector<VkSemaphore> imageAvailableSemaphores;
std::vector<VkSemaphore> renderFinishedSemaphores;
std::vector<VkFence> inFlightFences;