167 lines
3.5 KiB
C++
167 lines
3.5 KiB
C++
// 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
|