Add getUniform impl methods.

This will let us remove some of the uniform data management code in
the GL front-end, and simplify the GL back-end. It will also enable
us to implement uniform data more efficiently in the D3D11 back-end,
and probably Vulkan back-end later.

This also implements a new impl method for the ProgramGL class to
flag optimized-out uniforms as no longer used, post-link. This is
important because otherwise the optimized uniforms get assigned
valid locations, and then the getUniform calls are expected to
succeed.

We also use a workaround for uniform value queries for the GL
back-end. It seems as though some drivers (seen on NVIDIA and AMD)
may not properly clamp to the maximum representable integer value
when querying out-of-range floating point values. Work around this by
always calling the driver with the proper type and then casting the
value in ANGLE.

BUG=angleproject:1390

Change-Id: I03dc2382e7af52455c356a2bf3971a4d1bd46ec6
Reviewed-on: https://chromium-review.googlesource.com/616785
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 3c4c432..dfe0665 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -18,6 +18,7 @@
 #include "libANGLE/VaryingPacking.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/features.h"
+#include "libANGLE/queryconversions.h"
 #include "libANGLE/renderer/ContextImpl.h"
 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
@@ -2602,4 +2603,29 @@
     return false;
 }
 
+template <typename DestT>
+void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const
+{
+    const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
+    const gl::LinkedUniform &uniform         = mState.getUniforms()[locationInfo.index];
+
+    const uint8_t *srcPointer = uniform.getDataPtrToElement(locationInfo.element);
+    memcpy(dataOut, srcPointer, uniform.getElementSize());
+}
+
+void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
+{
+    getUniformInternal(location, params);
+}
+
+void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
+{
+    getUniformInternal(location, params);
+}
+
+void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
+{
+    getUniformInternal(location, params);
+}
+
 }  // namespace rx