Commit b66a9097 by Geoff Lang Committed by Commit Bot

Add support for OES_EGL_image_external and OES_EGL_image_external_essl3.

BUG=angleproject:1372 Change-Id: I8489e7fd0ab409b0775041ad5e9fbf0aab53886d Reviewed-on: https://chromium-review.googlesource.com/344734Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent a0d3aa41
...@@ -48,7 +48,7 @@ typedef unsigned int GLenum; ...@@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 145 #define ANGLE_SH_VERSION 146
typedef enum { typedef enum {
SH_GLES2_SPEC = 0x8B40, SH_GLES2_SPEC = 0x8B40,
...@@ -255,6 +255,7 @@ typedef struct ...@@ -255,6 +255,7 @@ typedef struct
// Set to 1 to enable the extension, else 0. // Set to 1 to enable the extension, else 0.
int OES_standard_derivatives; int OES_standard_derivatives;
int OES_EGL_image_external; int OES_EGL_image_external;
int OES_EGL_image_external_essl3;
int NV_EGL_stream_consumer_external; int NV_EGL_stream_consumer_external;
int ARB_texture_rectangle; int ARB_texture_rectangle;
int EXT_blend_func_extended; int EXT_blend_func_extended;
......
...@@ -480,6 +480,8 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType) ...@@ -480,6 +480,8 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
void TCompiler::setResourceString() void TCompiler::setResourceString()
{ {
std::ostringstream strstream; std::ostringstream strstream;
// clang-format off
strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
<< ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
<< ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
...@@ -490,6 +492,8 @@ void TCompiler::setResourceString() ...@@ -490,6 +492,8 @@ void TCompiler::setResourceString()
<< ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
<< ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
<< ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
<< ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
<< ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
<< ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
<< ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
...@@ -509,6 +513,7 @@ void TCompiler::setResourceString() ...@@ -509,6 +513,7 @@ void TCompiler::setResourceString()
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision; << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
// clang-format on
builtInResourcesString = strstream.str(); builtInResourcesString = strstream.str();
} }
......
...@@ -315,6 +315,17 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR ...@@ -315,6 +315,17 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float4);
}
if (type == GL_FRAGMENT_SHADER) if (type == GL_FRAGMENT_SHADER)
{ {
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
...@@ -324,6 +335,18 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR ...@@ -324,6 +335,18 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2,
float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float4, float1);
}
} }
const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow); const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow);
...@@ -351,6 +374,13 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR ...@@ -351,6 +374,13 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
}
if (type == GL_FRAGMENT_SHADER) if (type == GL_FRAGMENT_SHADER)
{ {
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType); symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType);
...@@ -403,6 +433,14 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR ...@@ -403,6 +433,14 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2,
int1);
}
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
...@@ -594,6 +632,8 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, ...@@ -594,6 +632,8 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_OES_standard_derivatives"] = EBhUndefined; extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
if (resources.OES_EGL_image_external) if (resources.OES_EGL_image_external)
extBehavior["GL_OES_EGL_image_external"] = EBhUndefined; extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
if (resources.OES_EGL_image_external_essl3)
extBehavior["GL_OES_EGL_image_external_essl3"] = EBhUndefined;
if (resources.NV_EGL_stream_consumer_external) if (resources.NV_EGL_stream_consumer_external)
extBehavior["GL_NV_EGL_stream_consumer_external"] = EBhUndefined; extBehavior["GL_NV_EGL_stream_consumer_external"] = EBhUndefined;
if (resources.ARB_texture_rectangle) if (resources.ARB_texture_rectangle)
......
...@@ -148,6 +148,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) ...@@ -148,6 +148,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
// Extensions. // Extensions.
resources->OES_standard_derivatives = 0; resources->OES_standard_derivatives = 0;
resources->OES_EGL_image_external = 0; resources->OES_EGL_image_external = 0;
resources->OES_EGL_image_external_essl3 = 0;
resources->NV_EGL_stream_consumer_external = 0;
resources->ARB_texture_rectangle = 0; resources->ARB_texture_rectangle = 0;
resources->EXT_blend_func_extended = 0; resources->EXT_blend_func_extended = 0;
resources->EXT_draw_buffers = 0; resources->EXT_draw_buffers = 0;
......
...@@ -201,6 +201,7 @@ int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunctio ...@@ -201,6 +201,7 @@ int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunctio
switch (textureFunction.sampler) switch (textureFunction.sampler)
{ {
case EbtSampler2D: case EbtSampler2D:
case EbtSamplerExternalOES:
hlslCoords = 2; hlslCoords = 2;
break; break;
case EbtSamplerCube: case EbtSamplerCube:
...@@ -275,6 +276,7 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out, ...@@ -275,6 +276,7 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
switch (textureFunction.sampler) switch (textureFunction.sampler)
{ {
case EbtSampler2D: case EbtSampler2D:
case EbtSamplerExternalOES:
out << "sampler2D s"; out << "sampler2D s";
break; break;
case EbtSamplerCube: case EbtSamplerCube:
...@@ -790,6 +792,7 @@ void OutputTextureSampleFunctionReturnStatement( ...@@ -790,6 +792,7 @@ void OutputTextureSampleFunctionReturnStatement(
switch (textureFunction.sampler) switch (textureFunction.sampler)
{ {
case EbtSampler2D: case EbtSampler2D:
case EbtSamplerExternalOES:
out << "tex2D"; out << "tex2D";
break; break;
case EbtSamplerCube: case EbtSamplerCube:
......
...@@ -50,8 +50,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &data) ...@@ -50,8 +50,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &data)
mResources.OES_standard_derivatives = extensions.standardDerivatives; mResources.OES_standard_derivatives = extensions.standardDerivatives;
mResources.EXT_draw_buffers = extensions.drawBuffers; mResources.EXT_draw_buffers = extensions.drawBuffers;
mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD; mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD;
// TODO: disabled until the extension is actually supported. mResources.OES_EGL_image_external = extensions.eglImageExternal;
mResources.OES_EGL_image_external = 0; mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3;
mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal; mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal;
// TODO: use shader precision caps to determine if high precision is supported? // TODO: use shader precision caps to determine if high precision is supported?
mResources.FragmentPrecisionHigh = 1; mResources.FragmentPrecisionHigh = 1;
......
...@@ -2089,6 +2089,7 @@ void Context::initCaps(GLuint clientVersion) ...@@ -2089,6 +2089,7 @@ void Context::initCaps(GLuint clientVersion)
{ {
// Disable ES3+ extensions // Disable ES3+ extensions
mExtensions.colorBufferFloat = false; mExtensions.colorBufferFloat = false;
mExtensions.eglImageExternalEssl3 = false;
} }
if (clientVersion > 2) if (clientVersion > 2)
......
...@@ -61,7 +61,7 @@ TextureState::TextureState(GLenum target) ...@@ -61,7 +61,7 @@ TextureState::TextureState(GLenum target)
swizzleGreen(GL_GREEN), swizzleGreen(GL_GREEN),
swizzleBlue(GL_BLUE), swizzleBlue(GL_BLUE),
swizzleAlpha(GL_ALPHA), swizzleAlpha(GL_ALPHA),
samplerState(), samplerState(SamplerState::CreateDefaultForTarget(target)),
baseLevel(0), baseLevel(0),
maxLevel(1000), maxLevel(1000),
immutableFormat(false), immutableFormat(false),
...@@ -755,7 +755,7 @@ void Texture::releaseTexImageInternal() ...@@ -755,7 +755,7 @@ void Texture::releaseTexImageInternal()
Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget) Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget)
{ {
ASSERT(target == mState.target); ASSERT(target == mState.target);
ASSERT(target == GL_TEXTURE_2D); ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES);
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal(); releaseTexImageInternal();
...@@ -847,6 +847,27 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, ...@@ -847,6 +847,27 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState,
} }
} }
// From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a
// texture unit that would have been rejected by a call to TexParameter* for the texture bound
// to that unit, the behavior of the implementation is as if the texture were incomplete. For
// example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the
// sampler object bound to a texture unit and the texture bound to that unit is an external
// texture, the texture will be considered incomplete.
// Sampler object state which does not affect sampling for the type of texture bound to a
// texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect completeness.
if (mState.target == GL_TEXTURE_EXTERNAL_OES)
{
if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE)
{
return false;
}
if (samplerState.minFilter != GL_LINEAR && samplerState.minFilter != GL_NEAREST)
{
return false;
}
}
// OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if: // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
// The internalformat specified for the texture arrays is a sized internal depth or // The internalformat specified for the texture arrays is a sized internal depth or
// depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_- // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
......
...@@ -53,6 +53,23 @@ SamplerState::SamplerState() ...@@ -53,6 +53,23 @@ SamplerState::SamplerState()
{ {
} }
// static
SamplerState SamplerState::CreateDefaultForTarget(GLenum target)
{
SamplerState state;
// According to OES_EGL_image_external: For external textures, the default min filter is
// GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE.
if (target == GL_TEXTURE_EXTERNAL_OES)
{
state.minFilter = GL_LINEAR;
state.wrapS = GL_CLAMP_TO_EDGE;
state.wrapT = GL_CLAMP_TO_EDGE;
}
return state;
}
static void MinMax(int a, int b, int *minimum, int *maximum) static void MinMax(int a, int b, int *minimum, int *maximum)
{ {
if (a < b) if (a < b)
......
...@@ -194,6 +194,7 @@ struct DepthStencilState ...@@ -194,6 +194,7 @@ struct DepthStencilState
struct SamplerState struct SamplerState
{ {
SamplerState(); SamplerState();
static SamplerState CreateDefaultForTarget(GLenum target);
GLenum minFilter; GLenum minFilter;
GLenum magFilter; GLenum magFilter;
......
...@@ -3178,21 +3178,17 @@ void TextureD3D_2DArray::markAllImagesDirty() ...@@ -3178,21 +3178,17 @@ void TextureD3D_2DArray::markAllImagesDirty()
TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer) TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(state, renderer) : TextureD3D(state, renderer)
{ {
mImage = renderer->createImage();
} }
TextureD3D_External::~TextureD3D_External() TextureD3D_External::~TextureD3D_External()
{ {
SafeDelete(mImage);
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
} }
ImageD3D *TextureD3D_External::getImage(const gl::ImageIndex &index) const ImageD3D *TextureD3D_External::getImage(const gl::ImageIndex &index) const
{ {
// External images only have one mipmap level UNREACHABLE();
ASSERT(index.type == GL_TEXTURE_EXTERNAL_OES); return nullptr;
ASSERT(index.mipIndex == 0);
return mImage;
} }
GLsizei TextureD3D_External::getLayerCount(int level) const GLsizei TextureD3D_External::getLayerCount(int level) const
...@@ -3200,29 +3196,6 @@ GLsizei TextureD3D_External::getLayerCount(int level) const ...@@ -3200,29 +3196,6 @@ GLsizei TextureD3D_External::getLayerCount(int level) const
return 1; return 1;
} }
GLsizei TextureD3D_External::getWidth(GLint level) const
{
ASSERT(level == 0);
return mImage->getWidth();
}
GLsizei TextureD3D_External::getHeight(GLint level) const
{
ASSERT(level == 0);
return mImage->getHeight();
}
GLenum TextureD3D_External::getInternalFormat(GLint level) const
{
ASSERT(level == 0);
return mImage->getInternalFormat();
}
bool TextureD3D_External::isDepth(GLint level) const
{
return false;
}
gl::Error TextureD3D_External::setImage(GLenum target, gl::Error TextureD3D_External::setImage(GLenum target,
size_t imageLevel, size_t imageLevel,
GLenum internalFormat, GLenum internalFormat,
...@@ -3308,15 +3281,11 @@ gl::Error TextureD3D_External::setImageExternal(GLenum target, ...@@ -3308,15 +3281,11 @@ gl::Error TextureD3D_External::setImageExternal(GLenum target,
{ {
ASSERT(target == GL_TEXTURE_EXTERNAL_OES); ASSERT(target == GL_TEXTURE_EXTERNAL_OES);
// If the strean is null, the external image is unbound and we release the storage SafeDelete(mTexStorage);
if (stream == nullptr)
{ // If the stream is null, the external image is unbound and we release the storage
SafeDelete(mTexStorage); if (stream != nullptr)
mTexStorage = nullptr;
}
else
{ {
SafeDelete(mTexStorage);
mTexStorage = mRenderer->createTextureStorageExternal(stream, desc); mTexStorage = mRenderer->createTextureStorageExternal(stream, desc);
} }
...@@ -3335,8 +3304,12 @@ void TextureD3D_External::releaseTexImage() ...@@ -3335,8 +3304,12 @@ void TextureD3D_External::releaseTexImage()
gl::Error TextureD3D_External::setEGLImageTarget(GLenum target, egl::Image *image) gl::Error TextureD3D_External::setEGLImageTarget(GLenum target, egl::Image *image)
{ {
UNREACHABLE(); EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
return gl::Error(GL_INVALID_OPERATION);
SafeDelete(mTexStorage);
mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d);
return gl::NoError();
} }
void TextureD3D_External::initMipmapsImages() void TextureD3D_External::initMipmapsImages()
...@@ -3350,19 +3323,9 @@ gl::Error TextureD3D_External::getRenderTarget(const gl::ImageIndex &index, Rend ...@@ -3350,19 +3323,9 @@ gl::Error TextureD3D_External::getRenderTarget(const gl::ImageIndex &index, Rend
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
bool TextureD3D_External::isValidLevel(int level) const
{
return (level == 0);
}
bool TextureD3D_External::isLevelComplete(int level) const
{
return (level == 0) ? (mTexStorage != nullptr) : false;
}
bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const
{ {
return isLevelComplete(index.mipIndex); return (index.mipIndex == 0) ? (mTexStorage != nullptr) : false;
} }
gl::Error TextureD3D_External::initializeStorage(bool renderTarget) gl::Error TextureD3D_External::initializeStorage(bool renderTarget)
...@@ -3393,20 +3356,6 @@ gl::Error TextureD3D_External::updateStorage() ...@@ -3393,20 +3356,6 @@ gl::Error TextureD3D_External::updateStorage()
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error TextureD3D_External::updateStorageLevel(int level)
{
UNREACHABLE();
return gl::Error(GL_NO_ERROR);
}
void TextureD3D_External::redefineImage(size_t level,
GLenum internalformat,
const gl::Extents &size,
bool forceRelease)
{
UNREACHABLE();
}
gl::ImageIndexIterator TextureD3D_External::imageIterator() const gl::ImageIndexIterator TextureD3D_External::imageIterator() const
{ {
return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount()); return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
......
...@@ -413,11 +413,6 @@ class TextureD3D_External : public TextureD3D ...@@ -413,11 +413,6 @@ class TextureD3D_External : public TextureD3D
ImageD3D *getImage(const gl::ImageIndex &index) const override; ImageD3D *getImage(const gl::ImageIndex &index) const override;
GLsizei getLayerCount(int level) const override; GLsizei getLayerCount(int level) const override;
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
gl::Error setImage(GLenum target, gl::Error setImage(GLenum target,
size_t level, size_t level,
GLenum internalFormat, GLenum internalFormat,
...@@ -492,18 +487,7 @@ class TextureD3D_External : public TextureD3D ...@@ -492,18 +487,7 @@ class TextureD3D_External : public TextureD3D
gl::Error updateStorage() override; gl::Error updateStorage() override;
void initMipmapsImages() override; void initMipmapsImages() override;
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
bool isImageComplete(const gl::ImageIndex &index) const override; bool isImageComplete(const gl::ImageIndex &index) const override;
gl::Error updateStorageLevel(int level);
void redefineImage(size_t level,
GLenum internalformat,
const gl::Extents &size,
bool forceRelease);
ImageD3D *mImage;
}; };
} }
......
...@@ -1231,6 +1231,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons ...@@ -1231,6 +1231,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
extensions->fboRenderMipmap = false; extensions->fboRenderMipmap = false;
extensions->debugMarker = true; extensions->debugMarker = true;
extensions->eglImage = true; extensions->eglImage = true;
extensions->eglImageExternal = true;
extensions->eglImageExternalEssl3 = true;
extensions->eglStreamConsumerExternal = true; extensions->eglStreamConsumerExternal = true;
extensions->unpackSubimage = true; extensions->unpackSubimage = true;
extensions->packSubimage = true; extensions->packSubimage = true;
......
...@@ -69,6 +69,8 @@ TextureImpl *Context9::createTexture(const gl::TextureState &state) ...@@ -69,6 +69,8 @@ TextureImpl *Context9::createTexture(const gl::TextureState &state)
return new TextureD3D_2D(state, mRenderer); return new TextureD3D_2D(state, mRenderer);
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
return new TextureD3D_Cube(state, mRenderer); return new TextureD3D_Cube(state, mRenderer);
case GL_TEXTURE_EXTERNAL_OES:
return new TextureD3D_External(state, mRenderer);
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -1657,6 +1657,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, ...@@ -1657,6 +1657,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
{ {
case GL_SAMPLER_2D: case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE: case GL_SAMPLER_CUBE:
case GL_SAMPLER_EXTERNAL_OES:
break; break;
case GL_BOOL: case GL_BOOL:
case GL_BOOL_VEC2: case GL_BOOL_VEC2:
......
...@@ -590,6 +590,7 @@ void GenerateCaps(IDirect3D9 *d3d9, ...@@ -590,6 +590,7 @@ void GenerateCaps(IDirect3D9 *d3d9,
extensions->colorBufferFloat = false; extensions->colorBufferFloat = false;
extensions->debugMarker = true; extensions->debugMarker = true;
extensions->eglImage = true; extensions->eglImage = true;
extensions->eglImageExternal = true;
extensions->unpackSubimage = true; extensions->unpackSubimage = true;
extensions->packSubimage = true; extensions->packSubimage = true;
extensions->vertexArrayObject = true; extensions->vertexArrayObject = true;
......
...@@ -857,13 +857,18 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam ...@@ -857,13 +857,18 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam
case GL_TEXTURE_COMPARE_FUNC: case GL_TEXTURE_COMPARE_FUNC:
case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_MAX_LOD:
// ES3 texture paramters are not supported on external textures as the extension is if (context->getClientVersion() < 3)
// written against ES2.
if (context->getClientVersion() < 3 || target == GL_TEXTURE_EXTERNAL_OES)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
if (target == GL_TEXTURE_EXTERNAL_OES && !context->getExtensions().eglImageExternalEssl3)
{
context->handleError(Error(GL_INVALID_ENUM,
"ES3 texture parameters are not available without "
"GL_OES_EGL_image_external_essl3."));
return false;
}
break; break;
default: break; default: break;
...@@ -1014,16 +1019,20 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam ...@@ -1014,16 +1019,20 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam
break; break;
case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MAX_LEVEL: if (param < 0)
if (target == GL_TEXTURE_EXTERNAL_OES) {
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
if (target == GL_TEXTURE_EXTERNAL_OES && param != 0)
{ {
// This is not specified, but in line with the spirit of OES_EGL_image_external spec,
// which generally forbids setting mipmap related parameters on external textures.
context->handleError( context->handleError(
Error(GL_INVALID_OPERATION, Error(GL_INVALID_OPERATION, "Base level must be 0 for external textures."));
"Setting the base level or max level of external textures not supported"));
return false; return false;
} }
return true;
case GL_TEXTURE_MAX_LEVEL:
if (param < 0) if (param < 0)
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
...@@ -2398,6 +2407,20 @@ bool ValidateEGLImageTargetTexture2DOES(Context *context, ...@@ -2398,6 +2407,20 @@ bool ValidateEGLImageTargetTexture2DOES(Context *context,
switch (target) switch (target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
if (!context->getExtensions().eglImage)
{
context->handleError(Error(
GL_INVALID_ENUM, "GL_TEXTURE_2D texture target requires GL_OES_EGL_image."));
}
break;
case GL_TEXTURE_EXTERNAL_OES:
if (!context->getExtensions().eglImageExternal)
{
context->handleError(Error(
GL_INVALID_ENUM,
"GL_TEXTURE_EXTERNAL_OES texture target requires GL_OES_EGL_image_external."));
}
break; break;
default: default:
......
...@@ -1997,7 +1997,8 @@ bool ValidateBindTexture(Context *context, GLenum target, GLuint texture) ...@@ -1997,7 +1997,8 @@ bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
} }
break; break;
case GL_TEXTURE_EXTERNAL_OES: case GL_TEXTURE_EXTERNAL_OES:
if (!context->getExtensions().eglStreamConsumerExternal) if (!context->getExtensions().eglImageExternal &&
!context->getExtensions().eglStreamConsumerExternal)
{ {
context->handleError( context->handleError(
Error(GL_INVALID_ENUM, "External texture extension not enabled")); Error(GL_INVALID_ENUM, "External texture extension not enabled"));
......
...@@ -2279,7 +2279,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) ...@@ -2279,7 +2279,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
if (!ValidTextureTarget(context, target)) if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
{ {
context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target")); context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
return; return;
...@@ -2434,7 +2434,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) ...@@ -2434,7 +2434,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
if (!ValidTextureTarget(context, target)) if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
{ {
context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target")); context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
return; return;
......
...@@ -358,37 +358,79 @@ TEST_P(EGLStreamTest, StreamProducerTextureNV12End2End) ...@@ -358,37 +358,79 @@ TEST_P(EGLStreamTest, StreamProducerTextureNV12End2End)
{ {
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
EGLDisplay display = window->getDisplay(); EGLDisplay display = window->getDisplay();
const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS); if (!eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture_nv12"))
if (strstr(extensionsString, "EGL_ANGLE_stream_producer_d3d_texture_nv12") == nullptr)
{ {
std::cout << "Stream producer d3d nv12 texture not supported" << std::endl; std::cout << "Stream producer d3d nv12 texture not supported" << std::endl;
return; return;
} }
// Shader setup bool useESSL3Shaders =
const std::string yuvVS = getClientVersion() >= 3 && extensionEnabled("GL_OES_EGL_image_external_essl3");
"attribute highp vec4 position; varying vec2 texcoord; void main(void)\n"
"{\n"
" gl_Position = position;\n"
" texcoord = (position.xy * 0.5) + 0.5;\n"
" texcoord.y = 1.0 - texcoord.y;\n"
"}\n";
// yuv to rgb conversion shader using Microsoft's given conversion formulas // yuv to rgb conversion shader using Microsoft's given conversion formulas
const std::string yuvPS = std::string yuvVS, yuvPS;
"#extension GL_NV_EGL_stream_consumer_external : require\n" if (useESSL3Shaders)
"precision highp float; varying vec2 texcoord;\n" {
"uniform samplerExternalOES y; uniform samplerExternalOES uv\n;" yuvVS =
"void main(void)\n" "#version 300 es\n"
"{\n" "in highp vec4 position;\n"
" float c = texture2D(y, texcoord).r - (16.0 / 256.0);\n" "out vec2 texcoord;\n"
" float d = texture2D(uv, texcoord).r - 0.5;\n" "void main(void)\n"
" float e = texture2D(uv, texcoord).g - 0.5;\n" "{\n"
" float r = 1.164383 * c + 1.596027 * e;\n" " gl_Position = position;\n"
" float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n" " texcoord = (position.xy * 0.5) + 0.5;\n"
" float b = 1.164383 * c + 2.017232 * d;\n" " texcoord.y = 1.0 - texcoord.y;\n"
" gl_FragColor = vec4(r, g, b, 1.0);\n" "}\n";
"}\n"; yuvPS =
"#version 300 es\n"
"#extension GL_OES_EGL_image_external_essl3 : require\n"
"#extension GL_NV_EGL_stream_consumer_external : require\n"
"precision highp float;\n"
"in vec2 texcoord;\n"
"out vec4 color;\n"
"uniform samplerExternalOES y;\n"
"uniform samplerExternalOES uv\n;"
"void main(void)\n"
"{\n"
" float c = texture(y, texcoord).r - (16.0 / 256.0);\n"
" float d = texture(uv, texcoord).r - 0.5;\n"
" float e = texture(uv, texcoord).g - 0.5;\n"
" float r = 1.164383 * c + 1.596027 * e;\n"
" float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
" float b = 1.164383 * c + 2.017232 * d;\n"
" color = vec4(r, g, b, 1.0);\n"
"}\n";
}
else
{
yuvVS =
"attribute highp vec4 position;\n"
"varying vec2 texcoord;\n"
"void main(void)\n"
"{\n"
" gl_Position = position;\n"
" texcoord = (position.xy * 0.5) + 0.5;\n"
" texcoord.y = 1.0 - texcoord.y;\n"
"}\n";
yuvPS =
"#extension GL_NV_EGL_stream_consumer_external : require\n"
"precision highp float;\n"
"varying vec2 texcoord;\n"
"uniform samplerExternalOES y;\n"
"uniform samplerExternalOES uv\n;"
"void main(void)\n"
"{\n"
" float c = texture2D(y, texcoord).r - (16.0 / 256.0);\n"
" float d = texture2D(uv, texcoord).r - 0.5;\n"
" float e = texture2D(uv, texcoord).g - 0.5;\n"
" float r = 1.164383 * c + 1.596027 * e;\n"
" float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
" float b = 1.164383 * c + 2.017232 * d;\n"
" gl_FragColor = vec4(r, g, b, 1.0);\n"
"}\n";
}
GLuint program = CompileProgram(yuvVS, yuvPS); GLuint program = CompileProgram(yuvVS, yuvPS);
ASSERT_NE(0u, program); ASSERT_NE(0u, program);
GLuint yUniform = glGetUniformLocation(program, "y"); GLuint yUniform = glGetUniformLocation(program, "y");
......
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