Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enable to build SkyBoxAsset using OpenGL #2504

Merged
merged 1 commit into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ protected override void Prepare(AssetCompilerContext context, AssetItem assetIte
var textureAssetItem = new AssetItem(textureUrl, textureAsset);

// Create and add the texture command.
var textureParameters = new TextureConvertParameters(assetSource, textureAsset, PlatformType.Windows, GraphicsPlatform.Direct3D11, graphicsProfile, gameSettingsAsset.GetOrCreate<TextureSettings>().TextureQuality, colorSpace);
var textureParameters = new TextureConvertParameters(assetSource, textureAsset, context.Platform, context.Platform.GetDefaultGraphicsPlatform(), graphicsProfile, gameSettingsAsset.GetOrCreate<TextureSettings>().TextureQuality, colorSpace);
var prereqStep = new AssetBuildStep(textureAssetItem);
prereqStep.Add(new TextureAssetCompiler.TextureConvertCommand(textureUrl, textureParameters, assetItem.Package));
result.BuildSteps.Add(prereqStep);
Expand Down
15 changes: 8 additions & 7 deletions sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -658,23 +658,24 @@ protected unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfile
#endif

#if STRIDE_UI_SDL
gameWindow = (Stride.Graphics.SDL.Window)windowHandle.NativeWindow;
// NOTE : This null handling is specific for Linux AssetCompiler #2504 (refactor required?)
gameWindow = windowHandle?.NativeWindow as SDL.Window ?? new SDL.Window("");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this new window for ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dump window is created to initialize the SDLContext which is then used for the OpenGL api as a context (see 699 line).
The author assumed when casting that the windowhandle object was not null but it wasn't, so I handled it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For opengl on windows this would load in sdl when using a winforms window then ?

Also, shouldn't it be initialized/set in a more appropriate spot then ? I.E.: ensure window is init first and has a native window handle, then this scope is called and retrieves the window without creating one ?

Copy link
Collaborator Author

@Jklawreszuk Jklawreszuk Oct 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it comes to Windows, from what I've noticed, Stride Asset Compiler (always) uses DirectX on Windows to compile assets and I haven't changed that. My change only applies to Linux (or MacOs if someone has decided to support it). So short answer is no

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the second question, this window object is used before the game starts so it will always be null. Also, I am not sure it even creates "real" window because Silk has command for this : SDL.CreateWindow()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently no one predicted it would be possible to run on Linux in the future 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyways, If you have any suggestions feel free to give any ideas

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why the OGL stuff requires a window when the D3d one doesn't, but that's best left to a proper refactor I guess.
Can you split the ternary into a specific line with a comment mentioning that this is a workaround specifically for the asset compiler ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Eideren Sure, Done!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong, but I think OpenGL has always needed a window to establish its context (the surface where to draw). Direct3D also needed it up until D3D9, but if I remember it correctly, it was D3D10 or 11 that started to allow setting up a swapchain without an associated HWND.
As Xenko supported both D3D9 and OpenGL, that may be the reason for requiring a window. Now that D3D9 is deprecated and D3D11 no longer needs it, only OpenGL is left with that requirement (as Vulkan can also render without a window).


var SDL = Graphics.SDL.Window.SDL;

#if STRIDE_GRAPHICS_API_OPENGLES
SDL.GLSetAttribute(GLattr.GLContextProfileMask, (int)GLprofile.GLContextProfileES);
SDL.GLSetAttribute(GLattr.ContextProfileMask, (int)GLprofile.ES);
#else
SDL.GLSetAttribute(GLattr.GLContextProfileMask, (int)GLprofile.GLContextProfileCore);
SDL.GLSetAttribute(GLattr.ContextProfileMask, (int)GLprofile.Core);
#endif


if (IsDebugMode)
SDL.GLSetAttribute(GLattr.GLContextFlags, (int)GLcontextFlag.GLContextDebugFlag);
SDL.GLSetAttribute(GLattr.ContextFlags, (int)GLcontextFlag.DebugFlag);

// Setup version
SDL.GLSetAttribute(GLattr.GLContextMajorVersion, currentVersion / 100);
SDL.GLSetAttribute(GLattr.GLContextMinorVersion, (currentVersion / 10) % 10);
SDL.GLSetAttribute(GLattr.ContextMajorVersion, currentVersion / 100);
SDL.GLSetAttribute(GLattr.ContextMinorVersion, (currentVersion / 10) % 10);

MainGraphicsContext = new SdlContext(SDL, (Silk.NET.SDL.Window*)gameWindow.SdlHandle);
((SdlContext)MainGraphicsContext).Create();
Expand All @@ -690,7 +691,7 @@ protected unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfile
#endif

// Create shared context for creating graphics resources from other threads
SDL.GLSetAttribute(GLattr.GLShareWithCurrentContext, 1);
SDL.GLSetAttribute(GLattr.ShareWithCurrentContext, 1);
deviceCreationContext = new SdlContext(SDL, (Silk.NET.SDL.Window*)gameWindow.SdlHandle);
((SdlContext)deviceCreationContext).Create();

Expand Down
6 changes: 3 additions & 3 deletions sources/engine/Stride.Graphics/OpenGL/Texture.OpenGL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,11 @@ private void CreateTexture2DArray(bool compressed, int width, int height, int mi
{
if (compressed)
{
GL.CompressedTexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) ArraySize, border: 0, imageSize: 0, data: IntPtr.Zero);
GL.CompressedTexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) ArraySize, border: 0, imageSize: 0, data: null);
}
else
{
GL.TexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) ArraySize, border: 0, TextureFormat, TextureType, IntPtr.Zero);
GL.TexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) ArraySize, border: 0, TextureFormat, TextureType, null);
}
}

Expand Down Expand Up @@ -620,7 +620,7 @@ internal uint GeneratePixelBufferObject(BufferTargetARB target, PixelStoreParame
GL.BindBuffer(target, result);
if (RowPitch < 4)
GL.PixelStore(alignment, 1);
GL.BufferData(target, (UIntPtr) totalSize, IntPtr.Zero, bufferUsage);
GL.BufferData(target, (UIntPtr) totalSize, null, bufferUsage);
GL.BindBuffer(target, 0);

return result;
Expand Down
9 changes: 3 additions & 6 deletions sources/engine/Stride.Graphics/Texture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -474,10 +474,7 @@ internal Texture InitializeFrom(Texture parentTexture, TextureViewDescription vi
internal Texture InitializeFrom(Texture parentTexture, TextureDescription description, TextureViewDescription viewDescription, DataBox[] textureDatas = null)
{
ParentTexture = parentTexture;
if (ParentTexture != null)
{
ParentTexture.AddReferenceInternal();
}
ParentTexture?.AddReferenceInternal();

textureDescription = description;
textureViewDescription = viewDescription;
Expand Down Expand Up @@ -1143,8 +1140,8 @@ public Image GetDataAsImage(CommandList commandList)
if (Usage == GraphicsResourceUsage.Staging)
return GetDataAsImage(commandList, this); // Directly if this is a staging resource

using (var stagingTexture = ToStaging())
return GetDataAsImage(commandList, stagingTexture);
using var stagingTexture = ToStaging();
return GetDataAsImage(commandList, stagingTexture);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Stride.Rendering.Images
{
var u = 0.0;
var p = 0.5;
for (int kk=k; kk; p*=0.5, kk>>=1)
for (int kk=k; kk > 0; p*=0.5, kk>>=1)
{
if (kk & 1) // kk mod 2 == 1
u += p;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,41 +96,37 @@ protected override void DrawCore(RenderDrawContext context)
{
for (int faceIndex = 0; faceIndex < faceCount; faceIndex++)
{
using (var outputView = output.ToTextureView(ViewType.Single, faceIndex, mipLevel))
using var outputView = output.ToTextureView(ViewType.Single, faceIndex, mipLevel);
var inputLevel = MathUtil.Log2(input.Width / output.Width);
if (mipLevel == 0 && DoNotFilterHighestLevel)
{
var inputLevel = MathUtil.Log2(input.Width / output.Width);
if (mipLevel == 0 && DoNotFilterHighestLevel)
if (input.Width >= output.Width && inputLevel < input.MipLevels && input.Format == output.Format)
{
if (input.Width >= output.Width && inputLevel < input.MipLevels && input.Format == output.Format)
{
// Optimization: make a simple copy of the texture when possible
var inputSubresource = inputLevel + faceIndex * input.MipLevels;
var outputSubresource = 0 + faceIndex * output.MipLevels;
context.CommandList.CopyRegion(input, inputSubresource, null, output, outputSubresource);
}
else // otherwise rescale the closest mipmap
{
var inputMipmapLevel = Math.Min(inputLevel, input.MipLevels - 1);
using (var inputView = input.ToTextureView(ViewType.Single, faceIndex, inputMipmapLevel))
{
scaler.SetInput(inputView);
scaler.SetOutput(outputView);
scaler.Draw(context);
}
}
// Optimization: make a simple copy of the texture when possible
var inputSubresource = inputLevel + faceIndex * input.MipLevels;
var outputSubresource = 0 + faceIndex * output.MipLevels;
context.CommandList.CopyRegion(input, inputSubresource, null, output, outputSubresource);
}
else
else // otherwise rescale the closest mipmap
{
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.Face, faceIndex);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.Roughness, roughness);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.MipmapCount, input.MipLevels - 1);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.RadianceMap, input);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.RadianceMapSize, input.Width);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeParams.NbOfSamplings, SamplingsCount);
shader.SetOutput(outputView);
shader.Draw(context);
var inputMipmapLevel = Math.Min(inputLevel, input.MipLevels - 1);
using var inputView = input.ToTextureView(ViewType.Single, faceIndex, inputMipmapLevel);
scaler.SetInput(inputView);
scaler.SetOutput(outputView);
scaler.Draw(context);
}
}
else
{
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.Face, faceIndex);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.Roughness, roughness);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.MipmapCount, input.MipLevels - 1);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.RadianceMap, input);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeShaderKeys.RadianceMapSize, input.Width);
shader.Parameters.Set(RadiancePrefilteringGGXNoComputeParams.NbOfSamplings, SamplingsCount);
shader.SetOutput(outputView);
shader.Draw(context);
}
}

if (mipCount > 1)
Expand Down