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