Remove deprecated and unsued OpenGL backend

This commit is contained in:
Wojtek Figat
2020-12-30 11:27:37 +01:00
parent 4c205be617
commit 5e469a0ae3
68 changed files with 5 additions and 26520 deletions

View File

@@ -124,20 +124,6 @@ void SplashScreen::Show()
if (IsVisible() || CommandLine::Options.Headless)
return;
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
// Notes:
// We cannot show splash screen on OpenGL because it sucks.
// Actually it's because the first window we show (it should be the main editor window)
// the OpenGL backend will use its context to submit all graphics commands.
// also other contexts (child windows, tooltip windows, etc.)
// will share the main context command line.
// TODO: we could show the splash screen after the main window is created!
LOG(Warning, "The current platform does not support showing splash screen.");
#else
LOG(Info, "Showing splash screen");
// Create window
@@ -203,7 +189,6 @@ void SplashScreen::Show()
}
_window->Show();
#endif
}
void SplashScreen::Close()

View File

@@ -33,11 +33,7 @@
#define GPU_ALLOW_PROFILE_EVENTS (!BUILD_RELEASE)
// Enable/disable creating GPU resources on separate threads (otherwise only the main thread can be used)
#if GRAPHICS_API_OPENGL
#define GPU_ENABLE_ASYNC_RESOURCES_CREATION 0
#else
#define GPU_ENABLE_ASYNC_RESOURCES_CREATION 1
#endif
// Enable/disable force shaders recompilation
#define GPU_FORCE_RECOMPILE_SHADERS 0

View File

@@ -1,22 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/Config.h"
// Flax uses DirectX versioning to switch between graphics features.
// Version mapping:
// DirectX 10 = OpenGL ES 3.0 = OpenGL 4.1
// DirectX 11 = OpenGl ES 3.1 = OpenGL 4.4
#define SHADER_DATA_FORMAT_RAW 0
#define SHADER_DATA_FORMAT_LZ4 1
// Enables force OpenGL shaders verification
#define GPU_OGL_DEBUG_SHADERS 1
// True if use OpenGL Debug Layer
#define GPU_OGL_USE_DEBUG_LAYER GPU_ENABLE_DIAGNOSTICS
// True if don't release the OpenGL shaders source code, can be used to debug rendering
#define GPU_OGL_KEEP_SHADER_SRC GPU_ENABLE_DIAGNOSTICS

View File

@@ -1,11 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_WINDOWS
#include "Win32/Win32ContextOGL.h"
typedef Win32ContextOGL ContextOGL;
#endif

View File

@@ -1,167 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "FBOCache.h"
#if GRAPHICS_API_OPENGL
#include "TextureOGL.h"
#include "RenderToolsOGL.h"
FBOCache::FBOCache()
: Table(2048)
{
}
FBOCache::~FBOCache()
{
Dispose();
}
GLuint FBOCache::GetFBO(uint32 rtCount, GPUTextureViewOGL* depthStencil, GPUTextureViewOGL* rts[])
{
ASSERT(rtCount > 0 || depthStencil != nullptr);
Key key(rtCount, depthStencil, rts);
GLuint fbo;
if (!Table.TryGet(key, fbo))
{
// Create new FBO
glGenFramebuffers(1, &fbo);
VALIDATE_OPENGL_RESULT();
// Bind FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
VALIDATE_OPENGL_RESULT();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
VALIDATE_OPENGL_RESULT();
// Initialize FBO
for (int32 i = 0; i < rtCount; i++)
{
rts[i]->AttachToFramebuffer(GL_COLOR_ATTACHMENT0 + i);
}
if(depthStencil)
{
GLenum attachmentPoint = PixelFormatExtensions::HasStencil(depthStencil->GetFormat()) ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
depthStencil->AttachToFramebuffer(attachmentPoint);
}
// We now need to set mapping between shader outputs and
// color attachments. This largely redundant step is performed
// by glDrawBuffers()
static const GLenum DrawBuffers[] =
{
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3,
GL_COLOR_ATTACHMENT4,
GL_COLOR_ATTACHMENT5,
GL_COLOR_ATTACHMENT6,
GL_COLOR_ATTACHMENT7,
GL_COLOR_ATTACHMENT8,
GL_COLOR_ATTACHMENT9,
GL_COLOR_ATTACHMENT10,
GL_COLOR_ATTACHMENT11,
GL_COLOR_ATTACHMENT12,
GL_COLOR_ATTACHMENT13,
GL_COLOR_ATTACHMENT14,
GL_COLOR_ATTACHMENT15
};
// The state set by glDrawBuffers() is part of the state of the framebuffer.
// So it can be set up once and left it set.
glDrawBuffers(rtCount, DrawBuffers);
VALIDATE_OPENGL_RESULT();
// Validate
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
const Char* str = TEXT("Unknown");
switch (status)
{
#define STATUS_TO_STR(name) case name: str = TEXT(#name); break
STATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
STATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
STATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
STATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
STATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
STATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
STATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS);
#undef STATUS_TO_STR
}
LOG(Error, "Framebuffer is incomplete. Status: {0}", str);
}
// Register in cache
Table.Add(key, fbo);
}
return fbo;
}
void FBOCache::OnTextureRelease(TextureOGL* texture)
{
for (auto i = Table.Begin(); i.IsNotEnd(); ++i)
{
if (i->Key.HasReference(texture))
{
GLuint fbo = i->Value;
glDeleteFramebuffers(1, &fbo);
Table.Remove(i);
}
}
}
void FBOCache::Dispose()
{
for (auto i = Table.Begin(); i.IsNotEnd(); ++i)
{
GLuint fbo = i->Value;
glDeleteFramebuffers(1, &fbo);
}
Table.Clear();
}
FBOCache::Key::Key(uint32 rtCount, GPUTextureViewOGL* depthStencil, GPUTextureViewOGL* rts[])
{
Hash = rtCount * 371;
HashCombinePointer(Hash, depthStencil);
RTCount = rtCount;
DepthStencil = depthStencil;
for (int32 i = 0; i < rtCount; i++)
{
RT[i] = rts[i];
HashCombinePointer(Hash, rts[i]);
}
}
bool FBOCache::Key::HasReference(TextureOGL* texture)
{
for (int32 i = 0; i < RTCount; i++)
{
if (RT[i] && RT[i]->GetTexture() == texture)
return true;
}
return (DepthStencil && DepthStencil->GetTexture() == texture);
}
bool FBOCache::Key::operator==(const Key & other) const
{
if (Hash != 0 && other.Hash != 0 && Hash != other.Hash)
return false;
if (RTCount != other.RTCount)
return false;
for (int32 rt = 0; rt < RTCount; rt++)
{
if (RT[rt] != other.RT[rt])
return false;
}
return DepthStencil == other.DepthStencil;
}
#endif

View File

@@ -1,62 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Common.h"
#include "Config.h"
#if GRAPHICS_API_OPENGL
#include "IncludeOpenGLHeaders.h"
class GPUTextureViewOGL;
class TextureOGL;
class FBOCache
{
private:
struct Key
{
uint32 Hash;
uint32 RTCount;
GPUTextureViewOGL* DepthStencil;
GPUTextureViewOGL* RT[GPU_MAX_RT_BINDED];
Key()
: Hash(0)
, RTCount(0)
, DepthStencil(nullptr)
{
for (int32 rt = 0; rt < GPU_MAX_RT_BINDED; rt++)
RT[rt] = nullptr;
}
Key(uint32 rtCount, GPUTextureViewOGL* depthStencil, GPUTextureViewOGL* rts[]);
bool HasReference(TextureOGL* texture);
bool operator== (const Key& other) const;
static uint32 HashFunction(const Key& key)
{
return key.Hash;
}
};
Dictionary<Key, GLuint> Table;
public:
FBOCache();
~FBOCache();
public:
GLuint GetFBO(uint32 rtCount, GPUTextureViewOGL* depthStencil, GPUTextureViewOGL* rts[]);
void OnTextureRelease(TextureOGL* texture);
void Dispose();
};
#endif

View File

@@ -1,185 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/Config.h"
#include "Engine/Core/Core.h"
#include "Engine/Graphics/GPUAdapter.h"
#include "Engine/Platform/Platform.h"
#include "IncludeOpenGLHeaders.h"
/// <summary>
/// Graphics Device adapter implementation for OpenGL backend.
/// </summary>
class GPUAdapterOGL : public GPUAdapter
{
public:
AdapterOGL()
{
}
public:
int32 Version = 0;
int32 VersionMajor = 0;
int32 VersionMinor = 0;
String Vendor;
String Renderer;
uint32 VendorId = 0;
bool AmdWorkaround = false;
typedef StringAnsi Extension;
Array<Extension> Extensions;
public:
bool HasExtension(const char* str)
{
for (int32 i = 0; i < Extensions.Count(); i++)
{
if (Extensions[i] == str)
return true;
}
return false;
}
public:
bool Init(HDC deviceContext)
{
#define CHECK_NULL(obj) if (obj == nullptr) { return true; }
// Get OpenGL version
const char* pcVer;
{
pcVer = (const char*)glGetString(GL_VERSION);
ASSERT(pcVer);
StringAnsi version = pcVer;
version = version.substr(0, version.find(' '));
const auto split = version.Find('.');
if (split == -1)
{
VersionMajor = atoi(version.c_str());
}
else
{
VersionMajor = atoi(version.substr(0, split).Get());
VersionMinor = atoi(version.substr(split + 1).Get());
}
}
Version = VersionMajor * 100 + VersionMinor * 10;
// Get GPU info
const char* pcVendor = (const char*)glGetString(GL_VENDOR);
CHECK_NULL(pcVendor);
Vendor = pcVendor;
const char* pcRenderer = (const char*)glGetString(GL_RENDERER);
CHECK_NULL(pcRenderer);
Renderer = pcRenderer;
// Get extensions list
#if PLATFORM_WINDOWS && false
/*
// Check for Win32 specific extensions probe function
auto _wglGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)GetGLFuncAddress("wglGetExtensionsString");
CHECK_NULL(_wglGetExtensionsString);
const char* wglExtensions = _wglGetExtensionsString(deviceContext);
// Parse them, and add them to the main list
Extensions.EnsureCapacity(512);
std::stringstream ext;
ext << wglExtensions;
std::string instr;
while (ext >> instr)
Extensions.Add(instr);
*/
#else
GLint numExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
Extensions.Resize(numExtensions);
for (GLint i = 0; i < numExtensions; i++)
{
Extensions[i] = (const char*)glGetStringi(GL_EXTENSIONS, i);
}
#endif
// Pick a GPU vendor id
#if PLATFORM_IOS
VendorId = 0x1010;
#else
if (Vendor.Contains(TEXT("ATI ")))
{
VendorId = 0x1002;
#if PLATFORM_WINDOWS || PLATFORM_LINUX
AmdWorkaround = true;
#endif
}
#if PLATFORM_LINUX
else if (Vendor.Contains(TEXT("X.Org")))
{
VendorId = 0x1002;
bAmdWorkaround = true;
}
#endif
else if (Vendor.Contains(TEXT("Intel ")) || Vendor == TEXT("Intel"))
{
VendorId = 0x8086;
#if PLATFORM_WINDOWS || PLATFORM_LINUX
AmdWorkaround = true;
#endif
}
else if (Vendor.Contains(TEXT("NVIDIA ")))
{
VendorId = 0x10DE;
}
else if (Vendor.Contains(TEXT("ImgTec")))
{
VendorId = 0x1010;
}
else if (Vendor.Contains(TEXT("ARM")))
{
VendorId = 0x13B5;
}
else if (Vendor.Contains(TEXT("Qualcomm")))
{
VendorId = 0x5143;
}
if (VendorId == 0)
{
// Fix for Mesa Radeon
if (strstr(pcVer, "Mesa") && (strstr(pcRenderer, "AMD") || strstr(pcRenderer, "ATI")))
{
VendorId = 0x1002;
}
}
#endif
#undef CHECK_NULL
return false;
}
public:
// [GPUAdapter]
bool IsValid() const override
{
return true;
}
uint32 GetVendorId() const override
{
return VendorId;
}
const Char* GetDescription() const override
{
static String desc = Vendor + TEXT(" ") + Renderer;
return *desc;
}
};
#endif

View File

@@ -1,209 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if GRAPHICS_API_OPENGL
#include "GPUBufferOGL.h"
#include "GPUDeviceOGL.h"
#include "RenderToolsOGL.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
#include "Engine/Debug/Exceptions/ArgumentNullException.h"
#include "Engine/Debug/Exceptions/ArgumentOutOfRangeException.h"
#include "Engine/Debug/Exceptions/InvalidOperationException.h"
GPUBufferOGL::GPUBufferOGL(GPUDeviceOGL* device, const String& name)
: GPUResourceOGL<Buffer>(device, name)
{
}
GPUBufferOGL::~GPUBufferOGL()
{
}
bool GPUBufferOGL::init()
{
ASSERT(IsInMainThread());
// Pick a buffer usage mode
GLenum usage;
switch (_desc.Usage)
{
case GPUResourceUsage::Default:
case GPUResourceUsage::Immutable: usage = GL_STATIC_DRAW; break;
case GPUResourceUsage::Staging:
case GPUResourceUsage::Dynamic: usage = GL_DYNAMIC_DRAW; break;
}
// Pick a buffer target
GLenum target = GL_ARRAY_BUFFER;
if (_desc.Flags & GPUBufferFlags::VertexBuffer)
target = GL_ARRAY_BUFFER;
else if (_desc.Flags & GPUBufferFlags::IndexBuffer)
target = GL_ELEMENT_ARRAY_BUFFER;
else if (_desc.Flags & GPUBufferFlags::UnorderedAccess)
target = GL_SHADER_STORAGE_BUFFER;
else if (_desc.Flags & GPUBufferFlags::Argument)
target = GL_DRAW_INDIRECT_BUFFER;
else if (_desc.Flags & GPUBufferFlags::ShaderResource)
target = GL_TEXTURE_BUFFER;
else if (_desc.Usage == GPUResourceUsage::Staging)
target = GL_PIXEL_UNPACK_BUFFER;
BufferTarget = target;
// Create a buffer
glGenBuffers(1, &BufferId);
VALIDATE_OPENGL_RESULT();
if (!BufferId)
{
LOG(Warning, "Cannot create OpenGL buffer");
return true;
}
// Initialize
if (_desc.InitData)
{
glBindBuffer(target, BufferId);
VALIDATE_OPENGL_RESULT();
glBufferData(target, _desc.Size, _desc.InitData, usage);
VALIDATE_OPENGL_RESULT();
glBindBuffer(target, 0);
}
if (_desc.Flags & GPUBufferFlags::ShaderResource)
{
MISSING_CODE("Shader resource OpenGL GPU buffer");
/*TextureTarget = TextureTarget.TextureBuffer;
glGenTextures(1, &_textureId);
VALIDATE_OPENGL_RESULT();
glBindTexture(TextureTarget, _textureId);
glTexBuffer(TextureBufferTarget::TextureBuffer, (SizedInternalFormat)TextureInternalFormat, BufferId);
glBindTexture(TextureTarget, 0);
*/
}
return false;
}
void GPUBufferOGL::release()
{
_device->VAOCache.OnObjectRelease(this);
// Release resource
if (BufferId != 0)
{
glDeleteBuffers(1, &BufferId);
VALIDATE_OPENGL_RESULT();
}
BufferId = 0;
BufferTarget = 0;
_memoryUsage = 0;
// Base
GPUBuffer::release();
}
bool GPUBufferOGL::SetData(const void* data, uint64 size)
{
// Validate input and buffer state
if (size == 0 || data == nullptr)
{
Log::ArgumentNullException(TEXT("Buffer.SetData"));
return true;
}
if (size > GetSize())
{
Log::ArgumentOutOfRangeException(TEXT("Buffer.SetData"));
return true;
}
if (!IsDynamic() && !IsStaging())
{
Log::InvalidOperationException(TEXT("Buffer.SetData"));
return true;
}
if (BufferId == 0)
{
return true;
}
GPUDeviceLock lock(_device);
// Map the staging resource for reading
GLenum access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
glBindBuffer(BufferTarget, BufferId);
VALIDATE_OPENGL_RESULT();
glBufferData(BufferTarget, size, 0, GL_DYNAMIC_DRAW);
VALIDATE_OPENGL_RESULT();
void* buffer = glMapBufferRange(BufferTarget, 0, size, access);
VALIDATE_OPENGL_RESULT();
if (buffer == nullptr)
{
LOG(Warning, "Cannot map OpenGL buffer.");
return true;
}
// Copy memory
Platform::MemoryCopy(buffer, data, size);
// Unmap resource
if (!glUnmapBuffer(BufferTarget))
{
VALIDATE_OPENGL_RESULT();
LOG(Warning, "OpenGL buffer data corrupted");
return true;
}
glBindBuffer(BufferTarget, 0);
VALIDATE_OPENGL_RESULT();
return false;
}
bool GPUBufferOGL::GetData(BytesContainer& data)
{
// Validate input and buffer state
if (!IsDynamic() && !IsStaging())
{
Log::InvalidOperationException(TEXT("Buffer.GetData"));
return true;
}
if (BufferId == 0)
{
return true;
}
auto size = GetSize();
GPUDeviceLock lock(_device);
// Map the staging resource for reading
GLenum access = GL_MAP_READ_BIT;
glBindBuffer(BufferTarget, BufferId);
VALIDATE_OPENGL_RESULT();
void* buffer = glMapBufferRange(BufferTarget, 0, size, access);
VALIDATE_OPENGL_RESULT();
if (buffer == nullptr)
{
LOG(Warning, "Cannot map OpenGL buffer.");
return true;
}
// Copy memory
data.Copy((byte*)buffer, size);
// Unmap resource
glBindBuffer(BufferTarget, BufferId);
VALIDATE_OPENGL_RESULT();
if (!glUnmapBuffer(BufferTarget))
{
VALIDATE_OPENGL_RESULT();
LOG(Warning, "OpenGL buffer data corrupted");
return true;
}
return false;
}
void GPUBufferOGL::Bind(int32 slotIndex)
{
// TODO: finish this
CRASH;
}
#endif

View File

@@ -1,53 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/GPUBuffer.h"
#include "GPUResourceOGL.h"
#include "IShaderResourceOGL.h"
/// <summary>
/// GPU buffer for OpenGL
/// </summary>
/// <seealso cref="GPUResourceOGL" />
class GPUBufferOGL : public GPUResourceOGL<GPUBuffer>, public IShaderResourceOGL
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUBufferOGL"/> class.
/// </summary>
/// <param name="device">The graphics device.</param>
/// <param name="name">The resource name.</param>
GPUBufferOGL(GPUDeviceOGL* device, const String& name);
/// <summary>
/// Finalizes an instance of the <see cref="GPUBufferOGL"/> class.
/// </summary>
~GPUBufferOGL();
public:
GLenum BufferTarget = 0;
GLuint BufferId = 0;
public:
// [GPUBuffer]
bool SetData(const void* data, uint64 size) override;
bool GetData(BytesContainer& data) override;
// [IShaderResourceOGL]
void Bind(int32 slotIndex) override;
protected:
// [GPUBuffer]
bool OnInit() override;
void OnReleaseGPU() override;
};
#endif

View File

@@ -1,53 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "GPUConstantBufferOGL.h"
#if GRAPHICS_API_OPENGL
#include "../RenderToolsOGL.h"
#include "Engine/Threading/Threading.h"
GPUConstantBufferOGL::GPUConstantBufferOGL(GPUDeviceOGL* device, const String& name, uint32 size)
: GPUResourceOGL(device, name)
{
_size = size;
}
GPUConstantBufferOGL::~GPUConstantBufferOGL()
{
ReleaseGPU();
}
GLuint GPUConstantBufferOGL::GetHandle()
{
// Create buffer if missing
if (_handle == 0)
{
glGenBuffers(1, &_handle);
VALIDATE_OPENGL_RESULT();
glBindBuffer(GL_UNIFORM_BUFFER, _handle);
VALIDATE_OPENGL_RESULT();
glBufferData(GL_UNIFORM_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW);
VALIDATE_OPENGL_RESULT();
glBindBuffer(GL_UNIFORM_BUFFER, 0);
VALIDATE_OPENGL_RESULT();
}
return _handle;
}
void GPUConstantBufferOGL::ReleaseGPU()
{
if (_handle != 0)
{
glDeleteBuffers(1, &_handle);
VALIDATE_OPENGL_RESULT();
_handle = 0;
}
_memoryUsage = 0;
}
#endif

View File

@@ -1,887 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "GPUContextOGL.h"
#if GRAPHICS_API_OPENGL
#include "Engine/Core/Math/Viewport.h"
#include "Engine/Profiler/RenderStats.h"
#include "Engine/Threading/Threading.h"
#include "PipelineStateOGL.h"
#include "BufferOGL.h"
#include "TextureOGL.h"
#include "GPUTextureViewOGL.h"
#include "GPUDeviceOGL.h"
#include "GPULimitsOGL.h"
#include "IShaderResourceOGL.h"
#include "Shaders/GPUConstantBufferOGL.h"
#include "Shaders/GPUShaderProgramOGL.h"
#include "feature/PixelFormatExtensions.h"
GPUContextOGL::GPUContextOGL(GPUDeviceOGL* device)
: GPUContext(device)
, _device(device)
, _omDirtyFlag(false)
, _rtCount(0)
, _rtDepth(nullptr)
, _uaOutput(nullptr)
, _srDirtyFlag(false)
, _uaDirtyFlag(false)
, _cbDirtyFlag(false)
, _activeTextureUnit(-1)
{
}
GPUContextOGL::~GPUContextOGL()
{
}
void GPUContextOGL::FrameBegin()
{
// Base
GPUContext::FrameBegin();
// Setup
_omDirtyFlag = false;
_uaDirtyFlag = false;
_srDirtyFlag = false;
_cbDirtyFlag = false;
_rtCount = 0;
_currentState = nullptr;
_rtDepth = nullptr;
_uaOutput = nullptr;
Platform::MemoryClear(_rtHandles, sizeof(_rtHandles));
Platform::MemoryClear(_srHandles, sizeof(_srHandles));
Platform::MemoryClear(_uaHandles, sizeof(_uaHandles));
Platform::MemoryClear(_cbHandles, sizeof(_cbHandles));
Platform::MemoryClear(_vbHandles, sizeof(_vbHandles));
Platform::MemoryClear(_vbStrides, sizeof(_vbStrides));
_ibHandle = nullptr;
// TODO: dont setup this state every frame
m_DepthEnableState = true;
glEnable(GL_DEPTH_TEST);
m_DepthWritesEnableState = true;
m_DepthCmpFunc = ComparisonFunc::Less;
glDepthFunc(RenderToolsOGL::ComparisonFuncToOGL(m_DepthCmpFunc));
glDepthMask(1);
Writeframe = false;
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
CullMode = ::CullMode::TwoSided;
glDisable(GL_CULL_FACE);
DepthClampEnable = true;
glEnable(GL_DEPTH_CLAMP);
BlendMode = BlendingMode::Opaque;
glDisable(GL_BLEND);
}
void GPUContextOGL::Clear(GPUTextureView* rt, const Color& color)
{
auto rtOGL = reinterpret_cast<GPUTextureViewOGL*>(rt);
int32 rtIndex = -1;
for (int32 i = 0; i < _rtCount; i++)
{
if (_rtHandles[i] == rtOGL)
{
rtIndex = i;
break;
}
}
if (rtIndex == -1)
{
// Check if not render targets is binded
if (_rtCount == 0)
{
// Bind target just for clear
SetRenderTarget(rtOGL);
flushOM();
glClearBufferfv(GL_COLOR, 0, color.Raw);
VALIDATE_OPENGL_RESULT();
SetRenderTarget();
return;
}
LOG(Fatal, "Failed to clear the render target. On OpenGL, it must be binded to the pipeline first.");
}
flushOM();
glClearBufferfv(GL_COLOR, rtIndex, color.Raw);
VALIDATE_OPENGL_RESULT();
}
void GPUContextOGL::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
{
auto depthBufferOGL = static_cast<GPUTextureViewOGL*>(depthBuffer);
if (depthBufferOGL != _rtDepth)
{
LOG(Fatal, "Failed to clear the depth buffer. On OpenGL, it must be binded to the pipeline first.");
}
glClearDepthf(depthValue);
RENDER_STAT_DISPATCH_CALL();
glDepthMask(1);
VALIDATE_OPENGL_RESULT();
glClear(GL_DEPTH_BUFFER_BIT);
VALIDATE_OPENGL_RESULT();
}
void GPUContextOGL::ClearUA(Buffer* buf, const Vector4& value)
{
ASSERT(buf != nullptr && buf->IsUnorderedAccess());
auto bufOGL = reinterpret_cast<BufferOGL*>(buf);
MISSING_CODE("GPUContextOGL::ClearUA");
/*GL.BindBuffer(bufOGL->BufferTarget, bufOGL->BufferId);
GL.ClearBufferData(bufOGL->BufferTarget, buffer.TextureInternalFormat, buffer.TextureFormat, All.UnsignedInt8888, value);
GL.BindBuffer(buffer.BufferTarget, 0);*/
}
void GPUContextOGL::ResetRenderTarget()
{
if (_rtCount > 0 || _uaOutput || _rtDepth)
{
_omDirtyFlag = true;
_rtCount = 0;
_rtDepth = nullptr;
_uaOutput = nullptr;
Platform::MemoryClear(_rtHandles, sizeof(_rtHandles));
flushOM();
}
}
void GPUContextOGL::SetRenderTarget(GPUTextureView* rt)
{
auto rtOGL = reinterpret_cast<GPUTextureViewOGL*>(rt);
GPUTextureViewOGL* rtv = rtOGL;
int32 newRtCount = rtv ? 1 : 0;
if (_rtCount != newRtCount || _rtHandles[0] != rtv || _rtDepth != nullptr || _uaOutput)
{
_omDirtyFlag = true;
_rtCount = newRtCount;
_rtDepth = nullptr;
_rtHandles[0] = rtv;
_uaOutput = nullptr;
}
}
void GPUContextOGL::SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt)
{
auto rtOGL = reinterpret_cast<GPUTextureViewOGL*>(rt);
auto depthBufferOGL = static_cast<GPUTextureViewOGL*>(depthBuffer);
GPUTextureViewOGL* rtv = rtOGL;
GPUTextureViewOGL* dsv = depthBufferOGL && depthBufferOGL->GetTexture()->IsDepthStencil() ? depthBufferOGL : nullptr;
int32 newRtCount = rtv ? 1 : 0;
if (_rtCount != newRtCount || _rtHandles[0] != rtv || _rtDepth != dsv || _uaOutput)
{
_omDirtyFlag = true;
_rtCount = newRtCount;
_rtDepth = dsv;
_rtHandles[0] = rtv;
_uaOutput = nullptr;
}
}
void GPUContextOGL::SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts)
{
ASSERT(Math::IsInRange(rtsCount, 1, GPU_MAX_RT_BINDED));
auto depthBufferOGL = static_cast<GPUTextureViewOGL*>(depthBuffer);
GPUTextureViewOGL* dsv = depthBufferOGL && depthBufferOGL->GetTexture()->IsDepthStencil() ? depthBufferOGL : nullptr;
GPUTextureViewOGL* rtvs[GPU_MAX_RT_BINDED];
for (int32 i = 0; i < rtsCount; i++)
{
auto rtOGL = reinterpret_cast<GPUTextureViewOGL*>(rts[i]);
rtvs[i] = rtOGL;
}
int32 rtvsSize = sizeof(GPUTextureViewOGL*) * rtsCount;
if (_rtCount != rtsCount || _rtDepth != dsv || _uaOutput || Platform::MemoryCompare(_rtHandles, rtvs, rtvsSize) != 0)
{
_omDirtyFlag = true;
_rtCount = rtsCount;
_rtDepth = dsv;
_uaOutput = nullptr;
Platform::MemoryCopy(_rtHandles, rtvs, rtvsSize);
}
}
void GPUContextOGL::SetRenderTarget(GPUTextureView* rt, Buffer* uaOutput)
{
auto rtOGL = reinterpret_cast<GPUTextureViewOGL*>(rt);
auto uaOutputOGL = reinterpret_cast<BufferOGL*>(uaOutput);
MISSING_CODE("GPUContextOGL::SetRenderTarget with UAV");
/*GPUTextureViewOGL* rtv = rtOGL ? rtOGL : nullptr;
GPUTextureViewOGL* uav = uaOutputOGL ? uaOutputOGL->GetUAV() : nullptr;
int32 newRtCount = rtv ? 1 : 0;
if (_rtCount != newRtCount || _rtHandles[0] != rtv || _rtDepth != nullptr || _uaOutput != uav)
{
_omDirtyFlag = true;
_rtCount = newRtCount;
_rtDepth = nullptr;
_rtHandles[0] = rtv;
_uaOutput = uav;
}*/
}
void GPUContextOGL::ResetSR()
{
// TODO: check if need to set dirty flag always to true?
_srDirtyFlag = true;
Platform::MemoryClear(_srHandles, sizeof(_srHandles));
}
void GPUContextOGL::ResetUA()
{
// TODO: check if need to set dirty flag always to true?
_uaDirtyFlag = true;
Platform::MemoryClear(_uaHandles, sizeof(_uaHandles));
}
void GPUContextOGL::ResetCB()
{
// TODO: check if need to set dirty flag always to true?
_cbDirtyFlag = true;
Platform::MemoryClear(_cbHandles, sizeof(_cbHandles));
}
void GPUContextOGL::BindCB(int32 slot, ConstantBuffer* cb)
{
ASSERT(slot >= 0 && slot < GPU_MAX_CB_BINDED);
auto cbOGL = static_cast<GPUConstantBufferOGL*>(cb);
if (_cbHandles[slot] != cbOGL)
{
_cbDirtyFlag = true;
_cbHandles[slot] = cbOGL;
}
}
void GPUContextOGL::BindSR(int32 slot, GPUTextureView* rt)
{
ASSERT(slot >= 0 && slot < GPU_MAX_SR_BINDED);
auto rtOGL = reinterpret_cast<GPUTextureViewOGL*>(rt);
if (_srHandles[slot] != rtOGL)
{
_srDirtyFlag = true;
_srHandles[slot] = rtOGL;
}
}
void GPUContextOGL::BindSR(int32 slot, Buffer* buf)
{
ASSERT(slot >= 0 && slot < GPU_MAX_SR_BINDED);
ASSERT(buf == nullptr || buf->IsShaderResource());
auto bufOGL = reinterpret_cast<BufferOGL*>(buf);
if (_srHandles[slot] != bufOGL)
{
_srDirtyFlag = true;
_srHandles[slot] = bufOGL;
}
}
void GPUContextOGL::BindUA(int32 slot, Buffer* buf)
{
MISSING_CODE("GPUContextOGL::BindUA");
}
void GPUContextOGL::BindUA(int32 slot, RenderTarget* rt)
{
MISSING_CODE("GPUContextOGL::BindUA");
}
void GPUContextOGL::Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCountX, uint32 threadGroupCountY, uint32 threadGroupCountZ)
{
ASSERT(shader);
// Bind compute shader
glUseProgram((GLuint)shader->GetBufferHandle());
VALIDATE_OPENGL_RESULT();
// Flush
flushCBs();
flushSRVs();
flushUAVs();
flushOM();
// Dispatch
glDispatchCompute(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
VALIDATE_OPENGL_RESULT();
RENDER_STAT_DISPATCH_CALL();
}
void GPUContextOGL::ResolveMultisample(Texture* sourceMultisampleTexture, Texture* destTexture, int32 sourceSubResource, int32 destSubResource, PixelFormat format)
{
MISSING_CODE("GPUContextOGL::ResolveMultisample");
}
GLint getGLDrawMode(PipelineStateOGL* state)
{
GLint primType;
switch (state->PrimitiveTopologyType)
{
case PrimitiveTopologyType::Point:
primType = GL_POINTS;
break;
case PrimitiveTopologyType::Line:
primType = GL_LINES;
break;
case PrimitiveTopologyType::Triangle:
primType = GL_TRIANGLES;
break;
}
return primType;
}
void GPUContextOGL::Draw(Buffer** vertexBuffers, int32 vertexBuffersCount, uint32 startVertex, uint32 verticesCount)
{
ASSERT(_currentState && vertexBuffers && vertexBuffers[0] && vertexBuffersCount > 0 && vertexBuffersCount <= GPU_MAX_VB_BINDED);
VAOCache::StreamData streams[GPU_MAX_VB_BINDED];
for (int32 i = 0; i < vertexBuffersCount; i++)
{
auto bufferOGL = (BufferOGL*)vertexBuffers[i];
ASSERT(bufferOGL->BufferId != 0);
streams[i].Buffer = bufferOGL;
streams[i].Offset = 0;
streams[i].Stride = bufferOGL ? bufferOGL->GetStride() : 0;
}
GLuint vao = _device->VAOCache.GetVAO(_currentState->VS, nullptr, vertexBuffersCount, streams);
GLint primType = getGLDrawMode(_currentState);
// Draw
onDrawCall();
glBindVertexArray(vao);
VALIDATE_OPENGL_RESULT();
glDrawArrays(primType, startIndex, vertices);
VALIDATE_OPENGL_RESULT();
RENDER_STAT_DRAW_CALL(vertices, vertices / 3);
}
void GPUContextOGL::DrawIndexed(Buffer** vertexBuffers, int32 vertexBuffersCount, Buffer* indexBuffer, uint32 indicesCount, int32 startVertex, int32 startIndex)
{
// TODO: implement VAO binding
MISSING_CODE("GPUContextOGL::DrawIndexed");
}
void GPUContextOGL::DrawIndexedInstanced(Buffer** vertexBuffers, int32 vertexBuffersCount, Buffer* indexBuffer, uint32 indicesCount, uint32 instanceCount, int32 startInstance, int32 startVertex, int32 startIndex)
{
MISSING_CODE("GPUContextOGL::DrawIndexedInstanced");
}
void GPUContextOGL::DrawInstancedIndirect(Buffer* bufferForArgs, uint32 offsetForArgs)
{
MISSING_CODE("GPUContextOGL::DrawInstancedIndirect");
}
void GPUContextOGL::SetViewport(int width, int height)
{
// TODO: cache viewport depth to reduce api calls
glDepthRangef(0.0, 1.0);
glViewport(0, 0, width, height);
VALIDATE_OPENGL_RESULT();
}
void GPUContextOGL::SetViewport(const Viewport& viewport)
{
// TODO: cache viewport depth to reduce api calls
glDepthRangef(viewport.MinDepth, viewport.MaxDepth);
glViewport((GLsizei)viewport.X, (GLsizei)viewport.Y, (GLsizei)viewport.Width, (GLsizei)viewport.Height);
VALIDATE_OPENGL_RESULT();
}
void GPUContextOGL::SetState(PipelineState* state)
{
// Check if state will change
if (_currentState != state)
{
// Set new state
_currentState = (PipelineStateOGL*)state;
// Invalidate pipeline state
// TODO: maybe don't flush all or only on draw call?
_cbDirtyFlag = true;
_srDirtyFlag = true;
_uaDirtyFlag = true;
if (_currentState)
{
_currentState->OnBind();
glUseProgram(0);
VALIDATE_OPENGL_RESULT();
glBindProgramPipeline(_currentState->ProgramPipeline);
VALIDATE_OPENGL_RESULT();
if (m_DepthEnableState != _currentState->DepthTestEnable)
{
m_DepthEnableState = _currentState->DepthTestEnable;
if (m_DepthEnableState)
{
glEnable(GL_DEPTH_TEST);
}
else
{
glDisable(GL_DEPTH_TEST);
}
}
if (m_DepthWritesEnableState != _currentState->EnableDepthWrite)
{
m_DepthWritesEnableState = _currentState->EnableDepthWrite;
glDepthMask(m_DepthWritesEnableState ? 1 : 0);
}
if (m_DepthCmpFunc != _currentState->DepthFunc)
{
m_DepthCmpFunc = _currentState->DepthFunc;
glDepthFunc(RenderToolsOGL::ComparisonFuncToOGL(m_DepthCmpFunc));
}
if (Writeframe != _currentState->Wireframe)
{
Writeframe = _currentState->Wireframe;
auto PolygonMode = Writeframe ? GL_LINE : GL_FILL;
glPolygonMode(GL_FRONT_AND_BACK, PolygonMode);
}
if (CullMode != _currentState->CullMode)
{
CullMode = _currentState->CullMode;
if (CullMode == CullMode::TwoSided)
{
glDisable(GL_CULL_FACE);
}
else
{
glEnable(GL_CULL_FACE);
auto CullFace = CullMode == CullMode::Normal ? GL_BACK : GL_FRONT;
glCullFace(CullFace);
}
}
if (DepthClampEnable != _currentState->DepthClipEnable)
{
DepthClampEnable = _currentState->DepthClipEnable;
if (DepthClampEnable)
{
glEnable(GL_DEPTH_CLAMP);
}
else
{
glDisable(GL_DEPTH_CLAMP);
}
}
if (BlendMode != _currentState->BlendMode)
{
BlendMode = _currentState->BlendMode;
todo_update_pipeline_state_for_opengl_to_match_new_blend_state
const auto& desc = GPUDeviceOGL::BlendModes[(int32)BlendMode];
if (desc.BlendEnable)
{
glBlendFuncSeparate(desc.SrcBlend, desc.DestBlend, desc.SrcBlendAlpha, desc.DestBlendAlpha);
VALIDATE_OPENGL_RESULT();
glBlendEquationSeparate(desc.BlendOp, desc.BlendOpAlpha);
VALIDATE_OPENGL_RESULT();
}
else
{
glDisable(GL_BLEND);
}
}
}
else
{
// TODO: what to do when no state is binded?
}
RENDER_STAT_PS_STATE_CHANGE();
}
}
void GPUContextOGL::ClearState()
{
ResetRenderTarget();
ResetSR();
ResetUA();
SetState(nullptr);
FlushState();
}
void GPUContextOGL::FlushState()
{
// Flush
flushCBs();
flushSRVs();
flushUAVs();
flushOM();
}
void GPUContextOGL::Flush()
{
glFinish();
}
void GPUContextOGL::UpdateSubresource(Texture* texture, int32 arrayIndex, int32 mipIndex, void* data, uint32 rowPitch, uint32 slicePitch)
{
ASSERT(IsInMainThread());
ASSERT(texture && texture->IsAllocated() && data && !texture->IsMultiSample());
auto textureOGL = static_cast<TextureOGL*>(texture);
auto target = textureOGL->Target;
auto format = textureOGL->FormatGL;
bool isCompressed = PixelFormatExtensions::IsCompressed(texture->Format());
int formatSize = PixelFormatExtensions::SizeInBytes(texture->Format());
SetActiveTextureUnit(0);
glBindTexture(target, textureOGL->TextureID);
VALIDATE_OPENGL_RESULT();
// TODO: maybe don't bind it?
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
int32 mipWidth, mipHeight, mipDepth;
texture->GetMipSize(mipIndex, mipWidth, mipHeight, mipDepth);
// Determine the opengl read unpack alignment
auto expectedRowPitch = mipWidth * formatSize;
auto packAlignment = 1;
if ((rowPitch & 1) != 0)
{
if (rowPitch == expectedRowPitch)
packAlignment = 1;
}
else if ((rowPitch & 2) != 0)
{
auto diff = rowPitch - expectedRowPitch;
if (diff >= 0 && diff < 2)
packAlignment = 2;
}
else if ((rowPitch & 4) != 0)
{
auto diff = rowPitch - expectedRowPitch;
if (diff >= 0 && diff < 4)
packAlignment = 4;
}
else if ((rowPitch & 8) != 0)
{
auto diff = rowPitch - expectedRowPitch;
if (diff >= 0 && diff < 8)
packAlignment = 8;
}
else if (rowPitch == expectedRowPitch)
{
packAlignment = 4;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, packAlignment);
VALIDATE_OPENGL_RESULT();
// Just to be clear: OpenGL sucks and is very shitty graphics API
switch (texture->GetDescription().Dimensions)
{
case TextureDimensions::Texture:
{
glPixelStorei(GL_UNPACK_ROW_LENGTH, mipWidth);
VALIDATE_OPENGL_RESULT();
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
if (texture->IsArray())
{
CRASH;
}
else
{
ASSERT(arrayIndex == 0);
if (isCompressed)
{
glCompressedTexSubImage2D(target, mipIndex, 0, 0, mipWidth, mipHeight, format, slicePitch, data);
VALIDATE_OPENGL_RESULT();
}
else
{
auto formatInfo = _device->GetLimits()->TextureFormats[(int32)texture->Format()];
glTexSubImage2D(target, mipIndex, 0, 0, mipWidth, mipHeight, formatInfo.Format, formatInfo.Type, data);
VALIDATE_OPENGL_RESULT();
}
}
break;
}
case TextureDimensions::CubeTexture:
{
if (texture->IsArray())
{
CRASH;
}
else
{
ASSERT(arrayIndex == 0);
CRASH;
}
break;
}
case TextureDimensions::VolumeTexture:
{
CRASH;
break;
}
}
}
void GPUContextOGL::CopyTexture(Texture* dstResource, uint32 dstSubresource, uint32 dstX, uint32 dstY, uint32 dstZ, Texture* srcResource, uint32 srcSubresource)
{
MISSING_CODE("GPUContextOGL::CopyTexture");
}
void GPUContextOGL::ResetCounter(Buffer* buffer, uint32 alignedByteOffset)
{
MISSING_CODE("GPUContextOGL::ResetCounter");
}
void GPUContextOGL::CopyCounter(Buffer* dstBuffer, uint32 dstAlignedByteOffset, Buffer* srcBuffer)
{
MISSING_CODE("GPUContextOGL::CopyCounter");
}
void GPUContextOGL::CopyResource(GPUResource* dstResource, GPUResource* srcResource)
{
MISSING_CODE("GPUContextOGL::CopyResource");
/*glBindBuffer(GL_COPY_READ_BUFFER, mBufferId);
VALIDATE_OPENGL_RESULT();
glBindBuffer(GL_COPY_WRITE_BUFFER, dstBuffer.getGLBufferId());
VALIDATE_OPENGL_RESULT();
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length);
VALIDATE_OPENGL_RESULT();*/
/*VERIFY_GL_SCOPE();
ASSERT(FOpenGL::SupportsCopyBuffer());
FOpenGLVertexBuffer* SourceBuffer = ResourceCast(SourceBufferRHI);
FOpenGLVertexBuffer* DestBuffer = ResourceCast(DestBufferRHI);
ASSERT(SourceBuffer->GetSize() == DestBuffer->GetSize());
glBindBuffer(GL_COPY_READ_BUFFER, SourceBuffer->Resource);
glBindBuffer(GL_COPY_WRITE_BUFFER, DestBuffer->Resource);
FOpenGL::CopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, SourceBuffer->GetSize());
glBindBuffer(GL_COPY_READ_BUFFER, 0);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);*/
}
void GPUContextOGL::CopySubresource(GPUResource* dstResource, uint32 dstSubresource, GPUResource* srcResource, uint32 srcSubresource)
{
MISSING_CODE("GPUContextOGL::CopySubresource");
}
void GPUContextOGL::SetActiveTextureUnit(int32 unit)
{
if (_activeTextureUnit != unit)
{
glActiveTexture(GL_TEXTURE0 + unit);
VALIDATE_OPENGL_RESULT();
_activeTextureUnit = unit;
}
}
void GPUContextOGL::flushSRVs()
{
// Check if need to flush shader resources
if (_srDirtyFlag)
{
// Clear flag
_srDirtyFlag = false;
// TODO: din't interate over all slots, only the used ones by the given pipeline state (cache it)
int32 shaderStagesCount = ShaderStage_Count;
for (int32 slot = 0; slot < GPU_MAX_SR_BINDED; slot++)
{
const auto srOGL = _srHandles[slot];
if (srOGL == nullptr || !_currentState->IsUsingSR(slot))
continue;
SetActiveTextureUnit(slot);
//for (int32 stageIndex = 0; stageIndex < shaderStagesCount; stageIndex++)
{
//const auto stage = (ShaderStage)stageIndex;
srOGL->Bind(slot);
//glProgramUniform1i(GLProgramObj, it->Location + ArrInd, slot);
// TODO: don't use glUniform1i all the time? maybe bind only on shader init?
//glUniform1i(slot, slot);
//VALIDATE_OPENGL_RESULT();
}
}
}
}
void GPUContextOGL::flushUAVs()
{
// Check if need to flush unordered access
if (_uaDirtyFlag)
{
// Clear flag
_uaDirtyFlag = false;
if (_currentState == nullptr)
return;
// Set shader resources views table
//_context->CSSetUnorderedAccessViews(0, ARRAY_COUNT(_uaHandles), _uaHandles, nullptr);
}
}
void GPUContextOGL::flushCBs()
{
// Check if need to flush constant buffers
if (_cbDirtyFlag)
{
// Clear flag
_cbDirtyFlag = false;
if (_currentState == nullptr)
return;
for (int32 slot = 0; slot < MAX_CONSTANT_BUFFER_SLOTS; slot++)
{
auto cbOGL = _cbHandles[slot];
GLuint handle = cbOGL ? cbOGL->GetHandle() : 0;
if (handle == 0)
continue;
// Update buffer is need to
if (cbOGL->IsDirty())
{
// Update buffer
glBindBuffer(GL_UNIFORM_BUFFER, handle);
VALIDATE_OPENGL_RESULT();
glBufferSubData(GL_UNIFORM_BUFFER, 0, cbOGL->GetSize(), cbOGL->GetDataToUpload());
VALIDATE_OPENGL_RESULT();
glBindBuffer(GL_UNIFORM_BUFFER, 0);
VALIDATE_OPENGL_RESULT();
// Register as flushed
cbOGL->OnUploaded();
}
// Bind
if (_currentState->VS && _currentState->VS->IsUsingCB(slot))
{
glUniformBlockBinding(_currentState->VS->GetHandle(), slot, slot);
VALIDATE_OPENGL_RESULT();
}
if (_currentState->GS && _currentState->GS->IsUsingCB(slot))
{
glUniformBlockBinding(_currentState->GS->GetHandle(), slot, slot);
VALIDATE_OPENGL_RESULT();
}
if (_currentState->PS && _currentState->PS->IsUsingCB(slot))
{
glUniformBlockBinding(_currentState->PS->GetHandle(), slot, slot);
VALIDATE_OPENGL_RESULT();
}
// TODO: bind constant buffer to Compute Shader ???
glBindBufferBase(GL_UNIFORM_BUFFER, slot, handle);
VALIDATE_OPENGL_RESULT();
}
}
}
void GPUContextOGL::flushOM()
{
// Check if need to flush output merger state or/and unorder access views
if (_omDirtyFlag)
{
#if _DEBUG
// Validate binded render targets amount
int32 rtCount = 0;
for (int i = 0; i < ARRAY_COUNT(_rtHandles) && i < _rtCount; i++)
{
if (_rtHandles[i] != nullptr)
rtCount++;
else
break;
}
ASSERT(rtCount == _rtCount);
#endif
// Check if render to window backbuffer
if (_rtCount == 1 && _rtHandles[0]->IsBackbuffer())
{
// On-screen rendering
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
VALIDATE_OPENGL_RESULT();
}
// Check if use UAV
else if (_uaOutput)
{
}
// Check if bind sth
else if(_rtCount || _rtDepth)
{
// Get or create FBO
GLuint fbo = _device->FBOCache.GetFBO(_rtCount, _rtDepth, _rtHandles);
// Bind FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
VALIDATE_OPENGL_RESULT();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
VALIDATE_OPENGL_RESULT();
}
else
{
// Unbind FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
VALIDATE_OPENGL_RESULT();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
VALIDATE_OPENGL_RESULT();
}
// Clear flag
_omDirtyFlag = false;
}
}
void GPUContextOGL::onDrawCall()
{
// Flush
flushCBs();
flushSRVs();
flushUAVs();
flushOM();
}
#endif

View File

@@ -1,149 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/GPUContext.h"
#include "GPUDeviceOGL.h"
#include "GPUResourceOGL.h"
#include "PipelineStateOGL.h"
#include "RenderToolsOGL.h"
#if GRAPHICS_API_OPENGL
class GPUConstantBufferOGL;
class GPUTextureViewOGL;
class BufferOGL;
class IShaderResourceOGL;
/// <summary>
/// GPU Context for OpenGL
/// </summary>
class GPUContextOGL : public GPUContext
{
private:
GPUDeviceOGL* _device;
// Output Merger
bool _omDirtyFlag;
int32 _rtCount;
GPUTextureViewOGL* _rtDepth;
GPUTextureViewOGL* _rtHandles[GPU_MAX_RT_BINDED];
GPUTextureViewOGL* _uaOutput;
// Shader Resources
bool _srDirtyFlag;
IShaderResourceOGL* _srHandles[GPU_MAX_SR_BINDED];
// Unordered Access
bool _uaDirtyFlag;
GPUResource* _uaHandles[GPU_MAX_UA_BINDED];
// Constant Buffers
bool _cbDirtyFlag;
GPUConstantBufferOGL* _cbHandles[GPU_MAX_CB_BINDED];
// Vertex Buffers
BufferOGL* _ibHandle;
BufferOGL* _vbHandles[GPU_MAX_VB_BINDED];
uint32 _vbStrides[GPU_MAX_VB_BINDED];
// Pipeline State
PipelineStateOGL* _currentState;
bool m_DepthEnableState;
bool m_DepthWritesEnableState;
ComparisonFunc m_DepthCmpFunc;
/*bool m_StencilTestEnableState; // TODO: support stencil buffer usage
uint16 m_StencilReadMask = 0xFFFF;
uint16 m_StencilWriteMask = 0xFFFF;
struct StencilOpState
{
COMPARISON_FUNCTION Func = COMPARISON_FUNC_UNKNOWN;
STENCIL_OP StencilFailOp = STENCIL_OP_UNDEFINED;
STENCIL_OP StencilDepthFailOp = STENCIL_OP_UNDEFINED;
STENCIL_OP StencilPassOp = STENCIL_OP_UNDEFINED;
int32 Ref = std::numeric_limits<Int32>::min();
uint32 Mask = MAX_uint32;
}m_StencilOpState[2];*/
bool Writeframe;
CullMode CullMode;
bool DepthClampEnable;
BlendingMode BlendMode;
// OpenGL state
int32 _activeTextureUnit;
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUContextOGL"/> class.
/// </summary>
/// <param name="device">The graphics device.</param>
GPUContextOGL(GPUDeviceOGL* device);
/// <summary>
/// Finalizes an instance of the <see cref="GPUContextOGL"/> class.
/// </summary>
~GPUContextOGL();
private:
void SetActiveTextureUnit(int32 unit);
void flushSRVs();
void flushUAVs();
void flushCBs();
void flushOM();
void onDrawCall();
public:
// [GPUContext]
void FrameBegin() override;
bool IsDepthBufferBinded() override
{
return _rtDepth != nullptr;
}
void Clear(GPUTextureView* rt, const Color& color) override;
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override;
void ClearUA(Buffer* buf, const Vector4& value) override;
void ResetRenderTarget() override;
void SetRenderTarget(GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
void SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts) override;
void SetRenderTarget(GPUTextureView* rt, Buffer* uaOutput) override;
void ResetSR() override;
void ResetUA() override;
void ResetCB() override;
void BindCB(int32 slot, ConstantBuffer* cb) override;
void BindSR(int32 slot, GPUTextureView* rt) override;
void BindSR(int32 slot, Buffer* buf) override;
void BindUA(int32 slot, Buffer* buf) override;
void BindUA(int32 slot, Texture* rt) override;
void UpdateCB(ConstantBuffer* cb, const void* data) override;
void UpdateBuffer(Buffer* buffer, const void* data, uint32 size) override;
void Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCountX, uint32 threadGroupCountY, uint32 threadGroupCountZ) override;
void ResolveMultisample(Texture* sourceMultisampleTexture, Texture* destTexture, int32 sourceSubResource, int32 destSubResource, PixelFormat format) override;
void Draw(Buffer** vertexBuffers, int32 vertexBuffersCount, uint32 startVertex, uint32 verticesCount) override;
void DrawInstanced(Buffer** vertexBuffers, int32 vertexBuffersCount, uint32 instanceCount, int32 startInstance, uint32 startVertex, uint32 verticesCount) override;
void DrawIndexed(Buffer** vertexBuffers, int32 vertexBuffersCount, Buffer* indexBuffer, uint32 indicesCount, int32 startVertex, int32 startIndex) override;
void DrawIndexedInstanced(Buffer** vertexBuffers, int32 vertexBuffersCount, Buffer* indexBuffer, uint32 indicesCount, uint32 instanceCount, int32 startInstance, int32 startVertex, int32 startIndex) override;
void DrawInstancedIndirect(Buffer* bufferForArgs, uint32 offsetForArgs) override;
void SetViewport(const Viewport& viewport) override;
PipelineState* GetState() const override
{
return _currentState;
}
void SetState(PipelineState* state) override;
void ClearState() override;
void FlushState() override;
void Flush() override;
void UpdateSubresource(Texture* texture, int32 arrayIndex, int32 mipIndex, void* data, uint32 rowPitch, uint32 slicePitch) override;
void CopyTexture(Texture* dstResource, uint32 dstSubresource, uint32 dstX, uint32 dstY, uint32 dstZ, Texture* srcResource, uint32 srcSubresource) override;
void ResetCounter(Buffer* buffer, uint32 alignedByteOffset) override;
void CopyCounter(Buffer* dstBuffer, uint32 dstAlignedByteOffset, Buffer* srcBuffer) override;
void CopyResource(GPUResource* dstResource, GPUResource* srcResource) override;
void CopySubresource(GPUResource* dstResource, uint32 dstSubresource, GPUResource* srcResource, uint32 srcSubresource) override;
};
#endif

View File

@@ -1,315 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "Engine/Graphics/Config.h"
#if GRAPHICS_API_OPENGL
#include "GPUDeviceOGL.h"
#include "GPUResourcesFactoryOGL.h"
#include "GPULimitsOGL.h"
#include "ContextOGL.h"
#include "Win32/Win32ContextOGL.h"
#include "Engine/Core/Log.h"
#include "Engine/Render2D/Render2D.h"
#include "Engine/Graphics/RenderTask.h"
#include <regex>
GPUDeviceOGL::BlendDesc GPUDeviceOGL::BlendModes[5] =
{
// Opaque rendering (default)
{
false,
GL_ONE, GL_ZERO, GL_FUNC_ADD,
GL_ONE, GL_ZERO, GL_FUNC_ADD,
},
// Additive rendering
{
true,
GL_SRC_ALPHA, GL_ONE, GL_FUNC_ADD,
GL_SRC_ALPHA, GL_ONE, GL_FUNC_ADD,
},
// Alpha blended rendering
{
true,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_FUNC_ADD,
GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_FUNC_ADD,
},
// Add color rendering
{
true,
GL_ONE, GL_ONE, GL_FUNC_ADD,
GL_ONE, GL_ONE, GL_FUNC_ADD,
},
// Multiply output color with texture color
{
true,
GL_ZERO, GL_SRC_COLOR, GL_FUNC_ADD,
GL_ZERO, GL_SRC_ALPHA, GL_FUNC_ADD,
},
};
#define DEFINE_GL_ENTRYPOINTS(Type,Func) Type Func = NULL;
ENUM_GL_ENTRYPOINTS_ALL(DEFINE_GL_ENTRYPOINTS);
GPUDeviceOGL::GPUDeviceOGL(RendererType type, ShaderProfile profile, AdapterOGL* adapter, GPULimits* limits)
: GPUDevice(type, profile, limits, New<GPUResourcesFactoryOGL>(this))
, _adapter(adapter)
{
}
GPUDeviceOGL* GPUDeviceOGL::Create()
{
#define CHECK_NULL(obj) if (obj == nullptr) { return nullptr; }
bool GRunningUnderRenderDoc = false;
// Create a dummy context so that wglCreateContextAttribsARB can be initialized
Win32ContextOGL::Data DummyContext;
Win32ContextOGL::CreateDummyGLWindow(&DummyContext);
DummyContext.OpenGLContext = wglCreateContext(DummyContext.DeviceContext);
CHECK_NULL(DummyContext.OpenGLContext);
ASSERT(DummyContext.OpenGLContext);
Win32ContextOGL::ContextMakeCurrent(DummyContext.DeviceContext, DummyContext.OpenGLContext);
Win32ContextOGL::wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GetGLFuncAddress("wglCreateContextAttribsARB");
CHECK_NULL(DummyContext.OpenGLContext);
Win32ContextOGL::ContextMakeCurrent(NULL, NULL);
wglDeleteContext(DummyContext.OpenGLContext);
#if GRAPHICS_API_OPENGLES
todo_support-opengles
#else
// Try to create OpenGL 4.4 context
Win32ContextOGL::PlatformCreateOpenGLContextCore(&DummyContext, 4, 4, NULL);
if (DummyContext.OpenGLContext == nullptr)
{
// Try to create OpenGL 4.1 context
Win32ContextOGL::PlatformCreateOpenGLContextCore(&DummyContext, 4, 1, NULL);
if (DummyContext.OpenGLContext == nullptr)
{
LOG(Error, "OpenGL 4.1 is not supported by the driver.");
return nullptr;
}
}
#endif
Win32ContextOGL::ContextMakeCurrent(DummyContext.DeviceContext, DummyContext.OpenGLContext);
// Get all OpenGL functions from the OpenGL DLL
{
// Retrieve the OpenGL DLL
void* OpenGLDLL = Platform::GetDllHandle(TEXT("opengl32.dll"));
if (!OpenGLDLL)
{
LOG(Error, "Couldn't load opengl32.dll");
return nullptr;
}
// Initialize entry points required from opengl32.dll
#define GET_GL_ENTRYPOINTS_DLL(Type,Func) Func = (Type)Platform::GetDllExport(OpenGLDLL, #Func);
ENUM_GL_ENTRYPOINTS_DLL(GET_GL_ENTRYPOINTS_DLL);
// Release the OpenGL DLL
Platform::FreeDllHandle(OpenGLDLL);
// Initialize all entry points required by Flax
#define GET_GL_ENTRYPOINTS(Type,Func) Func = (Type)wglGetProcAddress(#Func);
ENUM_GL_ENTRYPOINTS(GET_GL_ENTRYPOINTS);
ENUM_GL_ENTRYPOINTS_OPTIONAL(GET_GL_ENTRYPOINTS);
// Check that all of the entry points have been initialized
bool isMissing = false;
#define CHECK_GL_ENTRYPOINTS(Type,Func) if (Func == NULL) { isMissing = true; LOG(Warning, "Failed to find entry point for {0}", TEXT(#Func)); }
ENUM_GL_ENTRYPOINTS_DLL(CHECK_GL_ENTRYPOINTS);
ENUM_GL_ENTRYPOINTS(CHECK_GL_ENTRYPOINTS);
if (isMissing)
{
LOG(Error, "Failed to find all OpenGL entry points.");
return nullptr;
}
}
// Create adapter
auto adapter = New<AdapterOGL>();
if (adapter->Init(DummyContext.DeviceContext))
{
Delete(adapter);
LOG(Error, "Failed to init OpenGL adapter.");
return nullptr;
}
// Create device
GPUDeviceOGL* device = nullptr;
#if GRAPHICS_API_OPENGLES
{
todo_support_opengles
//device = New<GPUDeviceOGLES3>(adapter);
}
#else
{
if (adapter->Version >= 440)
device = New<GPUDeviceOGL4_4>(adapter);
else
device = New<GPUDeviceOGL4_1>(adapter);
}
#endif
if (device->Init())
{
LOG(Warning, "Graphics Device init failed");
Delete(device);
return nullptr;
}
return device;
#undef CHECK_NULL
}
bool GPUDeviceOGL::Init()
{
// Base
if (GPUDevice::Init())
return true;
_state = DeviceState::Created;
// Init device limits
if (Limits->Init())
{
LOG(Warning, "Cannot initialize device limits.");
return true;
}
// Create main context
_mainContext = New<GPUContextOGL>(this);
// TODO: create vertex buffer for the quad drawing?
// Finished
_state = DeviceState::Inited;
return false;
}
bool GPUDeviceOGL::CanDraw()
{
return GPUDevice::CanDraw() && ContextOGL::IsReady();
}
GPUDeviceOGL::~GPUDeviceOGL()
{
// Ensure to be disposed
GPUDeviceOGL::Dispose();
}
#if GPU_OGL_USE_DEBUG_LAYER
void OpenGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
{
if (type != GL_DEBUG_TYPE_PERFORMANCE && type != GL_DEBUG_TYPE_OTHER)
{
LOG(Warning, "OpenGL error: {0}", (const char*)message);
}
}
#endif
void GPUDeviceOGL::InitWithMainContext()
{
#if GPU_OGL_USE_DEBUG_LAYER
if (_adapter->HasExtension("GL_ARB_debug_output"))
{
glDebugMessageCallbackARB(&OpenGlErrorCallback, 0);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
}
#endif
// Init some OpenGL states
glFrontFace(GL_CW);
// Intel HD4000 under <= 10.8.4 requires GL_DITHER disabled or dithering will occur on any channel < 8bits.
// No other driver does this but we don't need GL_DITHER on anyway.
glDisable(GL_DITHER);
// Render targets with sRGB flag should do sRGB conversion like in D3D11
glEnable(GL_FRAMEBUFFER_SRGB);
// Engine always expects seamless cubemap, so enable it if available
if (GetLimits()->SupportsSeamlessCubemap)
{
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
#if PLATFORM_WINDOWS || PLATFORM_LINUX
if (GetLimits()->SupportsClipControl)
{
glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);
}
#endif
}
void GPUDeviceOGL::Dispose()
{
GPUDeviceLock lock(this);
// Check if has been disposed already
if (_state == DeviceState::Disposed)
return;
// Set current state
_state = DeviceState::Disposing;
// Wait for rendering end
WaitForGPU();
// Pre dispose
preDispose();
// Clear device resources
FBOCache.Dispose();
VAOCache.Dispose();
// Clear OpenGL stuff
SAFE_DELETE(_mainContext);
SAFE_DELETE(_adapter);
// Base
GPUDevice::Dispose();
// Set current state
_state = DeviceState::Disposed;
}
void GPUDeviceOGL::WaitForGPU()
{
// Note: in OpenGL driver manages CPU/GPU work synchronization and work submission
}
#if GRAPHICS_API_OPENGLES
GPUDeviceOGLES3::GPUDeviceOGLES3(AdapterOGL* adapter)
: GPUDeviceOGL(RendererType::OpenGLES3, ShaderProfile::Unknown, adapter, New<GPULimitsOGL>(this))
{
}
GPUDeviceOGLES3_1::GPUDeviceOGLES3_1(AdapterOGL* adapter)
: GPUDeviceOGL(RendererType::OpenGLES3_1, ShaderProfile::Unknown, adapter, New<GPULimitsOGL>(this))
{
}
#else
GPUDeviceOGL4_1::GPUDeviceOGL4_1(AdapterOGL* adapter)
: GPUDeviceOGL(RendererType::OpenGL4_1, ShaderProfile::GLSL_410, adapter, New<GPULimitsOGL>(this))
{
}
GPUDeviceOGL4_4::GPUDeviceOGL4_4(AdapterOGL* adapter)
: GPUDeviceOGL(RendererType::OpenGL4_4, ShaderProfile::GLSL_440, adapter, New<GPULimitsOGL>(this))
{
}
#endif
#endif

View File

@@ -1,177 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/Config.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "AdapterOGL.h"
#include "FBOCache.h"
#include "VAOCache.h"
#include "Engine/Graphics/GPUDevice.h"
class Engine;
class GPUContextOGL;
class GPULimitsOGL;
class GPUSwapChainOGL;
/// <summary>
/// Base for all OpenGL graphics devices.
/// </summary>
class GPUDeviceOGL : public GPUDevice
{
friend GPUContextOGL;
friend GPUSwapChainOGL;
public:
typedef struct BlendDesc
{
bool BlendEnable;
GLenum SrcBlend;
GLenum DestBlend;
GLenum BlendOp;
GLenum SrcBlendAlpha;
GLenum DestBlendAlpha;
GLenum BlendOpAlpha;
} BlendDesc;
static BlendDesc BlendModes[5];
protected:
GPUContextOGL* _mainContext;
AdapterOGL* _adapter;
protected:
GPUDeviceOGL(RendererType type, ShaderProfile profile, AdapterOGL* adapter, GPULimits* limits);
public:
static GPUDeviceOGL* Create();
~GPUDeviceOGL();
public:
GPULimitsOGL* GetLimits()
{
return (GPULimitsOGL*)Limits;
}
/// <summary>
/// The frame buffer objects cache.
/// </summary>
FBOCache FBOCache;
/// <summary>
/// The vertex array objects cache.
/// </summary>
VAOCache VAOCache;
/// <summary>
/// Performs graphics device initialization after OpenGL main context creation and assign.
/// </summary>
void InitWithMainContext();
public:
// [GPUDevice]
Adapter* GetAdapter() const override
{
return _adapter;
}
GPUContext* GetMainContext() override
{
return reinterpret_cast<GPUContext*>(_mainContext);
}
void* GetNativePtr() const override
{
return nullptr;
}
bool Init() override;
bool CanDraw() override;
void WaitForGPU() override;
void Dispose() override;
Texture* CreateTexture(const StringView& name) override
{
return New<GPUTextureOGL>(_device, name);
}
Shader* CreateShader(const StringView& name) override
{
return New<GPUShaderOGL>(_device, name);
}
PipelineState* CreatePipelineState() override
{
return New<GPUPipelineStateOGL>(_device);
}
GPUTimerQuery* CreateTimerQuery() override
{
return New<GPUTimerQueryOGL>(_device);
}
Buffer* CreateBuffer(const StringView& name) override
{
return New<GPUBufferOGL>(_device, name);
}
GPUSwapChain* CreateGPUSwapChain(Window* parent, int32 width, int32 height, bool fullscreen) override
{
return GPUSwapChainOGL::Create(_device, parent, width, height, fullscreen);
}
};
#if GRAPHICS_API_OPENGLES
/// <summary>
/// Base for all OpenGL ES graphics devices
/// </summary>
class GPUDeviceOGLES : public GPUDeviceOGL
{
};
/// <summary>
/// Implementation of Graphics Device for OpenGL ES 3.0 (or higher) rendering system.
/// </summary>
class GPUDeviceOGLES3 : public GPUDeviceOGLES
{
public:
GPUDeviceOGLES3(AdapterOGL* adapter);
};
/// <summary>
/// Implementation of Graphics Device for OpenGL ES 3.1 (or higher) rendering system.
/// </summary>
class GPUDeviceOGLES3_1 : public GPUDeviceOGLES
{
public:
GPUDeviceOGLES3_1(AdapterOGL* adapter);
};
#else
/// <summary>
/// Implementation of Graphics Device for OpenGL 4.1 (or higher) rendering system.
/// </summary>
class GPUDeviceOGL4_1 : public GPUDeviceOGL
{
public:
GPUDeviceOGL4_1(AdapterOGL* adapter);
};
/// <summary>
/// Implementation of Graphics Device for OpenGL 4.4 (or higher) rendering system.
/// </summary>
class GPUDeviceOGL4_4 : public GPUDeviceOGL
{
public:
GPUDeviceOGL4_4(AdapterOGL* adapter);
};
#endif
#endif

View File

@@ -1,559 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/Config.h"
#include "Engine/Graphics/GPULimits.h"
#include "Engine/Graphics/RenderTools.h"
#include "GPUDeviceOGL.h"
#if BUILD_DEBUG
#include "Engine/Core/Types/StringBuilder.h"
#endif
struct TextureFormatOGL
{
public:
GLenum InternalFormat;
GLenum Format;
GLenum Type;
bool IsCompressed;
public:
TextureFormatOGL()
{
InternalFormat = GL_NONE;
Format = GL_NONE;
Type = GL_NONE;
IsCompressed = false;
}
TextureFormatOGL(GLenum internalFormat, GLenum format, GLenum type, bool isCompressed = false, bool isBGRA = false)
{
InternalFormat = internalFormat;
Format = format;
Type = type;
IsCompressed = isCompressed;
}
};
/// <summary>
/// Implementation of GPU Limits for OpenGL
/// </summary>
/// <seealso cref="GPULimits" />
class GPULimitsOGL : public GPULimits
{
protected:
GPUDeviceOGL * _device;
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPULimitsOGL"/> class.
/// </summary>
/// <param name="device">The device.</param>
GPULimitsOGL(GPUDeviceOGL* device)
: _device(device)
{
}
public:
bool SupportsTessellation;
bool SupportsGPUMemoryInfo;
bool SupportsComputeShaders;
bool SupportsVertexAttribBinding;
bool SupportsTextureView;
bool SupportsVolumeTextureRendering;
bool SupportsASTC;
bool SupportsCopyImage;
bool SupportsSeamlessCubemap;
bool SupportsTextureFilterAnisotropic;
bool SupportsDrawBuffersBlend;
bool SupportsSeparateShaderObjects;
bool SupportsClipControl;
uint64 VideoMemorySize;
int32 MaxTextureMipCount;
int32 MaxTextureSize;
int32 MaxCubeTextureSize;
int32 MaxVolumeTextureSize;
int32 MaxTextureArraySize;
int32 MaxOpenGLDrawBuffers;
int32 MaxTextureImageUnits;
int32 MaxCombinedTextureImageUnits;
int32 MaxVertexTextureImageUnits;
int32 MaxGeometryTextureImageUnits;
int32 MaxHullTextureImageUnits;
int32 MaxDomainTextureImageUnits;
int32 MaxVaryingVectors;
int32 MaxVertexUniformComponents;
int32 MaxPixelUniformComponents;
int32 MaxGeometryUniformComponents;
int32 MaxHullUniformComponents;
int32 MaxDomainUniformComponents;
int32 MaxComputeTextureImageUnits;
int32 MaxComputeUniformComponents;
TextureFormatOGL TextureFormats[static_cast<int32>(PixelFormat::Maximum)];
public:
GLenum GetInternalTextureFormat(PixelFormat format)
{
return TextureFormats[(int32)format].InternalFormat;
}
GLenum GetInternalTextureFormat(PixelFormat format, GPUTextureFlags flags)
{
GLenum f = TextureFormats[(int32)format].InternalFormat;
// Correct GL texure format
if (flags & GPUTextureFlags::DepthStencil)
{
if (f == GL_R32F)
f = GL_DEPTH_COMPONENT32F;
else if (f == GL_R16)
f = GL_DEPTH_COMPONENT16;
}
return f;
}
private:
void InitFormats()
{
// References:
// http://www.opengl.org/wiki/Image_Format
// http://www.g-truc.net/post-0335.html
// http://renderingpipeline.com/2012/07/texture-compression/
TextureFormats[(int32)PixelFormat::Unknown] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::R32G32B32A32_Typeless] = TextureFormatOGL(GL_RGBA32F, GL_RGBA, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32G32B32A32_Float] = TextureFormatOGL(GL_RGBA32F, GL_RGBA, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32G32B32A32_UInt] = TextureFormatOGL(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
TextureFormats[(int32)PixelFormat::R32G32B32A32_SInt] = TextureFormatOGL(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
TextureFormats[(int32)PixelFormat::R32G32B32_Typeless] = TextureFormatOGL(GL_RGB32F, GL_RGB, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32G32B32_Float] = TextureFormatOGL(GL_RGB32F, GL_RGB, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32G32B32_UInt] = TextureFormatOGL(GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT);
TextureFormats[(int32)PixelFormat::R32G32B32_SInt] = TextureFormatOGL(GL_RGB32I, GL_RGB_INTEGER, GL_INT);
TextureFormats[(int32)PixelFormat::R16G16B16A16_Typeless] = TextureFormatOGL(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
TextureFormats[(int32)PixelFormat::R16G16B16A16_Float] = TextureFormatOGL(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
TextureFormats[(int32)PixelFormat::R16G16B16A16_UNorm] = TextureFormatOGL(GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16G16B16A16_UInt] = TextureFormatOGL(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16G16B16A16_SNorm] = TextureFormatOGL(GL_RGBA16_SNORM, GL_RGBA, GL_SHORT);
TextureFormats[(int32)PixelFormat::R16G16B16A16_SInt] = TextureFormatOGL(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT);
TextureFormats[(int32)PixelFormat::R32G32_Typeless] = TextureFormatOGL(GL_RG32F, GL_RG, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32G32_Float] = TextureFormatOGL(GL_RG32F, GL_RG, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32G32_UInt] = TextureFormatOGL(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);
TextureFormats[(int32)PixelFormat::R32G32_SInt] = TextureFormatOGL(GL_RG32I, GL_RG_INTEGER, GL_INT);
TextureFormats[(int32)PixelFormat::R32G8X24_Typeless] = TextureFormatOGL(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
TextureFormats[(int32)PixelFormat::D32_Float_S8X24_UInt] = TextureFormatOGL(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
TextureFormats[(int32)PixelFormat::R32_Float_X8X24_Typeless] = TextureFormatOGL(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
TextureFormats[(int32)PixelFormat::X32_Typeless_G8X24_UInt] = TextureFormatOGL(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
TextureFormats[(int32)PixelFormat::R10G10B10A2_Typeless] = TextureFormatOGL(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
TextureFormats[(int32)PixelFormat::R10G10B10A2_UNorm] = TextureFormatOGL(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
TextureFormats[(int32)PixelFormat::R10G10B10A2_UInt] = TextureFormatOGL(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV);
TextureFormats[(int32)PixelFormat::R11G11B10_Float] = TextureFormatOGL(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV);
TextureFormats[(int32)PixelFormat::R8G8B8A8_Typeless] = TextureFormatOGL(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8B8A8_UNorm] = TextureFormatOGL(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8B8A8_UNorm_sRGB] = TextureFormatOGL(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8B8A8_UInt] = TextureFormatOGL(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8B8A8_SNorm] = TextureFormatOGL(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE);
TextureFormats[(int32)PixelFormat::R8G8B8A8_SInt] = TextureFormatOGL(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE);
TextureFormats[(int32)PixelFormat::R16G16_Typeless] = TextureFormatOGL(GL_RG16F, GL_RG, GL_HALF_FLOAT);
TextureFormats[(int32)PixelFormat::R16G16_Float] = TextureFormatOGL(GL_RG16F, GL_RG, GL_HALF_FLOAT);
TextureFormats[(int32)PixelFormat::R16G16_UNorm] = TextureFormatOGL(GL_RG16, GL_RG, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16G16_UInt] = TextureFormatOGL(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16G16_SNorm] = TextureFormatOGL(GL_RG16_SNORM, GL_RG, GL_SHORT);
TextureFormats[(int32)PixelFormat::R16G16_SInt] = TextureFormatOGL(GL_RG16I, GL_RG_INTEGER, GL_SHORT);
TextureFormats[(int32)PixelFormat::R32_Typeless] = TextureFormatOGL(GL_R32F, GL_RED, GL_FLOAT);
TextureFormats[(int32)PixelFormat::D32_Float] = TextureFormatOGL(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32_Float] = TextureFormatOGL(GL_R32F, GL_RED, GL_FLOAT);
TextureFormats[(int32)PixelFormat::R32_UInt] = TextureFormatOGL(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
TextureFormats[(int32)PixelFormat::R32_SInt] = TextureFormatOGL(GL_R32I, GL_RED_INTEGER, GL_INT);
TextureFormats[(int32)PixelFormat::R24G8_Typeless] = TextureFormatOGL(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
TextureFormats[(int32)PixelFormat::D24_UNorm_S8_UInt] = TextureFormatOGL(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
TextureFormats[(int32)PixelFormat::R24_UNorm_X8_Typeless] = TextureFormatOGL(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
TextureFormats[(int32)PixelFormat::X24_Typeless_G8_UInt] = TextureFormatOGL(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
TextureFormats[(int32)PixelFormat::R8G8_Typeless] = TextureFormatOGL(GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8_UNorm] = TextureFormatOGL(GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8_UInt] = TextureFormatOGL(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8G8_SNorm] = TextureFormatOGL(GL_RG8_SNORM, GL_RG, GL_BYTE);
TextureFormats[(int32)PixelFormat::R8G8_SInt] = TextureFormatOGL(GL_RG8I, GL_RG_INTEGER, GL_BYTE);
TextureFormats[(int32)PixelFormat::R16_Typeless] = TextureFormatOGL(GL_R16F, GL_RED, GL_HALF_FLOAT);
TextureFormats[(int32)PixelFormat::R16_Float] = TextureFormatOGL(GL_R16F, GL_RED, GL_HALF_FLOAT);
TextureFormats[(int32)PixelFormat::D16_UNorm] = TextureFormatOGL(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16_UNorm] = TextureFormatOGL(GL_R16, GL_RED, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16_UInt] = TextureFormatOGL(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);
TextureFormats[(int32)PixelFormat::R16_SNorm] = TextureFormatOGL(GL_R16_SNORM, GL_RED, GL_SHORT);
TextureFormats[(int32)PixelFormat::R16_SInt] = TextureFormatOGL(GL_R16I, GL_RED_INTEGER, GL_SHORT);
TextureFormats[(int32)PixelFormat::R8_Typeless] = TextureFormatOGL(GL_R8, GL_RED, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8_UNorm] = TextureFormatOGL(GL_R8, GL_RED, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8_UInt] = TextureFormatOGL(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);
TextureFormats[(int32)PixelFormat::R8_SNorm] = TextureFormatOGL(GL_R8_SNORM, GL_RED, GL_BYTE);
TextureFormats[(int32)PixelFormat::R8_SInt] = TextureFormatOGL(GL_R8I, GL_RED_INTEGER, GL_BYTE);
TextureFormats[(int32)PixelFormat::A8_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::R1_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::R9G9B9E5_SharedExp] = TextureFormatOGL(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV);
TextureFormats[(int32)PixelFormat::R8G8_B8G8_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::G8R8_G8B8_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::BC1_Typeless] = TextureFormatOGL(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC1_UNorm] = TextureFormatOGL(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC1_UNorm_sRGB] = TextureFormatOGL(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC2_Typeless] = TextureFormatOGL(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC2_UNorm] = TextureFormatOGL(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC2_UNorm_sRGB] = TextureFormatOGL(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC3_Typeless] = TextureFormatOGL(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC3_UNorm] = TextureFormatOGL(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC3_UNorm_sRGB] = TextureFormatOGL(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC4_Typeless] = TextureFormatOGL(GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC4_UNorm] = TextureFormatOGL(GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC4_SNorm] = TextureFormatOGL(GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC5_Typeless] = TextureFormatOGL(GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC5_UNorm] = TextureFormatOGL(GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC5_SNorm] = TextureFormatOGL(GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::B5G6R5_UNorm] = TextureFormatOGL(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV);
TextureFormats[(int32)PixelFormat::B5G5R5A1_UNorm] = TextureFormatOGL(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
TextureFormats[(int32)PixelFormat::B8G8R8A8_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::B8G8R8X8_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::R10G10B10_Xr_Bias_A2_UNorm] = TextureFormatOGL();
TextureFormats[(int32)PixelFormat::B8G8R8A8_Typeless] = TextureFormatOGL(GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
TextureFormats[(int32)PixelFormat::B8G8R8A8_UNorm_sRGB] = TextureFormatOGL(GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
TextureFormats[(int32)PixelFormat::B8G8R8X8_Typeless] = TextureFormatOGL(GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
TextureFormats[(int32)PixelFormat::B8G8R8X8_UNorm_sRGB] = TextureFormatOGL(GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
TextureFormats[(int32)PixelFormat::BC6H_Typeless] = TextureFormatOGL(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC6H_Uf16] = TextureFormatOGL(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC6H_Sf16] = TextureFormatOGL(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC7_Typeless] = TextureFormatOGL(GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC7_UNorm] = TextureFormatOGL(GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGB, GL_UNSIGNED_BYTE, true);
TextureFormats[(int32)PixelFormat::BC7_UNorm_sRGB] = TextureFormatOGL(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGB, GL_UNSIGNED_BYTE, true);
// Check features for each PixelFormat
for (int32 i = 0; i < static_cast<int32>(PixelFormat::Maximum); i++)
{
// TODO: try to detect MSAA or some feature levels like on D3D11
auto format = static_cast<PixelFormat>(i);
auto& info = TextureFormats[i];
FormatSupport support = FormatSupport::None;
if (info.Format != 0)
{
support = FormatSupport::Texture1D | FormatSupport::Texture2D | FormatSupport::Texture3D | FormatSupport::DepthStencil | FormatSupport::Buffer;
}
_featuresPerFormat[i] = FeaturesPerFormat(format, MSAALevel::None, support);
}
}
#if BUILD_DEBUG
void PrintStats()
{
#define PRINT_STAT(name) sb.AppendFormat(TEXT("{0} = {1}\n"), TEXT(#name), name)
StringBuilder sb;
sb.AppendLine();
sb.AppendLine();
auto adapter = (AdapterOGL*)_device->GetAdapter();
sb.AppendFormat(TEXT("OpenGL {0}.{1}\n"), adapter->VersionMajor, adapter->VersionMinor);
sb.AppendLine();
PRINT_STAT(SupportsTessellation);
PRINT_STAT(SupportsGPUMemoryInfo);
PRINT_STAT(SupportsComputeShaders);
PRINT_STAT(SupportsVertexAttribBinding);
PRINT_STAT(SupportsTextureView);
PRINT_STAT(SupportsVolumeTextureRendering);
PRINT_STAT(SupportsASTC);
PRINT_STAT(SupportsCopyImage);
PRINT_STAT(SupportsSeamlessCubemap);
PRINT_STAT(SupportsTextureFilterAnisotropic);
PRINT_STAT(SupportsDrawBuffersBlend);
PRINT_STAT(SupportsSeparateShaderObjects);
PRINT_STAT(SupportsClipControl);
sb.AppendLine();
PRINT_STAT(VideoMemorySize);
PRINT_STAT(MaxTextureMipCount);
PRINT_STAT(MaxTextureSize);
PRINT_STAT(MaxCubeTextureSize);
PRINT_STAT(MaxVolumeTextureSize);
PRINT_STAT(MaxTextureArraySize);
PRINT_STAT(MaxOpenGLDrawBuffers);
PRINT_STAT(MaxTextureImageUnits);
PRINT_STAT(MaxCombinedTextureImageUnits);
PRINT_STAT(MaxVertexTextureImageUnits);
PRINT_STAT(MaxGeometryTextureImageUnits);
PRINT_STAT(MaxHullTextureImageUnits);
PRINT_STAT(MaxDomainTextureImageUnits);
PRINT_STAT(MaxVaryingVectors);
PRINT_STAT(MaxVertexUniformComponents);
PRINT_STAT(MaxPixelUniformComponents);
PRINT_STAT(MaxGeometryUniformComponents);
PRINT_STAT(MaxHullUniformComponents);
PRINT_STAT(MaxDomainUniformComponents);
PRINT_STAT(MaxComputeTextureImageUnits);
PRINT_STAT(MaxComputeUniformComponents);
sb.AppendLine();
LOG_STR(Info, sb.ToString());
#undef PRINT_STAT
}
#endif
public:
// [GPULimits]
bool Init() override
{
auto adapter = (AdapterOGL*)_device->GetAdapter();
auto VersionMajor = adapter->VersionMajor;
auto VersionMinor = adapter->VersionMinor;
// Test graphics pipeline features support
SupportsTessellation = (VersionMajor >= 4) || adapter->HasExtension("GL_ARB_tessellation_shader");
SupportsGPUMemoryInfo = adapter->HasExtension("GL_NVX_gpu_memory_info");
SupportsComputeShaders = (VersionMajor == 4 && VersionMinor >= 3) || (VersionMajor > 4) || adapter->HasExtension("GL_ARB_compute_shader");
SupportsVertexAttribBinding = (VersionMajor == 4 && VersionMinor >= 3) || (VersionMajor > 4) || adapter->HasExtension("GL_ARB_vertex_attrib_binding");
SupportsTextureView = (VersionMajor == 4 && VersionMinor >= 3) || (VersionMajor > 4) || adapter->HasExtension("GL_ARB_texture_view");
SupportsASTC = adapter->HasExtension("GL_KHR_texture_compression_astc_ldr");
SupportsCopyImage = adapter->HasExtension("GL_ARB_copy_image");
SupportsSeamlessCubemap = adapter->HasExtension("GL_ARB_seamless_cube_map");
SupportsTextureFilterAnisotropic = adapter->HasExtension("GL_EXT_texture_filter_anisotropic");
SupportsDrawBuffersBlend = adapter->HasExtension("GL_ARB_draw_buffers_blend");
SupportsClipControl = adapter->HasExtension("GL_ARB_clip_control");
#if GRAPHICS_API_OPENGL_ES
SupportsSeparateShaderObjects = false;
#else
SupportsSeparateShaderObjects = (VersionMajor == 4 && VersionMinor >= 4) || adapter->HasExtension("GL_ARB_separate_shader_objects");
#endif
// Get video memory size (in bytes)
VideoMemorySize = 0;
if (SupportsGPUMemoryInfo)
{
GLint VMSizeKB = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &VMSizeKB);
VideoMemorySize = VMSizeKB * 1024ll;
}
// Test whether the GPU can support volume-texture rendering.
// There is no API to query this - you just have to test whether a 3D texture is framebuffer-complete.
{
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer);
GLuint volumeTexture;
glGenTextures(1, &volumeTexture);
glBindTexture(GL_TEXTURE_3D, volumeTexture);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 256, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, volumeTexture, 0);
SupportsVolumeTextureRendering = (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glDeleteTextures(1, &volumeTexture);
glDeleteFramebuffers(1, &frameBuffer);
}
// Get the device limits with OpenGL API
#define LOG_AND_GET_GL_INT_TEMP(IntEnum, Default) GLint Value_##IntEnum = Default; if (IntEnum) {glGetIntegerv(IntEnum, &Value_##IntEnum); glGetError();} else {Value_##IntEnum = Default;}
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TEXTURE_SIZE, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_CUBE_MAP_TEXTURE_SIZE, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_ARRAY_TEXTURE_LAYERS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_3D_TEXTURE_SIZE, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_RENDERBUFFER_SIZE, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_DRAW_BUFFERS, 1);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_COLOR_ATTACHMENTS, 1);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_SAMPLES, 1);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_COLOR_TEXTURE_SAMPLES, 1);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_DEPTH_TEXTURE_SAMPLES, 1);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_INTEGER_SAMPLES, 1);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_VERTEX_ATTRIBS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_VERTEX_UNIFORM_COMPONENTS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_VARYING_VECTORS, 0);
// Setup the actual limits
MaxTextureSize = Value_GL_MAX_TEXTURE_SIZE;
MaxTextureMipCount = Math::Min<int32>(GPU_MAX_TEXTURE_MIP_LEVELS, MipLevelsCount(MaxTextureSize));
MaxCubeTextureSize = Value_GL_MAX_CUBE_MAP_TEXTURE_SIZE;
MaxTextureArraySize = Value_GL_MAX_ARRAY_TEXTURE_LAYERS;
MaxVolumeTextureSize = MaxCubeTextureSize;
MaxOpenGLDrawBuffers = Value_GL_MAX_DRAW_BUFFERS;
MaxTextureImageUnits = Value_GL_MAX_TEXTURE_IMAGE_UNITS;
MaxCombinedTextureImageUnits = Value_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;
MaxVertexTextureImageUnits = Value_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
MaxGeometryTextureImageUnits = Value_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS;
MaxHullTextureImageUnits = Value_GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS;
MaxDomainTextureImageUnits = Value_GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS;
MaxVaryingVectors = Value_GL_MAX_VARYING_VECTORS;
MaxVertexUniformComponents = Value_GL_MAX_VERTEX_UNIFORM_COMPONENTS;
MaxPixelUniformComponents = Value_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS;
MaxGeometryUniformComponents = Value_GL_MAX_GEOMETRY_UNIFORM_COMPONENTS;
if (SupportsTessellation)
{
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, 0);
MaxHullUniformComponents = Value_GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS;
MaxDomainUniformComponents = Value_GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS;
}
else
{
MaxHullUniformComponents = 0;
MaxDomainUniformComponents = 0;
}
if (SupportsComputeShaders)
{
LOG_AND_GET_GL_INT_TEMP(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, 0);
LOG_AND_GET_GL_INT_TEMP(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, 0);
MaxComputeTextureImageUnits = Value_GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS;
MaxComputeUniformComponents = Value_GL_MAX_COMPUTE_UNIFORM_COMPONENTS;
}
else
{
MaxComputeTextureImageUnits = 0;
MaxComputeUniformComponents = 0;
}
// For now, just allocate additional units if available and advertise no tessellation units for HW that can't handle more
if (MaxCombinedTextureImageUnits < 48)
{
// To work around AMD driver limitation of 32 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
// Going to hard code this for now (16 units in PS, 8 units in VS, 8 units in GS).
// This is going to be a problem for tessellation.
MaxTextureImageUnits = MaxTextureImageUnits > 16 ? 16 : MaxTextureImageUnits;
MaxVertexTextureImageUnits = MaxVertexTextureImageUnits > 8 ? 8 : MaxVertexTextureImageUnits;
MaxGeometryTextureImageUnits = MaxGeometryTextureImageUnits > 8 ? 8 : MaxGeometryTextureImageUnits;
MaxHullTextureImageUnits = 0;
MaxDomainTextureImageUnits = 0;
MaxCombinedTextureImageUnits = MaxCombinedTextureImageUnits > 32 ? 32 : MaxCombinedTextureImageUnits;
}
else
{
// Clamp things to the levels that the other path is going, but allow additional units for tessellation
MaxTextureImageUnits = MaxTextureImageUnits > 16 ? 16 : MaxTextureImageUnits;
MaxVertexTextureImageUnits = MaxVertexTextureImageUnits > 8 ? 8 : MaxVertexTextureImageUnits;
MaxGeometryTextureImageUnits = MaxGeometryTextureImageUnits > 8 ? 8 : MaxGeometryTextureImageUnits;
MaxHullTextureImageUnits = MaxHullTextureImageUnits > 8 ? 8 : MaxHullTextureImageUnits;
MaxDomainTextureImageUnits = MaxDomainTextureImageUnits > 8 ? 8 : MaxDomainTextureImageUnits;
MaxCombinedTextureImageUnits = MaxCombinedTextureImageUnits > 48 ? 48 : MaxCombinedTextureImageUnits;
}
InitFormats();
#if BUILD_DEBUG
PrintStats();
#endif
// Validate minimum specs for the engine to start
if (!SupportsTextureView)
{
LOG(Error, "The GPU does not meet minimal requirements.");
return true;
}
return false;
}
bool HasCompute() const override
{
return SupportsComputeShaders;
}
bool HasTessellation() const override
{
return SupportsTessellation;
}
bool HasGeometryShaders() const override
{
#if GRAPHICS_API_OPENGLES
return false;
#else
return true;
#endif
}
bool HasVolumeTextureRendering() const override
{
return SupportsVolumeTextureRendering;
}
bool HasDrawIndirect() const override
{
return false;
}
bool HasAppendConsumeBuffers() const override
{
return false;
}
bool HasSeparateRenderTargetBlendState() const override
{
return false;
}
bool HasDepthAsSRV() const override
{
return true;
}
bool HasMultisampleDepthAsSRV() const override
{
return true;
}
int32 MaximumMipLevelsCount() const override
{
return MaxTextureMipCount;
}
int32 MaximumTexture1DSize() const override
{
return MaxTextureSize;
}
int32 MaximumTexture1DArraySize() const override
{
return MaxTextureArraySize;
}
int32 MaximumTexture2DSize() const override
{
return MaxTextureSize;
}
int32 MaximumTexture2DArraySize() const override
{
return MaxTextureArraySize;
}
int32 MaximumTexture3DSize() const override
{
return MaxVolumeTextureSize;
}
int32 MaximumTextureCubeSize() const override
{
return MaxCubeTextureSize;
}
};
#endif

View File

@@ -1,101 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if GRAPHICS_API_OPENGL
#include "GPUPipelineStateOGL.h"
#include "GPUDeviceOGL.h"
#include "GPULimitsOGL.h"
#include "RenderToolsOGL.h"
#include "Shaders/GPUShaderProgramOGL.h"
GPUPipelineStateOGL::GPUPipelineStateOGL(GPUDeviceOGL* device)
: GPUResourceOGL<PipelineState>(device, StringView::Empty)
{
}
GPUPipelineStateOGL::~GPUPipelineStateOGL()
{
ReleaseGPU();
}
void GPUPipelineStateOGL::OnBind()
{
if (!IsCreated)
{
ASSERT(ProgramPipeline == 0 && Program == 0);
glGenProgramPipelines(1, &ProgramPipeline);
VALIDATE_OPENGL_RESULT();
_usedSRsMask = 0;
if (VS != nullptr)
{
glUseProgramStages(ProgramPipeline, GL_VERTEX_SHADER_BIT, VS->GetHandle());
VALIDATE_OPENGL_RESULT();
_usedSRsMask |= VS->GetSRsMask();
}
if (PS != nullptr)
{
glUseProgramStages(ProgramPipeline, GL_FRAGMENT_SHADER_BIT, PS->GetHandle());
VALIDATE_OPENGL_RESULT();
_usedSRsMask |= PS->GetSRsMask();
}
if (GS != nullptr)
{
glUseProgramStages(ProgramPipeline, GL_GEOMETRY_SHADER_BIT, GS->GetHandle());
VALIDATE_OPENGL_RESULT();
_usedSRsMask |= GS->GetSRsMask();
}
IsCreated = true;
}
}
void GPUPipelineStateOGL::ReleaseGPU()
{
if (_memoryUsage == 0)
return;
if (Program != 0)
{
glDeleteProgram(Program);
Program = 0;
}
if (ProgramPipeline != 0)
{
glDeleteProgramPipelines(1, &ProgramPipeline);
ProgramPipeline = 0;
}
IsCreated = false;
_memoryUsage = 0;
}
bool GPUPipelineStateOGL::IsValid() const
{
return _memoryUsage != 0;
}
bool GPUPipelineStateOGL::Init(const Description& desc)
{
// Cache state
_memoryUsage = 1;
EnableDepthWrite = desc.EnableDepthWrite;
DepthTestEnable = desc.DepthTestEnable;
DepthClipEnable = desc.DepthClipEnable;
DepthFunc = desc.DepthFunc;
VS = (GPUShaderProgramVSOGL*)desc.VS;
GS = (GPUShaderProgramGSOGL*)desc.GS;
PS = (GPUShaderProgramPSOGL*)desc.PS;
PrimitiveTopologyType = desc.PrimitiveTopologyType;
Wireframe = desc.Wireframe;
CullMode = desc.CullMode;
BlendMode = desc.BlendMode;
return PipelineState::Create(desc);
}
#endif

View File

@@ -1,80 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/GPUPipelineState.h"
#include "GPUResourceOGL.h"
#if GRAPHICS_API_OPENGL
class GPUShaderProgramVSOGL;
class GPUShaderProgramGSOGL;
class GPUShaderProgramPSOGL;
/// <summary>
/// Graphics pipeline state object for OpenGL.
/// </summary>
class GPUPipelineStateOGL : public GPUResourceOGL<PipelineState>
{
private:
int32 _usedSRsMask;
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUPipelineStateOGL"/> class.
/// </summary>
/// <param name="device">The graphics device.</param>
GPUPipelineStateOGL(GPUDeviceOGL* device);
/// <summary>
/// Finalizes an instance of the <see cref="GPUPipelineStateOGL"/> class.
/// </summary>
~GPUPipelineStateOGL();
public:
bool EnableDepthWrite;
bool DepthTestEnable;
bool DepthClipEnable;
ComparisonFunc DepthFunc;
GPUShaderProgramVSOGL* VS;
GPUShaderProgramGSOGL* GS;
GPUShaderProgramPSOGL* PS;
PrimitiveTopologyType PrimitiveTopologyType;
bool Wireframe;
CullMode CullMode;
BlendingMode BlendMode;
bool IsCreated = false;
GLuint Program = 0;
GLuint ProgramPipeline = 0;
public:
int32 GetSRsMask() const
{
return _usedSRsMask;
}
bool IsUsingSR(int32 slotIndex) const
{
return _usedSRsMask & (1 << slotIndex) != 0;
}
public:
void OnBind();
public:
// [GPUResourceOGL]
void ReleaseGPU() final override;
// [GPUPipelineState]
bool IsValid() const override;
bool Init(const Description& desc) override;
};
#endif

View File

@@ -1,103 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/Config.h"
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/GPUResource.h"
#include "Engine/Core/Log.h"
#include "IncludeOpenGLHeaders.h"
#include "GPUDeviceOGL.h"
/// <summary>
/// Describes base implementation of Graphics Device resource for OpenGL (BaseType must be GPUResource or inherit from)
/// </summary>
template<class BaseType>
class GPUResourceOGL : public BaseType
{
protected:
GPUDeviceOGL* _device;
uint64 _memoryUsage;
private:
#if GPU_ENABLE_RESOURCE_NAMING
String _name;
#endif
protected:
/// <summary>
/// Init
/// </summary>
/// <param name="device">Graphics Device handle</param>
/// <param name="name">Resource name</param>
GPUResourceOGL(GPUDeviceOGL* device, const String& name)
: _device(device)
, _memoryUsage(0)
#if GPU_ENABLE_RESOURCE_NAMING
, _name(name)
#endif
{
ASSERT(device);
// Register
device->Resources.Add(this);
}
public:
/// <summary>
/// Destructor
/// </summary>
virtual ~GPUResourceOGL()
{
// Unregister
if (_device)
_device->Resources.Remove(this);
// Check if is still using any GPU memory
if (_memoryUsage != 0)
{
LOG(Fatal, "GPU resource \'{0}\' has not been fully disposed.", GPUResource::ToString());
}
}
public:
/// <summary>
/// Gets graphics device
/// </summary>
/// <returns>Device</returns>
FORCE_INLINE GPUDeviceOGL* GetDevice() const
{
return _device;
}
public:
// [GPUResource]
uint64 GetMemoryUsage() const override
{
return _memoryUsage;
}
#if GPU_ENABLE_RESOURCE_NAMING
String GetName() const override
{
return _name;
}
#endif
void OnDeviceDispose() override
{
// Base
GPUResource::OnDeviceDispose();
// Unlink device handle
_device = nullptr;
}
};
#endif

View File

@@ -1,258 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if GRAPHICS_API_OPENGL
#include "GPUShaderOGL.h"
#include "Engine/Core/Memory/Allocator.h"
#include "Engine/Serialization/MemoryReadStream.h"
#include "GPUConstantBufferOGL.h"
#include "GPUShaderProgramOGL.h"
#include "Engine/Graphics/GPULimitsOGL.h"
#include <LZ4/lz4.h>
GPUShaderOGL::GPUShaderOGL(GPUDeviceOGL* device, const String& name)
: GPUResourceOGL<Shader>(device, name)
{
}
GPUShaderOGL::~GPUShaderOGL()
{
}
void GPUShaderOGL::ReleaseGPU()
{
// Base
GPUResourceOGL::ReleaseGPU();
}
static bool SupportsSeparateShaderObjects()
{
return ((GPULimitsOGL*)GPUDevice::Instance->Limits)->SupportsSeparateShaderObjects;
}
// Verify that an OpenGL program has linked successfully.
static bool VerifyLinkedProgram(GLuint program)
{
#if BUILD_DEBUG || GPU_OGL_DEBUG_SHADERS
GLint linkStatus = 0;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE)
{
GLint logLength;
char defaultLog[] = "No log";
char* compileLog = defaultLog;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 1)
{
compileLog = (char*)Allocator::Allocate(logLength);
glGetProgramInfoLog(program, logLength, NULL, compileLog);
}
LOG(Error, "Failed to link program. Compile log: \n{0}", compileLog);
if (logLength > 1)
{
Allocator::Free(compileLog);
}
return false;
}
#endif
return true;
}
// Verify that an OpenGL shader has compiled successfully.
static bool VerifyCompiledShader(GLuint shader, const char* glslCode)
{
#if BUILD_DEBUG || GPU_OGL_DEBUG_SHADERS
if (SupportsSeparateShaderObjects() && glIsProgram(shader))
{
bool const compiledOK = VerifyLinkedProgram(shader);
#if GPU_OGL_DEBUG_SHADERS
if (!compiledOK && glslCode)
{
LOG(Warning, "Shader: \n{0}", glslCode);
}
#endif
return compiledOK;
}
else
{
GLint compileStatus;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus != GL_TRUE)
{
GLint logLength;
char defaultLog[] = "No log";
char* compileLog = defaultLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
#if PLATFORM_ANDROID
if (LogLength == 0)
{
// Make it big anyway
// There was a bug in android 2.2 where glGetShaderiv would return 0 even though there was a error message
// https://code.google.com/p/android/issues/detail?id=9953
LogLength = 4096;
}
#endif
if (logLength > 1)
{
compileLog = (char*)Allocator::Allocate(logLength);
glGetShaderInfoLog(shader, logLength, NULL, compileLog);
}
#if GPU_OGL_DEBUG_SHADERS
if (glslCode)
{
LOG(Warning, "Shader: \n{0}", glslCode);
}
#endif
LOG(Fatal, "Failed to compile shader. Compile log: \n{0}", compileLog);
if (logLength > 1)
{
Allocator::Free(compileLog);
}
return false;
}
}
#endif
return true;
}
static bool VerifyProgramPipeline(GLuint Program)
{
bool result = true;
// Don't try and validate SSOs here - the draw state matters to SSOs and it definitely can't be guaranteed to be valid at this stage
if (SupportsSeparateShaderObjects())
{
#if GPU_OGL_DEBUG_SHADERS
result = glIsProgramPipeline(Program) == GL_TRUE;
#endif
}
else
{
result = VerifyLinkedProgram(Program);
}
return result;
}
bool GPUShaderOGL::Create(MemoryReadStream& stream)
{
ASSERT(_device);
ReleaseGPU();
// Version
int32 version;
stream.ReadInt32(&version);
if (version != GPU_SHADER_CACHE_VERSION)
{
LOG(Warning, "Unsupported OpenGL shader version {0}.", version);
return true;
}
Array<byte> cache;
Array<byte> cache2;
// Shaders count
int32 shadersCount;
stream.ReadInt32(&shadersCount);
for (int32 i = 0; i < shadersCount; i++)
{
uint32 cacheSize;
ShaderStage type = static_cast<ShaderStage>(stream.ReadByte());
int32 permutationsCount = stream.ReadByte();
ASSERT(Math::IsInRange(permutationsCount, 1, SHADER_PERMUTATIONS_MAX_COUNT));
// Load shader name
StringAnsi name;
stream.ReadStringAnsi(&name, 11);
for (int32 permutationIndex = 0; permutationIndex < permutationsCount; permutationIndex++)
{
// Load cache
int32 cacheType;
stream.ReadInt32(&cacheType);
uint32 cacheOriginalSize;
stream.ReadUint32(&cacheOriginalSize);
stream.ReadUint32(&cacheSize);
ASSERT(Math::IsInRange<uint32>(cacheSize, 1, 1024 * 1024));
cache.EnsureCapacity(cacheSize);
stream.ReadBytes(cache.Get(), cacheSize);
// Check if unpack the data
byte* shaderBytes = cache.Get();
if (cacheType == SHADER_DATA_FORMAT_RAW)
{
ASSERT(cacheOriginalSize == cacheSize);
}
else if (cacheType == SHADER_DATA_FORMAT_LZ4)
{
// Decompress LZ4 data
cache2.EnsureCapacity(cacheOriginalSize);
int32 res = LZ4_decompress_safe((const char*)cache.Get(), (char*)cache2.Get(), cacheSize, cacheOriginalSize);
if (res <= 0)
{
LOG(Warning, "Failed to decompress OpenGL shader data. Result: {0}.", res);
return true;
}
cacheSize = cacheOriginalSize;
shaderBytes = cache2.Get();
}
else
{
LOG(Warning, "Unknown OpenGL shader data format.");
return true;
}
// Create Flax shader object
GPUShaderProgram* shader;
switch (type)
{
case ShaderStage::Vertex: shader = New<GPUShaderProgramVSOGL>(_device, shaderBytes, cacheSize, stream, name); break;
case ShaderStage::Hull: shader = New<GPUShaderProgramHSOGL>(_device, shaderBytes, cacheSize, stream, name); break;
case ShaderStage::Domain: shader = New<GPUShaderProgramDSOGL>(_device, shaderBytes, cacheSize, stream, name); break;
case ShaderStage::Geometry: shader = New<GPUShaderProgramGSOGL>(shaderBytes, cacheSize, stream, name); break;
case ShaderStage::Pixel: shader = New<GPUShaderProgramPSOGL>(shaderBytes, cacheSize, stream, name); break;
case ShaderStage::Compute: shader = New<GPUShaderProgramCSOGL>(shaderBytes, cacheSize, stream, name); break;
default: return true;
}
// Add to collection
_shaders.Add(shader, permutationIndex);
}
}
// Constant Buffers
byte constantBuffersCount = stream.ReadByte();
byte maximumConstantBufferSlot = stream.ReadByte();
if (constantBuffersCount > 0)
{
ASSERT(maximumConstantBufferSlot < MAX_CONSTANT_BUFFER_SLOTS);
for (int32 i = 0; i < constantBuffersCount; i++)
{
// Load info
byte slotIndex = stream.ReadByte();
uint32 size;
stream.ReadUint32(&size);
// Create CB
#if GPU_ENABLE_RESOURCE_NAMING
String name = ToString() + TEXT(".CB") + i;
#else
String name;
#endif
auto cb = New<GPUConstantBufferOGL>(_device, name, size);
ASSERT(_constantBuffers[slotIndex] == nullptr);
_constantBuffers[slotIndex] = cb;
}
}
return false;
}
#endif

View File

@@ -1,39 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/Shaders/GPUShader.h"
#include "GPUDeviceOGL.h"
#include "GPUResourceOGL.h"
/// <summary>
/// Shader for OpenGL
/// </summary>
class GPUShaderOGL : public GPUResourceOGL<Shader>
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="ShaderOGL"/> class.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="name">The name.</param>
ShaderOGL(GPUDeviceOGL* device, const String& name);
/// <summary>
/// Destructor
/// </summary>
~ShaderOGL();
public:
// [GPUResourceOGL]
void ReleaseGPU() final override;
// [GPUShader]
bool Create(MemoryReadStream& stream) override;
};
#endif

View File

@@ -1,57 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "GPUShaderProgramOGL.h"
#if GRAPHICS_API_OPENGL
#include "../RenderToolsOGL.h"
#include "../GPUDeviceOGL.h"
#include "../GPULimitsOGL.h"
GPUShaderProgramVSOGL::GPUShaderProgramVSOGL(GPUDeviceOGL* device, byte* shaderBytes, uint32 shaderBytesSize, ReadStream& stream, const StringAnsi& name)
: GPUShaderProgramOGL(GL_VERTEX_SHADER, shaderBytes, shaderBytesSize, stream, name)
, _device(device)
{
// Temporary variables
byte Type, Format, SemanticIndex, InputSlot, InputSlotClass;
uint32 AlignedByteOffset, InstanceDataStepRate;
// Load Input Layout (it may be empty)
byte layoutSize;
stream.ReadByte(&layoutSize);
ASSERT(layoutSize <= VERTEX_SHADER_MAX_INPUT_ELEMENTS);
Layout.SetSize(layoutSize);
uint32 offset = 0;
for (int32 a = 0; a < layoutSize; a++)
{
auto& e = Layout[a];
// TODO: cleanup the old vertex input layout loading style to be more robust
stream.ReadByte(&Type);
stream.ReadByte(&SemanticIndex);
stream.ReadByte(&Format);
stream.ReadByte(&InputSlot);
stream.ReadUint32(&AlignedByteOffset);
stream.ReadByte(&InputSlotClass);
stream.ReadUint32(&InstanceDataStepRate);
e.BufferSlot = InputSlot;
e.Format = (PixelFormat)Format;
e.Size = PixelFormatExtensions::SizeInBytes(e.Format);
e.InstanceDataStepRate = InstanceDataStepRate;
e.InputIndex = SemanticIndex;
e.TypeCount = PixelFormatExtensions::ComputeComponentsCount(e.Format);
if (PixelFormatExtensions::IsBGRAOrder(e.Format))
e.TypeCount = GL_BGRA;
e.Normalized = PixelFormatExtensions::IsNormalized(e.Format) ? GL_TRUE : GL_FALSE;
e.GlType = _device->GetLimits()->TextureFormats[(int32)e.Format].Type;
e.IsInteger = e.GlType == GL_SHORT || e.GlType == GL_UNSIGNED_SHORT || e.GlType == GL_INT || e.GlType == GL_UNSIGNED_INT || e.GlType == GL_UNSIGNED_BYTE;
// Items are always specified in a sequential order
e.RelativeOffset = AlignedByteOffset == INPUT_LAYOUT_ELEMENT_ALIGN ? offset : AlignedByteOffset;
offset = (e.RelativeOffset == 0 ? 0 : offset) + e.Size;
}
}
#endif

View File

@@ -1,282 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Serialization/ReadStream.h"
#include "Engine/Graphics/Shaders/GPUShaderProgram.h"
#include "../RenderToolsOGL.h"
#include "../GPUDeviceOGL.h"
#if GRAPHICS_API_OPENGL
/// <summary>
/// Shaders base class for OpenGL
/// </summary>
template<typename BaseType>
class GPUShaderProgramOGL : public BaseType
{
protected:
GLuint _handle;
GLenum _shaderType;
Array<byte> _shader;
#if GPU_OGL_KEEP_SHADER_SRC
const char* ShaderSource = nullptr;
#endif
public:
/// <summary>
/// Init
/// </summary>
/// <param name="shaderType">Type of the OpenGL shader</param>
/// <param name="shaderBytes">Bytes with an compiled shader</param>
/// <param name="shaderBytesSize">Size in bytes of the cached shader</param>
/// <param name="stream">Stream with data to read</param>
/// <param name="name">Shader function name</param>
GPUShaderProgramOGL(GLenum shaderType, byte* shaderBytes, uint32 shaderBytesSize, ReadStream& stream, const StringAnsi& name)
: _handle(0)
, _shaderType(shaderType)
{
_name = name;
// Cache shader source (it cannot be compiled on content loading thread) - because OpenGL sucks
// TODO: use shared context and compile shaders on a content threads instead of main thread
_shader.Set(shaderBytes, shaderBytesSize);
// Load meta
stream.ReadUint32(&_instructionsCount);
stream.ReadUint32(&_usedCBsMask);
stream.ReadUint32(&_usedSRsMask);
stream.ReadUint32(&_usedUAsMask);
}
/// <summary>
/// Destructor
/// </summary>
~GPUShaderProgramOGL()
{
#if GPU_OGL_KEEP_SHADER_SRC
Allocator::Free(ShaderSource);
#endif
if (_handle != 0)
{
glDeleteProgram(_handle);
VALIDATE_OPENGL_RESULT();
}
}
private:
static GLuint glCreateGPUShaderProgram(GLenum type, const char* source)
{
const GLuint shader = glCreateShader(type);
if (shader)
{
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
const GLuint program = glCreateProgram();
if (program)
{
GLint compiled = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
if (compiled)
{
glAttachShader(program, shader);
glLinkProgram(program);
glDetachShader(program, shader);
}
}
glDeleteShader(shader);
return program;
}
return 0;
}
public:
// Gets the OpenGL shader object handle. Performs compilation if shader has not been created yet.
GLuint GetHandle()
{
if (_handle == 0)
{
// Compile the shader
_handle = glCreateGPUShaderProgram(_shaderType, (const char*)_shader.Get());
VALIDATE_OPENGL_RESULT();
// Check the status and the messages
{
GLint linkCompileSuccess = 0;
glGetProgramiv(_handle, GL_LINK_STATUS, &linkCompileSuccess);
VALIDATE_OPENGL_RESULT();
if (!linkCompileSuccess && _handle > 0)
{
GLint infologLength = 0;
glGetProgramiv(_handle, GL_INFO_LOG_LENGTH, &infologLength);
VALIDATE_OPENGL_RESULT();
if (infologLength > 0)
{
GLint charsWritten = 0;
Array<GLchar> infoLog;
infoLog.Resize(infologLength);
glGetProgramInfoLog(_handle, infologLength, &charsWritten, infoLog.Get());
VALIDATE_OPENGL_RESULT();
LOG(Warning, "Compile and linker info log:");
LOG_STR(Warning, String(infoLog.Get()));
}
}
}
#if GPU_OGL_KEEP_SHADER_SRC
ShaderSource = Allocator::Allocate(_shader.Count());
Platform::MemoryCopy((void*)ShaderSource, (void*)_shader.Get(), _shader.Count() * sizeof(char));
#endif
// Cleanup source buffer
_shader.Resize(0);
}
return _handle;
}
public:
// [BaseType]
uint32 GetBufferSize() const override
{
return 0;
}
void* GetBufferHandle() const override
{
return (void*)_handle;
}
};
/// <summary>
/// Vertex Shader for OpenGL
/// </summary>
class GPUShaderProgramVSOGL : public GPUShaderProgramOGL<GPUShaderProgramVS>
{
public:
struct LayoutElement
{
int32 BufferSlot;
PixelFormat Format;
int32 Size;
int32 InstanceDataStepRate;
int32 InputIndex;
int32 RelativeOffset;
int32 TypeCount;
GLboolean Normalized;
GLenum GlType;
bool IsInteger;
};
private:
GPUDeviceOGL* _device;
public:
/// <summary>
/// Init
/// </summary>
/// <param name="device">The graphics device.</param>
/// <param name="shaderBytes">Bytes with an compiled shader</param>
/// <param name="shaderBytesSize">Size in bytes of the cached shader</param>
/// <param name="stream">Stream with data to read</param>
/// <param name="name">Shader function name</param>
GPUShaderProgramVSOGL(GPUDeviceOGL* device, byte* shaderBytes, uint32 shaderBytesSize, ReadStream& stream, const StringAnsi& name);
/// <summary>
/// Destructor
/// </summary>
~GPUShaderProgramVSOGL()
{
_device->VAOCache.OnObjectRelease(this);
}
public:
Array<LayoutElement, FixedAllocation<VERTEX_SHADER_MAX_INPUT_ELEMENTS>> Layout;
public:
// [GPUShaderProgramOGL]
void* GetInputLayout() const override
{
return (void*)nullptr;
}
byte GetInputLayoutSize() const override
{
return Layout.Count();
}
};
/// <summary>
/// Geometry Shader for OpenGL
/// </summary>
class GPUShaderProgramGSOGL : public GPUShaderProgramOGL<GPUShaderProgramGS>
{
public:
/// <summary>
/// Init
/// </summary>
/// <param name="shaderBytes">Bytes with an compiled shader</param>
/// <param name="shaderBytesSize">Size in bytes of the cached shader</param>
/// <param name="stream">Stream with data to read</param>
/// <param name="name">Shader function name</param>
GPUShaderProgramGSOGL(byte* shaderBytes, uint32 shaderBytesSize, ReadStream& stream, const StringAnsi& name)
: GPUShaderProgramOGL(GL_GEOMETRY_SHADER, shaderBytes, shaderBytesSize, stream, name)
{
}
};
/// <summary>
/// Pixel Shader for OpenGL
/// </summary>
class GPUShaderProgramPSOGL : public GPUShaderProgramOGL<GPUShaderProgramPS>
{
public:
/// <summary>
/// Init
/// </summary>
/// <param name="shaderBytes">Bytes with an compiled shader</param>
/// <param name="shaderBytesSize">Size in bytes of the cached shader</param>
/// <param name="stream">Stream with data to read</param>
/// <param name="name">Shader function name</param>
GPUShaderProgramPSOGL(byte* shaderBytes, uint32 shaderBytesSize, ReadStream& stream, const StringAnsi& name)
: GPUShaderProgramOGL(GL_FRAGMENT_SHADER, shaderBytes, shaderBytesSize, stream, name)
{
}
};
/// <summary>
/// Compute Shader for OpenGL
/// </summary>
class GPUShaderProgramCSOGL : public GPUShaderProgramOGL<GPUShaderProgramCS>
{
public:
/// <summary>
/// Init
/// </summary>
/// <param name="shaderBytes">Bytes with an compiled shader</param>
/// <param name="shaderBytesSize">Size in bytes of the cached shader</param>
/// <param name="stream">Stream with data to read</param>
/// <param name="name">Shader function name</param>
GPUShaderProgramCSOGL(byte* shaderBytes, uint32 shaderBytesSize, ReadStream& stream, const StringAnsi& name)
: GPUShaderProgramOGL(GL_COMPUTE_SHADER, shaderBytes, shaderBytesSize, stream, name)
{
}
};
#endif

View File

@@ -1,39 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "GPUSwapChainOGL.h"
#if GRAPHICS_API_OPENGL
#include "Engine/Threading/Threading.h"
#include "Engine/Platform/Window.h"
#include "RenderToolsOGL.h"
#if PLATFORM_WIN32
#include "Win32/Win32GPUSwapChainOGL.h"
#endif
GPUSwapChainOGL* GPUSwapChainOGL::Create(GPUDeviceOGL* device, Window* parent, int32 width, int32 height, bool fullscreen)
{
// Create object
#if PLATFORM_WIN32
Win32GPUSwapChainOGL* result = Win32GPUSwapChainOGL::Create(device, parent);
#else
#Error "The current platform does not support OpenGL backend."
#endif
// Resize output
result->Resize(width, height);
// Check if enter fullscreen mode
if (fullscreen)
result->SetFullscreen(true);
return result;
}
GPUSwapChainOGL::GPUSwapChainOGL(GPUDeviceOGL* device, Window* parent)
: GPUResourceOGL(device, StringView::Empty)
{
setParent(parent);
}
#endif

View File

@@ -1,38 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/GPUSwapChain.h"
#include "GPUDeviceOGL.h"
#include "GPUResourceOGL.h"
#include "GPUTextureViewOGL.h"
#include "IncludeOpenGLHeaders.h"
#if GRAPHICS_API_OPENGL
/// <summary>
/// Graphics Device rendering output for OpenGL
/// </summary>
class GPUSwapChainOGL : public GPUResourceOGL<GPUSwapChain>
{
protected:
GPUTextureViewOGL _backBufferHandle;
GPUSwapChainOGL(GPUDeviceOGL* device, Window* parent);
public:
// Init
static GPUSwapChainOGL* Create(GPUDeviceOGL* device, Window* parent, int32 width, int32 height, bool fullscreen);
public:
// [GPUSwapChain]
GPUTextureView* GetBackBufferView() const override
{
return (GPUTextureView*)&_backBufferHandle;
}
};
#endif

View File

@@ -1,94 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "TextureOGL.h"
#if GRAPHICS_API_OPENGL
#include "RenderToolsOGL.h"
#include "GPUDeviceOGL.h"
#include "GPULimitsOGL.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
void TextureOGL::initHandles()
{
// Cache properties
bool useSRV = IsShaderResource();
bool useDSV = IsDepthStencil();
bool useRTV = IsRenderTarget();
bool useUAV = IsUnorderedAccess();
int32 arraySize = ArraySize();
int32 mipLevels = MipLevels();
bool isArray = arraySize > 1;
bool isCubeMap = IsCubeMap();
bool isMsaa = IsMultiSample();
bool isVolume = IsVolume();
// Create resource views
if (useUAV)
{
_uav.InitAsFull(this, Format());
}
if (isVolume)
{
// Create handle for whole 3d texture
_handleVolume.InitAsFull(this);
// Init per slice views
_handlesPerSlice.Resize(Depth(), false);
if (_desc.HasPerSliceViews() && useRTV)
{
for (int32 sliceIndex = 0; sliceIndex < Depth(); sliceIndex++)
{
_handlesPerSlice[sliceIndex].InitAsView(this, Format(), GPUTextureViewOGL::ViewType::Texture2D, mipLevels, sliceIndex, 1);
}
}
}
else if (isArray)
{
// Resize handles
_handlesPerSlice.Resize(ArraySize(), false);
// Create per array slice handles
for (int32 arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
_handlesPerSlice[arrayIndex].InitAsView(this, Format(), GPUTextureViewOGL::ViewType::Texture2D, mipLevels, arrayIndex, 1);
}
// Create whole array handle
{
if (isCubeMap)
{
_handleArray.InitAsView(this, Format(), GPUTextureViewOGL::ViewType::Texture2D_Array, mipLevels, 0, arraySize);
}
else
{
_handleArray.InitAsView(this, Format(), GPUTextureViewOGL::ViewType::TextureCube_Array, mipLevels, 0, arraySize);
}
}
}
else
{
// Create single handle for the whole texture
_handlesPerSlice.Resize(1, false);
_handlesPerSlice[0].InitAsFull(this);
}
// Init per mip map handles
if (HasPerMipViews())
{
// Init handles
_handlesPerMip.Resize(arraySize, false);
for (int32 arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
auto& slice = _handlesPerMip[arrayIndex];
slice.Resize(mipLevels, false);
for (int32 mipIndex = 0; mipIndex < mipLevels; mipIndex++)
{
slice[mipIndex].InitAsView(this, Format(), GPUTextureViewOGL::ViewType::Texture2D, mipLevels, arrayIndex, 1, mipIndex);
}
}
}
}
#endif

View File

@@ -1,166 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "TextureOGL.h"
#if GRAPHICS_API_OPENGL
#include "RenderToolsOGL.h"
#include "GPUDeviceOGL.h"
#include "GPULimitsOGL.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
TextureOGL::TextureOGL(GPUDeviceOGL* device, const String& name)
: GPUResourceOGL(device, name)
{
}
bool TextureOGL::init()
{
ASSERT(IsInMainThread());
switch (_desc.Dimensions)
{
case TextureDimensions::Texture:
{
if (IsMultiSample())
{
Target = IsArray() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_MULTISAMPLE;
}
else
{
Target = IsArray() ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
}
}
break;
case TextureDimensions::CubeTexture:
{
Target = IsArray() ? GL_TEXTURE_CUBE_MAP_ARRAY : GL_TEXTURE_CUBE_MAP;
}
break;
case TextureDimensions::VolumeTexture:
{
Target = GL_TEXTURE_3D;
}
break;
}
// Generate texture handle
glGenTextures(1, &TextureID);
VALIDATE_OPENGL_RESULT();
// Set texture type
glBindTexture(Target, TextureID);
VALIDATE_OPENGL_RESULT();
glTexParameteri(Target, GL_TEXTURE_MAX_LEVEL, _desc.MipLevels - 1);
VALIDATE_OPENGL_RESULT();
// Allocate internal buffer so that glTexSubImageXD can be used
FormatGL = _device->GetLimits()->GetInternalTextureFormat(_desc.Format, _desc.Flags);
// Init storage info
switch (_desc.Dimensions)
{
case TextureDimensions::Texture:
{
if (IsMultiSample())
{
if (IsArray())
{
CRASH;
//glTexStorage3DMultisample(Target, (GLsizei)_desc.MultiSampleLevel, FormatGL, _desc.Width, _desc.Height, _desc.ArraySize, GL_TRUE);
}
else
{
glTexStorage2DMultisample(Target, (GLsizei)_desc.MultiSampleLevel, FormatGL, _desc.Width, _desc.Height, GL_TRUE);
}
}
else
{
if (IsArray())
{
glTexStorage3D(Target, _desc.MipLevels, FormatGL, _desc.Width, _desc.Height, _desc.ArraySize);
}
else
{
glTexStorage2D(Target, _desc.MipLevels, FormatGL, _desc.Width, _desc.Height);
}
}
}
break;
case TextureDimensions::CubeTexture:
{
if (IsArray())
{
glTexStorage3D(Target, _desc.MipLevels, FormatGL, _desc.Width, _desc.Height, _desc.ArraySize);
}
else
{
glTexStorage2D(Target, _desc.MipLevels, FormatGL, _desc.Width, _desc.Height);
}
}
break;
case TextureDimensions::VolumeTexture:
{
glTexStorage3D(Target, _desc.MipLevels, FormatGL, _desc.Width, _desc.Height, _desc.Depth);
}
break;
}
VALIDATE_OPENGL_RESULT();
// Update memory usage
_memoryUsage = calculateMemoryUsage();
// Initialize handles to the resource
if (IsRegularTexture())
{
// 'Regular' texture is using only one handle (texture/cubemap)
_handlesPerSlice.Resize(1, false);
_handlesPerSlice[0].InitAsFull(this);
}
else
{
// Create all handles
initHandles();
}
return false;
}
void TextureOGL::onResidentMipsChanged()
{
// TODO: change GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL to match D3D11 behaviour
}
void TextureOGL::release()
{
if (IsRenderTarget() || IsUnorderedAccess())
_device->FBOCache.OnTextureRelease(this);
// Release views
_handlesPerMip.Resize(0, false);
_handlesPerSlice.Resize(0, false);
_handleArray.Release();
_handleVolume.Release();
// Release texture
glDeleteTextures(1, &TextureID);
VALIDATE_OPENGL_RESULT();
TextureID = 0;
Target = 0;
FormatGL = 0;
_memoryUsage = 0;
// Base
Texture::release();
}
bool TextureOGL::GetData(int32 arrayOrDepthSliceIndex, int32 mipMapIndex, TextureData::MipData& data, uint32 mipRowPitch)
{
MISSING_CODE("TextureOGL::GetData");
return true;
}
#endif

View File

@@ -1,88 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/Textures/GPUTexture.h"
#include "GPUDeviceOGL.h"
#include "GPUResourceOGL.h"
#include "GPUTextureViewOGL.h"
#if GRAPHICS_API_OPENGL
/// <summary>
/// Texture object for OpenGL
/// </summary>
class GPUTextureOGL : public GPUResourceOGL<Texture>
{
private:
GPUTextureViewOGL _uav;
GPUTextureViewOGL _handleArray;
GPUTextureViewOGL _handleVolume;
Array<GPUTextureViewOGL> _handlesPerSlice; // [slice]
Array<Array<GPUTextureViewOGL>> _handlesPerMip; // [slice][mip]
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUTextureOGL"/> class.
/// </summary>
/// <param name="device">The device.</param>
/// <param name="name">The name.</param>
GPUTextureOGL(GPUDeviceOGL* device, const String& name);
/// <summary>
/// Finalizes an instance of the <see cref="GPUTextureOGL"/> class.
/// </summary>
~GPUTextureOGL()
{
}
public:
GLuint TextureID = 0;
GLenum Target = 0;
GLenum FormatGL = 0;
GPUTextureViewOGL* HandleUAV() const
{
ASSERT((GetDescription().Flags & GPUTextureFlags::UnorderedAccess) != 0);
return (GPUTextureViewOGL*)&_uav;
}
private:
void initHandles();
public:
// [GPUTexture]
GPUTextureView* Handle(int32 arrayOrDepthIndex) const override
{
return (GPUTextureView*)&_handlesPerSlice[arrayOrDepthIndex];
}
GPUTextureView* Handle(int32 arrayOrDepthIndex, int32 mipMapIndex) const override
{
return (GPUTextureView*)&_handlesPerMip[arrayOrDepthIndex][mipMapIndex];
}
GPUTextureView* ViewArray() const override
{
ASSERT(ArraySize() > 1);
return (GPUTextureView*)&_handleArray;
}
GPUTextureView* ViewVolume() const override
{
ASSERT(IsVolume());
return (GPUTextureView*)&_handleVolume;
}
bool GetData(int32 arrayOrDepthSliceIndex, int32 mipMapIndex, TextureData::MipData& data, uint32 mipRowPitch) override;
protected:
// [GPUTexture]
bool OnInit() override;
void onResidentMipsChanged() override;
void OnReleaseGPU() override;
};
#endif

View File

@@ -1,264 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "GPUTextureViewOGL.h"
#if GRAPHICS_API_OPENGL
#include "TextureOGL.h"
#include "GPUDeviceOGL.h"
#include "GPULimitsOGL.h"
#include "RenderToolsOGL.h"
GPUTextureViewOGL::~GPUTextureViewOGL()
{
if (ViewID != 0)
{
glDeleteTextures(1, &ViewID);
VALIDATE_OPENGL_RESULT();
}
}
void GPUTextureViewOGL::InitAsBackbuffer(GPUResource* parent, PixelFormat format)
{
ASSERT(ViewID == 0);
ViewTarget = 0;
Texture = nullptr;
IsFullView = true;
MipLevels = 1;
FirstArraySlice = 0;
NumArraySlices = 1;
MostDetailedMip = 0;
Init(parent, format);
}
void GPUTextureViewOGL::InitAsFull(TextureOGL* parent)
{
InitAsFull(parent, parent->Format());
}
void GPUTextureViewOGL::InitAsFull(TextureOGL* parent, PixelFormat format)
{
ASSERT(ViewID == 0);
ViewTarget = parent->Target;
Texture = parent;
IsFullView = true;
MipLevels = parent->MipLevels();
FirstArraySlice = 0;
NumArraySlices = parent->ArraySize();
MostDetailedMip = 0;
Init(parent, format);
}
void GPUTextureViewOGL::InitAsView(TextureOGL* parent, PixelFormat format, ViewType type, int32 mipLevels, int32 firstArraySlice, int32 numArraySlices, int32 mostDetailedMipIndex)
{
ASSERT(ViewID == 0);
switch (type)
{
case ViewType::Texture1D:
ViewTarget = GL_TEXTURE_1D;
break;
case ViewType::Texture1D_Array:
ViewTarget = GL_TEXTURE_1D_ARRAY;
break;
case ViewType::Texture2D:
ViewTarget = parent->IsMultiSample() ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
break;
case ViewType::Texture2D_Array:
ViewTarget = parent->IsMultiSample() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY;
break;
case ViewType::Texture3D:
ViewTarget = GL_TEXTURE_3D;
break;
case ViewType::TextureCube:
ViewTarget = GL_TEXTURE_CUBE_MAP;
break;
case ViewType::TextureCube_Array:
ViewTarget = GL_TEXTURE_CUBE_MAP_ARRAY;
break;
}
glGenTextures(1, &ViewID);
VALIDATE_OPENGL_RESULT();
auto internalFormat = parent->GetDevice()->GetLimits()->GetInternalTextureFormat(format);
glTextureView(ViewID, ViewTarget, parent->TextureID, internalFormat, mostDetailedMipIndex, mipLevels, firstArraySlice, numArraySlices);
VALIDATE_OPENGL_RESULT();
Texture = parent;
IsFullView = false;
MipLevels = mipLevels;
FirstArraySlice = firstArraySlice;
NumArraySlices = numArraySlices;
MostDetailedMip = mostDetailedMipIndex;
}
void GPUTextureViewOGL::AttachToFramebuffer(GLenum attachmentPoint)
{
auto desc = GetTexture()->GetDescription();
auto textureId = GetTexture()->TextureID;
switch (desc.Dimensions)
{
case TextureDimensions::Texture:
{
if (desc.IsArray())
{
if (NumArraySlices == desc.ArraySize)
{
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
glFramebufferTexture(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
}
else if (NumArraySlices == 1)
{
// Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture,
// cube map array texture, or multisample array texture.
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip, FirstArraySlice);
VALIDATE_OPENGL_RESULT();
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip, FirstArraySlice);
VALIDATE_OPENGL_RESULT();
}
else
{
LOG(Fatal, "Only one slice or the entire texture array can be attached to a framebuffer");
}
}
else
{
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachmentPoint, GetTexture()->Target, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachmentPoint, GetTexture()->Target, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
}
}
break;
case TextureDimensions::CubeTexture:
{
if (desc.IsArray())
{
// Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers.
// So the parameters that represent the Z component are layer-faces.
if (NumArraySlices == desc.ArraySize)
{
// glFramebufferTexture() attaches the given mipmap levelas a layered image with the number of layers that the given texture has.
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
glFramebufferTexture(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
}
else if (NumArraySlices == 1)
{
// Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture,
// cube map array texture, or multisample array texture.
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip, FirstArraySlice);
VALIDATE_OPENGL_RESULT();
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip, FirstArraySlice);
VALIDATE_OPENGL_RESULT();
}
else
{
LOG(Fatal, "Only one slice or the entire cubemap array can be attached to a framebuffer");
}
}
else
{
if (NumArraySlices == desc.ArraySize)
{
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
glFramebufferTexture(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
}
else if (NumArraySlices == 1)
{
// Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture,
// cube map array texture, or multisample array texture.
static const GLenum CubeMapFaces[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};
auto CubeMapFaceBindTarget = CubeMapFaces[FirstArraySlice];
// For glFramebufferTexture2D, if texture is not zero, textarget must be one of GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE,
// GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
// GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
// or GL_TEXTURE_2D_MULTISAMPLE.
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, CubeMapFaceBindTarget, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, CubeMapFaceBindTarget, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
}
else
{
LOG(Fatal, "Only one slice or the entire cubemap can be attached to a framebuffer");
}
}
}
break;
case TextureDimensions::VolumeTexture:
{
if (NumArraySlices == desc.ArraySize)
{
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
glFramebufferTexture(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip);
VALIDATE_OPENGL_RESULT();
}
else if (NumArraySlices == 1)
{
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip, FirstArraySlice);
VALIDATE_OPENGL_RESULT();
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, attachmentPoint, textureId, MostDetailedMip, FirstArraySlice);
VALIDATE_OPENGL_RESULT();
}
else
{
LOG(Fatal, "Only one slice or the entire 3D texture can be attached to a framebuffer");
}
}
break;
}
}
void GPUTextureViewOGL::Release()
{
if (ViewID != 0)
{
glDeleteTextures(1, &ViewID);
VALIDATE_OPENGL_RESULT();
ViewID = 0;
}
ViewTarget = 0;
}
void GPUTextureViewOGL::Bind(int32 slotIndex)
{
if (IsFullView)
{
glBindTexture(Texture->Target, Texture->TextureID);
VALIDATE_OPENGL_RESULT();
}
else
{
// TODO: bind image with glBindImageTexture
CRASH;
}
}
#endif

View File

@@ -1,93 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/GPUTextureView.h"
#include "IncludeOpenGLHeaders.h"
#if GRAPHICS_API_OPENGL
#include "IShaderResourceOGL.h"
class TextureOGL;
/// <summary>
/// Render target handle for OpenGL
/// </summary>
class GPUTextureViewOGL : public GPUTextureView, public IShaderResourceOGL
{
public:
/// <summary>
/// The OpenGL texture view target.
/// </summary>
GLuint ViewTarget;
/// <summary>
/// The OpenGL texture view target.
/// </summary>
GLuint ViewID;
public:
GPUTextureViewOGL()
{
ViewTarget = 0;
ViewID = 0;
Texture = nullptr;
}
~GPUTextureViewOGL();
public:
TextureOGL* Texture;
bool IsFullView;
int32 MipLevels;
int32 FirstArraySlice;
int32 NumArraySlices;
int32 MostDetailedMip;
public:
bool IsBackbuffer() const
{
// Render output backbuffers are used as a special case for rendering in OpenGL
return IsFullView && Texture == nullptr;
}
TextureOGL* GetTexture() const
{
return Texture;
}
void InitAsBackbuffer(GPUResource* parent, PixelFormat format);
void InitAsFull(TextureOGL* parent);
void InitAsFull(TextureOGL* parent, PixelFormat format);
enum class ViewType
{
Texture1D,
Texture1D_Array,
Texture2D,
Texture2D_Array,
Texture3D,
TextureCube,
TextureCube_Array,
};
void InitAsView(TextureOGL* parent, PixelFormat format, ViewType type, int32 mipLevels, int32 firstArraySlice, int32 numArraySlices, int32 mostDetailedMipIndex = 0);
void AttachToFramebuffer(GLenum attachmentPoint);
void Release();
public:
// [IShaderResourceOGL]
void Bind(int32 slotIndex) override;
};
#endif

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if GRAPHICS_API_OPENGL
#include "GPUTimerQueryOGL.h"
#include "RenderToolsOGL.h"
GPUTimerQueryOGL::GPUTimerQueryOGL(GPUDeviceOGL* device)
: GPUResourceOGL<GPUTimerQuery>(device, String::Empty)
{
GLuint queries[2];
glGenQueries(2, queries);
VALIDATE_OPENGL_RESULT();
_startQuery = queries[0];
_endQuery = queries[1];
// Set non-zero mem usage (fake)
_memoryUsage = sizeof(queries);
}
GPUTimerQueryOGL::~GPUTimerQueryOGL()
{
ReleaseGPU();
}
void GPUTimerQueryOGL::ReleaseGPU()
{
if (_memoryUsage == 0)
return;
GLuint queries[2];
queries[0] = _startQuery;
queries[1] = _endQuery;
glDeleteQueries(2, queries);
VALIDATE_OPENGL_RESULT();
_memoryUsage = 0;
}
void GPUTimerQueryOGL::Begin()
{
glQueryCounter(_startQuery, GL_TIMESTAMP);
VALIDATE_OPENGL_RESULT();
_endCalled = false;
}
void GPUTimerQueryOGL::End()
{
if (_endCalled)
return;
glQueryCounter(_endQuery, GL_TIMESTAMP);
VALIDATE_OPENGL_RESULT();
_endCalled = true;
_finalized = false;
}
bool GPUTimerQueryOGL::HasResult()
{
if (!_endCalled)
return false;
GLint done = 0;
glGetQueryObjectiv(_endQuery, GL_QUERY_RESULT_AVAILABLE, &done);
VALIDATE_OPENGL_RESULT();
return done == GL_TRUE;
}
float GPUTimerQueryOGL::GetResult()
{
if (!_finalized)
{
#if BUILD_DEBUG
ASSERT(HasResult());
#endif
GLuint64 timeStart;
GLuint64 timeEnd;
glGetQueryObjectui64v(_startQuery, GL_QUERY_RESULT, &timeStart);
VALIDATE_OPENGL_RESULT();
glGetQueryObjectui64v(_endQuery, GL_QUERY_RESULT, &timeEnd);
VALIDATE_OPENGL_RESULT();
_timeDelta = (timeEnd - timeStart) / 1000000.0f;
_finalized = true;
}
return _timeDelta;
}
#endif

View File

@@ -1,49 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Graphics/GPUTimerQuery.h"
#include "GPUResourceOGL.h"
#if GRAPHICS_API_OPENGL
/// <summary>
/// GPU timer query object for OpenGL
/// </summary>
class GPUTimerQueryOGL : public GPUResourceOGL<GPUTimerQuery>
{
private:
bool _finalized = false;
bool _endCalled = false;
float _timeDelta = 0.0f;
GLuint _startQuery;
GLuint _endQuery;
public:
/// <summary>
/// Initializes a new instance of the <see cref="GPUTimerQueryOGL"/> class.
/// </summary>
/// <param name="device">The graphics device.</param>
GPUTimerQueryOGL(GPUDeviceOGL* device);
/// <summary>
/// Finalizes an instance of the <see cref="GPUTimerQueryOGL"/> class.
/// </summary>
~GPUTimerQueryOGL();
public:
// [GPUResourceOGL]
void ReleaseGPU() final override;
// [GPUTimerQuery]
void Begin() override;
void End() override;
bool HasResult() override;
float GetResult() override;
};
#endif

View File

@@ -1,18 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
using Flax.Build.NativeCpp;
/// <summary>
/// OpenGL graphics backend module.
/// </summary>
public class GraphicsDeviceOGL : GraphicsDeviceBaseModule
{
/// <inheritdoc />
public override void Setup(BuildOptions options)
{
base.Setup(options);
options.PublicDefinitions.Add("GRAPHICS_API_OPENGL");
//options.PublicDefinitions.Add("GRAPHICS_API_OPENGLES");
}
}

View File

@@ -1,12 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/BaseTypes.h"
class IShaderResourceOGL
{
public:
virtual void Bind(int32 slotIndex) = 0;
};

View File

@@ -1,415 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Config.h"
#if GRAPHICS_API_OPENGL
#if PLATFORM_WINDOWS
#include "Engine/Platform/Windows/IncludeWindowsHeaders.h"
#include "Engine/Platform/Windows/ComPtr.h"
#include <Wingdi.h>
#include <OpenGL/GL/glcorearb.h>
#include <OpenGL/GL/glext.h>
#include <OpenGL/GL/wglext.h>
#pragma comment(lib, "opengl32.lib")
// List all OpenGL entry points used by Flax that must be loaded from opengl32.dll
#define ENUM_GL_ENTRYPOINTS_DLL(EnumMacro) \
EnumMacro(PFNGLBINDTEXTUREPROC,glBindTexture) \
EnumMacro(PFNGLBLENDFUNCPROC,glBlendFunc) \
EnumMacro(PFNGLCOLORMASKPROC,glColorMask) \
EnumMacro(PFNGLCOPYTEXIMAGE1DPROC,glCopyTexImage1D) \
EnumMacro(PFNGLCOPYTEXIMAGE2DPROC,glCopyTexImage2D) \
EnumMacro(PFNGLCOPYTEXSUBIMAGE1DPROC,glCopyTexSubImage1D) \
EnumMacro(PFNGLCOPYTEXSUBIMAGE2DPROC,glCopyTexSubImage2D) \
EnumMacro(PFNGLCULLFACEPROC,glCullFace) \
EnumMacro(PFNGLDELETETEXTURESPROC,glDeleteTextures) \
EnumMacro(PFNGLDEPTHFUNCPROC,glDepthFunc) \
EnumMacro(PFNGLDEPTHMASKPROC,glDepthMask) \
EnumMacro(PFNGLDEPTHRANGEPROC,glDepthRange) \
EnumMacro(PFNGLDISABLEPROC,glDisable) \
EnumMacro(PFNGLDRAWARRAYSPROC,glDrawArrays) \
EnumMacro(PFNGLDRAWBUFFERPROC,glDrawBuffer) \
EnumMacro(PFNGLDRAWELEMENTSPROC,glDrawElements) \
EnumMacro(PFNGLENABLEPROC,glEnable) \
EnumMacro(PFNGLFINISHPROC,glFinish) \
EnumMacro(PFNGLFLUSHPROC,glFlush) \
EnumMacro(PFNGLFRONTFACEPROC,glFrontFace) \
EnumMacro(PFNGLGENTEXTURESPROC,glGenTextures) \
EnumMacro(PFNGLGETBOOLEANVPROC,glGetBooleanv) \
EnumMacro(PFNGLGETDOUBLEVPROC,glGetDoublev) \
EnumMacro(PFNGLGETERRORPROC,glGetError) \
EnumMacro(PFNGLGETFLOATVPROC,glGetFloatv) \
EnumMacro(PFNGLGETINTEGERVPROC,glGetIntegerv) \
EnumMacro(PFNGLGETPOINTERVPROC,glGetPointerv) \
EnumMacro(PFNGLGETSTRINGPROC,glGetString) \
EnumMacro(PFNGLGETTEXIMAGEPROC,glGetTexImage) \
EnumMacro(PFNGLGETTEXLEVELPARAMETERFVPROC,glGetTexLevelParameterfv) \
EnumMacro(PFNGLGETTEXLEVELPARAMETERIVPROC,glGetTexLevelParameteriv) \
EnumMacro(PFNGLGETTEXPARAMETERFVPROC,glGetTexParameterfv) \
EnumMacro(PFNGLGETTEXPARAMETERIVPROC,glGetTexParameteriv) \
EnumMacro(PFNGLHINTPROC,glHint) \
EnumMacro(PFNGLISENABLEDPROC,glIsEnabled) \
EnumMacro(PFNGLISTEXTUREPROC,glIsTexture) \
EnumMacro(PFNGLLINEWIDTHPROC,glLineWidth) \
EnumMacro(PFNGLLOGICOPPROC,glLogicOp) \
EnumMacro(PFNGLPIXELSTOREFPROC,glPixelStoref) \
EnumMacro(PFNGLPIXELSTOREIPROC,glPixelStorei) \
EnumMacro(PFNGLPOINTSIZEPROC,glPointSize) \
EnumMacro(PFNGLPOLYGONMODEPROC,glPolygonMode) \
EnumMacro(PFNGLPOLYGONOFFSETPROC,glPolygonOffset) \
EnumMacro(PFNGLREADBUFFERPROC,glReadBuffer) \
EnumMacro(PFNGLREADPIXELSPROC,glReadPixels) \
EnumMacro(PFNGLSCISSORPROC,glScissor) \
EnumMacro(PFNGLCLEARDEPTHPROC,glClearDepth) \
EnumMacro(PFNGLCLEARCOLORPROC,glClearColor) \
EnumMacro(PFNGLCLEARSTENCILPROC,glClearStencil) \
EnumMacro(PFNGLCLEARPROC,glClear) \
EnumMacro(PFNGLSTENCILFUNCPROC,glStencilFunc) \
EnumMacro(PFNGLSTENCILMASKPROC,glStencilMask) \
EnumMacro(PFNGLSTENCILOPPROC,glStencilOp) \
EnumMacro(PFNGLTEXIMAGE1DPROC,glTexImage1D) \
EnumMacro(PFNGLTEXIMAGE2DPROC,glTexImage2D) \
EnumMacro(PFNGLTEXPARAMETERFPROC,glTexParameterf) \
EnumMacro(PFNGLTEXPARAMETERFVPROC,glTexParameterfv) \
EnumMacro(PFNGLTEXPARAMETERIPROC,glTexParameteri) \
EnumMacro(PFNGLTEXPARAMETERIVPROC,glTexParameteriv) \
EnumMacro(PFNGLTEXSUBIMAGE1DPROC,glTexSubImage1D) \
EnumMacro(PFNGLTEXSUBIMAGE2DPROC,glTexSubImage2D) \
EnumMacro(PFNGLVIEWPORTPROC,glViewport)
// List all OpenGL entry points used by Flax
#define ENUM_GL_ENTRYPOINTS(EnumMacro) \
EnumMacro(PFNGLBINDSAMPLERPROC,glBindSampler) \
EnumMacro(PFNGLDELETESAMPLERSPROC,glDeleteSamplers) \
EnumMacro(PFNGLGENSAMPLERSPROC,glGenSamplers) \
EnumMacro(PFNGLSAMPLERPARAMETERIPROC,glSamplerParameteri) \
EnumMacro(PFNGLCLEARBUFFERFVPROC,glClearBufferfv) \
EnumMacro(PFNGLCLEARBUFFERIVPROC,glClearBufferiv) \
EnumMacro(PFNGLCLEARBUFFERUIVPROC,glClearBufferuiv) \
EnumMacro(PFNGLCLEARBUFFERFIPROC,glClearBufferfi) \
EnumMacro(PFNGLCOLORMASKIPROC,glColorMaski) \
EnumMacro(PFNGLDISABLEIPROC,glDisablei) \
EnumMacro(PFNGLENABLEIPROC,glEnablei) \
EnumMacro(PFNGLGETBOOLEANI_VPROC,glGetBooleani_v) \
EnumMacro(PFNGLGETINTEGERI_VPROC,glGetIntegeri_v) \
EnumMacro(PFNGLISENABLEDIPROC,glIsEnabledi) \
EnumMacro(PFNGLBLENDCOLORPROC,glBlendColor) \
EnumMacro(PFNGLBLENDEQUATIONPROC,glBlendEquation) \
EnumMacro(PFNGLDRAWRANGEELEMENTSPROC,glDrawRangeElements) \
EnumMacro(PFNGLTEXIMAGE3DPROC,glTexImage3D) \
EnumMacro(PFNGLTEXSUBIMAGE3DPROC,glTexSubImage3D) \
EnumMacro(PFNGLCOPYTEXSUBIMAGE3DPROC,glCopyTexSubImage3D) \
EnumMacro(PFNGLACTIVETEXTUREPROC,glActiveTexture) \
EnumMacro(PFNGLSAMPLECOVERAGEPROC,glSampleCoverage) \
EnumMacro(PFNGLCOMPRESSEDTEXIMAGE3DPROC,glCompressedTexImage3D) \
EnumMacro(PFNGLCOMPRESSEDTEXIMAGE2DPROC,glCompressedTexImage2D) \
EnumMacro(PFNGLCOMPRESSEDTEXIMAGE1DPROC,glCompressedTexImage1D) \
EnumMacro(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC,glCompressedTexSubImage3D) \
EnumMacro(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC,glCompressedTexSubImage2D) \
EnumMacro(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC,glCompressedTexSubImage1D) \
EnumMacro(PFNGLGETCOMPRESSEDTEXIMAGEPROC,glGetCompressedTexImage) \
EnumMacro(PFNGLBLENDFUNCSEPARATEPROC,glBlendFuncSeparate) \
EnumMacro(PFNGLMULTIDRAWARRAYSPROC,glMultiDrawArrays) \
EnumMacro(PFNGLMULTIDRAWELEMENTSPROC,glMultiDrawElements) \
EnumMacro(PFNGLPOINTPARAMETERFPROC,glPointParameterf) \
EnumMacro(PFNGLPOINTPARAMETERFVPROC,glPointParameterfv) \
EnumMacro(PFNGLPOINTPARAMETERIPROC,glPointParameteri) \
EnumMacro(PFNGLPOINTPARAMETERIVPROC,glPointParameteriv) \
EnumMacro(PFNGLGENQUERIESPROC,glGenQueries) \
EnumMacro(PFNGLDELETEQUERIESPROC,glDeleteQueries) \
EnumMacro(PFNGLISQUERYPROC,glIsQuery) \
EnumMacro(PFNGLBEGINQUERYPROC,glBeginQuery) \
EnumMacro(PFNGLENDQUERYPROC,glEndQuery) \
EnumMacro(PFNGLGETQUERYIVPROC,glGetQueryiv) \
EnumMacro(PFNGLGETQUERYOBJECTIVPROC,glGetQueryObjectiv) \
EnumMacro(PFNGLGETQUERYOBJECTUIVPROC,glGetQueryObjectuiv) \
EnumMacro(PFNGLBINDBUFFERPROC,glBindBuffer) \
EnumMacro(PFNGLBINDBUFFERBASEPROC,glBindBufferBase) \
EnumMacro(PFNGLDELETEBUFFERSPROC,glDeleteBuffers) \
EnumMacro(PFNGLGENBUFFERSPROC,glGenBuffers) \
EnumMacro(PFNGLISBUFFERPROC,glIsBuffer) \
EnumMacro(PFNGLBUFFERDATAPROC,glBufferData) \
EnumMacro(PFNGLBUFFERSUBDATAPROC,glBufferSubData) \
EnumMacro(PFNGLGETBUFFERSUBDATAPROC,glGetBufferSubData) \
EnumMacro(PFNGLMAPBUFFERPROC,glMapBuffer) \
EnumMacro(PFNGLUNMAPBUFFERPROC,glUnmapBuffer) \
EnumMacro(PFNGLGETBUFFERPARAMETERIVPROC,glGetBufferParameteriv) \
EnumMacro(PFNGLGETBUFFERPOINTERVPROC,glGetBufferPointerv) \
EnumMacro(PFNGLBLENDEQUATIONSEPARATEPROC,glBlendEquationSeparate) \
EnumMacro(PFNGLDRAWBUFFERSPROC,glDrawBuffers) \
EnumMacro(PFNGLSTENCILOPSEPARATEPROC,glStencilOpSeparate) \
EnumMacro(PFNGLSTENCILFUNCSEPARATEPROC,glStencilFuncSeparate) \
EnumMacro(PFNGLSTENCILMASKSEPARATEPROC,glStencilMaskSeparate) \
EnumMacro(PFNGLATTACHSHADERPROC,glAttachShader) \
EnumMacro(PFNGLBINDATTRIBLOCATIONPROC,glBindAttribLocation) \
EnumMacro(PFNGLBINDFRAGDATALOCATIONPROC,glBindFragDataLocation) \
EnumMacro(PFNGLCOMPILESHADERPROC,glCompileShader) \
EnumMacro(PFNGLCREATEPROGRAMPROC,glCreateProgram) \
EnumMacro(PFNGLCREATESHADERPROC,glCreateShader) \
EnumMacro(PFNGLDELETEPROGRAMPROC,glDeleteProgram) \
EnumMacro(PFNGLDELETESHADERPROC,glDeleteShader) \
EnumMacro(PFNGLDETACHSHADERPROC,glDetachShader) \
EnumMacro(PFNGLDISABLEVERTEXATTRIBARRAYPROC,glDisableVertexAttribArray) \
EnumMacro(PFNGLENABLEVERTEXATTRIBARRAYPROC,glEnableVertexAttribArray) \
EnumMacro(PFNGLGETACTIVEATTRIBPROC,glGetActiveAttrib) \
EnumMacro(PFNGLGETACTIVEUNIFORMPROC,glGetActiveUniform) \
EnumMacro(PFNGLGETATTACHEDSHADERSPROC,glGetAttachedShaders) \
EnumMacro(PFNGLGETATTRIBLOCATIONPROC,glGetAttribLocation) \
EnumMacro(PFNGLGETPROGRAMIVPROC,glGetProgramiv) \
EnumMacro(PFNGLGETPROGRAMINFOLOGPROC,glGetProgramInfoLog) \
EnumMacro(PFNGLGETSHADERIVPROC,glGetShaderiv) \
EnumMacro(PFNGLGETSHADERINFOLOGPROC,glGetShaderInfoLog) \
EnumMacro(PFNGLGETSHADERSOURCEPROC,glGetShaderSource) \
EnumMacro(PFNGLGETUNIFORMLOCATIONPROC,glGetUniformLocation) \
EnumMacro(PFNGLGETUNIFORMBLOCKINDEXPROC,glGetUniformBlockIndex) \
EnumMacro(PFNGLGETUNIFORMFVPROC,glGetUniformfv) \
EnumMacro(PFNGLGETUNIFORMIVPROC,glGetUniformiv) \
EnumMacro(PFNGLGETVERTEXATTRIBDVPROC,glGetVertexAttribdv) \
EnumMacro(PFNGLGETVERTEXATTRIBFVPROC,glGetVertexAttribfv) \
EnumMacro(PFNGLGETVERTEXATTRIBIVPROC,glGetVertexAttribiv) \
EnumMacro(PFNGLGETVERTEXATTRIBPOINTERVPROC,glGetVertexAttribPointerv) \
EnumMacro(PFNGLISPROGRAMPROC,glIsProgram) \
EnumMacro(PFNGLISSHADERPROC,glIsShader) \
EnumMacro(PFNGLLINKPROGRAMPROC,glLinkProgram) \
EnumMacro(PFNGLSHADERSOURCEPROC,glShaderSource) \
EnumMacro(PFNGLUSEPROGRAMPROC,glUseProgram) \
EnumMacro(PFNGLUNIFORM1FPROC,glUniform1f) \
EnumMacro(PFNGLUNIFORM2FPROC,glUniform2f) \
EnumMacro(PFNGLUNIFORM3FPROC,glUniform3f) \
EnumMacro(PFNGLUNIFORM4FPROC,glUniform4f) \
EnumMacro(PFNGLUNIFORM1IPROC,glUniform1i) \
EnumMacro(PFNGLUNIFORM2IPROC,glUniform2i) \
EnumMacro(PFNGLUNIFORM3IPROC,glUniform3i) \
EnumMacro(PFNGLUNIFORM4IPROC,glUniform4i) \
EnumMacro(PFNGLUNIFORM1FVPROC,glUniform1fv) \
EnumMacro(PFNGLUNIFORM2FVPROC,glUniform2fv) \
EnumMacro(PFNGLUNIFORM3FVPROC,glUniform3fv) \
EnumMacro(PFNGLUNIFORM4FVPROC,glUniform4fv) \
EnumMacro(PFNGLUNIFORM1IVPROC,glUniform1iv) \
EnumMacro(PFNGLUNIFORM2IVPROC,glUniform2iv) \
EnumMacro(PFNGLUNIFORM3IVPROC,glUniform3iv) \
EnumMacro(PFNGLUNIFORM4IVPROC,glUniform4iv) \
EnumMacro(PFNGLUNIFORM1UIVPROC,glUniform1uiv) \
EnumMacro(PFNGLUNIFORM2UIVPROC,glUniform2uiv) \
EnumMacro(PFNGLUNIFORM3UIVPROC,glUniform3uiv) \
EnumMacro(PFNGLUNIFORM4UIVPROC,glUniform4uiv) \
EnumMacro(PFNGLUNIFORMBLOCKBINDINGPROC,glUniformBlockBinding) \
EnumMacro(PFNGLUNIFORMMATRIX2FVPROC,glUniformMatrix2fv) \
EnumMacro(PFNGLUNIFORMMATRIX3FVPROC,glUniformMatrix3fv) \
EnumMacro(PFNGLUNIFORMMATRIX4FVPROC,glUniformMatrix4fv) \
EnumMacro(PFNGLVALIDATEPROGRAMPROC,glValidateProgram) \
EnumMacro(PFNGLVERTEXATTRIB1DPROC,glVertexAttrib1d) \
EnumMacro(PFNGLVERTEXATTRIB1DVPROC,glVertexAttrib1dv) \
EnumMacro(PFNGLVERTEXATTRIB1FPROC,glVertexAttrib1f) \
EnumMacro(PFNGLVERTEXATTRIB1FVPROC,glVertexAttrib1fv) \
EnumMacro(PFNGLVERTEXATTRIB1SPROC,glVertexAttrib1s) \
EnumMacro(PFNGLVERTEXATTRIB1SVPROC,glVertexAttrib1sv) \
EnumMacro(PFNGLVERTEXATTRIB2DPROC,glVertexAttrib2d) \
EnumMacro(PFNGLVERTEXATTRIB2DVPROC,glVertexAttrib2dv) \
EnumMacro(PFNGLVERTEXATTRIB2FPROC,glVertexAttrib2f) \
EnumMacro(PFNGLVERTEXATTRIB2FVPROC,glVertexAttrib2fv) \
EnumMacro(PFNGLVERTEXATTRIB2SPROC,glVertexAttrib2s) \
EnumMacro(PFNGLVERTEXATTRIB2SVPROC,glVertexAttrib2sv) \
EnumMacro(PFNGLVERTEXATTRIB3DPROC,glVertexAttrib3d) \
EnumMacro(PFNGLVERTEXATTRIB3DVPROC,glVertexAttrib3dv) \
EnumMacro(PFNGLVERTEXATTRIB3FPROC,glVertexAttrib3f) \
EnumMacro(PFNGLVERTEXATTRIB3FVPROC,glVertexAttrib3fv) \
EnumMacro(PFNGLVERTEXATTRIB3SPROC,glVertexAttrib3s) \
EnumMacro(PFNGLVERTEXATTRIB3SVPROC,glVertexAttrib3sv) \
EnumMacro(PFNGLVERTEXATTRIB4NBVPROC,glVertexAttrib4Nbv) \
EnumMacro(PFNGLVERTEXATTRIB4NIVPROC,glVertexAttrib4Niv) \
EnumMacro(PFNGLVERTEXATTRIB4NSVPROC,glVertexAttrib4Nsv) \
EnumMacro(PFNGLVERTEXATTRIB4NUBPROC,glVertexAttrib4Nub) \
EnumMacro(PFNGLVERTEXATTRIB4NUBVPROC,glVertexAttrib4Nubv) \
EnumMacro(PFNGLVERTEXATTRIB4NUIVPROC,glVertexAttrib4Nuiv) \
EnumMacro(PFNGLVERTEXATTRIB4NUSVPROC,glVertexAttrib4Nusv) \
EnumMacro(PFNGLVERTEXATTRIB4BVPROC,glVertexAttrib4bv) \
EnumMacro(PFNGLVERTEXATTRIB4DPROC,glVertexAttrib4d) \
EnumMacro(PFNGLVERTEXATTRIB4DVPROC,glVertexAttrib4dv) \
EnumMacro(PFNGLVERTEXATTRIB4FPROC,glVertexAttrib4f) \
EnumMacro(PFNGLVERTEXATTRIB4FVPROC,glVertexAttrib4fv) \
EnumMacro(PFNGLVERTEXATTRIB4IVPROC,glVertexAttrib4iv) \
EnumMacro(PFNGLVERTEXATTRIB4SPROC,glVertexAttrib4s) \
EnumMacro(PFNGLVERTEXATTRIB4SVPROC,glVertexAttrib4sv) \
EnumMacro(PFNGLVERTEXATTRIB4UBVPROC,glVertexAttrib4ubv) \
EnumMacro(PFNGLVERTEXATTRIB4UIVPROC,glVertexAttrib4uiv) \
EnumMacro(PFNGLVERTEXATTRIB4USVPROC,glVertexAttrib4usv) \
EnumMacro(PFNGLVERTEXATTRIBI4IVPROC,glVertexAttribI4iv) \
EnumMacro(PFNGLVERTEXATTRIBI4UIVPROC,glVertexAttribI4uiv) \
EnumMacro(PFNGLVERTEXATTRIBI4SVPROC,glVertexAttribI4sv) \
EnumMacro(PFNGLVERTEXATTRIBI4USVPROC,glVertexAttribI4usv) \
EnumMacro(PFNGLVERTEXATTRIBI4BVPROC,glVertexAttribI4bv) \
EnumMacro(PFNGLVERTEXATTRIBI4UBVPROC,glVertexAttribI4ubv) \
EnumMacro(PFNGLVERTEXATTRIBPOINTERPROC,glVertexAttribPointer) \
EnumMacro(PFNGLVERTEXATTRIBIPOINTERPROC,glVertexAttribIPointer) \
EnumMacro(PFNGLUNIFORMMATRIX2X3FVPROC,glUniformMatrix2x3fv) \
EnumMacro(PFNGLUNIFORMMATRIX3X2FVPROC,glUniformMatrix3x2fv) \
EnumMacro(PFNGLUNIFORMMATRIX2X4FVPROC,glUniformMatrix2x4fv) \
EnumMacro(PFNGLUNIFORMMATRIX4X2FVPROC,glUniformMatrix4x2fv) \
EnumMacro(PFNGLUNIFORMMATRIX3X4FVPROC,glUniformMatrix3x4fv) \
EnumMacro(PFNGLUNIFORMMATRIX4X3FVPROC,glUniformMatrix4x3fv) \
EnumMacro(PFNGLISRENDERBUFFERPROC,glIsRenderbuffer) \
EnumMacro(PFNGLBINDRENDERBUFFERPROC,glBindRenderbuffer) \
EnumMacro(PFNGLDELETERENDERBUFFERSPROC,glDeleteRenderbuffers) \
EnumMacro(PFNGLGENRENDERBUFFERSPROC,glGenRenderbuffers) \
EnumMacro(PFNGLRENDERBUFFERSTORAGEPROC,glRenderbufferStorage) \
EnumMacro(PFNGLGETRENDERBUFFERPARAMETERIVPROC,glGetRenderbufferParameteriv) \
EnumMacro(PFNGLISFRAMEBUFFERPROC,glIsFramebuffer) \
EnumMacro(PFNGLBINDFRAMEBUFFERPROC,glBindFramebuffer) \
EnumMacro(PFNGLDELETEFRAMEBUFFERSPROC,glDeleteFramebuffers) \
EnumMacro(PFNGLGENFRAMEBUFFERSPROC,glGenFramebuffers) \
EnumMacro(PFNGLCHECKFRAMEBUFFERSTATUSPROC,glCheckFramebufferStatus) \
EnumMacro(PFNGLFRAMEBUFFERTEXTURE1DPROC,glFramebufferTexture1D) \
EnumMacro(PFNGLFRAMEBUFFERTEXTURE2DPROC,glFramebufferTexture2D) \
EnumMacro(PFNGLFRAMEBUFFERTEXTURE3DPROC,glFramebufferTexture3D) \
EnumMacro(PFNGLFRAMEBUFFERTEXTUREPROC,glFramebufferTexture) \
EnumMacro(PFNGLFRAMEBUFFERRENDERBUFFERPROC,glFramebufferRenderbuffer) \
EnumMacro(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC,glGetFramebufferAttachmentParameteriv) \
EnumMacro(PFNGLGENERATEMIPMAPPROC,glGenerateMipmap) \
EnumMacro(PFNGLBLITFRAMEBUFFERPROC,glBlitFramebuffer) \
EnumMacro(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC,glRenderbufferStorageMultisample) \
EnumMacro(PFNGLFRAMEBUFFERTEXTURELAYERPROC,glFramebufferTextureLayer) \
EnumMacro(PFNGLMAPBUFFERRANGEPROC,glMapBufferRange) \
EnumMacro(PFNGLFLUSHMAPPEDBUFFERRANGEPROC,glFlushMappedBufferRange) \
EnumMacro(PFNGLVERTEXATTRIBDIVISORPROC,glVertexAttribDivisor) \
EnumMacro(PFNGLDRAWARRAYSINSTANCEDPROC,glDrawArraysInstanced) \
EnumMacro(PFNGLDRAWELEMENTSINSTANCEDPROC,glDrawElementsInstanced) \
EnumMacro(PFNGLGETSTRINGIPROC,glGetStringi) \
EnumMacro(PFNGLGENVERTEXARRAYSPROC,glGenVertexArrays) \
EnumMacro(PFNGLDELETEVERTEXARRAYSPROC,glDeleteVertexArrays) \
EnumMacro(PFNGLBINDVERTEXARRAYPROC,glBindVertexArray) \
EnumMacro(PFNGLCOPYBUFFERSUBDATAPROC,glCopyBufferSubData) \
EnumMacro(PFNGLTEXBUFFERPROC,glTexBuffer) \
EnumMacro(PFNGLTEXIMAGE2DMULTISAMPLEPROC,glTexImage2DMultisample) \
EnumMacro(PFNGLQUERYCOUNTERPROC, glQueryCounter)\
EnumMacro(PFNGLISSYNCPROC, glIsSync)\
EnumMacro(PFNGLDELETESYNCPROC, glDeleteSync)\
EnumMacro(PFNGLGETQUERYOBJECTUI64VPROC, glGetQueryObjectui64v)\
EnumMacro(PFNGLFENCESYNCPROC, glFenceSync)\
EnumMacro(PFNGLGETSYNCIVPROC, glGetSynciv)\
EnumMacro(PFNGLCLIENTWAITSYNCPROC, glClientWaitSync)\
EnumMacro(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange)
#define ENUM_GL_ENTRYPOINTS_OPTIONAL(EnumMacro) \
EnumMacro(PFNGLCLIPCONTROLPROC,glClipControl) \
EnumMacro(PFNGLDEBUGMESSAGECALLBACKARBPROC,glDebugMessageCallbackARB) \
EnumMacro(PFNGLDEBUGMESSAGECONTROLARBPROC,glDebugMessageControlARB) \
EnumMacro(PFNGLDEBUGMESSAGECALLBACKAMDPROC,glDebugMessageCallbackAMD) \
EnumMacro(PFNGLDEBUGMESSAGEENABLEAMDPROC,glDebugMessageEnableAMD) \
EnumMacro(PFNGLGETACTIVEUNIFORMSIVPROC,glGetActiveUniformsiv) \
EnumMacro(PFNGLGETVERTEXATTRIBIUIVPROC,glGetVertexAttribIuiv) \
EnumMacro(PFNGLGETACTIVEUNIFORMNAMEPROC,glGetActiveUniformName) \
EnumMacro(PFNGLGETUNIFORMUIVPROC,glGetUniformuiv) \
EnumMacro(PFNGLGETACTIVEUNIFORMBLOCKIVPROC,glGetActiveUniformBlockiv) \
EnumMacro(PFNGLGETBUFFERPARAMETERI64VPROC,glGetBufferParameteri64v) \
EnumMacro(PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC,glGetActiveUniformBlockName) \
EnumMacro(PFNGLGETSAMPLERPARAMETERFVPROC,glGetSamplerParameterfv) \
EnumMacro(PFNGLGETSAMPLERPARAMETERIVPROC,glGetSamplerParameteriv) \
EnumMacro(PFNGLDISPATCHCOMPUTEPROC, glDispatchCompute) \
EnumMacro(PFNGLDISPATCHCOMPUTEINDIRECTPROC, glDispatchComputeIndirect) \
EnumMacro(PFNGLBINDIMAGETEXTUREPROC, glBindImageTexture) \
EnumMacro(PFNGLMEMORYBARRIERPROC, glMemoryBarrier) \
EnumMacro(PFNGLBLENDEQUATIONIPROC, glBlendEquationi) \
EnumMacro(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei) \
EnumMacro(PFNGLBLENDFUNCIPROC, glBlendFunci) \
EnumMacro(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei)\
EnumMacro(PFNGLBLENDEQUATIONSEPARATEIARBPROC,glBlendEquationSeparateiARB)\
EnumMacro(PFNGLBLENDEQUATIONIARBPROC,glBlendEquationiARB)\
EnumMacro(PFNGLBLENDFUNCSEPARATEIARBPROC,glBlendFuncSeparateiARB)\
EnumMacro(PFNGLBLENDFUNCIARBPROC,glBlendFunciARB)\
EnumMacro(PFNGLCLEARBUFFERDATAPROC, glClearBufferData)\
EnumMacro(PFNGLCLEARBUFFERSUBDATAPROC, glClearBufferSubData)\
EnumMacro(PFNGLPUSHDEBUGGROUPPROC, glPushDebugGroup)\
EnumMacro(PFNGLPOPDEBUGGROUPPROC, glPopDebugGroup)\
EnumMacro(PFNGLOBJECTLABELPROC, glObjectLabel)\
EnumMacro(PFNGLOBJECTLABELPROC, glObjectPtrLabel)\
EnumMacro(PFNGLPATCHPARAMETERIPROC, glPatchParameteri)\
EnumMacro(PFNGLBINDVERTEXBUFFERPROC, glBindVertexBuffer)\
EnumMacro(PFNGLVERTEXATTRIBFORMATPROC, glVertexAttribFormat)\
EnumMacro(PFNGLVERTEXATTRIBIFORMATPROC, glVertexAttribIFormat)\
EnumMacro(PFNGLVERTEXATTRIBBINDINGPROC, glVertexAttribBinding)\
EnumMacro(PFNGLVERTEXBINDINGDIVISORPROC, glVertexBindingDivisor)\
EnumMacro(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData)\
EnumMacro(PFNGLTEXSTORAGE1DPROC, glTexStorage1D)\
EnumMacro(PFNGLTEXSTORAGE2DPROC, glTexStorage2D)\
EnumMacro(PFNGLTEXSTORAGE3DPROC, glTexStorage3D)\
EnumMacro(PFNGLBUFFERSTORAGEPROC, glBufferStorage)\
EnumMacro(PFNGLTEXTUREVIEWPROC, glTextureView)\
EnumMacro(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, glTexStorage2DMultisample)\
EnumMacro(PFNGLDRAWELEMENTSINDIRECTPROC, glDrawElementsIndirect)\
EnumMacro(PFNGLDRAWARRAYSINDIRECTPROC, glDrawArraysIndirect)\
EnumMacro(PFNGLDEPTHBOUNDSEXTPROC, glDepthBoundsEXT)\
EnumMacro(PFNGLGETTEXTUREHANDLENVPROC, glGetTextureHandleARB)\
EnumMacro(PFNGLGETTEXTURESAMPLERHANDLENVPROC, glGetTextureSamplerHandleARB)\
EnumMacro(PFNGLMAKETEXTUREHANDLERESIDENTNVPROC, glMakeTextureHandleResidentARB)\
EnumMacro(PFNGLUNIFORMHANDLEUI64NVPROC, glUniformHandleui64ARB)\
EnumMacro(PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC, glMakeTextureHandleNonResidentARB)\
EnumMacro(PFNGLPUSHDEBUGGROUPPROC, glPushDebugGroupKHR)\
EnumMacro(PFNGLPOPDEBUGGROUPPROC, glPopDebugGroupKHR)\
EnumMacro(PFNGLOBJECTLABELPROC, glObjectLabelKHR)\
EnumMacro(PFNGLOBJECTLABELPROC, glObjectPtrLabelKHR)\
EnumMacro(PFNGLDEBUGMESSAGECALLBACKARBPROC,glDebugMessageCallbackKHR) \
EnumMacro(PFNGLDEBUGMESSAGECONTROLARBPROC,glDebugMessageControlKHR) \
EnumMacro(PFNGLPATCHPARAMETERIPROC, glPatchParameteriEXT)\
EnumMacro(PFNGLTEXTUREVIEWPROC, glTextureViewEXT)\
EnumMacro(PFNGLBLENDEQUATIONIPROC, glBlendEquationiEXT) \
EnumMacro(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparateiEXT) \
EnumMacro(PFNGLBLENDFUNCIPROC, glBlendFunciEXT) \
EnumMacro(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparateiEXT)\
EnumMacro(PFNGLCOLORMASKIPROC,glColorMaskiEXT) \
EnumMacro(PFNGLDISABLEIPROC,glDisableiEXT) \
EnumMacro(PFNGLENABLEIPROC,glEnableiEXT) \
EnumMacro(PFNGLFRAMEBUFFERTEXTUREPROC,glFramebufferTextureEXT) \
EnumMacro(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubDataEXT) \
EnumMacro(PFNGLTEXBUFFERPROC,glTexBufferEXT) \
EnumMacro(PFNGLDEPTHRANGEFPROC,glDepthRangef) \
EnumMacro(PFNGLCLEARDEPTHFPROC,glClearDepthf) \
EnumMacro(PFNGLGETSHADERPRECISIONFORMATPROC, glGetShaderPrecisionFormat) \
EnumMacro(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri) \
EnumMacro(PFNGLUSEPROGRAMSTAGESPROC, glUseProgramStages) \
EnumMacro(PFNGLBINDPROGRAMPIPELINEPROC, glBindProgramPipeline) \
EnumMacro(PFNGLDELETEPROGRAMPIPELINESPROC, glDeleteProgramPipelines) \
EnumMacro(PFNGLGENPROGRAMPIPELINESPROC, glGenProgramPipelines) \
EnumMacro(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i) \
EnumMacro(PFNGLPROGRAMUNIFORM4IVPROC, glProgramUniform4iv) \
EnumMacro(PFNGLPROGRAMUNIFORM4FVPROC, glProgramUniform4fv) \
EnumMacro(PFNGLPROGRAMUNIFORM4UIVPROC, glProgramUniform4uiv) \
EnumMacro(PFNGLGETPROGRAMPIPELINEIVPROC, glGetProgramPipelineiv) \
EnumMacro(PFNGLVALIDATEPROGRAMPIPELINEPROC, glValidateProgramPipeline) \
EnumMacro(PFNGLGETPROGRAMPIPELINEINFOLOGPROC, glGetProgramPipelineInfoLog) \
EnumMacro(PFNGLISPROGRAMPIPELINEPROC, glIsProgramPipeline) \
EnumMacro(PFNGLGETPROGRAMBINARYPROC, glGetProgramBinary) \
EnumMacro(PFNGLPROGRAMBINARYPROC, glProgramBinary)
// List of all OpenGL entry points
#define ENUM_GL_ENTRYPOINTS_ALL(EnumMacro) \
ENUM_GL_ENTRYPOINTS_DLL(EnumMacro) \
ENUM_GL_ENTRYPOINTS(EnumMacro) \
ENUM_GL_ENTRYPOINTS_OPTIONAL(EnumMacro)
// Declare all GL functions
#define DECLARE_GL_ENTRYPOINTS(Type,Func) extern Type Func;
ENUM_GL_ENTRYPOINTS_ALL(DECLARE_GL_ENTRYPOINTS);
inline void* GetGLFuncAddress(const char* name)
{
// Reference: https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions
void* p = (void*)wglGetProcAddress(name);
if (p == 0 || (p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) || (p == (void*)-1))
{
HMODULE module = LoadLibraryA("opengl32.dll");
p = (void*)GetProcAddress(module, name);
}
return p;
}
#endif
#endif

View File

@@ -1,75 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "RenderToolsOGL.h"
#if GRAPHICS_API_OPENGL
#include "Engine/Core/Types/StringBuilder.h"
#include "Engine/Core/Log.h"
const Char* RenderToolsOGL::GetErrorString(GLenum errorCode)
{
switch (errorCode)
{
#define OGL_ERROR(name) case name: return TEXT(#name)
OGL_ERROR(GL_INVALID_ENUM);
OGL_ERROR(GL_INVALID_VALUE);
OGL_ERROR(GL_INVALID_OPERATION);
OGL_ERROR(GL_OUT_OF_MEMORY);
OGL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
#undef OGL_ERROR
}
return nullptr;
}
void RenderToolsOGL::CheckError(const char* file, uint32 line)
{
GLenum errorCode = glGetError();
if (errorCode != GL_NO_ERROR)
{
StringBuilder sb;
sb.AppendFormat(TEXT("OpenGL error at {0}:{1}"), file, line);
const Char* errorString = GetErrorString(errorCode);
if (errorString)
{
sb.AppendLine().Append(errorString);
}
#if PLATFORM_WINDOWS
{
HGLRC context = wglGetCurrentContext();
if (!context)
{
sb.AppendLine().Append(TEXT("No OpenGL context set!"));
}
}
#endif
/*
do
{
const Char* errorString = GetErrorString(errorCode);
if (errorString)
{
sb.AppendLine().Append(errorString);
}
errorCode = glGetError();
} while (errorCode != GL_NO_ERROR);
*/
LOG_STR(Fatal, sb.ToString());
}
}
void RenderToolsOGL::ErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam)
{
if (type != GL_DEBUG_TYPE_PERFORMANCE && type != GL_DEBUG_TYPE_OTHER)
{
LOG(Fatal, "OpenGL error: {0}", message);
}
}
#endif

View File

@@ -1,53 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/BaseTypes.h"
#include "Engine/Graphics/RenderTools.h"
#include "Engine/Graphics/Enums.h"
#if GRAPHICS_API_OPENGL
#include "Engine/Graphics/Textures/GPUTextureDescription.h"
#include "IncludeOpenGLHeaders.h"
#if GPU_ENABLE_ASSERTION
// OpenGL results validation
#define VALIDATE_OPENGL_RESULT() RenderToolsOGL::CheckError(__FILE__, __LINE__)
#else
#define VALIDATE_OPENGL_RESULT(x)
#endif
/// <summary>
/// Set of utilities for rendering on OpenGL platform.
/// </summary>
namespace RenderToolsOGL
{
inline GLenum ComparisonFuncToOGL(ComparisonFunc func)
{
switch (func)
{
case ComparisonFunc::Never: return GL_NEVER;
case ComparisonFunc::Less: return GL_LESS;
case ComparisonFunc::Equal: return GL_EQUAL;
case ComparisonFunc::LessEqual: return GL_LEQUAL;
case ComparisonFunc::Grather: return GL_GREATER;
case ComparisonFunc::NotEqual: return GL_NOTEQUAL;
case ComparisonFunc::GratherEqual: return GL_GEQUAL;
case ComparisonFunc::Always: return GL_ALWAYS;
default: CRASH; return GL_ALWAYS;
}
}
const Char* GetErrorString(GLenum errorCode);
void CheckError(const char* file, uint32 line);
void ErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
};
#endif

View File

@@ -1,167 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "VAOCache.h"
#if GRAPHICS_API_OPENGL
#include "TextureOGL.h"
#include "BufferOGL.h"
#include "RenderToolsOGL.h"
#include "Shaders/GPUShaderProgramOGL.h"
VAOCache::VAOCache()
: Table(2048)
{
}
VAOCache::~VAOCache()
{
Dispose();
}
GLuint VAOCache::GetVAO(GPUShaderProgramVSOGL* vs, BufferOGL* indexBuffer, uint32 streamsCount, StreamData streams[])
{
Key key(vs, indexBuffer, streamsCount, streams);
GLuint vao;
if (!Table.TryGet(key, vao))
{
// Create new VAO
glGenVertexArrays(1, &vao);
VALIDATE_OPENGL_RESULT();
// Bind VAO
glBindVertexArray(vao);
VALIDATE_OPENGL_RESULT();
// Initialize VAO
for (int32 i = 0; i < vs->Layout.Count(); i++)
{
auto& item = vs->Layout[i];
auto bufferSlot = item.BufferSlot;
if (bufferSlot >= streamsCount)
{
LOG(Error, "Incorrect input buffer slot");
continue;
}
auto& stream = streams[bufferSlot];
ASSERT(stream.Buffer != nullptr && stream.Buffer->BufferId != 0);
glBindBuffer(GL_ARRAY_BUFFER, stream.Buffer->BufferId);
VALIDATE_OPENGL_RESULT();
GLvoid* DataStartOffset = reinterpret_cast<GLvoid*>(static_cast<size_t>(stream.Offset + item.RelativeOffset));
if (item.IsInteger)
glVertexAttribIPointer(i, item.TypeCount, item.GlType, stream.Stride, DataStartOffset);
else
glVertexAttribPointer(i, item.TypeCount, item.GlType, item.Normalized, stream.Stride, DataStartOffset);
VALIDATE_OPENGL_RESULT();
glVertexAttribDivisor(i, item.InstanceDataStepRate);
VALIDATE_OPENGL_RESULT();
glEnableVertexAttribArray(i);
VALIDATE_OPENGL_RESULT();
}
if (indexBuffer)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer->BufferId);
}
// Register in cache
Table.Add(key, vao);
}
return vao;
}
void VAOCache::OnObjectRelease(GPUShaderProgramVSOGL* obj)
{
for (auto i = Table.Begin(); i.IsNotEnd(); ++i)
{
if (i->Key.HasReference(obj))
{
GLuint fbo = i->Value;
glDeleteVertexArrays(1, &fbo);
Table.Remove(i);
}
}
}
void VAOCache::OnObjectRelease(BufferOGL* obj)
{
for (auto i = Table.Begin(); i.IsNotEnd(); ++i)
{
if (i->Key.HasReference(obj))
{
GLuint fbo = i->Value;
glDeleteVertexArrays(1, &fbo);
Table.Remove(i);
}
}
}
void VAOCache::Dispose()
{
for (auto i = Table.Begin(); i.IsNotEnd(); ++i)
{
GLuint fbo = i->Value;
glDeleteVertexArrays(1, &fbo);
}
Table.Clear();
}
VAOCache::Key::Key(GPUShaderProgramVSOGL* vs, BufferOGL* indexBuffer, uint32 streamsCount, StreamData streams[])
{
VS = vs;
IndexBuffer = indexBuffer;
StreamsCount = streamsCount;
Hash = streamsCount * 371;
HashCombinePointer(Hash, vs);
HashCombinePointer(Hash, indexBuffer);
for (int32 i = 0; i < streamsCount; i++)
{
Streams[i] = streams[i];
HashCombinePointer(Hash, streams[i].Buffer);
HashCombine(Hash, streams[i].Offset);
HashCombine(Hash, streams[i].Stride);
}
}
bool VAOCache::Key::HasReference(GPUShaderProgramVSOGL* obj)
{
return obj == VS;
}
bool VAOCache::Key::HasReference(BufferOGL* obj)
{
for (int32 i = 0; i < ARRAY_COUNT(Streams); i++)
{
if (Streams[i].Buffer == obj)
return true;
}
return IndexBuffer == obj;
}
bool VAOCache::Key::operator==(const Key & other) const
{
if (Hash != 0 && other.Hash != 0 && Hash != other.Hash)
return false;
if (StreamsCount != other.StreamsCount || IndexBuffer != other.IndexBuffer)
return false;
for (int32 rt = 0; rt < StreamsCount; rt++)
{
if (Streams[rt] != other.Streams[rt])
return false;
}
return true;
}
#endif

View File

@@ -1,92 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Common.h"
#include "Config.h"
#if GRAPHICS_API_OPENGL
#include "IncludeOpenGLHeaders.h"
class GPUTextureViewOGL;
class PipelineStateOGL;
class GPUShaderProgramVSOGL;
class TextureOGL;
class BufferOGL;
class VAOCache
{
public:
struct StreamData
{
BufferOGL* Buffer;
uint32 Stride;
uint32 Offset;
StreamData()
: Buffer(nullptr)
, Stride(0)
, Offset(0)
{
}
bool operator== (const StreamData& other) const
{
return Buffer == other.Buffer && Stride == other.Stride && Offset == other.Offset;
}
bool operator!= (const StreamData& other) const
{
return !operator==(other);
}
};
private:
struct Key
{
uint32 Hash;
GPUShaderProgramVSOGL* VS;
BufferOGL* IndexBuffer;
uint32 StreamsCount;
StreamData Streams[GPU_MAX_VB_BINDED];
Key()
: Hash(0)
, StreamsCount(0)
, VS(nullptr)
, IndexBuffer(nullptr)
{
}
Key(GPUShaderProgramVSOGL* vs, BufferOGL* indexBuffer, uint32 streamsCount, StreamData streams[]);
bool HasReference(GPUShaderProgramVSOGL* obj);
bool HasReference(BufferOGL* obj);
bool operator== (const Key& other) const;
static uint32 HashFunction(const Key& key)
{
return key.Hash;
}
};
Dictionary<Key, GLuint> Table;
public:
VAOCache();
~VAOCache();
public:
GLuint GetVAO(GPUShaderProgramVSOGL* vs, BufferOGL* indexBuffer, uint32 streamsCount, StreamData streams[]);
void OnObjectRelease(GPUShaderProgramVSOGL* obj);
void OnObjectRelease(BufferOGL* obj);
void Dispose();
};
#endif

View File

@@ -1,126 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "Win32ContextOGL.h"
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
#include "Engine/Platform/Platform.h"
#include "Engine/Core/Log.h"
#include "../AdapterOGL.h"
#include "../GPUDeviceOGL.h"
PFNWGLCREATECONTEXTATTRIBSARBPROC Win32ContextOGL::wglCreateContextAttribsARB = NULL;
HGLRC Win32ContextOGL::OpenGLContext = 0;
HDC Win32ContextOGL::OpenGLContextWin = 0;
Array<Win32GPUSwapChainOGL*, FixedAllocation<32>> Win32ContextOGL::ChildWindows;
// A dummy window procedure (for WinAPI).
static LRESULT CALLBACK PlatformDummyGLWndproc(HWND hWnd, uint32 Message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, Message, wParam, lParam);
}
// Initializes a pixel format descriptor for the given window handle.
void Win32ContextOGL::PlatformInitPixelFormatForDevice(HDC context)
{
// Pixel format descriptor for the context
PIXELFORMATDESCRIPTOR PixelFormatDesc;
Platform::MemoryClear(&PixelFormatDesc, sizeof(PixelFormatDesc));
PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
PixelFormatDesc.nVersion = 1;
PixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
PixelFormatDesc.cColorBits = 32;
PixelFormatDesc.cDepthBits = 0;
PixelFormatDesc.cStencilBits = 0;
PixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
// Set the pixel format
int32 PixelFormat = ChoosePixelFormat(context, &PixelFormatDesc);
if (!PixelFormat || !SetPixelFormat(context, PixelFormat, &PixelFormatDesc))
{
LOG(Error, "Failed to set pixel format for device context.");
}
}
// Creates a dummy window used to construct OpenGL contexts.
void Win32ContextOGL::CreateDummyGLWindow(Data* context)
{
const Char* DummyWindowClassName = TEXT("DummyGLWindow");
// Register a dummy window class
{
WNDCLASS wc;
Platform::MemoryClear(&wc, sizeof(wc));
wc.style = CS_OWNDC;
wc.lpfnWndProc = PlatformDummyGLWndproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_MENUTEXT);
wc.lpszMenuName = NULL;
wc.lpszClassName = DummyWindowClassName;
ATOM ClassAtom = ::RegisterClass(&wc);
ASSERT(ClassAtom);
}
// Create a dummy window
context->WindowHandle = CreateWindowEx(
WS_EX_WINDOWEDGE,
DummyWindowClassName,
NULL,
WS_POPUP,
0, 0, 1, 1,
NULL, NULL, NULL, NULL);
ASSERT(context->WindowHandle);
context->bReleaseWindowOnDestroy = true;
// Get the device context.
context->DeviceContext = GetDC(context->WindowHandle);
ASSERT(context->DeviceContext);
PlatformInitPixelFormatForDevice(context->DeviceContext);
}
// Create a core profile OpenGL context.
void Win32ContextOGL::PlatformCreateOpenGLContextCore(Data* result, int majorVersion, int minorVersion, HGLRC parentContext)
{
ASSERT(result);
result->SyncInterval = -1; // invalid value to enforce setup on first buffer swap
result->ViewportFramebuffer = 0;
PlatformCreateOpenGLContextCore(&result->OpenGLContext, result->DeviceContext, majorVersion, minorVersion, parentContext);
}
void Win32ContextOGL::PlatformCreateOpenGLContextCore(HGLRC* result, HDC deviceContext, int majorVersion, int minorVersion, HGLRC parentContext)
{
ASSERT(wglCreateContextAttribsARB);
ASSERT(result && deviceContext);
int debugFlag = 0;
#if GPU_OGL_USE_DEBUG_LAYER
debugFlag = WGL_CONTEXT_DEBUG_BIT_ARB;
#endif
int attributes[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, majorVersion,
WGL_CONTEXT_MINOR_VERSION_ARB, minorVersion,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | debugFlag,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
*result = wglCreateContextAttribsARB(deviceContext, parentContext, attributes);
}
void Win32ContextOGL::PlatformCreateOpenGLContextCore(HGLRC* result, HDC deviceContext, HGLRC parentContext)
{
auto adapter = (AdapterOGL*)GPUDevice::Instance->GetAdapter();
PlatformCreateOpenGLContextCore(result, deviceContext, adapter->VersionMajor, adapter->VersionMinor, parentContext);
}
#endif

View File

@@ -1,80 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "../IncludeOpenGLHeaders.h"
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
#include "Engine/Core/Common.h"
class Win32GPUSwapChainOGL;
class Win32ContextOGL
{
public:
// Platform specific OpenGL context.
struct Data
{
HWND WindowHandle;
HDC DeviceContext;
HGLRC OpenGLContext;
bool bReleaseWindowOnDestroy;
int32 SyncInterval;
GLuint ViewportFramebuffer;
GLuint VertexArrayObject; // one has to be generated and set for each context (OpenGL 3.2 Core requirements)
GLuint BackBufferResource; // TODO: use it
GLenum BackBufferTarget; // TODO: use it
~Data()
{
if (OpenGLContext)
{
ContextMakeCurrent(NULL, NULL);
wglDeleteContext(OpenGLContext);
}
ReleaseDC(WindowHandle, DeviceContext);
ASSERT(bReleaseWindowOnDestroy);
DestroyWindow(WindowHandle);
}
};
static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
public:
static HGLRC OpenGLContext;
static HDC OpenGLContextWin;
static Array<Win32GPUSwapChainOGL*, FixedAllocation<32>> ChildWindows;
public:
static bool IsReady()
{
return OpenGLContext != 0;
}
static void ContextMakeCurrent(HDC dc, HGLRC rc)
{
BOOL result = wglMakeCurrent(dc, rc);
if (!result)
{
result = wglMakeCurrent(nullptr, nullptr);
}
ASSERT(result);
}
static HGLRC GetCurrentContext()
{
return wglGetCurrentContext();
}
static void PlatformInitPixelFormatForDevice(HDC context);
static void CreateDummyGLWindow(Data* context);
static void PlatformCreateOpenGLContextCore(Data* result, int majorVersion, int minorVersion, HGLRC parentContext);
static void PlatformCreateOpenGLContextCore(HGLRC* result, HDC deviceContext, int majorVersion, int minorVersion, HGLRC parentContext);
static void PlatformCreateOpenGLContextCore(HGLRC* result, HDC deviceContext, HGLRC parentContext);
};
#endif

View File

@@ -1,185 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "Win32GPUSwapChainOGL.h"
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
#include "Engine/Threading/Threading.h"
#include "Engine/Platform/Window.h"
#include "Engine/Platform/Windows/WindowsWindow.h"
#include "Win32ContextOGL.h"
#include "../RenderToolsOGL.h"
Win32GPUSwapChainOGL* Win32GPUSwapChainOGL::Create(GPUDeviceOGL* device, const String& name, Window* parent)
{
auto winWindow = (WindowsWindow*)parent;
auto hwnd = winWindow->GetHWND();
auto hdc = GetDC(hwnd);
Win32ContextOGL::PlatformInitPixelFormatForDevice(hdc);
return New<Win32GPUSwapChainOGL>(device, name, parent, hwnd, hdc);
}
Win32GPUSwapChainOGL::Win32GPUSwapChainOGL(GPUDeviceOGL* device, const String& name, Window* parent, HWND hwnd, HDC hdc)
: GPUSwapChainOGL(device, name, parent)
, _hwnd(hwnd)
, _hdc(hdc)
, _context(0)
, _isDisposing(false)
{
}
Win32GPUSwapChainOGL::~Win32GPUSwapChainOGL()
{
ReleaseDC(_hwnd, _hdc);
}
void Win32GPUSwapChainOGL::ReleaseGPU()
{
if (_isDisposing || _memoryUsage == 0)
return;
_isDisposing = true;
// TODO: disable fullscreenmode
// Release data
_backBufferHandle.Release();
if (_context)
{
// Check if the main context is going to be closed
if (_context == Win32ContextOGL::OpenGLContext)
{
// Release all GPU resources
_device->Dispose();
// Release all the child windows
while (Win32ContextOGL::ChildWindows.HasItems())
{
Win32ContextOGL::ChildWindows[0]->ReleaseGPU();
}
Win32ContextOGL::OpenGLContext = 0;
Win32ContextOGL::OpenGLContextWin = 0;
}
else
{
Win32ContextOGL::ChildWindows.Remove(this);
}
Win32ContextOGL::ContextMakeCurrent(NULL, NULL);
wglDeleteContext(_context);
_context = nullptr;
}
_memoryUsage = 0;
_width = _height = 0;
// Restore the main context if still valid
if (Win32ContextOGL::OpenGLContext)
{
Win32ContextOGL::ContextMakeCurrent(Win32ContextOGL::OpenGLContextWin, Win32ContextOGL::OpenGLContext);
}
_isDisposing = false;
}
bool Win32GPUSwapChainOGL::IsFullscreen()
{
// TODO: support fullscreen on OpenGL
return false;
}
void Win32GPUSwapChainOGL::SetFullscreen(bool isFullscreen)
{
// TODO: support fullscreen on OpenGL
LOG(Warning, "TODO: support fullscreen on OpenGL/Windows");
}
bool Win32GPUSwapChainOGL::Resize(int32 width, int32 height)
{
// Check if size won't change
if (width == _width && height == _height)
{
// Back
return false;
}
// Wait for GPU to flush commands
WaitForGPU();
// Lock device
GPUDeviceLock lock(_device);
// Check if has no context
if (_context == 0)
{
// Create the context
Win32ContextOGL::PlatformCreateOpenGLContextCore(&_context, _hdc, Win32ContextOGL::OpenGLContext);
if (_context == 0)
{
LOG(Error, "Failed to create OpenGL device context");
return true;
}
// Check if the main context is missing
if (Win32ContextOGL::OpenGLContext == 0)
{
// Be a master context
Win32ContextOGL::OpenGLContext = _context;
Win32ContextOGL::OpenGLContextWin = _hdc;
// Init device
_device->InitWithMainContext();
}
else
{
// Be a child context
Win32ContextOGL::ChildWindows.Add(this);
}
// Use the main context
Win32ContextOGL::ContextMakeCurrent(Win32ContextOGL::OpenGLContextWin, Win32ContextOGL::OpenGLContext);
}
else
{
// TODO: need to resize the backuffer? win32 window gets resized by the platform backend
}
// Init back buffer handle
_backBufferHandle.InitAsBackbuffer(this, GPU_BACK_BUFFER_PIXEL_FORMAT);
// Cache data
_width = width;
_height = height;
// Calculate memory usage
_memoryUsage = CalculateTextureMemoryUsage(PixelFormat::R8G8B8A8_UNorm, _width, _height, 1) * 2;
return false;
}
void Win32GPUSwapChainOGL::Present(bool vsync)
{
// TODO: vsync on OpenGL
//wglSwapIntervalEXT(vsync ? 1 : 0);
//VALIDATE_OPENGL_RESULT();
// Present frame
SwapBuffers(_hdc);
// Base
GPUSwapChain::Present(vsync);
}
bool Win32GPUSwapChainOGL::DownloadData(TextureData* result)
{
MISSING_CODE("Win32GPUSwapChainOGL::DownloadData");
return true;
}
Task* Win32GPUSwapChainOGL::DownloadDataAsync(TextureData* result)
{
MISSING_CODE("Win32GPUSwapChainOGL::DownloadDataAsync");
return nullptr;
}
#endif

View File

@@ -1,45 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "../GPUSwapChainOGL.h"
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
/// <summary>
/// Graphics Device rendering output for OpenGL on Windows
/// </summary>
class Win32GPUSwapChainOGL : public GPUSwapChainOGL
{
private:
HWND _hwnd;
HDC _hdc;
HGLRC _context;
bool _isDisposing;
Win32GPUSwapChainOGL(GPUDeviceOGL* device, const String& name, Window* parent, HWND hwnd, HDC hdc);
~Win32GPUSwapChainOGL();
public:
// Init
static Win32GPUSwapChainOGL* Create(GPUDeviceOGL* device, const String& name, Window* parent);
public:
// [GPUResourceOGL]
void ReleaseGPU() override;
// [GPUSwapChainOGL]
bool IsFullscreen() override;
void SetFullscreen(bool isFullscreen) override;
bool DownloadData(TextureData* result) override;
Task* DownloadDataAsync(TextureData* result) override;
void Present(bool vsync) override;
bool Resize(int32 width, int32 height) override;
};
#endif

View File

@@ -551,16 +551,11 @@ void Render2D::Begin(GPUContext* context, GPUTexture* output, GPUTexture* depthB
void Render2D::Begin(GPUContext* context, GPUTextureView* output, GPUTextureView* depthBuffer, const Viewport& viewport)
{
Matrix view, projection, viewProjection;
float halfWidth = viewport.Width * 0.5f;
float halfHeight = viewport.Height * 0.5f;
#if GRAPHICS_API_OPENGL
const float ZNear = -100.0f;
const float ZFar = 100.0f;
#else
const float ZNear = 0.0f;
const float ZFar = 1.0f;
#endif
Matrix::OrthoOffCenter(-halfWidth, halfWidth, halfHeight, -halfHeight, ZNear, ZFar, projection);
const float halfWidth = viewport.Width * 0.5f;
const float halfHeight = viewport.Height * 0.5f;
const float zNear = 0.0f;
const float zFar = 1.0f;
Matrix::OrthoOffCenter(-halfWidth, halfWidth, halfHeight, -halfHeight, zNear, zFar, projection);
Matrix::Translation(-halfWidth, -halfHeight, 0, view);
Matrix::Multiply(view, projection, viewProjection);

View File

@@ -1,9 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#include "../Config.h"
#define XSC_ENABLE_LANGUAGE_EXT 1
#include <Xsc/Xsc.h>
#pragma comment(lib, "XShaderCompiler.lib")

View File

@@ -1,17 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
using Flax.Build.NativeCpp;
/// <summary>
/// OpenGL shaders compiler module.
/// </summary>
public class ShaderCompilerOGL : ShaderCompiler
{
/// <inheritdoc />
public override void Setup(BuildOptions options)
{
base.Setup(options);
options.PublicDefinitions.Add("COMPILE_WITH_OGL_SHADER_COMPILER");
}
}

View File

@@ -1,585 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if COMPILE_WITH_OGL_SHADER_COMPILER
#include "ShaderCompilerOGL.h"
#include "Engine/Platform/Platform.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Serialization/MemoryWriteStream.h"
#include "Engine/Core/Log.h"
#include "../RenderToolsOGL.h"
#include "../ShaderAPI.h"
#include <fstream>
#include <iostream>
#include <LZ4/lz4.h>
ShaderCompilerOGL::ShaderCompilerOGL(ShaderProfile profile)
: _profile(profile)
, _context(nullptr)
, _sourceStream(0)
{
// Check for supported profiles
ASSERT(profile == ShaderProfile::GLSL_410 || profile == ShaderProfile::GLSL_440);
}
ShaderCompilerOGL::~ShaderCompilerOGL()
{
}
#define USE_DETAILED_LOG 1
class XscLog : public Xsc::Log
{
public:
std::stringstream Log;
private:
#if USE_DETAILED_LOG
static void PrintMultiLineString(std::stringstream& output, const std::string& str, const std::string& indent)
{
// Determine at which position the actual text begins (excluding the "error (X:Y) : " or the like)
auto textStartPos = str.find(" : ");
if (textStartPos != std::string::npos)
textStartPos += 3;
else
textStartPos = 0;
std::string newLineIndent(textStartPos, ' ');
size_t start = 0;
bool useNewLineIndent = false;
while (start < str.size())
{
output << indent;
if (useNewLineIndent)
output << newLineIndent;
// Print next line
auto end = str.find('\n', start);
if (end != std::string::npos)
{
output << str.substr(start, end - start);
start = end + 1;
}
else
{
output << str.substr(start);
start = end;
}
output << std::endl;
useNewLineIndent = true;
}
}
void PrintReport(std::stringstream& output, const Xsc::Report& report, const std::string& indent)
{
// Print optional context description
auto context = report.Context();
if (!context.empty())
PrintMultiLineString(output, context, indent);
// Print report message
auto msg = report.Message();
PrintMultiLineString(output, msg, indent);
// Print optional line and line-marker
if (report.HasLine())
{
const auto& line = report.Line();
const auto& marker = report.Marker();
// Print line
output << indent << line << std::endl;
// Print line marker
output << indent << marker << std::endl;
}
// Print optional hints
auto hints = report.GetHints();
if (hints.size() > 0)
{
for (auto hint : hints)
output << indent << hint << std::endl;
}
}
#endif
public:
// [Log]
void SubmitReport(const Xsc::Report& report) override
{
#if !USE_DETAILED_LOG
std::string str = report.Message();
switch (report.Type())
{
case Xsc::ReportTypes::Info:
Log << "Info: " << str << std::endl;
break;
case Xsc::ReportTypes::Warning:
Log << "Warning: " << str << std::endl;
break;
case Xsc::ReportTypes::Error:
Log << "Error: " << str << std::endl;
break;
}
#else
switch (report.Type())
{
case Xsc::ReportTypes::Info:
Log << "Info: " << std::endl;
break;
case Xsc::ReportTypes::Warning:
Log << "Warning: " << std::endl;
break;
case Xsc::ReportTypes::Error:
Log << "Error: " << std::endl;
break;
}
PrintReport(Log, report, FullIndent());
#endif
}
};
int GetUniformSize(Xsc::Reflection::DataType type)
{
switch (type)
{
//case Xsc::Reflection::DataType::Undefined:
// String types:
//case Xsc::Reflection::DataType::String:
// Scalar types
case Xsc::Reflection::DataType::Bool: return 1;
case Xsc::Reflection::DataType::Int: return 4;
case Xsc::Reflection::DataType::UInt: return 4;
case Xsc::Reflection::DataType::Half: return 2;
case Xsc::Reflection::DataType::Float: return 4;
case Xsc::Reflection::DataType::Double: return 8;
// Vector types
case Xsc::Reflection::DataType::Bool2: return 1 * 2;
case Xsc::Reflection::DataType::Bool3: return 1 * 3;
case Xsc::Reflection::DataType::Bool4: return 1 * 4;
case Xsc::Reflection::DataType::Int2: return 4 * 2;
case Xsc::Reflection::DataType::Int3: return 4 * 3;
case Xsc::Reflection::DataType::Int4: return 4 * 4;
case Xsc::Reflection::DataType::UInt2: return 4 * 2;
case Xsc::Reflection::DataType::UInt3: return 4 * 3;
case Xsc::Reflection::DataType::UInt4: return 4 * 4;
case Xsc::Reflection::DataType::Half2: return 2 * 2;
case Xsc::Reflection::DataType::Half3: return 2 * 3;
case Xsc::Reflection::DataType::Half4: return 2 * 4;
case Xsc::Reflection::DataType::Float2: return 4 * 2;
case Xsc::Reflection::DataType::Float3: return 4 * 3;
case Xsc::Reflection::DataType::Float4: return 4 * 4;
case Xsc::Reflection::DataType::Double2: return 8 * 2;
case Xsc::Reflection::DataType::Double3: return 8 * 3;
case Xsc::Reflection::DataType::Double4: return 8 * 4;
// Matrix types
case Xsc::Reflection::DataType::Bool2x2: return 1 * 2 * 2;
case Xsc::Reflection::DataType::Bool2x3: return 1 * 2 * 3;
case Xsc::Reflection::DataType::Bool2x4: return 1 * 2 * 4;
case Xsc::Reflection::DataType::Bool3x2: return 1 * 3 * 2;
case Xsc::Reflection::DataType::Bool3x3: return 1 * 3 * 4;
case Xsc::Reflection::DataType::Bool3x4: return 1 * 3 * 5;
case Xsc::Reflection::DataType::Bool4x2: return 1 * 4 * 2;
case Xsc::Reflection::DataType::Bool4x3: return 1 * 4 * 3;
case Xsc::Reflection::DataType::Bool4x4: return 1 * 4 * 4;
case Xsc::Reflection::DataType::Int2x2: return 4 * 2 * 2;
case Xsc::Reflection::DataType::Int2x3: return 4 * 2 * 3;
case Xsc::Reflection::DataType::Int2x4: return 4 * 2 * 4;
case Xsc::Reflection::DataType::Int3x2: return 4 * 3 * 2;
case Xsc::Reflection::DataType::Int3x3: return 4 * 3 * 3;
case Xsc::Reflection::DataType::Int3x4: return 4 * 3 * 4;
case Xsc::Reflection::DataType::Int4x2: return 4 * 4 * 2;
case Xsc::Reflection::DataType::Int4x3: return 4 * 4 * 3;
case Xsc::Reflection::DataType::Int4x4: return 4 * 4 * 4;
case Xsc::Reflection::DataType::UInt2x2: return 4 * 2 * 2;
case Xsc::Reflection::DataType::UInt2x3: return 4 * 2 * 3;
case Xsc::Reflection::DataType::UInt2x4: return 4 * 2 * 4;
case Xsc::Reflection::DataType::UInt3x2: return 4 * 3 * 2;
case Xsc::Reflection::DataType::UInt3x3: return 4 * 3 * 3;
case Xsc::Reflection::DataType::UInt3x4: return 4 * 3 * 4;
case Xsc::Reflection::DataType::UInt4x2: return 4 * 4 * 2;
case Xsc::Reflection::DataType::UInt4x3: return 4 * 4 * 3;
case Xsc::Reflection::DataType::UInt4x4: return 4 * 4 * 4;
case Xsc::Reflection::DataType::Half2x2: return 2 * 2 * 2;
case Xsc::Reflection::DataType::Half2x3: return 2 * 2 * 3;
case Xsc::Reflection::DataType::Half2x4: return 2 * 2 * 4;
case Xsc::Reflection::DataType::Half3x2: return 2 * 3 * 2;
case Xsc::Reflection::DataType::Half3x3: return 2 * 3 * 3;
case Xsc::Reflection::DataType::Half3x4: return 2 * 3 * 4;
case Xsc::Reflection::DataType::Half4x2: return 2 * 4 * 2;
case Xsc::Reflection::DataType::Half4x3: return 2 * 4 * 3;
case Xsc::Reflection::DataType::Half4x4: return 2 * 4 * 4;
case Xsc::Reflection::DataType::Float2x2: return 4 * 2 * 2;
case Xsc::Reflection::DataType::Float2x3: return 4 * 2 * 3;
case Xsc::Reflection::DataType::Float2x4: return 4 * 2 * 4;
case Xsc::Reflection::DataType::Float3x2: return 4 * 3 * 2;
case Xsc::Reflection::DataType::Float3x3: return 4 * 3 * 3;
case Xsc::Reflection::DataType::Float3x4: return 4 * 3 * 4;
case Xsc::Reflection::DataType::Float4x2: return 4 * 4 * 2;
case Xsc::Reflection::DataType::Float4x3: return 4 * 4 * 3;
case Xsc::Reflection::DataType::Float4x4: return 4 * 4 * 4;
case Xsc::Reflection::DataType::Double2x2: return 8 * 2 * 2;
case Xsc::Reflection::DataType::Double2x3: return 8 * 2 * 3;
case Xsc::Reflection::DataType::Double2x4: return 8 * 2 * 4;
case Xsc::Reflection::DataType::Double3x2: return 8 * 3 * 2;
case Xsc::Reflection::DataType::Double3x3: return 8 * 3 * 3;
case Xsc::Reflection::DataType::Double3x4: return 8 * 3 * 4;
case Xsc::Reflection::DataType::Double4x2: return 8 * 4 * 2;
case Xsc::Reflection::DataType::Double4x3: return 8 * 4 * 3;
case Xsc::Reflection::DataType::Double4x4: return 8 * 4 * 4;
}
return 0;
}
bool ShaderCompilerOGL::ProcessShader(Xsc::Reflection::ReflectionData& data, uint32& cbMask)
{
// Reset masks
cbMask = 0;
srMask = 0;
uaMask = 0;
// Extract constant buffers usage information
for (const auto& cb : data.constantBuffers)
{
if (cb.location < 0)
{
_context->OnError("Missing bound resource.");
return true;
}
// Set flag
cbMask |= 1 << cb.location;
// Try to add CB to the list
for (int32 b = 0; b < _constantBuffers.Count(); b++)
{
auto& cc = _constantBuffers[b];
if (cc.Slot == cb.location)
{
// Calculate the size (based on uniforms used in this buffer)
cc.Size = 0;
for (const auto& uniform : data.uniforms)
{
if (uniform.type == Xsc::Reflection::UniformType::Variable
&& uniform.uniformBlock == cb.location)
{
cc.Size += GetUniformSize((Xsc::Reflection::DataType)uniform.baseType);
}
}
cc.IsUsed = true;
break;
}
}
}
// Extract resources usage
for (const auto& sr : data.textures)
{
if (sr.location < 0)
{
_context->OnError("Missing bound resource.");
return true;
}
// Set flag
srMask |= 1 << sr.location;
}
return false;
}
bool ShaderCompilerOGL::CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite)
{
// Prepare
auto output = _context->Output;
auto options = _context->Options;
auto type = meta.GetStage();
auto permutationsCount = meta.GetPermutationsCount();
// Construct shader target
switch (type)
{
case ShaderStage::Vertex: _inputDesc.shaderTarget = Xsc::ShaderTarget::VertexShader; break;
case ShaderStage::Hull: _inputDesc.shaderTarget = Xsc::ShaderTarget::TessellationControlShader; break;
case ShaderStage::Domain: _inputDesc.shaderTarget = Xsc::ShaderTarget::TessellationEvaluationShader; break;
case ShaderStage::Geometry: _inputDesc.shaderTarget = Xsc::ShaderTarget::GeometryShader; break;
case ShaderStage::Pixel: _inputDesc.shaderTarget = Xsc::ShaderTarget::FragmentShader; break;
case ShaderStage::Compute: _inputDesc.shaderTarget = Xsc::ShaderTarget::ComputeShader; break;
default: return true;
}
// [Output] Type
output->WriteByte(static_cast<byte>(type));
// [Output] Permutations count
output->WriteByte(permutationsCount);
// [Output] Shader function name
output->WriteStringAnsi(meta.Name, 11);
// Compile all shader function permutations
for (int32 permutationIndex = 0; permutationIndex < permutationsCount; permutationIndex++)
{
_macros.Clear();
// Get function permutation macros
meta.GetDefinitionsForPermutation(permutationIndex, _macros);
// Add additional define for compiled function name
GetDefineForFunction(meta, _macros);
// Add custom and global macros (global last because contain null define to indicate ending)
_macros.Add(_context->Options->Macros);
_macros.Add(_globalMacros);
// Setup the source code
// TODO: use shared _sourceStream and reduce dynamic memory allocations
std::shared_ptr<std::stringstream> input = std::shared_ptr<std::stringstream>(new std::stringstream());
for (int32 i = 0; i < _macros.Count(); i++)
{
ASSERT(_macros[i].Name && _macros[i].Definition);
*input << "#define " << _macros[i].Name << " " << _macros[i].Definition << "\n";
}
*input << options->Source;
// Setup options for this permutation
std::stringstream outputStream;// TODO: reuse it to reduce dynamic memory allocations
_inputDesc.sourceCode = input;
_inputDesc.entryPoint = meta.Name;
_outputDesc.sourceCode = &outputStream;
// Compile
Xsc::Reflection::ReflectionData reflection;
try
{
// Captures and prints to log the full AST tree
#define DEBUG_AST 0
#if DEBUG_AST
_outputDesc.options.showAST = true;
std::stringstream buffer;
std::streambuf* old = std::cout.rdbuf(buffer.rdbuf());
#endif
// Cross-compile HLSL to GLSL
XscLog log;
bool result = Xsc::CompileShader(_inputDesc, _outputDesc, &log, &reflection);
#if DEBUG_AST
String text = String(buffer.str());
LOG_STR(Info, text);
#endif
// Check compilation result
if (!result)
{
auto str = log.Log.str();
_context->OnError(str.c_str());
return true;
}
}
catch (const std::exception& e)
{
_context->OnError(e.what());
return true;
}
// Process reflection data
uint32 cbMask, uaMsrMaskask, uaMask;
if (ProcessShader(reflection, cbMask, srMaskk, uaMask))
return true;
// Get the source code (and append the null-terminator)
auto str = outputStream.str();
str += "\0";
// Prepare the shader buffer (for raw mode)
int32 shaderBufferType = SHADER_DATA_FORMAT_RAW;
uint32 shaderBufferSize = (uint32)str.length() + 1;
uint32 shaderBufferOriginalSize = shaderBufferSize;
byte* shaderBuffer = (byte*)str.c_str();
// Try to compress the source code (don't compress if memory gain is too small)
{
float maxCompressionRatio = 0.75f;
// Try use LZ4
int32 srcSize = (int32)shaderBufferSize;
int32 estSize = LZ4_compressBound(srcSize);
_dataCompressedCache.Clear();
_dataCompressedCache.EnsureCapacity(estSize);
int32 dstSize = LZ4_compress_default(str.c_str(), (char*)_dataCompressedCache.Get(), srcSize, estSize);
float ratio = (float)dstSize / srcSize;
if (dstSize == 0)
{
LOG(Warning, "Shader source data LZ4 compression failed.");
}
else if (ratio <= maxCompressionRatio)
{
// Use compressed format
shaderBufferType = SHADER_DATA_FORMAT_LZ4;
shaderBufferSize = dstSize;
shaderBuffer = _dataCompressedCache.Get();
}
}
// [Output] Write cross-compiled shader function
output->WriteInt32(shaderBufferType);
output->WriteUint32(shaderBufferOriginalSize);
output->WriteUint32(shaderBufferSize);
output->WriteBytes(shaderBuffer, shaderBufferSize);
// [Output] Shader meta
uint32 instructionCount = 0;// TODO: use AST reflection to count the shader instructions
output->WriteUint32(instructionCount);
output->WriteUint32(cbMask);
output->WriteUint32(srMask);
output->WriteUint32(uaMask);
// Custom data
if (customDataWrite && customDataWrite(output, meta, permutationIndex, _macros))
return true;
}
return false;
}
class FlaxIncludeHandler : public Xsc::IncludeHandler
{
public:
FlaxIncludeHandler()
{
}
std::unique_ptr<std::istream> Include(const std::string& includeName, bool useSearchPathsFirst) override
{
const String filename(includeName);
auto shaderApi = ShaderAPI::Instance();
ScopeLock lock(shaderApi->Locker);
const auto shader = shaderApi->GetShaderSource(filename);
if (shader == nullptr)
return nullptr;
std::unique_ptr<std::stringstream> stream = std::unique_ptr<std::stringstream>(new std::stringstream());
*stream << shader->Get();
return stream;
}
};
bool ShaderCompilerOGL::Compile(ShaderCompilationContext* context)
{
// Clear cache
_globalMacros.Clear();
_macros.Clear();
_constantBuffers.Clear();
_context = context;
// Prepare
auto options = context->Options;
auto output = context->Output;
auto meta = context->Meta;
bool use440 = _profile == ShaderProfile::GLSL_440;
int32 shadersCount = meta->GetShadersCount();
FlaxIncludeHandler includeHandler;
// Setup global shader macros
_globalMacros.EnsureCapacity(32);
_macros.EnsureCapacity(32);
_globalMacros.Add({ "OPENGL", "1" });
GetGlobalDefines(_globalMacros);
// Allocate shader source stream data (it will include compilation macros)
//uint32 macrosCountApprox = _globalMacros.Count() + options->Macros.Count() + 10;
//_sourceStream.Reset(Math::Max<uint32>(_sourceStream.GetCapacity(), sizeof(Char) * Math::RoundUpToPowerOf2<uint32>(options->SourceLength + 32 * macrosCountApprox)));
// TODO: preallocate _sourceStream to reduce dynamic allocations
// Setup cross-compiler options
{
switch (_profile)
{
case ShaderProfile::GLSL_440: _inputDesc.shaderVersion = Xsc::InputShaderVersion::HLSL5; break;
case ShaderProfile::GLSL_410: _inputDesc.shaderVersion = Xsc::InputShaderVersion::HLSL4; break;
}
_inputDesc.filename = context->TargetNameAnsi;
_inputDesc.extensions = Xsc::Extensions::LayoutAttribute;
_inputDesc.includeHandler = &includeHandler;
}
{
switch (_profile)
{
case ShaderProfile::GLSL_440: _outputDesc.shaderVersion = Xsc::OutputShaderVersion::GLSL440; break;
case ShaderProfile::GLSL_410: _outputDesc.shaderVersion = Xsc::OutputShaderVersion::GLSL410; break;
}
_outputDesc.options.optimize = !options->NoOptimize;
_outputDesc.options.separateShaders = true;
_outputDesc.options.separateSamplers = true;
_outputDesc.options.preserveComments = false;
_outputDesc.options.explicitBinding = true;
_outputDesc.formatting.writeGeneratorHeader = false;
_outputDesc.formatting.blanks = false;
_outputDesc.nameMangling.inputPrefix = "f_";
_outputDesc.nameMangling.outputPrefix = "f_";
_outputDesc.nameMangling.useAlwaysSemantics = true;
_outputDesc.nameMangling.renameBufferFields = true;
}
// Setup constant buffers cache
_constantBuffers.EnsureCapacity(meta->CB.Count(), false);
for (int32 i = 0; i < meta->CB.Count(); i++)
_constantBuffers.Add({ meta->CB[i].Slot, false, 0 });
// [Output] Write version number
output->WriteInt32(1);
// [Output] Write amount of shaders
output->WriteInt32(shadersCount);
// Compile all shaders
if (CompileShaders(context))
return true;
// [Output] Constant Buffers
{
int32 cbsCount = _constantBuffers.Count();
ASSERT(cbsCount == meta->CB.Count());
// Find maximum used slot index
byte maxCbSlot = 0;
for (int32 i = 0; i < cbsCount; i++)
{
maxCbSlot = Math::Max(maxCbSlot, _constantBuffers[i].Slot);
}
output->WriteByte(static_cast<byte>(cbsCount));
output->WriteByte(maxCbSlot);
// TODO: do we still need to serialize max cb slot?
for (int32 i = 0; i < cbsCount; i++)
{
output->WriteByte(_constantBuffers[i].Slot);
output->WriteUint32(_constantBuffers[i].Size);
}
}
return false;
}
#endif

View File

@@ -1,50 +0,0 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if COMPILE_WITH_OGL_SHADER_COMPILER
#include "Engine/ShadersCompilation/ShaderCompiler.h"
#include "IncludeXShaderCompiler.h"
#include "../IncludeOpenGLHeaders.h"
#include "Engine/Serialization/MemoryWriteStream.h"
#include <sstream>
/// <summary>
/// Implementation of shaders compiler for OpenGL and OpenGL ES platforms
/// </summary>
class ShaderCompilerOGL : public ShaderCompiler
{
private:
ShaderProfile _profile;
ShaderCompilationContext* _context;
Array<ShaderMacro> _globalMacros;
Array<ShaderMacro> _macros;
Array<ShaderResourceBuffer> _constantBuffers;
Array<byte> _dataCompressedCache;
Xsc::ShaderInput _inputDesc;
Xsc::ShaderOutput _outputDesc;
std::stringstream _sourceStream;
public:
/// <summary>
/// Initializes a new instance of the <see cref="ShaderCompilerOGL"/> class.
/// </summary>
/// <param name="profile">The profile.</param>
ShaderCompilerOGL(ShaderProfile profile);
private:
bool ProcessShader(Xsc::Reflection::ReflectionData& data, uint32& cbMask, uint32& srMask, uint32& uaMask)
protected:
// [ShaderCompiler]
bool CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite = nullptr) override;
bool OnCompileBegin() override;
};
#endif

View File

@@ -29,9 +29,6 @@
#if COMPILE_WITH_DX_SHADER_COMPILER
#include "DirectX/ShaderCompilerDX.h"
#endif
#if COMPILE_WITH_OGL_SHADER_COMPILER
#include "OpenGL/ShaderCompilerOGL.h"
#endif
#if COMPILE_WITH_VK_SHADER_COMPILER
#include "Vulkan/ShaderCompilerVulkan.h"
#endif
@@ -159,13 +156,6 @@ ShaderCompiler* ShadersCompilation::CreateCompiler(ShaderProfile profile)
result = New<ShaderCompilerDX>(profile);
break;
#endif
#if COMPILE_WITH_OGL_SHADER_COMPILER
// OpenGL and OpenGL ES
case ShaderProfile::GLSL_410:
case ShaderProfile::GLSL_440:
result = New<ShaderCompilerOGL>(profile);
break;
#endif
#if COMPILE_WITH_VK_SHADER_COMPILER
// Vulkan
case ShaderProfile::Vulkan_SM5:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,936 +0,0 @@
#ifndef __glxext_h_
#define __glxext_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 33136 $ on $Date: 2016-09-15 06:33:58 -0400 (Thu, 15 Sep 2016) $
*/
#define GLX_GLXEXT_VERSION 20160914
/* Generated C header for:
* API: glx
* Versions considered: .*
* Versions emitted: 1\.[3-9]
* Default extensions included: glx
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef GLX_VERSION_1_3
#define GLX_VERSION_1_3 1
typedef XID GLXContextID;
typedef struct __GLXFBConfigRec *GLXFBConfig;
typedef XID GLXWindow;
typedef XID GLXPbuffer;
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_RGBA_BIT 0x00000001
#define GLX_COLOR_INDEX_BIT 0x00000002
#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
#define GLX_AUX_BUFFERS_BIT 0x00000010
#define GLX_DEPTH_BUFFER_BIT 0x00000020
#define GLX_STENCIL_BUFFER_BIT 0x00000040
#define GLX_ACCUM_BUFFER_BIT 0x00000080
#define GLX_CONFIG_CAVEAT 0x20
#define GLX_X_VISUAL_TYPE 0x22
#define GLX_TRANSPARENT_TYPE 0x23
#define GLX_TRANSPARENT_INDEX_VALUE 0x24
#define GLX_TRANSPARENT_RED_VALUE 0x25
#define GLX_TRANSPARENT_GREEN_VALUE 0x26
#define GLX_TRANSPARENT_BLUE_VALUE 0x27
#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
#define GLX_DONT_CARE 0xFFFFFFFF
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_PSEUDO_COLOR 0x8004
#define GLX_STATIC_COLOR 0x8005
#define GLX_GRAY_SCALE 0x8006
#define GLX_STATIC_GRAY 0x8007
#define GLX_TRANSPARENT_RGB 0x8008
#define GLX_TRANSPARENT_INDEX 0x8009
#define GLX_VISUAL_ID 0x800B
#define GLX_SCREEN 0x800C
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_X_RENDERABLE 0x8012
#define GLX_FBCONFIG_ID 0x8013
#define GLX_RGBA_TYPE 0x8014
#define GLX_COLOR_INDEX_TYPE 0x8015
#define GLX_MAX_PBUFFER_WIDTH 0x8016
#define GLX_MAX_PBUFFER_HEIGHT 0x8017
#define GLX_MAX_PBUFFER_PIXELS 0x8018
#define GLX_PRESERVED_CONTENTS 0x801B
#define GLX_LARGEST_PBUFFER 0x801C
#define GLX_WIDTH 0x801D
#define GLX_HEIGHT 0x801E
#define GLX_EVENT_MASK 0x801F
#define GLX_DAMAGED 0x8020
#define GLX_SAVED 0x8021
#define GLX_WINDOW 0x8022
#define GLX_PBUFFER 0x8023
#define GLX_PBUFFER_HEIGHT 0x8040
#define GLX_PBUFFER_WIDTH 0x8041
typedef GLXFBConfig *( *PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
typedef GLXFBConfig *( *PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
typedef int ( *PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
typedef GLXWindow ( *PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
typedef void ( *PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
typedef GLXPixmap ( *PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
typedef void ( *PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
typedef GLXPbuffer ( *PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
typedef void ( *PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
typedef void ( *PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
typedef GLXContext ( *PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
typedef Bool ( *PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
typedef int ( *PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
typedef void ( *PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
typedef void ( *PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXFBConfig *glXGetFBConfigs (Display *dpy, int screen, int *nelements);
GLXFBConfig *glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements);
int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value);
XVisualInfo *glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config);
GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
void glXDestroyWindow (Display *dpy, GLXWindow win);
GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap);
GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list);
void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf);
void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
GLXDrawable glXGetCurrentReadDrawable (void);
int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value);
void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask);
void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
#endif
#endif /* GLX_VERSION_1_3 */
#ifndef GLX_VERSION_1_4
#define GLX_VERSION_1_4 1
typedef void ( *__GLXextFuncPtr)(void);
#define GLX_SAMPLE_BUFFERS 100000
#define GLX_SAMPLES 100001
typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName);
#ifdef GLX_GLXEXT_PROTOTYPES
__GLXextFuncPtr glXGetProcAddress (const GLubyte *procName);
#endif
#endif /* GLX_VERSION_1_4 */
#ifndef GLX_ARB_context_flush_control
#define GLX_ARB_context_flush_control 1
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#endif /* GLX_ARB_context_flush_control */
#ifndef GLX_ARB_create_context
#define GLX_ARB_create_context 1
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXContext glXCreateContextAttribsARB (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#endif
#endif /* GLX_ARB_create_context */
#ifndef GLX_ARB_create_context_profile
#define GLX_ARB_create_context_profile 1
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#endif /* GLX_ARB_create_context_profile */
#ifndef GLX_ARB_create_context_robustness
#define GLX_ARB_create_context_robustness 1
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
#endif /* GLX_ARB_create_context_robustness */
#ifndef GLX_ARB_fbconfig_float
#define GLX_ARB_fbconfig_float 1
#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
#endif /* GLX_ARB_fbconfig_float */
#ifndef GLX_ARB_framebuffer_sRGB
#define GLX_ARB_framebuffer_sRGB 1
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
#endif /* GLX_ARB_framebuffer_sRGB */
#ifndef GLX_ARB_get_proc_address
#define GLX_ARB_get_proc_address 1
typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName);
#ifdef GLX_GLXEXT_PROTOTYPES
__GLXextFuncPtr glXGetProcAddressARB (const GLubyte *procName);
#endif
#endif /* GLX_ARB_get_proc_address */
#ifndef GLX_ARB_multisample
#define GLX_ARB_multisample 1
#define GLX_SAMPLE_BUFFERS_ARB 100000
#define GLX_SAMPLES_ARB 100001
#endif /* GLX_ARB_multisample */
#ifndef GLX_ARB_robustness_application_isolation
#define GLX_ARB_robustness_application_isolation 1
#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
#endif /* GLX_ARB_robustness_application_isolation */
#ifndef GLX_ARB_robustness_share_group_isolation
#define GLX_ARB_robustness_share_group_isolation 1
#endif /* GLX_ARB_robustness_share_group_isolation */
#ifndef GLX_ARB_vertex_buffer_object
#define GLX_ARB_vertex_buffer_object 1
#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
#endif /* GLX_ARB_vertex_buffer_object */
#ifndef GLX_3DFX_multisample
#define GLX_3DFX_multisample 1
#define GLX_SAMPLE_BUFFERS_3DFX 0x8050
#define GLX_SAMPLES_3DFX 0x8051
#endif /* GLX_3DFX_multisample */
#ifndef GLX_AMD_gpu_association
#define GLX_AMD_gpu_association 1
#define GLX_GPU_VENDOR_AMD 0x1F00
#define GLX_GPU_RENDERER_STRING_AMD 0x1F01
#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define GLX_GPU_RAM_AMD 0x21A3
#define GLX_GPU_CLOCK_AMD 0x21A4
#define GLX_GPU_NUM_PIPES_AMD 0x21A5
#define GLX_GPU_NUM_SIMD_AMD 0x21A6
#define GLX_GPU_NUM_RB_AMD 0x21A7
#define GLX_GPU_NUM_SPI_AMD 0x21A8
typedef unsigned int ( *PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int *ids);
typedef int ( *PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void *data);
typedef unsigned int ( *PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx);
typedef GLXContext ( *PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list);
typedef GLXContext ( *PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int *attribList);
typedef Bool ( *PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx);
typedef Bool ( *PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx);
typedef GLXContext ( *PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef void ( *PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#ifdef GLX_GLXEXT_PROTOTYPES
unsigned int glXGetGPUIDsAMD (unsigned int maxCount, unsigned int *ids);
int glXGetGPUInfoAMD (unsigned int id, int property, GLenum dataType, unsigned int size, void *data);
unsigned int glXGetContextGPUIDAMD (GLXContext ctx);
GLXContext glXCreateAssociatedContextAMD (unsigned int id, GLXContext share_list);
GLXContext glXCreateAssociatedContextAttribsAMD (unsigned int id, GLXContext share_context, const int *attribList);
Bool glXDeleteAssociatedContextAMD (GLXContext ctx);
Bool glXMakeAssociatedContextCurrentAMD (GLXContext ctx);
GLXContext glXGetCurrentAssociatedContextAMD (void);
void glXBlitContextFramebufferAMD (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#endif /* GLX_AMD_gpu_association */
#ifndef GLX_EXT_buffer_age
#define GLX_EXT_buffer_age 1
#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
#endif /* GLX_EXT_buffer_age */
#ifndef GLX_EXT_create_context_es2_profile
#define GLX_EXT_create_context_es2_profile 1
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif /* GLX_EXT_create_context_es2_profile */
#ifndef GLX_EXT_create_context_es_profile
#define GLX_EXT_create_context_es_profile 1
#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
#endif /* GLX_EXT_create_context_es_profile */
#ifndef GLX_EXT_fbconfig_packed_float
#define GLX_EXT_fbconfig_packed_float 1
#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
#endif /* GLX_EXT_fbconfig_packed_float */
#ifndef GLX_EXT_framebuffer_sRGB
#define GLX_EXT_framebuffer_sRGB 1
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
#endif /* GLX_EXT_framebuffer_sRGB */
#ifndef GLX_EXT_import_context
#define GLX_EXT_import_context 1
#define GLX_SHARE_CONTEXT_EXT 0x800A
#define GLX_VISUAL_ID_EXT 0x800B
#define GLX_SCREEN_EXT 0x800C
typedef Display *( *PFNGLXGETCURRENTDISPLAYEXTPROC) (void);
typedef int ( *PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value);
typedef GLXContextID ( *PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
typedef GLXContext ( *PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID);
typedef void ( *PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context);
#ifdef GLX_GLXEXT_PROTOTYPES
Display *glXGetCurrentDisplayEXT (void);
int glXQueryContextInfoEXT (Display *dpy, GLXContext context, int attribute, int *value);
GLXContextID glXGetContextIDEXT (const GLXContext context);
GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID);
void glXFreeContextEXT (Display *dpy, GLXContext context);
#endif
#endif /* GLX_EXT_import_context */
#ifndef GLX_EXT_libglvnd
#define GLX_EXT_libglvnd 1
#define GLX_VENDOR_NAMES_EXT 0x20F6
#endif /* GLX_EXT_libglvnd */
#ifndef GLX_EXT_stereo_tree
#define GLX_EXT_stereo_tree 1
typedef struct {
int type;
unsigned long serial;
Bool send_event;
Display *display;
int extension;
int evtype;
GLXDrawable window;
Bool stereo_tree;
} GLXStereoNotifyEventEXT;
#define GLX_STEREO_TREE_EXT 0x20F5
#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
#define GLX_STEREO_NOTIFY_EXT 0x00000000
#endif /* GLX_EXT_stereo_tree */
#ifndef GLX_EXT_swap_control
#define GLX_EXT_swap_control 1
#define GLX_SWAP_INTERVAL_EXT 0x20F1
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
typedef void ( *PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXSwapIntervalEXT (Display *dpy, GLXDrawable drawable, int interval);
#endif
#endif /* GLX_EXT_swap_control */
#ifndef GLX_EXT_swap_control_tear
#define GLX_EXT_swap_control_tear 1
#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
#endif /* GLX_EXT_swap_control_tear */
#ifndef GLX_EXT_texture_from_pixmap
#define GLX_EXT_texture_from_pixmap 1
#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
#define GLX_Y_INVERTED_EXT 0x20D4
#define GLX_TEXTURE_FORMAT_EXT 0x20D5
#define GLX_TEXTURE_TARGET_EXT 0x20D6
#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
#define GLX_TEXTURE_1D_EXT 0x20DB
#define GLX_TEXTURE_2D_EXT 0x20DC
#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
#define GLX_FRONT_LEFT_EXT 0x20DE
#define GLX_FRONT_RIGHT_EXT 0x20DF
#define GLX_BACK_LEFT_EXT 0x20E0
#define GLX_BACK_RIGHT_EXT 0x20E1
#define GLX_FRONT_EXT 0x20DE
#define GLX_BACK_EXT 0x20E0
#define GLX_AUX0_EXT 0x20E2
#define GLX_AUX1_EXT 0x20E3
#define GLX_AUX2_EXT 0x20E4
#define GLX_AUX3_EXT 0x20E5
#define GLX_AUX4_EXT 0x20E6
#define GLX_AUX5_EXT 0x20E7
#define GLX_AUX6_EXT 0x20E8
#define GLX_AUX7_EXT 0x20E9
#define GLX_AUX8_EXT 0x20EA
#define GLX_AUX9_EXT 0x20EB
typedef void ( *PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
typedef void ( *PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXBindTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
void glXReleaseTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer);
#endif
#endif /* GLX_EXT_texture_from_pixmap */
#ifndef GLX_EXT_visual_info
#define GLX_EXT_visual_info 1
#define GLX_X_VISUAL_TYPE_EXT 0x22
#define GLX_TRANSPARENT_TYPE_EXT 0x23
#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
#define GLX_NONE_EXT 0x8000
#define GLX_TRUE_COLOR_EXT 0x8002
#define GLX_DIRECT_COLOR_EXT 0x8003
#define GLX_PSEUDO_COLOR_EXT 0x8004
#define GLX_STATIC_COLOR_EXT 0x8005
#define GLX_GRAY_SCALE_EXT 0x8006
#define GLX_STATIC_GRAY_EXT 0x8007
#define GLX_TRANSPARENT_RGB_EXT 0x8008
#define GLX_TRANSPARENT_INDEX_EXT 0x8009
#endif /* GLX_EXT_visual_info */
#ifndef GLX_EXT_visual_rating
#define GLX_EXT_visual_rating 1
#define GLX_VISUAL_CAVEAT_EXT 0x20
#define GLX_SLOW_VISUAL_EXT 0x8001
#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
#endif /* GLX_EXT_visual_rating */
#ifndef GLX_INTEL_swap_event
#define GLX_INTEL_swap_event 1
#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180
#define GLX_COPY_COMPLETE_INTEL 0x8181
#define GLX_FLIP_COMPLETE_INTEL 0x8182
#endif /* GLX_INTEL_swap_event */
#ifndef GLX_MESA_agp_offset
#define GLX_MESA_agp_offset 1
typedef unsigned int ( *PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer);
#ifdef GLX_GLXEXT_PROTOTYPES
unsigned int glXGetAGPOffsetMESA (const void *pointer);
#endif
#endif /* GLX_MESA_agp_offset */
#ifndef GLX_MESA_copy_sub_buffer
#define GLX_MESA_copy_sub_buffer 1
typedef void ( *PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCopySubBufferMESA (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
#endif
#endif /* GLX_MESA_copy_sub_buffer */
#ifndef GLX_MESA_pixmap_colormap
#define GLX_MESA_pixmap_colormap 1
typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
#endif
#endif /* GLX_MESA_pixmap_colormap */
#ifndef GLX_MESA_query_renderer
#define GLX_MESA_query_renderer 1
#define GLX_RENDERER_VENDOR_ID_MESA 0x8183
#define GLX_RENDERER_DEVICE_ID_MESA 0x8184
#define GLX_RENDERER_VERSION_MESA 0x8185
#define GLX_RENDERER_ACCELERATED_MESA 0x8186
#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187
#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188
#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189
#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A
#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B
#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C
#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D
#define GLX_RENDERER_ID_MESA 0x818E
typedef Bool ( *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value);
typedef const char *( *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute);
typedef Bool ( *PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
typedef const char *( *PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXQueryCurrentRendererIntegerMESA (int attribute, unsigned int *value);
const char *glXQueryCurrentRendererStringMESA (int attribute);
Bool glXQueryRendererIntegerMESA (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
const char *glXQueryRendererStringMESA (Display *dpy, int screen, int renderer, int attribute);
#endif
#endif /* GLX_MESA_query_renderer */
#ifndef GLX_MESA_release_buffers
#define GLX_MESA_release_buffers 1
typedef Bool ( *PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXReleaseBuffersMESA (Display *dpy, GLXDrawable drawable);
#endif
#endif /* GLX_MESA_release_buffers */
#ifndef GLX_MESA_set_3dfx_mode
#define GLX_MESA_set_3dfx_mode 1
#define GLX_3DFX_WINDOW_MODE_MESA 0x1
#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
typedef Bool ( *PFNGLXSET3DFXMODEMESAPROC) (int mode);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXSet3DfxModeMESA (int mode);
#endif
#endif /* GLX_MESA_set_3dfx_mode */
#ifndef GLX_NV_copy_buffer
#define GLX_NV_copy_buffer 1
typedef void ( *PFNGLXCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
typedef void ( *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
void glXNamedCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
#endif
#endif /* GLX_NV_copy_buffer */
#ifndef GLX_NV_copy_image
#define GLX_NV_copy_image 1
typedef void ( *PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCopyImageSubDataNV (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#endif /* GLX_NV_copy_image */
#ifndef GLX_NV_delay_before_swap
#define GLX_NV_delay_before_swap 1
typedef Bool ( *PFNGLXDELAYBEFORESWAPNVPROC) (Display *dpy, GLXDrawable drawable, GLfloat seconds);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXDelayBeforeSwapNV (Display *dpy, GLXDrawable drawable, GLfloat seconds);
#endif
#endif /* GLX_NV_delay_before_swap */
#ifndef GLX_NV_float_buffer
#define GLX_NV_float_buffer 1
#define GLX_FLOAT_COMPONENTS_NV 0x20B0
#endif /* GLX_NV_float_buffer */
#ifndef GLX_NV_multisample_coverage
#define GLX_NV_multisample_coverage 1
#define GLX_COVERAGE_SAMPLES_NV 100001
#define GLX_COLOR_SAMPLES_NV 0x20B3
#endif /* GLX_NV_multisample_coverage */
#ifndef GLX_NV_present_video
#define GLX_NV_present_video 1
#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0
typedef unsigned int *( *PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
typedef int ( *PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
#ifdef GLX_GLXEXT_PROTOTYPES
unsigned int *glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements);
int glXBindVideoDeviceNV (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
#endif
#endif /* GLX_NV_present_video */
#ifndef GLX_NV_robustness_video_memory_purge
#define GLX_NV_robustness_video_memory_purge 1
#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
#endif /* GLX_NV_robustness_video_memory_purge */
#ifndef GLX_NV_swap_group
#define GLX_NV_swap_group 1
typedef Bool ( *PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group);
typedef Bool ( *PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier);
typedef Bool ( *PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
typedef Bool ( *PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
typedef Bool ( *PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count);
typedef Bool ( *PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXJoinSwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint group);
Bool glXBindSwapBarrierNV (Display *dpy, GLuint group, GLuint barrier);
Bool glXQuerySwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
Bool glXQueryMaxSwapGroupsNV (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
Bool glXQueryFrameCountNV (Display *dpy, int screen, GLuint *count);
Bool glXResetFrameCountNV (Display *dpy, int screen);
#endif
#endif /* GLX_NV_swap_group */
#ifndef GLX_NV_video_capture
#define GLX_NV_video_capture 1
typedef XID GLXVideoCaptureDeviceNV;
#define GLX_DEVICE_ID_NV 0x20CD
#define GLX_UNIQUE_ID_NV 0x20CE
#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
typedef int ( *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
typedef GLXVideoCaptureDeviceNV *( *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements);
typedef void ( *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
typedef int ( *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
typedef void ( *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXBindVideoCaptureDeviceNV (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
GLXVideoCaptureDeviceNV *glXEnumerateVideoCaptureDevicesNV (Display *dpy, int screen, int *nelements);
void glXLockVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
int glXQueryVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
void glXReleaseVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
#endif
#endif /* GLX_NV_video_capture */
#ifndef GLX_NV_video_out
#define GLX_NV_video_out 1
typedef unsigned int GLXVideoDeviceNV;
#define GLX_VIDEO_OUT_COLOR_NV 0x20C3
#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4
#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5
#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define GLX_VIDEO_OUT_FRAME_NV 0x20C8
#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9
#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA
#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
typedef int ( *PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
typedef int ( *PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
typedef int ( *PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
typedef int ( *PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf);
typedef int ( *PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
typedef int ( *PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXGetVideoDeviceNV (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
int glXReleaseVideoDeviceNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
int glXBindVideoImageNV (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
int glXReleaseVideoImageNV (Display *dpy, GLXPbuffer pbuf);
int glXSendPbufferToVideoNV (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
int glXGetVideoInfoNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#endif /* GLX_NV_video_out */
#ifndef GLX_OML_swap_method
#define GLX_OML_swap_method 1
#define GLX_SWAP_METHOD_OML 0x8060
#define GLX_SWAP_EXCHANGE_OML 0x8061
#define GLX_SWAP_COPY_OML 0x8062
#define GLX_SWAP_UNDEFINED_OML 0x8063
#endif /* GLX_OML_swap_method */
#ifndef GLX_OML_sync_control
#define GLX_OML_sync_control 1
#ifndef GLEXT_64_TYPES_DEFINED
/* This code block is duplicated in glext.h, so must be protected */
#define GLEXT_64_TYPES_DEFINED
/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
/* (as used in the GLX_OML_sync_control extension). */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
#elif defined(__sun__) || defined(__digital__)
#include <inttypes.h>
#if defined(__STDC__)
#if defined(__arch64__) || defined(_LP64)
typedef long int int64_t;
typedef unsigned long int uint64_t;
#else
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#endif /* __arch64__ */
#endif /* __STDC__ */
#elif defined( __VMS ) || defined(__sgi)
#include <inttypes.h>
#elif defined(__SCO__) || defined(__USLC__)
#include <stdint.h>
#elif defined(__UNIXOS2__) || defined(__SOL64__)
typedef long int int32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#elif defined(_WIN32) && defined(__GNUC__)
#include <stdint.h>
#elif defined(_WIN32)
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
/* Fallback if nothing above works */
#include <inttypes.h>
#endif
#endif
typedef Bool ( *PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
typedef Bool ( *PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
typedef int64_t ( *PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
typedef Bool ( *PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
typedef Bool ( *PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXGetSyncValuesOML (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
Bool glXGetMscRateOML (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
int64_t glXSwapBuffersMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
Bool glXWaitForMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
Bool glXWaitForSbcOML (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
#endif
#endif /* GLX_OML_sync_control */
#ifndef GLX_SGIS_blended_overlay
#define GLX_SGIS_blended_overlay 1
#define GLX_BLENDED_RGBA_SGIS 0x8025
#endif /* GLX_SGIS_blended_overlay */
#ifndef GLX_SGIS_multisample
#define GLX_SGIS_multisample 1
#define GLX_SAMPLE_BUFFERS_SGIS 100000
#define GLX_SAMPLES_SGIS 100001
#endif /* GLX_SGIS_multisample */
#ifndef GLX_SGIS_shared_multisample
#define GLX_SGIS_shared_multisample 1
#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
#endif /* GLX_SGIS_shared_multisample */
#ifndef GLX_SGIX_dmbuffer
#define GLX_SGIX_dmbuffer 1
typedef XID GLXPbufferSGIX;
#ifdef _DM_BUFFER_H_
#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024
typedef Bool ( *PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXAssociateDMPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
#endif
#endif /* _DM_BUFFER_H_ */
#endif /* GLX_SGIX_dmbuffer */
#ifndef GLX_SGIX_fbconfig
#define GLX_SGIX_fbconfig 1
typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
#define GLX_WINDOW_BIT_SGIX 0x00000001
#define GLX_PIXMAP_BIT_SGIX 0x00000002
#define GLX_RGBA_BIT_SGIX 0x00000001
#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002
#define GLX_DRAWABLE_TYPE_SGIX 0x8010
#define GLX_RENDER_TYPE_SGIX 0x8011
#define GLX_X_RENDERABLE_SGIX 0x8012
#define GLX_FBCONFIG_ID_SGIX 0x8013
#define GLX_RGBA_TYPE_SGIX 0x8014
#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015
typedef int ( *PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
typedef GLXFBConfigSGIX *( *PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements);
typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
typedef GLXContext ( *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config);
typedef GLXFBConfigSGIX ( *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXGetFBConfigAttribSGIX (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
GLXFBConfigSGIX *glXChooseFBConfigSGIX (Display *dpy, int screen, int *attrib_list, int *nelements);
GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
GLXContext glXCreateContextWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
XVisualInfo *glXGetVisualFromFBConfigSGIX (Display *dpy, GLXFBConfigSGIX config);
GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *dpy, XVisualInfo *vis);
#endif
#endif /* GLX_SGIX_fbconfig */
#ifndef GLX_SGIX_hyperpipe
#define GLX_SGIX_hyperpipe 1
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int networkId;
} GLXHyperpipeNetworkSGIX;
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int channel;
unsigned int participationType;
int timeSlice;
} GLXHyperpipeConfigSGIX;
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
int destXOrigin, destYOrigin, destWidth, destHeight;
} GLXPipeRect;
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int XOrigin, YOrigin, maxHeight, maxWidth;
} GLXPipeRectLimits;
#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
#define GLX_BAD_HYPERPIPE_SGIX 92
#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
#define GLX_PIPE_RECT_SGIX 0x00000001
#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003
#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
#define GLX_HYPERPIPE_ID_SGIX 0x8030
typedef GLXHyperpipeNetworkSGIX *( *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
typedef int ( *PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
typedef GLXHyperpipeConfigSGIX *( *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
typedef int ( *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
typedef int ( *PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
typedef int ( *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
typedef int ( *PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
typedef int ( *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXHyperpipeNetworkSGIX *glXQueryHyperpipeNetworkSGIX (Display *dpy, int *npipes);
int glXHyperpipeConfigSGIX (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
GLXHyperpipeConfigSGIX *glXQueryHyperpipeConfigSGIX (Display *dpy, int hpId, int *npipes);
int glXDestroyHyperpipeConfigSGIX (Display *dpy, int hpId);
int glXBindHyperpipeSGIX (Display *dpy, int hpId);
int glXQueryHyperpipeBestAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
int glXHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
int glXQueryHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
#endif
#endif /* GLX_SGIX_hyperpipe */
#ifndef GLX_SGIX_pbuffer
#define GLX_SGIX_pbuffer 1
#define GLX_PBUFFER_BIT_SGIX 0x00000004
#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
#define GLX_LARGEST_PBUFFER_SGIX 0x801C
#define GLX_WIDTH_SGIX 0x801D
#define GLX_HEIGHT_SGIX 0x801E
#define GLX_EVENT_MASK_SGIX 0x801F
#define GLX_DAMAGED_SGIX 0x8020
#define GLX_SAVED_SGIX 0x8021
#define GLX_WINDOW_SGIX 0x8022
#define GLX_PBUFFER_SGIX 0x8023
typedef GLXPbufferSGIX ( *PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
typedef void ( *PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf);
typedef int ( *PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
typedef void ( *PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask);
typedef void ( *PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
void glXDestroyGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf);
int glXQueryGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
void glXSelectEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long mask);
void glXGetSelectedEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long *mask);
#endif
#endif /* GLX_SGIX_pbuffer */
#ifndef GLX_SGIX_swap_barrier
#define GLX_SGIX_swap_barrier 1
typedef void ( *PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
typedef Bool ( *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXBindSwapBarrierSGIX (Display *dpy, GLXDrawable drawable, int barrier);
Bool glXQueryMaxSwapBarriersSGIX (Display *dpy, int screen, int *max);
#endif
#endif /* GLX_SGIX_swap_barrier */
#ifndef GLX_SGIX_swap_group
#define GLX_SGIX_swap_group 1
typedef void ( *PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXJoinSwapGroupSGIX (Display *dpy, GLXDrawable drawable, GLXDrawable member);
#endif
#endif /* GLX_SGIX_swap_group */
#ifndef GLX_SGIX_video_resize
#define GLX_SGIX_video_resize 1
#define GLX_SYNC_FRAME_SGIX 0x00000000
#define GLX_SYNC_SWAP_SGIX 0x00000001
typedef int ( *PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window);
typedef int ( *PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h);
typedef int ( *PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
typedef int ( *PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
typedef int ( *PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXBindChannelToWindowSGIX (Display *display, int screen, int channel, Window window);
int glXChannelRectSGIX (Display *display, int screen, int channel, int x, int y, int w, int h);
int glXQueryChannelRectSGIX (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
int glXQueryChannelDeltasSGIX (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
int glXChannelRectSyncSGIX (Display *display, int screen, int channel, GLenum synctype);
#endif
#endif /* GLX_SGIX_video_resize */
#ifndef GLX_SGIX_video_source
#define GLX_SGIX_video_source 1
typedef XID GLXVideoSourceSGIX;
#ifdef _VL_H
typedef GLXVideoSourceSGIX ( *PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
typedef void ( *PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
void glXDestroyGLXVideoSourceSGIX (Display *dpy, GLXVideoSourceSGIX glxvideosource);
#endif
#endif /* _VL_H */
#endif /* GLX_SGIX_video_source */
#ifndef GLX_SGIX_visual_select_group
#define GLX_SGIX_visual_select_group 1
#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
#endif /* GLX_SGIX_visual_select_group */
#ifndef GLX_SGI_cushion
#define GLX_SGI_cushion 1
typedef void ( *PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCushionSGI (Display *dpy, Window window, float cushion);
#endif
#endif /* GLX_SGI_cushion */
#ifndef GLX_SGI_make_current_read
#define GLX_SGI_make_current_read 1
typedef Bool ( *PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXMakeCurrentReadSGI (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
GLXDrawable glXGetCurrentReadDrawableSGI (void);
#endif
#endif /* GLX_SGI_make_current_read */
#ifndef GLX_SGI_swap_control
#define GLX_SGI_swap_control 1
typedef int ( *PFNGLXSWAPINTERVALSGIPROC) (int interval);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXSwapIntervalSGI (int interval);
#endif
#endif /* GLX_SGI_swap_control */
#ifndef GLX_SGI_video_sync
#define GLX_SGI_video_sync 1
typedef int ( *PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count);
typedef int ( *PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXGetVideoSyncSGI (unsigned int *count);
int glXWaitVideoSyncSGI (int divisor, int remainder, unsigned int *count);
#endif
#endif /* GLX_SGI_video_sync */
#ifndef GLX_SUN_get_transparent_index
#define GLX_SUN_get_transparent_index 1
typedef Status ( *PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
#ifdef GLX_GLXEXT_PROTOTYPES
Status glXGetTransparentIndexSUN (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
#endif
#endif /* GLX_SUN_get_transparent_index */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,840 +0,0 @@
#ifndef __wglext_h_
#define __wglext_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 33136 $ on $Date: 2016-09-15 06:33:58 -0400 (Thu, 15 Sep 2016) $
*/
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#define WGL_WGLEXT_VERSION 20160914
/* Generated C header for:
* API: wgl
* Versions considered: .*
* Versions emitted: _nomatch_^
* Default extensions included: wgl
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#ifdef WGL_WGLEXT_PROTOTYPES
HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif
#endif /* WGL_ARB_buffer_region */
#ifndef WGL_ARB_context_flush_control
#define WGL_ARB_context_flush_control 1
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#endif /* WGL_ARB_context_flush_control */
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define ERROR_INVALID_VERSION_ARB 0x2095
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#ifdef WGL_WGLEXT_PROTOTYPES
HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
#endif /* WGL_ARB_create_context */
#ifndef WGL_ARB_create_context_profile
#define WGL_ARB_create_context_profile 1
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define ERROR_INVALID_PROFILE_ARB 0x2096
#endif /* WGL_ARB_create_context_profile */
#ifndef WGL_ARB_create_context_robustness
#define WGL_ARB_create_context_robustness 1
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#endif /* WGL_ARB_create_context_robustness */
#ifndef WGL_ARB_extensions_string
#define WGL_ARB_extensions_string 1
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
#ifdef WGL_WGLEXT_PROTOTYPES
const char *WINAPI wglGetExtensionsStringARB (HDC hdc);
#endif
#endif /* WGL_ARB_extensions_string */
#ifndef WGL_ARB_framebuffer_sRGB
#define WGL_ARB_framebuffer_sRGB 1
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
#endif /* WGL_ARB_framebuffer_sRGB */
#ifndef WGL_ARB_make_current_read
#define WGL_ARB_make_current_read 1
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
HDC WINAPI wglGetCurrentReadDCARB (void);
#endif
#endif /* WGL_ARB_make_current_read */
#ifndef WGL_ARB_multisample
#define WGL_ARB_multisample 1
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif /* WGL_ARB_multisample */
#ifndef WGL_ARB_pbuffer
#define WGL_ARB_pbuffer 1
DECLARE_HANDLE(HPBUFFERARB);
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif
#endif /* WGL_ARB_pbuffer */
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#endif /* WGL_ARB_pixel_format */
#ifndef WGL_ARB_pixel_format_float
#define WGL_ARB_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif /* WGL_ARB_pixel_format_float */
#ifndef WGL_ARB_render_texture
#define WGL_ARB_render_texture 1
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif
#endif /* WGL_ARB_render_texture */
#ifndef WGL_ARB_robustness_application_isolation
#define WGL_ARB_robustness_application_isolation 1
#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
#endif /* WGL_ARB_robustness_application_isolation */
#ifndef WGL_ARB_robustness_share_group_isolation
#define WGL_ARB_robustness_share_group_isolation 1
#endif /* WGL_ARB_robustness_share_group_isolation */
#ifndef WGL_3DFX_multisample
#define WGL_3DFX_multisample 1
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
#define WGL_SAMPLES_3DFX 0x2061
#endif /* WGL_3DFX_multisample */
#ifndef WGL_3DL_stereo_control
#define WGL_3DL_stereo_control 1
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
#endif
#endif /* WGL_3DL_stereo_control */
#ifndef WGL_AMD_gpu_association
#define WGL_AMD_gpu_association 1
#define WGL_GPU_VENDOR_AMD 0x1F00
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define WGL_GPU_RAM_AMD 0x21A3
#define WGL_GPU_CLOCK_AMD 0x21A4
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
#define WGL_GPU_NUM_RB_AMD 0x21A7
#define WGL_GPU_NUM_SPI_AMD 0x21A8
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#ifdef WGL_WGLEXT_PROTOTYPES
UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#endif /* WGL_AMD_gpu_association */
#ifndef WGL_ATI_pixel_format_float
#define WGL_ATI_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#endif /* WGL_ATI_pixel_format_float */
#ifndef WGL_EXT_create_context_es2_profile
#define WGL_EXT_create_context_es2_profile 1
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif /* WGL_EXT_create_context_es2_profile */
#ifndef WGL_EXT_create_context_es_profile
#define WGL_EXT_create_context_es_profile 1
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
#endif /* WGL_EXT_create_context_es_profile */
#ifndef WGL_EXT_depth_float
#define WGL_EXT_depth_float 1
#define WGL_DEPTH_FLOAT_EXT 0x2040
#endif /* WGL_EXT_depth_float */
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
#ifdef WGL_WGLEXT_PROTOTYPES
GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
#endif
#endif /* WGL_EXT_display_color_table */
#ifndef WGL_EXT_extensions_string
#define WGL_EXT_extensions_string 1
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
const char *WINAPI wglGetExtensionsStringEXT (void);
#endif
#endif /* WGL_EXT_extensions_string */
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_EXT_framebuffer_sRGB 1
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif /* WGL_EXT_framebuffer_sRGB */
#ifndef WGL_EXT_make_current_read
#define WGL_EXT_make_current_read 1
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
HDC WINAPI wglGetCurrentReadDCEXT (void);
#endif
#endif /* WGL_EXT_make_current_read */
#ifndef WGL_EXT_multisample
#define WGL_EXT_multisample 1
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
#define WGL_SAMPLES_EXT 0x2042
#endif /* WGL_EXT_multisample */
#ifndef WGL_EXT_pbuffer
#define WGL_EXT_pbuffer 1
DECLARE_HANDLE(HPBUFFEREXT);
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
#define WGL_PBUFFER_LARGEST_EXT 0x2033
#define WGL_PBUFFER_WIDTH_EXT 0x2034
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif
#endif /* WGL_EXT_pbuffer */
#ifndef WGL_EXT_pixel_format
#define WGL_EXT_pixel_format 1
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
#define WGL_ACCELERATION_EXT 0x2003
#define WGL_NEED_PALETTE_EXT 0x2004
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
#define WGL_SWAP_METHOD_EXT 0x2007
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
#define WGL_TRANSPARENT_EXT 0x200A
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
#define WGL_SHARE_DEPTH_EXT 0x200C
#define WGL_SHARE_STENCIL_EXT 0x200D
#define WGL_SHARE_ACCUM_EXT 0x200E
#define WGL_SUPPORT_GDI_EXT 0x200F
#define WGL_SUPPORT_OPENGL_EXT 0x2010
#define WGL_DOUBLE_BUFFER_EXT 0x2011
#define WGL_STEREO_EXT 0x2012
#define WGL_PIXEL_TYPE_EXT 0x2013
#define WGL_COLOR_BITS_EXT 0x2014
#define WGL_RED_BITS_EXT 0x2015
#define WGL_RED_SHIFT_EXT 0x2016
#define WGL_GREEN_BITS_EXT 0x2017
#define WGL_GREEN_SHIFT_EXT 0x2018
#define WGL_BLUE_BITS_EXT 0x2019
#define WGL_BLUE_SHIFT_EXT 0x201A
#define WGL_ALPHA_BITS_EXT 0x201B
#define WGL_ALPHA_SHIFT_EXT 0x201C
#define WGL_ACCUM_BITS_EXT 0x201D
#define WGL_ACCUM_RED_BITS_EXT 0x201E
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
#define WGL_DEPTH_BITS_EXT 0x2022
#define WGL_STENCIL_BITS_EXT 0x2023
#define WGL_AUX_BUFFERS_EXT 0x2024
#define WGL_NO_ACCELERATION_EXT 0x2025
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
#define WGL_FULL_ACCELERATION_EXT 0x2027
#define WGL_SWAP_EXCHANGE_EXT 0x2028
#define WGL_SWAP_COPY_EXT 0x2029
#define WGL_SWAP_UNDEFINED_EXT 0x202A
#define WGL_TYPE_RGBA_EXT 0x202B
#define WGL_TYPE_COLORINDEX_EXT 0x202C
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#endif /* WGL_EXT_pixel_format */
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_EXT_pixel_format_packed_float 1
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
#endif /* WGL_EXT_pixel_format_packed_float */
#ifndef WGL_EXT_swap_control
#define WGL_EXT_swap_control 1
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglSwapIntervalEXT (int interval);
int WINAPI wglGetSwapIntervalEXT (void);
#endif
#endif /* WGL_EXT_swap_control */
#ifndef WGL_EXT_swap_control_tear
#define WGL_EXT_swap_control_tear 1
#endif /* WGL_EXT_swap_control_tear */
#ifndef WGL_I3D_digital_video_control
#define WGL_I3D_digital_video_control 1
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
#endif
#endif /* WGL_I3D_digital_video_control */
#ifndef WGL_I3D_gamma
#define WGL_I3D_gamma 1
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif
#endif /* WGL_I3D_gamma */
#ifndef WGL_I3D_genlock
#define WGL_I3D_genlock 1
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif
#endif /* WGL_I3D_genlock */
#ifndef WGL_I3D_image_buffer
#define WGL_I3D_image_buffer 1
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
#ifdef WGL_WGLEXT_PROTOTYPES
LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
#endif
#endif /* WGL_I3D_image_buffer */
#ifndef WGL_I3D_swap_frame_lock
#define WGL_I3D_swap_frame_lock 1
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnableFrameLockI3D (void);
BOOL WINAPI wglDisableFrameLockI3D (void);
BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
#endif
#endif /* WGL_I3D_swap_frame_lock */
#ifndef WGL_I3D_swap_frame_usage
#define WGL_I3D_swap_frame_usage 1
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
BOOL WINAPI wglBeginFrameTrackingI3D (void);
BOOL WINAPI wglEndFrameTrackingI3D (void);
BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif
#endif /* WGL_I3D_swap_frame_usage */
#ifndef WGL_NV_DX_interop
#define WGL_NV_DX_interop 1
#define WGL_ACCESS_READ_ONLY_NV 0x00000000
#define WGL_ACCESS_READ_WRITE_NV 0x00000001
#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
#endif
#endif /* WGL_NV_DX_interop */
#ifndef WGL_NV_DX_interop2
#define WGL_NV_DX_interop2 1
#endif /* WGL_NV_DX_interop2 */
#ifndef WGL_NV_copy_image
#define WGL_NV_copy_image 1
typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#endif /* WGL_NV_copy_image */
#ifndef WGL_NV_delay_before_swap
#define WGL_NV_delay_before_swap 1
typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds);
#endif
#endif /* WGL_NV_delay_before_swap */
#ifndef WGL_NV_float_buffer
#define WGL_NV_float_buffer 1
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif /* WGL_NV_float_buffer */
#ifndef WGL_NV_gpu_affinity
#define WGL_NV_gpu_affinity 1
DECLARE_HANDLE(HGPUNV);
struct _GPU_DEVICE {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD Flags;
RECT rcVirtualScreen;
};
typedef struct _GPU_DEVICE *PGPU_DEVICE;
#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
BOOL WINAPI wglDeleteDCNV (HDC hdc);
#endif
#endif /* WGL_NV_gpu_affinity */
#ifndef WGL_NV_multisample_coverage
#define WGL_NV_multisample_coverage 1
#define WGL_COVERAGE_SAMPLES_NV 0x2042
#define WGL_COLOR_SAMPLES_NV 0x20B9
#endif /* WGL_NV_multisample_coverage */
#ifndef WGL_NV_present_video
#define WGL_NV_present_video 1
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
#endif
#endif /* WGL_NV_present_video */
#ifndef WGL_NV_render_depth_texture
#define WGL_NV_render_depth_texture 1
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
#define WGL_DEPTH_COMPONENT_NV 0x20A7
#endif /* WGL_NV_render_depth_texture */
#ifndef WGL_NV_render_texture_rectangle
#define WGL_NV_render_texture_rectangle 1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
#endif /* WGL_NV_render_texture_rectangle */
#ifndef WGL_NV_swap_group
#define WGL_NV_swap_group 1
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
BOOL WINAPI wglResetFrameCountNV (HDC hDC);
#endif
#endif /* WGL_NV_swap_group */
#ifndef WGL_NV_vertex_array_range
#define WGL_NV_vertex_array_range 1
typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
#ifdef WGL_WGLEXT_PROTOTYPES
void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
void WINAPI wglFreeMemoryNV (void *pointer);
#endif
#endif /* WGL_NV_vertex_array_range */
#ifndef WGL_NV_video_capture
#define WGL_NV_video_capture 1
DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
#define WGL_UNIQUE_ID_NV 0x20CE
#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#endif
#endif /* WGL_NV_video_capture */
#ifndef WGL_NV_video_output
#define WGL_NV_video_output 1
DECLARE_HANDLE(HPVIDEODEV);
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define WGL_VIDEO_OUT_FRAME 0x20C8
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#endif /* WGL_NV_video_output */
#ifndef WGL_OML_sync_control
#define WGL_OML_sync_control 1
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif
#endif /* WGL_OML_sync_control */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,143 +0,0 @@
/*
* ConsoleManip.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_CONSOLE_MANIP_H
#define XSC_CONSOLE_MANIP_H
#include "Export.h"
#include <ostream>
#include <iostream>
namespace Xsc
{
//! Namespace for console manipulation
namespace ConsoleManip
{
/* ===== Public flags ===== */
//! Output stream color flags enumeration.
struct ColorFlags
{
enum
{
Red = (1 << 0), //!< Red color flag.
Green = (1 << 1), //!< Green color flag.
Blue = (1 << 2), //!< Blue color flag.
Intens = (1 << 3), //!< Intensity color flag.
Black = 0, //!< Black color flag.
Gray = (Red | Green | Blue), //!< Gray color flag (Red | Green | Blue).
White = (Gray | Intens), //!< White color flag (Gray | Intens).
Yellow = (Red | Green | Intens), //!< Yellow color flag (Red | Green | Intens).
Pink = (Red | Blue | Intens), //!< Pink color flag (Red | Blue | Intens).
Cyan = (Green | Blue | Intens), //!< Cyan color flag (Green | Blue | Intens).
};
};
/* ===== Public functions ===== */
//! Enables or disables console manipulation. By default enabled.
void XSC_EXPORT Enable(bool enable);
//! Returns true if console manipulation is enabled.
bool XSC_EXPORT IsEnabled();
/**
\brief Pushes the specified front color flags onto the stack.
\param[in] front Specifies the flags for the front color.
This can be a bitwise OR combination of the flags declared in 'ColorFlags'.
\param[in,out] stream Specifies the output stream whose front color is to be changed.
This output stream is only required for Linux and MacOS, since the colors are specified by the streams itself.
\see ColorFlags
*/
void XSC_EXPORT PushColor(long front, std::ostream& stream = std::cout);
/**
\brief Pushes the specified front and back color flags onto the stack.
\param[in] front Specifies the flags for the front color.
This can be a bitwise OR combination of the flags declared in 'ColorFlags'.
\param[in] back Specifies the flags for the background color.
This can be a bitwise OR combination of the flags declared in 'ColorFlags'.
\param[in,out] stream Specifies the output stream whose front color is to be changed.
This output stream is only required for Linux and MacOS, since the colors are specified by the streams itself.
\see ColorFlags
*/
void XSC_EXPORT PushColor(long front, long back, std::ostream& stream = std::cout);
//! Pops the previous front and back color flags from the stack.
void XSC_EXPORT PopColor(std::ostream& stream = std::cout);
/* ===== Public classes ===== */
//! Helper class for scoped color stack operations.
class ScopedColor
{
public:
/**
\brief Constructor with output stream and front color flags.
\param[in,out] stream Specifies the output stream for which the scope is to be changed. This is only used for Unix systems.
\param[in] front Specifies the front color flags. This can be a bitwise OR combination of the entries of the ColorFlags enumeration.
\see ColorFlags
\see PushColor(long, std::ostream&)
*/
inline ScopedColor(long front, std::ostream& stream = std::cout) :
stream_ { stream }
{
PushColor(front, stream_);
}
/**
\brief Constructor with output stream, and front- and back color flags.
\param[in,out] stream Specifies the output stream for which the scope is to be changed. This is only used for Unix systems.
\param[in] front Specifies the front color flags. This can be a bitwise OR combination of the entries of the ColorFlags enumeration.
\param[in] back Specifies the back color flags. This can be a bitwise OR combination of the entries of the ColorFlags enumeration.
\see ColorFlags
\see PushColor(std::ostream&, long, long)
*/
inline ScopedColor(long front, long back, std::ostream& stream = std::cout) :
stream_ { stream }
{
PushColor(front, back, stream_);
}
/**
\brief Destructor which will reset the previous color from the output stream.
\see PopColor
*/
inline ~ScopedColor()
{
PopColor(stream_);
}
private:
std::ostream& stream_;
};
} // /namespace ConsoleManip
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,27 +0,0 @@
/*
* Export.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_EXPORT_H
#define XSC_EXPORT_H
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#if defined(_MSC_VER) && defined(XSC_SHARED_LIB)
# define XSC_EXPORT __declspec(dllexport)
#else
# define XSC_EXPORT
#endif
#define XSC_THREAD_LOCAL thread_local
#endif
// ================================================================================

View File

@@ -1,57 +0,0 @@
/*
* IncludeHandler.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_INCLUDE_HANDLER_H
#define XSC_INCLUDE_HANDLER_H
#include "Export.h"
#include <string>
#include <istream>
#include <memory>
#include <vector>
namespace Xsc
{
/* ===== Public classes ===== */
/**
\brief Interface for handling new include streams.
\remarks The default implementation will read the files from an std::ifstream.
*/
class XSC_EXPORT IncludeHandler
{
public:
virtual ~IncludeHandler();
/**
\brief Returns an input stream for the specified filename.
\param[in] includeName Specifies the include filename.
\param[in] useSearchPathsFirst Specifies whether to first use the search paths to find the file.
\return Unique pointer to the new input stream.
*/
virtual std::unique_ptr<std::istream> Include(const std::string& filename, bool useSearchPathsFirst);
//! List of search paths.
std::vector<std::string> searchPaths;
};
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,85 +0,0 @@
/*
* IndentHandler.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_INDENT_HANDLER_H
#define XSC_INDENT_HANDLER_H
#include "Export.h"
#include <string>
#include <stack>
namespace Xsc
{
/* ===== Public classes ===== */
//! Indentation handler base class.
class XSC_EXPORT IndentHandler
{
public:
IndentHandler(const std::string& initialIndent = std::string(2, ' '));
//! Sets the next indentation string. By default two spaces.
void SetIndent(const std::string& indent);
//! Increments the indentation.
void IncIndent();
//! Decrements the indentation.
void DecIndent();
//! Returns the current full indentation string.
inline const std::string& FullIndent() const
{
return indentFull_;
}
private:
std::string indent_;
std::string indentFull_;
std::stack<std::string::size_type> indentStack_;
};
//! Helper class for temporary indentation.
class ScopedIndent
{
public:
inline ScopedIndent(IndentHandler& handler) :
handler_ { handler }
{
handler_.IncIndent();
}
inline ~ScopedIndent()
{
handler_.DecIndent();
}
private:
IndentHandler& handler_;
};
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,106 +0,0 @@
/*
* Log.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_LOG_H
#define XSC_LOG_H
#include "IndentHandler.h"
#include "Report.h"
#include <vector>
#include <string>
namespace Xsc
{
/* ===== Public classes ===== */
//! Log base class.
class XSC_EXPORT Log
{
public:
//! Submits the specified report.
virtual void SubmitReport(const Report& report) = 0;
//! Sets the next indentation string. By default two spaces.
inline void SetIndent(const std::string& indent)
{
indentHandler_.SetIndent(indent);
}
//! Increments the indentation.
inline void IncIndent()
{
indentHandler_.IncIndent();
}
//! Decrements the indentation.
inline void DecIndent()
{
indentHandler_.DecIndent();
}
protected:
Log() = default;
//! Returns the current full indentation string.
inline const std::string& FullIndent() const
{
return indentHandler_.FullIndent();
}
private:
IndentHandler indentHandler_;
};
//! Standard output log (uses std::cout to submit a report).
class XSC_EXPORT StdLog : public Log
{
public:
//! Implements the base class interface.
void SubmitReport(const Report& report) override;
//! Prints all submitted reports to the standard output.
void PrintAll(bool verbose = true);
private:
struct IndentReport
{
std::string indent;
Report report;
};
using IndentReportList = std::vector<IndentReport>;
void PrintReport(const IndentReport& r, bool verbose);
void PrintAndClearReports(IndentReportList& reports, bool verbose, const std::string& headline = "");
IndentReportList infos_;
IndentReportList warnings_;
IndentReportList errors_;
};
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,435 +0,0 @@
/*
* Reflection.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_REFLECTION_H
#define XSC_REFLECTION_H
#include "Export.h"
#include <limits>
#include <string>
#include <map>
#include <vector>
#include <ostream>
namespace Xsc
{
//! Shader code reflection namespace
namespace Reflection
{
/* ===== Public enumerations ===== */
//! Sampler filter enumeration (D3D11_FILTER).
enum class Filter
{
MinMagMipPoint = 0,
MinMagPointMipLinear = 0x1,
MinPointMagLinearMipPoint = 0x4,
MinPointMagMipLinear = 0x5,
MinLinearMagMipPoint = 0x10,
MinLinearMagPointMipLinear = 0x11,
MinMagLinearMipPoint = 0x14,
MinMagMipLinear = 0x15,
Anisotropic = 0x55,
ComparisonMinMagMipPoint = 0x80,
ComparisonMinMagPointMipLinear = 0x81,
ComparisonMinPointMagLinearMipPoint = 0x84,
ComparisonMinPointMagMipLinear = 0x85,
ComparisonMinLinearMagMipPoint = 0x90,
ComparisonMinLinearMagPointMipLinear = 0x91,
ComparisonMinMagLinearMipPoint = 0x94,
ComparisonMinMagMipLinear = 0x95,
ComparisonAnisotropic = 0xd5,
MinimumMinMagMipPoint = 0x100,
MinimumMinMagPointMipLinear = 0x101,
MinimumMinPointMagLinearMipPoint = 0x104,
MinimumMinPointMagMipLinear = 0x105,
MinimumMinLinearMagMipPoint = 0x110,
MinimumMinLinearMagPointMipLinear = 0x111,
MinimumMinMagLinearMipPoint = 0x114,
MinimumMinMagMipLinear = 0x115,
MinimumAnisotropic = 0x155,
MaximumMinMagMipPoint = 0x180,
MaximumMinMagPointMipLinear = 0x181,
MaximumMinPointMagLinearMipPoint = 0x184,
MaximumMinPointMagMipLinear = 0x185,
MaximumMinLinearMagMipPoint = 0x190,
MaximumMinLinearMagPointMipLinear = 0x191,
MaximumMinMagLinearMipPoint = 0x194,
MaximumMinMagMipLinear = 0x195,
MaximumAnisotropic = 0x1d5,
};
//! Texture address mode enumeration (D3D11_TEXTURE_ADDRESS_MODE).
enum class TextureAddressMode
{
Wrap = 1,
Mirror = 2,
Clamp = 3,
Border = 4,
MirrorOnce = 5,
};
//! Sample comparison function enumeration (D3D11_COMPARISON_FUNC).
enum class ComparisonFunc
{
Never = 1,
Less = 2,
Equal = 3,
LessEqual = 4,
Greater = 5,
NotEqual = 6,
GreaterEqual = 7,
Always = 8,
};
/* ===== Public structures ===== */
/**
\brief Static sampler state descriptor structure (D3D11_SAMPLER_DESC).
\remarks All members and enumerations have the same values like the one in the "D3D11_SAMPLER_DESC" structure respectively.
Thus, they can all be statically casted from and to the original D3D11 values.
\see https://msdn.microsoft.com/en-us/library/windows/desktop/ff476207(v=vs.85).aspx
*/
struct SamplerState
{
Filter filter = Filter::MinMagMipLinear;
TextureAddressMode addressU = TextureAddressMode::Clamp;
TextureAddressMode addressV = TextureAddressMode::Clamp;
TextureAddressMode addressW = TextureAddressMode::Clamp;
float mipLODBias = 0.0f;
unsigned int maxAnisotropy = 1u;
ComparisonFunc comparisonFunc = ComparisonFunc::Never;
float borderColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float minLOD = -std::numeric_limits<float>::max();
float maxLOD = std::numeric_limits<float>::max();
};
//! Binding slot of textures, constant buffers, and fragment targets.
struct BindingSlot
{
//! Identifier of the binding point.
std::string ident;
//! Zero based binding point or location. If this is -1, the location has not been set.
int location;
};
enum class UniformType
{
Buffer,
UniformBuffer,
Sampler,
Variable,
Struct
};
enum class BufferType
{
Undefined,
Buffer,
StructuredBuffer,
ByteAddressBuffer,
RWBuffer,
RWStructuredBuffer,
RWByteAddressBuffer,
AppendStructuredBuffer,
ConsumeStructuredBuffer,
RWTexture1D,
RWTexture1DArray,
RWTexture2D,
RWTexture2DArray,
RWTexture3D,
Texture1D,
Texture1DArray,
Texture2D,
Texture2DArray,
Texture3D,
TextureCube,
TextureCubeArray,
Texture2DMS,
Texture2DMSArray,
};
enum class DataType
{
Undefined,
// String types,
String,
// Scalar types
Bool,
Int,
UInt,
Half,
Float,
Double,
// Vector types
Bool2,
Bool3,
Bool4,
Int2,
Int3,
Int4,
UInt2,
UInt3,
UInt4,
Half2,
Half3,
Half4,
Float2,
Float3,
Float4,
Double2,
Double3,
Double4,
// Matrix types
Bool2x2,
Bool2x3,
Bool2x4,
Bool3x2,
Bool3x3,
Bool3x4,
Bool4x2,
Bool4x3,
Bool4x4,
Int2x2,
Int2x3,
Int2x4,
Int3x2,
Int3x3,
Int3x4,
Int4x2,
Int4x3,
Int4x4,
UInt2x2,
UInt2x3,
UInt2x4,
UInt3x2,
UInt3x3,
UInt3x4,
UInt4x2,
UInt4x3,
UInt4x4,
Half2x2,
Half2x3,
Half2x4,
Half3x2,
Half3x3,
Half3x4,
Half4x2,
Half4x3,
Half4x4,
Float2x2,
Float2x3,
Float2x4,
Float3x2,
Float3x3,
Float3x4,
Float4x2,
Float4x3,
Float4x4,
Double2x2,
Double2x3,
Double2x4,
Double3x2,
Double3x3,
Double3x4,
Double4x2,
Double4x3,
Double4x4,
};
enum class VarType
{
Undefined,
Void,
// Scalar types
Bool,
Int,
UInt,
Half,
Float,
Double,
// Vector types
Bool2,
Bool3,
Bool4,
Int2,
Int3,
Int4,
UInt2,
UInt3,
UInt4,
Half2,
Half3,
Half4,
Float2,
Float3,
Float4,
Double2,
Double3,
Double4,
// Matrix types
Bool2x2,
Bool2x3,
Bool2x4,
Bool3x2,
Bool3x3,
Bool3x4,
Bool4x2,
Bool4x3,
Bool4x4,
Int2x2,
Int2x3,
Int2x4,
Int3x2,
Int3x3,
Int3x4,
Int4x2,
Int4x3,
Int4x4,
UInt2x2,
UInt2x3,
UInt2x4,
UInt3x2,
UInt3x3,
UInt3x4,
UInt4x2,
UInt4x3,
UInt4x4,
Half2x2,
Half2x3,
Half2x4,
Half3x2,
Half3x3,
Half3x4,
Half4x2,
Half4x3,
Half4x4,
Float2x2,
Float2x3,
Float2x4,
Float3x2,
Float3x3,
Float3x4,
Float4x2,
Float4x3,
Float4x4,
Double2x2,
Double2x3,
Double2x4,
Double3x2,
Double3x3,
Double3x4,
Double4x2,
Double4x3,
Double4x4,
};
//! A single element in a constant buffer or an opaque type
struct Uniform
{
//! Identifier of the element.
std::string ident;
//! Data type of the element.
UniformType type = UniformType::Variable;
//! Determines actual type of the element. Contents depend on "type".
int baseType = 0;
//! Index of the uniform block this uniform belongs to. -1 if none.
int uniformBlock = -1;
};
//! Number of threads within each work group of a compute shader.
struct NumThreads
{
//! Number of shader compute threads in X dimension.
int x = 0;
//! Number of shader compute threads in Y dimension.
int y = 0;
//! Number of shader compute threads in Z dimension.
int z = 0;
};
//! Structure for shader output statistics (e.g. texture/buffer binding points).
struct ReflectionData
{
//! All defined macros after pre-processing.
std::vector<std::string> macros;
//! Single shader uniforms.
std::vector<Uniform> uniforms;
//! Texture bindings.
std::vector<BindingSlot> textures;
//! Storage buffer bindings.
std::vector<BindingSlot> storageBuffers;
//! Constant buffer bindings.
std::vector<BindingSlot> constantBuffers;
//! Shader input attributes.
std::vector<BindingSlot> inputAttributes;
//! Shader output attributes.
std::vector<BindingSlot> outputAttributes;
//! Static sampler states (identifier, states).
std::map<std::string, SamplerState> samplerStates;
//! Number of local threads in a compute shader.
NumThreads numThreads;
};
} // /namespace Reflection
/* ===== Public functions ===== */
//! Returns the string representation of the specified 'SamplerState::Filter' type.
XSC_EXPORT std::string ToString(const Reflection::Filter t);
//! Returns the string representation of the specified 'SamplerState::TextureAddressMode' type.
XSC_EXPORT std::string ToString(const Reflection::TextureAddressMode t);
//! Returns the string representation of the specified 'SamplerState::ComparisonFunc' type.
XSC_EXPORT std::string ToString(const Reflection::ComparisonFunc t);
//! Prints the reflection data into the output stream in a human readable format.
XSC_EXPORT void PrintReflection(std::ostream& stream, const Reflection::ReflectionData& reflectionData);
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,113 +0,0 @@
/*
* Report.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_REPORT_H
#define XSC_REPORT_H
#include "Export.h"
#include <stdexcept>
#include <string>
#include <vector>
namespace Xsc
{
//! Report types enumeration.
enum class ReportTypes
{
Info, //!< Standard information.
Warning, //!< Warning message.
Error //!< Error message.
};
//! Report exception class which contains a completely constructed message with optional line marker, hints, and context description.
class XSC_EXPORT Report : public std::exception
{
public:
Report(const Report&) = default;
Report& operator = (const Report&) = default;
Report(const ReportTypes type, const std::string& message, const std::string& context = "");
Report(const ReportTypes type, const std::string& message, const std::string& line, const std::string& marker, const std::string& context = "");
//! Overrides the 'std::exception::what' function.
const char* what() const throw() override;
//! Moves the specified hints into this report.
void TakeHints(std::vector<std::string>&& hints);
//! Returns the type of this report.
inline ReportTypes Type() const
{
return type_;
}
//! Returns the context description string (e.g. a function name where the report occured). This may also be empty.
inline const std::string& Context() const
{
return context_;
}
//! Returns the message string.
inline const std::string& Message() const
{
return message_;
}
//! Returns the line string where the report occured. This line never has new-line characters at its end.
inline const std::string& Line() const
{
return line_;
}
//! Returns the line marker string to highlight the area where the report occured.
inline const std::string& Marker() const
{
return marker_;
}
//! Returns the list of optional hints of the report.
inline const std::vector<std::string>& GetHints() const
{
return hints_;
}
/**
\brief Returns true if this report has a line with line marker.
\see Line
\see Marker
*/
inline bool HasLine() const
{
return (!line_.empty());
}
private:
ReportTypes type_ = ReportTypes::Info;
std::string context_;
std::string message_;
std::string line_;
std::string marker_;
std::vector<std::string> hints_;
};
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,126 +0,0 @@
/*
* Targets.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_TARGETS_H
#define XSC_TARGETS_H
#include "Export.h"
#include <string>
#include <map>
namespace Xsc
{
/* ===== Public enumerations ===== */
//! Shader target enumeration.
enum class ShaderTarget
{
Undefined, //!< Undefined shader target.
VertexShader, //!< Vertex shader.
TessellationControlShader, //!< Tessellation-control (also Hull-) shader.
TessellationEvaluationShader, //!< Tessellation-evaluation (also Domain-) shader.
GeometryShader, //!< Geometry shader.
FragmentShader, //!< Fragment (also Pixel-) shader.
ComputeShader, //!< Compute shader.
};
//! Input shader version enumeration.
enum class InputShaderVersion
{
Cg = 2, //!< Cg (C for graphics) is a slightly extended HLSL3.
HLSL3 = 3, //!< HLSL Shader Model 3.0 (DirectX 9).
HLSL4 = 4, //!< HLSL Shader Model 4.0 (DirectX 10).
HLSL5 = 5, //!< HLSL Shader Model 5.0 (DirectX 11).
HLSL6 = 6, //!< HLSL Shader Model 6.0 (DirectX 12).
GLSL = 0x0000ffff, //!< GLSL (OpenGL).
ESSL = 0x0001ffff, //!< GLSL (OpenGL ES).
VKSL = 0x0002ffff, //!< GLSL (Vulkan).
};
//! Output shader version enumeration.
enum class OutputShaderVersion
{
GLSL110 = 110, //!< GLSL 1.10 (OpenGL 2.0).
GLSL120 = 120, //!< GLSL 1.20 (OpenGL 2.1).
GLSL130 = 130, //!< GLSL 1.30 (OpenGL 3.0).
GLSL140 = 140, //!< GLSL 1.40 (OpenGL 3.1).
GLSL150 = 150, //!< GLSL 1.50 (OpenGL 3.2).
GLSL330 = 330, //!< GLSL 3.30 (OpenGL 3.3).
GLSL400 = 400, //!< GLSL 4.00 (OpenGL 4.0).
GLSL410 = 410, //!< GLSL 4.10 (OpenGL 4.1).
GLSL420 = 420, //!< GLSL 4.20 (OpenGL 4.2).
GLSL430 = 430, //!< GLSL 4.30 (OpenGL 4.3).
GLSL440 = 440, //!< GLSL 4.40 (OpenGL 4.4).
GLSL450 = 450, //!< GLSL 4.50 (OpenGL 4.5).
GLSL460 = 460, //!< GLSL 4.60 (OpenGL 4.6).
GLSL = 0x0000ffff, //!< Auto-detect minimal required GLSL version (for OpenGL 2+).
ESSL100 = (0x00010000 + 100), //!< ESSL 1.00 (OpenGL ES 2.0). \note Currently not supported!
ESSL300 = (0x00010000 + 300), //!< ESSL 3.00 (OpenGL ES 3.0). \note Currently not supported!
ESSL310 = (0x00010000 + 310), //!< ESSL 3.10 (OpenGL ES 3.1). \note Currently not supported!
ESSL320 = (0x00010000 + 320), //!< ESSL 3.20 (OpenGL ES 3.2). \note Currently not supported!
ESSL = 0x0001ffff, //!< Auto-detect minimum required ESSL version (for OpenGL ES 2+). \note Currently not supported!
VKSL450 = (0x00020000 + 450), //!< VKSL 4.50 (Vulkan 1.0).
VKSL = 0x0002ffff, //!< Auto-detect minimum required VKSL version (for Vulkan/SPIR-V).
};
//! Intermediate language enumeration.
enum class IntermediateLanguage
{
SPIRV, //!< SPIR-V.
};
/* ===== Public functions ===== */
//! Returns the specified shader target as string.
XSC_EXPORT std::string ToString(const ShaderTarget target);
//! Returns the specified shader input version as string.
XSC_EXPORT std::string ToString(const InputShaderVersion shaderVersion);
//! Returns the specified shader output version as string.
XSC_EXPORT std::string ToString(const OutputShaderVersion shaderVersion);
//! Returns the specified intermediate language as string.
XSC_EXPORT std::string ToString(const IntermediateLanguage language);
//! Returns true if the shader input version specifies HLSL (for DirectX) or Cg (handled as dialect or HLSL).
XSC_EXPORT bool IsLanguageHLSL(const InputShaderVersion shaderVersion);
//! Returns true if the shader input version specifies GLSL (for OpenGL, OpenGL ES, and Vulkan).
XSC_EXPORT bool IsLanguageGLSL(const InputShaderVersion shaderVersion);
//! Returns true if the shader output version specifies GLSL (for OpenGL 2+).
XSC_EXPORT bool IsLanguageGLSL(const OutputShaderVersion shaderVersion);
//! Returns true if the shader output version specifies ESSL (for OpenGL ES 2+).
XSC_EXPORT bool IsLanguageESSL(const OutputShaderVersion shaderVersion);
//! Returns true if the shader output version specifies VKSL (for Vulkan).
XSC_EXPORT bool IsLanguageVKSL(const OutputShaderVersion shaderVersion);
//! Returns the enumeration of all supported GLSL extensions as a map of extension name and version number.
XSC_EXPORT const std::map<std::string, int>& GetGLSLExtensionEnumeration();
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,28 +0,0 @@
/*
* Version.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_VERSION_H
#define XSC_VERSION_H
/* ===== Public macros ===== */
//! Xsc major version number.
#define XSC_VERSION_MAJOR 0
//! Xsc minor version number.
#define XSC_VERSION_MINOR 10
//! Xsc version string in the form "X.YZ", where X is the major version, and YZ is the minor version.
#define XSC_VERSION_STRING "0.10 Alpha"
#endif
// ================================================================================

View File

@@ -1,397 +0,0 @@
/*
* Xsc.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_XSC_H
#define XSC_XSC_H
#include "Export.h"
#include "Log.h"
#include "IncludeHandler.h"
#include "Targets.h"
#include "Version.h"
#include "Reflection.h"
#include <string>
#include <vector>
#include <map>
#include <istream>
#include <ostream>
#include <memory>
/**
\mainpage
Welcome to the XShaderCompiler, Version 0.10 Alpha
Here is a quick start example:
\code
#include <Xsc/Xsc.h>
#include <fstream>
int main()
{
// Open input and output streams
auto inputStream = std::make_shared<std::ifstream>("Example.hlsl");
std::ofstream outputStream("Example.VS.vert");
// Initialize shader input descriptor structure
Xsc::ShaderInput inputDesc;
{
inputDesc.sourceCode = inputStream;
inputDesc.shaderVersion = Xsc::InputShaderVersion::HLSL5;
inputDesc.entryPoint = "VS";
inputDesc.shaderTarget = Xsc::ShaderTarget::VertexShader;
}
// Initialize shader output descriptor structure
Xsc::ShaderOutput outputDesc;
{
outputDesc.sourceCode = &outputStream;
outputDesc.shaderVersion = Xsc::OutputShaderVersion::GLSL330;
}
// Compile HLSL code into GLSL
Xsc::StdLog log;
bool result = Xsc::CompileShader(inputDesc, outputDesc, &log);
// Show compilation status
if (result)
std::cout << "Compilation successful" << std::endl;
else
std::cerr << "Compilation failed" << std::endl;
return 0;
}
\endcode
*/
//! Main XShaderCompiler namespace
namespace Xsc
{
/* ===== Public structures ===== */
//! Compiler warning flags.
struct Warnings
{
enum : unsigned int
{
Basic = (1 << 0), //!< Warning for basic issues (control path, disabled code etc.).
Syntax = (1 << 1), //!< Warning for syntactic issues.
PreProcessor = (1 << 2), //!< Warning for pre-processor issues.
UnusedVariables = (1 << 3), //!< Warning for unused variables.
EmptyStatementBody = (1 << 4), //!< Warning for statements with empty body.
ImplicitTypeConversions = (1 << 5), //!< Warning for specific implicit type conversions.
DeclarationShadowing = (1 << 6), //!< Warning for declarations that shadow a previous local (e.g. for-loops or variables in class hierarchy).
UnlocatedObjects = (1 << 7), //!< Warning for optional objects that where not found.
RequiredExtensions = (1 << 8), //!< Warning for required extensions in the output code.
CodeReflection = (1 << 9), //!< Warning for issues during code reflection.
IndexBoundary = (1 << 10), //!< Warning for index boundary violations.
All = (~0u), //!< All warnings.
};
};
/**
\brief Language extension flags.
\remakrs This is only supported, if the compiler was build with the 'XSC_ENABLE_LANGUAGE_EXT' macro.
*/
struct Extensions
{
enum : unsigned int
{
LayoutAttribute = (1 << 0), //!< Enables the 'layout' attribute extension (e.g. "[layout(rgba8)]").
SpaceAttribute = (1 << 1), //!< Enables the 'space' attribute extension for a stronger type system (e.g. "[space(OBJECT, MODEL)]").
All = (~0u) //!< All extensions.
};
};
//! Formatting descriptor structure for the output shader.
struct Formatting
{
//! If true, scopes are always written in braces. By default false.
bool alwaysBracedScopes = false;
//! If true, blank lines are allowed. By default true.
bool blanks = true;
//! If true, wrapper functions for special intrinsics are written in a compact formatting (i.e. all in one line). By default false.
bool compactWrappers = false;
//! Indentation string for code generation. By default std::string(4, ' ').
std::string indent = " ";
//! If true, line marks are allowed. By default false.
bool lineMarks = false;
//! If true, auto-formatting of line separation is allowed. By default true.
bool lineSeparation = true;
//! If true, the '{'-braces for an open scope gets its own line. If false, braces are written like in Java coding conventions. By default true.
bool newLineOpenScope = true;
//! If true, the generator header comment with metadata will be added on top of the output shader source. If false, no header comment will be added. By default true.
bool writeGeneratorHeader = true;
};
//! Structure for additional translation options.
struct Options
{
//! If true, the shader output may contain GLSL extensions, if the target shader version is too low. By default false.
bool allowExtensions = false;
/**
\brief If true, binding slots for all buffer types will be generated sequentially, starting with index at 'autoBindingStartSlot'. By default false.
\remarks This will also enable 'explicitBinding'.
*/
bool autoBinding = false;
//! Index to start generating binding slots from. Only relevant if 'autoBinding' is enabled. By default 0.
int autoBindingStartSlot = 0;
//! If true, explicit binding slots are enabled. By default false.
bool explicitBinding = false;
//! If true, code obfuscation is performed. By default false.
bool obfuscate = false;
//! If true, little code optimizations are performed. By default false.
bool optimize = false;
//TODO: maybe merge this option with "optimize" (preferWrappers == !optimize)
//! If true, intrinsics are prefered to be implemented as wrappers (instead of inlining). By default false.
bool preferWrappers = false;
//! If true, only the preprocessed source code will be written out. By default false.
bool preprocessOnly = false;
//! If true, commentaries are preserved for each statement. By default false.
bool preserveComments = false;
//! If true, matrices have row-major alignment. Otherwise the matrices have column-major alignment. By default false.
bool rowMajorAlignment = false;
//! If true, generated GLSL code will contain separate sampler and texture objects when supported. By default true.
bool separateSamplers = true;
//! If true, generated GLSL code will support the 'ARB_separate_shader_objects' extension. By default false.
bool separateShaders = false;
//! If true, the AST (Abstract Syntax Tree) will be written to the log output. By default false.
bool showAST = false;
//! If true, the timings of the different compilation processes are written to the log output. By default false.
bool showTimes = false;
//TODO: remove this option, and determine automatically when unrolling initializers are required!
//! If true, array initializations will be unrolled. By default false.
bool unrollArrayInitializers = false;
//! If true, the source code is only validated, but no output code will be generated. By default false.
bool validateOnly = false;
};
//! Name mangling descriptor structure for shader input/output variables (also referred to as "varyings"), temporary variables, and reserved keywords.
struct NameMangling
{
/**
\brief Name mangling prefix for shader input variables. By default "xsv_".
\remarks This can also be empty or equal to "outputPrefix".
*/
std::string inputPrefix = "xsv_";
/**
\brief Name mangling prefix for shader output variables. By default "xsv_".
\remarks This can also be empty or equal to "inputPrefix".
*/
std::string outputPrefix = "xsv_";
/**
\brief Name mangling prefix for reserved words (such as "texture", "main", "sin" etc.). By default "xsr_".
\remarks This must not be equal to any of the other prefixes and it must not be empty.
*/
std::string reservedWordPrefix = "xsr_";
/**
\brief Name mangling prefix for temporary variables. By default "xst_".
\remarks This must not be equal to any of the other prefixes and it must not be empty.
*/
std::string temporaryPrefix = "xst_";
/**
\brief Name mangling prefix for namespaces like structures or classes. By default "xsn_".
\remarks This can also be empty, but if it's not empty it must not be equal to any of the other prefixes.
*/
std::string namespacePrefix = "xsn_";
/**
If true, shader input/output variables are always renamed to their semantics,
even for vertex input and fragment output. Otherwise, their original identifiers are used. By default false.
*/
bool useAlwaysSemantics = false;
/**
\brief If true, the data fields of a 'buffer'-objects is renamed rather than the outer identifier. By default false.
\remarks This can be useful for external diagnostic tools, to access the original identifier.
*/
bool renameBufferFields = false;
};
//! Shader input descriptor structure.
struct ShaderInput
{
//! Specifies the filename of the input shader code. This is an optional attribute, and only a hint to the compiler.
std::string filename;
//! Specifies the input source code stream.
std::shared_ptr<std::istream> sourceCode;
//! Specifies the input shader version (e.g. InputShaderVersion::HLSL5 for "HLSL 5"). By default InputShaderVersion::HLSL5.
InputShaderVersion shaderVersion = InputShaderVersion::HLSL5;
//! Specifies the target shader (Vertex, Fragment etc.). By default ShaderTarget::Undefined.
ShaderTarget shaderTarget = ShaderTarget::Undefined;
//! Specifies the HLSL shader entry point. By default "main".
std::string entryPoint = "main";
/**
\brief Specifies the secondary HLSL shader entry point.
\remarks This is only used for a Tessellation-Control Shader (alias Hull Shader) entry point,
when a Tessellation-Control Shader (alias Domain Shader) is the output target.
This is required to translate all Tessellation-Control attributes (i.e. "partitioning" and "outputtopology")
to the Tessellation-Evaluation output shader. If this is empty, the default values for these attributes are used.
*/
std::string secondaryEntryPoint;
/**
\brief Compiler warning flags. This can be a bitwise OR combination of the "Warnings" enumeration entries. By default 0.
\see Warnings
*/
unsigned int warnings = 0;
/**
\brief Language extension flags. This can be a bitwise OR combination of the "Extensions" enumeration entries. By default 0.
\remarks This is ignored, if the compiler was not build with the 'XSC_ENABLE_LANGUAGE_EXT' macro.
\see Extensions
*/
unsigned int extensions = 0;
/**
\brief Optional pointer to the implementation of the "IncludeHandler" interface. By default null.
\remarks If this is null, the default include handler will be used, which will include files with the STL input file streams.
*/
IncludeHandler* includeHandler = nullptr;
};
//! Vertex shader semantic (or rather attribute) layout structure.
struct VertexSemantic
{
//! Specifies the shader semantic (or rather attribute).
std::string semantic;
//! Specifies the binding location.
int location;
};
//! Shader output descriptor structure.
struct ShaderOutput
{
//! Specifies the filename of the output shader code. This is an optional attribute, and only a hint to the compiler.
std::string filename;
//! Specifies the output source code stream. This will contain the output code. This must not be null when passed to the "CompileShader" function!
std::ostream* sourceCode = nullptr;
//! Specifies the output shader version. By default OutputShaderVersion::GLSL (to auto-detect minimum required version).
OutputShaderVersion shaderVersion = OutputShaderVersion::GLSL;
//! Optional list of vertex semantic layouts, to bind a vertex attribute (semantic name) to a location index (only used when 'explicitBinding' is true).
std::vector<VertexSemantic> vertexSemantics;
//! Additional options to configure the code generation.
Options options;
//! Output code formatting descriptor.
Formatting formatting;
//! Specifies the options for name mangling.
NameMangling nameMangling;
};
//! Descriptor structure for the shader disassembler.
struct AssemblyDescriptor
{
//! Specifies the intermediate language of the assembly input code. Currently only SPIR-V is supported. By default IntermediateLanguage::SPIRV.
IntermediateLanguage intermediateLanguage = IntermediateLanguage::SPIRV;
//! Specifies the prefix character to be used for ID numbers in the SPIR-V instructions.
char idPrefixChar = '%';
//! Specifies whether to show the module header or not. By default true.
bool showHeader = true;
//! Specifies whether to show the instruction byte offsets in the disassembly or not. By default true.
bool showOffsets = true;
//! Specifies whether to show the debug names instead of the ID numbers. By default false.
bool showNames = false;
//! Specifies whether to indent the instruction operands or not. By default true.
bool indentOperands = true;
};
/* ===== Public functions ===== */
/**
\brief Cross compiles the shader code from the specified input stream into the specified output shader code.
\param[in] inputDesc Input shader code descriptor.
\param[in] outputDesc Output shader code descriptor.
\param[in] log Optional pointer to an output log. Inherit from the "Log" class interface. By default null.
\param[out] reflectionData Optional pointer to a code reflection data structure. By default null.
\return True if the code has been translated successfully.
\throw std::invalid_argument If either the input or output streams are null.
\see ShaderInput
\see ShaderOutput
\see Log
\see ReflectionData
*/
XSC_EXPORT bool CompileShader(
const ShaderInput& inputDesc,
const ShaderOutput& outputDesc,
Log* log = nullptr,
Reflection::ReflectionData* reflectionData = nullptr
);
/**
\brief Disassembles the SPIR-V binary code into a human readable code.
\param[in,out] streamIn Specifies the input stream of the SPIR-V binary code.
\param[in,out] streamOut Specifies the output stream of the human readable code.
\param[in] formatting Specifies the output formatting.
\throws std::runtime_error If the disassembling failed.
\throws std::invalid_argument If 'desc.intermediateLanguage' has an invalid value.
*/
XSC_EXPORT void DisassembleShader(
std::istream& streamIn,
std::ostream& streamOut,
const AssemblyDescriptor& desc = {}
);
} // /namespace Xsc
#endif
// ================================================================================

View File

@@ -1,47 +0,0 @@
/*
* IncludeHandlerC.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_INCLUDE_HANDLER_C_H
#define XSC_INCLUDE_HANDLER_C_H
#ifdef __cplusplus
extern "C" {
#endif
/**
\brief Function callback interface for handling '#include'-directives.
\param[in] filename Specifies the include filename.
\param[in] searchPaths Specifies an array of include paths. The last entry in this array is NULL.
\param[in] useSearchPathsFirst Specifies whether search paths are to be used first, to find the include file.
\return Pointer to the source code of the included file, or NULL to ignore this include directive.
*/
typedef const char* (*XSC_PFN_HANDLE_INCLUDE)(const char* filename, const char** searchPaths, bool useSearchPathsFirst);
//! Include handler structure.
struct XscIncludeHandler
{
//! Function pointer to handle the '#include'-directives.
XSC_PFN_HANDLE_INCLUDE handleIncludePfn;
//! Pointer to an array of search paths. This must be either NULL, point to an array where the last entry is always NULL.
const char** searchPaths;
};
#ifdef __cplusplus
} // /extern "C"
#endif
#endif
// ================================================================================

View File

@@ -1,50 +0,0 @@
/*
* LogC.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_LOG_C_H
#define XSC_LOG_C_H
#include "ReportC.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
\brief Function callback interface for handling reports.
\param[in] report Specifies the compiler report.
\param[in] indent Specifies the current indentation string.
*/
typedef void (*XSC_PFN_HANDLE_REPORT)(const struct XscReport* report, const char* indent);
//! Output log structure.
struct XscLog
{
//! Function pointer to handle compiler reports.
XSC_PFN_HANDLE_REPORT handleReportPfn;
};
//! Default log.
#define XSC_DEFAULT_LOG ((const struct XscLog*)(1))
#ifdef __cplusplus
} // /extern "C"
#endif
#endif
// ================================================================================

View File

@@ -1,199 +0,0 @@
/*
* ReflectionC.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_REFLECTION_C_H
#define XSC_REFLECTION_C_H
#include <Xsc/Export.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
//! Sampler filter enumeration (D3D11_FILTER).
enum XscFilter
{
XscEFilterMinMagMipPoint = 0,
XscEFilterMinMagPointMipLinear = 0x1,
XscEFilterMinPointMagLinearMipPoint = 0x4,
XscEFilterMinPointMagMipLinear = 0x5,
XscEFilterMinLinearMagMipPoint = 0x10,
XscEFilterMinLinearMagPointMipLinear = 0x11,
XscEFilterMinMagLinearMipPoint = 0x14,
XscEFilterMinMagMipLinear = 0x15,
XscEFilterAnisotropic = 0x55,
XscEFilterComparisonMinMagMipPoint = 0x80,
XscEFilterComparisonMinMagPointMipLinear = 0x81,
XscEFilterComparisonMinPointMagLinearMipPoint = 0x84,
XscEFilterComparisonMinPointMagMipLinear = 0x85,
XscEFilterComparisonMinLinearMagMipPoint = 0x90,
XscEFilterComparisonMinLinearMagPointMipLinear = 0x91,
XscEFilterComparisonMinMagLinearMipPoint = 0x94,
XscEFilterComparisonMinMagMipLinear = 0x95,
XscEFilterComparisonAnisotropic = 0xd5,
XscEFilterMinimumMinMagMipPoint = 0x100,
XscEFilterMinimumMinMagPointMipLinear = 0x101,
XscEFilterMinimumMinPointMagLinearMipPoint = 0x104,
XscEFilterMinimumMinPointMagMipLinear = 0x105,
XscEFilterMinimumMinLinearMagMipPoint = 0x110,
XscEFilterMinimumMinLinearMagPointMipLinear = 0x111,
XscEFilterMinimumMinMagLinearMipPoint = 0x114,
XscEFilterMinimumMinMagMipLinear = 0x115,
XscEFilterMinimumAnisotropic = 0x155,
XscEFilterMaximumMinMagMipPoint = 0x180,
XscEFilterMaximumMinMagPointMipLinear = 0x181,
XscEFilterMaximumMinPointMagLinearMipPoint = 0x184,
XscEFilterMaximumMinPointMagMipLinear = 0x185,
XscEFilterMaximumMinLinearMagMipPoint = 0x190,
XscEFilterMaximumMinLinearMagPointMipLinear = 0x191,
XscEFilterMaximumMinMagLinearMipPoint = 0x194,
XscEFilterMaximumMinMagMipLinear = 0x195,
XscEFilterMaximumAnisotropic = 0x1d5,
};
//! Texture address mode enumeration (D3D11_TEXTURE_ADDRESS_MODE).
enum XscTextureAddressMode
{
XscEAddressWrap = 1,
XscEAddressMirror = 2,
XscEAddressClamp = 3,
XscEAddressBorder = 4,
XscEAddressMirrorOnce = 5,
};
//! Sample comparison function enumeration (D3D11_COMPARISON_FUNC).
enum XscComparisonFunc
{
XscEComparisonNever = 1,
XscEComparisonLess = 2,
XscEComparisonEqual = 3,
XscEComparisonLessEqual = 4,
XscEComparisonGreater = 5,
XscEComparisonNotEqual = 6,
XscEComparisonGreaterEqual = 7,
XscEComparisonAlways = 8,
};
/**
\brief Static sampler state descriptor structure (D3D11_SAMPLER_DESC).
\remarks All members and enumerations have the same values like the one in the "D3D11_SAMPLER_DESC" structure respectively.
Thus, they can all be statically casted from and to the original D3D11 values.
\see https://msdn.microsoft.com/en-us/library/windows/desktop/ff476207(v=vs.85).aspx
*/
struct XscSamplerState
{
const char* ident;
enum XscFilter filter;
enum XscTextureAddressMode addressU;
enum XscTextureAddressMode addressV;
enum XscTextureAddressMode addressW;
float mipLODBias;
unsigned int maxAnisotropy;
enum XscComparisonFunc comparisonFunc;
float borderColor[4];
float minLOD;
float maxLOD;
};
//! Binding slot of textures, constant buffers, and fragment targets.
struct XscBindingSlot
{
//! Identifier of the binding point.
const char* ident;
//! Zero based binding point or location. If this is -1, the location has not been set explicitly.
int location;
};
//! Number of threads within each work group of a compute shader.
struct XscNumThreads
{
int x;
int y;
int z;
};
//! Structure for shader output statistics (e.g. texture/buffer binding points).
struct XscReflectionData
{
//! All defined macros after pre-processing.
const char** macros;
//! Number of elements in 'macros'.
size_t macrosCount;
//! Single shader uniforms.
const char** uniforms;
//! Number of elements in 'uniforms'.
size_t uniformsCount;
//! Texture bindings.
const struct XscBindingSlot* textures;
//! Number of elements in 'textures'.
size_t texturesCount;
//! Storage buffer bindings.
const struct XscBindingSlot* storageBuffers;
//! Number of elements in 'storageBuffers'.
size_t storageBuffersCount;
//! Constant buffer bindings.
const struct XscBindingSlot* constantBuffers;
//! Number of elements in 'constantBuffers'.
size_t constantBufferCounts;
//! Shader input attributes.
const struct XscBindingSlot* inputAttributes;
//! Number of elements in 'inputAttributes'.
size_t inputAttributesCount;
//! Shader output attributes.
const struct XscBindingSlot* outputAttributes;
//! Number of elements in 'outputAttributes'.
size_t outputAttributesCount;
//! Static sampler states (identifier, states).
const struct XscSamplerState* samplerStates;
//! Number of elements in 'samplerStates'.
size_t samplerStatesCount;
//! 'numthreads' attribute of a compute shader.
struct XscNumThreads numThreads;
};
//! Returns the string representation of the specified 'SamplerState::Filter' type.
XSC_EXPORT void XscFilterToString(const enum XscFilter t, char* str, size_t maxSize);
//! Returns the string representation of the specified 'SamplerState::TextureAddressMode' type.
XSC_EXPORT void XscTextureAddressModeToString(const enum XscTextureAddressMode t, char* str, size_t maxSize);
//! Returns the string representation of the specified 'SamplerState::ComparisonFunc' type.
XSC_EXPORT void XscComparisonFuncToString(const enum XscComparisonFunc t, char* str, size_t maxSize);
#ifdef __cplusplus
} // /extern "C"
#endif
#endif
// ================================================================================

View File

@@ -1,60 +0,0 @@
/*
* ReportC.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_REPORT_C_H
#define XSC_REPORT_C_H
#ifdef __cplusplus
extern "C" {
#endif
//! Report types enumeration.
enum XscReportType
{
XscEReportInfo, //!< Standard information.
XscEReportWarning, //!< Warning message.
XscEReportError, //!< Error message.
};
//! Report structure for warning and error messages.
struct XscReport
{
//! Specifies the report type.
enum XscReportType type;
//! Specifies the context description string (e.g. a function name where the report occured). This may also be NULL.
const char* context;
//! Specifies the message string.
const char* message;
//! Specifies the line string where the report occured. This line never has new-line characters at its end. This may also be NULL.
const char* line;
//! Specifies the line marker string to highlight the area where the report occured. This may also be NULL.
const char* marker;
//! Specifies the list of optional hints of the report. This may also be NULL.
const char** hints;
//! Specifies the number of hints. If 'hints' is NULL, this is 0.
size_t hintsCount;
};
#ifdef __cplusplus
} // /extern "C"
#endif
#endif
// ================================================================================

View File

@@ -1,139 +0,0 @@
/*
* TargetsC.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_TARGETS_C_H
#define XSC_TARGETS_C_H
#include <Xsc/Export.h>
#include <stdbool.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
//! Shader target enumeration.
enum XscShaderTarget
{
XscETargetUndefined, //!< Undefined shader target.
XscETargetVertexShader, //!< Vertex shader.
XscETargetTessellationControlShader, //!< Tessellation-control (also Hull-) shader.
XscETargetTessellationEvaluationShader, //!< Tessellation-evaluation (also Domain-) shader.
XscETargetGeometryShader, //!< Geometry shader.
XscETargetFragmentShader, //!< Fragment (also Pixel-) shader.
XscETargetComputeShader, //!< Compute shader.
};
//! Output shader version enumeration.
enum XscInputShaderVersion
{
XscEInputCg = 2, //!< Cg (C for graphics) is a slightly extended HLSL3.
XscEInputHLSL3 = 3, //!< HLSL Shader Model 3.0 (DirectX 9).
XscEInputHLSL4 = 4, //!< HLSL Shader Model 4.0 (DirectX 10).
XscEInputHLSL5 = 5, //!< HLSL Shader Model 5.0 (DirectX 11).
XscEInputHLSL6 = 6, //!< HLSL Shader Model 6.0 (DirectX 12).
XscEInputGLSL = 0x0000ffff, //!< GLSL (OpenGL).
XscEInputESSL = 0x0001ffff, //!< GLSL (OpenGL ES).
XscEInputVKSL = 0x0002ffff, //!< GLSL (Vulkan).
};
//! Output shader version enumeration.
enum XscOutputShaderVersion
{
XscEOutputGLSL110 = 110, //!< GLSL 1.10 (OpenGL 2.0).
XscEOutputGLSL120 = 120, //!< GLSL 1.20 (OpenGL 2.1).
XscEOutputGLSL130 = 130, //!< GLSL 1.30 (OpenGL 3.0).
XscEOutputGLSL140 = 140, //!< GLSL 1.40 (OpenGL 3.1).
XscEOutputGLSL150 = 150, //!< GLSL 1.50 (OpenGL 3.2).
XscEOutputGLSL330 = 330, //!< GLSL 3.30 (OpenGL 3.3).
XscEOutputGLSL400 = 400, //!< GLSL 4.00 (OpenGL 4.0).
XscEOutputGLSL410 = 410, //!< GLSL 4.10 (OpenGL 4.1).
XscEOutputGLSL420 = 420, //!< GLSL 4.20 (OpenGL 4.2).
XscEOutputGLSL430 = 430, //!< GLSL 4.30 (OpenGL 4.3).
XscEOutputGLSL440 = 440, //!< GLSL 4.40 (OpenGL 4.4).
XscEOutputGLSL450 = 450, //!< GLSL 4.50 (OpenGL 4.5).
XscEOutputGLSL = 0x0000ffff, //!< Auto-detect minimal required GLSL version (for OpenGL 2+).
XscEOutputESSL100 = (0x00010000 + 100), //!< ESSL 1.00 (OpenGL ES 2.0). \note Currently not supported!
XscEOutputESSL300 = (0x00010000 + 300), //!< ESSL 3.00 (OpenGL ES 3.0). \note Currently not supported!
XscEOutputESSL310 = (0x00010000 + 310), //!< ESSL 3.10 (OpenGL ES 3.1). \note Currently not supported!
XscEOutputESSL320 = (0x00010000 + 320), //!< ESSL 3.20 (OpenGL ES 3.2). \note Currently not supported!
XscEOutputESSL = 0x0001ffff, //!< Auto-detect minimum required ESSL version (for OpenGL ES 2+). \note Currently not supported!
XscEOutputVKSL450 = (0x00020000 + 450), //!< VKSL 4.50 (Vulkan 1.0).
XscEOutputVKSL = 0x0002ffff, //!< Auto-detect minimum required VKSL version (for Vulkan/SPIR-V).
};
//! Returns the specified shader target as string.
XSC_EXPORT void XscShaderTargetToString(const enum XscShaderTarget target, char* str, size_t maxSize);
//! Returns the specified shader input version as string.
XSC_EXPORT void XscInputShaderVersionToString(const enum XscInputShaderVersion shaderVersion, char* str, size_t maxSize);
//! Returns the specified shader output version as string.
XSC_EXPORT void XscOutputShaderVersionToString(const enum XscOutputShaderVersion shaderVersion, char* str, size_t maxSize);
//! Returns true if the shader input version specifies HLSL (for DirectX).
XSC_EXPORT bool XscIsInputLanguageHLSL(const enum XscInputShaderVersion shaderVersion);
//! Returns true if the shader input version specifies GLSL (for OpenGL, OpenGL ES, and Vulkan).
XSC_EXPORT bool XscIsInputLanguageGLSL(const enum XscInputShaderVersion shaderVersion);
//! Returns true if the shader output version specifies GLSL (for OpenGL 2+).
XSC_EXPORT bool XscIsOutputLanguageGLSL(const enum XscOutputShaderVersion shaderVersion);
//! Returns true if the shader output version specifies ESSL (for OpenGL ES 2+).
XSC_EXPORT bool XscIsOutputLanguageESSL(const enum XscOutputShaderVersion shaderVersion);
//! Returns true if the shader output version specifies VKSL (for Vulkan).
XSC_EXPORT bool XscIsOutputLanguageVKSL(const enum XscOutputShaderVersion shaderVersion);
/**
\brief Returns the enumeration of all supported GLSL extensions as a map of extension name and version number.
\param[in] iterator Specifies the iterator. This must be NULL, to get the first element, or the value previously returned by this function.
\param[out] extension Specifies the output string of the extension name.
\param[in] maxSize Specifies the maximal size of the extension name string including the null terminator.
\param[out] version Specifies the output extension version.
\remarks Here is a usage example:
\code
char extension[256];
int version;
// Get first extension
void* iterator = XscGetGLSLExtensionEnumeration(NULL, extension, 256, &version);
while (iterator != NULL)
{
// Print extension name and version
printf("%s ( %d )\n", extension, version);
// Get next extension
iterator = XscGetGLSLExtensionEnumeration(iterator, extension, 256, &version);
}
\endcode
\note This can NOT be used in a multi-threaded environment!
*/
XSC_EXPORT void* XscGetGLSLExtensionEnumeration(void* iterator, char* extension, size_t maxSize, int* version);
#ifdef __cplusplus
} // /extern "C"
#endif
#endif
// ================================================================================

View File

@@ -1,300 +0,0 @@
/*
* XscC.h
*
* This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
* See "LICENSE.txt" for license information.
*/
#ifndef XSC_XSC_C_H
#define XSC_XSC_C_H
#include <Xsc/Export.h>
#include <Xsc/Version.h>
#include "TargetsC.h"
#include "LogC.h"
#include "IncludeHandlerC.h"
#include "ReflectionC.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
//! Compiler warning flags.
enum XscWarnings
{
XscWarnBasic = (1 << 0), //!< Warning for basic issues (control path, disabled code etc.).
XscWarnSyntax = (1 << 1), //!< Warning for syntactic issues.
XscWarnPreProcessor = (1 << 2), //!< Warning for pre-processor issues.
XscWarnUnusedVariables = (1 << 3), //!< Warning for unused variables.
XscWarnEmptyStatementBody = (1 << 4), //!< Warning for statements with empty body.
XscWarnImplicitTypeConversions = (1 << 5), //!< Warning for specific implicit type conversions.
XscWarnDeclarationShadowing = (1 << 6), //!< Warning for declarations that shadow a previous local (e.g. for-loops or variables in class hierarchy).
XscWarnUnlocatedObjects = (1 << 7), //!< Warning for optional objects that where not found.
XscWarnRequiredExtensions = (1 << 8), //!< Warning for required extensions in the output code.
XscWarnCodeReflection = (1 << 9), //!< Warning for issues during code reflection.
XscWarnIndexBoundary = (1 << 10), //!< Warning for index boundary violations.
XscWarnAll = (~0u), //!< All warnings.
};
/**
\brief Language extension flags.
\remakrs This is only supported, if the compiler was build with the 'XSC_ENABLE_LANGUAGE_EXT' macro.
*/
enum XscExtensions
{
XscExtLayoutAttribute = (1 << 0), //!< Enables the 'layout' attribute (e.g. "[layout(rgba8)]").
XscExtSpaceAttribute = (1 << 1), //!< Enables the 'space' attribute extension for a stronger type system (e.g. "[space(OBJECT, MODEL)]").
XscExtAll = (~0u) //!< All extensions.
};
//! Formatting descriptor structure for the output shader.
struct XscFormatting
{
//! If true, scopes are always written in braces. By default false.
bool alwaysBracedScopes;
//! If true, blank lines are allowed. By default true.
bool blanks;
//! If true, wrapper functions for special intrinsics are written in a compact formatting (i.e. all in one line). By default false.
bool compactWrappers;
//! Indentation string for code generation. By default 4 spaces.
const char* indent;
//! If true, line marks are allowed. By default false.
bool lineMarks;
//! If true, auto-formatting of line separation is allowed. By default true.
bool lineSeparation;
//! If true, the '{'-braces for an open scope gets its own line. If false, braces are written like in Java coding conventions. By default true.
bool newLineOpenScope;
};
//! Structure for additional translation options.
struct XscOptions
{
//! If true, the shader output may contain GLSL extensions, if the target shader version is too low. By default false.
bool allowExtensions;
/**
\brief If true, binding slots for all buffer types will be generated sequentially, starting with index at 'autoBindingStartSlot'. By default false.
\remarks This will also enable 'explicitBinding'.
*/
bool autoBinding;
//! Index to start generating binding slots from. Only relevant if 'autoBinding' is enabled. By default 0.
int autoBindingStartSlot;
//! If true, explicit binding slots are enabled. By default false.
bool explicitBinding;
//! If true, code obfuscation is performed. By default false.
bool obfuscate;
//! If true, little code optimizations are performed. By default false.
bool optimize;
//! If true, intrinsics are prefered to be implemented as wrappers (instead of inlining). By default false.
bool preferWrappers;
//! If true, only the preprocessed source code will be written out. By default false.
bool preprocessOnly;
//! If true, commentaries are preserved for each statement. By default false.
bool preserveComments;
//! If true, matrices have row-major alignment. Otherwise the matrices have column-major alignment. By default false.
bool rowMajorAlignment;
//! If true, generated GLSL code will contain separate sampler and texture objects when supported. By default true.
bool separateSamplers;
//! If true, generated GLSL code will support the 'ARB_separate_shader_objects' extension. By default false.
bool separateShaders;
//! If true, the AST (Abstract Syntax Tree) will be written to the log output. By default false.
bool showAST;
//! If true, the timings of the different compilation processes are written to the log output. By default false.
bool showTimes;
//! If true, array initializations will be unrolled. By default false.
bool unrollArrayInitializers;
//! If true, the source code is only validated, but no output code will be generated. By default false.
bool validateOnly;
};
//! Name mangling descriptor structure for shader input/output variables (also referred to as "varyings"), temporary variables, and reserved keywords.
struct XscNameMangling
{
/**
\brief Name mangling prefix for shader input variables. By default "xsv_".
\remarks This can also be empty or equal to "outputPrefix".
*/
const char* inputPrefix;
/**
\brief Name mangling prefix for shader output variables. By default "xsv_".
\remarks This can also be empty or equal to "inputPrefix".
*/
const char* outputPrefix;
/**
\brief Name mangling prefix for reserved words (such as "texture", "main", "sin" etc.). By default "xsr_".
\remarks This must not be equal to any of the other prefixes and it must not be empty.
*/
const char* reservedWordPrefix;
/**
\brief Name mangling prefix for temporary variables. By default "xst_".
\remarks This must not be equal to any of the other prefixes and it must not be empty.
*/
const char* temporaryPrefix;
/**
\brief Name mangling prefix for namespaces like structures or classes. By default "xsn_".
\remarks This can also be empty, but if it's not empty it must not be equal to any of the other prefixes.
*/
const char* namespacePrefix;
/**
If true, shader input/output variables are always renamed to their semantics,
even for vertex input and fragment output. Otherwise, their original identifiers are used. By default false.
*/
bool useAlwaysSemantics;
/**
\brief If true, the data fields of a 'buffer'-objects is renamed rather than the outer identifier. By default false.
\remarks This can be useful for external diagnostic tools, to access the original identifier.
*/
bool renameBufferFields;
};
//! Shader input descriptor structure.
struct XscShaderInput
{
//! Specifies the filename of the input shader code. This is an optional attribute, and only a hint to the compiler. By default NULL.
const char* filename;
//! Specifies the input source code. This must not be null when passed to the "XscCompileShader" function!
const char* sourceCode;
//! Specifies the input shader version (e.g. XscEInputHLSL5 for "HLSL 5"). By default XscEInputHLSL5.
enum XscInputShaderVersion shaderVersion;
//! Specifies the target shader (Vertex, Fragment etc.). By default XscUndefinedShader.
enum XscShaderTarget shaderTarget;
//! Specifies the HLSL shader entry point. By default "main".
const char* entryPoint;
/**
\brief Specifies the secondary HLSL shader entry point. By default NULL.
\remarks This is only used for a Tessellation-Control Shader (alias Hull Shader) entry point,
when a Tessellation-Control Shader (alias Domain Shader) is the output target.
This is required to translate all Tessellation-Control attributes (i.e. "partitioning" and "outputtopology")
to the Tessellation-Evaluation output shader. If this is empty, the default values for these attributes are used.
*/
const char* secondaryEntryPoint;
/**
\brief Compiler warning flags. This can be a bitwise OR combination of the "XscWarnings" enumeration entries. By default 0.
\see XscWarnings
*/
unsigned int warnings;
/**
\brief Language extension flags. This can be a bitwise OR combination of the "Extensions" enumeration entries. By default 0.
\remarks This is ignored, if the compiler was not build with the 'XSC_ENABLE_LANGUAGE_EXT' macro.
\see Extensions
*/
unsigned int extensions;
//! Include handler member which contains a function pointer to handle '#include'-directives.
struct XscIncludeHandler includeHandler;
};
//! Vertex shader semantic (or rather attribute) layout structure.
struct XscVertexSemantic
{
//! Specifies the shader semantic (or rather attribute).
const char* semantic;
//! Specifies the binding location.
int location;
};
//! Shader output descriptor structure.
struct XscShaderOutput
{
//! Specifies the filename of the output shader code. This is an optional attribute, and only a hint to the compiler.
const char* filename;
//! Specifies the output source code. This will contain the output code. This must not be null when passed to the "XscCompileShader" function!
const char** sourceCode;
//! Specifies the output shader version. By default XscEOutputGLSL (to auto-detect minimum required version).
enum XscOutputShaderVersion shaderVersion;
//! Optional list of vertex semantic layouts, to bind a vertex attribute (semantic name) to a location index (only used when 'explicitBinding' is true). By default NULL.
const struct XscVertexSemantic* vertexSemantics;
//! Number of elements the 'vertexSemantics' member points to. By default 0.
size_t vertexSemanticsCount;
//! Additional options to configure the code generation.
struct XscOptions options;
//! Output code formatting descriptor.
struct XscFormatting formatting;
//! Specifies the options for name mangling.
struct XscNameMangling nameMangling;
};
/**
\brief Initializes the specified descriptor structures to their default values.
\param[out] inputDesc Input shader code descriptor. If NULL, this structure is not initialized.
\param[out] outputDesc Output shader code descriptor. If NULL, this structure is not initialized.
*/
XSC_EXPORT void XscInitialize(struct XscShaderInput* inputDesc, struct XscShaderOutput* outputDesc);
/**
\brief Cross compiles the shader code from the specified input stream into the specified output shader code.
\param[in] inputDesc Input shader code descriptor.
\param[in] outputDesc Output shader code descriptor.
\param[in] log Optional pointer to an output log. This can be NULL (to ignore log) or XSC_DEFAULT_LOG (to use the default log).
\param[out] reflectionData Optional pointer to a code reflection data structure. If NULL, no reflection data is written out.
\return True if the code has been translated successfully.
\see ShaderInput
\see ShaderOutput
\see Log
\see ReflectionData
*/
XSC_EXPORT bool XscCompileShader(
const struct XscShaderInput* inputDesc,
const struct XscShaderOutput* outputDesc,
const struct XscLog* log,
struct XscReflectionData* reflectionData
);
#ifdef __cplusplus
} // /extern "C"
#endif
#endif
// ================================================================================