diff options
author | Geoff Lang <geofflang@chromium.org> | 2014-09-05 16:28:14 -0400 |
---|---|---|
committer | Geoff Lang <geofflang@chromium.org> | 2014-09-18 19:13:05 +0000 |
commit | 76b10c9a9735c27627065d9fe68f78374ef48934 (patch) | |
tree | 3720943e40719deedb1da2adde725bbba92235ca | |
parent | ac7579c2bd0cc9afdf5892a766e6967bf3a341f0 (diff) | |
download | angle-76b10c9a9735c27627065d9fe68f78374ef48934.tar.gz |
Use dynamically sized containers for texture and sampler bindings.
BUG=angle:685
Change-Id: I7af97a95deee69fbdebca2b57403244f45516e67
Reviewed-on: https://chromium-review.googlesource.com/216564
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
-rw-r--r-- | src/libGLESv2/Context.cpp | 223 | ||||
-rw-r--r-- | src/libGLESv2/Context.h | 28 | ||||
-rw-r--r-- | src/libGLESv2/ProgramBinary.cpp | 145 | ||||
-rw-r--r-- | src/libGLESv2/ProgramBinary.h | 10 | ||||
-rw-r--r-- | src/libGLESv2/ResourceManager.cpp | 10 | ||||
-rw-r--r-- | src/libGLESv2/ResourceManager.h | 4 | ||||
-rw-r--r-- | src/libGLESv2/State.cpp | 81 | ||||
-rw-r--r-- | src/libGLESv2/State.h | 22 | ||||
-rw-r--r-- | src/libGLESv2/angletypes.h | 11 | ||||
-rw-r--r-- | src/libGLESv2/constants.h | 4 | ||||
-rw-r--r-- | src/libGLESv2/libGLESv2.cpp | 19 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 20 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 12 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp | 2 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 31 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/Renderer9.h | 12 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp | 2 |
17 files changed, 302 insertions, 334 deletions
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp index f2852b06..87480c46 100644 --- a/src/libGLESv2/Context.cpp +++ b/src/libGLESv2/Context.cpp @@ -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(); diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h index 5cf4746e..bf886a83 100644 --- a/src/libGLESv2/Context.h +++ b/src/libGLESv2/Context.h @@ -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; diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp index 1cc55d25..405a73cc 100644 --- a/src/libGLESv2/ProgramBinary.cpp +++ b/src/libGLESv2/ProgramBinary.cpp @@ -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; diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h index 2fe924bb..738d63f9 100644 --- a/src/libGLESv2/ProgramBinary.h +++ b/src/libGLESv2/ProgramBinary.h @@ -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; diff --git a/src/libGLESv2/ResourceManager.cpp b/src/libGLESv2/ResourceManager.cpp index eccc1399..9121de17 100644 --- a/src/libGLESv2/ResourceManager.cpp +++ b/src/libGLESv2/ResourceManager.cpp @@ -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); } diff --git a/src/libGLESv2/ResourceManager.h b/src/libGLESv2/ResourceManager.h index 7ef90d29..7d53bd48 100644 --- a/src/libGLESv2/ResourceManager.h +++ b/src/libGLESv2/ResourceManager.h @@ -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); diff --git a/src/libGLESv2/State.cpp b/src/libGLESv2/State.cpp index 5497fa78..3c03b90e 100644 --- a/src/libGLESv2/State.cpp +++ b/src/libGLESv2/State.cpp @@ -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(); diff --git a/src/libGLESv2/State.h b/src/libGLESv2/State.h index d3b3edc5..5f043313 100644 --- a/src/libGLESv2/State.h +++ b/src/libGLESv2/State.h @@ -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; diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h index 79ad810e..922053e9 100644 --- a/src/libGLESv2/angletypes.h +++ b/src/libGLESv2/angletypes.h @@ -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, diff --git a/src/libGLESv2/constants.h b/src/libGLESv2/constants.h index c87f92d4..69c4823f 100644 --- a/src/libGLESv2/constants.h +++ b/src/libGLESv2/constants.h @@ -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 diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp index 821226bf..a62e163f 100644 --- a/src/libGLESv2/libGLESv2.cpp +++ b/src/libGLESv2/libGLESv2.cpp @@ -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); } } diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp index d7cadf6c..b12a6540 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp @@ -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; diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h index 2d9e3034..4a794d27 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h @@ -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; diff --git a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp index 39bec903..b1867fba 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp @@ -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); diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp index e82971db..deea35b5 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp @@ -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; diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h index e7dab81a..c7c3dde3 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h +++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h @@ -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; diff --git a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp index 879a6427..d6f950a5 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp @@ -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; |