Browse Source

Compute shader docs;

bjorn 7 years ago
parent
commit
4bde8ef3df

+ 21 - 0
api/lovr/graphics/Shader/getType.lua

@@ -0,0 +1,21 @@
+return {
+  summary = 'Get the type of the Shader.',
+  description = [[
+    Returns the type of the Shader, which will be "graphics" or "compute".
+
+    Graphics shaders are created with `lovr.graphics.newShader` and can be used for rendering with
+    `lovr.graphics.setShader`.  Compute shaders are created with `lovr.graphics.newComputeShader`
+    and can be run using `lovr.graphics.compute`.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'type',
+      type = 'ShaderType',
+      description = 'The type of the Shader.'
+    }
+  },
+  related = {
+    'ShaderType'
+  }
+}

+ 33 - 1
api/lovr/graphics/Shader/init.lua

@@ -5,7 +5,10 @@ return {
     They can be used for lighting, postprocessing, particles, animation, and much more.  You can use
     `lovr.graphics.setShader` to change the active Shader.
   ]],
-  constructor = 'lovr.graphics.newShader',
+  constructors = {
+    'lovr.graphics.newShader',
+    'lovr.graphics.newComputeShader'
+  },
   notes = [[
     The current GLSL version used is 150.
 
@@ -64,6 +67,34 @@ return {
         in vec4 vertexColor;
         in vec4 gl_FragCoord;
         out vec4 lovrFragColor;
+
+    ### Compute Shaders
+
+    Compute shaders can be created with `lovr.graphics.newComputeShader` and run with
+    `lovr.graphics.compute`.  Currently, compute shaders are written with raw GLSL.  There is no
+    default compute shader, instead the `void compute();` function must be implemented.
+
+    You can use the `layout` qualifier to specify a local work group size:
+
+        layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in;
+
+    And the following built in variables can be used:
+
+        in uvec3 gl_NumWorkGroups;      // The size passed to lovr.graphics.compute
+        in uvec3 gl_WorkGroupSize;      // The local work group size
+        in uvec3 gl_WorkGroupID;        // The current global work group
+        in uvec3 gl_LocalInvocationID;  // The current local work group
+        in uvec3 gl_GlobalInvocationID; // A unique ID combining the global and local IDs
+
+    Compute shaders don't return anything but they can write data to `Texture`s or `ShaderBlock`s.
+    To bind a texture in a way that can be written to a compute shader, declare the uniforms with a
+    type of `image2D`, `imageCube`, etc. instead of the usual `sampler2D` or `samplerCube`.  Once a
+    texture is bound to an image uniform, you can use the `imageLoad` and `imageStore` GLSL
+    functions to read and write pixels in the image.  Variables in `ShaderBlock`s can be written to
+    using assignment syntax.
+
+    LÖVR handles synchronization of textures and shader blocks so there is no need to use manual
+    memory barriers to synchronize writes to resources from compute shaders.
   ]],
   example = {
     description = 'Set a simple shader that colors pixels based on vertex normals.',
@@ -93,6 +124,7 @@ return {
     ]=]
   },
   related = {
+    'lovr.graphics.newComputeShader',
     'lovr.graphics.setShader',
     'lovr.graphics.getShader'
   }

+ 24 - 0
api/lovr/graphics/ShaderType.lua

@@ -0,0 +1,24 @@
+return {
+  summary = 'Different types of shaders.',
+  description = [[
+    Shaders can be used for either rendering operations or generic compute tasks.  Graphics shaders
+    are created with `lovr.graphics.newShader` and compute shaders are created with
+    `lovr.graphics.newComputeShader`.  `Shader:getType` can be used on an existing Shader to figure
+    out what type it is.
+  ]],
+  values = {
+    {
+      name = 'graphics',
+      description = 'A graphics shader.'
+    },
+    {
+      name = 'stream',
+      description = 'A compute shader.'
+    }
+  },
+  related = {
+    'Shader',
+    'lovr.graphics.newShader',
+    'lovr.graphics.newComputeShader'
+  }
+}

+ 46 - 0
api/lovr/graphics/compute.lua

@@ -0,0 +1,46 @@
+return {
+  tag = 'graphicsPrimitives',
+  summary = 'Run a compute shader.',
+  description = [[
+    This function runs a compute shader on the GPU.  Compute shaders must be created with
+    `lovr.graphics.newComputeShader` and they should implement the `void compute();` GLSL function.
+    Running a compute shader doesn't actually do anything, but the Shader can modify data stored in
+    `Texture`s or `ShaderBlock`s to get interesting things to happen.
+
+    When running the compute shader, you can specify the number of times to run it in 3 dimensions,
+    which is useful to iterate over large numbers of elements like pixels or array elements.
+  ]],
+  arguments = {
+    {
+      name = 'shader',
+      type = 'Shader',
+      description = 'The compute shader to run.'
+    },
+    {
+      name = 'x',
+      type = 'number',
+      default = '1',
+      description = 'The amount of times to run in the x direction.'
+    },
+    {
+      name = 'y',
+      type = 'number',
+      default = '1',
+      description = 'The amount of times to run in the y direction.'
+    },
+    {
+      name = 'z',
+      type = 'number',
+      default = '1',
+      description = 'The amount of times to run in the z direction.'
+    }
+  },
+  returns = {},
+  notes = 'Only compute shaders created with `lovr.graphics.newComputeShaders` can be used here.',
+  related = {
+    'lovr.graphics.newComputeShader',
+    'lovr.graphics.getShader',
+    'lovr.graphics.setShader',
+    'Shader'
+  }
+}

+ 37 - 0
api/lovr/graphics/newComputeShader.lua

@@ -0,0 +1,37 @@
+return {
+  tag = 'graphicsObjects',
+  summary = 'Create a new compute Shader.',
+  description = [[
+    Creates a new compute Shader, used for running generic compute operations on the GPU.
+  ]],
+  arguments = {
+    {
+      name = 'source',
+      type = 'string',
+      description = 'The code or filename of the compute shader.'
+    }
+  },
+  returns = {
+    {
+      name = 'shader',
+      type = 'Shader',
+      description = 'The new compute Shader.'
+    }
+  },
+  notes = [[
+    Compute shaders are not supported on all hardware, use `lovr.graphics.getSupported` to check
+    if they're available on the current system.
+
+    The source code for a compute shader needs to implement the `void compute();` GLSL function.
+    This function doesn't return anything, but the compute shader is able to write data out to
+    `Texture`s or `ShaderBlock`s.
+
+    The GLSL version used for compute shaders is GLSL 430.
+  ]],
+  related = {
+    'lovr.graphics.compute',
+    'lovr.graphics.newShader',
+    'lovr.graphics.setShader',
+    'lovr.graphics.getShader'
+  }
+}