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
parent 41cb9428
......@@ -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 @@ Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool n
mState.unpackAlignment = 4;
mState.packReverseRowOrder = false;
mIndexDataManager = NULL;
mLineLoopIB = NULL;
mInvalidEnum = false;
mInvalidValue = false;
mInvalidOperation = false;
......@@ -236,9 +231,6 @@ Context::~Context()
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
delete mIndexDataManager;
delete mLineLoopIB;
if (mMaskedClearSavedState)
{
mMaskedClearSavedState->Release();
......@@ -253,8 +245,6 @@ void Context::makeCurrent(egl::Surface *surface)
if (!mHasBeenCurrent)
{
mIndexDataManager = new IndexDataManager(mRenderer);
mSupportsShaderModel3 = mRenderer->getShaderModel3Support();
mMaximumPointSize = mRenderer->getMaxPointSize();
mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
......@@ -340,7 +330,6 @@ void Context::markAllStateDirty()
}
mAppliedProgramBinarySerial = 0;
mAppliedIBSerial = 0;
mDxUniformsDirty = true;
}
......@@ -1845,23 +1834,6 @@ void Context::applyState(GLenum drawMode)
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 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
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 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
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 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
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 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
{
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 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
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 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
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 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
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 @@ void Context::sync(bool block)
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;
......
......@@ -41,10 +41,6 @@ class Surface;
namespace gl
{
struct TranslatedAttribute;
struct TranslatedIndexData;
class Buffer;
class Shader;
class Program;
class ProgramBinary;
......@@ -56,10 +52,8 @@ class Renderbuffer;
class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
class StreamingIndexBuffer;
class Stencilbuffer;
class DepthStencilbuffer;
class IndexDataManager;
class Fence;
class Query;
......@@ -376,8 +370,6 @@ class Context
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 @@ class Context
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 @@ class Context
std::string mExtensionString;
std::string mRendererString;
IndexDataManager *mIndexDataManager;
StreamingIndexBuffer *mLineLoopIB;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
......@@ -505,7 +492,6 @@ class Context
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;
......
......@@ -107,7 +107,7 @@ void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *min
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 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *bu
}
}
translated->indexBuffer = indexBuffer->getBuffer();
translated->serial = indexBuffer->getSerial();
*d3dIndexBuffer = indexBuffer->getBuffer();
*serial = indexBuffer->getSerial();
translated->startIndex = streamOffset / indexSize(format);
if (buffer)
......
......@@ -31,9 +31,6 @@ struct TranslatedIndexData
UINT minIndex;
UINT maxIndex;
UINT startIndex;
IDirect3DIndexBuffer9 *indexBuffer;
unsigned int serial;
};
class IndexBuffer
......@@ -128,7 +125,7 @@ class IndexDataManager
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:
......
......@@ -41,6 +41,8 @@ namespace gl
{
class ProgramBinary;
class VertexAttribute;
class Buffer;
struct TranslatedIndexData;
}
namespace rx
......@@ -69,9 +71,6 @@ class Renderer
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 @@ class Renderer
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;
......
......@@ -230,16 +230,6 @@ void Renderer11::deleteConfigs(ConfigDesc *configDescList)
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 @@ bool Renderer11::setViewport(const gl::Rectangle& viewport, float zNear, float z
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,15 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *frameBuffer)
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();
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();
......@@ -455,6 +461,18 @@ GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::Verte
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
......
......@@ -41,9 +41,6 @@ class Renderer11 : public Renderer
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 @@ class Renderer11 : public Renderer
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);
......
......@@ -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 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Rend
mMaxSupportedSamples = 0;
mVertexDataManager = NULL;
mAppliedIBSerial = 0;
mMaskedClearSavedState = NULL;
mVertexDataManager = NULL;
mIndexDataManager = NULL;
mLineLoopIB = NULL;
}
Renderer9::~Renderer9()
......@@ -398,9 +404,10 @@ void Renderer9::initializeDevice()
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 @@ bool Renderer9::setViewport(const gl::Rectangle& viewport, float zNear, float zF
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 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
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 @@ GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::Vertex
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 @@ void Renderer9::releaseDeviceResources()
delete mVertexDataManager;
mVertexDataManager = NULL;
delete mIndexDataManager;
mIndexDataManager = NULL;
delete mLineLoopIB;
mLineLoopIB = NULL;
}
......
......@@ -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 @@ class Renderer9 : public Renderer
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 @@ class Renderer9 : public Renderer
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 @@ class Renderer9 : public Renderer
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 @@ class Renderer9 : public Renderer
D3DCAPS9 mDeviceCaps;
D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
D3DPRIMITIVETYPE mPrimitiveType;
int mPrimitiveCount;
GLsizei mRepeatDraw;
gl::TranslatedIndexData mIndexInfo;
bool mSceneStarted;
bool mSupportsNonPower2Textures;
bool mSupportsTextureFilterAnisotropy;
......@@ -255,6 +270,8 @@ class Renderer9 : public Renderer
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 @@ class Renderer9 : public Renderer
gl::VertexDataManager *mVertexDataManager;
VertexDeclarationCache mVertexDeclarationCache;
gl::IndexDataManager *mIndexDataManager;
gl::StreamingIndexBuffer *mLineLoopIB;
};
}
......
......@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
#include "libGLESv2/Context.h"
#include "libGLESv2/VertexDataManager.h"
namespace gl
{
......
......@@ -236,46 +236,6 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT
}
}
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)
......
......@@ -35,8 +35,6 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
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);
......
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