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