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() ...@@ -487,4 +487,46 @@ bool Display::getCompressedTextureSupport()
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); 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 ...@@ -62,6 +62,8 @@ class Display
virtual D3DCAPS9 getDeviceCaps(); virtual D3DCAPS9 getDeviceCaps();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getCompressedTextureSupport(); virtual bool getCompressedTextureSupport();
virtual bool getFloatTextureSupport(bool *filtering);
virtual bool getHalfFloatTextureSupport(bool *filtering);
private: private:
DISALLOW_COPY_AND_ASSIGN(Display); DISALLOW_COPY_AND_ASSIGN(Display);
......
...@@ -266,6 +266,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -266,6 +266,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mMaxSupportedSamples = max; mMaxSupportedSamples = max;
mSupportsCompressedTextures = display->getCompressedTextureSupport(); mSupportsCompressedTextures = display->getCompressedTextureSupport();
mSupportsFloatTextures = display->getFloatTextureSupport(&mSupportsFloatLinearFilter);
mSupportsHalfFloatTextures = display->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter);
initExtensionString(); initExtensionString();
...@@ -2793,6 +2795,26 @@ bool Context::supportsCompressedTextures() const ...@@ -2793,6 +2795,26 @@ bool Context::supportsCompressedTextures() const
return mSupportsCompressedTextures; 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) void Context::detachBuffer(GLuint buffer)
{ {
// [OpenGL ES 2.0.24] section 2.9 page 22: // [OpenGL ES 2.0.24] section 2.9 page 22:
...@@ -2994,6 +3016,26 @@ void Context::initExtensionString() ...@@ -2994,6 +3016,26 @@ void Context::initExtensionString()
mExtensionString += "GL_EXT_texture_compression_dxt1 "; 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) if (getMaxSupportedSamples() != 0)
{ {
mExtensionString += "GL_ANGLE_framebuffer_multisample "; mExtensionString += "GL_ANGLE_framebuffer_multisample ";
......
...@@ -378,6 +378,10 @@ class Context ...@@ -378,6 +378,10 @@ class Context
int getNearestSupportedSamples(D3DFORMAT format, int requested) const; int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const; const char *getExtensionString() const;
bool supportsCompressedTextures() 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, void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
...@@ -444,6 +448,10 @@ class Context ...@@ -444,6 +448,10 @@ class Context
std::map<D3DFORMAT, bool *> mMultiSampleSupport; std::map<D3DFORMAT, bool *> mMultiSampleSupport;
GLsizei mMaxSupportedSamples; GLsizei mMaxSupportedSamples;
bool mSupportsCompressedTextures; bool mSupportsCompressedTextures;
bool mSupportsFloatTextures;
bool mSupportsFloatLinearFilter;
bool mSupportsHalfFloatTextures;
bool mSupportsHalfFloatLinearFilter;
// state caching flags // state caching flags
bool mClearStateDirty; bool mClearStateDirty;
......
...@@ -45,6 +45,7 @@ Texture::Texture(GLuint id) : RefCountObject(id) ...@@ -45,6 +45,7 @@ Texture::Texture(GLuint id) : RefCountObject(id)
mDirtyMetaData = true; mDirtyMetaData = true;
mDirty = true; mDirty = true;
mIsRenderable = false; mIsRenderable = false;
mType = GL_UNSIGNED_BYTE;
mBaseTexture = NULL; mBaseTexture = NULL;
} }
...@@ -174,25 +175,33 @@ GLuint Texture::getHeight() const ...@@ -174,25 +175,33 @@ GLuint Texture::getHeight() const
return mHeight; return mHeight;
} }
bool Texture::isFloatingPoint() const
{
return (mType == GL_FLOAT || mType == GL_HALF_FLOAT_OES);
}
// Selects an internal Direct3D 9 format for storing an Image // Selects an internal Direct3D 9 format for storing an Image
D3DFORMAT Texture::selectFormat(GLenum format) D3DFORMAT Texture::selectFormat(GLenum format, GLenum type)
{ {
if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{ {
return D3DFMT_DXT1; return D3DFMT_DXT1;
} }
else if (type == GL_FLOAT)
{
return D3DFMT_A32B32G32R32F;
}
else if (type == GL_HALF_FLOAT_OES)
{
return D3DFMT_A16B16G16R16F;
}
else else
{ {
return D3DFMT_A8R8G8B8; return D3DFMT_A8R8G8B8;
} }
} }
int Texture::imagePitch(const Image &img) const
{
return img.width * 4;
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line. // into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line.
void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
...@@ -200,60 +209,100 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei ...@@ -200,60 +209,100 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
{ {
GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment); GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
switch (type)
{
case GL_UNSIGNED_BYTE:
switch (format) switch (format)
{ {
case GL_ALPHA: case GL_ALPHA:
loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
case GL_LUMINANCE: case GL_LUMINANCE:
loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
case GL_RGB: case GL_RGB:
switch (type)
{
case GL_UNSIGNED_BYTE:
loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
case GL_RGBA:
case GL_UNSIGNED_SHORT_5_6_5: loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break;
case GL_BGRA_EXT:
loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
break; break;
case GL_UNSIGNED_SHORT_5_6_5:
case GL_RGBA: switch (format)
switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_RGB:
loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
default: UNREACHABLE();
}
break; break;
case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4:
switch (format)
{
case GL_RGBA:
loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_5_5_1:
switch (format)
{
case GL_RGBA:
loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
break; break;
case GL_BGRA_EXT: case GL_FLOAT:
switch (type) switch (format)
{ {
case GL_UNSIGNED_BYTE: // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); case GL_ALPHA:
loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_LUMINANCE:
loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_RGB:
loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_RGBA:
loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
default: UNREACHABLE();
}
break;
case GL_HALF_FLOAT_OES:
switch (format)
{
// float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
case GL_ALPHA:
loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_LUMINANCE:
loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_LUMINANCE_ALPHA:
loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_RGB:
loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
case GL_RGBA:
loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
break; break;
...@@ -281,6 +330,46 @@ void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GL ...@@ -281,6 +330,46 @@ void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GL
} }
} }
void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
float *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
dest[4 * x + 1] = 0;
dest[4 * x + 2] = 0;
dest[4 * x + 3] = source[x];
}
}
}
void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
dest[4 * x + 1] = 0;
dest[4 * x + 2] = 0;
dest[4 * x + 3] = source[x];
}
}
}
void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
...@@ -301,6 +390,46 @@ void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width ...@@ -301,6 +390,46 @@ void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width
} }
} }
void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
float *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
dest[4 * x + 1] = source[x];
dest[4 * x + 2] = source[x];
dest[4 * x + 3] = 1.0f;
}
}
}
void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
dest[4 * x + 1] = source[x];
dest[4 * x + 2] = source[x];
dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
}
}
}
void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
...@@ -321,6 +450,46 @@ void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei ...@@ -321,6 +450,46 @@ void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei
} }
} }
void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
float *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
dest[4 * x + 1] = source[2*x+0];
dest[4 * x + 2] = source[2*x+0];
dest[4 * x + 3] = source[2*x+1];
}
}
}
void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
dest[4 * x + 1] = source[2*x+0];
dest[4 * x + 2] = source[2*x+0];
dest[4 * x + 3] = source[2*x+1];
}
}
}
void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
...@@ -362,6 +531,46 @@ void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, G ...@@ -362,6 +531,46 @@ void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, G
} }
} }
void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
float *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 2];
dest[4 * x + 3] = 1.0f;
}
}
}
void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 2];
dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
}
}
}
void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
...@@ -424,6 +633,34 @@ void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, ...@@ -424,6 +633,34 @@ void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width,
} }
} }
void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const float *source = NULL;
float *dest = NULL;
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16);
memcpy(dest, source, width * 16);
}
}
void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputPitch;
dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8;
memcpy(dest, source, width * 8);
}
}
void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{ {
...@@ -438,7 +675,7 @@ void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLs ...@@ -438,7 +675,7 @@ void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLs
} }
} }
void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img) void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img)
{ {
IDirect3DTexture9 *newTexture = NULL; IDirect3DTexture9 *newTexture = NULL;
IDirect3DSurface9 *newSurface = NULL; IDirect3DSurface9 *newSurface = NULL;
...@@ -465,7 +702,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image ...@@ -465,7 +702,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image
levelToFetch = upsampleCount; levelToFetch = upsampleCount;
} }
HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format), HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format, type),
D3DPOOL_SYSTEMMEM, &newTexture, NULL); D3DPOOL_SYSTEMMEM, &newTexture, NULL);
if (FAILED(result)) if (FAILED(result))
...@@ -488,7 +725,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image ...@@ -488,7 +725,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image
void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img) void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
{ {
createSurface(width, height, format, img); createSurface(width, height, format, type, img);
if (pixels != NULL && img->surface != NULL) if (pixels != NULL && img->surface != NULL)
{ {
...@@ -511,7 +748,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type ...@@ -511,7 +748,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img) void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
{ {
createSurface(width, height, format, img); createSurface(width, height, format, GL_UNSIGNED_BYTE, img);
if (pixels != NULL && img->surface != NULL) if (pixels != NULL && img->surface != NULL)
{ {
...@@ -716,7 +953,7 @@ GLenum Texture2D::getFormat() const ...@@ -716,7 +953,7 @@ GLenum Texture2D::getFormat() const
// //
// Returns true if the existing texture was unsuitable had to be destroyed. If so, it will also set // Returns true if the existing texture was unsuitable had to be destroyed. If so, it will also set
// a new height and width for the texture by working backwards from the given width and height. // a new height and width for the texture by working backwards from the given width and height.
bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height) bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type)
{ {
bool widthOkay = (mWidth >> level == width); bool widthOkay = (mWidth >> level == width);
bool heightOkay = (mHeight >> level == height); bool heightOkay = (mHeight >> level == height);
...@@ -725,7 +962,9 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt ...@@ -725,7 +962,9 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
|| (widthOkay && mHeight >> level == 0 && height == 1) || (widthOkay && mHeight >> level == 0 && height == 1)
|| (heightOkay && mWidth >> level == 0 && width == 1)); || (heightOkay && mWidth >> level == 0 && width == 1));
bool textureOkay = (sizeOkay && internalFormat == mImageArray[0].format); bool typeOkay = (type == mType);
bool textureOkay = (sizeOkay && typeOkay && internalFormat == mImageArray[0].format);
if (!textureOkay) if (!textureOkay)
{ {
...@@ -756,6 +995,7 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt ...@@ -756,6 +995,7 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
mWidth = width << level; mWidth = width << level;
mHeight = height << level; mHeight = height << level;
mImageArray[0].format = internalFormat; mImageArray[0].format = internalFormat;
mType = type;
} }
return !textureOkay; return !textureOkay;
...@@ -763,14 +1003,14 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt ...@@ -763,14 +1003,14 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{ {
redefineTexture(level, internalFormat, width, height); redefineTexture(level, internalFormat, width, height, type);
Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]); Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
} }
void Texture2D::setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) void Texture2D::setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{ {
redefineTexture(level, internalFormat, width, height); redefineTexture(level, internalFormat, width, height, GL_UNSIGNED_BYTE);
Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]); Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]);
} }
...@@ -828,7 +1068,7 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL ...@@ -828,7 +1068,7 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{ {
if (redefineTexture(level, internalFormat, width, height)) if (redefineTexture(level, internalFormat, width, height, mType))
{ {
convertToRenderTarget(); convertToRenderTarget();
pushTexture(mTexture, true); pushTexture(mTexture, true);
...@@ -865,7 +1105,7 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, ...@@ -865,7 +1105,7 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x,
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height)) if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height, mType))
{ {
convertToRenderTarget(); convertToRenderTarget();
pushTexture(mTexture, true); pushTexture(mTexture, true);
...@@ -919,6 +1159,16 @@ bool Texture2D::isComplete() const ...@@ -919,6 +1159,16 @@ bool Texture2D::isComplete() const
default: UNREACHABLE(); default: UNREACHABLE();
} }
if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) ||
(getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter()))
{
if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width)) if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width))
|| (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height))) || (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height)))
{ {
...@@ -967,7 +1217,7 @@ IDirect3DBaseTexture9 *Texture2D::createTexture() ...@@ -967,7 +1217,7 @@ IDirect3DBaseTexture9 *Texture2D::createTexture()
IDirect3DTexture9 *texture; IDirect3DTexture9 *texture;
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format); D3DFORMAT format = selectFormat(mImageArray[0].format, mType);
HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL);
...@@ -1018,7 +1268,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget() ...@@ -1018,7 +1268,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget()
{ {
egl::Display *display = getDisplay(); egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0].format); D3DFORMAT format = selectFormat(mImageArray[0].format, mType);
HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
...@@ -1328,6 +1578,15 @@ bool TextureCubeMap::isComplete() const ...@@ -1328,6 +1578,15 @@ bool TextureCubeMap::isComplete() const
} }
} }
if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) ||
(getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter()))
{
if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
if (mipmapping) if (mipmapping)
{ {
if (!isPow2(size) && (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE)) if (!isPow2(size) && (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE))
...@@ -1368,7 +1627,7 @@ bool TextureCubeMap::isCompressed() const ...@@ -1368,7 +1627,7 @@ bool TextureCubeMap::isCompressed() const
IDirect3DBaseTexture9 *TextureCubeMap::createTexture() IDirect3DBaseTexture9 *TextureCubeMap::createTexture()
{ {
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0][0].format); D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType);
IDirect3DCubeTexture9 *texture; IDirect3DCubeTexture9 *texture;
...@@ -1424,7 +1683,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget() ...@@ -1424,7 +1683,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget()
{ {
egl::Display *display = getDisplay(); egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
D3DFORMAT format = selectFormat(mImageArray[0][0].format); D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType);
HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
......
...@@ -58,6 +58,7 @@ class Texture : public RefCountObject ...@@ -58,6 +58,7 @@ class Texture : public RefCountObject
virtual GLenum getFormat() const = 0; virtual GLenum getFormat() const = 0;
virtual bool isComplete() const = 0; virtual bool isComplete() const = 0;
virtual bool isCompressed() const = 0; virtual bool isCompressed() const = 0;
bool isFloatingPoint() const;
IDirect3DBaseTexture9 *getTexture(); IDirect3DBaseTexture9 *getTexture();
virtual Renderbuffer *getColorbuffer(GLenum target) = 0; virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
...@@ -106,8 +107,7 @@ class Texture : public RefCountObject ...@@ -106,8 +107,7 @@ class Texture : public RefCountObject
IDirect3DSurface9 *surface; IDirect3DSurface9 *surface;
}; };
static D3DFORMAT selectFormat(GLenum format); static D3DFORMAT selectFormat(GLenum format, GLenum type);
int imagePitch(const Image& img) const;
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img); 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); 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 ...@@ -140,6 +140,7 @@ class Texture : public RefCountObject
GLenum mMagFilter; GLenum mMagFilter;
GLenum mWrapS; GLenum mWrapS;
GLenum mWrapT; GLenum mWrapT;
GLenum mType;
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture); DISALLOW_COPY_AND_ASSIGN(Texture);
...@@ -149,30 +150,51 @@ class Texture : public RefCountObject ...@@ -149,30 +150,51 @@ class Texture : public RefCountObject
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; 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, void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; 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, void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; 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, void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; 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, void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; 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, void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const; 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. IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
bool mDirty; bool mDirty;
bool mDirtyMetaData; bool mDirtyMetaData;
bool mIsRenderable; bool mIsRenderable;
void createSurface(GLsizei width, GLsizei height, GLenum format, Image *img);
}; };
class Texture2D : public Texture class Texture2D : public Texture
...@@ -209,7 +231,7 @@ class Texture2D : public Texture ...@@ -209,7 +231,7 @@ class Texture2D : public Texture
virtual bool dirtyImageData() const; 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); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[MAX_TEXTURE_LEVELS]; Image mImageArray[MAX_TEXTURE_LEVELS];
......
...@@ -1068,6 +1068,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1068,6 +1068,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copyImage(level, internalformat, x, y, width, height, source); texture->copyImage(level, internalformat, x, y, width, height, source);
} }
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
...@@ -1084,6 +1089,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma ...@@ -1084,6 +1089,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copyImage(target, level, internalformat, x, y, width, height, source); texture->copyImage(target, level, internalformat, x, y, width, height, source);
} }
else else
...@@ -1156,6 +1166,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1156,6 +1166,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source); texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
} }
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
...@@ -1172,6 +1187,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL ...@@ -1172,6 +1187,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (texture->isFloatingPoint())
{
return error(GL_INVALID_OPERATION);
}
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source); texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
} }
else else
...@@ -4256,6 +4276,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL ...@@ -4256,6 +4276,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -4266,6 +4288,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL ...@@ -4266,6 +4288,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -4277,6 +4301,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL ...@@ -4277,6 +4301,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -4320,6 +4346,21 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL ...@@ -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) if (target == GL_TEXTURE_2D)
{ {
gl::Texture2D *texture = context->getTexture2D(); gl::Texture2D *texture = context->getTexture2D();
...@@ -4486,6 +4527,21 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -4486,6 +4527,21 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
if (context) 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) if (target == GL_TEXTURE_2D)
{ {
gl::Texture2D *texture = context->getTexture2D(); gl::Texture2D *texture = context->getTexture2D();
...@@ -4500,6 +4556,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -4500,6 +4556,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION); 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); texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
} }
else if (gl::IsCubemapTextureTarget(target)) else if (gl::IsCubemapTextureTarget(target))
...@@ -4516,6 +4577,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -4516,6 +4577,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION); 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); texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
} }
else else
......
...@@ -247,6 +247,28 @@ int ComputePixelSize(GLenum format, GLenum type) ...@@ -247,6 +247,28 @@ int ComputePixelSize(GLenum format, GLenum type)
case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5:
return sizeof(unsigned short); 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(); default: UNREACHABLE();
} }
...@@ -283,6 +305,21 @@ bool CheckTextureFormatType(GLenum format, GLenum type) ...@@ -283,6 +305,21 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
return false; 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_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_5_5_1:
return (format == GL_RGBA); 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