Move the index data manager and draw calls into the renderer implementation.
TRAC #22016
Signed-off-by: Daniel Koch
Signed-off-by: Geoff Lang
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1492 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 13fab27..2450cf5 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -27,8 +27,6 @@
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h"
-#include "libGLESv2/VertexDataManager.h"
-#include "libGLESv2/IndexDataManager.h"
#undef near
#undef far
@@ -153,9 +151,6 @@
mState.unpackAlignment = 4;
mState.packReverseRowOrder = false;
- mIndexDataManager = NULL;
- mLineLoopIB = NULL;
-
mInvalidEnum = false;
mInvalidValue = false;
mInvalidOperation = false;
@@ -236,9 +231,6 @@
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
- delete mIndexDataManager;
- delete mLineLoopIB;
-
if (mMaskedClearSavedState)
{
mMaskedClearSavedState->Release();
@@ -253,8 +245,6 @@
if (!mHasBeenCurrent)
{
- mIndexDataManager = new IndexDataManager(mRenderer);
-
mSupportsShaderModel3 = mRenderer->getShaderModel3Support();
mMaximumPointSize = mRenderer->getMaxPointSize();
mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
@@ -340,7 +330,6 @@
}
mAppliedProgramBinarySerial = 0;
- mAppliedIBSerial = 0;
mDxUniformsDirty = true;
}
@@ -1845,23 +1834,6 @@
mState.rasterizer.frontFace == GL_CCW, stencilSize);
}
-// Applies the indices and element array bindings to the Direct3D 9 device
-GLenum Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
-{
- GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
-
- if (err == GL_NO_ERROR)
- {
- if (indexInfo->serial != mAppliedIBSerial)
- {
- mDevice->SetIndices(indexInfo->indexBuffer);
- mAppliedIBSerial = indexInfo->serial;
- }
- }
-
- return err;
-}
-
// Applies the shaders and shader constants to the Direct3D 9 device
void Context::applyShaders()
{
@@ -2065,13 +2037,7 @@
return error(GL_INVALID_OPERATION);
}
- D3DPRIMITIVETYPE primitiveType;
- int primitiveCount;
-
- if(!gl_d3d9::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
- return error(GL_INVALID_ENUM);
-
- if (primitiveCount <= 0)
+ if (!mRenderer->applyPrimitiveType(mode, count))
{
return;
}
@@ -2085,8 +2051,7 @@
ProgramBinary *programBinary = getCurrentProgramBinary();
- GLsizei repeatDraw = 1;
- GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances, &repeatDraw);
+ GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
if (err != GL_NO_ERROR)
{
return error(err);
@@ -2102,38 +2067,7 @@
if (!skipDraw(mode))
{
- mRenderer->startScene();
-
- if (mode == GL_LINE_LOOP)
- {
- drawLineLoop(count, GL_NONE, NULL, 0);
- }
- else if (instances > 0)
- {
- StaticIndexBuffer *countingIB = mIndexDataManager->getCountingIndices(count);
- if (countingIB)
- {
- if (mAppliedIBSerial != countingIB->getSerial())
- {
- mDevice->SetIndices(countingIB->getBuffer());
- mAppliedIBSerial = countingIB->getSerial();
- }
-
- for (int i = 0; i < repeatDraw; i++)
- {
- mDevice->DrawIndexedPrimitive(primitiveType, 0, 0, count, 0, primitiveCount);
- }
- }
- else
- {
- ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
- return error(GL_OUT_OF_MEMORY);
- }
- }
- else // Regular case
- {
- mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
- }
+ mRenderer->drawArrays(mode, count, instances);
}
}
@@ -2148,14 +2082,8 @@
{
return error(GL_INVALID_OPERATION);
}
-
- D3DPRIMITIVETYPE primitiveType;
- int primitiveCount;
-
- if(!gl_d3d9::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
- return error(GL_INVALID_ENUM);
-
- if (primitiveCount <= 0)
+
+ if (!mRenderer->applyPrimitiveType(mode, count))
{
return;
}
@@ -2168,7 +2096,7 @@
applyState(mode);
TranslatedIndexData indexInfo;
- GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
+ GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
if (err != GL_NO_ERROR)
{
return error(err);
@@ -2177,8 +2105,7 @@
ProgramBinary *programBinary = getCurrentProgramBinary();
GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
- GLsizei repeatDraw = 1;
- err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances, &repeatDraw);
+ err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
if (err != GL_NO_ERROR)
{
return error(err);
@@ -2194,19 +2121,7 @@
if (!skipDraw(mode))
{
- mRenderer->startScene();
-
- if (mode == GL_LINE_LOOP)
- {
- drawLineLoop(count, type, indices, indexInfo.minIndex);
- }
- else
- {
- for (int i = 0; i < repeatDraw; i++)
- {
- mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
- }
- }
+ mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get());
}
}
@@ -2216,151 +2131,6 @@
mRenderer->sync(block);
}
-void Context::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex)
-{
- // Get the raw indices for an indexed draw
- if (type != GL_NONE && mState.elementArrayBuffer.get())
- {
- Buffer *indexBuffer = mState.elementArrayBuffer.get();
- intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset;
- }
-
- UINT startIndex = 0;
- bool succeeded = false;
-
- if (supports32bitIndices())
- {
- const int spaceNeeded = (count + 1) * sizeof(unsigned int);
-
- if (!mLineLoopIB)
- {
- mLineLoopIB = new StreamingIndexBuffer(mRenderer, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
- }
-
- if (mLineLoopIB)
- {
- mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
-
- UINT offset = 0;
- unsigned int *data = static_cast<unsigned int*>(mLineLoopIB->map(spaceNeeded, &offset));
- startIndex = offset / 4;
-
- if (data)
- {
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
- mLineLoopIB->unmap();
- succeeded = true;
- }
- }
- }
- else
- {
- const int spaceNeeded = (count + 1) * sizeof(unsigned short);
-
- if (!mLineLoopIB)
- {
- mLineLoopIB = new StreamingIndexBuffer(mRenderer, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
- }
-
- if (mLineLoopIB)
- {
- mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
- UINT offset = 0;
- unsigned short *data = static_cast<unsigned short*>(mLineLoopIB->map(spaceNeeded, &offset));
- startIndex = offset / 2;
-
- if (data)
- {
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
- mLineLoopIB->unmap();
- succeeded = true;
- }
- }
- }
-
- if (succeeded)
- {
- if (mAppliedIBSerial != mLineLoopIB->getSerial())
- {
- mDevice->SetIndices(mLineLoopIB->getBuffer());
- mAppliedIBSerial = mLineLoopIB->getSerial();
- }
-
- mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
- }
- else
- {
- ERR("Could not create a looping index buffer for GL_LINE_LOOP.");
- return error(GL_OUT_OF_MEMORY);
- }
-}
-
void Context::recordInvalidEnum()
{
mInvalidEnum = true;
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 69169e4..79be9e7 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -41,10 +41,6 @@
namespace gl
{
-struct TranslatedAttribute;
-struct TranslatedIndexData;
-
-class Buffer;
class Shader;
class Program;
class ProgramBinary;
@@ -56,10 +52,8 @@
class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
-class StreamingIndexBuffer;
class Stencilbuffer;
class DepthStencilbuffer;
-class IndexDataManager;
class Fence;
class Query;
@@ -376,8 +370,6 @@
void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances);
void sync(bool block); // flush/finish
- void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex);
-
void recordInvalidEnum();
void recordInvalidValue();
void recordInvalidOperation();
@@ -433,7 +425,6 @@
bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode);
- GLenum applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void applyTextures(SamplerType type);
@@ -481,10 +472,6 @@
std::string mExtensionString;
std::string mRendererString;
-
- IndexDataManager *mIndexDataManager;
-
- StreamingIndexBuffer *mLineLoopIB;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
@@ -505,7 +492,6 @@
unsigned int mAppliedTextureSerialPS[MAX_TEXTURE_IMAGE_UNITS];
unsigned int mAppliedTextureSerialVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
unsigned int mAppliedProgramBinarySerial;
- unsigned int mAppliedIBSerial;
rx::RenderTarget::Desc mRenderTargetDesc; // D3D9_REPLACE
bool mDxUniformsDirty;
BindingPointer<ProgramBinary> mCurrentProgramBinary;
diff --git a/src/libGLESv2/IndexDataManager.cpp b/src/libGLESv2/IndexDataManager.cpp
index fc8c20b..c290d07 100644
--- a/src/libGLESv2/IndexDataManager.cpp
+++ b/src/libGLESv2/IndexDataManager.cpp
@@ -107,7 +107,7 @@
else UNREACHABLE();
}
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated, IDirect3DIndexBuffer9 **d3dIndexBuffer, unsigned int *serial)
{
if (!mStreamingBufferShort)
{
@@ -198,8 +198,8 @@
}
}
- translated->indexBuffer = indexBuffer->getBuffer();
- translated->serial = indexBuffer->getSerial();
+ *d3dIndexBuffer = indexBuffer->getBuffer();
+ *serial = indexBuffer->getSerial();
translated->startIndex = streamOffset / indexSize(format);
if (buffer)
diff --git a/src/libGLESv2/IndexDataManager.h b/src/libGLESv2/IndexDataManager.h
index ba021c5..5f9f7a9 100644
--- a/src/libGLESv2/IndexDataManager.h
+++ b/src/libGLESv2/IndexDataManager.h
@@ -31,9 +31,6 @@
UINT minIndex;
UINT maxIndex;
UINT startIndex;
-
- IDirect3DIndexBuffer9 *indexBuffer;
- unsigned int serial;
};
class IndexBuffer
@@ -128,7 +125,7 @@
IndexDataManager(rx::Renderer9 *renderer);
virtual ~IndexDataManager();
- GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
+ GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated, IDirect3DIndexBuffer9 **indexBuffer, unsigned int *serial);
StaticIndexBuffer *getCountingIndices(GLsizei count);
private:
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 60d579c..adf6b9f 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -41,6 +41,8 @@
{
class ProgramBinary;
class VertexAttribute;
+class Buffer;
+struct TranslatedIndexData;
}
namespace rx
@@ -69,9 +71,6 @@
virtual int generateConfigs(ConfigDesc **configDescList) = 0;
virtual void deleteConfigs(ConfigDesc *configDescList) = 0;
- virtual void startScene() = 0;
- virtual void endScene() = 0;
-
virtual void sync(bool block) = 0;
virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
@@ -93,8 +92,12 @@
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, gl::TranslatedIndexData *indexInfo) = 0;
- virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw) = 0;
+ virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0;
+ virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer) = 0;
virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index ab4047d..7bd4022 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -230,16 +230,6 @@
delete [] (configDescList);
}
-void Renderer11::startScene()
-{
- // TODO: nop in d3d11?
-}
-
-void Renderer11::endScene()
-{
- // TODO: nop in d3d11?
-}
-
void Renderer11::sync(bool block)
{
// TODO
@@ -436,7 +426,15 @@
return true;
}
-bool Renderer11::applyRenderTarget(gl::Framebuffer *frameBuffer)
+bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
+{
+ // TODO
+ UNIMPLEMENTED();
+
+ return false;
+}
+
+bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
{
// TODO
UNIMPLEMENTED();
@@ -447,7 +445,7 @@
return true;
}
-GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw)
+GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
{
// TODO
UNIMPLEMENTED();
@@ -455,6 +453,26 @@
return GL_OUT_OF_MEMORY;
}
+GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, gl::TranslatedIndexData *indexInfo)
+{
+ // TODO
+ UNIMPLEMENTED();
+
+ return GL_OUT_OF_MEMORY;
+}
+
+void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
+{
+ // TODO
+ UNIMPLEMENTED();
+}
+
+void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer)
+{
+ // TODO
+ UNIMPLEMENTED();
+}
+
void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
{
// TODO
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 5e6c730..192282f 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -41,9 +41,6 @@
virtual int generateConfigs(ConfigDesc **configDescList);
virtual void deleteConfigs(ConfigDesc *configDescList);
- virtual void startScene();
- virtual void endScene();
-
virtual void sync(bool block);
virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
@@ -63,10 +60,14 @@
unsigned int renderTargetWidth, unsigned int renderTargetHeight,
gl::ProgramBinary *currentProgram, bool forceSetUniforms);
+ virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary);
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+ virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, gl::TranslatedIndexData *indexInfo);
- virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw);
+ virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
+ virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer);
virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 7469c04..05ecb55 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -10,9 +10,11 @@
#include "libGLESv2/main.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/mathutil.h"
+#include "libGLESv2/Buffer.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/IndexDataManager.h"
#include "libGLESv2/VertexDataManager.h"
#include "libGLESv2/renderer/Renderer9.h"
#include "libGLESv2/renderer/renderer9_utils.h"
@@ -87,9 +89,13 @@
mMaxSupportedSamples = 0;
- mVertexDataManager = NULL;
+ mAppliedIBSerial = 0;
mMaskedClearSavedState = NULL;
+
+ mVertexDataManager = NULL;
+ mIndexDataManager = NULL;
+ mLineLoopIB = NULL;
}
Renderer9::~Renderer9()
@@ -398,9 +404,10 @@
mSceneStarted = false;
- ASSERT(!mBlit && !mVertexDataManager);
+ ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager);
mBlit = new Blit(this);
mVertexDataManager = new gl::VertexDataManager(this);
+ mIndexDataManager = new gl::IndexDataManager(this);
}
D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
@@ -975,6 +982,45 @@
return true;
}
+bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
+{
+ switch (mode)
+ {
+ case GL_POINTS:
+ mPrimitiveType = D3DPT_POINTLIST;
+ mPrimitiveCount = count;
+ break;
+ case GL_LINES:
+ mPrimitiveType = D3DPT_LINELIST;
+ mPrimitiveCount = count / 2;
+ break;
+ case GL_LINE_LOOP:
+ mPrimitiveType = D3DPT_LINESTRIP;
+ mPrimitiveCount = count - 1; // D3D doesn't support line loops, so we draw the last line separately
+ break;
+ case GL_LINE_STRIP:
+ mPrimitiveType = D3DPT_LINESTRIP;
+ mPrimitiveCount = count - 1;
+ break;
+ case GL_TRIANGLES:
+ mPrimitiveType = D3DPT_TRIANGLELIST;
+ mPrimitiveCount = count / 3;
+ break;
+ case GL_TRIANGLE_STRIP:
+ mPrimitiveType = D3DPT_TRIANGLESTRIP;
+ mPrimitiveCount = count - 2;
+ break;
+ case GL_TRIANGLE_FAN:
+ mPrimitiveType = D3DPT_TRIANGLEFAN;
+ mPrimitiveCount = count - 2;
+ break;
+ default:
+ return error(GL_INVALID_ENUM, false);
+ }
+
+ return mPrimitiveCount > 0;
+}
+
bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
{
// if there is no color attachment we must synthesize a NULL colorattachment
@@ -1094,7 +1140,7 @@
return true;
}
-GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw)
+GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
{
gl::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
@@ -1103,7 +1149,229 @@
return err;
}
- return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, repeatDraw);
+ return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw);
+}
+
+// Applies the indices and element array bindings to the Direct3D 9 device
+GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, gl::TranslatedIndexData *indexInfo)
+{
+ IDirect3DIndexBuffer9 *indexBuffer;
+ unsigned int serial;
+ GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo, &indexBuffer, &serial);
+
+ mIndexInfo.minIndex = indexInfo->minIndex;
+ mIndexInfo.maxIndex = indexInfo->maxIndex;
+ mIndexInfo.startIndex = indexInfo->startIndex;
+
+ if (err == GL_NO_ERROR)
+ {
+ if (serial != mAppliedIBSerial)
+ {
+ mDevice->SetIndices(indexBuffer);
+ mAppliedIBSerial = serial;
+ }
+ }
+
+ return err;
+}
+
+void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
+{
+ startScene();
+
+ if (mode == GL_LINE_LOOP)
+ {
+ drawLineLoop(count, GL_NONE, NULL, 0, NULL);
+ }
+ else if (instances > 0)
+ {
+ gl::StaticIndexBuffer *countingIB = mIndexDataManager->getCountingIndices(count);
+ if (countingIB)
+ {
+ if (mAppliedIBSerial != countingIB->getSerial())
+ {
+ mDevice->SetIndices(countingIB->getBuffer());
+ mAppliedIBSerial = countingIB->getSerial();
+ }
+
+ for (int i = 0; i < mRepeatDraw; i++)
+ {
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount);
+ }
+ }
+ else
+ {
+ ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+ }
+ else // Regular case
+ {
+ mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount);
+ }
+}
+
+void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer)
+{
+ startScene();
+
+ if (mode == GL_LINE_LOOP)
+ {
+ drawLineLoop(count, type, indices, mIndexInfo.minIndex, elementArrayBuffer);
+ }
+ else
+ {
+ for (int i = 0; i < mRepeatDraw; i++)
+ {
+ GLsizei vertexCount = mIndexInfo.maxIndex - mIndexInfo.minIndex + 1;
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)mIndexInfo.minIndex, mIndexInfo.minIndex, vertexCount, mIndexInfo.startIndex, mPrimitiveCount);
+ }
+ }
+}
+
+void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+{
+ // Get the raw indices for an indexed draw
+ if (type != GL_NONE && elementArrayBuffer)
+ {
+ gl::Buffer *indexBuffer = elementArrayBuffer;
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset;
+ }
+
+ UINT startIndex = 0;
+ bool succeeded = false;
+
+ if (get32BitIndexSupport())
+ {
+ const int spaceNeeded = (count + 1) * sizeof(unsigned int);
+
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new gl::StreamingIndexBuffer(this, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
+ }
+
+ if (mLineLoopIB)
+ {
+ mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
+
+ UINT offset = 0;
+ unsigned int *data = static_cast<unsigned int*>(mLineLoopIB->map(spaceNeeded, &offset));
+ startIndex = offset / 4;
+
+ if (data)
+ {
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+
+ mLineLoopIB->unmap();
+ succeeded = true;
+ }
+ }
+ }
+ else
+ {
+ const int spaceNeeded = (count + 1) * sizeof(unsigned short);
+
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new gl::StreamingIndexBuffer(this, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
+ }
+
+ if (mLineLoopIB)
+ {
+ mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+
+ UINT offset = 0;
+ unsigned short *data = static_cast<unsigned short*>(mLineLoopIB->map(spaceNeeded, &offset));
+ startIndex = offset / 2;
+
+ if (data)
+ {
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+
+ mLineLoopIB->unmap();
+ succeeded = true;
+ }
+ }
+ }
+
+ if (succeeded)
+ {
+ if (mAppliedIBSerial != mLineLoopIB->getSerial())
+ {
+ mDevice->SetIndices(mLineLoopIB->getBuffer());
+ mAppliedIBSerial = mLineLoopIB->getSerial();
+ }
+
+ mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
+ }
+ else
+ {
+ ERR("Could not create a looping index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
+ }
}
void Renderer9::applyShaders(gl::ProgramBinary *programBinary)
@@ -1339,6 +1607,12 @@
delete mVertexDataManager;
mVertexDataManager = NULL;
+
+ delete mIndexDataManager;
+ mIndexDataManager = NULL;
+
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
}
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index abecc13..3bf38ab 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -23,13 +23,17 @@
#include <D3Dcompiler.h>
#include "common/angleutils.h"
+#include "libGLESv2/Context.h"
#include "libGLESv2/renderer/ShaderCache.h"
#include "libGLESv2/renderer/VertexDeclarationCache.h"
#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/IndexDataManager.h"
namespace gl
{
class VertexDataManager;
+class StreamingIndexBuffer;
+struct TranslatedAttribute;
}
namespace rx
@@ -49,8 +53,8 @@
virtual int generateConfigs(ConfigDesc **configDescList);
virtual void deleteConfigs(ConfigDesc *configDescList);
- virtual void startScene();
- virtual void endScene();
+ void startScene();
+ void endScene();
virtual void sync(bool block);
@@ -93,8 +97,12 @@
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary);
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+ virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, gl::TranslatedIndexData *indexInfo);
- virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw);
+ virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
+ virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer);
virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
@@ -166,6 +174,8 @@
private:
DISALLOW_COPY_AND_ASSIGN(Renderer9);
+ void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+
void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
@@ -209,6 +219,11 @@
D3DCAPS9 mDeviceCaps;
D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
+ D3DPRIMITIVETYPE mPrimitiveType;
+ int mPrimitiveCount;
+ GLsizei mRepeatDraw;
+ gl::TranslatedIndexData mIndexInfo;
+
bool mSceneStarted;
bool mSupportsNonPower2Textures;
bool mSupportsTextureFilterAnisotropy;
@@ -255,6 +270,8 @@
gl::Color mCurBlendColor;
GLuint mCurSampleMask;
+ unsigned int mAppliedIBSerial;
+
// A pool of event queries that are currently unused.
std::vector<IDirect3DQuery9*> mEventQueryPool;
VertexShaderCache mVertexShaderCache;
@@ -262,6 +279,9 @@
gl::VertexDataManager *mVertexDataManager;
VertexDeclarationCache mVertexDeclarationCache;
+
+ gl::IndexDataManager *mIndexDataManager;
+ gl::StreamingIndexBuffer *mLineLoopIB;
};
}
diff --git a/src/libGLESv2/renderer/VertexDeclarationCache.h b/src/libGLESv2/renderer/VertexDeclarationCache.h
index 2b87277..2364e10 100644
--- a/src/libGLESv2/renderer/VertexDeclarationCache.h
+++ b/src/libGLESv2/renderer/VertexDeclarationCache.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
#include "libGLESv2/Context.h"
+#include "libGLESv2/VertexDataManager.h"
namespace gl
{
diff --git a/src/libGLESv2/renderer/renderer9_utils.cpp b/src/libGLESv2/renderer/renderer9_utils.cpp
index c11f5c6..fa63904 100644
--- a/src/libGLESv2/renderer/renderer9_utils.cpp
+++ b/src/libGLESv2/renderer/renderer9_utils.cpp
@@ -236,46 +236,6 @@
}
}
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
- D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
-{
- switch (primitiveType)
- {
- case GL_POINTS:
- *d3dPrimitiveType = D3DPT_POINTLIST;
- *d3dPrimitiveCount = elementCount;
- break;
- case GL_LINES:
- *d3dPrimitiveType = D3DPT_LINELIST;
- *d3dPrimitiveCount = elementCount / 2;
- break;
- case GL_LINE_LOOP:
- *d3dPrimitiveType = D3DPT_LINESTRIP;
- *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
- break;
- case GL_LINE_STRIP:
- *d3dPrimitiveType = D3DPT_LINESTRIP;
- *d3dPrimitiveCount = elementCount - 1;
- break;
- case GL_TRIANGLES:
- *d3dPrimitiveType = D3DPT_TRIANGLELIST;
- *d3dPrimitiveCount = elementCount / 3;
- break;
- case GL_TRIANGLE_STRIP:
- *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
- *d3dPrimitiveCount = elementCount - 2;
- break;
- case GL_TRIANGLE_FAN:
- *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
- *d3dPrimitiveCount = elementCount - 2;
- break;
- default:
- return false;
- }
-
- return true;
-}
-
D3DFORMAT ConvertRenderbufferFormat(GLenum format)
{
switch (format)
diff --git a/src/libGLESv2/renderer/renderer9_utils.h b/src/libGLESv2/renderer/renderer9_utils.h
index 957ae63..9436945 100644
--- a/src/libGLESv2/renderer/renderer9_utils.h
+++ b/src/libGLESv2/renderer/renderer9_utils.h
@@ -35,8 +35,6 @@
DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
- D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);