ES31: Implement getMultisamplefv for D3D part.

Implement getMultisamplefv for d3d part.Because standard D3D sample
positions from https://msdn.microsoft.com/en-us/library/windows/
desktop/ff476218.aspx are fixed sample pattern,we put the sample
positions into a constant array in renderer11_utils.cpp with a
function to query it.

BUG=angleproject:1590
TEST=dEQP-GLES31.functional.texture.multisample.samples_*.sample_position

Change-Id: I6e6006ed1c4e22fe006522e9ffd3297247bee75e
Reviewed-on: https://chromium-review.googlesource.com/594970
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/TextureFunctionHLSL.cpp b/src/compiler/translator/TextureFunctionHLSL.cpp
index bbf69b1..d2b65a6 100644
--- a/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -168,7 +168,12 @@
         switch (hlslCoords)
         {
             case 2:
-                return "int3";
+                if (textureFunction.sampler == EbtSampler2DMS ||
+                    textureFunction.sampler == EbtISampler2DMS ||
+                    textureFunction.sampler == EbtUSampler2DMS)
+                    return "int2";
+                else
+                    return "int3";
             case 3:
                 return "int4";
             default:
@@ -202,6 +207,7 @@
         {
             case EbtSampler2D:
             case EbtSamplerExternalOES:
+            case EbtSampler2DMS:
                 hlslCoords = 2;
                 break;
             case EbtSamplerCube:
@@ -393,7 +399,12 @@
         case TextureFunctionHLSL::TextureFunction::SIZE:
             break;
         case TextureFunctionHLSL::TextureFunction::FETCH:
-            out << ", int mip";
+            if (textureFunction.sampler == EbtSampler2DMS ||
+                textureFunction.sampler == EbtISampler2DMS ||
+                textureFunction.sampler == EbtUSampler2DMS)
+                out << ", int index";
+            else
+                out << ", int mip";
             break;
         case TextureFunctionHLSL::TextureFunction::GRAD:
             break;
@@ -418,6 +429,9 @@
             case EbtUSampler2DArray:
             case EbtSampler2DShadow:
             case EbtSampler2DArrayShadow:
+            case EbtSampler2DMS:
+            case EbtISampler2DMS:
+            case EbtUSampler2DMS:
             case EbtSamplerExternalOES:
                 out << ", int2 offset";
                 break;
@@ -942,7 +956,12 @@
         else if (IsIntegerSampler(textureFunction.sampler) ||
                  textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
         {
-            out << ", mip)";
+            if (textureFunction.sampler == EbtSampler2DMS ||
+                textureFunction.sampler == EbtISampler2DMS ||
+                textureFunction.sampler == EbtUSampler2DMS)
+                out << "), index";
+            else
+                out << ", mip)";
         }
         else if (IsShadowSampler(textureFunction.sampler))
         {
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index a1f3214..f7f58da 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -4131,8 +4131,10 @@
 
 void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
 {
-    mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
-    const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+    // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
+    // the sample position should be queried by DRAW_FRAMEBUFFER.
+    mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
+    const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
 
     switch (pname)
     {
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index e1f9bc5..dd17686 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -370,9 +370,4 @@
     return mColorAttachmentsForRender.value();
 }
 
-gl::Error FramebufferD3D::getSamplePosition(size_t index, GLfloat *xy) const
-{
-    return gl::InternalError() << "getSamplePosition is unimplemented.";
-}
-
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.h b/src/libANGLE/renderer/d3d/FramebufferD3D.h
index ff0be31..b7d488a 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.h
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -99,8 +99,6 @@
 
     const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
 
-    gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
-
   private:
     virtual gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) = 0;
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
index d71572c..6455aaa 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -463,8 +463,12 @@
 
 gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
 {
-    UNIMPLEMENTED();
-    return gl::InternalError() << "getSamplePosition is unimplemented.";
+    const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment();
+    ASSERT(attachment);
+    GLsizei sampleCount = attachment->getSamples();
+
+    d3d11_gl::GetSamplePosition(sampleCount, index, xy);
+    return gl::NoError();
 }
 
 bool Framebuffer11::hasAnyInternalDirtyBit() const
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
index 6806b6d..7f5ff48 100644
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -3032,7 +3032,7 @@
             mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
         GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
         desc.SampleDesc.Count   = (supportedSamples == 0) ? 1 : supportedSamples;
-        desc.SampleDesc.Quality = 0;
+        desc.SampleDesc.Quality = static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);
 
         ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, &mTexture));
         mTexture.setDebugName("TexStorage2DMS.Texture");
@@ -3116,7 +3116,6 @@
 
     ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV));
     outSRV->setDebugName("TexStorage2DMS.SRV");
-
     return gl::NoError();
 }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 4c708ee..f29cb29 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -32,6 +32,19 @@
 {
 namespace
 {
+// Standard D3D sample positions from
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218.aspx
+using SamplePositionsArray = std::array<float, 32>;
+static constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
+    {{{0.5f, 0.5f}},
+     {{0.75f, 0.75f, 0.25f, 0.25f}},
+     {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}},
+     {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f,
+       0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}},
+     {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f,  0.75f,   0.4375f,
+       0.1875f, 0.375f,  0.625f,  0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f,
+       0.375f,  0.875f,  0.5f,    0.0625f, 0.25f,   0.125f,  0.125f,  0.75f,
+       0.0f,    0.5f,    0.9375f, 0.25f,   0.875f,  0.9375f, 0.0625f, 0.0f}}}};
 
 // Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
 class DXGISupportHelper : angle::NonCopyable
@@ -1444,6 +1457,16 @@
 #endif
 }
 
+void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy)
+{
+    size_t indexKey = static_cast<size_t>(ceil(log(sampleCount)));
+    ASSERT(indexKey < kSamplePositions.size() &&
+           (2 * index + 1) < kSamplePositions[indexKey].size());
+
+    xy[0] = kSamplePositions[indexKey][2 * index];
+    xy[1] = kSamplePositions[indexKey][2 * index + 1];
+}
+
 }  // namespace d3d11_gl
 
 namespace gl_d3d11
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
index b4fef5e..72bbec3 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -71,6 +71,8 @@
 void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps,
                   gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations);
 
+void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
+
 }  // namespace d3d11_gl
 
 namespace d3d11
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
index 97ecd6c..b556ee5 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -405,4 +405,10 @@
     return d3dFormatInfo.info().glInternalFormat;
 }
 
+gl::Error Framebuffer9::getSamplePosition(size_t index, GLfloat *xy) const
+{
+    UNREACHABLE();
+    return gl::InternalError() << "getSamplePosition is unsupported to d3d9.";
+}
+
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
index 9d8d5e1..21f0dc3 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -30,6 +30,8 @@
                             const GLenum *attachments,
                             const gl::Rectangle &area) override;
 
+    gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
+
   private:
     gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override;
 
diff --git a/src/libANGLE/validationES31.cpp b/src/libANGLE/validationES31.cpp
index cbf44e7..e4c118d 100644
--- a/src/libANGLE/validationES31.cpp
+++ b/src/libANGLE/validationES31.cpp
@@ -638,8 +638,9 @@
         return false;
     }
 
-    GLint maxSamples = context->getCaps().maxSamples;
-    if (index >= static_cast<GLuint>(maxSamples))
+    Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
+
+    if (index >= static_cast<GLuint>(framebuffer->getSamples(context)))
     {
         context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
         return false;
diff --git a/src/tests/deqp_support/deqp_gles31_test_expectations.txt b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
index 223b154..2c77358 100644
--- a/src/tests/deqp_support/deqp_gles31_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
@@ -35,10 +35,8 @@
 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.type.vertex_fragment.struct.* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.vertex_attribute_binding.* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.stencil_texturing.* = SKIP
-1442 D3D11 : dEQP-GLES31.functional.state_query.shader.sampler_type = SKIP
 
 // OpenGL Failing Tests
-1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_* = FAIL
 1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_2d_array = FAIL
 1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_2d_array = FAIL
 1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_int_2d = FAIL
@@ -80,7 +78,6 @@
 1951 D3D11 : dEQP-GLES31.functional.state_query.indexed.shader_storage_buffer_* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
 1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
-1442 D3D11 : dEQP-GLES31.functional.texture.multisample.samples* = FAIL
 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
@@ -1330,3 +1327,21 @@
 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_64.sample_mask_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_1.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_2.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_3.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_4.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_8.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_10.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_12.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_13.use_texture_* = FAIL
+1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.samples_64.use_texture_* = FAIL