diff --git a/src/Libs/FShade.GLSL/Assembler.fs b/src/Libs/FShade.GLSL/Assembler.fs index fceee20..8b0a285 100644 --- a/src/Libs/FShade.GLSL/Assembler.fs +++ b/src/Libs/FShade.GLSL/Assembler.fs @@ -1438,8 +1438,13 @@ module Assembler = | Some fmt -> fmt | _ -> t.Name - let private uniformLayout (isUniformBuffer : bool) (decorations : list) (set : int) (binding : int) = + // For some reason we use std430 for storage buffers but std140 for uniform buffers + type private Layout = + | None = 0 + | Std140 = 1 + | Std430 = 2 + let private uniformLayout (layout : Layout) (decorations : list) (set : int) (binding : int) = let decorations = decorations |> List.choose (fun d -> match d with @@ -1458,8 +1463,13 @@ module Assembler = else decorations let decorations = - if isUniformBuffer then "std140" :: decorations - else decorations + let layout = + match layout with + | Layout.Std430 -> ["std430"] + | Layout.Std140 -> ["std140"] + | _ -> [] + + layout @ decorations match decorations with | [] -> "" @@ -1529,7 +1539,7 @@ module Assembler = fields |> List.mapS (fun field -> state { let! binding = getBinding InputKind.StorageBuffer 1 [field] - let prefix = uniformLayout false [] set binding + let prefix = uniformLayout Layout.Std430 [] set binding let name = checkName field.cUniformName match field.cUniformType with @@ -1559,7 +1569,7 @@ module Assembler = | Some bufferName when config.createUniformBuffers -> let bufferName = checkName bufferName let! binding = getBinding InputKind.UniformBuffer 1 fields - let prefix = uniformLayout true [] set binding + let prefix = uniformLayout Layout.Std140 [] set binding let fieldStr = fields |> List.map (fun u -> @@ -1588,7 +1598,7 @@ module Assembler = match t with | GLSLTextureType.GLSLSampler samplerType -> let! binding = getBinding InputKind.Sampler cnt [u] - prefix <- uniformLayout false u.cUniformDecorations set binding + prefix <- uniformLayout Layout.None u.cUniformDecorations set binding do! Interface.addSampler { samplerSet = set @@ -1601,7 +1611,7 @@ module Assembler = | GLSLTextureType.GLSLImage imageType -> let! binding = getBinding InputKind.Image cnt [u] - prefix <- uniformLayout false u.cUniformDecorations set binding + prefix <- uniformLayout Layout.None u.cUniformDecorations set binding do! Interface.addImage { imageSet = set @@ -1612,7 +1622,7 @@ module Assembler = | CAccelerationStructure -> let! binding = getBinding InputKind.AccelerationStructure 1 [u] - prefix <- uniformLayout false u.cUniformDecorations set binding + prefix <- uniformLayout Layout.None u.cUniformDecorations set binding do! Interface.addAccelerationStructure { accelSet = set @@ -1622,7 +1632,7 @@ module Assembler = | _ -> let! binding = getBinding InputKind.UniformBuffer 1 [u] - prefix <- uniformLayout false u.cUniformDecorations set binding + prefix <- uniformLayout Layout.None u.cUniformDecorations set binding () diff --git a/src/Tests/FShade.GLSL.Tests/SimpleTests.fs b/src/Tests/FShade.GLSL.Tests/SimpleTests.fs index 2d76be0..0f3cf10 100644 --- a/src/Tests/FShade.GLSL.Tests/SimpleTests.fs +++ b/src/Tests/FShade.GLSL.Tests/SimpleTests.fs @@ -1234,4 +1234,35 @@ let ``Uniform alias with mismatching scope``() = e.Shaders |> ignore ) - Assert.That(exn.Message, Does.Contain "has conflicting values") \ No newline at end of file + Assert.That(exn.Message, Does.Contain "has conflicting values") + +[] +let ``Uniform and storage buffers use std140 and std430 layout``() = + Setup.Run() + + let fs (v : Vertex) = + fragment { + return uniform.RegionBuffer.[0] + } + + let fsu (v : Vertex) = + fragment { + return uniform.SomeUniformArr.[0] + } + + let cs (mybuffer : int[]) = + compute { + let id = getGlobalId().XY + mybuffer.[id.X] <- id.Y + } + + GLSL.shouldCompileAndContainRegex [ Effect.ofFunction fs ] [ "std430" ] + GLSL.shouldCompileAndContainRegex [ Effect.ofFunction fsu ] [ "std140" ] + + let glsl = + cs + |> ComputeShader.ofFunction (V3i(128,128,128)) + |> ComputeShader.toModule + |> ModuleCompiler.compileGLSL430 + + GLSL.shouldContainRegex glsl [ "std430", None ] \ No newline at end of file