Skip to content

Commit

Permalink
[GL] Improve querying of supported sample counts
Browse files Browse the repository at this point in the history
- Estimation of supported sample counts is more accurate
for textures if format queries are not supported. Takes into account
parameters such as GL_MAX_SAMPLES now.
- For framebuffer signatures the formats of the attachments are
considered rather than just checking parameters such as
GL_MAX_FRAMEBUFFER_SAMPLES.
  • Loading branch information
hyazinthh committed Apr 30, 2024
1 parent ea7f522 commit 812091b
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 40 deletions.
92 changes: 76 additions & 16 deletions src/Aardvark.Rendering.GL/Core/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context

let mutable numProgramBinaryFormats : Option<int> = None

let mutable maxSamples : Option<int> = None

let mutable maxColorTextureSamples : Option<int> = None

let mutable maxIntegerSamples : Option<int> = None

let mutable maxDepthTextureSamples : Option<int> = None

let mutable maxFramebufferSamples : Option<int> = None

let mutable shaderCachePath : Option<string> = Some defaultShaderCachePath

let formatSampleCounts = FastConcurrentDict()
Expand All @@ -240,11 +250,12 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context

let sharedMemoryManager = SharedMemoryManager(fun _ -> this.ResourceLock)

let getOrQuery (var : byref<'T option>) (query : unit -> 'T) =
let getOrQuery (description : string) (var : byref<'T option>) (query : unit -> 'T) =
match var with
| None ->
use __ = this.ResourceLock
let value = query()
GL.Check $"Failed to query {description}"
var <- Some value
value
| Some v -> v
Expand Down Expand Up @@ -278,48 +289,48 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context
member x.Runtime = runtime

member x.Driver =
getOrQuery &driverInfo Driver.readInfo
getOrQuery "driver info" &driverInfo Driver.readInfo

member x.PackAlignment =
getOrQuery &packAlignment (fun _ ->
getOrQuery "pack alignment" &packAlignment (fun _ ->
GL.GetInteger(GetPName.PackAlignment)
)

member x.UnpackAlignment =
getOrQuery &unpackAlignment (fun _ ->
getOrQuery "unpack alignment" &unpackAlignment (fun _ ->
GL.GetInteger(GetPName.UnpackAlignment)
)

member x.MaxTextureSize =
getOrQuery &maxTextureSize (fun _ ->
getOrQuery "max texture size" &maxTextureSize (fun _ ->
let s = GL.GetInteger(GetPName.MaxTextureSize)
V2i s
)

member x.MaxTextureSize3D =
getOrQuery &maxTextureSize3d (fun _ ->
getOrQuery "max 3D texture size" &maxTextureSize3d (fun _ ->
let s = GL.GetInteger(GetPName.Max3DTextureSize)
V3i s
)

member x.MaxTextureSizeCube =
getOrQuery &maxTextureSizeCube (fun _ ->
getOrQuery "max cube texture size" &maxTextureSizeCube (fun _ ->
GL.GetInteger(GetPName.MaxCubeMapTextureSize)
)

member x.MaxTextureArrayLayers =
getOrQuery &maxTextureArrayLayers (fun _ ->
getOrQuery "max texture array layers" &maxTextureArrayLayers (fun _ ->
GL.GetInteger(GetPName.MaxArrayTextureLayers)
)

member x.MaxRenderbufferSize =
getOrQuery &maxRenderbufferSize (fun _ ->
getOrQuery "max renderbuffer size" &maxRenderbufferSize (fun _ ->
let s = GL.GetInteger(GetPName.MaxRenderbufferSize)
V2i s
)

member x.MaxComputeWorkGroupSize =
getOrQuery &maxComputeWorkGroupSize (fun _ ->
getOrQuery "max compute work group size" &maxComputeWorkGroupSize (fun _ ->
let mutable res = V3i.Zero
GL.GetInteger(GetIndexedPName.MaxComputeWorkGroupSize, 0, &res.X)
GL.GetInteger(GetIndexedPName.MaxComputeWorkGroupSize, 1, &res.Y)
Expand All @@ -328,15 +339,40 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context
)

member x.MaxComputeWorkGroupInvocations =
getOrQuery &maxComputeWorkGroupInvocations (fun _ ->
getOrQuery "max compute work group invocations" &maxComputeWorkGroupInvocations (fun _ ->
GL.GetInteger(GetPName.MaxComputeWorkGroupInvocations)
)

member x.NumProgramBinaryFormats =
getOrQuery &numProgramBinaryFormats (fun _ ->
getOrQuery "number of program binary formats" &numProgramBinaryFormats (fun _ ->
GL.GetInteger(GetPName.NumProgramBinaryFormats)
)

member x.MaxSamples =
getOrQuery "max samples" &maxSamples (fun _ ->
GL.GetInteger(GetPName.MaxSamples)
)

member x.MaxColorTextureSamples =
getOrQuery "max color texture samples" &maxColorTextureSamples (fun _ ->
GL.GetInteger(GetPName.MaxColorTextureSamples)
)

member x.MaxIntegerSamples =
getOrQuery "max integer samples" &maxIntegerSamples (fun _ ->
GL.GetInteger(GetPName.MaxIntegerSamples)
)

member x.MaxDepthTextureSamples =
getOrQuery "max depth texture samples" &maxDepthTextureSamples (fun _ ->
GL.GetInteger(GetPName.MaxDepthTextureSamples)
)

member x.MaxFramebufferSamples =
getOrQuery "max framebuffer samples" &maxFramebufferSamples (fun _ ->
GL.GetInteger(unbox<GetPName> 0x9318)
)

member internal x.ImportMemoryBlock(external : ExternalMemoryBlock) =
sharedMemoryManager.Import external

Expand Down Expand Up @@ -423,6 +459,29 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context
/// </summary>
member internal x.GetFormatSamples(target : ImageTarget, format : TextureFormat) =
formatSampleCounts.GetOrCreate((target, format), fun _ ->
let estimate() =
let maxSamples =
[
x.MaxSamples

if format.IsColorRenderable then
x.MaxColorTextureSamples

if format.IsIntegerFormat then
x.MaxIntegerSamples

if format.HasDepth || format.HasStencil then
x.MaxDepthTextureSamples
]
|> List.min
|> max 1

Report.Line(3, $"[GL] Internal format queries not supported, assuming up to {maxSamples} are supported (target = {target}, format = {format})")

[1; 2; 4; 8; 16; 32; 64]
|> List.filter ((>=) maxSamples)
|> Set.ofList

if GL.ARB_internalformat_query then
let format = TextureFormat.toSizedInternalFormat format

Expand All @@ -433,12 +492,13 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context
let buffer = GL.Dispatch.GetInternalformat(target, format, InternalFormatParameter.Samples, count)
GL.Check "could not query sample counts"

Set.ofArray buffer
buffer
|> Set.ofArray
|> Set.add 1
else
Set.empty
estimate()
else
Log.warn "[GL] Internal format queries not supported, assuming all sample counts are supported (target = %A, format = %A)" target format
Set.ofList [1; 2; 4; 8; 16; 32; 64]
estimate()
)

/// <summary>
Expand Down
56 changes: 35 additions & 21 deletions src/Aardvark.Rendering.GL/Resources/FramebufferSignature.fs
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,42 @@ module internal FramebufferSignatureContextExtensions =
perLayerUniforms : Set<string>) =
use __ = x.ResourceLock

let maxSamples =
let counts = [
if not colorAttachments.IsEmpty then
GL.GetInteger(GetPName.MaxColorTextureSamples)

if colorAttachments |> Map.exists (fun _ att -> att.Format.IsIntegerFormat) then
GL.GetInteger(GetPName.MaxIntegerSamples)

if depthStencilAttachment.IsSome then
GL.GetInteger(GetPName.MaxDepthTextureSamples)
]

if counts.IsEmpty then GL.GetInteger(GetPName.MaxFramebufferSamples)
else List.min counts

GL.Check "could not query maximum samples for framebuffer signature"

let samples =
if samples > maxSamples then
Log.warn "[GL] cannot create framebuffer signature with %d samples (using %d instead)" samples maxSamples
maxSamples
if samples = 1 then samples
else
samples
let framebufferMaxSamples = max 1 x.MaxFramebufferSamples

let get fmt =
let rb = x.GetFormatSamples(ImageTarget.Renderbuffer, fmt)
let tex = x.GetFormatSamples(ImageTarget.Texture2DMultisample, fmt)
Set.union rb tex

let counts =
let all =
Set.ofList [1; 2; 4; 8; 16; 32; 64]

let color =
colorAttachments
|> Seq.map (_.Value.Format >> get)
|> List.ofSeq

let depthStencil =
depthStencilAttachment
|> Option.map get
|> Option.toList

all :: (color @ depthStencil)
|> Set.intersectMany
|> Set.filter ((>=) framebufferMaxSamples)

if counts.Contains samples then samples
else
let fallback =
counts
|> Set.toList
|> List.minBy ((-) samples >> abs)

Log.warn "[GL] Cannot create framebuffer signature with %d samples (using %d instead)" samples fallback
fallback

new FramebufferSignature(x.Runtime, colorAttachments, depthStencilAttachment, samples, layers, perLayerUniforms)
5 changes: 2 additions & 3 deletions src/Aardvark.Rendering.GL/Resources/Textures/Texture.fs
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,9 @@ module internal TextureUtilitiesAndExtensions =
let fallback =
counts
|> Set.toList
|> List.sortBy ((-) samples >> abs)
|> List.head
|> List.minBy ((-) samples >> abs)

Log.warn "[GL] cannot create %A image with %d samples (using %d instead)" format samples fallback
Log.warn "[GL] Cannot create %A image with %d samples (using %d instead)" format samples fallback
fallback
else
1
Expand Down

0 comments on commit 812091b

Please sign in to comment.