Implement support for floating point textures.

Trac #12909 Implements GL_OES_texture_float, GL_OES_texture_half_float, GL_OES_texture_float_linear, and GL_OES_texture_half_float_linear when supported by the hardware. Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Shannon Woods <shannon.woods@transgaming.com> git-svn-id: https://angleproject.googlecode.com/svn/trunk@404 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 06098890
......@@ -487,4 +487,46 @@ bool Display::getCompressedTextureSupport()
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
}
bool Display::getFloatTextureSupport(bool *filtering)
{
D3DDISPLAYMODE currentDisplayMode;
mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
if (SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
{
*filtering = true;
return true;
}
else
{
*filtering = false;
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
}
}
bool Display::getHalfFloatTextureSupport(bool *filtering)
{
D3DDISPLAYMODE currentDisplayMode;
mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
if (SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)))
{
*filtering = true;
return true;
}
else
{
*filtering = false;
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
}
}
}
......@@ -62,6 +62,8 @@ class Display
virtual D3DCAPS9 getDeviceCaps();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getCompressedTextureSupport();
virtual bool getFloatTextureSupport(bool *filtering);
virtual bool getHalfFloatTextureSupport(bool *filtering);
private:
DISALLOW_COPY_AND_ASSIGN(Display);
......
......@@ -266,6 +266,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mMaxSupportedSamples = max;
mSupportsCompressedTextures = display->getCompressedTextureSupport();
mSupportsFloatTextures = display->getFloatTextureSupport(&mSupportsFloatLinearFilter);
mSupportsHalfFloatTextures = display->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter);
initExtensionString();
......@@ -2793,6 +2795,26 @@ bool Context::supportsCompressedTextures() const
return mSupportsCompressedTextures;
}
bool Context::supportsFloatTextures() const
{
return mSupportsFloatTextures;
}
bool Context::supportsFloatLinearFilter() const
{
return mSupportsFloatLinearFilter;
}
bool Context::supportsHalfFloatTextures() const
{
return mSupportsHalfFloatTextures;
}
bool Context::supportsHalfFloatLinearFilter() const
{
return mSupportsHalfFloatLinearFilter;
}
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
......@@ -2994,6 +3016,26 @@ void Context::initExtensionString()
mExtensionString += "GL_EXT_texture_compression_dxt1 ";
}
if (supportsFloatTextures())
{
mExtensionString += "GL_OES_texture_float ";
}
if (supportsHalfFloatTextures())
{
mExtensionString += "GL_OES_texture_half_float ";
}
if (supportsFloatLinearFilter())
{
mExtensionString += "GL_OES_texture_float_linear ";
}
if (supportsHalfFloatLinearFilter())
{
mExtensionString += "GL_OES_texture_half_float_linear ";
}
if (getMaxSupportedSamples() != 0)
{
mExtensionString += "GL_ANGLE_framebuffer_multisample ";
......
......@@ -378,6 +378,10 @@ class Context
int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const;
bool supportsCompressedTextures() const;
bool supportsFloatTextures() const;
bool supportsFloatLinearFilter() const;
bool supportsHalfFloatTextures() const;
bool supportsHalfFloatLinearFilter() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
......@@ -444,6 +448,10 @@ class Context
std::map<D3DFORMAT, bool *> mMultiSampleSupport;
GLsizei mMaxSupportedSamples;
bool mSupportsCompressedTextures;
bool mSupportsFloatTextures;
bool mSupportsFloatLinearFilter;
bool mSupportsHalfFloatTextures;
bool mSupportsHalfFloatLinearFilter;
// state caching flags
bool mClearStateDirty;
......
......@@ -58,6 +58,7 @@ class Texture : public RefCountObject
virtual GLenum getFormat() const = 0;
virtual bool isComplete() const = 0;
virtual bool isCompressed() const = 0;
bool isFloatingPoint() const;
IDirect3DBaseTexture9 *getTexture();
virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
......@@ -106,8 +107,7 @@ class Texture : public RefCountObject
IDirect3DSurface9 *surface;
};
static D3DFORMAT selectFormat(GLenum format);
int imagePitch(const Image& img) const;
static D3DFORMAT selectFormat(GLenum format, GLenum type);
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
......@@ -140,6 +140,7 @@ class Texture : public RefCountObject
GLenum mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
GLenum mType;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
......@@ -149,30 +150,51 @@ class Texture : public RefCountObject
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img);
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
bool mDirty;
bool mDirtyMetaData;
bool mIsRenderable;
void createSurface(GLsizei width, GLsizei height, GLenum format, Image *img);
};
class Texture2D : public Texture
......@@ -209,7 +231,7 @@ class Texture2D : public Texture
virtual bool dirtyImageData() const;
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[MAX_TEXTURE_LEVELS];
......
......@@ -1068,6 +1068,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION);
}
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copyImage(level, internalformat, x, y, width, height, source);
}
else if (gl::IsCubemapTextureTarget(target))
......@@ -1084,6 +1089,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION);
}
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copyImage(target, level, internalformat, x, y, width, height, source);
}
else
......@@ -1156,6 +1166,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
}
else if (gl::IsCubemapTextureTarget(target))
......@@ -1172,6 +1187,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
}
else
......@@ -4256,6 +4276,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_ENUM);
......@@ -4266,6 +4288,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_ENUM);
......@@ -4277,6 +4301,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_ENUM);
......@@ -4320,6 +4346,21 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
}
}
if (type == GL_FLOAT)
{
if (!context->supportsFloatTextures())
{
return error(GL_INVALID_ENUM);
}
}
else if (type == GL_HALF_FLOAT_OES)
{
if (!context->supportsHalfFloatTextures())
{
return error(GL_INVALID_ENUM);
}
}
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
......@@ -4486,6 +4527,21 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
if (context)
{
if (format == GL_FLOAT)
{
if (!context->supportsFloatTextures())
{
return error(GL_INVALID_ENUM);
}
}
else if (format == GL_HALF_FLOAT_OES)
{
if (!context->supportsHalfFloatTextures())
{
return error(GL_INVALID_ENUM);
}
}
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
......@@ -4500,6 +4556,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
if (format != texture->getFormat())
{
return error(GL_INVALID_OPERATION);
}
texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else if (gl::IsCubemapTextureTarget(target))
......@@ -4516,6 +4577,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
if (format != texture->getFormat())
{
return error(GL_INVALID_OPERATION);
}
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else
......
......@@ -247,6 +247,28 @@ int ComputePixelSize(GLenum format, GLenum type)
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5:
return sizeof(unsigned short);
case GL_FLOAT:
switch (format)
{
case GL_ALPHA: return sizeof(float);
case GL_LUMINANCE: return sizeof(float);
case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
case GL_RGB: return sizeof(float) * 3;
case GL_RGBA: return sizeof(float) * 4;
default: UNREACHABLE();
}
break;
case GL_HALF_FLOAT_OES:
switch (format)
{
case GL_ALPHA: return sizeof(unsigned short);
case GL_LUMINANCE: return sizeof(unsigned short);
case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
case GL_RGB: return sizeof(unsigned short) * 3;
case GL_RGBA: return sizeof(unsigned short) * 4;
default: UNREACHABLE();
}
break;
default: UNREACHABLE();
}
......@@ -283,6 +305,21 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
return false;
}
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
switch (format)
{
case GL_RGBA:
case GL_RGB:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
return true;
default:
return false;
}
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
return (format == GL_RGBA);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment