diff --git a/src/Aardvark.Rendering.GL/Core/Context.fs b/src/Aardvark.Rendering.GL/Core/Context.fs index 371eb6030..719a2d1e6 100644 --- a/src/Aardvark.Rendering.GL/Core/Context.fs +++ b/src/Aardvark.Rendering.GL/Core/Context.fs @@ -215,6 +215,8 @@ type Context(runtime : IRuntime, createContext : unit -> ContextHandle) as this let mutable maxComputeWorkGroupInvocations : Option = None + let mutable numProgramBinaryFormats : Option = None + let mutable shaderCachePath : Option = Some defaultShaderCachePath let formatSampleCounts = FastConcurrentDict() @@ -311,6 +313,11 @@ type Context(runtime : IRuntime, createContext : unit -> ContextHandle) as this GL.GetInteger(GetPName.MaxComputeWorkGroupInvocations) ) + member x.NumProgramBinaryFormats = + getOrQuery &numProgramBinaryFormats (fun _ -> + GL.GetInteger(GetPName.NumProgramBinaryFormats) + ) + member internal x.ImportMemoryBlock(external : ExternalMemoryBlock) = sharedMemoryManager.Import external diff --git a/src/Aardvark.Rendering.GL/Core/Extensions/ARB_get_program_binary.fs b/src/Aardvark.Rendering.GL/Core/Extensions/ARB_get_program_binary.fs index 523696562..b03c131e7 100644 --- a/src/Aardvark.Rendering.GL/Core/Extensions/ARB_get_program_binary.fs +++ b/src/Aardvark.Rendering.GL/Core/Extensions/ARB_get_program_binary.fs @@ -22,4 +22,20 @@ module ARB_get_program_binary = if GL.ARB_get_program_binary then GL.GetProgramBinary(program, bufSize, &length, &binaryFormat, binary) else - failwith "glGetProgramBinary is not available." \ No newline at end of file + failwith "glGetProgramBinary is not available." + + static member GetProgramBinary(program : int, length : int) = + let data : byte[] = Array.zeroCreate length + let mutable format = Unchecked.defaultof + let mutable returnedLength = length + GL.Dispatch.GetProgramBinary(program, length, &returnedLength, &format, data) + + if returnedLength = length then + data, format + else + null, format + + static member GetProgramBinaryLength(program : int) = + let mutable result = 0 + GL.GetProgram(program, GetProgramParameterName.ProgramBinaryLength, &result) + result \ No newline at end of file diff --git a/src/Aardvark.Rendering.GL/Resources/Program.fs b/src/Aardvark.Rendering.GL/Resources/Program.fs index c90cad478..3b458773b 100644 --- a/src/Aardvark.Rendering.GL/Resources/Program.fs +++ b/src/Aardvark.Rendering.GL/Resources/Program.fs @@ -435,6 +435,10 @@ module ProgramExtensions = GL.Check "could not create program" try + if GL.ARB_get_program_binary then + GL.ProgramParameter(handle, ProgramParameterName.ProgramBinaryRetrievableHint, 1) + GL.Check "could not set program binary retrievable hint" + for s in shaders do GL.AttachShader(handle, s.Handle) GL.Check "could not attach shader to program" @@ -634,29 +638,28 @@ module ProgramExtensions = module Program = let tryGetBinary (program : Program) = - if GL.ARB_get_program_binary then - GL.GetError() |> ignore + if GL.ARB_get_program_binary && program.Context.NumProgramBinaryFormats > 0 then + let length = GL.Dispatch.GetProgramBinaryLength program.Handle + GL.Check "failed to get program binary length" - let mutable length = 0 - GL.GetProgram(program.Handle, GetProgramParameterName.ProgramBinaryLength, &length) + if length > 0 then + let data, format = GL.Dispatch.GetProgramBinary(program.Handle, length) + GL.Check "failed to get program binary" - let err = GL.GetError() - if err <> ErrorCode.NoError then - Log.warn "[GL] Failed to query program binary length: %A" err - None - else - let data : byte[] = Array.zeroCreate length - let mutable format = Unchecked.defaultof - GL.GetProgramBinary(program.Handle, length, &length, &format, data) - - let err = GL.GetError() - if err <> ErrorCode.NoError then - Log.warn "[GL] Failed to retrieve program binary: %A" err + if isNull data then + Log.warn "[GL] Failed to retrieve program binary" None else Some (format, data) + else + Log.warn "[GL] Program binary length is zero bytes" + None else - Report.Line(4, "[GL] Cannot read shader cache because GL_ARB_get_program_binary is not supported") + let reason = + if GL.ARB_get_program_binary then "no binary formats are supported" + else "GL_ARB_get_program_binary is not supported" + + Report.Line(4, $"[GL] Cannot read shader cache because {reason}") None let ofShaderCacheEntry (context : Context) (fixBindings : bool) (entry : ShaderCacheEntry) =