Mipmapped array textures

This commit is contained in:
Jack Andersen 2017-01-28 17:56:17 -10:00
parent 7bf2ad48a7
commit 80e93a8e38
5 changed files with 81 additions and 36 deletions

View File

@ -49,8 +49,8 @@ public:
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz);
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
const void* data, size_t sz);
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz);
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
ITextureR* newRenderTexture(size_t width, size_t height,
bool enableShaderColorBinding, bool enableShaderDepthBinding);

View File

@ -220,8 +220,8 @@ struct IGraphicsDataFactory
newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz)=0;
virtual ITextureSA*
newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
const void* data, size_t sz)=0;
newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz)=0;
virtual ITextureD*
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
virtual ITextureR*
@ -367,12 +367,15 @@ public:
IGraphicsBufferD* newPoolBuffer(BufferUse use,
size_t stride, size_t count)
{
return m_factory->newPoolBuffer(m_pool, use, stride, count);
if (m_factory)
return m_factory->newPoolBuffer(m_pool, use, stride, count);
return nullptr;
}
void deletePoolBuffer(IGraphicsBufferD* buf)
{
m_factory->deletePoolBuffer(m_pool, buf);
if (m_factory)
m_factory->deletePoolBuffer(m_pool, buf);
}
};

View File

@ -53,8 +53,8 @@ public:
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz);
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
const void* data, size_t sz);
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz);
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
ITextureR* newRenderTexture(size_t width, size_t height,
bool enableShaderColorBinding, bool enableShaderDepthBinding);

View File

@ -138,7 +138,7 @@ class GLTextureS : public ITextureS
switch (fmt)
{
case TextureFormat::RGBA8:
intFormat = GL_RGBA;
intFormat = GL_RGBA8;
format = GL_RGBA;
pxPitch = 4;
break;
@ -162,8 +162,10 @@ class GLTextureS : public ITextureS
size_t dataSz = width * height / 2;
glCompressedTexImage2D(GL_TEXTURE_2D, i, intFormat, width, height, 0, dataSz, dataIt);
dataIt += dataSz;
width /= 2;
height /= 2;
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
}
}
else
@ -172,8 +174,10 @@ class GLTextureS : public ITextureS
{
glTexImage2D(GL_TEXTURE_2D, i, intFormat, width, height, 0, format, GL_UNSIGNED_BYTE, dataIt);
dataIt += width * height * pxPitch;
width /= 2;
height /= 2;
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
}
}
}
@ -191,17 +195,45 @@ class GLTextureSA : public ITextureSA
{
friend class GLDataFactory;
GLuint m_tex;
GLTextureSA(size_t width, size_t height, size_t layers,
GLTextureSA(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz)
{
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
glGenTextures(1, &m_tex);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_tex);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (mips > 1)
{
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mips-1);
}
else
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLenum intFormat, format;
int pxPitch;
if (fmt == TextureFormat::RGBA8)
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, width, height, layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
{
intFormat = GL_RGBA8;
format = GL_RGBA;
pxPitch = 4;
}
else if (fmt == TextureFormat::I8)
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, width, height, layers, 0, GL_RED, GL_UNSIGNED_BYTE, data);
{
intFormat = GL_R8;
format = GL_RED;
pxPitch = 1;
}
for (size_t i=0 ; i<mips ; ++i)
{
glTexImage3D(GL_TEXTURE_2D_ARRAY, i, intFormat, width, height, layers, 0, format, GL_UNSIGNED_BYTE, dataIt);
dataIt += width * height * layers * pxPitch;
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
}
}
public:
~GLTextureSA() {glDeleteTextures(1, &m_tex);}
@ -317,10 +349,10 @@ GLDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mip
}
ITextureSA*
GLDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
const void *data, size_t sz)
GLDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void *data, size_t sz)
{
GLTextureSA* retval = new GLTextureSA(width, height, layers, fmt, data, sz);
GLTextureSA* retval = new GLTextureSA(width, height, layers, mips, fmt, data, sz);
m_deferredData->m_SATexs.emplace_back(retval);
return retval;
}
@ -1382,7 +1414,7 @@ GLTextureD::GLTextureD(size_t width, size_t height, TextureFormat fmt)
switch (fmt)
{
case TextureFormat::RGBA8:
m_intFormat = GL_RGBA;
m_intFormat = GL_RGBA8;
m_format = GL_RGBA;
pxPitch = 4;
break;

View File

@ -123,8 +123,10 @@ class MetalTextureS : public ITextureS
withBytes:dataIt
bytesPerRow:width * ppitchNum / ppitchDenom];
dataIt += width * height * ppitchNum / ppitchDenom;
width /= 2;
height /= 2;
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
}
}
}
@ -136,7 +138,7 @@ public:
class MetalTextureSA : public ITextureSA
{
friend class MetalDataFactory;
MetalTextureSA(MetalContext* ctx, size_t width, size_t height, size_t layers,
MetalTextureSA(MetalContext* ctx, size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz)
{
MTLPixelFormat pfmt = MTLPixelFormatRGBA8Unorm;
@ -155,21 +157,29 @@ class MetalTextureSA : public ITextureSA
MTLTextureDescriptor* desc =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pfmt
width:width height:height
mipmapped:NO];
mipmapped:(mips>1)?YES:NO];
desc.textureType = MTLTextureType2DArray;
desc.arrayLength = layers;
desc.mipmapLevelCount = mips;
desc.usage = MTLTextureUsageShaderRead;
m_tex = [ctx->m_dev newTextureWithDescriptor:desc];
const uint8_t* dataIt = reinterpret_cast<const uint8_t*>(data);
for (size_t i=0 ; i<layers ; ++i)
for (size_t i=0 ; i<mips ; ++i)
{
[m_tex replaceRegion:MTLRegionMake2D(0, 0, width, height)
mipmapLevel:0
slice:i
withBytes:dataIt
bytesPerRow:width * ppitch
bytesPerImage:width * height * ppitch];
dataIt += width * height * ppitch;
for (size_t j=0 ; j<layers ; ++j)
{
[m_tex replaceRegion:MTLRegionMake2D(0, 0, width, height)
mipmapLevel:i
slice:j
withBytes:dataIt
bytesPerRow:width * ppitch
bytesPerImage:width * height * ppitch];
dataIt += width * height * ppitch;
}
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
}
}
}
@ -1056,10 +1066,10 @@ ITextureS* MetalDataFactory::Context::newStaticTexture(size_t width, size_t heig
m_deferredData->m_STexs.emplace_back(retval);
return retval;
}
ITextureSA* MetalDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
const void* data, size_t sz)
ITextureSA* MetalDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz)
{
MetalTextureSA* retval = new MetalTextureSA(m_parent.m_ctx, width, height, layers, fmt, data, sz);
MetalTextureSA* retval = new MetalTextureSA(m_parent.m_ctx, width, height, layers, mips, fmt, data, sz);
m_deferredData->m_SATexs.emplace_back(retval);
return retval;
}