blob: 39a42cc62ca7856e6f959a7aa6bcbef2e5a9867f [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
Rafael Cintron05a449a2018-06-20 18:08:04 -070034 mContext = static_cast<gl::Context *>(getEGLWindow()->getContext());
Jamie Madill33510102017-09-20 10:39:18 -040035 rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(mContext);
Jamie Madill53ea9cc2016-05-17 10:12:52 -040036 mRenderer = context11->getRenderer();
Cooper Partin558f2b52015-06-02 09:34:11 -070037
Jamie Madill8f775602016-11-03 16:45:34 -040038 mSourceBuffer = new rx::Buffer11(mBufferState, mRenderer);
Cooper Partin558f2b52015-06-02 09:34:11 -070039 GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
Corentin Wallez336129f2017-10-17 15:55:40 -040040 gl::Error error = mSourceBuffer->setData(nullptr, gl::BufferBinding::Array, testData,
Corentin Wallez2e568cf2017-09-18 17:05:22 -040041 sizeof(testData), gl::BufferUsage::StaticDraw);
Cooper Partin558f2b52015-06-02 09:34:11 -070042 ASSERT_FALSE(error.isError());
43
Jamie Madill52b09c22016-04-11 14:12:31 -040044 mTranslatedAttribute.baseOffset = 0;
45 mTranslatedAttribute.usesFirstVertexOffset = false;
Cooper Partin558f2b52015-06-02 09:34:11 -070046 mTranslatedAttribute.stride = sizeof(GLfloat);
47
48 GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1};
49
Corentin Wallez0984d112015-10-29 14:06:04 -040050 for (size_t i = 0; i < ArraySize(indices); i++)
Cooper Partin558f2b52015-06-02 09:34:11 -070051 {
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 Wallez37c39792015-08-20 14:19:46 -040062 ANGLETest::TearDown();
Cooper Partin558f2b52015-06-02 09:34:11 -070063 }
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 Partin4d61f7e2015-08-12 10:56:50 -070094 createMappableCompareBufferFromEmulatedBuffer(
95 actual, sizeof(GLfloat) * static_cast<GLuint>(mExpectedExpandedData.size()),
96 &compareBuffer);
Cooper Partin558f2b52015-06-02 09:34:11 -070097
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 Madilldf0e48f2018-07-24 11:06:46 -0400114 ID3D11Buffer *emulatedBuffer = nullptr;
115 gl::Error error = mSourceBuffer->getEmulatedIndexedBuffer(
116 mContext, srcData, mTranslatedAttribute, 0, &emulatedBuffer);
117 ASSERT_FALSE(error.isError());
Cooper Partin558f2b52015-06-02 09:34:11 -0700118 ASSERT_TRUE(emulatedBuffer != nullptr);
Cooper Partin558f2b52015-06-02 09:34:11 -0700119 compareContents(emulatedBuffer);
120 }
121
122 protected:
Jamie Madill33510102017-09-20 10:39:18 -0400123 gl::Context *mContext;
Cooper Partin558f2b52015-06-02 09:34:11 -0700124 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 Madill8f775602016-11-03 16:45:34 -0400131 gl::BufferState mBufferState;
Cooper Partin558f2b52015-06-02 09:34:11 -0700132};
133
134// This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded
135// into a valid emulated indexed buffer.
136TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices)
137{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700138 rx::SourceIndexData srcData = {nullptr, mubyteIndices.data(),
139 static_cast<unsigned int>(mubyteIndices.size()),
140 GL_UNSIGNED_BYTE, false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700141 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.
146TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices)
147{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700148 rx::SourceIndexData srcData = {nullptr, mushortIndices.data(),
149 static_cast<unsigned int>(mushortIndices.size()),
150 GL_UNSIGNED_SHORT, false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700151 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.
156TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices)
157{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700158 rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
159 static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT,
160 false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700161 emulateAndCompare(&srcData);
162}
163
164// This tests verifies that a Buffer11 contents remain unchanged after calling getEmulatedIndexedBuffer
165TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation)
166{
167 // Copy the original source buffer before any expand calls have been made
Jamie Madill8f775602016-11-03 16:45:34 -0400168 gl::BufferState cleanSourceState;
169 rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(cleanSourceState, mRenderer);
Jamie Madill71c88b32017-09-14 22:20:29 -0400170 ASSERT_FALSE(
171 cleanSourceBuffer->copySubData(nullptr, mSourceBuffer, 0, 0, mSourceBuffer->getSize())
172 .isError());
Cooper Partin558f2b52015-06-02 09:34:11 -0700173
174 // Do a basic exanded and compare test.
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700175 rx::SourceIndexData srcData = {nullptr, muintIndices.data(),
176 static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT,
177 false};
Cooper Partin558f2b52015-06-02 09:34:11 -0700178 emulateAndCompare(&srcData);
179
180 const uint8_t *sourceBufferMem = nullptr;
181 const uint8_t *cleanBufferMem = nullptr;
182
Jamie Madill33510102017-09-20 10:39:18 -0400183 gl::Error error = mSourceBuffer->getData(mContext, &sourceBufferMem);
Cooper Partin558f2b52015-06-02 09:34:11 -0700184 ASSERT_FALSE(error.isError());
185
Jamie Madill33510102017-09-20 10:39:18 -0400186 error = cleanSourceBuffer->getData(mContext, &cleanBufferMem);
Cooper Partin558f2b52015-06-02 09:34:11 -0700187 ASSERT_FALSE(error.isError());
188
189 int result = memcmp(sourceBufferMem, cleanBufferMem, cleanSourceBuffer->getSize());
190 ASSERT_EQ(result, 0);
191
192 SafeDelete(cleanSourceBuffer);
193}
194
195ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest,
196 ES2_D3D11());
197
198} // anonymous namespace