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