Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 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/angletypes.h" |
| 12 | #include "libANGLE/Context.h" |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 13 | #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" |
Jamie Madill | 53ea9cc | 2016-05-17 10:12:52 -0400 | [diff] [blame] | 14 | #include "libANGLE/renderer/d3d/d3d11/Context11.h" |
| 15 | #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 16 | #include "libANGLE/renderer/d3d/IndexDataManager.h" |
| 17 | #include "test_utils/ANGLETest.h" |
| 18 | #include "test_utils/angle_test_instantiate.h" |
| 19 | |
| 20 | using namespace angle; |
| 21 | |
| 22 | namespace |
| 23 | { |
| 24 | |
| 25 | class D3D11EmulatedIndexedBufferTest : public ANGLETest |
| 26 | { |
| 27 | protected: |
| 28 | |
| 29 | void SetUp() override |
| 30 | { |
| 31 | ANGLETest::SetUp(); |
| 32 | ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer()); |
| 33 | |
Jamie Madill | 3351010 | 2017-09-20 10:39:18 -0400 | [diff] [blame^] | 34 | mContext = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); |
| 35 | rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(mContext); |
Jamie Madill | 53ea9cc | 2016-05-17 10:12:52 -0400 | [diff] [blame] | 36 | mRenderer = context11->getRenderer(); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 37 | |
Jamie Madill | 8f77560 | 2016-11-03 16:45:34 -0400 | [diff] [blame] | 38 | mSourceBuffer = new rx::Buffer11(mBufferState, mRenderer); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 39 | GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f }; |
Jamie Madill | b8353b0 | 2017-01-25 12:57:21 -0800 | [diff] [blame] | 40 | gl::Error error = mSourceBuffer->setData(nullptr, GL_ARRAY_BUFFER, testData, |
| 41 | sizeof(testData), GL_STATIC_DRAW); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 42 | ASSERT_FALSE(error.isError()); |
| 43 | |
Jamie Madill | 52b09c2 | 2016-04-11 14:12:31 -0400 | [diff] [blame] | 44 | mTranslatedAttribute.baseOffset = 0; |
| 45 | mTranslatedAttribute.usesFirstVertexOffset = false; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 46 | mTranslatedAttribute.stride = sizeof(GLfloat); |
| 47 | |
| 48 | GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1}; |
| 49 | |
Corentin Wallez | 0984d11 | 2015-10-29 14:06:04 -0400 | [diff] [blame] | 50 | for (size_t i = 0; i < ArraySize(indices); i++) |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 51 | { |
| 52 | mExpectedExpandedData.push_back(testData[indices[i]]); |
| 53 | mubyteIndices.push_back(indices[i]); |
| 54 | muintIndices.push_back(indices[i]); |
| 55 | mushortIndices.push_back(indices[i]); |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | void TearDown() override |
| 60 | { |
| 61 | SafeDelete(mSourceBuffer); |
Corentin Wallez | 37c3979 | 2015-08-20 14:19:46 -0400 | [diff] [blame] | 62 | ANGLETest::TearDown(); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | void createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer *sourceBuffer, GLuint size, ID3D11Buffer **mappableBuffer) |
| 66 | { |
| 67 | *mappableBuffer = nullptr; |
| 68 | |
| 69 | D3D11_BUFFER_DESC bufferDesc; |
| 70 | bufferDesc.ByteWidth = size; |
| 71 | bufferDesc.MiscFlags = 0; |
| 72 | bufferDesc.StructureByteStride = 0; |
| 73 | bufferDesc.Usage = D3D11_USAGE_STAGING; |
| 74 | bufferDesc.BindFlags = 0; |
| 75 | bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; |
| 76 | |
| 77 | HRESULT hr = mRenderer->getDevice()->CreateBuffer(&bufferDesc, nullptr, mappableBuffer); |
| 78 | ASSERT_TRUE(SUCCEEDED(hr)); |
| 79 | |
| 80 | D3D11_BOX srcBox; |
| 81 | srcBox.left = 0; |
| 82 | srcBox.right = size; |
| 83 | srcBox.top = 0; |
| 84 | srcBox.bottom = 1; |
| 85 | srcBox.front = 0; |
| 86 | srcBox.back = 1; |
| 87 | |
| 88 | mRenderer->getDeviceContext()->CopySubresourceRegion(*mappableBuffer, 0, 0, 0, 0, sourceBuffer, 0, &srcBox); |
| 89 | } |
| 90 | |
| 91 | void compareContents(ID3D11Buffer *actual) |
| 92 | { |
| 93 | ID3D11Buffer *compareBuffer = nullptr; |
Cooper Partin | 4d61f7e | 2015-08-12 10:56:50 -0700 | [diff] [blame] | 94 | createMappableCompareBufferFromEmulatedBuffer( |
| 95 | actual, sizeof(GLfloat) * static_cast<GLuint>(mExpectedExpandedData.size()), |
| 96 | &compareBuffer); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 97 | |
| 98 | D3D11_MAPPED_SUBRESOURCE mappedResource; |
| 99 | HRESULT hr = mRenderer->getDeviceContext()->Map(compareBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); |
| 100 | ASSERT_TRUE(SUCCEEDED(hr)); |
| 101 | |
| 102 | GLfloat* compareData = static_cast<GLfloat*>(mappedResource.pData); |
| 103 | for (size_t i = 0; i < mExpectedExpandedData.size(); i++) |
| 104 | { |
| 105 | EXPECT_EQ(mExpectedExpandedData[i], compareData[i]); |
| 106 | } |
| 107 | |
| 108 | mRenderer->getDeviceContext()->Unmap(compareBuffer, 0); |
| 109 | SafeRelease(compareBuffer); |
| 110 | } |
| 111 | |
| 112 | void emulateAndCompare(rx::SourceIndexData *srcData) |
| 113 | { |
Jamie Madill | 52b09c2 | 2016-04-11 14:12:31 -0400 | [diff] [blame] | 114 | auto bufferOrError = |
Jamie Madill | 3351010 | 2017-09-20 10:39:18 -0400 | [diff] [blame^] | 115 | mSourceBuffer->getEmulatedIndexedBuffer(mContext, srcData, mTranslatedAttribute, 0); |
Jamie Madill | 7d712e7 | 2016-03-29 21:54:33 -0400 | [diff] [blame] | 116 | ASSERT_FALSE(bufferOrError.isError()); |
| 117 | ID3D11Buffer *emulatedBuffer = bufferOrError.getResult(); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 118 | ASSERT_TRUE(emulatedBuffer != nullptr); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 119 | compareContents(emulatedBuffer); |
| 120 | } |
| 121 | |
| 122 | protected: |
Jamie Madill | 3351010 | 2017-09-20 10:39:18 -0400 | [diff] [blame^] | 123 | gl::Context *mContext; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 124 | rx::Buffer11 *mSourceBuffer; |
| 125 | rx::Renderer11 *mRenderer; |
| 126 | rx::TranslatedAttribute mTranslatedAttribute; |
| 127 | std::vector<GLfloat> mExpectedExpandedData; |
| 128 | std::vector<GLubyte> mubyteIndices; |
| 129 | std::vector<GLuint> muintIndices; |
| 130 | std::vector<GLushort> mushortIndices; |
Jamie Madill | 8f77560 | 2016-11-03 16:45:34 -0400 | [diff] [blame] | 131 | gl::BufferState mBufferState; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 132 | }; |
| 133 | |
| 134 | // This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded |
| 135 | // into a valid emulated indexed buffer. |
| 136 | TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices) |
| 137 | { |
Cooper Partin | 4d61f7e | 2015-08-12 10:56:50 -0700 | [diff] [blame] | 138 | rx::SourceIndexData srcData = {nullptr, mubyteIndices.data(), |
| 139 | static_cast<unsigned int>(mubyteIndices.size()), |
| 140 | GL_UNSIGNED_BYTE, false}; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 141 | emulateAndCompare(&srcData); |
| 142 | } |
| 143 | |
| 144 | // This tests that a GL_UNSIGNED_SHORT indices list can be successfully expanded |
| 145 | // into a valid emulated indexed buffer. |
| 146 | TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices) |
| 147 | { |
Cooper Partin | 4d61f7e | 2015-08-12 10:56:50 -0700 | [diff] [blame] | 148 | rx::SourceIndexData srcData = {nullptr, mushortIndices.data(), |
| 149 | static_cast<unsigned int>(mushortIndices.size()), |
| 150 | GL_UNSIGNED_SHORT, false}; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 151 | emulateAndCompare(&srcData); |
| 152 | } |
| 153 | |
| 154 | // This tests that a GL_UNSIGNED_INT indices list can be successfully expanded |
| 155 | // into a valid emulated indexed buffer. |
| 156 | TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices) |
| 157 | { |
Cooper Partin | 4d61f7e | 2015-08-12 10:56:50 -0700 | [diff] [blame] | 158 | rx::SourceIndexData srcData = {nullptr, muintIndices.data(), |
| 159 | static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT, |
| 160 | false}; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 161 | emulateAndCompare(&srcData); |
| 162 | } |
| 163 | |
| 164 | // This tests verifies that a Buffer11 contents remain unchanged after calling getEmulatedIndexedBuffer |
| 165 | TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation) |
| 166 | { |
| 167 | // Copy the original source buffer before any expand calls have been made |
Jamie Madill | 8f77560 | 2016-11-03 16:45:34 -0400 | [diff] [blame] | 168 | gl::BufferState cleanSourceState; |
| 169 | rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(cleanSourceState, mRenderer); |
Jamie Madill | 71c88b3 | 2017-09-14 22:20:29 -0400 | [diff] [blame] | 170 | ASSERT_FALSE( |
| 171 | cleanSourceBuffer->copySubData(nullptr, mSourceBuffer, 0, 0, mSourceBuffer->getSize()) |
| 172 | .isError()); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 173 | |
| 174 | // Do a basic exanded and compare test. |
Cooper Partin | 4d61f7e | 2015-08-12 10:56:50 -0700 | [diff] [blame] | 175 | rx::SourceIndexData srcData = {nullptr, muintIndices.data(), |
| 176 | static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT, |
| 177 | false}; |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 178 | emulateAndCompare(&srcData); |
| 179 | |
| 180 | const uint8_t *sourceBufferMem = nullptr; |
| 181 | const uint8_t *cleanBufferMem = nullptr; |
| 182 | |
Jamie Madill | 3351010 | 2017-09-20 10:39:18 -0400 | [diff] [blame^] | 183 | gl::Error error = mSourceBuffer->getData(mContext, &sourceBufferMem); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 184 | ASSERT_FALSE(error.isError()); |
| 185 | |
Jamie Madill | 3351010 | 2017-09-20 10:39:18 -0400 | [diff] [blame^] | 186 | error = cleanSourceBuffer->getData(mContext, &cleanBufferMem); |
Cooper Partin | 558f2b5 | 2015-06-02 09:34:11 -0700 | [diff] [blame] | 187 | ASSERT_FALSE(error.isError()); |
| 188 | |
| 189 | int result = memcmp(sourceBufferMem, cleanBufferMem, cleanSourceBuffer->getSize()); |
| 190 | ASSERT_EQ(result, 0); |
| 191 | |
| 192 | SafeDelete(cleanSourceBuffer); |
| 193 | } |
| 194 | |
| 195 | ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest, |
| 196 | ES2_D3D11()); |
| 197 | |
| 198 | } // anonymous namespace |