• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // D3D11EmulatedIndexedBufferTest:
7 //   Tests to validate our D3D11 support for emulating an indexed
8 //   vertex buffer.
9 //
10 
11 #include "libANGLE/Context.h"
12 #include "libANGLE/angletypes.h"
13 #include "libANGLE/renderer/d3d/IndexDataManager.h"
14 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
15 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
16 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
17 #include "test_utils/ANGLETest.h"
18 #include "test_utils/angle_test_instantiate.h"
19 #include "util/EGLWindow.h"
20 
21 using namespace angle;
22 
23 namespace
24 {
25 
26 class D3D11EmulatedIndexedBufferTest : public ANGLETest
27 {
28   protected:
testSetUp()29     void testSetUp() override
30     {
31         ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
32 
33         mContext                 = static_cast<gl::Context *>(getEGLWindow()->getContext());
34         rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(mContext);
35         mRenderer                = context11->getRenderer();
36 
37         mSourceBuffer       = new rx::Buffer11(mBufferState, mRenderer);
38         GLfloat testData[]  = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
39         angle::Result error = mSourceBuffer->setData(nullptr, gl::BufferBinding::Array, testData,
40                                                      sizeof(testData), gl::BufferUsage::StaticDraw);
41         ASSERT_EQ(angle::Result::Continue, error);
42 
43         mTranslatedAttribute.baseOffset            = 0;
44         mTranslatedAttribute.usesFirstVertexOffset = false;
45         mTranslatedAttribute.stride                = sizeof(GLfloat);
46 
47         GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1};
48 
49         for (size_t i = 0; i < ArraySize(indices); i++)
50         {
51             mExpectedExpandedData.push_back(testData[indices[i]]);
52             mubyteIndices.push_back(indices[i]);
53             muintIndices.push_back(indices[i]);
54             mushortIndices.push_back(indices[i]);
55         }
56     }
57 
testTearDown()58     void testTearDown() override { SafeDelete(mSourceBuffer); }
59 
createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer * sourceBuffer,GLuint size,ID3D11Buffer ** mappableBuffer)60     void createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer *sourceBuffer,
61                                                        GLuint size,
62                                                        ID3D11Buffer **mappableBuffer)
63     {
64         *mappableBuffer = nullptr;
65 
66         D3D11_BUFFER_DESC bufferDesc;
67         bufferDesc.ByteWidth           = size;
68         bufferDesc.MiscFlags           = 0;
69         bufferDesc.StructureByteStride = 0;
70         bufferDesc.Usage               = D3D11_USAGE_STAGING;
71         bufferDesc.BindFlags           = 0;
72         bufferDesc.CPUAccessFlags      = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
73 
74         HRESULT hr = mRenderer->getDevice()->CreateBuffer(&bufferDesc, nullptr, mappableBuffer);
75         ASSERT_TRUE(SUCCEEDED(hr));
76 
77         D3D11_BOX srcBox;
78         srcBox.left   = 0;
79         srcBox.right  = size;
80         srcBox.top    = 0;
81         srcBox.bottom = 1;
82         srcBox.front  = 0;
83         srcBox.back   = 1;
84 
85         mRenderer->getDeviceContext()->CopySubresourceRegion(*mappableBuffer, 0, 0, 0, 0,
86                                                              sourceBuffer, 0, &srcBox);
87     }
88 
compareContents(ID3D11Buffer * actual)89     void compareContents(ID3D11Buffer *actual)
90     {
91         ID3D11Buffer *compareBuffer = nullptr;
92         createMappableCompareBufferFromEmulatedBuffer(
93             actual, sizeof(GLfloat) * static_cast<GLuint>(mExpectedExpandedData.size()),
94             &compareBuffer);
95 
96         D3D11_MAPPED_SUBRESOURCE mappedResource;
97         HRESULT hr = mRenderer->getDeviceContext()->Map(compareBuffer, 0, D3D11_MAP_READ, 0,
98                                                         &mappedResource);
99         ASSERT_TRUE(SUCCEEDED(hr));
100 
101         GLfloat *compareData = static_cast<GLfloat *>(mappedResource.pData);
102         for (size_t i = 0; i < mExpectedExpandedData.size(); i++)
103         {
104             EXPECT_EQ(mExpectedExpandedData[i], compareData[i]);
105         }
106 
107         mRenderer->getDeviceContext()->Unmap(compareBuffer, 0);
108         SafeRelease(compareBuffer);
109     }
110 
emulateAndCompare(rx::SourceIndexData * srcData)111     void emulateAndCompare(rx::SourceIndexData *srcData)
112     {
113         ID3D11Buffer *emulatedBuffer = nullptr;
114         angle::Result error          = mSourceBuffer->getEmulatedIndexedBuffer(
115             mContext, srcData, mTranslatedAttribute, 0, &emulatedBuffer);
116         ASSERT_EQ(angle::Result::Continue, error);
117         ASSERT_TRUE(emulatedBuffer != nullptr);
118         compareContents(emulatedBuffer);
119     }
120 
121   protected:
122     gl::Context *mContext;
123     rx::Buffer11 *mSourceBuffer;
124     rx::Renderer11 *mRenderer;
125     rx::TranslatedAttribute mTranslatedAttribute;
126     std::vector<GLfloat> mExpectedExpandedData;
127     std::vector<GLubyte> mubyteIndices;
128     std::vector<GLuint> muintIndices;
129     std::vector<GLushort> mushortIndices;
130     gl::BufferState mBufferState;
131 };
132 
133 // This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded
134 // into a valid emulated indexed buffer.
TEST_P(D3D11EmulatedIndexedBufferTest,TestNativeToExpandedUsingGLubyteIndices)135 TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices)
136 {
137     rx::SourceIndexData srcData = {nullptr, mubyteIndices.data(),
138                                    static_cast<unsigned int>(mubyteIndices.size()),
139                                    gl::DrawElementsType::UnsignedByte, false};
140     emulateAndCompare(&srcData);
141 }
142 
143 // This tests that a GL_UNSIGNED_SHORT indices list can be successfully expanded
144 // into a valid emulated indexed buffer.
TEST_P(D3D11EmulatedIndexedBufferTest,TestNativeToExpandedUsingGLushortIndices)145 TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices)
146 {
147     rx::SourceIndexData srcData = {nullptr, mushortIndices.data(),
148                                    static_cast<unsigned int>(mushortIndices.size()),
149                                    gl::DrawElementsType::UnsignedShort, false};
150     emulateAndCompare(&srcData);
151 }
152 
153 // This tests that a GL_UNSIGNED_INT indices list can be successfully expanded
154 // into a valid emulated indexed buffer.
TEST_P(D3D11EmulatedIndexedBufferTest,TestNativeToExpandedUsingGLuintIndices)155 TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices)
156 {
157     rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
158                                    static_cast<unsigned int>(muintIndices.size()),
159                                    gl::DrawElementsType::UnsignedInt, false};
160     emulateAndCompare(&srcData);
161 }
162 
163 // This tests verifies that a Buffer11 contents remain unchanged after calling
164 // getEmulatedIndexedBuffer
TEST_P(D3D11EmulatedIndexedBufferTest,TestSourceBufferRemainsUntouchedAfterExpandOperation)165 TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation)
166 {
167     // Copy the original source buffer before any expand calls have been made
168     gl::BufferState cleanSourceState;
169     rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(cleanSourceState, mRenderer);
170     ASSERT_EQ(angle::Result::Continue, cleanSourceBuffer->copySubData(nullptr, mSourceBuffer, 0, 0,
171                                                                       mSourceBuffer->getSize()));
172 
173     // Do a basic exanded and compare test.
174     rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
175                                    static_cast<unsigned int>(muintIndices.size()),
176                                    gl::DrawElementsType::UnsignedInt, false};
177     emulateAndCompare(&srcData);
178 
179     const uint8_t *sourceBufferMem = nullptr;
180     const uint8_t *cleanBufferMem  = nullptr;
181 
182     ASSERT_EQ(angle::Result::Continue, mSourceBuffer->getData(mContext, &sourceBufferMem));
183     ASSERT_EQ(angle::Result::Continue, cleanSourceBuffer->getData(mContext, &cleanBufferMem));
184 
185     ASSERT_EQ(0, memcmp(sourceBufferMem, cleanBufferMem, cleanSourceBuffer->getSize()));
186 
187     SafeDelete(cleanSourceBuffer);
188 }
189 
190 ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest, ES2_D3D11(), ES3_D3D11(), ES31_D3D11());
191 
192 }  // anonymous namespace
193