Add state for sampler objects.

TRAC #23453

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Authored-by: Jamie Madill
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 809a9f7..e0d9e94 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -26,6 +26,7 @@
 #include "libGLESv2/renderer/RenderTarget.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/VertexArray.h"
+#include "libGLESv2/Sampler.h"
 
 #include "libEGL/Surface.h"
 
@@ -147,6 +148,11 @@
     mTexture3DZero.set(new Texture3D(mRenderer, 0));
     mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
 
+    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
+    {
+        mState.samplers[textureUnit] = 0;
+    }
+
     mState.activeSampler = 0;
     bindVertexArray(0);
     bindArrayBuffer(0);
@@ -664,6 +670,12 @@
     return mState.vertexArray;
 }
 
+GLuint Context::getSamplerHandle(GLuint textureUnit) const
+{
+    ASSERT(textureUnit < ArraySize(mState.samplers));
+    return mState.samplers[textureUnit];
+}
+
 GLuint Context::getArrayBufferHandle() const
 {
     return mState.arrayBuffer.id();
@@ -789,6 +801,11 @@
     return handle;
 }
 
+GLuint Context::createSampler()
+{
+    return mResourceManager->createSampler();
+}
+
 // Returns an unused framebuffer name
 GLuint Context::createFramebuffer()
 {
@@ -872,6 +889,16 @@
     }
 }
 
+void Context::deleteSampler(GLuint sampler)
+{
+    if (mResourceManager->getSampler(sampler))
+    {
+        detachSampler(sampler);
+    }
+
+    mResourceManager->deleteSampler(sampler);
+}
+
 void Context::deleteFramebuffer(GLuint framebuffer)
 {
     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
@@ -951,6 +978,11 @@
     }
 }
 
+Sampler *Context::getSampler(GLuint handle) const
+{
+    return mResourceManager->getSampler(handle);
+}
+
 Framebuffer *Context::getReadFramebuffer()
 {
     return getFramebuffer(mState.readFramebuffer);
@@ -968,6 +1000,11 @@
     return vao;
 }
 
+bool Context::isSampler(GLuint samplerName) const
+{
+    return mResourceManager->isSampler(samplerName);
+}
+
 void Context::bindArrayBuffer(unsigned int buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
@@ -1049,6 +1086,14 @@
     mState.vertexArray = vertexArray;
 }
 
+void Context::bindSampler(GLuint textureUnit, GLuint sampler)
+{
+    ASSERT(textureUnit < ArraySize(mState.samplers));
+    mResourceManager->checkSamplerAllocation(sampler);
+
+    mState.samplers[textureUnit] = sampler;
+}
+
 void Context::bindGenericUniformBuffer(GLuint buffer)
 {
     mResourceManager->checkBufferAllocation(buffer);
@@ -2889,6 +2934,21 @@
     }
 }
 
+void Context::detachSampler(GLuint sampler)
+{
+    // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
+    // 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(mState.samplers); textureUnit++)
+    {
+        if (mState.samplers[textureUnit] == sampler)
+        {
+            mState.samplers[textureUnit] = 0;
+        }
+    }
+}
+
 Texture *Context::getIncompleteTexture(TextureType type)
 {
     Texture *t = mIncompleteTextures[type].get();