mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Merge pull request #1715 from bjornbytes/compute-shaders
Compute Shaders
This commit is contained in:
@@ -155,9 +155,9 @@ love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStageType st
|
||||
return new ShaderStage(this, stage, source, gles, cachekey);
|
||||
}
|
||||
|
||||
love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
|
||||
love::graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
{
|
||||
return new Shader(vertex, pixel);
|
||||
return new Shader(stages);
|
||||
}
|
||||
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
|
||||
@@ -469,6 +469,12 @@ void Graphics::setActive(bool enable)
|
||||
active = enable;
|
||||
}
|
||||
|
||||
void Graphics::dispatch(int x, int y, int z)
|
||||
{
|
||||
glDispatchCompute(x, y, z);
|
||||
glMemoryBarrier(GL_ALL_BARRIER_BITS); // TODO: Improve synchronization
|
||||
}
|
||||
|
||||
void Graphics::draw(const DrawCommand &cmd)
|
||||
{
|
||||
gl.prepareDraw(this);
|
||||
@@ -1543,10 +1549,13 @@ void Graphics::initCapabilities()
|
||||
capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = gl.getMaxCubeTextureSize();
|
||||
capabilities.limits[LIMIT_TEXEL_BUFFER_SIZE] = gl.getMaxTexelBufferSize();
|
||||
capabilities.limits[LIMIT_SHADER_STORAGE_BUFFER_SIZE] = gl.getMaxShaderStorageBufferSize();
|
||||
capabilities.limits[LIMIT_THREADGROUPS_X] = gl.getMaxComputeWorkGroupsX();
|
||||
capabilities.limits[LIMIT_THREADGROUPS_Y] = gl.getMaxComputeWorkGroupsY();
|
||||
capabilities.limits[LIMIT_THREADGROUPS_Z] = gl.getMaxComputeWorkGroupsZ();
|
||||
capabilities.limits[LIMIT_RENDER_TARGETS] = gl.getMaxRenderTargets();
|
||||
capabilities.limits[LIMIT_TEXTURE_MSAA] = gl.getMaxSamples();
|
||||
capabilities.limits[LIMIT_ANISOTROPY] = gl.getMaxAnisotropy();
|
||||
static_assert(LIMIT_MAX_ENUM == 10, "Graphics::initCapabilities must be updated when adding a new system limit!");
|
||||
static_assert(LIMIT_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new system limit!");
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
|
||||
void setActive(bool active) override;
|
||||
|
||||
void dispatch(int x, int y, int z) override;
|
||||
|
||||
void draw(const DrawCommand &cmd) override;
|
||||
void draw(const DrawIndexedCommand &cmd) override;
|
||||
void drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, love::graphics::Texture *texture) override;
|
||||
@@ -137,7 +139,7 @@ private:
|
||||
};
|
||||
|
||||
love::graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
||||
love::graphics::Shader *newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel) override;
|
||||
love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
|
||||
love::graphics::StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) override;
|
||||
void setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBtexture) override;
|
||||
void initCapabilities() override;
|
||||
|
||||
@@ -103,6 +103,9 @@ OpenGL::OpenGL()
|
||||
, maxTextureArrayLayers(0)
|
||||
, maxTexelBufferSize(0)
|
||||
, maxShaderStorageBufferSize(0)
|
||||
, maxComputeWorkGroupsX(0)
|
||||
, maxComputeWorkGroupsY(0)
|
||||
, maxComputeWorkGroupsZ(0)
|
||||
, maxRenderTargets(1)
|
||||
, maxSamples(1)
|
||||
, maxTextureUnits(1)
|
||||
@@ -511,6 +514,19 @@ void OpenGL::initMaxValues()
|
||||
maxShaderStorageBufferBindings = 0;
|
||||
}
|
||||
|
||||
if (GLAD_ES_VERSION_3_1 || GLAD_VERSION_4_3)
|
||||
{
|
||||
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &maxComputeWorkGroupsX);
|
||||
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &maxComputeWorkGroupsY);
|
||||
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &maxComputeWorkGroupsZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxComputeWorkGroupsX = 0;
|
||||
maxComputeWorkGroupsY = 0;
|
||||
maxComputeWorkGroupsZ = 0;
|
||||
}
|
||||
|
||||
int maxattachments = 1;
|
||||
int maxdrawbuffers = 1;
|
||||
|
||||
@@ -1521,6 +1537,21 @@ int OpenGL::getMaxShaderStorageBufferSize() const
|
||||
return maxShaderStorageBufferSize;
|
||||
}
|
||||
|
||||
int OpenGL::getMaxComputeWorkGroupsX() const
|
||||
{
|
||||
return maxComputeWorkGroupsX;
|
||||
}
|
||||
|
||||
int OpenGL::getMaxComputeWorkGroupsY() const
|
||||
{
|
||||
return maxComputeWorkGroupsY;
|
||||
}
|
||||
|
||||
int OpenGL::getMaxComputeWorkGroupsZ() const
|
||||
{
|
||||
return maxComputeWorkGroupsZ;
|
||||
}
|
||||
|
||||
int OpenGL::getMaxRenderTargets() const
|
||||
{
|
||||
return std::min(maxRenderTargets, MAX_COLOR_RENDER_TARGETS);
|
||||
|
||||
@@ -390,6 +390,14 @@ public:
|
||||
**/
|
||||
int getMaxShaderStorageBufferSize() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum number of compute work groups that can be
|
||||
* dispatched in a given dimension.
|
||||
*/
|
||||
int getMaxComputeWorkGroupsX() const;
|
||||
int getMaxComputeWorkGroupsY() const;
|
||||
int getMaxComputeWorkGroupsZ() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum supported number of simultaneous render targets.
|
||||
**/
|
||||
@@ -474,6 +482,9 @@ private:
|
||||
int maxTextureArrayLayers;
|
||||
int maxTexelBufferSize;
|
||||
int maxShaderStorageBufferSize;
|
||||
int maxComputeWorkGroupsX;
|
||||
int maxComputeWorkGroupsY;
|
||||
int maxComputeWorkGroupsZ;
|
||||
int maxRenderTargets;
|
||||
int maxSamples;
|
||||
int maxTextureUnits;
|
||||
|
||||
@@ -42,8 +42,8 @@ static bool isBuffer(Shader::UniformType utype)
|
||||
return utype == Shader::UNIFORM_TEXELBUFFER || utype == Shader::UNIFORM_STORAGEBUFFER;
|
||||
}
|
||||
|
||||
Shader::Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
|
||||
: love::graphics::Shader(vertex, pixel)
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
: love::graphics::Shader(stages)
|
||||
, program(0)
|
||||
, builtinUniforms()
|
||||
, builtinUniformInfo()
|
||||
|
||||
@@ -43,7 +43,7 @@ class Shader final : public love::graphics::Shader, public Volatile
|
||||
{
|
||||
public:
|
||||
|
||||
Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel);
|
||||
Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]);
|
||||
virtual ~Shader();
|
||||
|
||||
// Implements Volatile
|
||||
|
||||
@@ -53,6 +53,8 @@ bool ShaderStage::loadVolatile()
|
||||
glstage = GL_VERTEX_SHADER;
|
||||
else if (stage == SHADERSTAGE_PIXEL)
|
||||
glstage = GL_FRAGMENT_SHADER;
|
||||
else if (stage == SHADERSTAGE_COMPUTE)
|
||||
glstage = GL_COMPUTE_SHADER;
|
||||
else
|
||||
throw love::Exception("%s shader stage is not handled in OpenGL backend code.", typestr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user