Commit 76b10c9a by Geoff Lang

Use dynamically sized containers for texture and sampler bindings.

BUG=angle:685 Change-Id: I7af97a95deee69fbdebca2b57403244f45516e67 Reviewed-on: https://chromium-review.googlesource.com/216564Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent ac7579c2
......@@ -43,6 +43,7 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
ASSERT(robustAccess == false); // Unimplemented
initCaps(clientVersion);
mState.initialize(mCaps, clientVersion);
mClientVersion = clientVersion;
......@@ -64,16 +65,26 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
mTexture2DZero.set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
mTexture3DZero.set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
bindTexture(GL_TEXTURE_2D, 0);
mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
bindTexture(GL_TEXTURE_CUBE_MAP, 0);
if (mClientVersion >= 3)
{
// TODO: These could also be enabled via extension
mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
bindTexture(GL_TEXTURE_3D, 0);
mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
bindTexture(GL_TEXTURE_2D_ARRAY, 0);
}
bindVertexArray(0);
bindArrayBuffer(0);
bindElementArrayBuffer(0);
bindTextureCubeMap(0);
bindTexture2D(0);
bindReadFramebuffer(0);
bindDrawFramebuffer(0);
bindRenderbuffer(0);
......@@ -151,15 +162,17 @@ Context::~Context()
deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
}
for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
{
mIncompleteTextures[type].set(NULL);
i->second.set(NULL);
}
mIncompleteTextures.clear();
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
mTexture3DZero.set(NULL);
mTexture2DArrayZero.set(NULL);
for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
{
i->second.set(NULL);
}
mZeroTextures.clear();
mResourceManager->release();
}
......@@ -501,32 +514,11 @@ void Context::bindElementArrayBuffer(unsigned int buffer)
mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
}
void Context::bindTexture2D(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
mState.setSamplerTexture(TEXTURE_2D, getTexture(texture));
}
void Context::bindTextureCubeMap(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
mState.setSamplerTexture(TEXTURE_CUBE, getTexture(texture));
}
void Context::bindTexture3D(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
mState.setSamplerTexture(TEXTURE_3D, getTexture(texture));
}
void Context::bindTexture2DArray(GLuint texture)
void Context::bindTexture(GLenum target, GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
mResourceManager->checkTextureAllocation(texture, target);
mState.setSamplerTexture(TEXTURE_2D_ARRAY, getTexture(texture));
mState.setSamplerTexture(target, getTexture(texture));
}
void Context::bindReadFramebuffer(GLuint framebuffer)
......@@ -569,7 +561,7 @@ void Context::bindVertexArray(GLuint vertexArray)
void Context::bindSampler(GLuint textureUnit, GLuint sampler)
{
ASSERT(textureUnit < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS); // TODO: Update for backend-determined array size
ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
mResourceManager->checkSamplerAllocation(sampler);
mState.setSamplerBinding(textureUnit, getSampler(sampler));
......@@ -824,36 +816,29 @@ Texture *Context::getTargetTexture(GLenum target) const
Texture2D *Context::getTexture2D() const
{
return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D));
return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
}
TextureCubeMap *Context::getTextureCubeMap() const
{
return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_CUBE));
return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
}
Texture3D *Context::getTexture3D() const
{
return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_3D));
return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
}
Texture2DArray *Context::getTexture2DArray() const
{
return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D_ARRAY));
return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
}
Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
if (mState.getSamplerTextureId(sampler, type) == 0)
{
switch (type)
{
default: UNREACHABLE();
case TEXTURE_2D: return mTexture2DZero.get();
case TEXTURE_CUBE: return mTextureCubeMapZero.get();
case TEXTURE_3D: return mTexture3DZero.get();
case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
}
return mZeroTextures.at(type).get();
}
else
{
......@@ -1405,63 +1390,54 @@ void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackA
programBinary->applyUniforms();
}
size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
TextureType *outTextureTypes, SamplerState *outSamplers)
void Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
{
size_t samplerRange = programBinary->getUsedSamplerRange(type);
for (size_t i = 0; i < samplerRange; i++)
{
outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps()); // OpenGL texture image unit index
GLenum textureType = programBinary->getSamplerTextureType(type, i);
GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
if (textureUnit != -1)
{
outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
outTextures[i]->getSamplerStateWithNativeOffset(&outSamplers[i]);
Sampler *samplerObject = mState.getSampler(textureUnit);
if (samplerObject)
Texture* texture = getSamplerTexture(textureUnit, textureType);
if (texture->getSamplerState().swizzleRequired())
{
samplerObject->getState(&outSamplers[i]);
mRenderer->generateSwizzle(texture);
}
}
else
{
outTextures[i] = NULL;
}
}
return samplerRange;
}
void Context::generateSwizzles(Texture *textures[], size_t count)
void Context::generateSwizzles(ProgramBinary *programBinary)
{
for (size_t i = 0; i < count; i++)
{
if (textures[i] && textures[i]->getSamplerState().swizzleRequired())
{
mRenderer->generateSwizzle(textures[i]);
}
}
generateSwizzles(programBinary, SAMPLER_VERTEX);
generateSwizzles(programBinary, SAMPLER_PIXEL);
}
// For each Direct3D sampler of either the pixel or vertex stage,
// looks up the corresponding OpenGL texture image unit and texture type,
// and sets the texture and its addressing/filtering state (or NULL when inactive).
void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
size_t framebufferSerialCount)
void Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
{
// Range of Direct3D samplers of given sampler type
size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
: mCaps.maxVertexTextureImageUnits;
for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
{
Texture *texture = textures[samplerIndex];
const SamplerState &sampler = samplers[samplerIndex];
TextureType textureType = textureTypes[samplerIndex];
if (texture)
GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
if (textureUnit != -1)
{
SamplerState sampler;
Texture* texture = getSamplerTexture(textureUnit, textureType);
texture->getSamplerStateWithNativeOffset(&sampler);
Sampler *samplerObject = mState.getSampler(textureUnit);
if (samplerObject)
{
samplerObject->getState(&sampler);
}
// TODO: std::binary_search may become unavailable using older versions of GCC
if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
!std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
......@@ -1471,22 +1447,36 @@ void Context::applyTextures(SamplerType shaderType, Texture *textures[], Texture
}
else
{
// Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
Texture *incompleteTexture = getIncompleteTexture(textureType);
mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
}
}
else
{
// No texture bound to this slot even though it is used by the shader, bind a NULL texture
mRenderer->setTexture(shaderType, samplerIndex, NULL);
}
}
for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
// Set all the remaining textures to NULL
size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
: mCaps.maxVertexTextureImageUnits;
for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
{
mRenderer->setTexture(shaderType, samplerIndex, NULL);
}
}
void Context::applyTextures(ProgramBinary *programBinary)
{
FramebufferTextureSerialArray framebufferSerials;
size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
}
bool Context::applyUniformBuffers()
{
Program *programObject = getProgram(mState.getCurrentProgramId());
......@@ -1683,18 +1673,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
ProgramBinary *programBinary = mState.getCurrentProgramBinary();
programBinary->updateSamplerMapping();
Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
generateSwizzles(vsTextures, vsTextureCount);
generateSwizzles(psTextures, psTextureCount);
generateSwizzles(programBinary);
if (!mRenderer->applyPrimitiveType(mode, count))
{
......@@ -1714,11 +1693,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
applyShaders(programBinary, transformFeedbackActive);
FramebufferTextureSerialArray frameBufferSerials;
size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
applyTextures(programBinary);
if (!applyUniformBuffers())
{
......@@ -1745,18 +1720,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type,
ProgramBinary *programBinary = mState.getCurrentProgramBinary();
programBinary->updateSamplerMapping();
Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
generateSwizzles(vsTextures, vsTextureCount);
generateSwizzles(psTextures, psTextureCount);
generateSwizzles(programBinary);
if (!mRenderer->applyPrimitiveType(mode, count))
{
......@@ -1791,11 +1755,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type,
applyShaders(programBinary, transformFeedbackActive);
FramebufferTextureSerialArray frameBufferSerials;
size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
applyTextures(programBinary);
if (!applyUniformBuffers())
{
......@@ -1981,22 +1941,21 @@ void Context::detachSampler(GLuint sampler)
mState.detachSampler(sampler);
}
Texture *Context::getIncompleteTexture(TextureType type)
Texture *Context::getIncompleteTexture(GLenum type)
{
Texture *t = mIncompleteTextures[type].get();
if (t == NULL)
if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
{
const GLubyte color[] = { 0, 0, 0, 255 };
const PixelUnpackState incompleteUnpackState(1);
Texture* t = NULL;
switch (type)
{
default:
UNREACHABLE();
// default falls through to TEXTURE_2D
case TEXTURE_2D:
case GL_TEXTURE_2D:
{
Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
......@@ -2004,7 +1963,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
}
break;
case TEXTURE_CUBE:
case GL_TEXTURE_CUBE_MAP:
{
TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
......@@ -2019,7 +1978,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
}
break;
case TEXTURE_3D:
case GL_TEXTURE_3D:
{
Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
......@@ -2028,7 +1987,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
}
break;
case TEXTURE_2D_ARRAY:
case GL_TEXTURE_2D_ARRAY:
{
Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
......@@ -2041,7 +2000,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
mIncompleteTextures[type].set(t);
}
return t;
return mIncompleteTextures[type].get();
}
bool Context::skipDraw(GLenum drawMode)
......@@ -2287,14 +2246,10 @@ void Context::initCaps(GLuint clientVersion)
// Apply implementation limits
mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
mCaps.maxVertexTextureImageUnits = std::min<GLuint>(mCaps.maxVertexTextureImageUnits, IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
mCaps.maxTextureImageUnits = std::min<GLuint>(mCaps.maxTextureImageUnits, MAX_TEXTURE_IMAGE_UNITS);
mCaps.maxCombinedTextureImageUnits = std::min<GLuint>(mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
GLuint maxSamples = 0;
mCaps.compressedTextureFormats.clear();
......
......@@ -115,10 +115,7 @@ class Context
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
void bindTexture3D(GLuint texture);
void bindTexture2DArray(GLuint texture);
void bindTexture(GLenum target, GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
......@@ -170,7 +167,7 @@ class Context
Texture3D *getTexture3D() const;
Texture2DArray *getTexture2DArray() const;
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
bool isSampler(GLuint samplerName) const;
......@@ -237,9 +234,9 @@ class Context
void applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode);
void applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
void applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
void applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
size_t framebufferSerialCount);
void applyTextures(ProgramBinary *programBinary);
bool applyUniformBuffers();
bool applyTransformFeedbackBuffers();
void markTransformFeedbackUsage();
......@@ -252,10 +249,10 @@ class Context
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
void generateSwizzles(Texture *textures[], size_t count);
size_t getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
TextureType *outTextureTypes, SamplerState *outSamplers);
Texture *getIncompleteTexture(TextureType type);
void generateSwizzles(ProgramBinary *programBinary, SamplerType type);
void generateSwizzles(ProgramBinary *programBinary);
Texture *getIncompleteTexture(GLenum type);
bool skipDraw(GLenum drawMode);
......@@ -276,10 +273,9 @@ class Context
int mClientVersion;
BindingPointer<Texture2D> mTexture2DZero;
BindingPointer<TextureCubeMap> mTextureCubeMapZero;
BindingPointer<Texture3D> mTexture3DZero;
BindingPointer<Texture2DArray> mTexture2DArrayZero;
typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
TextureMap mZeroTextures;
TextureMap mIncompleteTextures;
typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
......@@ -306,8 +302,6 @@ class Context
std::string mExtensionString;
std::vector<std::string> mExtensionStrings;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
// Recorded errors
typedef std::set<GLenum> ErrorSet;
ErrorSet mErrors;
......
......@@ -37,7 +37,7 @@ namespace gl
namespace
{
TextureType GetTextureType(GLenum samplerType)
GLenum GetTextureType(GLenum samplerType)
{
switch (samplerType)
{
......@@ -45,26 +45,26 @@ TextureType GetTextureType(GLenum samplerType)
case GL_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_SAMPLER_2D_SHADOW:
return TEXTURE_2D;
return GL_TEXTURE_2D;
case GL_SAMPLER_3D:
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
return TEXTURE_3D;
return GL_TEXTURE_3D;
case GL_SAMPLER_CUBE:
case GL_SAMPLER_CUBE_SHADOW:
return TEXTURE_CUBE;
return GL_TEXTURE_CUBE_MAP;
case GL_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
return TEXTURE_CUBE;
return GL_TEXTURE_CUBE_MAP;
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_ARRAY_SHADOW:
return TEXTURE_2D_ARRAY;
return GL_TEXTURE_2D_ARRAY;
default: UNREACHABLE();
}
return TEXTURE_2D;
return GL_TEXTURE_2D;
}
unsigned int ParseAndStripArrayIndex(std::string* name)
......@@ -207,16 +207,6 @@ ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
{
mSemanticIndex[index] = -1;
}
for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
{
mSamplersPS[index].active = false;
}
for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
{
mSamplersVS[index].active = false;
}
}
ProgramBinary::~ProgramBinary()
......@@ -380,8 +370,6 @@ bool ProgramBinary::usesGeometryShader() const
return usesPointSpriteEmulation();
}
// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
// index (0-15 for the pixel shader and 0-3 for the vertex shader).
GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
{
GLint logicalTextureUnit = -1;
......@@ -389,17 +377,15 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
switch (type)
{
case SAMPLER_PIXEL:
ASSERT(samplerIndex < ArraySize(mSamplersPS));
if (mSamplersPS[samplerIndex].active)
ASSERT(samplerIndex < caps.maxTextureImageUnits);
if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
{
logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
}
break;
case SAMPLER_VERTEX:
ASSERT(samplerIndex < ArraySize(mSamplersVS));
if (mSamplersVS[samplerIndex].active)
ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
{
logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
}
......@@ -417,22 +403,22 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
// Returns the texture type for a given Direct3D 9 sampler type and
// index (0-15 for the pixel shader and 0-3 for the vertex shader).
TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
switch (type)
{
case SAMPLER_PIXEL:
ASSERT(samplerIndex < ArraySize(mSamplersPS));
ASSERT(samplerIndex < mSamplersPS.size());
ASSERT(mSamplersPS[samplerIndex].active);
return mSamplersPS[samplerIndex].textureType;
case SAMPLER_VERTEX:
ASSERT(samplerIndex < ArraySize(mSamplersVS));
ASSERT(samplerIndex < mSamplersVS.size());
ASSERT(mSamplersVS[samplerIndex].active);
return mSamplersVS[samplerIndex].textureType;
default: UNREACHABLE();
}
return TEXTURE_2D;
return GL_TEXTURE_2D;
}
GLint ProgramBinary::getUniformLocation(std::string name)
......@@ -955,7 +941,7 @@ void ProgramBinary::updateSamplerMapping()
{
unsigned int samplerIndex = firstIndex + i;
if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
if (samplerIndex < mSamplersPS.size())
{
ASSERT(mSamplersPS[samplerIndex].active);
mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
......@@ -971,7 +957,7 @@ void ProgramBinary::updateSamplerMapping()
{
unsigned int samplerIndex = firstIndex + i;
if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
if (samplerIndex < mSamplersVS.size())
{
ASSERT(mSamplersVS[samplerIndex].active);
mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
......@@ -1142,18 +1128,23 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
initAttributesByLayout();
for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
const unsigned int psSamplerCount = stream.readInt<unsigned int>();
for (unsigned int i = 0; i < psSamplerCount; ++i)
{
stream.readBool(&mSamplersPS[i].active);
stream.readInt(&mSamplersPS[i].logicalTextureUnit);
stream.readInt(&mSamplersPS[i].textureType);
Sampler sampler;
stream.readBool(&sampler.active);
stream.readInt(&sampler.logicalTextureUnit);
stream.readInt(&sampler.textureType);
mSamplersPS.push_back(sampler);
}
for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
for (unsigned int i = 0; i < vsSamplerCount; ++i)
{
stream.readBool(&mSamplersVS[i].active);
stream.readInt(&mSamplersVS[i].logicalTextureUnit);
stream.readInt(&mSamplersVS[i].textureType);
Sampler sampler;
stream.readBool(&sampler.active);
stream.readInt(&sampler.logicalTextureUnit);
stream.readInt(&sampler.textureType);
mSamplersVS.push_back(sampler);
}
stream.readInt(&mUsedVertexSamplerRange);
......@@ -1383,14 +1374,16 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
stream.writeInt(mSemanticIndex[i]);
}
for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
stream.writeInt(mSamplersPS.size());
for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
{
stream.writeInt(mSamplersPS[i].active);
stream.writeInt(mSamplersPS[i].logicalTextureUnit);
stream.writeInt(mSamplersPS[i].textureType);
}
for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
stream.writeInt(mSamplersVS.size());
for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
{
stream.writeInt(mSamplersVS[i].active);
stream.writeInt(mSamplersVS[i].logicalTextureUnit);
......@@ -1591,6 +1584,9 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
reset();
mSamplersPS.resize(caps.maxTextureImageUnits);
mSamplersVS.resize(caps.maxVertexTextureImageUnits);
mTransformFeedbackBufferMode = transformFeedbackBufferMode;
rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
......@@ -1998,10 +1994,10 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
{
if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
&mUsedVertexSamplerRange, caps.maxVertexTextureImageUnits))
&mUsedVertexSamplerRange))
{
infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
caps.maxVertexTextureImageUnits);
mSamplersVS.size());
return false;
}
......@@ -2017,10 +2013,10 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
if (uniform.psRegisterIndex != GL_INVALID_INDEX)
{
if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
&mUsedPixelSamplerRange, caps.maxTextureImageUnits))
&mUsedPixelSamplerRange))
{
infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
caps.maxTextureImageUnits);
mSamplersPS.size());
return false;
}
......@@ -2062,20 +2058,20 @@ bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
GLenum samplerType,
unsigned int samplerCount,
Sampler *outArray,
GLuint *usedRange,
unsigned int limit)
std::vector<Sampler> &outSamplers,
GLuint *outUsedRange)
{
unsigned int samplerIndex = startSamplerIndex;
do
{
if (samplerIndex < limit)
if (samplerIndex < outSamplers.size())
{
outArray[samplerIndex].active = true;
outArray[samplerIndex].textureType = GetTextureType(samplerType);
outArray[samplerIndex].logicalTextureUnit = 0;
*usedRange = std::max(samplerIndex + 1, *usedRange);
Sampler& sampler = outSamplers[samplerIndex];
sampler.active = true;
sampler.textureType = GetTextureType(samplerType);
sampler.logicalTextureUnit = 0;
*outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
}
else
{
......@@ -2668,13 +2664,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
updateSamplerMapping();
const unsigned int maxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
{
textureUnitType[i] = TEXTURE_UNKNOWN;
}
std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
{
......@@ -2682,19 +2672,19 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
unsigned int unit = mSamplersPS[i].logicalTextureUnit;
if (unit >= maxCombinedTextureImageUnits)
if (unit >= textureUnitTypes.size())
{
if (infoLog)
{
infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
}
return false;
}
if (textureUnitType[unit] != TEXTURE_UNKNOWN)
if (textureUnitTypes[unit] != GL_NONE)
{
if (mSamplersPS[i].textureType != textureUnitType[unit])
if (mSamplersPS[i].textureType != textureUnitTypes[unit])
{
if (infoLog)
{
......@@ -2706,7 +2696,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
}
else
{
textureUnitType[unit] = mSamplersPS[i].textureType;
textureUnitTypes[unit] = mSamplersPS[i].textureType;
}
}
}
......@@ -2717,19 +2707,19 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
unsigned int unit = mSamplersVS[i].logicalTextureUnit;
if (unit >= maxCombinedTextureImageUnits)
if (unit >= textureUnitTypes.size())
{
if (infoLog)
{
infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
}
return false;
}
if (textureUnitType[unit] != TEXTURE_UNKNOWN)
if (textureUnitTypes[unit] != GL_NONE)
{
if (mSamplersVS[i].textureType != textureUnitType[unit])
if (mSamplersVS[i].textureType != textureUnitTypes[unit])
{
if (infoLog)
{
......@@ -2741,7 +2731,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
}
else
{
textureUnitType[unit] = mSamplersVS[i].textureType;
textureUnitTypes[unit] = mSamplersVS[i].textureType;
}
}
}
......@@ -2749,7 +2739,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
return true;
}
ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
{
}
......@@ -2807,14 +2797,9 @@ void ProgramBinary::reset()
mTransformFeedbackBufferMode = GL_NONE;
mTransformFeedbackLinkedVaryings.clear();
for (size_t i = 0; i < ArraySize(mSamplersPS); i++)
{
mSamplersPS[i] = Sampler();
}
for (size_t i = 0; i < ArraySize(mSamplersVS); i++)
{
mSamplersVS[i] = Sampler();
}
mSamplersPS.clear();
mSamplersVS.clear();
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
mUsesPointSize = false;
......
......@@ -110,7 +110,7 @@ class ProgramBinary : public RefCountObject
int getSemanticIndex(int attributeIndex);
GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps);
TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
bool usesPointSpriteEmulation() const;
......@@ -205,7 +205,7 @@ class ProgramBinary : public RefCountObject
bool active;
GLint logicalTextureUnit;
TextureType textureType;
GLenum textureType;
};
void reset();
......@@ -227,7 +227,7 @@ class ProgramBinary : public RefCountObject
bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps);
bool indexUniforms(InfoLog &infoLog, const Caps &caps);
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
Sampler *outArray, GLuint *usedRange, unsigned int limit);
std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
......@@ -303,8 +303,8 @@ class ProgramBinary : public RefCountObject
GLenum mTransformFeedbackBufferMode;
std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS];
Sampler mSamplersVS[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
std::vector<Sampler> mSamplersPS;
std::vector<Sampler> mSamplersVS;
GLuint mUsedVertexSamplerRange;
GLuint mUsedPixelSamplerRange;
bool mUsesPointSize;
......
......@@ -366,25 +366,25 @@ void ResourceManager::checkBufferAllocation(unsigned int buffer)
}
}
void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
{
if (!getTexture(texture) && texture != 0)
{
Texture *textureObject;
if (type == TEXTURE_2D)
if (type == GL_TEXTURE_2D)
{
textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
}
else if (type == TEXTURE_CUBE)
else if (type == GL_TEXTURE_CUBE_MAP)
{
textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
}
else if (type == TEXTURE_3D)
else if (type == GL_TEXTURE_3D)
{
textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
}
else if (type == TEXTURE_2D_ARRAY)
else if (type == GL_TEXTURE_2D_ARRAY)
{
textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
}
......
......@@ -65,11 +65,11 @@ class ResourceManager
Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
FenceSync *getFenceSync(GLuint handle);
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
void checkBufferAllocation(unsigned int buffer);
void checkTextureAllocation(GLuint texture, TextureType type);
void checkTextureAllocation(GLuint texture, GLenum type);
void checkRenderbufferAllocation(GLuint renderbuffer);
void checkSamplerAllocation(GLuint sampler);
......
......@@ -9,6 +9,7 @@
#include "libGLESv2/State.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Caps.h"
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Query.h"
#include "libGLESv2/Framebuffer.h"
......@@ -18,8 +19,18 @@
namespace gl
{
State::State()
{
}
State::~State()
{
reset();
}
void State::initialize(const Caps& caps, GLuint clientVersion)
{
mContext = NULL;
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
......@@ -65,7 +76,7 @@ State::State()
mDepthStencil.stencilMask = -1;
mDepthStencil.stencilWritemask = -1;
mDepthStencil.stencilBackFunc = GL_ALWAYS;
mDepthStencil.stencilBackMask = - 1;
mDepthStencil.stencilBackMask = -1;
mDepthStencil.stencilBackWritemask = -1;
mDepthStencil.stencilFail = GL_KEEP;
mDepthStencil.stencilPassDepthFail = GL_KEEP;
......@@ -97,18 +108,24 @@ State::State()
mBlend.colorMaskBlue = true;
mBlend.colorMaskAlpha = true;
mActiveSampler = 0;
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
{
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
}
for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
if (clientVersion >= 3)
{
mSamplers[textureUnit].set(NULL);
// TODO: These could also be enabled via extension
mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
}
mActiveSampler = 0;
mSamplers.resize(caps.maxCombinedTextureImageUnits);
mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
......@@ -121,15 +138,20 @@ State::State()
mDrawFramebuffer = NULL;
}
State::~State()
void State::reset()
{
for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{
for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
TextureBindingVector &textureVector = bindingVec->second;
for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
{
mSamplerTexture[type][sampler].set(NULL);
textureVector[textureIdx].set(NULL);
}
}
for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
{
mSamplers[samplerIdx].set(NULL);
}
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
......@@ -583,26 +605,26 @@ unsigned int State::getActiveSampler() const
return mActiveSampler;
}
void State::setSamplerTexture(TextureType type, Texture *texture)
void State::setSamplerTexture(GLenum type, Texture *texture)
{
mSamplerTexture[type][mActiveSampler].set(texture);
mSamplerTextures[type][mActiveSampler].set(texture);
}
Texture *State::getSamplerTexture(unsigned int sampler, TextureType type) const
Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
{
GLuint texid = mSamplerTexture[type][sampler].id();
const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
if (texid == 0) // Special case: 0 refers to default textures held by Context
if (binding.id() == 0) // Special case: 0 refers to default textures held by Context
{
return NULL;
}
return mSamplerTexture[type][sampler].get();
return binding.get();
}
GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
{
return mSamplerTexture[type][sampler].id();
return mSamplerTextures.at(type)[sampler].id();
}
void State::detachTexture(GLuint texture)
......@@ -616,13 +638,15 @@ void State::detachTexture(GLuint texture)
// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
// rebound to texture object zero
for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{
for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
TextureBindingVector &textureVector = bindingVec->second;
for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
{
if (mSamplerTexture[type][sampler].id() == texture)
BindingPointer<Texture> &binding = textureVector[textureIdx];
if (binding.id() == texture)
{
mSamplerTexture[type][sampler].set(NULL);
binding.set(NULL);
}
}
}
......@@ -650,7 +674,7 @@ void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
GLuint State::getSamplerId(GLuint textureUnit) const
{
ASSERT(textureUnit < ArraySize(mSamplers));
ASSERT(textureUnit < mSamplers.size());
return mSamplers[textureUnit].id();
}
......@@ -665,11 +689,12 @@ void State::detachSampler(GLuint sampler)
// If a sampler object that is currently bound to one or more texture units is
// deleted, it is as though BindSampler is called once for each texture unit to
// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
{
if (mSamplers[textureUnit].id() == sampler)
BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
if (samplerBinding.id() == sampler)
{
mSamplers[textureUnit].set(NULL);
samplerBinding.set(NULL);
}
}
}
......@@ -1308,19 +1333,19 @@ void State::getIntegerv(GLenum pname, GLint *params)
break;
case GL_TEXTURE_BINDING_2D:
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
*params = mSamplerTexture[TEXTURE_2D][mActiveSampler].id();
*params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
*params = mSamplerTexture[TEXTURE_CUBE][mActiveSampler].id();
*params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_3D:
ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
*params = mSamplerTexture[TEXTURE_3D][mActiveSampler].id();
*params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_2D_ARRAY:
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
*params = mSamplerTexture[TEXTURE_2D_ARRAY][mActiveSampler].id();
*params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
break;
case GL_UNIFORM_BUFFER_BINDING:
*params = mGenericUniformBuffer.id();
......
......@@ -24,6 +24,7 @@ namespace gl
class Query;
class VertexArray;
class Context;
struct Caps;
class State
{
......@@ -31,6 +32,9 @@ class State
State();
~State();
void initialize(const Caps& caps, GLuint clientVersion);
void reset();
void setContext(Context *context) { mContext = context; }
// State chunk getters
......@@ -126,9 +130,9 @@ class State
// Texture binding & active texture unit manipulation
void setActiveSampler(unsigned int active);
unsigned int getActiveSampler() const;
void setSamplerTexture(TextureType type, Texture *texture);
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
GLuint getSamplerTextureId(unsigned int sampler, TextureType type) const;
void setSamplerTexture(GLenum type, Texture *texture);
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
void detachTexture(GLuint texture);
// Sampler object binding manipulation
......@@ -272,7 +276,6 @@ class State
float mNearZ;
float mFarZ;
unsigned int mActiveSampler; // Active texture unit selector - GL_TEXTURE0
BindingPointer<Buffer> mArrayBuffer;
Framebuffer *mReadFramebuffer;
Framebuffer *mDrawFramebuffer;
......@@ -283,8 +286,15 @@ class State
VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
VertexArray *mVertexArray;
BindingPointer<Texture> mSamplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
BindingPointer<Sampler> mSamplers[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
// Texture and sampler bindings
size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0
typedef std::vector< BindingPointer<Texture> > TextureBindingVector;
typedef std::map<GLenum, TextureBindingVector> TextureBindingMap;
TextureBindingMap mSamplerTextures;
typedef std::vector< BindingPointer<Sampler> > SamplerBindingVector;
SamplerBindingVector mSamplers;
typedef std::map< GLenum, BindingPointer<Query> > ActiveQueryMap;
ActiveQueryMap mActiveQueries;
......
......@@ -19,17 +19,6 @@ class ProgramBinary;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
enum TextureType
{
TEXTURE_2D,
TEXTURE_CUBE,
TEXTURE_3D,
TEXTURE_2D_ARRAY,
TEXTURE_TYPE_COUNT,
TEXTURE_UNKNOWN
};
enum SamplerType
{
SAMPLER_PIXEL,
......
......@@ -15,12 +15,8 @@ namespace gl
enum
{
MAX_VERTEX_ATTRIBS = 16,
MAX_TEXTURE_IMAGE_UNITS = 16,
// Implementation upper limits, real maximums depend on the hardware
IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16,
IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
IMPLEMENTATION_MAX_VARYING_VECTORS = 32,
IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers
......
......@@ -265,35 +265,24 @@ void __stdcall glBindTexture(GLenum target, GLuint texture)
switch (target)
{
case GL_TEXTURE_2D:
context->bindTexture2D(texture);
return;
case GL_TEXTURE_CUBE_MAP:
context->bindTextureCubeMap(texture);
return;
break;
case GL_TEXTURE_3D:
if (context->getClientVersion() < 3)
{
context->recordError(gl::Error(GL_INVALID_ENUM));
return;
}
context->bindTexture3D(texture);
return;
case GL_TEXTURE_2D_ARRAY:
if (context->getClientVersion() < 3)
{
context->recordError(gl::Error(GL_INVALID_ENUM));
return;
}
context->bindTexture2DArray(texture);
return;
break;
default:
context->recordError(gl::Error(GL_INVALID_ENUM));
return;
}
context->bindTexture(target, texture);
}
}
......
......@@ -315,6 +315,17 @@ void Renderer11::initializeDevice()
ASSERT(!mPixelTransfer);
mPixelTransfer = new PixelTransfer11(this);
const gl::Caps &rendererCaps = getRendererCaps();
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits);
mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits);
markAllStateDirty();
}
......@@ -324,7 +335,7 @@ int Renderer11::generateConfigs(ConfigDesc **configDescList)
unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
(*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
int numConfigs = 0;
for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
{
const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]);
......@@ -1556,12 +1567,15 @@ void Renderer11::markAllStateDirty()
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
for (int i = 0; i < mForceSetVertexSamplerStates.size(); i++)
{
mForceSetVertexSamplerStates[i] = true;
mCurVertexSRVs[i] = NULL;
}
for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
for (int i = 0; i < mForceSetPixelSamplerStates.size(); i++)
{
mForceSetPixelSamplerStates[i] = true;
mCurPixelSRVs[i] = NULL;
......
......@@ -245,15 +245,15 @@ class Renderer11 : public Renderer
rx::RenderTarget::Desc mRenderTargetDesc;
// Currently applied sampler states
bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
std::vector<bool> mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> mCurVertexSamplerStates;
bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates;
// Currently applied textures
ID3D11ShaderResourceView *mCurVertexSRVs[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
ID3D11ShaderResourceView *mCurPixelSRVs[gl::MAX_TEXTURE_IMAGE_UNITS];
std::vector<ID3D11ShaderResourceView*> mCurVertexSRVs;
std::vector<ID3D11ShaderResourceView*> mCurPixelSRVs;
// Currently applied blend state
bool mForceSetBlendState;
......
......@@ -944,7 +944,7 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
static_cast<GLint64>(caps->maxFragmentUniformComponents);
caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxFragmentInputComponents;
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
// Transform feedback limits
caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel);
......
......@@ -379,6 +379,17 @@ void Renderer9::initializeDevice()
mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f
}
const gl::Caps &rendererCaps = getRendererCaps();
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits);
mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits);
markAllStateDirty();
mSceneStarted = false;
......@@ -633,8 +644,8 @@ void Renderer9::generateSwizzle(gl::Texture *texture)
void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
{
bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0)
{
......@@ -668,7 +679,7 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture
unsigned int serial = 0;
bool forceSetTexture = false;
unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
std::vector<unsigned int> &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
if (texture)
{
......@@ -2022,12 +2033,15 @@ void Renderer9::markAllStateDirty()
mForceSetViewport = true;
mForceSetBlendState = true;
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size());
for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++)
{
mForceSetVertexSamplerStates[i] = true;
mCurVertexTextureSerials[i] = 0;
}
for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size());
for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++)
{
mForceSetPixelSamplerStates[i] = true;
mCurPixelTextureSerials[i] = 0;
......@@ -3082,12 +3096,9 @@ TextureImpl *Renderer9::createTexture(GLenum target)
{
switch(target)
{
case GL_TEXTURE_2D: return new TextureD3D_2D(this);
case GL_TEXTURE_2D: return new TextureD3D_2D(this);
case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
case GL_TEXTURE_3D: return new TextureD3D_3D(this);
case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
default:
UNREACHABLE();
default: UNREACHABLE();
}
return NULL;
......
......@@ -295,15 +295,15 @@ class Renderer9 : public Renderer
GLuint mCurSampleMask;
// Currently applied sampler states
bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
std::vector<bool> mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> mCurVertexSamplerStates;
bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates;
// Currently applied textures
unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
std::vector<unsigned int> mCurVertexTextureSerials;
std::vector<unsigned int> mCurPixelTextureSerials;
unsigned int mAppliedIBSerial;
IDirect3DVertexShader9 *mAppliedVertexShader;
......
......@@ -436,7 +436,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
// Aggregate shader limits
caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4;
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxFragmentInputComponents;
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
// Transform feedback limits
caps->maxTransformFeedbackInterleavedComponents = 0;
......
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