Commit 53fae3e9 by Nicolas Capens Committed by Nicolas Capens

Eliminate GL buffers.

Bug 18591036 Change-Id: Ieb77935e0afd41c78dff2bb892185bc2d31505b8 Reviewed-on: https://swiftshader-review.googlesource.com/1540Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent ae17152b
......@@ -15,7 +15,7 @@
namespace sw
{
Resource::Resource(int bytes)
Resource::Resource(size_t bytes) : size(bytes)
{
blocked = 0;
......@@ -171,7 +171,7 @@ namespace sw
criticalSection.unlock();
}
const void *Resource::getBuffer() const
const void *Resource::data() const
{
return buffer;
}
......
......@@ -27,7 +27,7 @@ namespace sw
class Resource
{
public:
Resource(int bytes);
Resource(size_t bytes);
void destruct(); // Asynchronous destructor
......@@ -36,7 +36,8 @@ namespace sw
void unlock();
void unlock(Accessor relinquisher);
const void *getBuffer() const; // FIXME
const void *data() const;
const size_t size;
private:
~Resource(); // Always call destruct() instead
......
......@@ -60,7 +60,7 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
if(data)
{
memcpy((void*)mContents->getBuffer(), data, size);
memcpy((void*)mContents->data(), data, size);
}
}
}
......
......@@ -37,7 +37,7 @@ class Buffer : public RefCountObject
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
const void *data() { return mContents ? mContents->getBuffer() : 0; }
const void *data() { return mContents ? mContents->data() : 0; }
size_t size() const { return mSize; }
GLenum usage() const { return mUsage; }
......
......@@ -1671,7 +1671,7 @@ GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
sw::Resource *resource = attributes[i].vertexBuffer;
const void *buffer = (char*)resource->getBuffer() + attributes[i].offset;
const void *buffer = (char*)resource->data() + attributes[i].offset;
int stride = attributes[i].stride;
......
......@@ -60,7 +60,7 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
if(data)
{
memcpy((void*)mContents->getBuffer(), data, size);
memcpy((void*)mContents->data(), data, size);
}
}
}
......
......@@ -37,7 +37,7 @@ class Buffer : public RefCountObject
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
const void *data() { return mContents ? mContents->getBuffer() : 0; }
const void *data() { return mContents ? mContents->data() : 0; }
size_t size() const { return mSize; }
GLenum usage() const { return mUsage; }
......
......@@ -1941,7 +1941,7 @@ GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
}
sw::Resource *resource = attributes[i].vertexBuffer;
const void *buffer = (char*)resource->getBuffer() + attributes[i].offset;
const void *buffer = (char*)resource->data() + attributes[i].offset;
int stride = attributes[i].stride;
......
......@@ -22,62 +22,4 @@
namespace es2
{
Buffer::Buffer(GLuint id) : RefCountObject(id)
{
mContents = 0;
mSize = 0;
mUsage = GL_DYNAMIC_DRAW;
}
Buffer::~Buffer()
{
if(mContents)
{
mContents->destruct();
}
}
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
{
if(mContents)
{
mContents->destruct();
mContents = 0;
}
mSize = size;
mUsage = usage;
if(size > 0)
{
const int padding = 1024; // For SIMD processing of vertices
mContents = new sw::Resource(size + padding);
if(!mContents)
{
return error(GL_OUT_OF_MEMORY);
}
if(data)
{
memcpy((void*)mContents->getBuffer(), data, size);
}
}
}
void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
if(mContents)
{
char *buffer = (char*)mContents->lock(sw::PUBLIC);
memcpy(buffer + offset, data, size);
mContents->unlock();
}
}
sw::Resource *Buffer::getResource()
{
return mContents;
}
}
......@@ -27,27 +27,7 @@
namespace es2
{
class Buffer : public RefCountObject
{
public:
explicit Buffer(GLuint id);
virtual ~Buffer();
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
const void *data() { return mContents ? mContents->getBuffer() : 0; }
size_t size() const { return mSize; }
GLenum usage() const { return mUsage; }
sw::Resource *getResource();
public:
sw::Resource *mContents;
size_t mSize;
GLenum mUsage;
};
}
......
......@@ -106,12 +106,8 @@ struct Color
class VertexAttribute
{
public:
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mOffset(0), mArrayEnabled(false)
{
mCurrentValue[0] = 0.0f;
mCurrentValue[1] = 0.0f;
mCurrentValue[2] = 0.0f;
mCurrentValue[3] = 1.0f;
}
int typeSize() const
......@@ -138,17 +134,11 @@ class VertexAttribute
GLint mSize;
bool mNormalized;
GLsizei mStride; // 0 means natural stride
intptr_t mOffset;
union
{
const void *mPointer;
intptr_t mOffset;
};
BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.
sw::Resource *buffer;
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
float mCurrentValue[4]; // From glVertexAttrib
};
typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
......@@ -222,8 +212,7 @@ struct State
bool depthMask;
unsigned int activeSampler; // Active texture unit selector - GL_TEXTURE0
BindingPointer<Buffer> arrayBuffer;
BindingPointer<Buffer> elementArrayBuffer;
sw::Resource *elementArrayBuffer;
GLuint readFramebuffer;
GLuint drawFramebuffer;
BindingPointer<Renderbuffer> renderbuffer;
......@@ -317,14 +306,11 @@ public:
GLuint getActiveQuery(GLenum target) const;
GLuint getArrayBufferHandle() const;
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
const VertexAttribute &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
void setVertexAttribState(unsigned int attribNum, sw::Resource *buffer, GLint size, GLenum type,
bool normalized, GLsizei stride, intptr_t offset);
const VertexAttributeArray &getVertexAttributes();
void setUnpackAlignment(GLint alignment);
......@@ -335,13 +321,11 @@ public:
// These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types
GLuint createBuffer();
GLuint createShader(GLenum type);
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
......@@ -359,8 +343,6 @@ public:
GLuint createQuery();
void deleteQuery(GLuint query);
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
void bindTextureExternal(GLuint texture);
......@@ -376,9 +358,6 @@ public:
void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, const GLfloat *values);
Buffer *getBuffer(GLuint handle);
Fence *getFence(GLuint handle);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
......@@ -387,8 +366,6 @@ public:
virtual Renderbuffer *getRenderbuffer(GLuint handle);
Query *getQuery(GLuint handle, bool create, GLenum type);
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
Program *getCurrentProgram();
Texture2D *getTexture2D();
TextureCubeMap *getTextureCubeMap();
......@@ -397,12 +374,6 @@ public:
Framebuffer *getReadFramebuffer();
Framebuffer *getDrawFramebuffer();
bool getFloatv(GLenum pname, GLfloat *params);
bool getIntegerv(GLenum pname, GLint *params);
bool getBooleanv(GLenum pname, GLboolean *params);
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
......@@ -442,7 +413,6 @@ public:
void applyTextures(sw::SamplerType type);
void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer);
......
......@@ -20,27 +20,15 @@
#include <string.h>
#include <algorithm>
namespace
{
enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
}
namespace es2
{
IndexDataManager::IndexDataManager()
{
mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
if(!mStreamingBuffer)
{
ERR("Failed to allocate the streaming index buffer.");
}
}
IndexDataManager::~IndexDataManager()
{
delete mStreamingBuffer;
}
void copyIndices(GLenum type, const void *input, GLsizei count, void *output)
......@@ -90,68 +78,31 @@ void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIn
else UNREACHABLE();
}
GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, sw::Resource *buffer, const void *indices, TranslatedIndexData *translated)
{
if(!mStreamingBuffer)
{
return GL_OUT_OF_MEMORY;
}
intptr_t offset = reinterpret_cast<intptr_t>(indices);
bool alignedOffset = false;
if(buffer != NULL)
switch(type)
{
switch(type)
{
case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
default: UNREACHABLE(); alignedOffset = false;
}
if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
{
return GL_INVALID_OPERATION;
}
indices = static_cast<const GLubyte*>(buffer->data()) + offset;
case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
default: UNREACHABLE(); alignedOffset = false;
}
StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;
if(staticBuffer)
if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size))
{
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
translated->indexBuffer = staticBuffer;
translated->indexOffset = offset;
return GL_INVALID_OPERATION;
}
else
{
unsigned int streamOffset = 0;
int convertCount = count;
streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
if(output == NULL)
{
ERR("Failed to map index buffer.");
return GL_OUT_OF_MEMORY;
}
copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
streamingBuffer->unmap();
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
translated->indexBuffer = streamingBuffer->getResource();
translated->indexOffset = streamOffset;
}
indices = static_cast<const GLubyte*>(buffer->data()) + offset;
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
translated->indexBuffer = buffer;
translated->indexOffset = offset;
return GL_NO_ERROR;
}
......@@ -166,94 +117,4 @@ std::size_t IndexDataManager::typeSize(GLenum type)
}
}
StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mBufferSize(initialSize), mIndexBuffer(NULL)
{
if(initialSize > 0)
{
mIndexBuffer = new sw::Resource(initialSize + 16);
if(!mIndexBuffer)
{
ERR("Out of memory allocating an index buffer of size %lu.", initialSize);
}
}
mWritePosition = 0;
}
StreamingIndexBuffer::~StreamingIndexBuffer()
{
if(mIndexBuffer)
{
mIndexBuffer->destruct();
}
}
void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)
{
void *mapPtr = NULL;
if(mIndexBuffer)
{
mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;
if(!mapPtr)
{
ERR(" Lock failed");
return NULL;
}
*offset = mWritePosition;
mWritePosition += requiredSpace;
}
return mapPtr;
}
void StreamingIndexBuffer::unmap()
{
if(mIndexBuffer)
{
mIndexBuffer->unlock();
}
}
void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)
{
if(requiredSpace > mBufferSize)
{
if(mIndexBuffer)
{
mIndexBuffer->destruct();
mIndexBuffer = 0;
}
mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
mIndexBuffer = new sw::Resource(mBufferSize + 16);
if(!mIndexBuffer)
{
ERR("Out of memory allocating an index buffer of size %lu.", mBufferSize);
}
mWritePosition = 0;
}
else if(mWritePosition + requiredSpace > mBufferSize) // Recycle
{
if(mIndexBuffer)
{
mIndexBuffer->destruct();
mIndexBuffer = new sw::Resource(mBufferSize + 16);
}
mWritePosition = 0;
}
}
sw::Resource *StreamingIndexBuffer::getResource() const
{
return mIndexBuffer;
}
}
......@@ -32,36 +32,15 @@ struct TranslatedIndexData
sw::Resource *indexBuffer;
};
class StreamingIndexBuffer
{
public:
StreamingIndexBuffer(unsigned int initialSize);
virtual ~StreamingIndexBuffer();
void *map(unsigned int requiredSpace, unsigned int *offset);
void unmap();
void reserveSpace(unsigned int requiredSpace, GLenum type);
sw::Resource *getResource() const;
private:
sw::Resource *mIndexBuffer;
unsigned int mBufferSize;
unsigned int mWritePosition;
};
class IndexDataManager
{
public:
IndexDataManager();
virtual ~IndexDataManager();
GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
GLenum prepareIndexData(GLenum type, GLsizei count, sw::Resource *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
static std::size_t typeSize(GLenum type);
private:
StreamingIndexBuffer *mStreamingBuffer;
};
}
......
......@@ -29,11 +29,6 @@ ResourceManager::ResourceManager()
ResourceManager::~ResourceManager()
{
while(!mBufferMap.empty())
{
deleteBuffer(mBufferMap.begin()->first);
}
while(!mProgramMap.empty())
{
deleteProgram(mProgramMap.begin()->first);
......@@ -68,16 +63,6 @@ void ResourceManager::release()
}
}
// Returns an unused buffer name
GLuint ResourceManager::createBuffer()
{
GLuint handle = mBufferHandleAllocator.allocate();
mBufferMap[handle] = NULL;
return handle;
}
// Returns an unused shader/program name
GLuint ResourceManager::createShader(GLenum type)
{
......@@ -126,18 +111,6 @@ GLuint ResourceManager::createRenderbuffer()
return handle;
}
void ResourceManager::deleteBuffer(GLuint buffer)
{
BufferMap::iterator bufferObject = mBufferMap.find(buffer);
if(bufferObject != mBufferMap.end())
{
mBufferHandleAllocator.release(bufferObject->first);
if(bufferObject->second) bufferObject->second->release();
mBufferMap.erase(bufferObject);
}
}
void ResourceManager::deleteShader(GLuint shader)
{
ShaderMap::iterator shaderObject = mShaderMap.find(shader);
......@@ -200,20 +173,6 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
}
}
Buffer *ResourceManager::getBuffer(unsigned int handle)
{
BufferMap::iterator buffer = mBufferMap.find(handle);
if(buffer == mBufferMap.end())
{
return NULL;
}
else
{
return buffer->second;
}
}
Shader *ResourceManager::getShader(unsigned int handle)
{
ShaderMap::iterator shader = mShaderMap.find(handle);
......@@ -283,16 +242,6 @@ void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
mRenderbufferMap[handle] = buffer;
}
void ResourceManager::checkBufferAllocation(unsigned int buffer)
{
if(buffer != 0 && !getBuffer(buffer))
{
Buffer *bufferObject = new Buffer(buffer);
mBufferMap[buffer] = bufferObject;
bufferObject->addRef();
}
}
void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
{
if(!getTexture(texture) && texture != 0)
......
......@@ -24,7 +24,6 @@
namespace es2
{
class Buffer;
class Shader;
class Program;
class Texture;
......@@ -55,13 +54,11 @@ class ResourceManager
GLuint createTexture();
GLuint createRenderbuffer();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
Texture *getTexture(GLuint handle);
......@@ -69,16 +66,11 @@ class ResourceManager
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
void checkBufferAllocation(unsigned int buffer);
void checkTextureAllocation(GLuint texture, TextureType type);
private:
std::size_t mRefCount;
typedef std::map<GLint, Buffer*> BufferMap;
BufferMap mBufferMap;
HandleAllocator mBufferHandleAllocator;
typedef std::map<GLint, Shader*> ShaderMap;
ShaderMap mShaderMap;
......
......@@ -19,118 +19,21 @@
#include "IndexDataManager.h"
#include "common/debug.h"
namespace
{
enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};
}
namespace es2
{
VertexDataManager::VertexDataManager(Context *context) : mContext(context)
{
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mDirtyCurrentValue[i] = true;
mCurrentValueBuffer[i] = NULL;
}
mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
if(!mStreamingBuffer)
{
ERR("Failed to allocate the streaming vertex buffer.");
}
}
VertexDataManager::~VertexDataManager()
{
delete mStreamingBuffer;
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
delete mCurrentValueBuffer[i];
}
}
unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
{
Buffer *buffer = attribute.mBoundBuffer.get();
int inputStride = attribute.stride();
int elementSize = attribute.typeSize();
unsigned int streamOffset = 0;
char *output = NULL;
if(vertexBuffer)
{
output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);
}
if(output == NULL)
{
ERR("Failed to map vertex buffer.");
return -1;
}
const char *input = NULL;
if(buffer)
{
int offset = attribute.mOffset;
input = static_cast<const char*>(buffer->data()) + offset;
}
else
{
input = static_cast<const char*>(attribute.mPointer);
}
input += inputStride * start;
if(inputStride == elementSize)
{
memcpy(output, input, count * inputStride);
}
else
{
for(int i = 0; i < count; i++)
{
memcpy(output, input, elementSize);
output += elementSize;
input += inputStride;
}
}
vertexBuffer->unmap();
return streamOffset;
}
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
{
if(!mStreamingBuffer)
{
return GL_OUT_OF_MEMORY;
}
const VertexAttributeArray &attribs = mContext->getVertexAttributes();
Program *program = mContext->getCurrentProgram();
// Determine the required storage size per used buffer
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
if(program->getAttributeStream(i) != -1 && attribs[i].mArrayEnabled)
{
if(!attribs[i].mBoundBuffer)
{
mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);
}
}
}
mStreamingBuffer->reserveRequiredSpace();
// Perform the vertex data translations
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
......@@ -139,37 +42,10 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
{
if(attribs[i].mArrayEnabled)
{
Buffer *buffer = attribs[i].mBoundBuffer.get();
if(!buffer && attribs[i].mPointer == NULL)
{
// This is an application error that would normally result in a crash, but we catch it and return an error
ERR("An enabled vertex array has no buffer and no pointer.");
return GL_INVALID_OPERATION;
}
sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;
if(staticBuffer)
{
translated[i].vertexBuffer = staticBuffer;
translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;
translated[i].stride = attribs[i].stride();
}
else
{
unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
if(streamOffset == -1)
{
return GL_OUT_OF_MEMORY;
}
translated[i].vertexBuffer = mStreamingBuffer->getResource();
translated[i].offset = streamOffset;
translated[i].stride = attribs[i].typeSize();
}
translated[i].vertexBuffer = attribs[i].buffer;
translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;
translated[i].stride = attribs[i].stride();
switch(attribs[i].mType)
{
case GL_BYTE: translated[i].type = sw::STREAMTYPE_SBYTE; break;
......@@ -186,15 +62,7 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
}
else
{
if(mDirtyCurrentValue[i])
{
delete mCurrentValueBuffer[i];
mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
mDirtyCurrentValue[i] = false;
}
translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();
translated[i].vertexBuffer = 0;
translated[i].type = sw::STREAMTYPE_FLOAT;
translated[i].count = 4;
translated[i].stride = 0;
......@@ -206,129 +74,4 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
return GL_NO_ERROR;
}
VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(NULL)
{
if(size > 0)
{
mVertexBuffer = new sw::Resource(size + 1024);
if(!mVertexBuffer)
{
ERR("Out of memory allocating a vertex buffer of size %lu.", size);
}
}
}
VertexBuffer::~VertexBuffer()
{
if(mVertexBuffer)
{
mVertexBuffer->destruct();
}
}
void VertexBuffer::unmap()
{
if(mVertexBuffer)
{
mVertexBuffer->unlock();
}
}
sw::Resource *VertexBuffer::getResource() const
{
return mVertexBuffer;
}
ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))
{
if(mVertexBuffer)
{
float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);
vector[0] = x;
vector[1] = y;
vector[2] = z;
vector[3] = w;
mVertexBuffer->unlock();
}
}
ConstantVertexBuffer::~ConstantVertexBuffer()
{
}
StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)
{
mBufferSize = size;
mWritePosition = 0;
mRequiredSpace = 0;
}
StreamingVertexBuffer::~StreamingVertexBuffer()
{
}
void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)
{
mRequiredSpace += requiredSpace;
}
void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)
{
void *mapPtr = NULL;
if(mVertexBuffer)
{
mapPtr = (char*)mVertexBuffer->lock(sw::PUBLIC) + mWritePosition;
if(!mapPtr)
{
ERR("Lock failed");
return NULL;
}
*offset = mWritePosition;
mWritePosition += requiredSpace;
}
return mapPtr;
}
void StreamingVertexBuffer::reserveRequiredSpace()
{
if(mRequiredSpace > mBufferSize)
{
if(mVertexBuffer)
{
mVertexBuffer->destruct();
mVertexBuffer = 0;
}
mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2); // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
mVertexBuffer = new sw::Resource(mBufferSize);
if(!mVertexBuffer)
{
ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
}
mWritePosition = 0;
}
else if(mWritePosition + mRequiredSpace > mBufferSize) // Recycle
{
if(mVertexBuffer)
{
mVertexBuffer->destruct();
mVertexBuffer = new sw::Resource(mBufferSize);
}
mWritePosition = 0;
}
mRequiredSpace = 0;
}
}
......@@ -36,62 +36,16 @@ struct TranslatedAttribute
sw::Resource *vertexBuffer;
};
class VertexBuffer
{
public:
VertexBuffer(unsigned int size);
virtual ~VertexBuffer();
void unmap();
sw::Resource *getResource() const;
protected:
sw::Resource *mVertexBuffer;
};
class ConstantVertexBuffer : public VertexBuffer
{
public:
ConstantVertexBuffer(float x, float y, float z, float w);
~ConstantVertexBuffer();
};
class StreamingVertexBuffer : public VertexBuffer
{
public:
StreamingVertexBuffer(unsigned int size);
~StreamingVertexBuffer();
void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);
void reserveRequiredSpace();
void addRequiredSpace(unsigned int requiredSpace);
protected:
unsigned int mBufferSize;
unsigned int mWritePosition;
unsigned int mRequiredSpace;
};
class VertexDataManager
{
public:
VertexDataManager(Context *context);
virtual ~VertexDataManager();
void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
private:
unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
Context *const mContext;
StreamingVertexBuffer *mStreamingBuffer;
bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
};
}
......
......@@ -156,17 +156,15 @@ public:
{
if(buffer)
{
buffer->release();
buffer->destruct();
}
}
void storage(RADsizei size)
{
ASSERT(!buffer);
buffer = new es2::Buffer(0);
buffer->addRef();
buffer->mContents = new sw::Resource(size);
buffer->mSize = size;
const int padding = 1024; // For SIMD processing of vertices
buffer = new sw::Resource(size + padding);
}
void *map()
......@@ -175,7 +173,7 @@ public:
return const_cast<void*>(buffer->data());
}
es2::Buffer *buffer;
sw::Resource *buffer;
RADbitfield access;
RADbitfield mapAccess;
......@@ -1005,7 +1003,7 @@ public:
class DrawElements : public Command
{
public:
DrawElements(RADprimitiveType mode, RADindexType type, RADsizei count, es2::Buffer *indexBuffer, RADuint offset)
DrawElements(RADprimitiveType mode, RADindexType type, RADsizei count, sw::Resource *indexBuffer, RADuint offset)
{
this->mode = mode;
this->type = type;
......@@ -1060,21 +1058,21 @@ public:
default: UNREACHABLE();
}
context->mState.elementArrayBuffer.set(indexBuffer);
context->mState.elementArrayBuffer = indexBuffer;
context->drawElements(glMode, count, glType, 0);
}
RADprimitiveType mode;
RADindexType type;
RADsizei count;
es2::Buffer *indexBuffer;
sw::Resource *indexBuffer;
RADuint offset;
};
class BindGroup : public Command
{
public:
BindGroup(RADbitfield stages, RADuint group, RADuint count, es2::Buffer *buffer, RADuint offset)
BindGroup(RADbitfield stages, RADuint group, RADuint count, sw::Resource *buffer, RADuint offset)
{
this->stages = stages;
this->group = group;
......@@ -1096,19 +1094,19 @@ public:
// FIXME: Should parse the layout out of the shaders
es2::Program *program = pipeline->vertexProgram->program;
es2::Buffer *element0 = reinterpret_cast<es2::Buffer*>(groupElements[0].handle);
void *offset0 = reinterpret_cast<void*>(static_cast<uintptr_t>(groupElements[0].offset));
sw::Resource *element0 = reinterpret_cast<sw::Resource*>(groupElements[0].handle);
uintptr_t offset0 = static_cast<uintptr_t>(groupElements[0].offset);
int position = program->getAttributeLocation("position");
context->setVertexAttribState(position, element0, 3, GL_FLOAT, GL_TRUE, 0, offset0);
context->setEnableVertexAttribArray(position, true);
es2::Buffer *element1 = reinterpret_cast<es2::Buffer*>(groupElements[1].handle);
void *offset1 = reinterpret_cast<void*>(static_cast<uintptr_t>(groupElements[1].offset));
sw::Resource *element1 = reinterpret_cast<sw::Resource*>(groupElements[1].handle);
uintptr_t offset1 = static_cast<uintptr_t>(groupElements[1].offset);
int tc = program->getAttributeLocation("tc");
context->setVertexAttribState(tc, element1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, offset1);
context->setEnableVertexAttribArray(tc, true);
es2::Buffer *element2 = reinterpret_cast<es2::Buffer*>(groupElements[2].handle);
sw::Resource *element2 = reinterpret_cast<sw::Resource*>(groupElements[2].handle);
const void *uniform = static_cast<const uint8_t*>(element2->data()) + groupElements[2].offset;
int scale = program->getUniformLocation("scale");
program->setUniform4fv(scale, 1, (const GLfloat*)uniform);
......@@ -1123,7 +1121,7 @@ public:
RADbitfield stages;
RADuint group;
RADuint count;
es2::Buffer *buffer;
sw::Resource *buffer;
RADuint offset;
};
......@@ -1319,7 +1317,7 @@ void RADAPIENTRY radQueueDrawArrays(RADqueue queue, RADprimitiveType mode, RADin
void RADAPIENTRY radQueueDrawElements(RADqueue queue, RADprimitiveType mode, RADindexType type, RADsizei count, RADindexHandle indexHandle, RADuint offset)
{
rad::Queue *radQueue = reinterpret_cast<rad::Queue*>(queue);
es2::Buffer *indexBuffer = reinterpret_cast<es2::Buffer*>(indexHandle);
sw::Resource *indexBuffer = reinterpret_cast<sw::Resource*>(indexHandle);
rad::DrawElements *command = new rad::DrawElements(mode, type, count, indexBuffer, offset);
radQueue->submit(command);
}
......@@ -1334,7 +1332,7 @@ void RADAPIENTRY radQueueBindPipeline(RADqueue queue, RADpipelineType pipelineTy
void RADAPIENTRY radQueueBindGroup(RADqueue queue, RADbitfield stages, RADuint group, RADuint count, RADbindGroupHandle groupHandle, RADuint offset)
{
rad::Queue *radQueue = reinterpret_cast<rad::Queue*>(queue);
es2::Buffer *groupBuffer = reinterpret_cast<es2::Buffer*>(groupHandle);
sw::Resource *groupBuffer = reinterpret_cast<sw::Resource*>(groupHandle);
rad::BindGroup *command = new rad::BindGroup(stages, group, count, groupBuffer, offset);
radQueue->submit(command);
}
......
......@@ -196,7 +196,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman
<ClInclude Include="IndexDataManager.h" />
<ClInclude Include="main.h" />
<ClInclude Include="mathutil.h" />
<ClInclude Include="Object.hpp" />
<ClInclude Include="Program.h" />
<ClInclude Include="Query.h" />
<ClInclude Include="RefCountObject.h" />
......
......@@ -145,9 +145,6 @@
<ClInclude Include="..\common\debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Object.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="libRAD.rc" />
......
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