Skip to content

Commit 0d871b5

Browse files
committed
Use hash table for index conversion compute pipeline cache instead of tree map
Change-Id: I83cfdfb1918d3bc36f34ac81953da812cc48f26c
1 parent f12e3ca commit 0d871b5

File tree

3 files changed

+84
-25
lines changed

3 files changed

+84
-25
lines changed

src/libANGLE/renderer/metal/mtl_render_utils.h

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,37 @@
1616
#include "libANGLE/renderer/metal/mtl_command_buffer.h"
1717
#include "libANGLE/renderer/metal/mtl_state_cache.h"
1818

19+
namespace rx
20+
{
21+
namespace mtl
22+
{
23+
struct IndexConversionPipelineCacheKey
24+
{
25+
gl::DrawElementsType srcType;
26+
bool srcBufferOffsetAligned;
27+
28+
bool operator==(const IndexConversionPipelineCacheKey &other) const;
29+
30+
size_t hash() const;
31+
};
32+
33+
} // namespace mtl
34+
} // namespace rx
35+
36+
namespace std
37+
{
38+
39+
template <>
40+
struct hash<rx::mtl::IndexConversionPipelineCacheKey>
41+
{
42+
size_t operator()(const rx::mtl::IndexConversionPipelineCacheKey &key) const
43+
{
44+
return key.hash();
45+
}
46+
};
47+
48+
} // namespace std
49+
1950
namespace rx
2051
{
2152

@@ -218,17 +249,9 @@ class RenderUtils : public Context, angle::NonCopyable
218249
RenderPipelineCache mStencilBlitRenderPipelineCache;
219250
RenderPipelineCache mDepthStencilBlitRenderPipelineCache;
220251

221-
struct IndexConvesionPipelineCacheKey
222-
{
223-
gl::DrawElementsType srcType;
224-
bool srcBufferOffsetAligned;
225-
226-
bool operator==(const IndexConvesionPipelineCacheKey &other) const;
227-
bool operator<(const IndexConvesionPipelineCacheKey &other) const;
228-
};
229-
std::map<IndexConvesionPipelineCacheKey, AutoObjCPtr<id<MTLComputePipelineState>>>
252+
std::unordered_map<IndexConversionPipelineCacheKey, AutoObjCPtr<id<MTLComputePipelineState>>>
230253
mIndexConversionPipelineCaches;
231-
std::map<IndexConvesionPipelineCacheKey, AutoObjCPtr<id<MTLComputePipelineState>>>
254+
std::unordered_map<IndexConversionPipelineCacheKey, AutoObjCPtr<id<MTLComputePipelineState>>>
232255
mTriFanFromElemArrayGeneratorPipelineCaches;
233256
AutoObjCPtr<id<MTLComputePipelineState>> mTriFanFromArraysGeneratorPipeline;
234257
};

src/libANGLE/renderer/metal/mtl_render_utils.mm

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,16 @@ void GetFirstLastIndicesFromClientElements(GLsizei count,
101101

102102
} // namespace
103103

104-
bool RenderUtils::IndexConvesionPipelineCacheKey::operator==(
105-
const IndexConvesionPipelineCacheKey &other) const
104+
bool IndexConversionPipelineCacheKey::operator==(const IndexConversionPipelineCacheKey &other) const
106105
{
107106
return srcType == other.srcType && srcBufferOffsetAligned == other.srcBufferOffsetAligned;
108107
}
109-
bool RenderUtils::IndexConvesionPipelineCacheKey::operator<(
110-
const IndexConvesionPipelineCacheKey &other) const
108+
size_t IndexConversionPipelineCacheKey::hash() const
111109
{
112-
if (!srcBufferOffsetAligned && other.srcBufferOffsetAligned)
113-
{
114-
return true;
115-
}
116-
if (srcBufferOffsetAligned && !other.srcBufferOffsetAligned)
117-
{
118-
return false;
119-
}
120-
return static_cast<int>(srcType) < static_cast<int>(other.srcType);
110+
size_t h = srcBufferOffsetAligned ? 1 : 0;
111+
h = (h << static_cast<size_t>(gl::DrawElementsType::EnumCount));
112+
h = h | static_cast<size_t>(srcType);
113+
return h;
121114
}
122115

123116
RenderUtils::RenderUtils(DisplayMtl *display) : Context(display) {}
@@ -752,7 +745,7 @@ void GetFirstLastIndicesFromClientElements(GLsizei count,
752745
size_t elementSize = gl::GetDrawElementsTypeSize(srcType);
753746
bool aligned = (srcOffset % elementSize) == 0;
754747

755-
IndexConvesionPipelineCacheKey key = {srcType, aligned};
748+
IndexConversionPipelineCacheKey key = {srcType, aligned};
756749

757750
auto &cache = mIndexConversionPipelineCaches[key];
758751

@@ -816,7 +809,7 @@ void GetFirstLastIndicesFromClientElements(GLsizei count,
816809
size_t elementSize = gl::GetDrawElementsTypeSize(srcType);
817810
bool aligned = (srcOffset % elementSize) == 0;
818811

819-
IndexConvesionPipelineCacheKey key = {srcType, aligned};
812+
IndexConversionPipelineCacheKey key = {srcType, aligned};
820813

821814
auto &cache = mTriFanFromElemArrayGeneratorPipelineCaches[key];
822815

src/tests/gl_tests/IndexBufferOffsetTest.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,49 @@ TEST_P(IndexBufferOffsetTest, DrawAtDifferentOffsets)
173173
EXPECT_GL_NO_ERROR();
174174
}
175175

176+
// Uses index buffer offset and 2 drawElement calls one of the other, one has aligned
177+
// offset and one doesn't
178+
TEST_P(IndexBufferOffsetTest, DrawAtDifferentOffsetAlignments)
179+
{
180+
GLubyte indexData8[] = {0, 1, 0, 1, 2, 3};
181+
GLushort indexData16[] = {0, 1, 2, 1, 2, 3};
182+
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
183+
glClear(GL_COLOR_BUFFER_BIT);
184+
185+
size_t indexDataWidth16 = 6 * sizeof(GLushort);
186+
187+
GLuint buffer[2];
188+
glGenBuffers(2, buffer);
189+
190+
glUseProgram(mProgram);
191+
glUniform4f(mColorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
192+
193+
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
194+
glVertexAttribPointer(mPositionAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
195+
glEnableVertexAttribArray(mPositionAttributeLocation);
196+
197+
// 8 bit index with aligned offset
198+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[0]);
199+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData8), indexData8, GL_DYNAMIC_DRAW);
200+
201+
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(2));
202+
203+
// 16 bits index buffer, which unaligned offset
204+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[1]);
205+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexDataWidth16, indexData16, GL_DYNAMIC_DRAW);
206+
207+
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT,
208+
reinterpret_cast<void *>(indexDataWidth16 / 2));
209+
210+
// Check the upper left triangle
211+
EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() / 4, GLColor::red);
212+
213+
// Check the down right triangle
214+
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
215+
216+
EXPECT_GL_NO_ERROR();
217+
}
218+
176219
// Uses index buffer offset and 2 drawElement calls one of the other with different counts,
177220
// makes sure the second drawElement call will have its data available.
178221
TEST_P(IndexBufferOffsetTest, DrawWithDifferentCountsSameOffset)

0 commit comments

Comments
 (0)