Store ShaderExecutables on the ProgramBinary instead of d3d9 shaders

Trac #22155
Signed-off-by: Geoff Lang
Signed-off-by: Nicolas Capens

Also hooks up binary loading to the loadExecutable function.
The other notable change is that getVertex/Pixel shader no longer
add reference counts to the returned objects.

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1505 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 62ba329..6b1f948 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -96,15 +96,8 @@
 
 ProgramBinary::~ProgramBinary()
 {
-    if (mPixelExecutable)
-    {
-        mPixelExecutable->Release();
-    }
-
-    if (mVertexExecutable)
-    {
-        mVertexExecutable->Release();
-    }
+    delete mPixelExecutable;
+    delete mVertexExecutable;
 
     while (!mUniforms.empty())
     {
@@ -123,12 +116,12 @@
     return mCurrentSerial++;
 }
 
-IDirect3DPixelShader9 *ProgramBinary::getPixelShader()
+rx::ShaderExecutable *ProgramBinary::getPixelExecutable()
 {
     return mPixelExecutable;
 }
 
-IDirect3DVertexShader9 *ProgramBinary::getVertexShader()
+rx::ShaderExecutable *ProgramBinary::getVertexExecutable()
 {
     return mVertexExecutable;
 }
@@ -1650,21 +1643,26 @@
     const char *vertexShaderFunction = ptr;
     ptr += vertexShaderSize;
 
-    mPixelExecutable = mRenderer->createPixelShader(reinterpret_cast<const DWORD*>(pixelShaderFunction), pixelShaderSize);
-    if (!mPixelExecutable)
+    rx::ShaderExecutable *executable;
+    executable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
+                                           pixelShaderSize, GL_FRAGMENT_SHADER, NULL);
+    if (!executable)
     {
         infoLog.append("Could not create pixel shader.");
         return false;
     }
+    mPixelExecutable = rx::ShaderExecutable9::makeShaderExecutable9(executable);
 
-    mVertexExecutable = mRenderer->createVertexShader(reinterpret_cast<const DWORD*>(vertexShaderFunction), vertexShaderSize);
-    if (!mVertexExecutable)
+    executable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+                                           vertexShaderSize, GL_VERTEX_SHADER, NULL);
+    if (!executable)
     {
         infoLog.append("Could not create vertex shader.");
-        mPixelExecutable->Release();
+        delete mPixelExecutable;
         mPixelExecutable = NULL;
         return false;
     }
+    mVertexExecutable = rx::ShaderExecutable9::makeShaderExecutable9(executable);
 
     return true;
 }
@@ -1734,12 +1732,12 @@
     stream.write(mDxPointsOrLinesLocation);
 
     UINT pixelShaderSize;
-    HRESULT result = mPixelExecutable->GetFunction(NULL, &pixelShaderSize);
+    HRESULT result = mPixelExecutable->getPixelShader()->GetFunction(NULL, &pixelShaderSize);
     ASSERT(SUCCEEDED(result));
     stream.write(pixelShaderSize);
 
     UINT vertexShaderSize;
-    result = mVertexExecutable->GetFunction(NULL, &vertexShaderSize);
+    result = mVertexExecutable->getVertexShader()->GetFunction(NULL, &vertexShaderSize);
     ASSERT(SUCCEEDED(result));
     stream.write(vertexShaderSize);
 
@@ -1769,11 +1767,11 @@
         memcpy(ptr, &identifier, sizeof(GUID));
         ptr += sizeof(GUID);
 
-        result = mPixelExecutable->GetFunction(ptr, &pixelShaderSize);
+        result = mPixelExecutable->getPixelShader()->GetFunction(ptr, &pixelShaderSize);
         ASSERT(SUCCEEDED(result));
         ptr += pixelShaderSize;
 
-        result = mVertexExecutable->GetFunction(ptr, &vertexShaderSize);
+        result = mVertexExecutable->getVertexShader()->GetFunction(ptr, &vertexShaderSize);
         ASSERT(SUCCEEDED(result));
         ptr += vertexShaderSize;
 
@@ -1829,27 +1827,21 @@
 
     if (vertexExecutable && pixelExecutable)
     {
-        rx::ShaderExecutable9 *vshader9 = rx::ShaderExecutable9::makeShaderExecutable9(vertexExecutable);
-        rx::ShaderExecutable9 *pshader9 = rx::ShaderExecutable9::makeShaderExecutable9(pixelExecutable);
-        mVertexExecutable = vshader9->getVertexShader();
-        mPixelExecutable = pshader9->getPixelShader();
+        mVertexExecutable = rx::ShaderExecutable9::makeShaderExecutable9(vertexExecutable);
+        mPixelExecutable = rx::ShaderExecutable9::makeShaderExecutable9(pixelExecutable);
 
-        if (!mPixelExecutable || !mVertexExecutable)
-        {
-            if (mVertexExecutable) mVertexExecutable->Release();
-            mVertexExecutable = NULL;
-            if (mPixelExecutable) mPixelExecutable->Release();
-            mPixelExecutable = NULL;
-            infoLog.append("Failed to create D3D shaders.");
-            success = false;
-        }
-
-        constantTableVS = vshader9->getConstantTable();
-        constantTablePS = pshader9->getConstantTable();
+        constantTableVS = mVertexExecutable->getConstantTable();
+        constantTablePS = mPixelExecutable->getConstantTable();
     }
     else
     {
+        infoLog.append("Failed to create D3D shaders.");
         success = false;
+
+        delete vertexExecutable;
+        vertexExecutable = NULL;
+        delete pixelExecutable;
+        pixelExecutable = NULL;
     }
 
     if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
@@ -1864,8 +1856,6 @@
             success = false;
         }
     }
-    delete vertexExecutable;
-    delete pixelExecutable;
 
     // these uniforms are searched as already-decorated because gl_ and dx_
     // are reserved prefixes, and do not receive additional decoration
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index e891b26..e6eca14 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -104,8 +104,8 @@
     explicit ProgramBinary(rx::Renderer *renderer);
     ~ProgramBinary();
 
-    IDirect3DPixelShader9 *getPixelShader();
-    IDirect3DVertexShader9 *getVertexShader();
+    rx::ShaderExecutable *getPixelExecutable();
+    rx::ShaderExecutable *getVertexExecutable();
 
     GLuint getAttributeLocation(const char *name);
     int getSemanticIndex(int attributeIndex);
@@ -189,8 +189,8 @@
     rx::Renderer9 *mRenderer;   // D3D9_REPLACE
     IDirect3DDevice9 *mDevice; // D3D9_REPLACE
 
-    IDirect3DPixelShader9 *mPixelExecutable; // D3D9_REPLACE
-    IDirect3DVertexShader9 *mVertexExecutable; // D3D9_REPLACE
+    rx::ShaderExecutable9 *mPixelExecutable; // D3D9_REPLACE
+    rx::ShaderExecutable9 *mVertexExecutable; // D3D9_REPLACE
 
     Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
     int mSemanticIndex[MAX_VERTEX_ATTRIBS];
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index d091d49..6a951a4 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1377,8 +1377,14 @@
 
 void Renderer9::applyShaders(gl::ProgramBinary *programBinary)
 {
-    IDirect3DVertexShader9 *vertexShader = programBinary->getVertexShader();
-    IDirect3DPixelShader9 *pixelShader = programBinary->getPixelShader();
+    ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+    ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
+
+    IDirect3DVertexShader9 *vertexShader = NULL;
+    if (vertexExe) vertexShader = ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader();
+
+    IDirect3DPixelShader9 *pixelShader = NULL;
+    if (pixelExe) pixelShader = ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader();
 
     mDevice->SetPixelShader(pixelShader);
     mDevice->SetVertexShader(vertexShader);
diff --git a/src/libGLESv2/renderer/ShaderExecutable9.cpp b/src/libGLESv2/renderer/ShaderExecutable9.cpp
index 5bd4486..0a19af1 100644
--- a/src/libGLESv2/renderer/ShaderExecutable9.cpp
+++ b/src/libGLESv2/renderer/ShaderExecutable9.cpp
@@ -50,23 +50,11 @@
 
 IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader()
 {
-    // Caller is responsible for releasing the returned shader reference.
-    if (mVertexExecutable)
-    {
-        mVertexExecutable->AddRef();
-    }
-
     return mVertexExecutable;
 }
 
 IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader()
 {
-    // Caller is responsible for releasing the returned shader reference.
-    if (mPixelExecutable)
-    {
-        mPixelExecutable->AddRef();
-    }
-
     return mPixelExecutable;
 }