Commit c0632c94 by Alexis Hetu Committed by Alexis Hétu

Added support for sampler2DRect in ESSL3

Being able to sample from sampler2DRect using the "texture" function is required for Chromium on Mac. Change-Id: Iea8970aaec29734a251bcfc19a03223d0ebfbc7e Reviewed-on: https://swiftshader-review.googlesource.com/17572Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 3c00576b
......@@ -250,6 +250,9 @@ void InsertBuiltInFunctions(GLenum type, const ShBuiltInResources &resources, TS
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2);
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float3);
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float4);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", sampler2DRect, float2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", sampler2DRect, float3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", sampler2DRect, float4);
}
if(resources.OES_EGL_image_external)
......
......@@ -421,11 +421,11 @@ namespace glsl
{
TString name = TFunction::unmangleName(nodeName);
if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D")
if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D" || name == "texture2DRect")
{
method = IMPLICIT;
}
else if(name == "texture2DProj" || name == "textureProj")
else if(name == "texture2DProj" || name == "textureProj" || name == "texture2DRectProj")
{
method = IMPLICIT;
proj = true;
......@@ -494,15 +494,6 @@ namespace glsl
proj = true;
offset = true;
}
else if(name == "texture2DRect")
{
method = RECT;
}
else if(name == "texture2DRectProj")
{
method = RECT;
proj = true;
}
else UNREACHABLE(0);
}
......@@ -1470,9 +1461,6 @@ namespace glsl
}
else UNREACHABLE(argumentCount);
break;
case TextureFunction::RECT:
emit(sw::Shader::OPCODE_TEXRECT, result, &coord, s);
break;
case TextureFunction::SIZE:
emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], s);
break;
......
......@@ -246,7 +246,6 @@ namespace glsl
SIZE, // textureSize()
FETCH,
GRAD,
RECT,
};
Method method;
......
......@@ -3170,8 +3170,9 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
{
int baseLevel = baseTexture->getBaseLevel();
int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
GLenum target = baseTexture->getTarget();
switch(baseTexture->getTarget())
switch(target)
{
case GL_TEXTURE_2D:
case GL_TEXTURE_EXTERNAL_OES:
......@@ -3189,7 +3190,8 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
}
egl::Image *surface = texture->getImage(surfaceLevel);
device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
device->setTextureLevel(sampler, 0, mipmapLevel, surface,
(target == GL_TEXTURE_RECTANGLE_ARB) ? sw::TEXTURE_RECTANGLE : sw::TEXTURE_2D);
}
}
break;
......
......@@ -69,6 +69,7 @@ namespace sw
{
TEXTURE_NULL,
TEXTURE_2D,
TEXTURE_RECTANGLE,
TEXTURE_CUBE,
TEXTURE_3D,
TEXTURE_2D_ARRAY,
......
......@@ -297,7 +297,6 @@ namespace sw
case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_TEXBIAS: TEXBIAS(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEXOFFSETBIAS: TEXOFFSETBIAS(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXRECT: TEXRECT(d, s0, src1); break;
case Shader::OPCODE_DISCARD: DISCARD(cMask, instruction); break;
case Shader::OPCODE_DFDX: DFDX(d, s0); break;
case Shader::OPCODE_DFDY: DFDY(d, s0); break;
......@@ -1179,11 +1178,6 @@ namespace sw
dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
}
void PixelProgram::TEXRECT(Vector4f &dst, Vector4f &src0, const Src &src1)
{
dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), (src0), Rectangle);
}
void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
{
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + src1.index * sizeof(Texture);
......
......@@ -118,7 +118,6 @@ namespace sw
void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &offset, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &dsx, Vector4f &dsy);
void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void TEXRECT(Vector4f &dst, Vector4f &src0, const Src &src1);
void DISCARD(Int cMask[4], const Shader::Instruction *instruction);
void DFDX(Vector4f &dst, Vector4f &src);
void DFDY(Vector4f &dst, Vector4f &src);
......
......@@ -323,7 +323,6 @@ namespace sw
case Shader::OPCODE_TEXELFETCHOFFSET:
case Shader::OPCODE_TEXGRAD:
case Shader::OPCODE_TEXGRADOFFSET:
case Shader::OPCODE_TEXRECT:
{
int sampler = inst->src[1].index;
......
......@@ -299,7 +299,7 @@ namespace sw
// FIXME: YUV is not supported by the floating point path
bool forceFloatFiltering = state.highPrecisionFiltering && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
bool rectangleTexture = (function == Rectangle);
bool rectangleTexture = (state.textureType == TEXTURE_RECTANGLE);
if(hasFloatTexture() || hasUnnormalizedIntegerTexture() || forceFloatFiltering || seamlessCube || rectangleTexture) // FIXME: Mostly identical to integer sampling
{
Float4 uuuu = u;
......@@ -2368,7 +2368,7 @@ namespace sw
Float4 coord = uvw;
if(function == Rectangle)
if(state.textureType == TEXTURE_RECTANGLE)
{
coord = Min(Max(coord, Float4(0.0f)), Float4(dim - Int4(1)));
}
......
......@@ -27,7 +27,6 @@ namespace sw
Lod, // Use provided LOD.
Grad, // Use provided gradients.
Fetch, // Use provided integer coordinates.
Rectangle, // Use non normalized texture coordinates.
Base // Sample base level.
};
......
......@@ -904,7 +904,6 @@ namespace sw
case OPCODE_TEXELFETCHOFFSET: return "texelfetchoffset";
case OPCODE_TEXGRAD: return "texgrad";
case OPCODE_TEXGRADOFFSET: return "texgradoffset";
case OPCODE_TEXRECT: return "texrect";
case OPCODE_BREAKP: return "breakp";
case OPCODE_TEXSIZE: return "texsize";
case OPCODE_PHASE: return "phase";
......@@ -1851,7 +1850,6 @@ namespace sw
case OPCODE_TEXELFETCHOFFSET:
case OPCODE_TEXGRAD:
case OPCODE_TEXGRADOFFSET:
case OPCODE_TEXRECT:
{
Parameter &dst = inst->dst;
Parameter &src1 = inst->src[1];
......
......@@ -214,7 +214,6 @@ namespace sw
OPCODE_TEXBIAS,
OPCODE_TEXLOD,
OPCODE_TEXOFFSETBIAS,
OPCODE_TEXRECT,
OPCODE_TEXSIZE,
OPCODE_FLOATBITSTOINT,
OPCODE_FLOATBITSTOUINT,
......
......@@ -336,7 +336,6 @@ namespace sw
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_TEXRECT: TEXRECT(d, s0, src1); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break;
case Shader::OPCODE_END: break;
default:
......@@ -1553,11 +1552,6 @@ namespace sw
dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
}
void VertexProgram::TEXRECT(Vector4f &dst, Vector4f &src0, const Src &src1)
{
dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), (src0), Rectangle);
}
void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
{
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + src1.index * sizeof(Texture);
......
......@@ -115,7 +115,6 @@ namespace sw
void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy);
void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void TEXRECT(Vector4f &dst, Vector4f &src0, const Src &src1);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src&);
Vector4f sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
......
......@@ -530,6 +530,99 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle)
Uninitialize();
}
// Test sampling from a rectangle texture
TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
EXPECT_EQ(GL_NONE, glGetError());
unsigned char green[4] = { 0, 255, 0, 255 };
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
EXPECT_EQ(GL_NONE, glGetError());
const std::string vs =
"#version 300 es\n"
"in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position.xy, 0.0, 1.0);\n"
"}\n";
const std::string fs =
"#version 300 es\n"
"#extension GL_ARB_texture_rectangle : require\n"
"precision mediump float;\n"
"uniform sampler2DRect tex;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
" fragColor = texture(tex, vec2(0, 0));\n"
"}\n";
GLuint program = glCreateProgram();
EXPECT_EQ(GL_NONE, glGetError());
GLuint vsShader = glCreateShader(GL_VERTEX_SHADER);
const char* vsSource[1] = { vs.c_str() };
glShaderSource(vsShader, 1, vsSource, nullptr);
glCompileShader(vsShader);
EXPECT_EQ(GL_NONE, glGetError());
GLuint fsShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fsSource[1] = { fs.c_str() };
glShaderSource(fsShader, 1, fsSource, nullptr);
glCompileShader(fsShader);
EXPECT_EQ(GL_NONE, glGetError());
glAttachShader(program, vsShader);
glAttachShader(program, fsShader);
glLinkProgram(program);
EXPECT_EQ(GL_NONE, glGetError());
glUseProgram(program);
GLint location = glGetUniformLocation(program, "tex");
ASSERT_NE(-1, location);
glUniform1i(location, 0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(GL_NONE, glGetError());
GLint prevProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);
glUseProgram(program);
EXPECT_EQ(GL_NONE, glGetError());
GLint posLoc = glGetAttribLocation(program, "position");
EXPECT_EQ(GL_NONE, glGetError());
float vertices[18] = { -1.0f, 1.0f, 0.5f,
-1.0f, -1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
-1.0f, 1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
1.0f, 1.0f, 0.5f };
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(posLoc);
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_EQ(GL_NONE, glGetError());
glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
glDisableVertexAttribArray(posLoc);
glUseProgram(prevProgram);
EXPECT_EQ(GL_NONE, glGetError());
compareColor(green);
EXPECT_EQ(GL_NONE, glGetError());
Uninitialize();
}
// Test attaching a rectangle texture and rendering to it.
TEST_F(SwiftShaderTest, TextureRectangle_RenderToRectangle)
{
......
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