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;
};
}
......
......@@ -136,8 +136,7 @@ Context::Context(const egl::Config *config, const Context *shareContext) : mConf
mTextureExternalZero.set(new TextureExternal(0));
mState.activeSampler = 0;
bindArrayBuffer(0);
bindElementArrayBuffer(0);
mState.elementArrayBuffer = 0;
bindTextureCubeMap(0);
bindTexture2D(0);
bindReadFramebuffer(0);
......@@ -200,7 +199,7 @@ Context::~Context()
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mState.vertexAttribute[i].mBoundBuffer.set(NULL);
mState.vertexAttribute[i].buffer = 0;
}
for(int i = 0; i < QUERY_TYPE_COUNT; i++)
......@@ -208,9 +207,9 @@ Context::~Context()
mState.activeQuery[i].set(NULL);
}
mState.arrayBuffer.set(NULL);
mState.elementArrayBuffer.set(NULL);
mState.renderbuffer.set(NULL);
//mState.arrayBuffer.set(NULL);
//mState.elementArrayBuffer.set(NULL);
//mState.renderbuffer.set(NULL);
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
......@@ -664,11 +663,6 @@ GLuint Context::getRenderbufferHandle() const
return mState.renderbuffer.id();
}
GLuint Context::getArrayBufferHandle() const
{
return mState.arrayBuffer.id();
}
GLuint Context::getActiveQuery(GLenum target) const
{
Query *queryObject = NULL;
......@@ -703,20 +697,15 @@ const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
return mState.vertexAttribute[attribNum];
}
void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
GLsizei stride, const void *pointer)
void Context::setVertexAttribState(unsigned int attribNum, sw::Resource *buffer, GLint size, GLenum type, bool normalized,
GLsizei stride, intptr_t offset)
{
mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
mState.vertexAttribute[attribNum].buffer = buffer;
mState.vertexAttribute[attribNum].mSize = size;
mState.vertexAttribute[attribNum].mType = type;
mState.vertexAttribute[attribNum].mNormalized = normalized;
mState.vertexAttribute[attribNum].mStride = stride;
mState.vertexAttribute[attribNum].mPointer = pointer;
}
const void *Context::getVertexAttribPointer(unsigned int attribNum) const
{
return mState.vertexAttribute[attribNum].mPointer;
mState.vertexAttribute[attribNum].mOffset = offset;
}
const VertexAttributeArray &Context::getVertexAttributes()
......@@ -744,11 +733,6 @@ GLint Context::getUnpackAlignment() const
return mState.unpackAlignment;
}
GLuint Context::createBuffer()
{
return mResourceManager->createBuffer();
}
GLuint Context::createProgram()
{
return mResourceManager->createProgram();
......@@ -798,16 +782,6 @@ GLuint Context::createQuery()
return handle;
}
void Context::deleteBuffer(GLuint buffer)
{
if(mResourceManager->getBuffer(buffer))
{
detachBuffer(buffer);
}
mResourceManager->deleteBuffer(buffer);
}
void Context::deleteShader(GLuint shader)
{
mResourceManager->deleteShader(shader);
......@@ -881,11 +855,6 @@ void Context::deleteQuery(GLuint query)
}
}
Buffer *Context::getBuffer(GLuint handle)
{
return mResourceManager->getBuffer(handle);
}
Shader *Context::getShader(GLuint handle)
{
return mResourceManager->getShader(handle);
......@@ -916,20 +885,6 @@ Framebuffer *Context::getDrawFramebuffer()
return getFramebuffer(mState.drawFramebuffer);
}
void Context::bindArrayBuffer(unsigned int buffer)
{
mResourceManager->checkBufferAllocation(buffer);
mState.arrayBuffer.set(getBuffer(buffer));
}
void Context::bindElementArrayBuffer(unsigned int buffer)
{
mResourceManager->checkBufferAllocation(buffer);
mState.elementArrayBuffer.set(getBuffer(buffer));
}
void Context::bindTexture2D(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
......@@ -1145,16 +1100,6 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
}
}
Buffer *Context::getArrayBuffer()
{
return mState.arrayBuffer.get();
}
Buffer *Context::getElementArrayBuffer()
{
return mState.elementArrayBuffer.get();
}
Program *Context::getCurrentProgram()
{
return mState.program;
......@@ -1194,480 +1139,6 @@ Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
return mState.samplerTexture[type][sampler].get();
}
bool Context::getBooleanv(GLenum pname, GLboolean *params)
{
switch (pname)
{
case GL_SHADER_COMPILER: *params = GL_TRUE; break;
case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
case GL_COLOR_WRITEMASK:
params[0] = mState.colorMaskRed;
params[1] = mState.colorMaskGreen;
params[2] = mState.colorMaskBlue;
params[3] = mState.colorMaskAlpha;
break;
case GL_CULL_FACE: *params = mState.cullFace; break;
case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
case GL_STENCIL_TEST: *params = mState.stencilTest; break;
case GL_DEPTH_TEST: *params = mState.depthTest; break;
case GL_BLEND: *params = mState.blend; break;
case GL_DITHER: *params = mState.dither; break;
default:
return false;
}
return true;
}
bool Context::getFloatv(GLenum pname, GLfloat *params)
{
// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
// GetIntegerv as its native query function. As it would require conversion in any
// case, this should make no difference to the calling application.
switch (pname)
{
case GL_LINE_WIDTH: *params = mState.lineWidth; break;
case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
case GL_ALIASED_LINE_WIDTH_RANGE:
params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
break;
case GL_ALIASED_POINT_SIZE_RANGE:
params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
break;
case GL_DEPTH_RANGE:
params[0] = mState.zNear;
params[1] = mState.zFar;
break;
case GL_COLOR_CLEAR_VALUE:
params[0] = mState.colorClearValue.red;
params[1] = mState.colorClearValue.green;
params[2] = mState.colorClearValue.blue;
params[3] = mState.colorClearValue.alpha;
break;
case GL_BLEND_COLOR:
params[0] = mState.blendColor.red;
params[1] = mState.blendColor.green;
params[2] = mState.blendColor.blue;
params[3] = mState.blendColor.alpha;
break;
case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
*params = MAX_TEXTURE_MAX_ANISOTROPY;
break;
default:
return false;
}
return true;
}
bool Context::getIntegerv(GLenum pname, GLint *params)
{
// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
// GetIntegerv as its native query function. As it would require conversion in any
// case, this should make no difference to the calling application. You may find it in
// Context::getFloatv.
switch (pname)
{
case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break;
case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break;
case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break;
case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break;
case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break;
case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.id(); break;
// case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break;
case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break;
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break;
case GL_STENCIL_FUNC: *params = mState.stencilFunc; break;
case GL_STENCIL_REF: *params = mState.stencilRef; break;
case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break;
case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break;
case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break;
case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break;
case GL_STENCIL_FAIL: *params = mState.stencilFail; break;
case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break;
case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break;
case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break;
case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break;
case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break;
case GL_DEPTH_FUNC: *params = mState.depthFunc; break;
case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break;
case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break;
case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break;
case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break;
case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break;
case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break;
case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break;
case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break;
case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
{
if(S3TC_SUPPORT)
{
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT
// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
// GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE
// GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE
*params = 4;
}
else
{
*params = 0;
}
}
break;
case GL_MAX_SAMPLES_ANGLE: *params = IMPLEMENTATION_MAX_SAMPLES; break;
case GL_SAMPLE_BUFFERS:
case GL_SAMPLES:
{
Framebuffer *framebuffer = getDrawFramebuffer();
int width, height, samples;
if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
{
switch(pname)
{
case GL_SAMPLE_BUFFERS:
if(samples > 1)
{
*params = 1;
}
else
{
*params = 0;
}
break;
case GL_SAMPLES:
*params = samples & ~1;
break;
}
}
else
{
*params = 0;
}
}
break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = IMPLEMENTATION_COLOR_READ_TYPE; break;
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
case GL_MAX_VIEWPORT_DIMS:
{
int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
params[0] = maxDimension;
params[1] = maxDimension;
}
break;
case GL_COMPRESSED_TEXTURE_FORMATS:
{
if(S3TC_SUPPORT)
{
params[0] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
params[1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
params[2] = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
params[3] = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
}
}
break;
case GL_VIEWPORT:
params[0] = mState.viewportX;
params[1] = mState.viewportY;
params[2] = mState.viewportWidth;
params[3] = mState.viewportHeight;
break;
case GL_SCISSOR_BOX:
params[0] = mState.scissorX;
params[1] = mState.scissorY;
params[2] = mState.scissorWidth;
params[3] = mState.scissorHeight;
break;
case GL_CULL_FACE_MODE: *params = mState.cullMode; break;
case GL_FRONT_FACE: *params = mState.frontFace; break;
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
{
Framebuffer *framebuffer = getDrawFramebuffer();
Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
if(colorbuffer)
{
switch (pname)
{
case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
}
}
else
{
*params = 0;
}
}
break;
case GL_DEPTH_BITS:
{
Framebuffer *framebuffer = getDrawFramebuffer();
Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
if(depthbuffer)
{
*params = depthbuffer->getDepthSize();
}
else
{
*params = 0;
}
}
break;
case GL_STENCIL_BITS:
{
Framebuffer *framebuffer = getDrawFramebuffer();
Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
if(stencilbuffer)
{
*params = stencilbuffer->getStencilSize();
}
else
{
*params = 0;
}
}
break;
case GL_TEXTURE_BINDING_2D:
{
if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
{
error(GL_INVALID_OPERATION);
return false;
}
*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
}
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
{
if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
{
error(GL_INVALID_OPERATION);
return false;
}
*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
}
break;
case GL_TEXTURE_BINDING_EXTERNAL_OES:
{
if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
{
error(GL_INVALID_OPERATION);
return false;
}
*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id();
}
break;
default:
return false;
}
return true;
}
bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
{
// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
// to the fact that it is stored internally as a float, and so would require conversion
// if returned from Context::getIntegerv. Since this conversion is already implemented
// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
// application.
switch (pname)
{
case GL_COMPRESSED_TEXTURE_FORMATS:
{
*type = GL_INT;
*numParams = S3TC_SUPPORT ? 4 : 0;
}
break;
case GL_SHADER_BINARY_FORMATS:
{
*type = GL_INT;
*numParams = 0;
}
break;
case GL_MAX_VERTEX_ATTRIBS:
case GL_MAX_VERTEX_UNIFORM_VECTORS:
case GL_MAX_VARYING_VECTORS:
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
case GL_MAX_TEXTURE_IMAGE_UNITS:
case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
case GL_MAX_RENDERBUFFER_SIZE:
case GL_NUM_SHADER_BINARY_FORMATS:
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
case GL_ARRAY_BUFFER_BINDING:
case GL_FRAMEBUFFER_BINDING:
case GL_RENDERBUFFER_BINDING:
case GL_CURRENT_PROGRAM:
case GL_PACK_ALIGNMENT:
case GL_UNPACK_ALIGNMENT:
case GL_GENERATE_MIPMAP_HINT:
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
case GL_DEPTH_BITS:
case GL_STENCIL_BITS:
case GL_ELEMENT_ARRAY_BUFFER_BINDING:
case GL_CULL_FACE_MODE:
case GL_FRONT_FACE:
case GL_ACTIVE_TEXTURE:
case GL_STENCIL_FUNC:
case GL_STENCIL_VALUE_MASK:
case GL_STENCIL_REF:
case GL_STENCIL_FAIL:
case GL_STENCIL_PASS_DEPTH_FAIL:
case GL_STENCIL_PASS_DEPTH_PASS:
case GL_STENCIL_BACK_FUNC:
case GL_STENCIL_BACK_VALUE_MASK:
case GL_STENCIL_BACK_REF:
case GL_STENCIL_BACK_FAIL:
case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
case GL_STENCIL_BACK_PASS_DEPTH_PASS:
case GL_DEPTH_FUNC:
case GL_BLEND_SRC_RGB:
case GL_BLEND_SRC_ALPHA:
case GL_BLEND_DST_RGB:
case GL_BLEND_DST_ALPHA:
case GL_BLEND_EQUATION_RGB:
case GL_BLEND_EQUATION_ALPHA:
case GL_STENCIL_WRITEMASK:
case GL_STENCIL_BACK_WRITEMASK:
case GL_STENCIL_CLEAR_VALUE:
case GL_SUBPIXEL_BITS:
case GL_MAX_TEXTURE_SIZE:
case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
case GL_SAMPLE_BUFFERS:
case GL_SAMPLES:
case GL_IMPLEMENTATION_COLOR_READ_TYPE:
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_TEXTURE_BINDING_EXTERNAL_OES:
{
*type = GL_INT;
*numParams = 1;
}
break;
case GL_MAX_SAMPLES_ANGLE:
{
*type = GL_INT;
*numParams = 1;
}
break;
case GL_MAX_VIEWPORT_DIMS:
{
*type = GL_INT;
*numParams = 2;
}
break;
case GL_VIEWPORT:
case GL_SCISSOR_BOX:
{
*type = GL_INT;
*numParams = 4;
}
break;
case GL_SHADER_COMPILER:
case GL_SAMPLE_COVERAGE_INVERT:
case GL_DEPTH_WRITEMASK:
case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
case GL_SAMPLE_COVERAGE:
case GL_SCISSOR_TEST:
case GL_STENCIL_TEST:
case GL_DEPTH_TEST:
case GL_BLEND:
case GL_DITHER:
{
*type = GL_BOOL;
*numParams = 1;
}
break;
case GL_COLOR_WRITEMASK:
{
*type = GL_BOOL;
*numParams = 4;
}
break;
case GL_POLYGON_OFFSET_FACTOR:
case GL_POLYGON_OFFSET_UNITS:
case GL_SAMPLE_COVERAGE_VALUE:
case GL_DEPTH_CLEAR_VALUE:
case GL_LINE_WIDTH:
{
*type = GL_FLOAT;
*numParams = 1;
}
break;
case GL_ALIASED_LINE_WIDTH_RANGE:
case GL_ALIASED_POINT_SIZE_RANGE:
case GL_DEPTH_RANGE:
{
*type = GL_FLOAT;
*numParams = 2;
}
break;
case GL_COLOR_CLEAR_VALUE:
case GL_BLEND_COLOR:
{
*type = GL_FLOAT;
*numParams = 4;
}
break;
case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
*type = GL_FLOAT;
*numParams = 1;
break;
default:
return false;
}
return true;
}
// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
bool Context::applyRenderTarget()
{
......@@ -1960,7 +1431,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;
......@@ -1982,7 +1453,7 @@ GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
// Applies the indices and element array bindings
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
if(err == GL_NO_ERROR)
{
......@@ -2625,31 +2096,6 @@ int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)
return 4;
}
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
// If a buffer object is deleted while it is bound, all bindings to that object in the current context
// (i.e. in the thread that called Delete-Buffers) are reset to zero.
if(mState.arrayBuffer.id() == buffer)
{
mState.arrayBuffer.set(NULL);
}
if(mState.elementArrayBuffer.id() == buffer)
{
mState.elementArrayBuffer.set(NULL);
}
for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
{
if(mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
{
mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
}
}
}
void Context::detachTexture(GLuint texture)
{
// [OpenGL ES 2.0.24] section 3.8 page 84:
......@@ -2757,18 +2203,6 @@ bool Context::isTriangleMode(GLenum drawMode)
return false;
}
void Context::setVertexAttrib(GLuint index, const GLfloat *values)
{
ASSERT(index < MAX_VERTEX_ATTRIBS);
mState.vertexAttribute[index].mCurrentValue[0] = values[0];
mState.vertexAttribute[index].mCurrentValue[1] = values[1];
mState.vertexAttribute[index].mCurrentValue[2] = values[2];
mState.vertexAttribute[index].mCurrentValue[3] = values[3];
mVertexDataManager->dirtyCurrentValue(index);
}
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask)
......
......@@ -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