blob: 5cdcb96cc26b7b0a7354197d724247436580a9be [file] [log] [blame]
Cooper Partin558f2b52015-06-02 09:34:11 -07001//
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 Partin558f2b52015-06-02 09:34:11 -070013#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040014#include "libANGLE/renderer/d3d/d3d11/Context11.h"
15#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
Cooper Partin558f2b52015-06-02 09:34:11 -070016#include "libANGLE/renderer/d3d/IndexDataManager.h"
17#include "test_utils/ANGLETest.h"
18#include "test_utils/angle_test_instantiate.h"
19
20using namespace angle;
21
22namespace
23{
24
25class 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
34 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
Jamie Madill53ea9cc2016-05-17 10:12:52 -040035 rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
36 mRenderer = context11->getRenderer();
Cooper Partin558f2b52015-06-02 09:34:11 -070037
38 mSourceBuffer = new rx::Buffer11(mRenderer);
39 GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
40 gl::Error error = mSourceBuffer->setData(testData, sizeof(testData), GL_STATIC_DRAW);
41 ASSERT_FALSE(error.isError());
42
Jamie Madill52b09c22016-04-11 14:12:31 -040043 mTranslatedAttribute.baseOffset = 0;
44 mTranslatedAttribute.usesFirstVertexOffset = false;
Cooper Partin558f2b52015-06-02 09:34:11 -070045 mTranslatedAttribute.stride = sizeof(GLfloat);
46
47 GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1};
48
Corentin Wallez0984d112015-10-29 14:06:04 -040049 for (size_t i = 0; i < ArraySize(indices); i++)
Cooper Partin558f2b52015-06-02 09:34:11 -070050 {
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 Wallez37c39792015-08-20 14:19:46 -040061 ANGLETest::TearDown();
Cooper Partin558f2b52015-06-02 09:34:11 -070062 }
63
64 void createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer *sourceBuffer, GLuint size, ID3D11Buffer **mappableBuffer)
65 {
66 *mappableBuffer = nullptr;
67
68 D3D11_BUFFER_DESC bufferDesc;
69 bufferDesc.ByteWidth = size;
70 bufferDesc.MiscFlags = 0;
71 bufferDesc.StructureByteStride = 0;
72 bufferDesc.Usage = D3D11_USAGE_STAGING;
73 bufferDesc.BindFlags = 0;
74 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
75
76 HRESULT hr = mRenderer->getDevice()->CreateBuffer(&bufferDesc, nullptr, mappableBuffer);
77 ASSERT_TRUE(SUCCEEDED(hr));
78
79 D3D11_BOX srcBox;
80 srcBox.left = 0;
81 srcBox.right = size;
82 srcBox.top = 0;
83 srcBox.bottom = 1;
84 srcBox.front = 0;
85 srcBox.back = 1;
86
87 mRenderer->getDeviceContext()->CopySubresourceRegion(*mappableBuffer, 0, 0, 0, 0, sourceBuffer, 0, &srcBox);
88 }
89
90 void compareContents(ID3D11Buffer *actual)
91 {
92 ID3D11Buffer *compareBuffer = nullptr;
Cooper Partin4d61f7e2015-08-12 10:56:50 -070093 createMappableCompareBufferFromEmulatedBuffer(
94 actual, sizeof(GLfloat) * static_cast<GLuint>(mExpectedExpandedData.size()),
95 &compareBuffer);
Cooper Partin558f2b52015-06-02 09:34:11 -070096
97 D3D11_MAPPED_SUBRESOURCE mappedResource;
98 HRESULT hr = mRenderer->getDeviceContext()->Map(compareBuffer, 0, D3D11_MAP_READ, 0, &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
111 void emulateAndCompare(rx::SourceIndexData *srcData)
112 {
Jamie Madill52b09c22016-04-11 14:12:31 -0400113 auto bufferOrError =
114 mSourceBuffer->getEmulatedIndexedBuffer(srcData, mTranslatedAttribute, 0);
Jamie Madill7d712e72016-03-29 21:54:33 -0400115 ASSERT_FALSE(bufferOrError.isError());
116 ID3D11Buffer *emulatedBuffer = bufferOrError.getResult();
Cooper Partin558f2b52015-06-02 09:34:11 -0700117 ASSERT_TRUE(emulatedBuffer != nullptr);
Cooper Partin558f2b52015-06-02 09:34:11 -0700118 compareContents(emulatedBuffer);
119 }
120
121 protected:
122 rx::Buffer11 *mSourceBuffer;
123 rx::Renderer11 *mRenderer;
124 rx::TranslatedAttribute mTranslatedAttribute;
125 std::vector<GLfloat> mExpectedExpandedData;
126 std::vector<GLubyte> mubyteIndices;
127 std::vector<GLuint> muintIndices;
128 std::vector<GLushort> mushortIndices;
129};
130
131// This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded
132// into a valid emulated indexed buffer.
133TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices)
134{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700135 rx::SourceIndexData srcData = {nullptr, mubyteIndices.data(),
136 static_cast<unsigned int>(mubyteIndices.size()),
137 GL_UNSIGNED_BYTE, false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700138 emulateAndCompare(&srcData);
139}
140
141// This tests that a GL_UNSIGNED_SHORT indices list can be successfully expanded
142// into a valid emulated indexed buffer.
143TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices)
144{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700145 rx::SourceIndexData srcData = {nullptr, mushortIndices.data(),
146 static_cast<unsigned int>(mushortIndices.size()),
147 GL_UNSIGNED_SHORT, false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700148 emulateAndCompare(&srcData);
149}
150
151// This tests that a GL_UNSIGNED_INT indices list can be successfully expanded
152// into a valid emulated indexed buffer.
153TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices)
154{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700155 rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
156 static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT,
157 false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700158 emulateAndCompare(&srcData);
159}
160
161// This tests verifies that a Buffer11 contents remain unchanged after calling getEmulatedIndexedBuffer
162TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation)
163{
164 // Copy the original source buffer before any expand calls have been made
165 rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(mRenderer);
166 cleanSourceBuffer->copySubData(mSourceBuffer, 0, 0, mSourceBuffer->getSize());
167
168 // Do a basic exanded and compare test.
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700169 rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
170 static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT,
171 false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700172 emulateAndCompare(&srcData);
173
174 const uint8_t *sourceBufferMem = nullptr;
175 const uint8_t *cleanBufferMem = nullptr;
176
177 gl::Error error = mSourceBuffer->getData(&sourceBufferMem);
178 ASSERT_FALSE(error.isError());
179
180 error = cleanSourceBuffer->getData(&cleanBufferMem);
181 ASSERT_FALSE(error.isError());
182
183 int result = memcmp(sourceBufferMem, cleanBufferMem, cleanSourceBuffer->getSize());
184 ASSERT_EQ(result, 0);
185
186 SafeDelete(cleanSourceBuffer);
187}
188
189ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest,
190 ES2_D3D11());
191
192} // anonymous namespace