blob: 4d6426c7d50875f754cb4f61fca8250c490c1530 [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
Cooper Partin558f2b52015-06-02 09:34:11 -070011#include "libANGLE/Context.h"
Jamie Madille4634a12018-11-14 09:54:35 -050012#include "libANGLE/angletypes.h"
13#include "libANGLE/renderer/d3d/IndexDataManager.h"
Cooper Partin558f2b52015-06-02 09:34:11 -070014#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040015#include "libANGLE/renderer/d3d/d3d11/Context11.h"
16#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
Cooper Partin558f2b52015-06-02 09:34:11 -070017#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:
Cooper Partin558f2b52015-06-02 09:34:11 -070028 void SetUp() override
29 {
30 ANGLETest::SetUp();
31 ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
32
Rafael Cintron05a449a2018-06-20 18:08:04 -070033 mContext = static_cast<gl::Context *>(getEGLWindow()->getContext());
Jamie Madill33510102017-09-20 10:39:18 -040034 rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(mContext);
Jamie Madill53ea9cc2016-05-17 10:12:52 -040035 mRenderer = context11->getRenderer();
Cooper Partin558f2b52015-06-02 09:34:11 -070036
Jamie Madille4634a12018-11-14 09:54:35 -050037 mSourceBuffer = new rx::Buffer11(mBufferState, mRenderer);
38 GLfloat testData[] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
Jamie Madill666818e2018-11-14 09:54:33 -050039 angle::Result error = mSourceBuffer->setData(nullptr, gl::BufferBinding::Array, testData,
40 sizeof(testData), gl::BufferUsage::StaticDraw);
41 ASSERT_EQ(angle::Result::Continue(), error);
Cooper Partin558f2b52015-06-02 09:34:11 -070042
Jamie Madill52b09c22016-04-11 14:12:31 -040043 mTranslatedAttribute.baseOffset = 0;
44 mTranslatedAttribute.usesFirstVertexOffset = false;
Jamie Madille4634a12018-11-14 09:54:35 -050045 mTranslatedAttribute.stride = sizeof(GLfloat);
Cooper Partin558f2b52015-06-02 09:34:11 -070046
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
Jamie Madille4634a12018-11-14 09:54:35 -050064 void createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer *sourceBuffer,
65 GLuint size,
66 ID3D11Buffer **mappableBuffer)
Cooper Partin558f2b52015-06-02 09:34:11 -070067 {
68 *mappableBuffer = nullptr;
69
70 D3D11_BUFFER_DESC bufferDesc;
Jamie Madille4634a12018-11-14 09:54:35 -050071 bufferDesc.ByteWidth = size;
72 bufferDesc.MiscFlags = 0;
Cooper Partin558f2b52015-06-02 09:34:11 -070073 bufferDesc.StructureByteStride = 0;
Jamie Madille4634a12018-11-14 09:54:35 -050074 bufferDesc.Usage = D3D11_USAGE_STAGING;
75 bufferDesc.BindFlags = 0;
76 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
Cooper Partin558f2b52015-06-02 09:34:11 -070077
78 HRESULT hr = mRenderer->getDevice()->CreateBuffer(&bufferDesc, nullptr, mappableBuffer);
79 ASSERT_TRUE(SUCCEEDED(hr));
80
81 D3D11_BOX srcBox;
Jamie Madille4634a12018-11-14 09:54:35 -050082 srcBox.left = 0;
83 srcBox.right = size;
84 srcBox.top = 0;
Cooper Partin558f2b52015-06-02 09:34:11 -070085 srcBox.bottom = 1;
Jamie Madille4634a12018-11-14 09:54:35 -050086 srcBox.front = 0;
87 srcBox.back = 1;
Cooper Partin558f2b52015-06-02 09:34:11 -070088
Jamie Madille4634a12018-11-14 09:54:35 -050089 mRenderer->getDeviceContext()->CopySubresourceRegion(*mappableBuffer, 0, 0, 0, 0,
90 sourceBuffer, 0, &srcBox);
Cooper Partin558f2b52015-06-02 09:34:11 -070091 }
92
93 void compareContents(ID3D11Buffer *actual)
94 {
95 ID3D11Buffer *compareBuffer = nullptr;
Cooper Partin4d61f7e2015-08-12 10:56:50 -070096 createMappableCompareBufferFromEmulatedBuffer(
97 actual, sizeof(GLfloat) * static_cast<GLuint>(mExpectedExpandedData.size()),
98 &compareBuffer);
Cooper Partin558f2b52015-06-02 09:34:11 -070099
100 D3D11_MAPPED_SUBRESOURCE mappedResource;
Jamie Madille4634a12018-11-14 09:54:35 -0500101 HRESULT hr = mRenderer->getDeviceContext()->Map(compareBuffer, 0, D3D11_MAP_READ, 0,
102 &mappedResource);
Cooper Partin558f2b52015-06-02 09:34:11 -0700103 ASSERT_TRUE(SUCCEEDED(hr));
104
Jamie Madille4634a12018-11-14 09:54:35 -0500105 GLfloat *compareData = static_cast<GLfloat *>(mappedResource.pData);
Cooper Partin558f2b52015-06-02 09:34:11 -0700106 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 Madilldf0e48f2018-07-24 11:06:46 -0400117 ID3D11Buffer *emulatedBuffer = nullptr;
Jamie Madill666818e2018-11-14 09:54:33 -0500118 angle::Result error = mSourceBuffer->getEmulatedIndexedBuffer(
Jamie Madilldf0e48f2018-07-24 11:06:46 -0400119 mContext, srcData, mTranslatedAttribute, 0, &emulatedBuffer);
Jamie Madill666818e2018-11-14 09:54:33 -0500120 ASSERT_EQ(angle::Result::Continue(), error);
Cooper Partin558f2b52015-06-02 09:34:11 -0700121 ASSERT_TRUE(emulatedBuffer != nullptr);
Cooper Partin558f2b52015-06-02 09:34:11 -0700122 compareContents(emulatedBuffer);
123 }
124
125 protected:
Jamie Madill33510102017-09-20 10:39:18 -0400126 gl::Context *mContext;
Cooper Partin558f2b52015-06-02 09:34:11 -0700127 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 Madill8f775602016-11-03 16:45:34 -0400134 gl::BufferState mBufferState;
Cooper Partin558f2b52015-06-02 09:34:11 -0700135};
136
137// This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded
138// into a valid emulated indexed buffer.
139TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices)
140{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700141 rx::SourceIndexData srcData = {nullptr, mubyteIndices.data(),
142 static_cast<unsigned int>(mubyteIndices.size()),
143 GL_UNSIGNED_BYTE, false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700144 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.
149TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices)
150{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700151 rx::SourceIndexData srcData = {nullptr, mushortIndices.data(),
152 static_cast<unsigned int>(mushortIndices.size()),
153 GL_UNSIGNED_SHORT, false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700154 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.
159TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices)
160{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700161 rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
162 static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT,
163 false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700164 emulateAndCompare(&srcData);
165}
166
Jamie Madille4634a12018-11-14 09:54:35 -0500167// This tests verifies that a Buffer11 contents remain unchanged after calling
168// getEmulatedIndexedBuffer
Cooper Partin558f2b52015-06-02 09:34:11 -0700169TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation)
170{
171 // Copy the original source buffer before any expand calls have been made
Jamie Madill8f775602016-11-03 16:45:34 -0400172 gl::BufferState cleanSourceState;
173 rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(cleanSourceState, mRenderer);
Jamie Madill71c88b32017-09-14 22:20:29 -0400174 ASSERT_FALSE(
175 cleanSourceBuffer->copySubData(nullptr, mSourceBuffer, 0, 0, mSourceBuffer->getSize())
176 .isError());
Cooper Partin558f2b52015-06-02 09:34:11 -0700177
178 // Do a basic exanded and compare test.
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700179 rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
180 static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT,
181 false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700182 emulateAndCompare(&srcData);
183
184 const uint8_t *sourceBufferMem = nullptr;
Jamie Madille4634a12018-11-14 09:54:35 -0500185 const uint8_t *cleanBufferMem = nullptr;
Cooper Partin558f2b52015-06-02 09:34:11 -0700186
Jamie Madill666818e2018-11-14 09:54:33 -0500187 angle::Result error = mSourceBuffer->getData(mContext, &sourceBufferMem);
188 ASSERT_EQ(angle::Result::Continue(), error);
Cooper Partin558f2b52015-06-02 09:34:11 -0700189
Jamie Madill33510102017-09-20 10:39:18 -0400190 error = cleanSourceBuffer->getData(mContext, &cleanBufferMem);
Cooper Partin558f2b52015-06-02 09:34:11 -0700191 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 Madille4634a12018-11-14 09:54:35 -0500199ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest, ES2_D3D11());
Cooper Partin558f2b52015-06-02 09:34:11 -0700200
Jamie Madille4634a12018-11-14 09:54:35 -0500201} // anonymous namespace