Commit 558f2b5a by Cooper Partin Committed by Jamie Madill

Added emulated indexed pointsprite rendering support.

This emulation is for renderers that do not support Geometry Shaders. BUG=angleproject:949 Change-Id: I7acf003e83ea6661f10a703486e6d07eb28786f8 Reviewed-on: https://chromium-review.googlesource.com/274851Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarCooper Partin <coopp@microsoft.com>
parent ccda698b
...@@ -39,6 +39,7 @@ struct Data; ...@@ -39,6 +39,7 @@ struct Data;
namespace rx namespace rx
{ {
struct TranslatedIndexData; struct TranslatedIndexData;
struct SourceIndexData;
struct Workarounds; struct Workarounds;
class DisplayImpl; class DisplayImpl;
......
...@@ -69,7 +69,7 @@ IndexDataManager::~IndexDataManager() ...@@ -69,7 +69,7 @@ IndexDataManager::~IndexDataManager()
SafeDelete(mStreamingBufferInt); SafeDelete(mStreamingBufferInt);
} }
gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated) gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated, SourceIndexData *sourceData)
{ {
const gl::Type &typeInfo = gl::GetTypeInfo(type); const gl::Type &typeInfo = gl::GetTypeInfo(type);
...@@ -222,7 +222,13 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf ...@@ -222,7 +222,13 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
translated->startIndex = (streamOffset >> destTypeInfo.bytesShift); translated->startIndex = (streamOffset >> destTypeInfo.bytesShift);
translated->startOffset = streamOffset; translated->startOffset = streamOffset;
translated->indexType = destinationIndexType; translated->indexType = destinationIndexType;
if (sourceData)
{
// Update pretranslated source index data
sourceData->srcIndices = indices;
sourceData->srcIndexType = type;
sourceData->srcCount = count;
}
if (storage) if (storage)
{ {
storage->promoteStaticUsage(count << typeInfo.bytesShift); storage->promoteStaticUsage(count << typeInfo.bytesShift);
......
...@@ -48,13 +48,21 @@ struct TranslatedIndexData ...@@ -48,13 +48,21 @@ struct TranslatedIndexData
unsigned int serial; unsigned int serial;
}; };
struct SourceIndexData
{
const GLvoid *srcIndices;
unsigned int srcCount;
GLenum srcIndexType;
bool srcIndicesChanged;
};
class IndexDataManager : angle::NonCopyable class IndexDataManager : angle::NonCopyable
{ {
public: public:
explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass); explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass);
virtual ~IndexDataManager(); virtual ~IndexDataManager();
gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated, SourceIndexData *sourceData);
private: private:
gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer); gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer);
......
...@@ -106,7 +106,10 @@ gl::Error RendererD3D::drawElements(const gl::Data &data, ...@@ -106,7 +106,10 @@ gl::Error RendererD3D::drawElements(const gl::Data &data,
gl::VertexArray *vao = data.state->getVertexArray(); gl::VertexArray *vao = data.state->getVertexArray();
TranslatedIndexData indexInfo; TranslatedIndexData indexInfo;
indexInfo.indexRange = indexRange; indexInfo.indexRange = indexRange;
error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
SourceIndexData sourceIndexInfo;
error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo, &sourceIndexInfo);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -118,7 +121,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data, ...@@ -118,7 +121,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data,
ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
GLsizei vertexCount = indexInfo.indexRange.length() + 1; GLsizei vertexCount = indexInfo.indexRange.length() + 1;
error = applyVertexBuffer(*data.state, mode, indexInfo.indexRange.start, vertexCount, instances); error = applyVertexBuffer(*data.state, mode, indexInfo.indexRange.start, vertexCount, instances, &sourceIndexInfo);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -144,7 +147,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data, ...@@ -144,7 +147,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data,
if (!skipDraw(data, mode)) if (!skipDraw(data, mode))
{ {
error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances, program->usesPointSize());
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -188,7 +191,7 @@ gl::Error RendererD3D::drawArrays(const gl::Data &data, ...@@ -188,7 +191,7 @@ gl::Error RendererD3D::drawArrays(const gl::Data &data,
applyTransformFeedbackBuffers(*data.state); applyTransformFeedbackBuffers(*data.state);
error = applyVertexBuffer(*data.state, mode, first, count, instances); error = applyVertexBuffer(*data.state, mode, first, count, instances, nullptr);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -134,8 +134,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -134,8 +134,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
bool rasterizerDiscard, bool transformFeedbackActive) = 0; bool rasterizerDiscard, bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0; virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) = 0; virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo) = 0;
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo) = 0;
virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0; virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0;
virtual void markAllStateDirty() = 0; virtual void markAllStateDirty() = 0;
...@@ -206,7 +206,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -206,7 +206,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
protected: protected:
virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) = 0; virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) = 0;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances,
bool usesPointSize) = 0;
virtual bool getLUID(LUID *adapterLuid) const = 0; virtual bool getLUID(LUID *adapterLuid) const = 0;
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
namespace rx namespace rx
{ {
class Renderer11; class Renderer11;
struct SourceIndexData;
struct TranslatedAttribute;
enum BufferUsage enum BufferUsage
{ {
...@@ -27,6 +29,7 @@ enum BufferUsage ...@@ -27,6 +29,7 @@ enum BufferUsage
BUFFER_USAGE_PIXEL_PACK, BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM, BUFFER_USAGE_UNIFORM,
BUFFER_USAGE_SYSTEM_MEMORY, BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
}; };
struct PackPixelsParams struct PackPixelsParams
...@@ -53,6 +56,7 @@ class Buffer11 : public BufferD3D ...@@ -53,6 +56,7 @@ class Buffer11 : public BufferD3D
virtual ~Buffer11(); virtual ~Buffer11();
ID3D11Buffer *getBuffer(BufferUsage usage); ID3D11Buffer *getBuffer(BufferUsage usage);
ID3D11Buffer *getEmulatedIndexedBuffer(SourceIndexData *indexInfo, const TranslatedAttribute *attribute);
ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size); ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size);
ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
bool isMapped() const { return mMappedStorage != NULL; } bool isMapped() const { return mMappedStorage != NULL; }
...@@ -74,6 +78,7 @@ class Buffer11 : public BufferD3D ...@@ -74,6 +78,7 @@ class Buffer11 : public BufferD3D
private: private:
class BufferStorage; class BufferStorage;
class EmulatedIndexedStorage;
class NativeStorage; class NativeStorage;
class PackStorage; class PackStorage;
class SystemMemoryStorage; class SystemMemoryStorage;
...@@ -117,6 +122,8 @@ class Buffer11 : public BufferD3D ...@@ -117,6 +122,8 @@ class Buffer11 : public BufferD3D
BufferStorage *getLatestBufferStorage() const; BufferStorage *getLatestBufferStorage() const;
BufferStorage *getContantBufferRangeStorage(GLintptr offset, GLsizeiptr size); BufferStorage *getContantBufferRangeStorage(GLintptr offset, GLsizeiptr size);
void invalidateEmulatedIndexedBuffer();
}; };
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/ProgramD3D.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/VertexAttribute.h" #include "libANGLE/VertexAttribute.h"
...@@ -98,7 +99,7 @@ void InputLayoutCache::markDirty() ...@@ -98,7 +99,7 @@ void InputLayoutCache::markDirty()
} }
gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttribute> &unsortedAttributes, gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttribute> &unsortedAttributes,
GLenum mode, gl::Program *program) GLenum mode, gl::Program *program, SourceIndexData *sourceInfo)
{ {
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
...@@ -107,6 +108,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttri ...@@ -107,6 +108,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttri
programD3D->sortAttributesByLayout(unsortedAttributes, sortedSemanticIndices, sortedAttributes); programD3D->sortAttributesByLayout(unsortedAttributes, sortedSemanticIndices, sortedAttributes);
bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS); bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
bool indexedPointSpriteEmulationActive = instancedPointSpritesActive && (sourceInfo != nullptr);
if (!mDevice || !mDeviceContext) if (!mDevice || !mDeviceContext)
{ {
...@@ -293,8 +295,22 @@ gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttri ...@@ -293,8 +295,22 @@ gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttri
VertexBuffer11 *vertexBuffer = GetAs<VertexBuffer11>(sortedAttributes[i]->vertexBuffer); VertexBuffer11 *vertexBuffer = GetAs<VertexBuffer11>(sortedAttributes[i]->vertexBuffer);
Buffer11 *bufferStorage = sortedAttributes[i]->storage ? GetAs<Buffer11>(sortedAttributes[i]->storage) : NULL; Buffer11 *bufferStorage = sortedAttributes[i]->storage ? GetAs<Buffer11>(sortedAttributes[i]->storage) : NULL;
buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK) // If indexed pointsprite emulation is active, then we need to take a less efficent code path.
: vertexBuffer->getBuffer(); // Emulated indexed pointsprite rendering requires that the vertex buffers match exactly to
// the indices passed by the caller. This could expand or shrink the vertex buffer depending
// on the number of points indicated by the index list or how many duplicates are found on the index list.
if (bufferStorage == nullptr)
{
buffer = vertexBuffer->getBuffer();
}
else if (indexedPointSpriteEmulationActive)
{
buffer = bufferStorage->getEmulatedIndexedBuffer(sourceInfo, sortedAttributes[i]);
}
else
{
buffer = bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
}
vertexStride = sortedAttributes[i]->stride; vertexStride = sortedAttributes[i]->stride;
vertexOffset = sortedAttributes[i]->offset; vertexOffset = sortedAttributes[i]->offset;
...@@ -322,7 +338,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttri ...@@ -322,7 +338,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(const std::vector<TranslatedAttri
} }
// Instanced PointSprite emulation requires two additional ID3D11Buffers. // Instanced PointSprite emulation requires two additional ID3D11Buffers.
// A vertex buffer needs to be created and added to the list of current buffers, // A vertex buffer needs to be created and added to the list of current buffers,
// strides and offsets collections. This buffer contains the vertices for a single // strides and offsets collections. This buffer contains the vertices for a single
// PointSprite quad. // PointSprite quad.
// An index buffer also needs to be created and applied because rendering instanced // An index buffer also needs to be created and applied because rendering instanced
......
...@@ -27,6 +27,8 @@ class Program; ...@@ -27,6 +27,8 @@ class Program;
namespace rx namespace rx
{ {
struct TranslatedAttribute; struct TranslatedAttribute;
struct TranslatedIndexData;
struct SourceIndexData;
class InputLayoutCache : angle::NonCopyable class InputLayoutCache : angle::NonCopyable
{ {
...@@ -39,7 +41,7 @@ class InputLayoutCache : angle::NonCopyable ...@@ -39,7 +41,7 @@ class InputLayoutCache : angle::NonCopyable
void markDirty(); void markDirty();
gl::Error applyVertexBuffers(const std::vector<TranslatedAttribute> &attributes, gl::Error applyVertexBuffers(const std::vector<TranslatedAttribute> &attributes,
GLenum mode, gl::Program *program); GLenum mode, gl::Program *program, SourceIndexData *sourceInfo);
private: private:
struct InputLayoutElement struct InputLayoutElement
......
...@@ -237,6 +237,7 @@ Renderer11::Renderer11(egl::Display *display) ...@@ -237,6 +237,7 @@ Renderer11::Renderer11(egl::Display *display)
mLineLoopIB = NULL; mLineLoopIB = NULL;
mTriangleFanIB = NULL; mTriangleFanIB = NULL;
mAppliedIBChanged = false;
mBlit = NULL; mBlit = NULL;
mPixelTransfer = NULL; mPixelTransfer = NULL;
...@@ -1515,7 +1516,7 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) ...@@ -1515,7 +1516,7 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo)
{ {
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances);
if (error.isError()) if (error.isError())
...@@ -1523,12 +1524,18 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLi ...@@ -1523,12 +1524,18 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLi
return error; return error;
} }
return mInputLayoutCache.applyVertexBuffers(mTranslatedAttribCache, mode, state.getProgram()); // If index information is passed, mark it with the current changed status.
if (sourceInfo)
{
sourceInfo->srcIndicesChanged = mAppliedIBChanged;
}
return mInputLayoutCache.applyVertexBuffers(mTranslatedAttribCache, mode, state.getProgram(), sourceInfo);
} }
gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo)
{ {
gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo, sourceIndexInfo);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -1548,6 +1555,7 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen ...@@ -1548,6 +1555,7 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
buffer = indexBuffer->getBuffer(); buffer = indexBuffer->getBuffer();
} }
mAppliedIBChanged = false;
if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
{ {
mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
...@@ -1555,6 +1563,7 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen ...@@ -1555,6 +1563,7 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
mAppliedIB = buffer; mAppliedIB = buffer;
mAppliedIBFormat = bufferFormat; mAppliedIBFormat = bufferFormat;
mAppliedIBOffset = indexInfo->startOffset; mAppliedIBOffset = indexInfo->startOffset;
mAppliedIBChanged = true;
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -1690,9 +1699,9 @@ gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei coun ...@@ -1690,9 +1699,9 @@ gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei coun
} }
else else
{ {
// If gl_PointSize is used and GL_POINTS is specified, then it is expected to render pointsprites. // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
// If instanced pointsprite emulation is being used the topology is expexted to be // Emulating instanced point sprites for FL9_3 requires the topology to be
// D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced must be used. // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
if (mode == GL_POINTS && useInstancedPointSpriteEmulation) if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
{ {
mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
...@@ -1706,8 +1715,10 @@ gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei coun ...@@ -1706,8 +1715,10 @@ gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei coun
} }
gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances,
bool usesPointSize)
{ {
bool useInstancedPointSpriteEmulation = usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation;
int minIndex = static_cast<int>(indexInfo.indexRange.start); int minIndex = static_cast<int>(indexInfo.indexRange.start);
if (mode == GL_LINE_LOOP) if (mode == GL_LINE_LOOP)
...@@ -1725,8 +1736,27 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons ...@@ -1725,8 +1736,27 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
} }
else else
{ {
mDeviceContext->DrawIndexed(count, 0, -minIndex); // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
return gl::Error(GL_NO_ERROR); // Emulating instanced point sprites for FL9_3 requires the topology to be
// D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
{
// The count parameter passed to drawElements represents the total number of instances
// to be rendered. Each instance is referenced by the bound index buffer from the
// the caller.
//
// Indexed pointsprite emulation replicates data for duplicate entries found
// in the index buffer.
// This is not an efficent rendering mechanism and is only used on downlevel renderers
// that do not support geometry shaders.
mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
return gl::Error(GL_NO_ERROR);
}
else
{
mDeviceContext->DrawIndexed(count, 0, -minIndex);
return gl::Error(GL_NO_ERROR);
}
} }
} }
......
...@@ -134,13 +134,14 @@ class Renderer11 : public RendererD3D ...@@ -134,13 +134,14 @@ class Renderer11 : public RendererD3D
bool rasterizerDiscard, bool transformFeedbackActive); bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray); virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances); virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
void applyTransformFeedbackBuffers(const gl::State &state) override; void applyTransformFeedbackBuffers(const gl::State &state) override;
gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override; gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances,
bool usesPointSize);
virtual void markAllStateDirty(); virtual void markAllStateDirty();
...@@ -391,6 +392,7 @@ class Renderer11 : public RendererD3D ...@@ -391,6 +392,7 @@ class Renderer11 : public RendererD3D
ID3D11Buffer *mAppliedIB; ID3D11Buffer *mAppliedIB;
DXGI_FORMAT mAppliedIBFormat; DXGI_FORMAT mAppliedIBFormat;
unsigned int mAppliedIBOffset; unsigned int mAppliedIBOffset;
bool mAppliedIBChanged;
// Currently applied transform feedback buffers // Currently applied transform feedback buffers
size_t mAppliedNumXFBBindings; size_t mAppliedNumXFBBindings;
......
...@@ -1416,7 +1416,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) ...@@ -1416,7 +1416,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer()); return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer());
} }
gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData * /*sourceInfo*/)
{ {
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances);
if (error.isError()) if (error.isError())
...@@ -1428,9 +1428,9 @@ gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLin ...@@ -1428,9 +1428,9 @@ gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLin
} }
// Applies the indices and element array bindings to the Direct3D 9 device // Applies the indices and element array bindings to the Direct3D 9 device
gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo)
{ {
gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo, sourceIndexInfo);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -1497,7 +1497,8 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count ...@@ -1497,7 +1497,8 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count
} }
gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/,
bool /*usesPointSize*/)
{ {
startScene(); startScene();
......
...@@ -110,14 +110,15 @@ class Renderer9 : public RendererD3D ...@@ -110,14 +110,15 @@ class Renderer9 : public RendererD3D
bool rasterizerDiscard, bool transformFeedbackActive); bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray); virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances); virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
void applyTransformFeedbackBuffers(const gl::State &state) override; void applyTransformFeedbackBuffers(const gl::State &state) override;
gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override; gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances,
bool usesPointSize);
gl::Error clear(const ClearParameters &clearParams, gl::Error clear(const ClearParameters &clearParams,
const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *colorBuffer,
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
], ],
'angle_end2end_tests_win_sources': 'angle_end2end_tests_win_sources':
[ [
'<(angle_path)/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11FormatTablesTest.cpp', '<(angle_path)/src/tests/gl_tests/D3D11FormatTablesTest.cpp',
'<(angle_path)/src/tests/gl_tests/QueryDisplayAttribTest.cpp', '<(angle_path)/src/tests/gl_tests/QueryDisplayAttribTest.cpp',
# TODO(cwallez) for Linux, requires a portable implementation of threads # TODO(cwallez) for Linux, requires a portable implementation of threads
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// D3D11EmulatedIndexedBufferTest:
// Tests to validate our D3D11 support for emulating an indexed
// vertex buffer.
//
#include "libANGLE/angletypes.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_instantiate.h"
using namespace angle;
namespace
{
class D3D11EmulatedIndexedBufferTest : public ANGLETest
{
protected:
void SetUp() override
{
ANGLETest::SetUp();
ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
mRenderer = rx::GetAs<rx::Renderer11>(context->getRenderer());
mSourceBuffer = new rx::Buffer11(mRenderer);
GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
gl::Error error = mSourceBuffer->setData(testData, sizeof(testData), GL_STATIC_DRAW);
ASSERT_FALSE(error.isError());
mTranslatedAttribute.offset = 0;
mTranslatedAttribute.stride = sizeof(GLfloat);
GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1};
for (size_t i = 0; i < _countof(indices); i++)
{
mExpectedExpandedData.push_back(testData[indices[i]]);
mubyteIndices.push_back(indices[i]);
muintIndices.push_back(indices[i]);
mushortIndices.push_back(indices[i]);
}
}
void TearDown() override
{
SafeDelete(mSourceBuffer);
ANGLETest::TearDown();
}
void createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer *sourceBuffer, GLuint size, ID3D11Buffer **mappableBuffer)
{
*mappableBuffer = nullptr;
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = size;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
bufferDesc.Usage = D3D11_USAGE_STAGING;
bufferDesc.BindFlags = 0;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
HRESULT hr = mRenderer->getDevice()->CreateBuffer(&bufferDesc, nullptr, mappableBuffer);
ASSERT_TRUE(SUCCEEDED(hr));
D3D11_BOX srcBox;
srcBox.left = 0;
srcBox.right = size;
srcBox.top = 0;
srcBox.bottom = 1;
srcBox.front = 0;
srcBox.back = 1;
mRenderer->getDeviceContext()->CopySubresourceRegion(*mappableBuffer, 0, 0, 0, 0, sourceBuffer, 0, &srcBox);
}
void compareContents(ID3D11Buffer *actual)
{
ID3D11Buffer *compareBuffer = nullptr;
createMappableCompareBufferFromEmulatedBuffer(actual, sizeof(GLfloat) * mExpectedExpandedData.size(), &compareBuffer);
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT hr = mRenderer->getDeviceContext()->Map(compareBuffer, 0, D3D11_MAP_READ, 0, &mappedResource);
ASSERT_TRUE(SUCCEEDED(hr));
GLfloat* compareData = static_cast<GLfloat*>(mappedResource.pData);
for (size_t i = 0; i < mExpectedExpandedData.size(); i++)
{
EXPECT_EQ(mExpectedExpandedData[i], compareData[i]);
}
mRenderer->getDeviceContext()->Unmap(compareBuffer, 0);
SafeRelease(compareBuffer);
}
void emulateAndCompare(rx::SourceIndexData *srcData)
{
ID3D11Buffer* emulatedBuffer = mSourceBuffer->getEmulatedIndexedBuffer(srcData, &mTranslatedAttribute);
ASSERT_TRUE(emulatedBuffer != nullptr);
compareContents(emulatedBuffer);
}
protected:
rx::Buffer11 *mSourceBuffer;
rx::Renderer11 *mRenderer;
rx::TranslatedAttribute mTranslatedAttribute;
std::vector<GLfloat> mExpectedExpandedData;
std::vector<GLubyte> mubyteIndices;
std::vector<GLuint> muintIndices;
std::vector<GLushort> mushortIndices;
};
// This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded
// into a valid emulated indexed buffer.
TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices)
{
rx::SourceIndexData srcData = {mubyteIndices.data(), mubyteIndices.size(), GL_UNSIGNED_BYTE, false};
emulateAndCompare(&srcData);
}
// This tests that a GL_UNSIGNED_SHORT indices list can be successfully expanded
// into a valid emulated indexed buffer.
TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices)
{
rx::SourceIndexData srcData = {mushortIndices.data(), mushortIndices.size(), GL_UNSIGNED_SHORT, false};
emulateAndCompare(&srcData);
}
// This tests that a GL_UNSIGNED_INT indices list can be successfully expanded
// into a valid emulated indexed buffer.
TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices)
{
rx::SourceIndexData srcData = {muintIndices.data(), muintIndices.size(), GL_UNSIGNED_INT, false};
emulateAndCompare(&srcData);
}
// This tests verifies that a Buffer11 contents remain unchanged after calling getEmulatedIndexedBuffer
TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation)
{
// Copy the original source buffer before any expand calls have been made
rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(mRenderer);
cleanSourceBuffer->copySubData(mSourceBuffer, 0, 0, mSourceBuffer->getSize());
// Do a basic exanded and compare test.
rx::SourceIndexData srcData = {muintIndices.data(), muintIndices.size(), GL_UNSIGNED_INT, false};
emulateAndCompare(&srcData);
const uint8_t *sourceBufferMem = nullptr;
const uint8_t *cleanBufferMem = nullptr;
gl::Error error = mSourceBuffer->getData(&sourceBufferMem);
ASSERT_FALSE(error.isError());
error = cleanSourceBuffer->getData(&cleanBufferMem);
ASSERT_FALSE(error.isError());
int result = memcmp(sourceBufferMem, cleanBufferMem, cleanSourceBuffer->getSize());
ASSERT_EQ(result, 0);
SafeDelete(cleanSourceBuffer);
}
ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest,
ES2_D3D11());
} // anonymous namespace
...@@ -60,23 +60,64 @@ class IndexedPointsTest : public ANGLETest ...@@ -60,23 +60,64 @@ class IndexedPointsTest : public ANGLETest
); );
mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
if (mProgram == 0) ASSERT_NE(0u, mProgram);
const std::string vertexShaderSource2 = SHADER_SOURCE
(
precision highp float;
attribute vec2 position;
attribute vec4 color;
varying vec4 vcolor;
void main()
{
gl_PointSize = 5.0;
gl_Position = vec4(position, 0.0, 1.0);
vcolor = color;
}
);
const std::string fragmentShaderSource2 = SHADER_SOURCE
(
precision highp float;
varying vec4 vcolor;
void main()
{
gl_FragColor = vec4(vcolor.xyz, 1.0);
}
);
mVertexWithColorBufferProgram = CompileProgram(vertexShaderSource2, fragmentShaderSource2);
ASSERT_NE(0u, mVertexWithColorBufferProgram);
// Construct a vertex buffer of position values and color values
// contained in a single structure
const float verticesWithColor[] =
{ {
FAIL() << "shader compilation failed."; getIndexPositionX(0), getIndexPositionY(0), 0.0f, 1.0f, 0.0f,
} getIndexPositionX(2), getIndexPositionY(2), 0.0f, 1.0f, 0.0f,
getIndexPositionX(1), getIndexPositionY(1), 0.0f, 1.0f, 0.0f,
getIndexPositionX(3), getIndexPositionY(3), 0.0f, 1.0f, 0.0f,
};
glGenBuffers(1, &mVertexWithColorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesWithColor), &verticesWithColor[0], GL_STATIC_DRAW);
// Construct a vertex buffer of position values only
const GLfloat vertices[] = const GLfloat vertices[] =
{ {
getIndexPositionX(0), getIndexPositionY(0), getIndexPositionX(0), getIndexPositionY(0),
getIndexPositionX(1), getIndexPositionY(1),
getIndexPositionX(2), getIndexPositionY(2), getIndexPositionX(2), getIndexPositionY(2),
getIndexPositionX(1), getIndexPositionY(1),
getIndexPositionX(3), getIndexPositionY(3), getIndexPositionX(3), getIndexPositionY(3),
}; };
glGenBuffers(1, &mVertexBuffer); glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);
const IndexType indices[] = { 0, 1, 2, 3 }; // The indices buffer is shared between both variations of tests
const IndexType indices[] = { 0, 2, 1, 3 };
glGenBuffers(1, &mIndexBuffer); glGenBuffers(1, &mIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);
...@@ -84,12 +125,16 @@ class IndexedPointsTest : public ANGLETest ...@@ -84,12 +125,16 @@ class IndexedPointsTest : public ANGLETest
virtual void TearDown() virtual void TearDown()
{ {
glDeleteBuffers(1, &mVertexBuffer);
glDeleteBuffers(1, &mIndexBuffer);
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
glDeleteBuffers(1, &mVertexWithColorBuffer);
glDeleteProgram(mVertexWithColorBufferProgram);
ANGLETest::TearDown(); ANGLETest::TearDown();
} }
void runTest(GLuint firstIndex) void runTest(GLuint firstIndex, bool useVertexBufferWithColor = false)
{ {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
...@@ -97,14 +142,30 @@ class IndexedPointsTest : public ANGLETest ...@@ -97,14 +142,30 @@ class IndexedPointsTest : public ANGLETest
GLint viewportSize[4]; GLint viewportSize[4];
glGetIntegerv(GL_VIEWPORT, viewportSize); glGetIntegerv(GL_VIEWPORT, viewportSize);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); // Choose appropriate program to apply for the test
GLint vertexLocation = glGetAttribLocation(mProgram, "position"); GLuint program = useVertexBufferWithColor ? mVertexWithColorBufferProgram : mProgram;
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertexLocation);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); if (useVertexBufferWithColor)
{
glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer);
GLint vertexLocation = glGetAttribLocation(program, "position");
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, VertexWithColorSize, 0);
glEnableVertexAttribArray(vertexLocation);
GLint vertexColorLocation = glGetAttribLocation(program, "color");
glVertexAttribPointer(vertexColorLocation, 3, GL_FLOAT, GL_FALSE, VertexWithColorSize, (GLvoid*)((sizeof(float) * 2)));
glEnableVertexAttribArray(vertexColorLocation);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
GLint vertexLocation = glGetAttribLocation(program, "position");
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertexLocation);
}
glUseProgram(mProgram); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glUseProgram(program);
glDrawElements(GL_POINTS, mPointCount - firstIndex, IndexTypeName, reinterpret_cast<void*>(firstIndex * sizeof(IndexType))); glDrawElements(GL_POINTS, mPointCount - firstIndex, IndexTypeName, reinterpret_cast<void*>(firstIndex * sizeof(IndexType)));
...@@ -119,15 +180,32 @@ class IndexedPointsTest : public ANGLETest ...@@ -119,15 +180,32 @@ class IndexedPointsTest : public ANGLETest
} }
else else
{ {
EXPECT_PIXEL_EQ(x, y, 255, 0, 0, 255); if (useVertexBufferWithColor)
{
// Pixel data is assumed to be GREEN
EXPECT_PIXEL_EQ(x, y, 0, 255, 0, 255);
}
else
{
// Pixel data is assumed to be RED
EXPECT_PIXEL_EQ(x, y, 255, 0, 0, 255);
}
} }
} }
swapBuffers();
} }
GLuint mProgram; GLuint mProgram;
GLuint mVertexBuffer; GLuint mVertexBuffer;
GLuint mIndexBuffer; GLuint mIndexBuffer;
GLuint mVertexWithColorBufferProgram;
GLuint mVertexWithColorBuffer;
static const GLuint mPointCount = 4; static const GLuint mPointCount = 4;
private:
const size_t VertexWithColorSize = sizeof(float) * 5;
}; };
typedef IndexedPointsTest<GLubyte, GL_UNSIGNED_BYTE> IndexedPointsTestUByte; typedef IndexedPointsTest<GLubyte, GL_UNSIGNED_BYTE> IndexedPointsTestUByte;
...@@ -152,6 +230,26 @@ TEST_P(IndexedPointsTestUByte, UnsignedByteOffset3) ...@@ -152,6 +230,26 @@ TEST_P(IndexedPointsTestUByte, UnsignedByteOffset3)
runTest(3); runTest(3);
} }
TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset0)
{
runTest(0, true);
}
TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset1)
{
runTest(1, true);
}
TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset2)
{
runTest(2, true);
}
TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset3)
{
runTest(3, true);
}
typedef IndexedPointsTest<GLushort, GL_UNSIGNED_SHORT> IndexedPointsTestUShort; typedef IndexedPointsTest<GLushort, GL_UNSIGNED_SHORT> IndexedPointsTestUShort;
TEST_P(IndexedPointsTestUShort, UnsignedShortOffset0) TEST_P(IndexedPointsTestUShort, UnsignedShortOffset0)
...@@ -174,6 +272,34 @@ TEST_P(IndexedPointsTestUShort, UnsignedShortOffset3) ...@@ -174,6 +272,34 @@ TEST_P(IndexedPointsTestUShort, UnsignedShortOffset3)
runTest(3); runTest(3);
} }
TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset0)
{
runTest(0, true);
}
TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset1)
{
runTest(1, true);
}
TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset2)
{
runTest(2, true);
}
TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset3)
{
runTest(3, true);
}
TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffsetChangingIndices)
{
runTest(3, true);
runTest(1, true);
runTest(0, true);
runTest(2, true);
}
typedef IndexedPointsTest<GLuint, GL_UNSIGNED_INT> IndexedPointsTestUInt; typedef IndexedPointsTest<GLuint, GL_UNSIGNED_INT> IndexedPointsTestUInt;
TEST_P(IndexedPointsTestUInt, UnsignedIntOffset0) TEST_P(IndexedPointsTestUInt, UnsignedIntOffset0)
...@@ -216,7 +342,47 @@ TEST_P(IndexedPointsTestUInt, UnsignedIntOffset3) ...@@ -216,7 +342,47 @@ TEST_P(IndexedPointsTestUInt, UnsignedIntOffset3)
runTest(3); runTest(3);
} }
TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset0)
{
if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
{
return;
}
runTest(0, false);
}
TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset1)
{
if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
{
return;
}
runTest(1, false);
}
TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset2)
{
if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
{
return;
}
runTest(2, false);
}
TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset3)
{
if (getClientVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
{
return;
}
runTest(3, false);
}
// TODO(geofflang): Figure out why this test fails on Intel OpenGL // TODO(geofflang): Figure out why this test fails on Intel OpenGL
ANGLE_INSTANTIATE_TEST(IndexedPointsTestUByte, ES2_D3D11()); ANGLE_INSTANTIATE_TEST(IndexedPointsTestUByte, ES2_D3D11(), ES2_D3D11_FL9_3());
ANGLE_INSTANTIATE_TEST(IndexedPointsTestUShort, ES2_D3D11()); ANGLE_INSTANTIATE_TEST(IndexedPointsTestUShort, ES2_D3D11(), ES2_D3D11_FL9_3());
ANGLE_INSTANTIATE_TEST(IndexedPointsTestUInt, ES2_D3D11()); ANGLE_INSTANTIATE_TEST(IndexedPointsTestUInt, ES2_D3D11(), ES2_D3D11_FL9_3());
...@@ -154,10 +154,11 @@ IndexDataManagerPerfTest::IndexDataManagerPerfTest() ...@@ -154,10 +154,11 @@ IndexDataManagerPerfTest::IndexDataManagerPerfTest()
void IndexDataManagerPerfTest::step(float dt, double totalTime) void IndexDataManagerPerfTest::step(float dt, double totalTime)
{ {
rx::TranslatedIndexData translatedIndexData; rx::TranslatedIndexData translatedIndexData;
rx::SourceIndexData sourceIndexData;
for (unsigned int iteration = 0; iteration < 100; ++iteration) for (unsigned int iteration = 0; iteration < 100; ++iteration)
{ {
mIndexBuffer.getIndexRange(GL_UNSIGNED_SHORT, 0, mIndexCount, &translatedIndexData.indexRange); mIndexBuffer.getIndexRange(GL_UNSIGNED_SHORT, 0, mIndexCount, &translatedIndexData.indexRange);
mIndexDataManager.prepareIndexData(GL_UNSIGNED_SHORT, mIndexCount, &mIndexBuffer, nullptr, &translatedIndexData); mIndexDataManager.prepareIndexData(GL_UNSIGNED_SHORT, mIndexCount, &mIndexBuffer, nullptr, &translatedIndexData, &sourceIndexData);
} }
if (mTimer->getElapsedTime() >= 5.0) if (mTimer->getElapsedTime() >= 5.0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment