diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2')
141 files changed, 11917 insertions, 8989 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h index 4d7dde04e1..4f7f5f2c85 100644 --- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h +++ b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h @@ -15,6 +15,7 @@ #include <cstddef> #include <string> #include <vector> +#include <stdint.h> namespace gl { @@ -26,7 +27,7 @@ class BinaryInputStream { mError = false; mOffset = 0; - mData = static_cast<const char*>(data); + mData = static_cast<const uint8_t*>(data); mLength = length; } @@ -85,7 +86,7 @@ class BinaryInputStream return; } - v->assign(mData + mOffset, length); + v->assign(reinterpret_cast<const char *>(mData) + mOffset, length); mOffset += length; } @@ -115,11 +116,16 @@ class BinaryInputStream return mOffset == mLength; } + const uint8_t *data() + { + return mData; + } + private: DISALLOW_COPY_AND_ASSIGN(BinaryInputStream); bool mError; size_t mOffset; - const char *mData; + const uint8_t *mData; size_t mLength; template <typename T> diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h index 35a6767502..daa862ca0d 100644 --- a/src/3rdparty/angle/src/libGLESv2/Buffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h @@ -19,7 +19,6 @@ namespace rx { -class Renderer; class BufferImpl; }; diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp index 5342de1331..b87689cd3f 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp @@ -9,10 +9,8 @@ #include "libGLESv2/Context.h" -#include "libGLESv2/main.h" #include "common/utilities.h" #include "common/platform.h" -#include "libGLESv2/formatutils.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Fence.h" #include "libGLESv2/Framebuffer.h" @@ -21,14 +19,15 @@ #include "libGLESv2/Program.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Query.h" -#include "libGLESv2/Texture.h" #include "libGLESv2/ResourceManager.h" -#include "libGLESv2/renderer/d3d/IndexDataManager.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/VertexArray.h" #include "libGLESv2/Sampler.h" -#include "libGLESv2/validationES.h" +#include "libGLESv2/Texture.h" #include "libGLESv2/TransformFeedback.h" +#include "libGLESv2/VertexArray.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/main.h" +#include "libGLESv2/validationES.h" +#include "libGLESv2/renderer/Renderer.h" #include "libEGL/Surface.h" @@ -38,7 +37,7 @@ namespace gl { -Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) +Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer) { ASSERT(robustAccess == false); // Unimplemented @@ -66,22 +65,24 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere // In order that access to these initial textures not be lost, they are treated as texture // objects all of whose names are 0. - mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0)); - bindTexture(GL_TEXTURE_2D, 0); + Texture2D *zeroTexture2D = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0); + mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D); - mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0)); - bindTexture(GL_TEXTURE_CUBE_MAP, 0); + TextureCubeMap *zeroTextureCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0); + mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube); if (mClientVersion >= 3) { // TODO: These could also be enabled via extension - mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0)); - bindTexture(GL_TEXTURE_3D, 0); + Texture3D *zeroTexture3D = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0); + mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D); - mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0)); - bindTexture(GL_TEXTURE_2D_ARRAY, 0); + Texture2DArray *zeroTexture2DArray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0); + mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray); } + mState.initializeZeroTextures(mZeroTextures); + bindVertexArray(0); bindArrayBuffer(0); bindElementArrayBuffer(0); @@ -91,13 +92,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere bindRenderbuffer(0); bindGenericUniformBuffer(0); - for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) + for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++) { bindIndexedUniformBuffer(0, i, 0, -1); } bindGenericTransformFeedbackBuffer(0); - for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (unsigned int i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++) { bindIndexedTransformFeedbackBuffer(0, i, 0, -1); } @@ -119,8 +120,6 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere mResetStatus = GL_NO_ERROR; mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT); mRobustAccess = robustAccess; - - mState.setContext(this); } Context::~Context() @@ -175,7 +174,10 @@ Context::~Context() } mZeroTextures.clear(); - mResourceManager->release(); + if (mResourceManager) + { + mResourceManager->release(); + } } void Context::makeCurrent(egl::Surface *surface) @@ -194,14 +196,11 @@ void Context::makeCurrent(egl::Surface *surface) // Wrap the existing swapchain resources into GL objects and assign them to the '0' names rx::SwapChain *swapchain = surface->getSwapChain(); - Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain); - DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain); - Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero); + rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false); + rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true); + Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); setFramebufferZero(framebufferZero); - - // Store the current client version in the renderer - mRenderer->setCurrentClientVersion(mClientVersion); } // NOTE: this function should not assume that this context is current! @@ -229,7 +228,7 @@ GLuint Context::createProgram() GLuint Context::createShader(GLenum type) { - return mResourceManager->createShader(type); + return mResourceManager->createShader(getData(), type); } GLuint Context::createTexture() @@ -242,15 +241,10 @@ GLuint Context::createRenderbuffer() return mResourceManager->createRenderbuffer(); } -GLsync Context::createFenceSync(GLenum condition) +GLsync Context::createFenceSync() { GLuint handle = mResourceManager->createFenceSync(); - gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle); - ASSERT(fenceSync); - - fenceSync->set(condition); - return reinterpret_cast<GLsync>(handle); } @@ -294,7 +288,7 @@ GLuint Context::createFenceNV() { GLuint handle = mFenceNVHandleAllocator.allocate(); - mFenceNVMap[handle] = new FenceNV(mRenderer); + mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV()); return handle; } @@ -355,12 +349,12 @@ void Context::deleteFenceSync(GLsync fenceSync) // wait commands finish. However, since the name becomes invalid, we cannot query the fence, // and since our API is currently designed for being called from a single thread, we can delete // the fence immediately. - mResourceManager->deleteFenceSync(uintptr_t(fenceSync)); + mResourceManager->deleteFenceSync(reinterpret_cast<uintptr_t>(fenceSync)); } void Context::deleteVertexArray(GLuint vertexArray) { - auto vertexArrayObject = mVertexArrayMap.find(vertexArray); + VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray); if (vertexArrayObject != mVertexArrayMap.end()) { @@ -461,12 +455,12 @@ Renderbuffer *Context::getRenderbuffer(GLuint handle) FenceSync *Context::getFenceSync(GLsync handle) const { - return mResourceManager->getFenceSync(uintptr_t(handle)); + return mResourceManager->getFenceSync(reinterpret_cast<uintptr_t>(handle)); } VertexArray *Context::getVertexArray(GLuint handle) const { - auto vertexArray = mVertexArrayMap.find(handle); + VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle); if (vertexArray == mVertexArrayMap.end()) { @@ -515,18 +509,30 @@ void Context::bindElementArrayBuffer(unsigned int buffer) mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer)); } -void Context::bindTexture(GLenum target, GLuint texture) +void Context::bindTexture(GLenum target, GLuint handle) { - mResourceManager->checkTextureAllocation(texture, target); + Texture *texture = NULL; + + if (handle == 0) + { + texture = mZeroTextures[target].get(); + } + else + { + mResourceManager->checkTextureAllocation(handle, target); + texture = getTexture(handle); + } - mState.setSamplerTexture(target, getTexture(texture)); + ASSERT(texture); + + mState.setSamplerTexture(target, texture); } void Context::bindReadFramebuffer(GLuint framebuffer) { if (!getFramebuffer(framebuffer)) { - mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer); + mFramebufferMap[framebuffer] = new Framebuffer(framebuffer); } mState.setReadFramebufferBinding(getFramebuffer(framebuffer)); @@ -536,7 +542,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer) { if (!getFramebuffer(framebuffer)) { - mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer); + mFramebufferMap[framebuffer] = new Framebuffer(framebuffer); } mState.setDrawFramebufferBinding(getFramebuffer(framebuffer)); @@ -640,33 +646,44 @@ void Context::useProgram(GLuint program) } } -void Context::linkProgram(GLuint program) +Error Context::linkProgram(GLuint program) { Program *programObject = mResourceManager->getProgram(program); - bool linked = programObject->link(getCaps()); + Error error = programObject->link(getData()); + if (error.isError()) + { + return error; + } // if the current program was relinked successfully we // need to install the new executables - if (linked && program == mState.getCurrentProgramId()) + if (programObject->isLinked() && program == mState.getCurrentProgramId()) { mState.setCurrentProgramBinary(programObject->getProgramBinary()); } + + return Error(GL_NO_ERROR); } -void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length) +Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length) { Program *programObject = mResourceManager->getProgram(program); - bool loaded = programObject->setProgramBinary(binaryFormat, binary, length); + Error error = programObject->setProgramBinary(binaryFormat, binary, length); + if (error.isError()) + { + return error; + } // if the current program was reloaded successfully we // need to install the new executables - if (loaded && program == mState.getCurrentProgramId()) + if (programObject->isLinked() && program == mState.getCurrentProgramId()) { mState.setCurrentProgramBinary(programObject->getProgramBinary()); } + return Error(GL_NO_ERROR); } void Context::bindTransformFeedback(GLuint transformFeedback) @@ -724,33 +741,6 @@ void Context::setFramebufferZero(Framebuffer *buffer) mFramebufferMap[0] = buffer; } -void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) -{ - ASSERT(getTextureCaps().get(internalformat).renderable); - - RenderbufferStorage *renderbuffer = NULL; - - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0) - { - renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples); - } - else if (formatInfo.depthBits > 0) - { - renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples); - } - else if (formatInfo.stencilBits > 0) - { - renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples); - } - else - { - renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples); - } - - mState.getCurrentRenderbuffer()->setStorage(renderbuffer); -} - Framebuffer *Context::getFramebuffer(unsigned int handle) const { FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle); @@ -837,14 +827,7 @@ Texture2DArray *Context::getTexture2DArray() const Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const { - if (mState.getSamplerTextureId(sampler, type) == 0) - { - return mZeroTextures.at(type).get(); - } - else - { - return mState.getSamplerTexture(sampler, type); - } + return mState.getSamplerTexture(sampler, type); } void Context::getBooleanv(GLenum pname, GLboolean *params) @@ -962,7 +945,7 @@ void Context::getIntegerv(GLenum pname, GLint *params) *params = static_cast<GLint>(mExtensionStrings.size()); break; default: - mState.getIntegerv(pname, params); + mState.getIntegerv(getData(), pname, params); break; } } @@ -1309,309 +1292,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned return false; } -// Applies the render target surface, depth stencil surface, viewport rectangle and -// scissor rectangle to the renderer -Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport) -{ - Framebuffer *framebufferObject = mState.getDrawFramebuffer(); - ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE); - - gl::Error error = mRenderer->applyRenderTarget(framebufferObject); - if (error.isError()) - { - return error; - } - - float nearZ, farZ; - mState.getDepthRange(&nearZ, &farZ); - mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace, - ignoreViewport); - - mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled()); - - return gl::Error(GL_NO_ERROR); -} - -// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device -Error Context::applyState(GLenum drawMode) -{ - Framebuffer *framebufferObject = mState.getDrawFramebuffer(); - int samples = framebufferObject->getSamples(); - - RasterizerState rasterizer = mState.getRasterizerState(); - rasterizer.pointDrawMode = (drawMode == GL_POINTS); - rasterizer.multiSample = (samples != 0); - - Error error = mRenderer->setRasterizerState(rasterizer); - if (error.isError()) - { - return error; - } - - unsigned int mask = 0; - if (mState.isSampleCoverageEnabled()) - { - GLclampf coverageValue; - bool coverageInvert = false; - mState.getSampleCoverageParams(&coverageValue, &coverageInvert); - if (coverageValue != 0) - { - float threshold = 0.5f; - - for (int i = 0; i < samples; ++i) - { - mask <<= 1; - - if ((i + 1) * coverageValue >= threshold) - { - threshold += 1.0f; - mask |= 1; - } - } - } - - if (coverageInvert) - { - mask = ~mask; - } - } - else - { - mask = 0xFFFFFFFF; - } - error = mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask); - if (error.isError()) - { - return error; - } - - error = mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(), - rasterizer.frontFace == GL_CCW); - if (error.isError()) - { - return error; - } - - return Error(GL_NO_ERROR); -} - -// Applies the shaders and shader constants to the Direct3D 9 device -Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive) -{ - const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes(); - - VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; - VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues()); - - const Framebuffer *fbo = mState.getDrawFramebuffer(); - - Error error = mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - return programBinary->applyUniforms(); -} - -Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type) -{ - size_t samplerRange = programBinary->getUsedSamplerRange(type); - - for (size_t i = 0; i < samplerRange; i++) - { - GLenum textureType = programBinary->getSamplerTextureType(type, i); - GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps()); - if (textureUnit != -1) - { - Texture* texture = getSamplerTexture(textureUnit, textureType); - if (texture->getSamplerState().swizzleRequired()) - { - Error error = mRenderer->generateSwizzle(texture); - if (error.isError()) - { - return error; - } - } - } - } - - return Error(GL_NO_ERROR); -} - -Error Context::generateSwizzles(ProgramBinary *programBinary) -{ - Error error = generateSwizzles(programBinary, SAMPLER_VERTEX); - if (error.isError()) - { - return error; - } - - error = generateSwizzles(programBinary, SAMPLER_PIXEL); - if (error.isError()) - { - return error; - } - - return Error(GL_NO_ERROR); -} - -// For each Direct3D sampler of either the pixel or vertex stage, -// looks up the corresponding OpenGL texture image unit and texture type, -// and sets the texture and its addressing/filtering state (or NULL when inactive). -Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType, - const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount) -{ - size_t samplerRange = programBinary->getUsedSamplerRange(shaderType); - for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) - { - GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex); - GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps()); - if (textureUnit != -1) - { - SamplerState sampler; - Texture* texture = getSamplerTexture(textureUnit, textureType); - texture->getSamplerStateWithNativeOffset(&sampler); - - Sampler *samplerObject = mState.getSampler(textureUnit); - if (samplerObject) - { - samplerObject->getState(&sampler); - } - - // TODO: std::binary_search may become unavailable using older versions of GCC - if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) && - !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial())) - { - Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler); - if (error.isError()) - { - return error; - } - - error = mRenderer->setTexture(shaderType, samplerIndex, texture); - if (error.isError()) - { - return error; - } - } - else - { - // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. - Texture *incompleteTexture = getIncompleteTexture(textureType); - gl::Error error = mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture); - if (error.isError()) - { - return error; - } - } - } - else - { - // No texture bound to this slot even though it is used by the shader, bind a NULL texture - Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } - } - - // Set all the remaining textures to NULL - size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits - : mCaps.maxVertexTextureImageUnits; - for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) - { - Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } - - return Error(GL_NO_ERROR); -} - -Error Context::applyTextures(ProgramBinary *programBinary) -{ - FramebufferTextureSerialArray framebufferSerials; - size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials); - - Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - return Error(GL_NO_ERROR); -} - -Error Context::applyUniformBuffers() -{ - Program *programObject = getProgram(mState.getCurrentProgramId()); - ProgramBinary *programBinary = programObject->getProgramBinary(); - - std::vector<Buffer*> boundBuffers; - - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++) - { - GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex); - - if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0) - { - // undefined behaviour - return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer."); - } - else - { - Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding); - ASSERT(uniformBuffer); - boundBuffers.push_back(uniformBuffer); - } - } - - return programBinary->applyUniformBuffers(boundBuffers, getCaps()); -} - -bool Context::applyTransformFeedbackBuffers() -{ - TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) - { - Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) - { - transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i); - transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i); - } - mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets); - return true; - } - else - { - return false; - } -} - -void Context::markTransformFeedbackUsage() -{ - for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) - { - Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i); - if (buffer) - { - buffer->markTransformFeedbackUsage(); - } - } -} - Error Context::clear(GLbitfield mask) { if (mState.isRasterizerDiscardEnabled()) @@ -1619,290 +1299,71 @@ Error Context::clear(GLbitfield mask) return Error(GL_NO_ERROR); } - ClearParameters clearParams = mState.getClearParameters(mask); - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clear(getData(), mask); } -Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) +Error Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferfv can be called to clear the color buffer or depth buffer - ClearParameters clearParams = mState.getClearParameters(0); - - if (buffer == GL_COLOR) - { - for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) - { - clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); - } - clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_FLOAT; - } - - if (buffer == GL_DEPTH) - { - clearParams.clearDepth = true; - clearParams.depthClearValue = values[0]; - } - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferfv(getData(), buffer, drawbuffer, values); } -Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values) +Error Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferuv can only be called to clear a color buffer - ClearParameters clearParams = mState.getClearParameters(0); - for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) - { - clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); - } - clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_UNSIGNED_INT; - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferuiv(getData(), buffer, drawbuffer, values); } -Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) +Error Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferfv can be called to clear the color buffer or stencil buffer - ClearParameters clearParams = mState.getClearParameters(0); - - if (buffer == GL_COLOR) - { - for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) - { - clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); - } - clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_INT; - } - - if (buffer == GL_STENCIL) - { - clearParams.clearStencil = true; - clearParams.stencilClearValue = values[1]; - } - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferiv(getData(), buffer, drawbuffer, values); } -Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil) +Error Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferfi can only be called to clear a depth stencil buffer - ClearParameters clearParams = mState.getClearParameters(0); - clearParams.clearDepth = true; - clearParams.depthClearValue = depth; - clearParams.clearStencil = true; - clearParams.stencilClearValue = stencil; - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferfi(getData(), buffer, drawbuffer, depth, stencil); } Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels) { - Framebuffer *framebuffer = mState.getReadFramebuffer(); - - GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); - const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat); - GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment()); - - return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), - reinterpret_cast<uint8_t*>(pixels)); + return mRenderer->readPixels(getData(), x, y, width, height, format, type, bufSize, pixels); } Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) { - ASSERT(mState.getCurrentProgramId() != 0); - - ProgramBinary *programBinary = mState.getCurrentProgramBinary(); - programBinary->updateSamplerMapping(); - - Error error = generateSwizzles(programBinary); - if (error.isError()) - { - return error; - } - - if (!mRenderer->applyPrimitiveType(mode, count)) - { - return Error(GL_NO_ERROR); - } - - error = applyRenderTarget(mode, false); - if (error.isError()) - { - return error; - } - - error = applyState(mode); - if (error.isError()) - { - return error; - } - - error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances); - if (error.isError()) - { - return error; - } - - bool transformFeedbackActive = applyTransformFeedbackBuffers(); - - error = applyShaders(programBinary, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - error = applyTextures(programBinary); - if (error.isError()) - { - return error; - } - - error = applyUniformBuffers(); - if (error.isError()) - { - return error; - } - - if (!skipDraw(mode)) - { - error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - if (transformFeedbackActive) - { - markTransformFeedbackUsage(); - } - } - - return gl::Error(GL_NO_ERROR); + return mRenderer->drawArrays(getData(), mode, first, count, instances); } Error Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances, const rx::RangeUI &indexRange) { - ASSERT(mState.getCurrentProgramId() != 0); - - ProgramBinary *programBinary = mState.getCurrentProgramBinary(); - programBinary->updateSamplerMapping(); - - Error error = generateSwizzles(programBinary); - if (error.isError()) - { - return error; - } - - if (!mRenderer->applyPrimitiveType(mode, count)) - { - return Error(GL_NO_ERROR); - } - - error = applyRenderTarget(mode, false); - if (error.isError()) - { - return error; - } - - error = applyState(mode); - if (error.isError()) - { - return error; - } - - VertexArray *vao = mState.getVertexArray(); - rx::TranslatedIndexData indexInfo; - indexInfo.indexRange = indexRange; - error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo); - if (error.isError()) - { - return error; - } - - GLsizei vertexCount = indexInfo.indexRange.length() + 1; - error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), - mState.getVertexAttribCurrentValues(), - indexInfo.indexRange.start, vertexCount, instances); - if (error.isError()) - { - return error; - } - - bool transformFeedbackActive = applyTransformFeedbackBuffers(); - // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation - // layer. - ASSERT(!transformFeedbackActive); - - error = applyShaders(programBinary, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - error = applyTextures(programBinary); - if (error.isError()) - { - return error; - } - - error = applyUniformBuffers(); - if (error.isError()) - { - return error; - } - - if (!skipDraw(mode)) - { - error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); - if (error.isError()) - { - return error; - } - } - - return Error(GL_NO_ERROR); + return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange); } // Implements glFlush when block is false, glFinish when block is true -void Context::sync(bool block) +Error Context::sync(bool block) { - mRenderer->sync(block); + return mRenderer->sync(block); } void Context::recordError(const Error &error) @@ -1931,6 +1392,7 @@ GLenum Context::getError() GLenum Context::getResetStatus() { + //TODO(jmadill): needs MANGLE reworking if (mResetStatus == GL_NO_ERROR && !mContextLost) { // mResetStatus will be set by the markContextLost callback @@ -1981,7 +1443,7 @@ const Extensions &Context::getExtensions() const void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type) { Framebuffer *framebuffer = mState.getReadFramebuffer(); - ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE); + ASSERT(framebuffer && framebuffer->completeness(getData()) == GL_FRAMEBUFFER_COMPLETE); FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); ASSERT(attachment); @@ -2000,7 +1462,7 @@ void Context::detachTexture(GLuint texture) // allocation map management either here or in the resource manager at detach time. // Zero textures are held by the Context, and we don't attempt to request them from // the State. - mState.detachTexture(texture); + mState.detachTexture(mZeroTextures, texture); } void Context::detachBuffer(GLuint buffer) @@ -2072,95 +1534,6 @@ void Context::detachSampler(GLuint sampler) mState.detachSampler(sampler); } -Texture *Context::getIncompleteTexture(GLenum type) -{ - if (mIncompleteTextures.find(type) == mIncompleteTextures.end()) - { - const GLubyte color[] = { 0, 0, 0, 255 }; - const PixelUnpackState incompleteUnpackState(1); - - Texture* t = NULL; - switch (type) - { - default: - UNREACHABLE(); - // default falls through to TEXTURE_2D - - case GL_TEXTURE_2D: - { - Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID); - incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - t = incomplete2d; - } - break; - - case GL_TEXTURE_CUBE_MAP: - { - TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID); - - incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - - t = incompleteCube; - } - break; - - case GL_TEXTURE_3D: - { - Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID); - incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - - t = incomplete3d; - } - break; - - case GL_TEXTURE_2D_ARRAY: - { - Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID); - incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - - t = incomplete2darray; - } - break; - } - - mIncompleteTextures[type].set(t); - } - - return mIncompleteTextures[type].get(); -} - -bool Context::skipDraw(GLenum drawMode) -{ - if (drawMode == GL_POINTS) - { - // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, - // which affects varying interpolation. Since the value of gl_PointSize is - // undefined when not written, just skip drawing to avoid unexpected results. - if (!mState.getCurrentProgramBinary()->usesPointSize()) - { - // This is stictly speaking not an error, but developers should be - // notified of risking undefined behavior. - ERR("Point rendering without writing to gl_PointSize."); - - return true; - } - } - else if (IsTriangleMode(drawMode)) - { - if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK) - { - return true; - } - } - - return false; -} - void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) { mState.getVertexArray()->setVertexAttribDivisor(index, divisor); @@ -2293,63 +1666,12 @@ size_t Context::getExtensionStringCount() const return mExtensionStrings.size(); } -size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray) +Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { - size_t serialCount = 0; - - Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); - for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) - { - FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); - if (attachment && attachment->isTexture()) - { - Texture *texture = attachment->getTexture(); - (*outSerialArray)[serialCount++] = texture->getTextureSerial(); - } - } - - FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); - if (depthStencilAttachment && depthStencilAttachment->isTexture()) - { - Texture *depthStencilTexture = depthStencilAttachment->getTexture(); - (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial(); - } - - std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount); - - return serialCount; -} - -void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - Framebuffer *readFramebuffer = mState.getReadFramebuffer(); - Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); - - bool blitRenderTarget = false; - bool blitDepth = false; - bool blitStencil = false; - if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer()) - { - blitRenderTarget = true; - } - if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) - { - blitStencil = true; - } - if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) - { - blitDepth = true; - } - - Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); - Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); - if (blitRenderTarget || blitDepth || blitStencil) - { - const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL; - mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor, - blitRenderTarget, blitDepth, blitStencil, filter); - } + return mRenderer->blitFramebuffer(getData(), srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); } void Context::releaseShaderCompiler() @@ -2416,6 +1738,11 @@ void Context::initCaps(GLuint clientVersion) mExtensions.maxSamples = maxSamples; } +Data Context::getData() const +{ + return Data(mClientVersion, mState, mCaps, mTextureCaps, mExtensions, mResourceManager); +} + } extern "C" diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h index 1b888aec83..1e890de3ef 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.h +++ b/src/3rdparty/angle/src/libGLESv2/Context.h @@ -13,12 +13,12 @@ #include "common/angleutils.h" #include "common/RefCountObject.h" #include "libGLESv2/Caps.h" +#include "libGLESv2/Constants.h" +#include "libGLESv2/Data.h" #include "libGLESv2/Error.h" #include "libGLESv2/HandleAllocator.h" -#include "libGLESv2/angletypes.h" -#include "libGLESv2/Constants.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/State.h" +#include "libGLESv2/angletypes.h" #include "angle_gl.h" @@ -50,11 +50,6 @@ class Texture3D; class Texture2DArray; class Framebuffer; class Renderbuffer; -class RenderbufferStorage; -class Colorbuffer; -class Depthbuffer; -class Stencilbuffer; -class DepthStencilbuffer; class FenceNV; class FenceSync; class Query; @@ -68,7 +63,7 @@ class TransformFeedback; class Context { public: - Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); + Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); virtual ~Context(); @@ -86,7 +81,7 @@ class Context GLuint createRenderbuffer(); GLuint createSampler(); GLuint createTransformFeedback(); - GLsync createFenceSync(GLenum condition); + GLsync createFenceSync(); void deleteBuffer(GLuint buffer); void deleteShader(GLuint shader); @@ -115,7 +110,7 @@ class Context void bindArrayBuffer(GLuint buffer); void bindElementArrayBuffer(GLuint buffer); - void bindTexture(GLenum target, GLuint texture); + void bindTexture(GLenum target, GLuint handle); void bindReadFramebuffer(GLuint framebuffer); void bindDrawFramebuffer(GLuint framebuffer); void bindRenderbuffer(GLuint renderbuffer); @@ -130,8 +125,8 @@ class Context void bindPixelPackBuffer(GLuint buffer); void bindPixelUnpackBuffer(GLuint buffer); void useProgram(GLuint program); - void linkProgram(GLuint program); - void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length); + Error linkProgram(GLuint program); + Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length); void bindTransformFeedback(GLuint transformFeedback); Error beginQuery(GLenum target, GLuint query); @@ -139,8 +134,6 @@ class Context void setFramebufferZero(Framebuffer *framebuffer); - void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples); - void setVertexAttribDivisor(GLuint index, GLuint divisor); void samplerParameteri(GLuint sampler, GLenum pname, GLint param); @@ -183,17 +176,17 @@ class Context bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams); Error clear(GLbitfield mask); - Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values); - Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values); - Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values); - Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil); + Error clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values); + Error clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values); + Error clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values); + Error clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels); Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances); Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances, const rx::RangeUI &indexRange); - void sync(bool block); // flush/finish + Error sync(bool block); // flush/finish void recordError(const Error &error); @@ -215,32 +208,21 @@ class Context void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type); - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); + Error blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); rx::Renderer *getRenderer() { return mRenderer; } State &getState() { return mState; } const State &getState() const { return mState; } + Data getData() const; + void releaseShaderCompiler(); private: DISALLOW_COPY_AND_ASSIGN(Context); - // TODO: std::array may become unavailable using older versions of GCC - typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray; - - Error applyRenderTarget(GLenum drawMode, bool ignoreViewport); - Error applyState(GLenum drawMode); - Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive); - Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials, - size_t framebufferSerialCount); - Error applyTextures(ProgramBinary *programBinary); - Error applyUniformBuffers(); - bool applyTransformFeedbackBuffers(); - void markTransformFeedbackUsage(); - void detachBuffer(GLuint buffer); void detachTexture(GLuint texture); void detachFramebuffer(GLuint framebuffer); @@ -249,18 +231,9 @@ class Context void detachTransformFeedback(GLuint transformFeedback); void detachSampler(GLuint sampler); - Error generateSwizzles(ProgramBinary *programBinary, SamplerType type); - Error generateSwizzles(ProgramBinary *programBinary); - - Texture *getIncompleteTexture(GLenum type); - - bool skipDraw(GLenum drawMode); - void initRendererString(); void initExtensionStrings(); - size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray); - void initCaps(GLuint clientVersion); // Caps to use for validation @@ -273,7 +246,6 @@ class Context int mClientVersion; - typedef std::map< GLenum, BindingPointer<Texture> > TextureMap; TextureMap mZeroTextures; TextureMap mIncompleteTextures; diff --git a/src/3rdparty/angle/src/libGLESv2/Data.cpp b/src/3rdparty/angle/src/libGLESv2/Data.cpp new file mode 100644 index 0000000000..3ddf591d77 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/Data.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Data.cpp: Container class for all GL relevant state, caps and objects + +#include "libGLESv2/Data.h" +#include "libGLESv2/ResourceManager.h" + +namespace gl +{ + +Data::Data(GLint clientVersionIn, const State &stateIn, const Caps &capsIn, + const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn, + const ResourceManager *resourceManagerIn) + : clientVersion(clientVersionIn), + state(&stateIn), + caps(&capsIn), + textureCaps(&textureCapsIn), + extensions(&extensionsIn), + resourceManager(resourceManagerIn) +{} + +Data::~Data() +{ +} + +Data::Data(const Data &other) + : clientVersion(other.clientVersion), + state(other.state), + caps(other.caps), + textureCaps(other.textureCaps), + extensions(other.extensions), + resourceManager(other.resourceManager) +{ +} + +Data &Data::operator=(const Data &other) +{ + clientVersion = other.clientVersion; + state = other.state; + caps = other.caps; + textureCaps = other.textureCaps; + extensions = other.extensions; + resourceManager = other.resourceManager; + return *this; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h new file mode 100644 index 0000000000..9234403e13 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/Data.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Data.h: Container class for all GL relevant state, caps and objects + +#ifndef LIBGLESV2_DATA_H_ +#define LIBGLESV2_DATA_H_ + +#include "libGLESv2/State.h" + +namespace gl +{ + +struct Data +{ + public: + Data(GLint clientVersion, const State &state, const Caps &caps, + const TextureCapsMap &textureCaps, const Extensions &extensions, + const ResourceManager *resourceManager); + ~Data(); + + Data(const Data &other); + Data &operator=(const Data &other); + + GLint clientVersion; + const State *state; + const Caps *caps; + const TextureCapsMap *textureCaps; + const Extensions *extensions; + const ResourceManager *resourceManager; +}; + +} + +#endif // LIBGLESV2_DATA_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libGLESv2/Fence.cpp index ee9a07a5c4..966a327de5 100644 --- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Fence.cpp @@ -4,191 +4,113 @@ // found in the LICENSE file. // -// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension. - -// Important note on accurate timers in Windows: -// -// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call -// as timeGetTime on laptops and "jumping" during certain hardware events. -// -// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc" -// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc -// -// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer -// from buggy implementations. +// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence +// extension and GLES3 sync objects. #include "libGLESv2/Fence.h" #include "libGLESv2/renderer/FenceImpl.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/main.h" +#include "common/utilities.h" #include "angle_gl.h" namespace gl { -FenceNV::FenceNV(rx::Renderer *renderer) +FenceNV::FenceNV(rx::FenceNVImpl *impl) + : mFence(impl), + mIsSet(false), + mStatus(GL_FALSE), + mCondition(GL_NONE) { - mFence = renderer->createFence(); } FenceNV::~FenceNV() { - delete mFence; + SafeDelete(mFence); } GLboolean FenceNV::isFence() const { // GL_NV_fence spec: // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. - return (mFence->isSet() ? GL_TRUE : GL_FALSE); + return (mIsSet ? GL_TRUE : GL_FALSE); } -void FenceNV::setFence(GLenum condition) +Error FenceNV::setFence(GLenum condition) { - mFence->set(); + Error error = mFence->set(); + if (error.isError()) + { + return error; + } mCondition = condition; mStatus = GL_FALSE; -} - -GLboolean FenceNV::testFence() -{ - // Flush the command buffer by default - bool result = mFence->test(true); + mIsSet = true; - mStatus = (result ? GL_TRUE : GL_FALSE); - return mStatus; + return Error(GL_NO_ERROR); } -void FenceNV::finishFence() +Error FenceNV::testFence(GLboolean *outResult) { - ASSERT(mFence->isSet()); - - while (!mFence->test(true)) + // Flush the command buffer by default + Error error = mFence->test(true, &mStatus); + if (error.isError()) { - Sleep(0); + return error; } -} - -GLint FenceNV::getFencei(GLenum pname) -{ - ASSERT(mFence->isSet()); - switch (pname) - { - case GL_FENCE_STATUS_NV: - { - // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. - if (mStatus == GL_TRUE) - { - return GL_TRUE; - } - - mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE); - return mStatus; - } - - case GL_FENCE_CONDITION_NV: - return mCondition; - - default: UNREACHABLE(); return 0; - } + *outResult = mStatus; + return Error(GL_NO_ERROR); } -FenceSync::FenceSync(rx::Renderer *renderer, GLuint id) - : RefCountObject(id) +Error FenceNV::finishFence() { - mFence = renderer->createFence(); - - LARGE_INTEGER counterFreqency = { 0 }; - BOOL success = QueryPerformanceFrequency(&counterFreqency); - UNUSED_ASSERTION_VARIABLE(success); - ASSERT(success); + ASSERT(mIsSet); - mCounterFrequency = counterFreqency.QuadPart; + return mFence->finishFence(&mStatus); } -FenceSync::~FenceSync() +FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id) + : RefCountObject(id), + mFence(impl), + mCondition(GL_NONE) { - delete mFence; } -void FenceSync::set(GLenum condition) +FenceSync::~FenceSync() { - mCondition = condition; - mFence->set(); + SafeDelete(mFence); } -GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout) +Error FenceSync::set(GLenum condition) { - ASSERT(mFence->isSet()); - - bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); - - if (mFence->test(flushCommandBuffer)) + Error error = mFence->set(); + if (error.isError()) { - return GL_ALREADY_SIGNALED; + return error; } - if (mFence->hasError()) - { - return GL_WAIT_FAILED; - } - - if (timeout == 0) - { - return GL_TIMEOUT_EXPIRED; - } - - LARGE_INTEGER currentCounter = { 0 }; - BOOL success = QueryPerformanceCounter(¤tCounter); - UNUSED_ASSERTION_VARIABLE(success); - ASSERT(success); - - LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll); - LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; - - while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer)) - { - Sleep(0); - BOOL success = QueryPerformanceCounter(¤tCounter); - UNUSED_ASSERTION_VARIABLE(success); - ASSERT(success); - } - - if (mFence->hasError()) - { - return GL_WAIT_FAILED; - } - - if (currentCounter.QuadPart >= endCounter) - { - return GL_TIMEOUT_EXPIRED; - } - - return GL_CONDITION_SATISFIED; + mCondition = condition; + return Error(GL_NO_ERROR); } -void FenceSync::serverWait() +Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) { - // Because our API is currently designed to be called from a single thread, we don't need to do - // extra work for a server-side fence. GPU commands issued after the fence is created will always - // be processed after the fence is signaled. + ASSERT(mCondition != GL_NONE); + return mFence->clientWait(flags, timeout, outResult); } -GLenum FenceSync::getStatus() const +Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout) { - if (mFence->test(false)) - { - // The spec does not specify any way to report errors during the status test (e.g. device lost) - // so we report the fence is unblocked in case of error or signaled. - return GL_SIGNALED; - } + return mFence->serverWait(flags, timeout); +} - return GL_UNSIGNALED; +Error FenceSync::getStatus(GLint *outResult) const +{ + return mFence->getStatus(outResult); } } diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.h b/src/3rdparty/angle/src/libGLESv2/Fence.h index 291edb3de1..fd565e96a6 100644 --- a/src/3rdparty/angle/src/libGLESv2/Fence.h +++ b/src/3rdparty/angle/src/libGLESv2/Fence.h @@ -4,18 +4,21 @@ // found in the LICENSE file. // -// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension. +// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence +// extension and GLES3 sync objects. #ifndef LIBGLESV2_FENCE_H_ #define LIBGLESV2_FENCE_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" #include "common/RefCountObject.h" namespace rx { -class Renderer; -class FenceImpl; +class FenceNVImpl; +class FenceSyncImpl; } namespace gl @@ -24,14 +27,13 @@ namespace gl class FenceNV { public: - explicit FenceNV(rx::Renderer *renderer); + explicit FenceNV(rx::FenceNVImpl *impl); virtual ~FenceNV(); GLboolean isFence() const; - void setFence(GLenum condition); - GLboolean testFence(); - void finishFence(); - GLint getFencei(GLenum pname); + Error setFence(GLenum condition); + Error testFence(GLboolean *outResult); + Error finishFence(); GLboolean getStatus() const { return mStatus; } GLuint getCondition() const { return mCondition; } @@ -39,7 +41,9 @@ class FenceNV private: DISALLOW_COPY_AND_ASSIGN(FenceNV); - rx::FenceImpl *mFence; + rx::FenceNVImpl *mFence; + + bool mIsSet; GLboolean mStatus; GLenum mCondition; @@ -48,21 +52,20 @@ class FenceNV class FenceSync : public RefCountObject { public: - explicit FenceSync(rx::Renderer *renderer, GLuint id); + explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id); virtual ~FenceSync(); - void set(GLenum condition); - GLenum clientWait(GLbitfield flags, GLuint64 timeout); - void serverWait(); - GLenum getStatus() const; + Error set(GLenum condition); + Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult); + Error serverWait(GLbitfield flags, GLuint64 timeout); + Error getStatus(GLint *outResult) const; GLuint getCondition() const { return mCondition; } private: DISALLOW_COPY_AND_ASSIGN(FenceSync); - rx::FenceImpl *mFence; - LONGLONG mCounterFrequency; + rx::FenceSyncImpl *mFence; GLenum mCondition; }; diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp index 5b21433f90..3d57262e3c 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp @@ -16,13 +16,18 @@ #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/RenderTarget.h" +#include "libGLESv2/renderer/RenderbufferImpl.h" +#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" #include "common/utilities.h" namespace rx { -RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +// TODO: Move these functions, and the D3D-specific header inclusions above, +// to FramebufferD3D. +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT) { if (attachment->isTexture()) { @@ -31,14 +36,16 @@ RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); const gl::ImageIndex *index = attachment->getTextureImageIndex(); ASSERT(index); - return textureD3D->getRenderTarget(*index); + return textureD3D->getRenderTarget(*index, outRT); + } + else + { + gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); + ASSERT(renderbuffer); + RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation()); + *outRT = renderbufferD3D->getRenderTarget(); + return gl::Error(GL_NO_ERROR); } - - gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); - ASSERT(renderbuffer); - - // TODO: cast to RenderbufferD3D - return renderbuffer->getStorage()->getRenderTarget(); } // Note: RenderTarget serials should ideally be in the RenderTargets themselves. @@ -56,9 +63,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment) gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); ASSERT(renderbuffer); - - // TODO: cast to RenderbufferD3D - return renderbuffer->getStorage()->getSerial(); + RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation()); + return renderbufferD3D->getRenderTargetSerial(); } } @@ -66,9 +72,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment) namespace gl { -Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id) - : mRenderer(renderer), - mId(id), +Framebuffer::Framebuffer(GLuint id) + : mId(id), mReadBufferState(GL_COLOR_ATTACHMENT0_EXT), mDepthbuffer(NULL), mStencilbuffer(NULL) @@ -91,124 +96,6 @@ Framebuffer::~Framebuffer() SafeDelete(mStencilbuffer); } -FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const -{ - if (handle == 0) - { - return NULL; - } - - gl::Context *context = gl::getContext(); - - switch (type) - { - case GL_NONE: - return NULL; - - case GL_RENDERBUFFER: - return new RenderbufferAttachment(binding, context->getRenderbuffer(handle)); - - case GL_TEXTURE_2D: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_2D) - { - return new TextureAttachment(binding, texture, ImageIndex::Make2D(level)); - } - else - { - return NULL; - } - } - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP) - { - return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level)); - } - else - { - return NULL; - } - } - - case GL_TEXTURE_3D: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_3D) - { - return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer)); - } - else - { - return NULL; - } - } - - case GL_TEXTURE_2D_ARRAY: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY) - { - return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer)); - } - else - { - return NULL; - } - } - - default: - UNREACHABLE(); - return NULL; - } -} - -void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer) -{ - ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - SafeDelete(mColorbuffers[colorAttachment]); - GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0; - mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer); -} - -void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer) -{ - SafeDelete(mDepthbuffer); - mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer); -} - -void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer) -{ - SafeDelete(mStencilbuffer); - mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer); -} - -void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer) -{ - FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer); - - SafeDelete(mDepthbuffer); - SafeDelete(mStencilbuffer); - - // ensure this is a legitimate depth+stencil format - if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0) - { - mDepthbuffer = attachment; - - // Make a new attachment object to ensure we do not double-delete - // See angle issue 686 - mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer); - } -} - void Framebuffer::detachTexture(GLuint textureId) { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) @@ -382,14 +269,13 @@ bool Framebuffer::usingExtendedDrawBuffers() const return false; } -GLenum Framebuffer::completeness() const +GLenum Framebuffer::completeness(const gl::Data &data) const { int width = 0; int height = 0; unsigned int colorbufferSize = 0; int samples = -1; bool missingAttachment = true; - GLuint clientVersion = mRenderer->getCurrentClientVersion(); for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { @@ -403,8 +289,7 @@ GLenum Framebuffer::completeness() const } GLenum internalformat = colorbuffer->getInternalFormat(); - // TODO(geofflang): use context's texture caps - const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat); + const TextureCaps &formatCaps = data.textureCaps->get(internalformat); const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); if (colorbuffer->isTexture()) { @@ -443,7 +328,7 @@ GLenum Framebuffer::completeness() const // in GLES 2.0, all color attachments attachments must have the same number of bitplanes // in GLES 3.0, there is no such restriction - if (clientVersion < 3) + if (data.clientVersion < 3) { if (formatInfo.pixelBytes != colorbufferSize) { @@ -483,14 +368,12 @@ GLenum Framebuffer::completeness() const } GLenum internalformat = mDepthbuffer->getInternalFormat(); - // TODO(geofflang): use context's texture caps - const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat); + const TextureCaps &formatCaps = data.textureCaps->get(internalformat); const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); if (mDepthbuffer->isTexture()) { // depth texture attachments require OES/ANGLE_depth_texture - // TODO(geofflang): use context's extensions - if (!mRenderer->getRendererExtensions().depthTextures) + if (!data.extensions->depthTextures) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -538,15 +421,13 @@ GLenum Framebuffer::completeness() const } GLenum internalformat = mStencilbuffer->getInternalFormat(); - // TODO(geofflang): use context's texture caps - const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat); + const TextureCaps &formatCaps = data.textureCaps->get(internalformat); const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); if (mStencilbuffer->isTexture()) { // texture stencil attachments come along as part // of OES_packed_depth_stencil + OES/ANGLE_depth_texture - // TODO(geofflang): use context's extensions - if (!mRenderer->getRendererExtensions().depthTextures) + if (!data.extensions->depthTextures) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -602,42 +483,44 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_COMPLETE; } -void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments) +Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments) { GLuint maxDimension = caps.maxRenderbufferSize; - invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension); + return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension); } -void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments, - GLint x, GLint y, GLsizei width, GLsizei height) +Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) { - ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE); for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex) { GLenum attachmentTarget = attachments[attachIndex]; - gl::FramebufferAttachment *attachment = - (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() : - getAttachment(attachmentTarget); + FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() + : getAttachment(attachmentTarget); if (attachment) { - rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); - if (renderTarget) + rx::RenderTarget *renderTarget = NULL; + Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - renderTarget->invalidate(x, y, width, height); + return error; } + + renderTarget->invalidate(x, y, width, height); } } + + return Error(GL_NO_ERROR); } -DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) - : Framebuffer(renderer, 0) +DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil) + : Framebuffer(0) { - Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer); + Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0); mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer); - Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil); + Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0); // Make a new attachment objects to ensure we do not double-delete // See angle issue 686 @@ -648,9 +531,9 @@ DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colo mReadBufferState = GL_BACK; } -int Framebuffer::getSamples() const +int Framebuffer::getSamples(const gl::Data &data) const { - if (completeness() == GL_FRAMEBUFFER_COMPLETE) + if (completeness(data) == GL_FRAMEBUFFER_COMPLETE) { // for a complete framebuffer, all attachments must have the same sample count // in this case return the first nonzero sample size @@ -675,7 +558,7 @@ bool Framebuffer::hasValidDepthStencil() const mDepthbuffer->id() == mStencilbuffer->id()); } -ColorbufferInfo Framebuffer::getColorbuffersForRender() const +ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const { ColorbufferInfo colorbuffersForRender; @@ -689,18 +572,78 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender() const ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment)); colorbuffersForRender.push_back(colorbuffer); } -#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED) - else + else if (!workarounds.mrtPerfWorkaround) { colorbuffersForRender.push_back(NULL); } -#endif } return colorbuffersForRender; } -GLenum DefaultFramebuffer::completeness() const +void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex) +{ + setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex)); +} + +void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer) +{ + setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer)); +} + +void Framebuffer::setNULLAttachment(GLenum attachment) +{ + setAttachment(attachment, NULL); +} + +void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj) +{ + if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS)) + { + size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0; + SafeDelete(mColorbuffers[colorAttachment]); + mColorbuffers[colorAttachment] = attachmentObj; + } + else if (attachment == GL_DEPTH_ATTACHMENT) + { + SafeDelete(mDepthbuffer); + mDepthbuffer = attachmentObj; + } + else if (attachment == GL_STENCIL_ATTACHMENT) + { + SafeDelete(mStencilbuffer); + mStencilbuffer = attachmentObj; + } + else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + { + SafeDelete(mDepthbuffer); + SafeDelete(mStencilbuffer); + + // ensure this is a legitimate depth+stencil format + if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0) + { + mDepthbuffer = attachmentObj; + + // Make a new attachment object to ensure we do not double-delete + // See angle issue 686 + if (attachmentObj->isTexture()) + { + mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(), + *attachmentObj->getTextureImageIndex()); + } + else + { + mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer()); + } + } + } + else + { + UNREACHABLE(); + } +} + +GLenum DefaultFramebuffer::completeness(const gl::Data &) const { // The default framebuffer *must* always be complete, though it may not be // subject to the same rules as application FBOs. ie, it could have 0x0 size. diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h index cc12d22953..d0fe8935ea 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h @@ -10,41 +10,44 @@ #ifndef LIBGLESV2_FRAMEBUFFER_H_ #define LIBGLESV2_FRAMEBUFFER_H_ -#include <vector> +#include "libGLESv2/Error.h" #include "common/angleutils.h" #include "common/RefCountObject.h" -#include "constants.h" +#include "Constants.h" + +#include <vector> namespace rx { -class Renderer; +class RenderbufferImpl; +struct Workarounds; } namespace gl { class FramebufferAttachment; -class Colorbuffer; -class Depthbuffer; -class Stencilbuffer; -class DepthStencilbuffer; +class Texture; +class Renderbuffer; +struct ImageIndex; struct Caps; +struct Extensions; +class TextureCapsMap; +struct Data; typedef std::vector<FramebufferAttachment *> ColorbufferInfo; class Framebuffer { public: - Framebuffer(rx::Renderer *renderer, GLuint id); - + Framebuffer(GLuint id); virtual ~Framebuffer(); GLuint id() const { return mId; } - void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer); - void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer); - void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer); - void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer); + void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex); + void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer); + void setNULLAttachment(GLenum attachment); void detachTexture(GLuint texture); void detachRenderbuffer(GLuint renderbuffer); @@ -66,24 +69,21 @@ class Framebuffer bool isEnabledColorAttachment(unsigned int colorAttachment) const; bool hasEnabledColorAttachment() const; bool hasStencil() const; - int getSamples() const; + int getSamples(const gl::Data &data) const; bool usingExtendedDrawBuffers() const; - virtual GLenum completeness() const; + virtual GLenum completeness(const gl::Data &data) const; bool hasValidDepthStencil() const; - void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments); - void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments, - GLint x, GLint y, GLsizei width, GLsizei height); + Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments); + Error invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); // Use this method to retrieve the color buffer map when doing rendering. // It will apply a workaround for poor shader performance on some systems // by compacting the list to skip NULL values. - ColorbufferInfo getColorbuffersForRender() const; + ColorbufferInfo getColorbuffersForRender(const rx::Workarounds &workarounds) const; protected: - rx::Renderer *mRenderer; - GLuint mId; FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS]; @@ -96,15 +96,15 @@ class Framebuffer private: DISALLOW_COPY_AND_ASSIGN(Framebuffer); - FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const; + void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj); }; class DefaultFramebuffer : public Framebuffer { public: - DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil); + DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil); - virtual GLenum completeness() const; + GLenum completeness(const gl::Data &data) const override; virtual FramebufferAttachment *getAttachment(GLenum attachment) const; private: @@ -118,7 +118,7 @@ namespace rx class RenderTarget; // TODO: place this in FramebufferD3D.h -RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT); unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment); } diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp index 540ede1cd2..894884a6d8 100644 --- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp +++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp @@ -187,7 +187,7 @@ GLenum RenderbufferAttachment::getActualFormat() const GLsizei RenderbufferAttachment::getSamples() const { - return mRenderbuffer->getStorage()->getSamples(); + return mRenderbuffer->getSamples(); } GLuint RenderbufferAttachment::id() const diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h index c18ef7364d..8d2dafa7ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h +++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h @@ -16,13 +16,6 @@ #include "angle_gl.h" -namespace rx -{ -class Renderer; -class RenderTarget; -class TextureStorage; -} - namespace gl { class Renderbuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp index 3522b997e8..b45cd9c169 100644 --- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp @@ -48,10 +48,101 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex) return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex); } +ImageIndex ImageIndex::MakeInvalid() +{ + return ImageIndex(GL_NONE, -1, -1); +} + ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn) : type(typeIn), mipIndex(mipIndexIn), layerIndex(layerIndexIn) {} +ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(GL_TEXTURE_2D, rx::Range<GLint>(minMip, maxMip), + rx::Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL); +} + +ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(0, 6), NULL); +} + +ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip, + GLint minLayer, GLint maxLayer) +{ + return ImageIndexIterator(GL_TEXTURE_3D, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(minLayer, maxLayer), NULL); +} + +ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, + const GLsizei *layerCounts) +{ + return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range<GLint>(minMip, maxMip), + rx::Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts); +} + +ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange, + const rx::Range<GLint> &layerRange, const GLsizei *layerCounts) + : mType(type), + mMipRange(mipRange), + mLayerRange(layerRange), + mLayerCounts(layerCounts), + mCurrentMip(mipRange.start), + mCurrentLayer(layerRange.start) +{} + +GLint ImageIndexIterator::maxLayer() const +{ + return (mLayerCounts ? static_cast<GLint>(mLayerCounts[mCurrentMip]) : mLayerRange.end); +} + +ImageIndex ImageIndexIterator::next() +{ + ASSERT(hasNext()); + + ImageIndex value = current(); + + // Iterate layers in the inner loop for now. We can add switchable + // layer or mip iteration if we need it. + + if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL) + { + if (mCurrentLayer < maxLayer()-1) + { + mCurrentLayer++; + } + else if (mCurrentMip < mMipRange.end-1) + { + mCurrentMip++; + mCurrentLayer = mLayerRange.start; + } + } + else if (mCurrentMip < mMipRange.end-1) + { + mCurrentMip++; + mCurrentLayer = mLayerRange.start; + } + + return value; +} + +ImageIndex ImageIndexIterator::current() const +{ + ImageIndex value(mType, mCurrentMip, mCurrentLayer); + + if (mType == GL_TEXTURE_CUBE_MAP) + { + value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer); + } + + return value; +} + +bool ImageIndexIterator::hasNext() const +{ + return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer()); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h index 9f2df88061..8bb14fd555 100644 --- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h +++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h @@ -10,6 +10,7 @@ #define LIBGLESV2_IMAGE_INDEX_H_ #include "angle_gl.h" +#include "common/mathutil.h" namespace gl { @@ -20,6 +21,7 @@ struct ImageIndex GLint mipIndex; GLint layerIndex; + ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn); ImageIndex(const ImageIndex &other); ImageIndex &operator=(const ImageIndex &other); @@ -29,11 +31,36 @@ struct ImageIndex static ImageIndex MakeCube(GLenum target, GLint mipIndex); static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex); static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL); + static ImageIndex MakeInvalid(); static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1); +}; + +class ImageIndexIterator +{ + public: + static ImageIndexIterator Make2D(GLint minMip, GLint maxMip); + static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip); + static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer); + static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts); + + ImageIndex next(); + ImageIndex current() const; + bool hasNext() const; private: - ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn); + + ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange, + const rx::Range<GLint> &layerRange, const GLsizei *layerCounts); + + GLint maxLayer() const; + + GLenum mType; + rx::Range<GLint> mMipRange; + rx::Range<GLint> mLayerRange; + const GLsizei *mLayerCounts; + GLint mCurrentMip; + GLint mCurrentLayer; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp index 9bfda09a64..3faa8c56f6 100644 --- a/src/3rdparty/angle/src/libGLESv2/Program.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Program.cpp @@ -244,7 +244,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name) // Links the HLSL code of the vertex and pixel shader by matching up their varyings, // compiling them into binaries, determining the attribute mappings, and collecting // a list of uniforms -bool Program::link(const Caps &caps) +Error Program::link(const Data &data) { unlink(false); @@ -252,10 +252,15 @@ bool Program::link(const Caps &caps) resetUniformBlockBindings(); mProgramBinary.set(new ProgramBinary(mRenderer->createProgram())); - mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader, - mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps); + LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader, + mTransformFeedbackVaryings, mTransformFeedbackBufferMode); + if (result.error.isError()) + { + return result.error; + } - return mLinked; + mLinked = result.linkSuccess; + return gl::Error(GL_NO_ERROR); } int AttributeBindings::getAttributeBinding(const std::string &name) const @@ -303,21 +308,22 @@ ProgramBinary* Program::getProgramBinary() const return mProgramBinary.get(); } -bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length) +Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length) { unlink(false); mInfoLog.reset(); mProgramBinary.set(new ProgramBinary(mRenderer->createProgram())); - mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length); - - if (!mLinked) + LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length); + if (result.error.isError()) { mProgramBinary.set(NULL); + return result.error; } - return mLinked; + mLinked = result.linkSuccess; + return Error(GL_NO_ERROR); } void Program::release() diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h index 6528dd1191..b92349eeef 100644 --- a/src/3rdparty/angle/src/libGLESv2/Program.h +++ b/src/3rdparty/angle/src/libGLESv2/Program.h @@ -29,6 +29,7 @@ class Renderer; namespace gl { struct Caps; +struct Data; class ResourceManager; class Shader; @@ -77,9 +78,9 @@ class Program void bindAttributeLocation(GLuint index, const char *name); - bool link(const Caps &caps); + Error link(const Data &data); bool isLinked(); - bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length); + Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length); ProgramBinary *getProgramBinary() const; int getInfoLogLength() const; diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp index 3f6d9e0ef9..6d64b38b56 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp @@ -23,13 +23,11 @@ #include "libGLESv2/Shader.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/ProgramImpl.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/d3d/DynamicHLSL.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/Context.h" #include "libGLESv2/Buffer.h" #include "common/blocklayout.h" +#include "common/features.h" namespace gl { @@ -37,36 +35,6 @@ namespace gl namespace { -GLenum GetTextureType(GLenum samplerType) -{ - switch (samplerType) - { - case GL_SAMPLER_2D: - case GL_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_SAMPLER_2D_SHADOW: - return GL_TEXTURE_2D; - case GL_SAMPLER_3D: - case GL_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_3D: - return GL_TEXTURE_3D; - case GL_SAMPLER_CUBE: - case GL_SAMPLER_CUBE_SHADOW: - return GL_TEXTURE_CUBE_MAP; - case GL_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - return GL_TEXTURE_CUBE_MAP; - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - return GL_TEXTURE_2D_ARRAY; - default: UNREACHABLE(); - } - - return GL_TEXTURE_2D; -} - unsigned int ParseAndStripArrayIndex(std::string* name) { unsigned int subscript = GL_INVALID_INDEX; @@ -83,52 +51,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name) return subscript; } -void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) -{ - size_t layoutIndex = 0; - for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) - { - ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS); - - const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex]; - - if (shaderAttr.type != GL_NONE) - { - GLenum transposedType = TransposeMatrixType(shaderAttr.type); - - for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++) - { - VertexFormat *defaultFormat = &inputLayout[layoutIndex]; - - defaultFormat->mType = VariableComponentType(transposedType); - defaultFormat->mNormalized = false; - defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool - defaultFormat->mComponents = VariableColumnCount(transposedType); - } - } - } -} - -std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars) -{ - std::vector<GLenum> defaultPixelOutput(1); - - ASSERT(!shaderOutputVars.empty()); - defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex; - - return defaultPixelOutput; -} - -bool IsRowMajorLayout(const sh::InterfaceBlockField &var) -{ - return var.isRowMajorLayout; -} - -bool IsRowMajorLayout(const sh::ShaderVariable &var) -{ - return false; -} - } VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index) @@ -136,47 +58,6 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element { } -ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[], - const GLenum signature[], - rx::ShaderExecutable *shaderExecutable) - : mShaderExecutable(shaderExecutable) -{ - for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) - { - mInputs[attributeIndex] = inputLayout[attributeIndex]; - mSignature[attributeIndex] = signature[attributeIndex]; - } -} - -ProgramBinary::VertexExecutable::~VertexExecutable() -{ - SafeDelete(mShaderExecutable); -} - -bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const -{ - for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) - { - if (mSignature[attributeIndex] != signature[attributeIndex]) - { - return false; - } - } - - return true; -} - -ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable) - : mOutputSignature(outputSignature), - mShaderExecutable(shaderExecutable) -{ -} - -ProgramBinary::PixelExecutable::~PixelExecutable() -{ - SafeDelete(mShaderExecutable); -} - LinkedVarying::LinkedVarying() { } @@ -187,17 +68,17 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, { } +LinkResult::LinkResult(bool linkSuccess, const Error &error) + : linkSuccess(linkSuccess), + error(error) +{ +} + unsigned int ProgramBinary::mCurrentSerial = 1; ProgramBinary::ProgramBinary(rx::ProgramImpl *impl) : RefCountObject(0), mProgram(impl), - mGeometryExecutable(NULL), - mUsedVertexSamplerRange(0), - mUsedPixelSamplerRange(0), - mUsesPointSize(false), - mShaderVersion(100), - mDirtySamplerMapping(true), mValidated(false), mSerial(issueSerial()) { @@ -220,103 +101,11 @@ unsigned int ProgramBinary::getSerial() const return mSerial; } -int ProgramBinary::getShaderVersion() const -{ - return mShaderVersion; -} - unsigned int ProgramBinary::issueSerial() { return mCurrentSerial++; } -rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo) -{ - std::vector<GLenum> outputs; - - const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(); - - for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) - { - const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - - if (colorbuffer) - { - outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding()); - } - else - { - outputs.push_back(GL_NONE); - } - } - - return getPixelExecutableForOutputLayout(outputs); -} - -rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature) -{ - for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) - { - if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature)) - { - return mPixelExecutables[executableIndex]->shaderExecutable(); - } - } - - InfoLog tempInfoLog; - rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature, - mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!pixelExecutable) - { - std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); - } - else - { - mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable)); - } - - return pixelExecutable; -} - -rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) -{ - GLenum signature[MAX_VERTEX_ATTRIBS]; - mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature); - - for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) - { - if (mVertexExecutables[executableIndex]->matchesSignature(signature)) - { - return mVertexExecutables[executableIndex]->shaderExecutable(); - } - } - - InfoLog tempInfoLog; - rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes, - mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!vertexExecutable) - { - std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3); - tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); - } - else - { - mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable)); - } - - return vertexExecutable; -} - -rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const -{ - return mGeometryExecutable; -} - GLuint ProgramBinary::getAttributeLocation(const char *name) { if (name) @@ -343,157 +132,42 @@ int ProgramBinary::getSemanticIndex(int attributeIndex) // Returns one more than the highest sampler index used. GLint ProgramBinary::getUsedSamplerRange(SamplerType type) { - switch (type) - { - case SAMPLER_PIXEL: - return mUsedPixelSamplerRange; - case SAMPLER_VERTEX: - return mUsedVertexSamplerRange; - default: - UNREACHABLE(); - return 0; - } + return mProgram->getUsedSamplerRange(type); } bool ProgramBinary::usesPointSize() const { - return mUsesPointSize; -} - -bool ProgramBinary::usesPointSpriteEmulation() const -{ - return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4; -} - -bool ProgramBinary::usesGeometryShader() const -{ - return usesPointSpriteEmulation(); + return mProgram->usesPointSize(); } GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps) { - GLint logicalTextureUnit = -1; - - switch (type) - { - case SAMPLER_PIXEL: - ASSERT(samplerIndex < caps.maxTextureImageUnits); - if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) - { - logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; - } - break; - case SAMPLER_VERTEX: - ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); - if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) - { - logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; - } - break; - default: UNREACHABLE(); - } - - if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits)) - { - return logicalTextureUnit; - } - - return -1; + return mProgram->getSamplerMapping(type, samplerIndex, caps); } -// Returns the texture type for a given Direct3D 9 sampler type and -// index (0-15 for the pixel shader and 0-3 for the vertex shader). GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) { - switch (type) - { - case SAMPLER_PIXEL: - ASSERT(samplerIndex < mSamplersPS.size()); - ASSERT(mSamplersPS[samplerIndex].active); - return mSamplersPS[samplerIndex].textureType; - case SAMPLER_VERTEX: - ASSERT(samplerIndex < mSamplersVS.size()); - ASSERT(mSamplersVS[samplerIndex].active); - return mSamplersVS[samplerIndex].textureType; - default: UNREACHABLE(); - } - - return GL_TEXTURE_2D; + return mProgram->getSamplerTextureType(type, samplerIndex); } GLint ProgramBinary::getUniformLocation(std::string name) { - unsigned int subscript = ParseAndStripArrayIndex(&name); - - unsigned int numUniforms = mUniformIndex.size(); - for (unsigned int location = 0; location < numUniforms; location++) - { - if (mUniformIndex[location].name == name) - { - const int index = mUniformIndex[location].index; - const bool isArray = mUniforms[index]->isArray(); - - if ((isArray && mUniformIndex[location].element == subscript) || - (subscript == GL_INVALID_INDEX)) - { - return location; - } - } - } - - return -1; + return mProgram->getUniformLocation(name); } GLuint ProgramBinary::getUniformIndex(std::string name) { - unsigned int subscript = ParseAndStripArrayIndex(&name); - - // The app is not allowed to specify array indices other than 0 for arrays of basic types - if (subscript != 0 && subscript != GL_INVALID_INDEX) - { - return GL_INVALID_INDEX; - } - - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) - { - if (mUniforms[index]->name == name) - { - if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) - { - return index; - } - } - } - - return GL_INVALID_INDEX; + return mProgram->getUniformIndex(name); } GLuint ProgramBinary::getUniformBlockIndex(std::string name) { - unsigned int subscript = ParseAndStripArrayIndex(&name); - - unsigned int numUniformBlocks = mUniformBlocks.size(); - for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) - { - const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; - if (uniformBlock.name == name) - { - const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); - if (subscript == uniformBlock.elementIndex || arrayElementZero) - { - return blockIndex; - } - } - } - - return GL_INVALID_INDEX; + return mProgram->getUniformBlockIndex(name); } UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex) { - ASSERT(blockIndex < mUniformBlocks.size()); - return mUniformBlocks[blockIndex]; + return mProgram->getUniformBlockByIndex(blockIndex); } GLint ProgramBinary::getFragDataLocation(const char *name) const @@ -517,524 +191,129 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const size_t ProgramBinary::getTransformFeedbackVaryingCount() const { - return mTransformFeedbackLinkedVaryings.size(); + return mProgram->getTransformFeedbackLinkedVaryings().size(); } const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const { - return mTransformFeedbackLinkedVaryings[idx]; + return mProgram->getTransformFeedbackLinkedVaryings()[idx]; } GLenum ProgramBinary::getTransformFeedbackBufferMode() const { - return mTransformFeedbackBufferMode; -} - -template <typename T> -static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) -{ - ASSERT(dest != NULL); - ASSERT(dirtyFlag != NULL); - - *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); - *dest = source; -} - -template <typename T> -void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) -{ - const int components = VariableComponentCount(targetUniformType); - const GLenum targetBoolType = VariableBoolVectorType(targetUniformType); - - LinkedUniform *targetUniform = getUniformByLocation(location); - - int elementCount = targetUniform->elementCount(); - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - - if (targetUniform->type == targetUniformType) - { - T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - T *dest = target + (i * 4); - const T *source = v + (i * components); - - for (int c = 0; c < components; c++) - { - SetIfDirty(dest + c, source[c], &targetUniform->dirty); - } - for (int c = components; c < 4; c++) - { - SetIfDirty(dest + c, T(0), &targetUniform->dirty); - } - } - } - else if (targetUniform->type == targetBoolType) - { - GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - GLint *dest = boolParams + (i * 4); - const T *source = v + (i * components); - - for (int c = 0; c < components; c++) - { - SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); - } - for (int c = components; c < 4; c++) - { - SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty); - } - } - } - else if (IsSampler(targetUniform->type)) - { - ASSERT(targetUniformType == GL_INT); - - GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4; - - bool wasDirty = targetUniform->dirty; - - for (int i = 0; i < count; i++) - { - GLint *dest = target + (i * 4); - const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components); - - SetIfDirty(dest + 0, source[0], &targetUniform->dirty); - SetIfDirty(dest + 1, 0, &targetUniform->dirty); - SetIfDirty(dest + 2, 0, &targetUniform->dirty); - SetIfDirty(dest + 3, 0, &targetUniform->dirty); - } - - if (!wasDirty && targetUniform->dirty) - { - mDirtySamplerMapping = true; - } - } - else UNREACHABLE(); -} - -void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) -{ - setUniform(location, count, v, GL_FLOAT); + return mProgram->getTransformFeedbackBufferMode(); } -void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) -{ - setUniform(location, count, v, GL_FLOAT_VEC2); -} - -void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) -{ - setUniform(location, count, v, GL_FLOAT_VEC3); -} - -void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) -{ - setUniform(location, count, v, GL_FLOAT_VEC4); -} - -template<typename T> -bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetHeight, srcWidth); - int copyHeight = std::min(targetWidth, srcHeight); - - for (int x = 0; x < copyWidth; x++) - { - for (int y = 0; y < copyHeight; y++) - { - SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyWidth; y++) - { - for (int x = copyHeight; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyWidth; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); - } - } - - return dirty; -} - -template<typename T> -bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetWidth, srcWidth); - int copyHeight = std::min(targetHeight, srcHeight); - - for (int y = 0; y < copyHeight; y++) - { - for (int x = 0; x < copyWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyHeight; y++) - { - for (int x = copyWidth; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyHeight; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); - } - } - - return dirty; +void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform1fv(location, count, v); } -template <int cols, int rows> -void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) -{ - LinkedUniform *targetUniform = getUniformByLocation(location); - - int elementCount = targetUniform->elementCount(); - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - const unsigned int targetMatrixStride = (4 * rows); - GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); - - for (int i = 0; i < count; i++) - { - // Internally store matrices as transposed versions to accomodate HLSL matrix indexing - if (transpose == GL_FALSE) - { - targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty; - } - else - { - targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty; - } - target += targetMatrixStride; - value += cols * rows; - } +void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform2fv(location, count, v); } -void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); +void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform3fv(location, count, v); } -void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); +void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform4fv(location, count, v); } -void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); +void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform1iv(location, count, v); } -void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); +void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform2iv(location, count, v); } -void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); +void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform3iv(location, count, v); } -void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); +void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform4iv(location, count, v); } -void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); +void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform1uiv(location, count, v); } -void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); +void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform2uiv(location, count, v); } -void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); +void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform3uiv(location, count, v); } -void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT); +void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform4uiv(location, count, v); } -void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT_VEC2); +void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix2fv(location, count, transpose, v); } -void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT_VEC3); +void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix3fv(location, count, transpose, v); } -void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT_VEC4); +void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix4fv(location, count, transpose, v); } -void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT); +void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix2x3fv(location, count, transpose, v); } -void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); +void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix2x4fv(location, count, transpose, v); } -void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); +void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix3x2fv(location, count, transpose, v); } -void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); +void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix3x4fv(location, count, transpose, v); } -template <typename T> -void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType) -{ - LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - if (IsMatrixType(targetUniform->type)) - { - const int rows = VariableRowCount(targetUniform->type); - const int cols = VariableColumnCount(targetUniform->type); - transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); - } - else if (uniformType == VariableComponentType(targetUniform->type)) - { - unsigned int size = VariableComponentCount(targetUniform->type); - memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), - size * sizeof(T)); - } - else - { - unsigned int size = VariableComponentCount(targetUniform->type); - switch (VariableComponentType(targetUniform->type)) - { - case GL_BOOL: - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1); - } - } - break; - - case GL_FLOAT: - { - GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast<T>(floatParams[i]); - } - } - break; - - case GL_INT: - { - GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast<T>(intParams[i]); - } - } - break; - - case GL_UNSIGNED_INT: - { - GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast<T>(uintParams[i]); - } - } - break; - - default: UNREACHABLE(); - } - } +void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix4x2fv(location, count, transpose, v); } -void ProgramBinary::getUniformfv(GLint location, GLfloat *params) -{ - getUniformv(location, params, GL_FLOAT); +void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix4x3fv(location, count, transpose, v); } -void ProgramBinary::getUniformiv(GLint location, GLint *params) -{ - getUniformv(location, params, GL_INT); +void ProgramBinary::getUniformfv(GLint location, GLfloat *v) { + mProgram->getUniformfv(location, v); } -void ProgramBinary::getUniformuiv(GLint location, GLuint *params) -{ - getUniformv(location, params, GL_UNSIGNED_INT); +void ProgramBinary::getUniformiv(GLint location, GLint *v) { + mProgram->getUniformiv(location, v); } -void ProgramBinary::dirtyAllUniforms() -{ - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) - { - mUniforms[index]->dirty = true; - } +void ProgramBinary::getUniformuiv(GLint location, GLuint *v) { + mProgram->getUniformuiv(location, v); } void ProgramBinary::updateSamplerMapping() { - if (!mDirtySamplerMapping) - { - return; - } - - mDirtySamplerMapping = false; - - // Retrieve sampler uniform values - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - LinkedUniform *targetUniform = mUniforms[uniformIndex]; - - if (targetUniform->dirty) - { - if (IsSampler(targetUniform->type)) - { - int count = targetUniform->elementCount(); - GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data); - - if (targetUniform->isReferencedByFragmentShader()) - { - unsigned int firstIndex = targetUniform->psRegisterIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < mSamplersPS.size()) - { - ASSERT(mSamplersPS[samplerIndex].active); - mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; - } - } - } - - if (targetUniform->isReferencedByVertexShader()) - { - unsigned int firstIndex = targetUniform->vsRegisterIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < mSamplersVS.size()) - { - ASSERT(mSamplersVS[samplerIndex].active); - mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; - } - } - } - } - } - } + return mProgram->updateSamplerMapping(); } // Applies all the uniforms set for this program object to the renderer Error ProgramBinary::applyUniforms() { - updateSamplerMapping(); - - Error error = mProgram->getRenderer()->applyUniforms(*this); - if (error.isError()) - { - return error; - } - - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - mUniforms[uniformIndex]->dirty = false; - } - - return gl::Error(GL_NO_ERROR); + return mProgram->applyUniforms(); } Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps) { - const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL}; - const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL}; - - const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers(); - const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers(); - - ASSERT(boundBuffers.size() == mUniformBlocks.size()); - - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) - { - UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex); - gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex]; - - ASSERT(uniformBlock && uniformBuffer); - - if (uniformBuffer->getSize() < uniformBlock->dataSize) - { - // undefined behaviour - return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."); - } - - // Unnecessary to apply an unreferenced standard or shared UBO - if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader()) - { - continue; - } - - if (uniformBlock->isReferencedByVertexShader()) - { - unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; - ASSERT(vertexUniformBuffers[registerIndex] == NULL); - ASSERT(registerIndex < caps.maxVertexUniformBlocks); - vertexUniformBuffers[registerIndex] = uniformBuffer; - } - - if (uniformBlock->isReferencedByFragmentShader()) - { - unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; - ASSERT(fragmentUniformBuffers[registerIndex] == NULL); - ASSERT(registerIndex < caps.maxFragmentUniformBlocks); - fragmentUniformBuffers[registerIndex] = uniformBuffer; - } - } - - return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers); + return mProgram->applyUniformBuffers(boundBuffers, caps); } bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader) @@ -1082,10 +361,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade return true; } -bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length) +LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length) { -#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD - return false; +#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_DISABLED + return LinkResult(false, Error(GL_NO_ERROR)); #else ASSERT(binaryFormat == mProgram->getBinaryFormat()); @@ -1097,7 +376,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina if (format != mProgram->getBinaryFormat()) { infoLog.append("Invalid program binary format."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } int majorVersion = stream.readInt<int>(); @@ -1105,7 +384,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) { infoLog.append("Invalid program binary version."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; @@ -1113,250 +392,38 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) { infoLog.append("Invalid program binary version."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } int compileFlags = stream.readInt<int>(); if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) { infoLog.append("Mismatched compilation flags."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) { stream.readInt(&mLinkedAttribute[i].type); stream.readString(&mLinkedAttribute[i].name); - stream.readInt(&mShaderAttributes[i].type); - stream.readString(&mShaderAttributes[i].name); + stream.readInt(&mProgram->getShaderAttributes()[i].type); + stream.readString(&mProgram->getShaderAttributes()[i].name); stream.readInt(&mSemanticIndex[i]); } initAttributesByLayout(); - const unsigned int psSamplerCount = stream.readInt<unsigned int>(); - for (unsigned int i = 0; i < psSamplerCount; ++i) - { - Sampler sampler; - stream.readBool(&sampler.active); - stream.readInt(&sampler.logicalTextureUnit); - stream.readInt(&sampler.textureType); - mSamplersPS.push_back(sampler); - } - const unsigned int vsSamplerCount = stream.readInt<unsigned int>(); - for (unsigned int i = 0; i < vsSamplerCount; ++i) - { - Sampler sampler; - stream.readBool(&sampler.active); - stream.readInt(&sampler.logicalTextureUnit); - stream.readInt(&sampler.textureType); - mSamplersVS.push_back(sampler); - } - - stream.readInt(&mUsedVertexSamplerRange); - stream.readInt(&mUsedPixelSamplerRange); - stream.readBool(&mUsesPointSize); - stream.readInt(&mShaderVersion); - - const unsigned int uniformCount = stream.readInt<unsigned int>(); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; - } - - mUniforms.resize(uniformCount); - for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) - { - GLenum type = stream.readInt<GLenum>(); - GLenum precision = stream.readInt<GLenum>(); - std::string name = stream.readString(); - unsigned int arraySize = stream.readInt<unsigned int>(); - int blockIndex = stream.readInt<int>(); - - int offset = stream.readInt<int>(); - int arrayStride = stream.readInt<int>(); - int matrixStride = stream.readInt<int>(); - bool isRowMajorMatrix = stream.readBool(); - - const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); - - LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); - - stream.readInt(&uniform->psRegisterIndex); - stream.readInt(&uniform->vsRegisterIndex); - stream.readInt(&uniform->registerCount); - stream.readInt(&uniform->registerElement); - - mUniforms[uniformIndex] = uniform; - } - - unsigned int uniformBlockCount = stream.readInt<unsigned int>(); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; - } - - mUniformBlocks.resize(uniformBlockCount); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) - { - std::string name = stream.readString(); - unsigned int elementIndex = stream.readInt<unsigned int>(); - unsigned int dataSize = stream.readInt<unsigned int>(); - - UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize); - - stream.readInt(&uniformBlock->psRegisterIndex); - stream.readInt(&uniformBlock->vsRegisterIndex); - - unsigned int numMembers = stream.readInt<unsigned int>(); - uniformBlock->memberUniformIndexes.resize(numMembers); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) - { - stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); - } - - mUniformBlocks[uniformBlockIndex] = uniformBlock; - } - - const unsigned int uniformIndexCount = stream.readInt<unsigned int>(); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; - } - - mUniformIndex.resize(uniformIndexCount); - for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) - { - stream.readString(&mUniformIndex[uniformIndexIndex].name); - stream.readInt(&mUniformIndex[uniformIndexIndex].element); - stream.readInt(&mUniformIndex[uniformIndexIndex].index); - } - - stream.readInt(&mTransformFeedbackBufferMode); - const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>(); - mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); - for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) - { - LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; - - stream.readString(&varying.name); - stream.readInt(&varying.type); - stream.readInt(&varying.size); - stream.readString(&varying.semanticName); - stream.readInt(&varying.semanticIndex); - stream.readInt(&varying.semanticIndexCount); - } - - const unsigned int vertexShaderCount = stream.readInt<unsigned int>(); - for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) - { - VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; - - for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++) - { - VertexFormat *vertexInput = &inputLayout[inputIndex]; - stream.readInt(&vertexInput->mType); - stream.readInt(&vertexInput->mNormalized); - stream.readInt(&vertexInput->mComponents); - stream.readBool(&vertexInput->mPureInteger); - } - - unsigned int vertexShaderSize = stream.readInt<unsigned int>(); - const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset(); - rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction), - vertexShaderSize, rx::SHADER_VERTEX, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - if (!shaderExecutable) - { - infoLog.append("Could not create vertex shader."); - return false; - } - - // generated converted input layout - GLenum signature[MAX_VERTEX_ATTRIBS]; - mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature); - - // add new binary - mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable)); - - stream.skip(vertexShaderSize); - } - - const size_t pixelShaderCount = stream.readInt<unsigned int>(); - for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++) + LinkResult result = mProgram->load(infoLog, &stream); + if (result.error.isError() || !result.linkSuccess) { - const size_t outputCount = stream.readInt<unsigned int>(); - std::vector<GLenum> outputs(outputCount); - for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++) - { - stream.readInt(&outputs[outputIndex]); - } - - const size_t pixelShaderSize = stream.readInt<unsigned int>(); - const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset(); - rx::Renderer *renderer = mProgram->getRenderer(); - rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize, - rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!shaderExecutable) - { - infoLog.append("Could not create pixel shader."); - return false; - } - - // add new binary - mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable)); - - stream.skip(pixelShaderSize); + return result; } - unsigned int geometryShaderSize = stream.readInt<unsigned int>(); - - if (geometryShaderSize > 0) - { - const char *geometryShaderFunction = (const char*) binary + stream.offset(); - rx::Renderer *renderer = mProgram->getRenderer(); - mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction), - geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!mGeometryExecutable) - { - infoLog.append("Could not create geometry shader."); - return false; - } - stream.skip(geometryShaderSize); - } - - if (!mProgram->load(infoLog, &stream)) - { - return false; - } - - const char *ptr = (const char*) binary + stream.offset(); - - const GUID *binaryIdentifier = (const GUID *) ptr; - ptr += sizeof(GUID); - - GUID identifier = mProgram->getRenderer()->getAdapterIdentifier(); - if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0) - { - infoLog.append("Invalid program binary."); - return false; - } - - mProgram->initializeUniformStorage(mUniforms); - - return true; -#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD + return LinkResult(true, Error(GL_NO_ERROR)); +#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED } -bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) +Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) { if (binaryFormat) { @@ -1375,168 +442,27 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL { stream.writeInt(mLinkedAttribute[i].type); stream.writeString(mLinkedAttribute[i].name); - stream.writeInt(mShaderAttributes[i].type); - stream.writeString(mShaderAttributes[i].name); + stream.writeInt(mProgram->getShaderAttributes()[i].type); + stream.writeString(mProgram->getShaderAttributes()[i].name); stream.writeInt(mSemanticIndex[i]); } - stream.writeInt(mSamplersPS.size()); - for (unsigned int i = 0; i < mSamplersPS.size(); ++i) - { - stream.writeInt(mSamplersPS[i].active); - stream.writeInt(mSamplersPS[i].logicalTextureUnit); - stream.writeInt(mSamplersPS[i].textureType); - } - - stream.writeInt(mSamplersVS.size()); - for (unsigned int i = 0; i < mSamplersVS.size(); ++i) - { - stream.writeInt(mSamplersVS[i].active); - stream.writeInt(mSamplersVS[i].logicalTextureUnit); - stream.writeInt(mSamplersVS[i].textureType); - } - - stream.writeInt(mUsedVertexSamplerRange); - stream.writeInt(mUsedPixelSamplerRange); - stream.writeInt(mUsesPointSize); - stream.writeInt(mShaderVersion); - - stream.writeInt(mUniforms.size()); - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) - { - const LinkedUniform &uniform = *mUniforms[uniformIndex]; - - stream.writeInt(uniform.type); - stream.writeInt(uniform.precision); - stream.writeString(uniform.name); - stream.writeInt(uniform.arraySize); - stream.writeInt(uniform.blockIndex); - - stream.writeInt(uniform.blockInfo.offset); - stream.writeInt(uniform.blockInfo.arrayStride); - stream.writeInt(uniform.blockInfo.matrixStride); - stream.writeInt(uniform.blockInfo.isRowMajorMatrix); - - stream.writeInt(uniform.psRegisterIndex); - stream.writeInt(uniform.vsRegisterIndex); - stream.writeInt(uniform.registerCount); - stream.writeInt(uniform.registerElement); - } - - stream.writeInt(mUniformBlocks.size()); - for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) - { - const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; - - stream.writeString(uniformBlock.name); - stream.writeInt(uniformBlock.elementIndex); - stream.writeInt(uniformBlock.dataSize); - - stream.writeInt(uniformBlock.memberUniformIndexes.size()); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) - { - stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); - } - - stream.writeInt(uniformBlock.psRegisterIndex); - stream.writeInt(uniformBlock.vsRegisterIndex); - } - - stream.writeInt(mUniformIndex.size()); - for (size_t i = 0; i < mUniformIndex.size(); ++i) - { - stream.writeString(mUniformIndex[i].name); - stream.writeInt(mUniformIndex[i].element); - stream.writeInt(mUniformIndex[i].index); - } - - stream.writeInt(mTransformFeedbackBufferMode); - stream.writeInt(mTransformFeedbackLinkedVaryings.size()); - for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) - { - const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; - - stream.writeString(varying.name); - stream.writeInt(varying.type); - stream.writeInt(varying.size); - stream.writeString(varying.semanticName); - stream.writeInt(varying.semanticIndex); - stream.writeInt(varying.semanticIndexCount); - } - - stream.writeInt(mVertexExecutables.size()); - for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) - { - VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; - - for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) - { - const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; - stream.writeInt(vertexInput.mType); - stream.writeInt(vertexInput.mNormalized); - stream.writeInt(vertexInput.mComponents); - stream.writeInt(vertexInput.mPureInteger); - } - - size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); - stream.writeInt(vertexShaderSize); - - const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction(); - stream.writeBytes(vertexBlob, vertexShaderSize); - } - - stream.writeInt(mPixelExecutables.size()); - for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) - { - PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; - - const std::vector<GLenum> outputs = pixelExecutable->outputSignature(); - stream.writeInt(outputs.size()); - for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++) - { - stream.writeInt(outputs[outputIndex]); - } - - size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength(); - stream.writeInt(pixelShaderSize); - - const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction(); - stream.writeBytes(pixelBlob, pixelShaderSize); - } - - size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; - stream.writeInt(geometryShaderSize); - - if (mGeometryExecutable != NULL && geometryShaderSize > 0) - { - const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); - stream.writeBytes(geometryBlob, geometryShaderSize); - } - - if (!mProgram->save(&stream)) - { - if (length) - { - *length = 0; - } - - return false; - } - - GUID identifier = mProgram->getRenderer()->getAdapterIdentifier(); + mProgram->save(&stream); GLsizei streamLength = stream.length(); const void *streamData = stream.data(); - GLsizei totalLength = streamLength + sizeof(GUID); - if (totalLength > bufSize) + if (streamLength > bufSize) { if (length) { *length = 0; } - return false; + // TODO: This should be moved to the validation layer but computing the size of the binary before saving + // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate + // sizes and then copy it. + return Error(GL_INVALID_OPERATION); } if (binary) @@ -1546,129 +472,197 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL memcpy(ptr, streamData, streamLength); ptr += streamLength; - memcpy(ptr, &identifier, sizeof(GUID)); - ptr += sizeof(GUID); - - ASSERT(ptr - totalLength == binary); + ASSERT(ptr - streamLength == binary); } if (length) { - *length = totalLength; + *length = streamLength; } - return true; + return Error(GL_NO_ERROR); } GLint ProgramBinary::getLength() { GLint length; - if (save(NULL, NULL, INT_MAX, &length)) - { - return length; - } - else + Error error = save(NULL, NULL, INT_MAX, &length); + if (error.isError()) { return 0; } + + return length; } -bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader, - const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps) +LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings, + Shader *fragmentShader, Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode) { if (!fragmentShader || !fragmentShader->isCompiled()) { - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER); if (!vertexShader || !vertexShader->isCompiled()) { - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } ASSERT(vertexShader->getType() == GL_VERTEX_SHADER); reset(); - mSamplersPS.resize(caps.maxTextureImageUnits); - mSamplersVS.resize(caps.maxVertexTextureImageUnits); + int registers; + std::vector<LinkedVarying> linkedVaryings; + LinkResult result = mProgram->link(data, infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode, + ®isters, &linkedVaryings, &mOutputVariables); + if (result.error.isError() || !result.linkSuccess) + { + return result; + } - mTransformFeedbackBufferMode = transformFeedbackBufferMode; + if (!linkAttributes(infoLog, attributeBindings, vertexShader)) + { + return LinkResult(false, Error(GL_NO_ERROR)); + } - rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); - rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps)) + { + return LinkResult(false, Error(GL_NO_ERROR)); + } - mShaderVersion = vertexShaderD3D->getShaderVersion(); + if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps)) + { + return LinkResult(false, Error(GL_NO_ERROR)); + } - int registers; - std::vector<LinkedVarying> linkedVaryings; - if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, ®isters, &linkedVaryings, &mOutputVariables)) + if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings, + transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps)) { - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } - mUsesPointSize = vertexShaderD3D->usesPointSize(); + // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called, + // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling. + result = mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers); + if (result.error.isError() || !result.linkSuccess) + { + infoLog.append("Failed to create D3D shaders."); + reset(); + return result; + } - bool success = true; + return LinkResult(true, Error(GL_NO_ERROR)); +} - if (!linkAttributes(infoLog, attributeBindings, vertexShader)) +bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps) +{ + const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); + const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); + + // Check that interface blocks defined in the vertex and fragment shaders are identical + typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap; + UniformBlockMap linkedUniformBlocks; + + for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) { - success = false; + const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; + linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; } - if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps)) + for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) { - success = false; + const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; + UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); + if (entry != linkedUniformBlocks.end()) + { + const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; + if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) + { + return false; + } + } } - // special case for gl_DepthRange, the only built-in uniform (also a struct) - if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange()) + for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) { - const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo(); + const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; - mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo)); - mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo)); - mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo)); + // Note: shared and std140 layouts are always considered active + if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + { + if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) + { + return false; + } + } } - if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps)) + for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) { - success = false; + const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex]; + + // Note: shared and std140 layouts are always considered active + if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + { + if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) + { + return false; + } + } } - if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings, - transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps)) + return true; +} + +bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock) +{ + const char* blockName = vertexInterfaceBlock.name.c_str(); + + // validate blocks for the same member types + if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) { - success = false; + infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); + return false; } - if (success) + if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) { - VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS]; - GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); - rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout); + infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); + return false; + } - std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey()); - rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput); + if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) + { + infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); + return false; + } - if (usesGeometryShader()) + const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) + { + const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; + const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; + + if (vertexMember.name != fragmentMember.name) { - std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); - mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(), - rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - rx::ANGLE_D3D_WORKAROUND_NONE); + infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", + blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); + return false; } - if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) + std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; + if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) { - infoLog.append("Failed to create D3D shaders."); - success = false; - reset(); + return false; } } - return success; + return true; } // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices @@ -1688,7 +682,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; - mShaderAttributes[attributeIndex] = attribute; + mProgram->getShaderAttributes()[attributeIndex] = attribute; if (location != -1) // Set by glBindAttribLocation or by location layout qualifier { @@ -1708,7 +702,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at // In GLSL 3.00, attribute aliasing produces a link error // In GLSL 1.00, attribute aliasing is allowed - if (mShaderVersion >= 300) + if (mProgram->getShaderVersion() >= 300) { if (!linkedAttribute.name.empty()) { @@ -1856,346 +850,6 @@ bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std return true; } -bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) -{ - const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation()); - const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation()); - - const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms(); - const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms(); - - // Check that uniforms defined in the vertex and fragment shaders are identical - typedef std::map<std::string, const sh::Uniform*> UniformMap; - UniformMap linkedUniforms; - - for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) - { - const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; - linkedUniforms[vertexUniform.name] = &vertexUniform; - } - - for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) - { - const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; - UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); - if (entry != linkedUniforms.end()) - { - const sh::Uniform &vertexUniform = *entry->second; - const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; - if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform)) - { - return false; - } - } - } - - for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) - { - const sh::Uniform &uniform = vertexUniforms[uniformIndex]; - - if (uniform.staticUse) - { - defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); - } - } - - for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) - { - const sh::Uniform &uniform = fragmentUniforms[uniformIndex]; - - if (uniform.staticUse) - { - defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); - } - } - - if (!indexUniforms(infoLog, caps)) - { - return false; - } - - mProgram->initializeUniformStorage(mUniforms); - - return true; -} - -void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister) -{ - ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader); - sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); - encoder.skipRegisters(uniformRegister); - - defineUniform(shader, uniform, uniform.name, &encoder); -} - -void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, - const std::string &fullName, sh::HLSLBlockEncoder *encoder) -{ - if (uniform.isStruct()) - { - for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) - { - const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); - - encoder->enterAggregateType(); - - for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) - { - const sh::ShaderVariable &field = uniform.fields[fieldIndex]; - const std::string &fieldFullName = (fullName + elementString + "." + field.name); - - defineUniform(shader, field, fieldFullName, encoder); - } - - encoder->exitAggregateType(); - } - } - else // Not a struct - { - // Arrays are treated as aggregate types - if (uniform.isArray()) - { - encoder->enterAggregateType(); - } - - LinkedUniform *linkedUniform = getUniformByName(fullName); - - if (!linkedUniform) - { - linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, - -1, sh::BlockMemberInfo::getDefaultBlockInfo()); - ASSERT(linkedUniform); - linkedUniform->registerElement = encoder->getCurrentElement(); - mUniforms.push_back(linkedUniform); - } - - ASSERT(linkedUniform->registerElement == encoder->getCurrentElement()); - - if (shader == GL_FRAGMENT_SHADER) - { - linkedUniform->psRegisterIndex = encoder->getCurrentRegister(); - } - else if (shader == GL_VERTEX_SHADER) - { - linkedUniform->vsRegisterIndex = encoder->getCurrentRegister(); - } - else UNREACHABLE(); - - // Advance the uniform offset, to track registers allocation for structs - encoder->encodeType(uniform.type, uniform.arraySize, false); - - // Arrays are treated as aggregate types - if (uniform.isArray()) - { - encoder->exitAggregateType(); - } - } -} - -bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps) -{ - ASSERT(IsSampler(uniform.type)); - ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX); - - if (uniform.vsRegisterIndex != GL_INVALID_INDEX) - { - if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS, - &mUsedVertexSamplerRange)) - { - infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", - mSamplersVS.size()); - return false; - } - - unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors; - if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors) - { - infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", - caps.maxVertexUniformVectors); - return false; - } - } - - if (uniform.psRegisterIndex != GL_INVALID_INDEX) - { - if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS, - &mUsedPixelSamplerRange)) - { - infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", - mSamplersPS.size()); - return false; - } - - unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors; - if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors) - { - infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", - caps.maxFragmentUniformVectors); - return false; - } - } - - return true; -} - -bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps) -{ - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - const LinkedUniform &uniform = *mUniforms[uniformIndex]; - - if (IsSampler(uniform.type)) - { - if (!indexSamplerUniform(uniform, infoLog, caps)) - { - return false; - } - } - - for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++) - { - mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex)); - } - } - - return true; -} - -bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex, - GLenum samplerType, - unsigned int samplerCount, - std::vector<Sampler> &outSamplers, - GLuint *outUsedRange) -{ - unsigned int samplerIndex = startSamplerIndex; - - do - { - if (samplerIndex < outSamplers.size()) - { - Sampler& sampler = outSamplers[samplerIndex]; - sampler.active = true; - sampler.textureType = GetTextureType(samplerType); - sampler.logicalTextureUnit = 0; - *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); - } - else - { - return false; - } - - samplerIndex++; - } while (samplerIndex < startSamplerIndex + samplerCount); - - return true; -} - -bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock) -{ - const char* blockName = vertexInterfaceBlock.name.c_str(); - - // validate blocks for the same member types - if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) - { - infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); - return false; - } - - if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) - { - infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); - return false; - } - - if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) - { - infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); - return false; - } - - const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) - { - const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; - const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; - - if (vertexMember.name != fragmentMember.name) - { - infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", - blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); - return false; - } - - std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; - if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) - { - return false; - } - } - - return true; -} - -bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) -{ - const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); - const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); - - // Check that interface blocks defined in the vertex and fragment shaders are identical - typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap; - UniformBlockMap linkedUniformBlocks; - - for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; - linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; - } - - for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; - UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); - if (entry != linkedUniformBlocks.end()) - { - const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; - if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) - { - return false; - } - } - } - - for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; - - // Note: shared and std140 layouts are always considered active - if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) - { - return false; - } - } - } - - for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex]; - - // Note: shared and std140 layouts are always considered active - if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) - { - return false; - } - } - } - - return true; -} - bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings, const std::vector<std::string> &transformFeedbackVaryingNames, GLenum transformFeedbackBufferMode, @@ -2253,142 +907,6 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons return true; } -template <typename VarT> -void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex, - sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, - bool inRowMajorLayout) -{ - for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) - { - const VarT &field = fields[uniformIndex]; - const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); - - if (field.isStruct()) - { - bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); - - for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) - { - encoder->enterAggregateType(); - - const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); - defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout); - - encoder->exitAggregateType(); - } - } - else - { - bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout); - - sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); - - LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize, - blockIndex, memberInfo); - - // add to uniform list, but not index, since uniform block uniforms have no location - blockUniformIndexes->push_back(mUniforms.size()); - mUniforms.push_back(newUniform); - } - } -} - -bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps) -{ - const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation()); - - // create uniform block entries if they do not exist - if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) - { - std::vector<unsigned int> blockUniformIndexes; - const unsigned int blockIndex = mUniformBlocks.size(); - - // define member uniforms - sh::BlockLayoutEncoder *encoder = NULL; - - if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) - { - encoder = new sh::Std140BlockEncoder; - } - else - { - encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); - } - ASSERT(encoder); - - defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout); - - size_t dataSize = encoder->getBlockSize(); - - // create all the uniform blocks - if (interfaceBlock.arraySize > 0) - { - for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) - { - UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize); - newUniformBlock->memberUniformIndexes = blockUniformIndexes; - mUniformBlocks.push_back(newUniformBlock); - } - } - else - { - UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize); - newUniformBlock->memberUniformIndexes = blockUniformIndexes; - mUniformBlocks.push_back(newUniformBlock); - } - } - - if (interfaceBlock.staticUse) - { - // Assign registers to the uniform blocks - const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); - const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); - ASSERT(blockIndex != GL_INVALID_INDEX); - ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); - - unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name); - - for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) - { - UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; - ASSERT(uniformBlock->name == interfaceBlock.name); - - if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), - interfaceBlockRegister + uniformBlockElement, caps)) - { - return false; - } - } - } - - return true; -} - -bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps) -{ - if (shader == GL_VERTEX_SHADER) - { - uniformBlock->vsRegisterIndex = registerIndex; - if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) - { - infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks); - return false; - } - } - else if (shader == GL_FRAGMENT_SHADER) - { - uniformBlock->psRegisterIndex = registerIndex; - if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) - { - infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks); - return false; - } - } - else UNREACHABLE(); - - return true; -} - bool ProgramBinary::isValidated() const { return mValidated; @@ -2464,13 +982,13 @@ GLint ProgramBinary::getActiveAttributeMaxLength() const void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const { - ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount() + ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount() if (bufsize > 0) { - std::string string = mUniforms[index]->name; + std::string string = mProgram->getUniforms()[index]->name; - if (mUniforms[index]->isArray()) + if (mProgram->getUniforms()[index]->isArray()) { string += "[0]"; } @@ -2484,27 +1002,27 @@ void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *len } } - *size = mUniforms[index]->elementCount(); + *size = mProgram->getUniforms()[index]->elementCount(); - *type = mUniforms[index]->type; + *type = mProgram->getUniforms()[index]->type; } GLint ProgramBinary::getActiveUniformCount() const { - return mUniforms.size(); + return mProgram->getUniforms().size(); } GLint ProgramBinary::getActiveUniformMaxLength() const { int maxLength = 0; - unsigned int numUniforms = mUniforms.size(); + unsigned int numUniforms = mProgram->getUniforms().size(); for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) { - if (!mUniforms[uniformIndex]->name.empty()) + if (!mProgram->getUniforms()[uniformIndex]->name.empty()) { - int length = (int)(mUniforms[uniformIndex]->name.length() + 1); - if (mUniforms[uniformIndex]->isArray()) + int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1); + if (mProgram->getUniforms()[uniformIndex]->isArray()) { length += 3; // Counting in "[0]". } @@ -2517,7 +1035,7 @@ GLint ProgramBinary::getActiveUniformMaxLength() const GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const { - const gl::LinkedUniform& uniform = *mUniforms[index]; + const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index]; switch (pname) { @@ -2540,34 +1058,25 @@ GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const bool ProgramBinary::isValidUniformLocation(GLint location) const { - ASSERT(rx::IsIntegerCastSafe<GLint>(mUniformIndex.size())); - return (location >= 0 && location < static_cast<GLint>(mUniformIndex.size())); + ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size())); + return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size())); } LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const { - ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size()); - return mUniforms[mUniformIndex[location].index]; + return mProgram->getUniformByLocation(location); } LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const { - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - if (mUniforms[uniformIndex]->name == name) - { - return mUniforms[uniformIndex]; - } - } - - return NULL; + return mProgram->getUniformByName(name); } void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const { - ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount() - const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; if (bufSize > 0) { @@ -2590,9 +1099,9 @@ void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const { - ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount() - const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; switch (pname) { @@ -2625,17 +1134,17 @@ void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pna GLuint ProgramBinary::getActiveUniformBlockCount() const { - return mUniformBlocks.size(); + return mProgram->getUniformBlocks().size(); } GLuint ProgramBinary::getActiveUniformBlockMaxLength() const { unsigned int maxLength = 0; - unsigned int numUniformBlocks = mUniformBlocks.size(); + unsigned int numUniformBlocks = mProgram->getUniformBlocks().size(); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) { - const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; if (!uniformBlock.name.empty()) { const unsigned int length = uniformBlock.name.length() + 1; @@ -2665,88 +1174,7 @@ void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps) bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps) { - // if any two active samplers in a program are of different types, but refer to the same - // texture image unit, and this is the current program, then ValidateProgram will fail, and - // DrawArrays and DrawElements will issue the INVALID_OPERATION error. - updateSamplerMapping(); - - std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE); - - for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) - { - if (mSamplersPS[i].active) - { - unsigned int unit = mSamplersPS[i].logicalTextureUnit; - - if (unit >= textureUnitTypes.size()) - { - if (infoLog) - { - infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); - } - - return false; - } - - if (textureUnitTypes[unit] != GL_NONE) - { - if (mSamplersPS[i].textureType != textureUnitTypes[unit]) - { - if (infoLog) - { - infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - return false; - } - } - else - { - textureUnitTypes[unit] = mSamplersPS[i].textureType; - } - } - } - - for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) - { - if (mSamplersVS[i].active) - { - unsigned int unit = mSamplersVS[i].logicalTextureUnit; - - if (unit >= textureUnitTypes.size()) - { - if (infoLog) - { - infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); - } - - return false; - } - - if (textureUnitTypes[unit] != GL_NONE) - { - if (mSamplersVS[i].textureType != textureUnitTypes[unit]) - { - if (infoLog) - { - infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - return false; - } - } - else - { - textureUnitTypes[unit] = mSamplersVS[i].textureType; - } - } - } - - return true; -} - -ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D) -{ + return mProgram->validateSamplers(infoLog, caps); } struct AttributeSorter @@ -2795,26 +1223,6 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA void ProgramBinary::reset() { - SafeDeleteContainer(mVertexExecutables); - SafeDeleteContainer(mPixelExecutables); - - SafeDelete(mGeometryExecutable); - - mTransformFeedbackBufferMode = GL_NONE; - mTransformFeedbackLinkedVaryings.clear(); - - mSamplersPS.clear(); - mSamplersVS.clear(); - - mUsedVertexSamplerRange = 0; - mUsedPixelSamplerRange = 0; - mUsesPointSize = false; - mShaderVersion = 0; - mDirtySamplerMapping = true; - - SafeDeleteContainer(mUniforms); - SafeDeleteContainer(mUniformBlocks); - mUniformIndex.clear(); mOutputVariables.clear(); mProgram->reset(); diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h index ad470d417b..3142d66c6d 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h @@ -24,11 +24,6 @@ #include <string> #include <vector> -// TODO(jmadill): place this in workarounds library -#define ANGLE_WORKAROUND_ENABLED 1 -#define ANGLE_WORKAROUND_DISABLED 2 -#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED - namespace sh { class HLSLBlockEncoder; @@ -44,7 +39,6 @@ class HLSLBlockEncoder; namespace rx { class ShaderExecutable; -class Renderer; struct TranslatedAttribute; class UniformStorage; class ProgramImpl; @@ -58,6 +52,7 @@ class InfoLog; class AttributeBindings; class Buffer; class Framebuffer; +struct Data; // Struct used for correlating uniforms/elements of uniform arrays to handles struct VariableLocation @@ -91,6 +86,14 @@ struct LinkedVarying unsigned int semanticIndexCount; }; +struct LinkResult +{ + bool linkSuccess; + Error error; + + LinkResult(bool linkSuccess, const Error &error); +}; + // This is the result of linking a program. It is the state that would be passed to ProgramBinary. class ProgramBinary : public RefCountObject { @@ -101,11 +104,6 @@ class ProgramBinary : public RefCountObject rx::ProgramImpl *getImplementation() { return mProgram; } const rx::ProgramImpl *getImplementation() const { return mProgram; } - rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo); - rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout); - rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]); - rx::ShaderExecutable *getGeometryExecutable() const; - GLuint getAttributeLocation(const char *name); int getSemanticIndex(int attributeIndex); @@ -113,8 +111,6 @@ class ProgramBinary : public RefCountObject GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex); GLint getUsedSamplerRange(SamplerType type); bool usesPointSize() const; - bool usesPointSpriteEmulation() const; - bool usesGeometryShader() const; GLint getUniformLocation(std::string name); GLuint getUniformIndex(std::string name); @@ -145,18 +141,17 @@ class ProgramBinary : public RefCountObject void getUniformiv(GLint location, GLint *params); void getUniformuiv(GLint location, GLuint *params); - void dirtyAllUniforms(); - Error applyUniforms(); Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps); - bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length); - bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length); + LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length); + Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length); GLint getLength(); - bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader, - const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps); - void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); + LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings, + Shader *fragmentShader, Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode); void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; GLint getActiveAttributeCount() const; @@ -188,30 +183,23 @@ class ProgramBinary : public RefCountObject void updateSamplerMapping(); unsigned int getSerial() const; - int getShaderVersion() const; void initAttributesByLayout(); void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const; - const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; } - static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader); + static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); + static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); private: DISALLOW_COPY_AND_ASSIGN(ProgramBinary); - struct Sampler - { - Sampler(); - - bool active; - GLint logicalTextureUnit; - GLenum textureType; - }; - void reset(); bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader); + bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); + bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock); static bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, @@ -219,102 +207,21 @@ class ProgramBinary : public RefCountObject const sh::ShaderVariable &fragmentVariable, bool validatePrecision); - static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); - static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); - bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); - void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister); - void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder); - bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps); - bool indexUniforms(InfoLog &infoLog, const Caps &caps); - static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, - std::vector<Sampler> &outSamplers, GLuint *outUsedRange); - bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock); - bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings, const std::vector<std::string> &transformFeedbackVaryingNames, GLenum transformFeedbackBufferMode, std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings, const Caps &caps) const; - template <typename VarT> - void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex, - sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, - bool inRowMajorLayout); - bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps); bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps); void defineOutputVariables(Shader *fragmentShader); - template <typename T> - void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); - - template <int cols, int rows> - void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); - - template <typename T> - void getUniformv(GLint location, T *params, GLenum uniformType); - - class VertexExecutable - { - public: - VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS], - const GLenum signature[MAX_VERTEX_ATTRIBS], - rx::ShaderExecutable *shaderExecutable); - ~VertexExecutable(); - - bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const; - - const VertexFormat *inputs() const { return mInputs; } - const GLenum *signature() const { return mSignature; } - rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } - - private: - VertexFormat mInputs[MAX_VERTEX_ATTRIBS]; - GLenum mSignature[MAX_VERTEX_ATTRIBS]; - rx::ShaderExecutable *mShaderExecutable; - }; - - class PixelExecutable - { - public: - PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable); - ~PixelExecutable(); - - bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; } - - const std::vector<GLenum> &outputSignature() const { return mOutputSignature; } - rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } - - private: - std::vector<GLenum> mOutputSignature; - rx::ShaderExecutable *mShaderExecutable; - }; - rx::ProgramImpl *mProgram; - std::vector<VertexExecutable *> mVertexExecutables; - std::vector<PixelExecutable *> mPixelExecutables; - - rx::ShaderExecutable *mGeometryExecutable; - sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; - sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mAttributesByLayout[MAX_VERTEX_ATTRIBS]; - GLenum mTransformFeedbackBufferMode; - std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings; - - std::vector<Sampler> mSamplersPS; - std::vector<Sampler> mSamplersVS; - GLuint mUsedVertexSamplerRange; - GLuint mUsedPixelSamplerRange; - bool mUsesPointSize; - int mShaderVersion; - bool mDirtySamplerMapping; - - std::vector<LinkedUniform*> mUniforms; - std::vector<UniformBlock*> mUniformBlocks; - std::vector<VariableLocation> mUniformIndex; std::map<int, VariableLocation> mOutputVariables; bool mValidated; diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp index 9406fce58d..911a389dfa 100644 --- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp @@ -4,77 +4,86 @@ // found in the LICENSE file. // -// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes -// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer -// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. +// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class, +// GL renderbuffer objects and related functionality. +// [OpenGL ES 2.0.24] section 4.4.3 page 108. #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Texture.h" #include "libGLESv2/formatutils.h" #include "libGLESv2/FramebufferAttachment.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/RenderTarget.h" +#include "libGLESv2/renderer/RenderbufferImpl.h" #include "common/utilities.h" namespace gl { -unsigned int RenderbufferStorage::mCurrentSerial = 1; - -Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage) +Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id) : RefCountObject(id), - mStorage(newStorage) + mRenderbuffer(impl) { - ASSERT(mStorage); + ASSERT(mRenderbuffer); + + mWidth = mRenderbuffer->getWidth(); + mHeight = mRenderbuffer->getHeight(); + mInternalFormat = mRenderbuffer->getInternalFormat(); + mActualFormat = mRenderbuffer->getActualFormat(); + mSamples = mRenderbuffer->getSamples(); } Renderbuffer::~Renderbuffer() { - SafeDelete(mStorage); + SafeDelete(mRenderbuffer); } -void Renderbuffer::setStorage(RenderbufferStorage *newStorage) +Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) { - ASSERT(newStorage); + Error error = mRenderbuffer->setStorage(width, height, internalformat, samples); + if (error.isError()) + { + return error; + } - SafeDelete(mStorage); - mStorage = newStorage; + mWidth = width; + mHeight = height; + mInternalFormat = internalformat; + mSamples = samples; + mActualFormat = mRenderbuffer->getActualFormat(); + + return Error(GL_NO_ERROR); } -RenderbufferStorage *Renderbuffer::getStorage() +rx::RenderbufferImpl *Renderbuffer::getImplementation() { - ASSERT(mStorage); - return mStorage; + ASSERT(mRenderbuffer); + return mRenderbuffer; } GLsizei Renderbuffer::getWidth() const { - ASSERT(mStorage); - return mStorage->getWidth(); + return mWidth; } GLsizei Renderbuffer::getHeight() const { - ASSERT(mStorage); - return mStorage->getHeight(); + return mHeight; } GLenum Renderbuffer::getInternalFormat() const { - ASSERT(mStorage); - return mStorage->getInternalFormat(); + return mInternalFormat; } GLenum Renderbuffer::getActualFormat() const { - ASSERT(mStorage); - return mStorage->getActualFormat(); + return mActualFormat; } GLsizei Renderbuffer::getSamples() const { - ASSERT(mStorage); - return mStorage->getSamples(); + return mSamples; } GLuint Renderbuffer::getRedSize() const @@ -107,176 +116,4 @@ GLuint Renderbuffer::getStencilSize() const return GetInternalFormatInfo(getActualFormat()).stencilBits; } -RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1)) -{ - mWidth = 0; - mHeight = 0; - mInternalFormat = GL_RGBA4; - mActualFormat = GL_RGBA8_OES; - mSamples = 0; -} - -RenderbufferStorage::~RenderbufferStorage() -{ -} - -rx::RenderTarget *RenderbufferStorage::getRenderTarget() -{ - return NULL; -} - -GLsizei RenderbufferStorage::getWidth() const -{ - return mWidth; -} - -GLsizei RenderbufferStorage::getHeight() const -{ - return mHeight; -} - -GLenum RenderbufferStorage::getInternalFormat() const -{ - return mInternalFormat; -} - -GLenum RenderbufferStorage::getActualFormat() const -{ - return mActualFormat; -} - -GLsizei RenderbufferStorage::getSamples() const -{ - return mSamples; -} - -unsigned int RenderbufferStorage::getSerial() const -{ - return mSerial; -} - -unsigned int RenderbufferStorage::issueSerials(unsigned int count) -{ - unsigned int firstSerial = mCurrentSerial; - mCurrentSerial += count; - return firstSerial; -} - -bool RenderbufferStorage::isTexture() const -{ - return false; -} - -unsigned int RenderbufferStorage::getTextureSerial() const -{ - return -1; -} - -Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) -{ - mRenderTarget = renderer->createRenderTarget(swapChain, false); - - if (mRenderTarget) - { - mWidth = mRenderTarget->getWidth(); - mHeight = mRenderTarget->getHeight(); - mInternalFormat = mRenderTarget->getInternalFormat(); - mActualFormat = mRenderTarget->getActualFormat(); - mSamples = mRenderTarget->getSamples(); - } -} - -Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL) -{ - mRenderTarget = renderer->createRenderTarget(width, height, format, samples); - - if (mRenderTarget) - { - mWidth = width; - mHeight = height; - mInternalFormat = format; - mActualFormat = mRenderTarget->getActualFormat(); - mSamples = mRenderTarget->getSamples(); - } -} - -Colorbuffer::~Colorbuffer() -{ - if (mRenderTarget) - { - delete mRenderTarget; - } -} - -rx::RenderTarget *Colorbuffer::getRenderTarget() -{ - return mRenderTarget; -} - -DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) -{ - mDepthStencil = renderer->createRenderTarget(swapChain, true); - if (mDepthStencil) - { - mWidth = mDepthStencil->getWidth(); - mHeight = mDepthStencil->getHeight(); - mInternalFormat = mDepthStencil->getInternalFormat(); - mSamples = mDepthStencil->getSamples(); - mActualFormat = mDepthStencil->getActualFormat(); - } -} - -DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) -{ - - mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples); - - mWidth = mDepthStencil->getWidth(); - mHeight = mDepthStencil->getHeight(); - mInternalFormat = GL_DEPTH24_STENCIL8_OES; - mActualFormat = mDepthStencil->getActualFormat(); - mSamples = mDepthStencil->getSamples(); -} - -DepthStencilbuffer::~DepthStencilbuffer() -{ - if (mDepthStencil) - { - delete mDepthStencil; - } -} - -rx::RenderTarget *DepthStencilbuffer::getRenderTarget() -{ - return mDepthStencil; -} - -Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) -{ - if (mDepthStencil) - { - mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage - } -} - -Depthbuffer::~Depthbuffer() -{ -} - -Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) -{ - if (mDepthStencil) - { - mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage - } -} - -Stencilbuffer::~Stencilbuffer() -{ -} - } diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h index 71bcb0e1f8..e9f12af3ce 100644 --- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h @@ -4,30 +4,27 @@ // found in the LICENSE file. // -// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the -// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer, -// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer -// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. +// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer. +// Implements GL renderbuffer objects and related functionality. +// [OpenGL ES 2.0.24] section 4.4.3 page 108. #ifndef LIBGLESV2_RENDERBUFFER_H_ #define LIBGLESV2_RENDERBUFFER_H_ #include "angle_gl.h" +#include "libGLESv2/Error.h" + #include "common/angleutils.h" #include "common/RefCountObject.h" namespace rx { -class Renderer; -class SwapChain; -class RenderTarget; -class TextureStorage; +class RenderbufferImpl; } namespace gl { -class RenderbufferStorage; class FramebufferAttachment; // A GL renderbuffer object is usually used as a depth or stencil buffer attachment @@ -38,11 +35,12 @@ class FramebufferAttachment; class Renderbuffer : public RefCountObject { public: - Renderbuffer(GLuint id, RenderbufferStorage *newStorage); + Renderbuffer(rx::RenderbufferImpl *impl, GLuint id); virtual ~Renderbuffer(); - void setStorage(RenderbufferStorage *newStorage); - RenderbufferStorage *getStorage(); + Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples); + + rx::RenderbufferImpl *getImplementation(); GLsizei getWidth() const; GLsizei getHeight() const; @@ -57,102 +55,15 @@ class Renderbuffer : public RefCountObject GLuint getStencilSize() const; private: - RenderbufferStorage *mStorage; -}; - -// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage -// is called. The specific concrete type depends on whether the internal format is -// colour depth, stencil or packed depth/stencil. -class RenderbufferStorage -{ - public: - RenderbufferStorage(); + DISALLOW_COPY_AND_ASSIGN(Renderbuffer); - virtual ~RenderbufferStorage() = 0; + rx::RenderbufferImpl *mRenderbuffer; - virtual rx::RenderTarget *getRenderTarget(); - - virtual GLsizei getWidth() const; - virtual GLsizei getHeight() const; - virtual GLenum getInternalFormat() const; - virtual GLenum getActualFormat() const; - virtual GLsizei getSamples() const; - - virtual unsigned int getSerial() const; - - virtual bool isTexture() const; - virtual unsigned int getTextureSerial() const; - - static unsigned int issueSerials(unsigned int count); - - protected: GLsizei mWidth; GLsizei mHeight; GLenum mInternalFormat; GLenum mActualFormat; GLsizei mSamples; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage); - - const unsigned int mSerial; - - static unsigned int mCurrentSerial; -}; - -class Colorbuffer : public RenderbufferStorage -{ - public: - Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain); - Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples); - - virtual ~Colorbuffer(); - - virtual rx::RenderTarget *getRenderTarget(); - - private: - DISALLOW_COPY_AND_ASSIGN(Colorbuffer); - - rx::RenderTarget *mRenderTarget; -}; - -class DepthStencilbuffer : public RenderbufferStorage -{ - public: - DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain); - DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples); - - ~DepthStencilbuffer(); - - virtual rx::RenderTarget *getRenderTarget(); - - protected: - rx::RenderTarget *mDepthStencil; - - private: - DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer); -}; - -class Depthbuffer : public DepthStencilbuffer -{ - public: - Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples); - - virtual ~Depthbuffer(); - - private: - DISALLOW_COPY_AND_ASSIGN(Depthbuffer); -}; - -class Stencilbuffer : public DepthStencilbuffer -{ - public: - Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples); - - virtual ~Stencilbuffer(); - - private: - DISALLOW_COPY_AND_ASSIGN(Stencilbuffer); }; } diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp index 9121de1750..38d53cad81 100644 --- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp @@ -21,9 +21,9 @@ namespace gl { ResourceManager::ResourceManager(rx::Renderer *renderer) + : mRenderer(renderer), + mRefCount(1) { - mRefCount = 1; - mRenderer = renderer; } ResourceManager::~ResourceManager() @@ -88,13 +88,13 @@ GLuint ResourceManager::createBuffer() } // Returns an unused shader/program name -GLuint ResourceManager::createShader(GLenum type) +GLuint ResourceManager::createShader(const gl::Data &data, GLenum type) { GLuint handle = mProgramShaderHandleAllocator.allocate(); if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) { - mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle); + mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle); } else UNREACHABLE(); @@ -146,7 +146,7 @@ GLuint ResourceManager::createFenceSync() { GLuint handle = mFenceSyncHandleAllocator.allocate(); - FenceSync *fenceSync = new FenceSync(mRenderer, handle); + FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle); fenceSync->addRef(); mFenceSyncMap[handle] = fenceSync; @@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle) } } -Program *ResourceManager::getProgram(unsigned int handle) +Program *ResourceManager::getProgram(unsigned int handle) const { - ProgramMap::iterator program = mProgramMap.find(handle); + ProgramMap::const_iterator program = mProgramMap.find(handle); if (program == mProgramMap.end()) { @@ -403,7 +403,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) { if (renderbuffer != 0 && !getRenderbuffer(renderbuffer)) { - Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0)); + Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer); mRenderbufferMap[renderbuffer] = renderbufferObject; renderbufferObject->addRef(); } diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h index 7d53bd4854..acad29b51d 100644 --- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h +++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h @@ -32,6 +32,7 @@ class Texture; class Renderbuffer; class Sampler; class FenceSync; +struct Data; class ResourceManager { @@ -43,7 +44,7 @@ class ResourceManager void release(); GLuint createBuffer(); - GLuint createShader(GLenum type); + GLuint createShader(const gl::Data &data, GLenum type); GLuint createProgram(); GLuint createTexture(); GLuint createRenderbuffer(); @@ -60,7 +61,7 @@ class ResourceManager Buffer *getBuffer(GLuint handle); Shader *getShader(GLuint handle); - Program *getProgram(GLuint handle); + Program *getProgram(GLuint handle) const; Texture *getTexture(GLuint handle); Renderbuffer *getRenderbuffer(GLuint handle); Sampler *getSampler(GLuint handle); @@ -78,8 +79,8 @@ class ResourceManager private: DISALLOW_COPY_AND_ASSIGN(ResourceManager); - std::size_t mRefCount; rx::Renderer *mRenderer; + std::size_t mRefCount; typedef std::unordered_map<GLuint, Buffer*> BufferMap; BufferMap mBufferMap; diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp index 4cf5251ff9..1cc17a0501 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp @@ -118,9 +118,15 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer); } -void Shader::compile() +void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const { - mCompiled = mShader->compile(mSource); + std::string debugInfo(mShader->getDebugInfo()); + getSourceImpl(debugInfo, bufSize, length, buffer); +} + +void Shader::compile(const gl::Data &data) +{ + mCompiled = mShader->compile(data, mSource); } void Shader::addRef() diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h index 7ba3bd165c..904217dab8 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.h +++ b/src/3rdparty/angle/src/libGLESv2/Shader.h @@ -31,6 +31,7 @@ class ShaderImpl; namespace gl { class ResourceManager; +struct Data; struct PackedVarying : public sh::Varying { @@ -73,8 +74,9 @@ class Shader void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; int getTranslatedSourceLength() const; void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; + void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const; - void compile(); + void compile(const gl::Data &data); bool isCompiled() const { return mCompiled; } void addRef(); diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp index 3c03b90e56..b5b62f5848 100644 --- a/src/3rdparty/angle/src/libGLESv2/State.cpp +++ b/src/3rdparty/angle/src/libGLESv2/State.cpp @@ -10,18 +10,20 @@ #include "libGLESv2/Context.h" #include "libGLESv2/Caps.h" -#include "libGLESv2/VertexArray.h" -#include "libGLESv2/Query.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" -#include "libGLESv2/renderer/RenderTarget.h" +#include "libGLESv2/Query.h" +#include "libGLESv2/VertexArray.h" #include "libGLESv2/formatutils.h" +#include "libGLESv2/renderer/RenderTarget.h" namespace gl { State::State() { + mMaxDrawBuffers = 0; + mMaxCombinedTextureImageUnits = 0; } State::~State() @@ -31,7 +33,8 @@ State::~State() void State::initialize(const Caps& caps, GLuint clientVersion) { - mContext = NULL; + mMaxDrawBuffers = caps.maxDrawBuffers; + mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; setClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -111,11 +114,15 @@ void State::initialize(const Caps& caps, GLuint clientVersion) mActiveSampler = 0; const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) + mVertexAttribCurrentValues.resize(caps.maxVertexAttributes); + for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex) { mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); } + mUniformBuffers.resize(caps.maxCombinedUniformBlocks); + mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes); + mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits); mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits); if (clientVersion >= 3) @@ -153,12 +160,6 @@ void State::reset() mSamplers[samplerIdx].set(NULL); } - const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) - { - mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); - } - mArrayBuffer.set(NULL); mRenderbuffer.set(NULL); @@ -170,15 +171,15 @@ void State::reset() } mGenericUniformBuffer.set(NULL); - for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) + mGenericTransformFeedbackBuffer.set(NULL); + for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr) { - mUniformBuffers[i].set(NULL); + bufItr->set(NULL); } - mGenericTransformFeedbackBuffer.set(NULL); - for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr) { - mTransformFeedbackBuffers[i].set(NULL); + bufItr->set(NULL); } mCopyReadBuffer.set(NULL); @@ -485,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert) mSampleCoverageInvert = invert; } -void State::getSampleCoverageParams(GLclampf *value, bool *invert) +void State::getSampleCoverageParams(GLclampf *value, bool *invert) const { ASSERT(value != NULL && invert != NULL); @@ -612,14 +613,7 @@ void State::setSamplerTexture(GLenum type, Texture *texture) Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const { - const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler]; - - if (binding.id() == 0) // Special case: 0 refers to default textures held by Context - { - return NULL; - } - - return binding.get(); + return mSamplerTextures.at(type)[sampler].get(); } GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const @@ -627,7 +621,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const return mSamplerTextures.at(type)[sampler].id(); } -void State::detachTexture(GLuint texture) +void State::detachTexture(const TextureMap &zeroTextures, GLuint texture) { // Textures have a detach method on State rather than a simple // removeBinding, because the zero/null texture objects are managed @@ -640,13 +634,15 @@ void State::detachTexture(GLuint texture) for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) { + GLenum textureType = bindingVec->first; TextureBindingVector &textureVector = bindingVec->second; for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) { BindingPointer<Texture> &binding = textureVector[textureIdx]; if (binding.id() == texture) { - binding.set(NULL); + // Zero textures are the "default" textures instead of NULL + binding.set(zeroTextures.at(textureType).get()); } } } @@ -667,6 +663,19 @@ void State::detachTexture(GLuint texture) } } +void State::initializeZeroTextures(const TextureMap &zeroTextures) +{ + for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++) + { + TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first]; + + for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit) + { + samplerTextureArray[textureUnit].set(i->second.get()); + } + } +} + void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler) { mSamplers[textureUnit].set(sampler); @@ -947,14 +956,14 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt GLuint State::getIndexedUniformBufferId(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); + ASSERT(static_cast<size_t>(index) < mUniformBuffers.size()); return mUniformBuffers[index].id(); } Buffer *State::getIndexedUniformBuffer(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); + ASSERT(static_cast<size_t>(index) < mUniformBuffers.size()); return mUniformBuffers[index].get(); } @@ -971,25 +980,30 @@ void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffe GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size()); return mTransformFeedbackBuffers[index].id(); } Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size()); return mTransformFeedbackBuffers[index].get(); } GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size()); return mTransformFeedbackBuffers[index].getOffset(); } +size_t State::getTransformFeedbackBufferIndexRange() const +{ + return mTransformFeedbackBuffers.size(); +} + void State::setCopyReadBufferBinding(Buffer *buffer) { mCopyReadBuffer.set(buffer); @@ -1033,19 +1047,19 @@ void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) void State::setVertexAttribf(GLuint index, const GLfloat values[4]) { - ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setFloatValues(values); } void State::setVertexAttribu(GLuint index, const GLuint values[4]) { - ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setUnsignedIntValues(values); } void State::setVertexAttribi(GLuint index, const GLint values[4]) { - ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setIntValues(values); } @@ -1062,15 +1076,10 @@ const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const { - ASSERT(attribNum < MAX_VERTEX_ATTRIBS); + ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size()); return mVertexAttribCurrentValues[attribNum]; } -const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const -{ - return mVertexAttribCurrentValues; -} - const void *State::getVertexAttribPointer(unsigned int attribNum) const { return getVertexArray()->getVertexAttribute(attribNum).pointer; @@ -1180,12 +1189,12 @@ void State::getFloatv(GLenum pname, GLfloat *params) } } -void State::getIntegerv(GLenum pname, GLint *params) +void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) { if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) { unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT); - ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers); + ASSERT(colorAttachment < mMaxDrawBuffers); Framebuffer *framebuffer = mDrawFramebuffer; *params = framebuffer->getDrawBufferState(colorAttachment); return; @@ -1238,12 +1247,12 @@ void State::getIntegerv(GLenum pname, GLint *params) case GL_SAMPLES: { gl::Framebuffer *framebuffer = mDrawFramebuffer; - if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE) { switch (pname) { case GL_SAMPLE_BUFFERS: - if (framebuffer->getSamples() != 0) + if (framebuffer->getSamples(data) != 0) { *params = 1; } @@ -1253,7 +1262,7 @@ void State::getIntegerv(GLenum pname, GLint *params) } break; case GL_SAMPLES: - *params = framebuffer->getSamples(); + *params = framebuffer->getSamples(data); break; } } @@ -1332,19 +1341,19 @@ void State::getIntegerv(GLenum pname, GLint *params) } break; case GL_TEXTURE_BINDING_2D: - ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id(); break; case GL_TEXTURE_BINDING_CUBE_MAP: - ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id(); break; case GL_TEXTURE_BINDING_3D: - ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id(); break; case GL_TEXTURE_BINDING_2D_ARRAY: - ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id(); break; case GL_UNIFORM_BUFFER_BINDING: @@ -1376,13 +1385,13 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size()) { *data = mTransformFeedbackBuffers[index].id(); } break; case GL_UNIFORM_BUFFER_BINDING: - if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + if (static_cast<size_t>(index) < mUniformBuffers.size()) { *data = mUniformBuffers[index].id(); } @@ -1399,25 +1408,25 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_START: - if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size()) { *data = mTransformFeedbackBuffers[index].getOffset(); } break; case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size()) { *data = mTransformFeedbackBuffers[index].getSize(); } break; case GL_UNIFORM_BUFFER_START: - if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + if (static_cast<size_t>(index) < mUniformBuffers.size()) { *data = mUniformBuffers[index].getOffset(); } break; case GL_UNIFORM_BUFFER_SIZE: - if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + if (static_cast<size_t>(index) < mUniformBuffers.size()) { *data = mUniformBuffers[index].getSize(); } @@ -1433,9 +1442,9 @@ bool State::hasMappedBuffer(GLenum target) const { if (target == GL_ARRAY_BUFFER) { - for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++) + for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++) { - const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex); + const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex)); gl::Buffer *boundBuffer = vertexAttrib.buffer.get(); if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped()) { diff --git a/src/3rdparty/angle/src/libGLESv2/State.h b/src/3rdparty/angle/src/libGLESv2/State.h index 5f0433136c..c3e6106bd8 100644 --- a/src/3rdparty/angle/src/libGLESv2/State.h +++ b/src/3rdparty/angle/src/libGLESv2/State.h @@ -25,6 +25,9 @@ class Query; class VertexArray; class Context; struct Caps; +struct Data; + +typedef std::map< GLenum, BindingPointer<Texture> > TextureMap; class State { @@ -35,8 +38,6 @@ class State void initialize(const Caps& caps, GLuint clientVersion); void reset(); - void setContext(Context *context) { mContext = context; } - // State chunk getters const RasterizerState &getRasterizerState() const; const BlendState &getBlendState() const; @@ -100,7 +101,7 @@ class State bool isSampleCoverageEnabled() const; void setSampleCoverage(bool enabled); void setSampleCoverageParams(GLclampf value, bool invert); - void getSampleCoverageParams(GLclampf *value, bool *invert); + void getSampleCoverageParams(GLclampf *value, bool *invert) const; // Scissor test state toggle & query bool isScissorTestEnabled() const; @@ -133,7 +134,8 @@ class State void setSamplerTexture(GLenum type, Texture *texture); Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const; - void detachTexture(GLuint texture); + void detachTexture(const TextureMap &zeroTextures, GLuint texture); + void initializeZeroTextures(const TextureMap &zeroTextures); // Sampler object binding manipulation void setSamplerBinding(GLuint textureUnit, Sampler *sampler); @@ -199,6 +201,7 @@ class State GLuint getIndexedTransformFeedbackBufferId(GLuint index) const; Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const; GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const; + size_t getTransformFeedbackBufferIndexRange() const; // GL_COPY_[READ/WRITE]_BUFFER void setCopyReadBufferBinding(Buffer *buffer); @@ -220,7 +223,6 @@ class State bool normalized, bool pureInteger, GLsizei stride, const void *pointer); const VertexAttribute &getVertexAttribState(unsigned int attribNum) const; const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const; - const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const; const void *getVertexAttribPointer(unsigned int attribNum) const; // Pixel pack state manipulation @@ -238,7 +240,7 @@ class State // State query functions void getBooleanv(GLenum pname, GLboolean *params); void getFloatv(GLenum pname, GLfloat *params); - void getIntegerv(GLenum pname, GLint *params); + void getIntegerv(const gl::Data &data, GLenum pname, GLint *params); bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); @@ -247,7 +249,9 @@ class State private: DISALLOW_COPY_AND_ASSIGN(State); - Context *mContext; + // Cached values from Context's caps + GLuint mMaxDrawBuffers; + GLuint mMaxCombinedTextureImageUnits; ColorF mColorClearValue; GLclampf mDepthClearValue; @@ -283,7 +287,8 @@ class State GLuint mCurrentProgramId; BindingPointer<ProgramBinary> mCurrentProgramBinary; - VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib + typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector; + VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib VertexArray *mVertexArray; // Texture and sampler bindings @@ -300,11 +305,12 @@ class State ActiveQueryMap mActiveQueries; BindingPointer<Buffer> mGenericUniformBuffer; - OffsetBindingPointer<Buffer> mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; + typedef std::vector< OffsetBindingPointer<Buffer> > BufferVector; + BufferVector mUniformBuffers; BindingPointer<TransformFeedback> mTransformFeedback; BindingPointer<Buffer> mGenericTransformFeedbackBuffer; - OffsetBindingPointer<Buffer> mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + BufferVector mTransformFeedbackBuffers; BindingPointer<Buffer> mCopyReadBuffer; BindingPointer<Buffer> mCopyWriteBuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp index 3ec492de07..cd4fc4e32a 100644 --- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp @@ -47,11 +47,14 @@ bool IsPointSampled(const gl::SamplerState &samplerState) return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST)); } +unsigned int Texture::mCurrentTextureSerial = 1; + Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target) : RefCountObject(id), mTexture(impl), + mTextureSerial(issueTextureSerial()), mUsage(GL_NONE), - mImmutable(false), + mImmutableLevelCount(0), mTarget(target) { } @@ -72,16 +75,6 @@ void Texture::setUsage(GLenum usage) getImplementation()->setUsage(usage); } -void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler) -{ - *sampler = mSamplerState; - - // Offset the effective base level by the texture storage's top level - rx::TextureStorage *texture = getNativeTexture(); - int topLevel = texture ? texture->getTopLevel() : 0; - sampler->baseLevel = topLevel + mSamplerState.baseLevel; -} - GLenum Texture::getUsage() const { return mUsage; @@ -138,35 +131,35 @@ GLenum Texture::getActualFormat(const ImageIndex &index) const return image->getActualFormat(); } -rx::TextureStorage *Texture::getNativeTexture() +Error Texture::generateMipmaps() { - return getImplementation()->getNativeTexture(); + return getImplementation()->generateMipmaps(); } -void Texture::generateMipmaps() +Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { - getImplementation()->generateMipmaps(); + return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source); } -void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +unsigned int Texture::getTextureSerial() const { - getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source); + return mTextureSerial; } -unsigned int Texture::getTextureSerial() +unsigned int Texture::issueTextureSerial() { - rx::TextureStorage *texture = getNativeTexture(); - return texture ? texture->getTextureSerial() : 0; + return mCurrentTextureSerial++; } bool Texture::isImmutable() const { - return mImmutable; + return (mImmutableLevelCount > 0); } int Texture::immutableLevelCount() { - return (mImmutable ? getNativeTexture()->getLevelCount() : 0); + return mImmutableLevelCount; } int Texture::mipLevels() const @@ -226,11 +219,11 @@ GLenum Texture2D::getActualFormat(GLint level) const return GL_NONE; } -void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { releaseTexImage(); - mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels); } void Texture2D::bindTexImage(egl::Surface *surface) @@ -254,35 +247,44 @@ void Texture2D::releaseTexImage() } } -void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, + const PixelUnpackState &unpack, const void *pixels) { releaseTexImage(); - mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels); + return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels); } -void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); + return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); } -void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels); + return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels); } -void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, + Framebuffer *source) { releaseTexImage(); - mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source); + return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source); } -void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1); + if (error.isError()) + { + return error; + } + + mImmutableLevelCount = levels; - mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1); + return Error(GL_NO_ERROR); } // Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85. @@ -359,11 +361,11 @@ bool Texture2D::isDepth(GLint level) const return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void Texture2D::generateMipmaps() +Error Texture2D::generateMipmaps() { releaseTexImage(); - mTexture->generateMipmaps(); + return mTexture->generateMipmaps(); } // Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -467,49 +469,27 @@ GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const return GL_NONE; } -void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels); } -void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels); + return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); } -void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); -} - -void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) -{ - mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels); + return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels); } // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -549,16 +529,23 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0; } -void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, + GLsizei width, GLsizei height, Framebuffer *source) { - mTexture->copyImage(target, level, format, x, y, width, height, source); + return mTexture->copyImage(target, level, format, x, y, width, height, source); } -void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) +Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1); + if (error.isError()) + { + return error; + } + + mImmutableLevelCount = levels; - mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1); + return Error(GL_NO_ERROR); } // Tests for texture sampling completeness @@ -734,31 +721,40 @@ bool Texture3D::isDepth(GLint level) const return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels); } -void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels); + return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels); } -void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); + return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); } -void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels); } -void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth); + if (error.isError()) + { + return error; + } - mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth); + mImmutableLevelCount = levels; + + return Error(GL_NO_ERROR); } bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const @@ -892,31 +888,40 @@ bool Texture2DArray::isDepth(GLint level) const return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels); } -void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels); + return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels); } -void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); + return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); } -void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels); } -void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth); + if (error.isError()) + { + return error; + } + + mImmutableLevelCount = levels; - mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth); + return Error(GL_NO_ERROR); } bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h index ca5686fde3..66d4df8015 100644 --- a/src/3rdparty/angle/src/libGLESv2/Texture.h +++ b/src/3rdparty/angle/src/libGLESv2/Texture.h @@ -14,7 +14,7 @@ #include "common/debug.h" #include "common/RefCountObject.h" #include "libGLESv2/angletypes.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "libGLESv2/renderer/TextureImpl.h" #include "libGLESv2/Caps.h" @@ -52,7 +52,6 @@ class Texture : public RefCountObject const SamplerState &getSamplerState() const { return mSamplerState; } SamplerState &getSamplerState() { return mSamplerState; } - void getSamplerStateWithNativeOffset(SamplerState *sampler); void setUsage(GLenum usage); GLenum getUsage() const; @@ -69,15 +68,16 @@ class Texture : public RefCountObject virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0; - rx::TextureStorage *getNativeTexture(); + virtual Error generateMipmaps(); - virtual void generateMipmaps(); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - unsigned int getTextureSerial(); + // Texture serials provide a unique way of identifying a Texture that isn't a raw pointer. + // "id" is not good enough, as Textures can be deleted, then re-allocated with the same id. + unsigned int getTextureSerial() const; bool isImmutable() const; - int immutableLevelCount(); + GLsizei immutableLevelCount(); rx::TextureImpl *getImplementation() { return mTexture; } const rx::TextureImpl *getImplementation() const { return mTexture; } @@ -86,17 +86,20 @@ class Texture : public RefCountObject protected: int mipLevels() const; + const rx::Image *getBaseLevelImage() const; + static unsigned int issueTextureSerial(); rx::TextureImpl *mTexture; SamplerState mSamplerState; GLenum mUsage; - bool mImmutable; + GLsizei mImmutableLevelCount; GLenum mTarget; - const rx::Image *getBaseLevelImage() const; + const unsigned int mTextureSerial; + static unsigned int mCurrentTextureSerial; private: DISALLOW_COPY_AND_ASSIGN(Texture); @@ -116,18 +119,18 @@ class Texture2D : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); - void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + Error setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); - virtual void generateMipmaps(); + virtual Error generateMipmaps(); private: DISALLOW_COPY_AND_ASSIGN(Texture2D); @@ -152,19 +155,12 @@ class TextureCubeMap : public Texture bool isCompressed(GLenum target, GLint level) const; bool isDepth(GLenum target, GLint level) const; - void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - - void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - - void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); - void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void storage(GLsizei levels, GLenum internalformat, GLsizei size); + Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + Error storage(GLsizei levels, GLenum internalformat, GLsizei size); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; @@ -195,11 +191,11 @@ class Texture3D : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; @@ -225,11 +221,11 @@ class Texture2DArray : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.h b/src/3rdparty/angle/src/libGLESv2/VertexArray.h index 993ba042cf..a724c0be1c 100644 --- a/src/3rdparty/angle/src/libGLESv2/VertexArray.h +++ b/src/3rdparty/angle/src/libGLESv2/VertexArray.h @@ -14,14 +14,13 @@ #define LIBGLESV2_VERTEXARRAY_H_ #include "common/RefCountObject.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "libGLESv2/VertexAttribute.h" #include <vector> namespace rx { -class Renderer; class VertexArrayImpl; } @@ -44,7 +43,7 @@ class VertexArray void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized, bool pureInteger, GLsizei stride, const void *pointer); - const VertexAttribute* getVertexAttributes() const { return mVertexAttributes.data(); } + const VertexAttribute* getVertexAttributes() const { return &mVertexAttributes[0]; } Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); } void setElementArrayBuffer(Buffer *buffer); GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); } diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp index bb6425df64..5a0cfc5ad9 100644 --- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp +++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp @@ -9,6 +9,10 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/State.h" +#include "libGLESv2/VertexArray.h" + +#include <float.h> namespace gl { @@ -148,16 +152,16 @@ VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueTyp void VertexFormat::GetInputLayout(VertexFormat *inputLayout, ProgramBinary *programBinary, - const VertexAttribute *attributes, - const gl::VertexAttribCurrentValueData *currentValues) + const State &state) { + const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes(); for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) { int semanticIndex = programBinary->getSemanticIndex(attributeIndex); if (semanticIndex != -1) { - inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type); + inputLayout[semanticIndex] = VertexFormat(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex).Type); } } } @@ -192,4 +196,15 @@ bool VertexFormat::operator<(const VertexFormat& other) const return mPureInteger < other.mPureInteger; } +bool Box::operator==(const Box &other) const +{ + return (x == other.x && y == other.y && z == other.z && + width == other.width && height == other.height && depth == other.depth); +} + +bool Box::operator!=(const Box &other) const +{ + return !(*this == other); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h index 642a6ec266..78fe6b0e26 100644 --- a/src/3rdparty/angle/src/libGLESv2/angletypes.h +++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h @@ -9,13 +9,13 @@ #ifndef LIBGLESV2_ANGLETYPES_H_ #define LIBGLESV2_ANGLETYPES_H_ -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "common/RefCountObject.h" -#include <float.h> namespace gl { class Buffer; +class State; class ProgramBinary; struct VertexAttribute; struct VertexAttribCurrentValueData; @@ -66,6 +66,8 @@ struct Box Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { } Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { } + bool operator==(const Box &other) const; + bool operator!=(const Box &other) const; }; struct Extents @@ -230,8 +232,7 @@ struct VertexFormat static void GetInputLayout(VertexFormat *inputLayout, ProgramBinary *programBinary, - const VertexAttribute *attributes, - const gl::VertexAttribCurrentValueData *currentValues); + const State& currentValues); bool operator==(const VertexFormat &other) const; bool operator!=(const VertexFormat &other) const; @@ -251,13 +252,6 @@ enum VertexConversionType VERTEX_CONVERT_BOTH = 3 }; -enum D3DWorkaroundType -{ - ANGLE_D3D_WORKAROUND_NONE, - ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION, - ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION -}; - } #endif // LIBGLESV2_ANGLETYPES_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp index 07f5d47473..587950a139 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp @@ -34,13 +34,12 @@ #include "libGLESv2/validationES3.h" #include "libGLESv2/queryconversions.h" - extern "C" { // OpenGL ES 2.0 functions -void __stdcall glActiveTexture(GLenum texture) +void GL_APIENTRY glActiveTexture(GLenum texture) { EVENT("(GLenum texture = 0x%X)", texture); @@ -57,7 +56,7 @@ void __stdcall glActiveTexture(GLenum texture) } } -void __stdcall glAttachShader(GLuint program, GLuint shader) +void GL_APIENTRY glAttachShader(GLuint program, GLuint shader) { EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); @@ -103,7 +102,7 @@ void __stdcall glAttachShader(GLuint program, GLuint shader) } } -void __stdcall glBeginQueryEXT(GLenum target, GLuint id) +void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); @@ -124,7 +123,7 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id) } } -void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) +void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) { EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); @@ -163,7 +162,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* } } -void __stdcall glBindBuffer(GLenum target, GLuint buffer) +void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer) { EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); @@ -210,7 +209,7 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer) } } -void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) +void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) { EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); @@ -235,7 +234,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) } } -void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) +void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer) { EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); @@ -252,7 +251,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) } } -void __stdcall glBindTexture(GLenum target, GLuint texture) +void GL_APIENTRY glBindTexture(GLenum target, GLuint texture) { EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); @@ -291,7 +290,7 @@ void __stdcall glBindTexture(GLenum target, GLuint texture) } } -void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", red, green, blue, alpha); @@ -304,12 +303,12 @@ void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp } } -void __stdcall glBlendEquation(GLenum mode) +void GL_APIENTRY glBlendEquation(GLenum mode) { glBlendEquationSeparate(mode, mode); } -void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); @@ -348,12 +347,12 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) } } -void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor) +void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); } -void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", srcRGB, dstRGB, srcAlpha, dstAlpha); @@ -488,7 +487,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha } } -void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) +void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", target, size, data, usage); @@ -550,7 +549,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, } } -void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) +void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", target, offset, size, data); @@ -611,7 +610,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, } } -GLenum __stdcall glCheckFramebufferStatus(GLenum target) +GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -626,13 +625,14 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); ASSERT(framebuffer); - return framebuffer->completeness(); + + return framebuffer->completeness(context->getData()); } return 0; } -void __stdcall glClear(GLbitfield mask) +void GL_APIENTRY glClear(GLbitfield mask) { EVENT("(GLbitfield mask = 0x%X)", mask); @@ -640,8 +640,9 @@ void __stdcall glClear(GLbitfield mask) if (context) { gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); + ASSERT(framebufferObject); - if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (framebufferObject->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return; @@ -662,7 +663,7 @@ void __stdcall glClear(GLbitfield mask) } } -void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", red, green, blue, alpha); @@ -674,7 +675,7 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp } } -void __stdcall glClearDepthf(GLclampf depth) +void GL_APIENTRY glClearDepthf(GLclampf depth) { EVENT("(GLclampf depth = %f)", depth); @@ -685,7 +686,7 @@ void __stdcall glClearDepthf(GLclampf depth) } } -void __stdcall glClearStencil(GLint s) +void GL_APIENTRY glClearStencil(GLint s) { EVENT("(GLint s = %d)", s); @@ -696,7 +697,7 @@ void __stdcall glClearStencil(GLint s) } } -void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)", red, green, blue, alpha); @@ -708,7 +709,7 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo } } -void __stdcall glCompileShader(GLuint shader) +void GL_APIENTRY glCompileShader(GLuint shader) { EVENT("(GLuint shader = %d)", shader); @@ -731,11 +732,11 @@ void __stdcall glCompileShader(GLuint shader) } } - shaderObject->compile(); + shaderObject->compile(context->getData()); } } -void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, +void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " @@ -771,7 +772,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->setCompressedImage(level, internalformat, width, height, imageSize, data); + gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -783,7 +789,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); + gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -794,7 +805,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna } } -void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " @@ -831,7 +842,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); + gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -843,7 +859,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); + gl::Error error = texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -854,7 +875,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs } } -void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", @@ -884,7 +905,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->copyImage(level, internalformat, x, y, width, height, framebuffer); + gl::Error error = texture->copyImage(level, internalformat, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -896,7 +922,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); + gl::Error error = texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -907,7 +938,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma } } -void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", @@ -937,7 +968,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -949,7 +985,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -960,7 +1001,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL } } -GLuint __stdcall glCreateProgram(void) +GLuint GL_APIENTRY glCreateProgram(void) { EVENT("()"); @@ -973,7 +1014,7 @@ GLuint __stdcall glCreateProgram(void) return 0; } -GLuint __stdcall glCreateShader(GLenum type) +GLuint GL_APIENTRY glCreateShader(GLenum type) { EVENT("(GLenum type = 0x%X)", type); @@ -995,7 +1036,7 @@ GLuint __stdcall glCreateShader(GLenum type) return 0; } -void __stdcall glCullFace(GLenum mode) +void GL_APIENTRY glCullFace(GLenum mode) { EVENT("(GLenum mode = 0x%X)", mode); @@ -1018,7 +1059,7 @@ void __stdcall glCullFace(GLenum mode) } } -void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) +void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers) { EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); @@ -1038,7 +1079,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) } } -void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) +void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences) { EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); @@ -1058,7 +1099,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) } } -void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) +void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); @@ -1081,7 +1122,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) } } -void __stdcall glDeleteProgram(GLuint program) +void GL_APIENTRY glDeleteProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -1111,7 +1152,7 @@ void __stdcall glDeleteProgram(GLuint program) } } -void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) +void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids) { EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); @@ -1131,7 +1172,7 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) } } -void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) +void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); @@ -1151,7 +1192,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) } } -void __stdcall glDeleteShader(GLuint shader) +void GL_APIENTRY glDeleteShader(GLuint shader) { EVENT("(GLuint shader = %d)", shader); @@ -1181,7 +1222,7 @@ void __stdcall glDeleteShader(GLuint shader) } } -void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) +void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures) { EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); @@ -1204,7 +1245,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) } } -void __stdcall glDepthFunc(GLenum func) +void GL_APIENTRY glDepthFunc(GLenum func) { EVENT("(GLenum func = 0x%X)", func); @@ -1231,7 +1272,7 @@ void __stdcall glDepthFunc(GLenum func) } } -void __stdcall glDepthMask(GLboolean flag) +void GL_APIENTRY glDepthMask(GLboolean flag) { EVENT("(GLboolean flag = %u)", flag); @@ -1242,7 +1283,7 @@ void __stdcall glDepthMask(GLboolean flag) } } -void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) +void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar) { EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); @@ -1253,7 +1294,7 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) } } -void __stdcall glDetachShader(GLuint program, GLuint shader) +void GL_APIENTRY glDetachShader(GLuint program, GLuint shader) { EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); @@ -1302,7 +1343,7 @@ void __stdcall glDetachShader(GLuint program, GLuint shader) } } -void __stdcall glDisable(GLenum cap) +void GL_APIENTRY glDisable(GLenum cap) { EVENT("(GLenum cap = 0x%X)", cap); @@ -1319,7 +1360,7 @@ void __stdcall glDisable(GLenum cap) } } -void __stdcall glDisableVertexAttribArray(GLuint index) +void GL_APIENTRY glDisableVertexAttribArray(GLuint index) { EVENT("(GLuint index = %d)", index); @@ -1336,7 +1377,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index) } } -void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) +void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); @@ -1357,7 +1398,7 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) } } -void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) { EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); @@ -1378,7 +1419,7 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun } } -void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) +void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", mode, count, type, indices); @@ -1401,7 +1442,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv } } -void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) +void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) { EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", mode, count, type, indices, primcount); @@ -1424,7 +1465,7 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t } } -void __stdcall glEnable(GLenum cap) +void GL_APIENTRY glEnable(GLenum cap) { EVENT("(GLenum cap = 0x%X)", cap); @@ -1441,7 +1482,7 @@ void __stdcall glEnable(GLenum cap) } } -void __stdcall glEnableVertexAttribArray(GLuint index) +void GL_APIENTRY glEnableVertexAttribArray(GLuint index) { EVENT("(GLuint index = %d)", index); @@ -1458,7 +1499,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index) } } -void __stdcall glEndQueryEXT(GLenum target) +void GL_APIENTRY glEndQueryEXT(GLenum target) { EVENT("GLenum target = 0x%X)", target); @@ -1479,7 +1520,7 @@ void __stdcall glEndQueryEXT(GLenum target) } } -void __stdcall glFinishFenceNV(GLuint fence) +void GL_APIENTRY glFinishFenceNV(GLuint fence) { EVENT("(GLuint fence = %d)", fence); @@ -1504,29 +1545,39 @@ void __stdcall glFinishFenceNV(GLuint fence) } } -void __stdcall glFinish(void) +void GL_APIENTRY glFinish(void) { EVENT("()"); gl::Context *context = gl::getNonLostContext(); if (context) { - context->sync(true); + gl::Error error = context->sync(true); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glFlush(void) +void GL_APIENTRY glFlush(void) { EVENT("()"); gl::Context *context = gl::getNonLostContext(); if (context) { - context->sync(false); + gl::Error error = context->sync(false); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); @@ -1548,33 +1599,19 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); ASSERT(framebuffer); - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (renderbuffer != 0) { - unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0); + gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); + framebuffer->setRenderbufferAttachment(attachment, renderbufferObject); } else { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: - framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); - break; - case GL_STENCIL_ATTACHMENT: - framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); - break; - case GL_DEPTH_STENCIL_ATTACHMENT: - framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); - break; - default: - UNREACHABLE(); - break; - } + framebuffer->setNULLAttachment(attachment); } } } -void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); @@ -1587,31 +1624,23 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t return; } - if (texture == 0) - { - textarget = GL_NONE; - } - gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + ASSERT(framebuffer); - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (texture != 0) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0); + gl::Texture *textureObj = context->getTexture(texture); + gl::ImageIndex index(textarget, level, gl::ImageIndex::ENTIRE_LEVEL); + framebuffer->setTextureAttachment(attachment, textureObj, index); } else { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, 0); break; - case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, 0); break; - case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break; - } + framebuffer->setNULLAttachment(attachment); } } } -void __stdcall glFrontFace(GLenum mode) +void GL_APIENTRY glFrontFace(GLenum mode) { EVENT("(GLenum mode = 0x%X)", mode); @@ -1631,7 +1660,7 @@ void __stdcall glFrontFace(GLenum mode) } } -void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) +void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers) { EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); @@ -1651,7 +1680,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) } } -void __stdcall glGenerateMipmap(GLenum target) +void GL_APIENTRY glGenerateMipmap(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -1721,11 +1750,16 @@ void __stdcall glGenerateMipmap(GLenum target) } } - texture->generateMipmaps(); + gl::Error error = texture->generateMipmaps(); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) +void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences) { EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); @@ -1745,7 +1779,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) } } -void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) +void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers) { EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); @@ -1765,7 +1799,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) } } -void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -1785,7 +1819,7 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) } } -void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) +void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) { EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); @@ -1805,7 +1839,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) } } -void __stdcall glGenTextures(GLsizei n, GLuint* textures) +void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures) { EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); @@ -1825,7 +1859,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures) } } -void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", @@ -1866,7 +1900,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, } } -void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", @@ -1908,7 +1942,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, } } -void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", program, maxcount, count, shaders); @@ -1942,7 +1976,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c } } -GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name) +GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name) { EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); @@ -1978,7 +2012,7 @@ GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name) return -1; } -void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) +void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); @@ -2003,7 +2037,7 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) } } -void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -2056,7 +2090,7 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params } } -GLenum __stdcall glGetError(void) +GLenum GL_APIENTRY glGetError(void) { EVENT("()"); @@ -2070,7 +2104,7 @@ GLenum __stdcall glGetError(void) return GL_NO_ERROR; } -void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) +void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) { EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); @@ -2094,19 +2128,40 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) switch (pname) { case GL_FENCE_STATUS_NV: + { + // GL_NV_fence spec: + // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV + // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + GLboolean status = GL_TRUE; + if (fenceObject->getStatus() != GL_TRUE) + { + gl::Error error = fenceObject->testFence(&status); + if (error.isError()) + { + context->recordError(error); + return; + } + } + *params = status; + break; + } + case GL_FENCE_CONDITION_NV: - break; + { + *params = fenceObject->getCondition(); + break; + } default: - context->recordError(gl::Error(GL_INVALID_ENUM)); - return; + { + context->recordError(gl::Error(GL_INVALID_ENUM)); + return; + } } - - params[0] = fenceObject->getFencei(pname); } } -void __stdcall glGetFloatv(GLenum pname, GLfloat* params) +void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params) { EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); @@ -2131,7 +2186,7 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params) } } -void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) +void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, attachment, pname, params); @@ -2214,6 +2269,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id(); gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle); + ASSERT(framebuffer); if (framebufferHandle == 0) { @@ -2428,7 +2484,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac } } -GLenum __stdcall glGetGraphicsResetStatusEXT(void) +GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void) { EVENT("()"); @@ -2442,7 +2498,7 @@ GLenum __stdcall glGetGraphicsResetStatusEXT(void) return GL_NO_ERROR; } -void __stdcall glGetIntegerv(GLenum pname, GLint* params) +void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params) { EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); @@ -2468,7 +2524,7 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params) } } -void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) +void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params) { EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); @@ -2552,7 +2608,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) } } -void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) +void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) { EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", program, bufsize, length, infolog); @@ -2578,7 +2634,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len } } -void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) +void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) { EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); @@ -2604,7 +2660,7 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) } } -void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) +void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) { EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); @@ -2656,7 +2712,7 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) } } -void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -2705,7 +2761,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* } } -void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) +void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params) { EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); @@ -2748,7 +2804,7 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) } } -void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) +void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", shader, bufsize, length, infolog); @@ -2774,7 +2830,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt } } -void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", shadertype, precisiontype, range, precision); @@ -2821,7 +2877,7 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp } } -void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", shader, bufsize, length, source); @@ -2847,7 +2903,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length } } -void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", shader, bufsize, length, source); @@ -2869,11 +2925,12 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, return; } - shaderObject->getTranslatedSource(bufsize, length, source); + // Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined + shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source); } } -const GLubyte* __stdcall glGetString(GLenum name) +const GLubyte* GL_APIENTRY glGetString(GLenum name) { EVENT("(GLenum name = 0x%X)", name); @@ -2919,7 +2976,7 @@ const GLubyte* __stdcall glGetString(GLenum name) } } -void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); @@ -3051,7 +3108,7 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) } } -void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -3098,7 +3155,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(gl::Error(GL_INVALID_ENUM)); return; } - *params = texture->immutableLevelCount(); + *params = static_cast<GLint>(texture->immutableLevelCount()); break; case GL_TEXTURE_USAGE_ANGLE: *params = texture->getUsage(); @@ -3183,7 +3240,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) } } -void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) +void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) { EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", program, location, bufSize, params); @@ -3205,7 +3262,7 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz } } -void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) +void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params) { EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); @@ -3226,7 +3283,7 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) } } -void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) +void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) { EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", program, location, bufSize, params); @@ -3248,7 +3305,7 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz } } -void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) +void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params) { EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); @@ -3269,7 +3326,7 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) } } -GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name) +GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name) { EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); @@ -3310,7 +3367,7 @@ GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name) return -1; } -void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) { EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); @@ -3344,7 +3401,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) } } -void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) +void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) { EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); @@ -3380,7 +3437,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) } } -void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) +void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) { EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); @@ -3403,7 +3460,7 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po } } -void __stdcall glHint(GLenum target, GLenum mode) +void GL_APIENTRY glHint(GLenum target, GLenum mode) { EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); @@ -3439,7 +3496,7 @@ void __stdcall glHint(GLenum target, GLenum mode) } } -GLboolean __stdcall glIsBuffer(GLuint buffer) +GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) { EVENT("(GLuint buffer = %d)", buffer); @@ -3457,7 +3514,7 @@ GLboolean __stdcall glIsBuffer(GLuint buffer) return GL_FALSE; } -GLboolean __stdcall glIsEnabled(GLenum cap) +GLboolean GL_APIENTRY glIsEnabled(GLenum cap) { EVENT("(GLenum cap = 0x%X)", cap); @@ -3476,7 +3533,7 @@ GLboolean __stdcall glIsEnabled(GLenum cap) return false; } -GLboolean __stdcall glIsFenceNV(GLuint fence) +GLboolean GL_APIENTRY glIsFenceNV(GLuint fence) { EVENT("(GLuint fence = %d)", fence); @@ -3496,7 +3553,7 @@ GLboolean __stdcall glIsFenceNV(GLuint fence) return GL_FALSE; } -GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) +GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer) { EVENT("(GLuint framebuffer = %d)", framebuffer); @@ -3514,7 +3571,7 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) return GL_FALSE; } -GLboolean __stdcall glIsProgram(GLuint program) +GLboolean GL_APIENTRY glIsProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -3532,7 +3589,7 @@ GLboolean __stdcall glIsProgram(GLuint program) return GL_FALSE; } -GLboolean __stdcall glIsQueryEXT(GLuint id) +GLboolean GL_APIENTRY glIsQueryEXT(GLuint id) { EVENT("(GLuint id = %d)", id); @@ -3545,7 +3602,7 @@ GLboolean __stdcall glIsQueryEXT(GLuint id) return GL_FALSE; } -GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) +GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer) { EVENT("(GLuint renderbuffer = %d)", renderbuffer); @@ -3563,7 +3620,7 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) return GL_FALSE; } -GLboolean __stdcall glIsShader(GLuint shader) +GLboolean GL_APIENTRY glIsShader(GLuint shader) { EVENT("(GLuint shader = %d)", shader); @@ -3581,7 +3638,7 @@ GLboolean __stdcall glIsShader(GLuint shader) return GL_FALSE; } -GLboolean __stdcall glIsTexture(GLuint texture) +GLboolean GL_APIENTRY glIsTexture(GLuint texture) { EVENT("(GLuint texture = %d)", texture); @@ -3599,7 +3656,7 @@ GLboolean __stdcall glIsTexture(GLuint texture) return GL_FALSE; } -void __stdcall glLineWidth(GLfloat width) +void GL_APIENTRY glLineWidth(GLfloat width) { EVENT("(GLfloat width = %f)", width); @@ -3616,7 +3673,7 @@ void __stdcall glLineWidth(GLfloat width) } } -void __stdcall glLinkProgram(GLuint program) +void GL_APIENTRY glLinkProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -3639,11 +3696,16 @@ void __stdcall glLinkProgram(GLuint program) } } - context->linkProgram(program); + gl::Error error = context->linkProgram(program); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glPixelStorei(GLenum pname, GLint param) +void GL_APIENTRY glPixelStorei(GLenum pname, GLint param) { EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); @@ -3699,7 +3761,7 @@ void __stdcall glPixelStorei(GLenum pname, GLint param) } } -void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) +void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units) { EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); @@ -3710,7 +3772,7 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) } } -void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, +void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data) { @@ -3742,7 +3804,7 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, } } -void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, +void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) { EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " @@ -3773,7 +3835,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, } } -void __stdcall glReleaseShaderCompiler(void) +void GL_APIENTRY glReleaseShaderCompiler(void) { EVENT("()"); @@ -3785,7 +3847,7 @@ void __stdcall glReleaseShaderCompiler(void) } } -void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, samples, internalformat, width, height); @@ -3799,16 +3861,22 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp return; } - context->setRenderbufferStorage(width, height, internalformat, samples); + gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + gl::Error error = renderbuffer->setStorage(width, height, internalformat, samples); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height); } -void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) +void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert) { EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert); @@ -3820,7 +3888,7 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) } } -void __stdcall glSetFenceNV(GLuint fence, GLenum condition) +void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition) { EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); @@ -3841,11 +3909,16 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition) return; } - fenceObject->setFence(condition); + gl::Error error = fenceObject->setFence(condition); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); @@ -3862,7 +3935,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) } } -void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) +void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) { EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", @@ -3883,7 +3956,7 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor } } -void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) +void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", shader, count, string, length); @@ -3917,12 +3990,12 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* } } -void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask) +void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask) { glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); } -void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); @@ -3970,12 +4043,12 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint } } -void __stdcall glStencilMask(GLuint mask) +void GL_APIENTRY glStencilMask(GLuint mask) { glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); } -void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) +void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask) { EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); @@ -4006,12 +4079,12 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) } } -void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) +void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); } -void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", face, fail, zfail, zpass); @@ -4094,7 +4167,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu } } -GLboolean __stdcall glTestFenceNV(GLuint fence) +GLboolean GL_APIENTRY glTestFenceNV(GLuint fence) { EVENT("(GLuint fence = %d)", fence); @@ -4115,13 +4188,21 @@ GLboolean __stdcall glTestFenceNV(GLuint fence) return GL_TRUE; } - return fenceObject->testFence(); + GLboolean result; + gl::Error error = fenceObject->testFence(&result); + if (error.isError()) + { + context->recordError(error); + return GL_TRUE; + } + + return result; } return GL_TRUE; } -void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, +void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " @@ -4150,51 +4231,38 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImagePosX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImageNegX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImagePosY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImageNegY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImagePosZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImageNegZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(target, level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; + default: UNREACHABLE(); } } } -void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) +void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); @@ -4238,12 +4306,12 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) } } -void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) +void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) { glTexParameterf(target, pname, (GLfloat)*params); } -void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) +void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); @@ -4287,12 +4355,12 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) } } -void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) +void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params) { glTexParameteri(target, pname, *params); } -void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, levels, internalformat, width, height); @@ -4323,14 +4391,24 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf case GL_TEXTURE_2D: { gl::Texture2D *texture2d = context->getTexture2D(); - texture2d->storage(levels, internalformat, width, height); + gl::Error error = texture2d->storage(levels, internalformat, width, height); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_CUBE_MAP: { gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); - textureCube->storage(levels, internalformat, width); + gl::Error error = textureCube->storage(levels, internalformat, width); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -4341,7 +4419,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf } } -void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " @@ -4377,7 +4455,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -4389,7 +4472,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -4399,12 +4487,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint } } -void __stdcall glUniform1f(GLint location, GLfloat x) +void GL_APIENTRY glUniform1f(GLint location, GLfloat x) { glUniform1fv(location, 1, &x); } -void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4421,12 +4509,12 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform1i(GLint location, GLint x) +void GL_APIENTRY glUniform1i(GLint location, GLint x) { glUniform1iv(location, 1, &x); } -void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4443,14 +4531,14 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) +void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y) { GLfloat xy[2] = {x, y}; glUniform2fv(location, 1, xy); } -void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4467,14 +4555,14 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform2i(GLint location, GLint x, GLint y) +void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y) { GLint xy[2] = {x, y}; glUniform2iv(location, 1, xy); } -void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4491,14 +4579,14 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) +void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { GLfloat xyz[3] = {x, y, z}; glUniform3fv(location, 1, xyz); } -void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4515,14 +4603,14 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) +void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z) { GLint xyz[3] = {x, y, z}; glUniform3iv(location, 1, xyz); } -void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4539,14 +4627,14 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { GLfloat xyzw[4] = {x, y, z, w}; glUniform4fv(location, 1, xyzw); } -void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4563,14 +4651,14 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) +void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { GLint xyzw[4] = {x, y, z, w}; glUniform4iv(location, 1, xyzw); } -void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4587,7 +4675,7 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -4605,7 +4693,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans } } -void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -4623,7 +4711,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans } } -void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -4641,7 +4729,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans } } -void __stdcall glUseProgram(GLuint program) +void GL_APIENTRY glUseProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -4674,7 +4762,7 @@ void __stdcall glUseProgram(GLuint program) } } -void __stdcall glValidateProgram(GLuint program) +void GL_APIENTRY glValidateProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -4701,7 +4789,7 @@ void __stdcall glValidateProgram(GLuint program) } } -void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) +void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x) { EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); @@ -4719,7 +4807,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) } } -void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4737,7 +4825,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) { EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); @@ -4755,7 +4843,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) } } -void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4773,7 +4861,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) { EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); @@ -4791,7 +4879,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) } } -void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4809,7 +4897,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); @@ -4827,7 +4915,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G } } -void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4844,7 +4932,7 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) +void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) { EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); @@ -4861,7 +4949,7 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) } } -void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) +void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) { EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", @@ -4936,7 +5024,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo } } -void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); @@ -4955,7 +5043,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) // OpenGL ES 3.0 functions -void __stdcall glReadBuffer(GLenum mode) +void GL_APIENTRY glReadBuffer(GLenum mode) { EVENT("(GLenum mode = 0x%X)", mode); @@ -4973,7 +5061,7 @@ void __stdcall glReadBuffer(GLenum mode) } } -void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) +void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) { EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, " "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices); @@ -4992,7 +5080,7 @@ void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize } } -void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " @@ -5020,14 +5108,24 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5038,7 +5136,7 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL } } -void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " @@ -5073,14 +5171,24 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5091,7 +5199,7 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint } } -void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", @@ -5129,11 +5237,16 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL return; } - texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); + gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " @@ -5168,14 +5281,24 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); + gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); + gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5186,7 +5309,7 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna } } -void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " @@ -5233,16 +5356,26 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, - format, imageSize, data); + gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, - format, imageSize, data); + gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5253,7 +5386,7 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs } } -void __stdcall glGenQueries(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenQueries(GLsizei n, GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -5279,7 +5412,7 @@ void __stdcall glGenQueries(GLsizei n, GLuint* ids) } } -void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids) +void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -5305,7 +5438,7 @@ void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids) } } -GLboolean __stdcall glIsQuery(GLuint id) +GLboolean GL_APIENTRY glIsQuery(GLuint id) { EVENT("(GLuint id = %u)", id); @@ -5324,7 +5457,7 @@ GLboolean __stdcall glIsQuery(GLuint id) return GL_FALSE; } -void __stdcall glBeginQuery(GLenum target, GLuint id) +void GL_APIENTRY glBeginQuery(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); @@ -5351,7 +5484,7 @@ void __stdcall glBeginQuery(GLenum target, GLuint id) } } -void __stdcall glEndQuery(GLenum target) +void GL_APIENTRY glEndQuery(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -5378,7 +5511,7 @@ void __stdcall glEndQuery(GLenum target) } } -void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -5410,7 +5543,7 @@ void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params) } } -void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) { EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params); @@ -5468,7 +5601,7 @@ void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) } } -GLboolean __stdcall glUnmapBuffer(GLenum target) +GLboolean GL_APIENTRY glUnmapBuffer(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -5487,7 +5620,7 @@ GLboolean __stdcall glUnmapBuffer(GLenum target) return GL_FALSE; } -void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) +void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); @@ -5504,7 +5637,7 @@ void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) } } -void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs) +void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum* bufs) { gl::Context *context = gl::getNonLostContext(); if (context) @@ -5519,7 +5652,7 @@ void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs) } } -void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5537,7 +5670,7 @@ void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5555,7 +5688,7 @@ void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5573,7 +5706,7 @@ void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5591,7 +5724,7 @@ void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5609,7 +5742,7 @@ void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5627,7 +5760,7 @@ void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, " "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)", @@ -5649,12 +5782,17 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr return; } - context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mask, filter); + gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, samples, internalformat, width, height); @@ -5674,11 +5812,12 @@ void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, return; } - context->setRenderbufferStorage(width, height, internalformat, samples); + gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + renderbuffer->setStorage(width, height, internalformat, samples); } } -void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)", target, attachment, texture, level, layer); @@ -5695,27 +5834,20 @@ void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuin gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); ASSERT(framebuffer); - gl::Texture *textureObject = context->getTexture(texture); - GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE; - - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (texture != 0) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer); + gl::Texture *textureObject = context->getTexture(texture); + gl::ImageIndex index(textureObject->getTarget(), level, layer); + framebuffer->setTextureAttachment(attachment, textureObject, index); } else { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, layer); break; - case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, layer); break; - case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break; - } + framebuffer->setNULLAttachment(attachment); } } } -GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +GLvoid* GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", target, offset, length, access); @@ -5735,7 +5867,7 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le return NULL; } -void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); @@ -5752,7 +5884,7 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip } } -void __stdcall glBindVertexArray(GLuint array) +void GL_APIENTRY glBindVertexArray(GLuint array) { EVENT("(GLuint array = %u)", array); @@ -5779,7 +5911,7 @@ void __stdcall glBindVertexArray(GLuint array) } } -void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays) +void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint* arrays) { EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays); @@ -5808,7 +5940,7 @@ void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays) } } -void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays) +void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint* arrays) { EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays); @@ -5834,7 +5966,7 @@ void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays) } } -GLboolean __stdcall glIsVertexArray(GLuint array) +GLboolean GL_APIENTRY glIsVertexArray(GLuint array) { EVENT("(GLuint array = %u)", array); @@ -5860,7 +5992,7 @@ GLboolean __stdcall glIsVertexArray(GLuint array) return GL_FALSE; } -void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data) +void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint* data) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)", target, index, data); @@ -5941,7 +6073,7 @@ void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data) } } -void __stdcall glBeginTransformFeedback(GLenum primitiveMode) +void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode) { EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode); @@ -5986,7 +6118,7 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode) } } -void __stdcall glEndTransformFeedback(void) +void GL_APIENTRY glEndTransformFeedback(void) { EVENT("(void)"); @@ -6012,7 +6144,7 @@ void __stdcall glEndTransformFeedback(void) } } -void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)", target, index, buffer, offset, size); @@ -6090,7 +6222,7 @@ void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi } } -void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer) +void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", target, index, buffer); @@ -6146,7 +6278,7 @@ void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer) } } -void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) +void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) { EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)", program, count, varyings, bufferMode); @@ -6195,7 +6327,7 @@ void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const } } -void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) { EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, " "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", @@ -6234,7 +6366,7 @@ void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz } } -void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) +void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) { EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)", index, size, type, stride, pointer); @@ -6304,7 +6436,7 @@ void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs } } -void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) { EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); @@ -6346,7 +6478,7 @@ void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) } } -void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) { EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)", index, pname, params); @@ -6388,7 +6520,7 @@ void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) } } -void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) { EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", index, x, y, z, w); @@ -6413,7 +6545,7 @@ void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint } } -void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) { EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", index, x, y, z, w); @@ -6438,7 +6570,7 @@ void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GL } } -void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v) +void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint* v) { EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v); @@ -6461,7 +6593,7 @@ void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v) } } -void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v) +void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint* v) { EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v); @@ -6484,7 +6616,7 @@ void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v) } } -void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params) +void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint* params) { EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)", program, location, params); @@ -6506,7 +6638,7 @@ void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params) } } -GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name) +GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name) { EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name); @@ -6547,30 +6679,30 @@ GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name) return 0; } -void __stdcall glUniform1ui(GLint location, GLuint v0) +void GL_APIENTRY glUniform1ui(GLint location, GLuint v0) { glUniform1uiv(location, 1, &v0); } -void __stdcall glUniform2ui(GLint location, GLuint v0, GLuint v1) +void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1) { const GLuint xy[] = { v0, v1 }; glUniform2uiv(location, 1, xy); } -void __stdcall glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) { const GLuint xyz[] = { v0, v1, v2 }; glUniform3uiv(location, 1, xyz); } -void __stdcall glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) { const GLuint xyzw[] = { v0, v1, v2, v3 }; glUniform4uiv(location, 1, xyzw); } -void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", location, count, value); @@ -6588,7 +6720,7 @@ void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", location, count, value); @@ -6606,7 +6738,7 @@ void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)", location, count, value); @@ -6624,7 +6756,7 @@ void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", location, count, value); @@ -6642,7 +6774,7 @@ void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) +void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)", buffer, drawbuffer, value); @@ -6687,7 +6819,7 @@ void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val } } -void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) +void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)", buffer, drawbuffer, value); @@ -6724,7 +6856,7 @@ void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v } } -void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) +void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)", buffer, drawbuffer, value); @@ -6769,7 +6901,7 @@ void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v } } -void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)", buffer, drawbuffer, depth, stencil); @@ -6806,7 +6938,7 @@ void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G } } -const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index) +const GLubyte* GL_APIENTRY glGetStringi(GLenum name, GLuint index) { EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index); @@ -6837,7 +6969,7 @@ const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index) return NULL; } -void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)", readTarget, writeTarget, readOffset, writeOffset, size); @@ -6851,7 +6983,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp return; } - if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget)) + if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, writeTarget)) { context->recordError(gl::Error(GL_INVALID_ENUM)); return; @@ -6881,7 +7013,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp return; } - if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size) + if (readBuffer == writeBuffer && std::abs(readOffset - writeOffset) < size) { context->recordError(gl::Error(GL_INVALID_VALUE)); return; @@ -6900,7 +7032,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp } } -void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) +void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) { EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)", program, uniformCount, uniformNames, uniformIndices); @@ -6954,7 +7086,7 @@ void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const G } } -void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) +void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) { EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, uniformCount, uniformIndices, pname, params); @@ -7034,7 +7166,7 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const } } -GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) +GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) { EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName); @@ -7075,7 +7207,7 @@ GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlo return 0; } -void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) { EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, uniformBlockIndex, pname, params); @@ -7134,7 +7266,7 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde } } -void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) { EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockIndex, bufSize, length, uniformBlockName); @@ -7176,7 +7308,7 @@ void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn } } -void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)", program, uniformBlockIndex, uniformBlockBinding); @@ -7225,7 +7357,7 @@ void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G } } -void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) +void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) { EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", mode, first, count, instanceCount); @@ -7244,7 +7376,7 @@ void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GL } } -void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) +void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) { EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)", mode, count, type, indices, instanceCount); @@ -7263,7 +7395,7 @@ void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, } } -GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags) +GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags) { EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags); @@ -7288,13 +7420,24 @@ GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags) return 0; } - return context->createFenceSync(condition); + GLsync fenceSync = context->createFenceSync(); + + gl::FenceSync *fenceSyncObject = context->getFenceSync(fenceSync); + gl::Error error = fenceSyncObject->set(condition); + if (error.isError()) + { + context->deleteFenceSync(fenceSync); + context->recordError(error); + return NULL; + } + + return fenceSync; } return NULL; } -GLboolean __stdcall glIsSync(GLsync sync) +GLboolean GL_APIENTRY glIsSync(GLsync sync) { EVENT("(GLsync sync = 0x%0.8p)", sync); @@ -7313,7 +7456,7 @@ GLboolean __stdcall glIsSync(GLsync sync) return GL_FALSE; } -void __stdcall glDeleteSync(GLsync sync) +void GL_APIENTRY glDeleteSync(GLsync sync) { EVENT("(GLsync sync = 0x%0.8p)", sync); @@ -7336,7 +7479,7 @@ void __stdcall glDeleteSync(GLsync sync) } } -GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags, timeout); @@ -7364,13 +7507,21 @@ GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeou return GL_WAIT_FAILED; } - return fenceSync->clientWait(flags, timeout); + GLenum result = GL_WAIT_FAILED; + gl::Error error = fenceSync->clientWait(flags, timeout, &result); + if (error.isError()) + { + context->recordError(error); + return GL_WAIT_FAILED; + } + + return result; } return GL_FALSE; } -void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags, timeout); @@ -7404,11 +7555,15 @@ void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) return; } - fenceSync->serverWait(); + gl::Error error = fenceSync->serverWait(flags, timeout); + if (error.isError()) + { + context->recordError(error); + } } } -void __stdcall glGetInteger64v(GLenum pname, GLint64* params) +void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64* params) { EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", pname, params); @@ -7440,7 +7595,7 @@ void __stdcall glGetInteger64v(GLenum pname, GLint64* params) } } -void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) { EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)", sync, pname, bufSize, length, values); @@ -7471,10 +7626,20 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* switch (pname) { case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break; - case GL_SYNC_STATUS: values[0] = static_cast<GLint>(fenceSync->getStatus()); break; case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break; case GL_SYNC_FLAGS: values[0] = 0; break; + case GL_SYNC_STATUS: + { + gl::Error error = fenceSync->getStatus(values); + if (error.isError()) + { + context->recordError(error); + return; + } + break; + } + default: context->recordError(gl::Error(GL_INVALID_ENUM)); return; @@ -7482,7 +7647,7 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* } } -void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)", target, index, data); @@ -7558,7 +7723,7 @@ void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) } } -void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname, params); @@ -7618,7 +7783,7 @@ void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa } } -void __stdcall glGenSamplers(GLsizei count, GLuint* samplers) +void GL_APIENTRY glGenSamplers(GLsizei count, GLuint* samplers) { EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers); @@ -7644,7 +7809,7 @@ void __stdcall glGenSamplers(GLsizei count, GLuint* samplers) } } -void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers) +void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint* samplers) { EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers); @@ -7670,7 +7835,7 @@ void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers) } } -GLboolean __stdcall glIsSampler(GLuint sampler) +GLboolean GL_APIENTRY glIsSampler(GLuint sampler) { EVENT("(GLuint sampler = %u)", sampler); @@ -7689,7 +7854,7 @@ GLboolean __stdcall glIsSampler(GLuint sampler) return GL_FALSE; } -void __stdcall glBindSampler(GLuint unit, GLuint sampler) +void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler) { EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler); @@ -7718,7 +7883,7 @@ void __stdcall glBindSampler(GLuint unit, GLuint sampler) } } -void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) +void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) { EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param); @@ -7751,12 +7916,12 @@ void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) } } -void __stdcall glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) +void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) { glSamplerParameteri(sampler, pname, *param); } -void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param); @@ -7789,12 +7954,12 @@ void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) } } -void __stdcall glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) +void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) { glSamplerParameterf(sampler, pname, *param); } -void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) { EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params); @@ -7822,7 +7987,7 @@ void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* para } } -void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) { EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params); @@ -7850,7 +8015,7 @@ void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* pa } } -void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor) +void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor) { EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor); @@ -7873,7 +8038,7 @@ void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor) } } -void __stdcall glBindTransformFeedback(GLenum target, GLuint id) +void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); @@ -7916,7 +8081,7 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id) } } -void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) +void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) { EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids); @@ -7936,7 +8101,7 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) } } -void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -7956,7 +8121,7 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) } } -GLboolean __stdcall glIsTransformFeedback(GLuint id) +GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id) { EVENT("(GLuint id = %u)", id); @@ -7975,7 +8140,7 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id) return GL_FALSE; } -void __stdcall glPauseTransformFeedback(void) +void GL_APIENTRY glPauseTransformFeedback(void) { EVENT("(void)"); @@ -8002,7 +8167,7 @@ void __stdcall glPauseTransformFeedback(void) } } -void __stdcall glResumeTransformFeedback(void) +void GL_APIENTRY glResumeTransformFeedback(void) { EVENT("(void)"); @@ -8029,7 +8194,7 @@ void __stdcall glResumeTransformFeedback(void) } } -void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) +void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) { EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)", program, bufSize, length, binaryFormat, binary); @@ -8048,7 +8213,7 @@ void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* leng } } -void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) +void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) { EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", program, binaryFormat, binary, length); @@ -8067,7 +8232,7 @@ void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid } } -void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value) +void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value) { EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", program, pname, value); @@ -8086,7 +8251,7 @@ void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value) } } -void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) +void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) { EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)", target, numAttachments, attachments); @@ -8106,14 +8271,21 @@ void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, co } gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) + ASSERT(framebuffer); + + if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE) { - framebuffer->invalidate(context->getCaps(), numAttachments, attachments); + gl::Error error = framebuffer->invalidate(context->getCaps(), numAttachments, attachments); + if (error.isError()) + { + context->recordError(error); + return; + } } } } -void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, " "GLint y = %d, GLsizei width = %d, GLsizei height = %d)", @@ -8134,14 +8306,21 @@ void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, } gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) + ASSERT(framebuffer); + + if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE) { - framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height); + gl::Error error = framebuffer->invalidateSub(numAttachments, attachments, x, y, width, height); + if (error.isError()) + { + context->recordError(error); + return; + } } } } -void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, levels, internalformat, width, height); @@ -8165,14 +8344,24 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform case GL_TEXTURE_2D: { gl::Texture2D *texture2d = context->getTexture2D(); - texture2d->storage(levels, internalformat, width, height); + gl::Error error = texture2d->storage(levels, internalformat, width, height); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_CUBE_MAP: { gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); - textureCube->storage(levels, internalformat, width); + gl::Error error = textureCube->storage(levels, internalformat, width); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -8183,7 +8372,7 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform } } -void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " "GLsizei height = %d, GLsizei depth = %d)", @@ -8208,14 +8397,24 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform case GL_TEXTURE_3D: { gl::Texture3D *texture3d = context->getTexture3D(); - texture3d->storage(levels, internalformat, width, height, depth); + gl::Error error = texture3d->storage(levels, internalformat, width, height, depth); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture2darray = context->getTexture2DArray(); - texture2darray->storage(levels, internalformat, width, height, depth); + gl::Error error = texture2darray->storage(levels, internalformat, width, height, depth); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -8225,7 +8424,7 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform } } -void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, " "GLint* params = 0x%0.8p)", @@ -8281,7 +8480,7 @@ void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenu // Extension functions -void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, +void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " @@ -8299,12 +8498,17 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi return; } - context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mask, filter); + gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, +void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " @@ -8315,7 +8519,7 @@ void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat UNIMPLEMENTED(); // FIXME } -void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, +void GL_APIENTRY glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) { EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", @@ -8340,15 +8544,16 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l return; } - if (!programBinary->save(binaryFormat, binary, bufSize, length)) + gl::Error error = programBinary->save(binaryFormat, binary, bufSize, length); + if (error.isError()) { - context->recordError(gl::Error(GL_INVALID_OPERATION)); + context->recordError(error); return; } } } -void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, +void GL_APIENTRY glProgramBinaryOES(GLuint program, GLenum binaryFormat, const void *binary, GLint length) { EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", @@ -8371,11 +8576,16 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, return; } - context->setProgramBinary(program, binaryFormat, binary, length); + gl::Error error = context->setProgramBinary(program, binaryFormat, binary, length); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) +void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs) { EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs); @@ -8388,6 +8598,8 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) return; } + ASSERT(context->getState().getDrawFramebuffer()); + if (context->getState().getDrawFramebuffer()->id() == 0) { if (n != 1) @@ -8416,6 +8628,7 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) } gl::Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + ASSERT(framebuffer); for (unsigned int colorAttachment = 0; colorAttachment < static_cast<unsigned int>(n); colorAttachment++) { @@ -8429,7 +8642,7 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) } } -void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params) +void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, void** params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); @@ -8461,7 +8674,7 @@ void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params } } -void * __stdcall glMapBufferOES(GLenum target, GLenum access) +void * GL_APIENTRY glMapBufferOES(GLenum target, GLenum access) { EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access); @@ -8507,7 +8720,7 @@ void * __stdcall glMapBufferOES(GLenum target, GLenum access) return NULL; } -GLboolean __stdcall glUnmapBufferOES(GLenum target) +GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -8543,7 +8756,7 @@ GLboolean __stdcall glUnmapBufferOES(GLenum target) return GL_FALSE; } -void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", target, offset, length, access); @@ -8638,7 +8851,7 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr return NULL; } -void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length) +void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); @@ -8686,7 +8899,7 @@ void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsi } } -__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname) +__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname) { struct Extension { @@ -8744,7 +8957,7 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * // Non-public functions used by EGL -bool __stdcall glBindTexImage(egl::Surface *surface) +bool EGLAPIENTRY glBindTexImage(egl::Surface *surface) { EVENT("(egl::Surface* surface = 0x%0.8p)", surface); diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp index 51447e273a..00f63ae079 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.cpp +++ b/src/3rdparty/angle/src/libGLESv2/main.cpp @@ -11,24 +11,42 @@ #include "common/tls.h" -#if defined(ANGLE_PLATFORM_WINRT) -__declspec(thread) -#endif -static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; +static TLSIndex currentTLS = TLS_INVALID_INDEX; namespace gl { -Current *AllocateCurrent() +// TODO(kbr): figure out how these are going to be managed on +// non-Windows platforms. These routines would need to be exported +// from ANGLE and called cooperatively when users create and destroy +// threads -- or the initialization of the TLS index, and allocation +// of thread-local data, will have to be done lazily. Will have to use +// destructor function with pthread_create_key on POSIX platforms to +// clean up thread-local data. + +// Call this exactly once at process startup. +bool CreateThreadLocalIndex() { -#if defined(ANGLE_PLATFORM_WINRT) - if (currentTLS == TLS_OUT_OF_INDEXES) + currentTLS = CreateTLSIndex(); + if (currentTLS == TLS_INVALID_INDEX) { - currentTLS = CreateTLSIndex(); + return false; } -#endif - ASSERT(currentTLS != TLS_OUT_OF_INDEXES); - if (currentTLS == TLS_OUT_OF_INDEXES) + return true; +} + +// Call this exactly once at process shutdown. +void DestroyThreadLocalIndex() +{ + DestroyTLSIndex(currentTLS); + currentTLS = TLS_INVALID_INDEX; +} + +// Call this upon thread startup. +Current *AllocateCurrent() +{ + ASSERT(currentTLS != TLS_INVALID_INDEX); + if (currentTLS == TLS_INVALID_INDEX) { return NULL; } @@ -46,14 +64,9 @@ Current *AllocateCurrent() return current; } +// Call this upon thread shutdown. void DeallocateCurrent() { -#if defined(ANGLE_PLATFORM_WINRT) - if (currentTLS == TLS_OUT_OF_INDEXES) - { - return; - } -#endif Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS)); SafeDelete(current); SetTLSValue(currentTLS, NULL); @@ -61,22 +74,21 @@ void DeallocateCurrent() } -#ifndef QT_OPENGL_ES_2_ANGLE_STATIC - +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC) extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: { -#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain - return DisableThreadLibraryCalls(instance); -#endif - currentTLS = CreateTLSIndex(); - if (currentTLS == TLS_OUT_OF_INDEXES) + if (!gl::CreateThreadLocalIndex()) { return FALSE; } + +#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS + gl::InitializeDebugAnnotations(); +#endif } // Fall through to initialize index case DLL_THREAD_ATTACH: @@ -91,9 +103,11 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved break; case DLL_PROCESS_DETACH: { -#if !defined(ANGLE_PLATFORM_WINRT) gl::DeallocateCurrent(); - DestroyTLSIndex(currentTLS); + gl::DestroyThreadLocalIndex(); + +#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS + gl::UninitializeDebugAnnotations(); #endif } break; @@ -103,8 +117,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved return TRUE; } - -#endif // !QT_OPENGL_ES_2_ANGLE_STATIC +#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC namespace gl { @@ -152,7 +165,7 @@ Context *getNonLostContext() { if (context->isContextLost()) { - gl::error(GL_OUT_OF_MEMORY); + context->recordError(Error(GL_OUT_OF_MEMORY, "Context has been lost.")); return NULL; } else @@ -170,32 +183,4 @@ egl::Display *getDisplay() return current->display; } -// Records an error code -void error(GLenum errorCode) -{ - gl::Context *context = glGetCurrentContext(); - context->recordError(Error(errorCode)); - - switch (errorCode) - { - case GL_INVALID_ENUM: - TRACE("\t! Error generated: invalid enum\n"); - break; - case GL_INVALID_VALUE: - TRACE("\t! Error generated: invalid value\n"); - break; - case GL_INVALID_OPERATION: - TRACE("\t! Error generated: invalid operation\n"); - break; - case GL_OUT_OF_MEMORY: - TRACE("\t! Error generated: out of memory\n"); - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - TRACE("\t! Error generated: invalid framebuffer operation\n"); - break; - default: UNREACHABLE(); - } -} - } - diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h index c30ad3375c..dff02787f5 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.h +++ b/src/3rdparty/angle/src/libGLESv2/main.h @@ -14,14 +14,11 @@ #include <GLES2/gl2.h> #include <EGL/egl.h> -#ifndef Sleep -#define Sleep(ms) WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE) -#endif - namespace egl { class Display; class Surface; +class AttributeMap; } namespace gl @@ -40,16 +37,6 @@ Context *getContext(); Context *getNonLostContext(); egl::Display *getDisplay(); -void error(GLenum errorCode); - -template<class T> -const T &error(GLenum errorCode, const T &returnValue) -{ - error(errorCode); - - return returnValue; -} - } namespace rx @@ -64,11 +51,11 @@ gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, void glDestroyContext(gl::Context *context); void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface); gl::Context *glGetCurrentContext(); -rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType); +rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap); void glDestroyRenderer(rx::Renderer *renderer); -__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname); -bool __stdcall glBindTexImage(egl::Surface *surface); +__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname); +bool EGLAPIENTRY glBindTexImage(egl::Surface *surface); } #endif // LIBGLESV2_MAIN_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h index f0b5f02227..c031effabd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h @@ -12,6 +12,8 @@ #include "common/angleutils.h" #include "libGLESv2/Buffer.h" +#include <cstdint> + namespace rx { @@ -21,7 +23,6 @@ class BufferImpl virtual ~BufferImpl() { } virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0; - virtual void *getData() = 0; virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0; virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h index d54e6becd3..1dd46785d9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h @@ -4,29 +4,47 @@ // found in the LICENSE file. // -// FenceImpl.h: Defines the rx::FenceImpl class. +// FenceImpl.h: Defines the rx::FenceNVImpl and rx::FenceSyncImpl classes. #ifndef LIBGLESV2_RENDERER_FENCEIMPL_H_ #define LIBGLESV2_RENDERER_FENCEIMPL_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" +#include "angle_gl.h" + namespace rx { -class FenceImpl +class FenceNVImpl +{ + public: + FenceNVImpl() { }; + virtual ~FenceNVImpl() { }; + + virtual gl::Error set() = 0; + virtual gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) = 0; + virtual gl::Error finishFence(GLboolean *outFinished) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(FenceNVImpl); +}; + +class FenceSyncImpl { public: - FenceImpl() { }; - virtual ~FenceImpl() { }; + FenceSyncImpl() { }; + virtual ~FenceSyncImpl() { }; - virtual bool isSet() const = 0; - virtual void set() = 0; - virtual bool test(bool flushCommandBuffer) = 0; - virtual bool hasError() const = 0; + virtual gl::Error set() = 0; + virtual gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) = 0; + virtual gl::Error serverWait(GLbitfield flags, GLuint64 timeout) = 0; + virtual gl::Error getStatus(GLint *outResult) = 0; private: - DISALLOW_COPY_AND_ASSIGN(FenceImpl); + DISALLOW_COPY_AND_ASSIGN(FenceSyncImpl); }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp index 370b086233..5b9b75f562 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp @@ -4,18 +4,20 @@ // found in the LICENSE file. // -// Image.h: Implements the rx::Image class, an abstract base class for the +// Image.h: Implements the rx::Image class, an abstract base class for the // renderer-specific classes which will define the interface to the underlying // surfaces or resources. #include "libGLESv2/renderer/Image.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/main.h" namespace rx { Image::Image() { - mWidth = 0; + mWidth = 0; mHeight = 0; mDepth = 0; mInternalFormat = GL_NONE; @@ -25,4 +27,20 @@ Image::Image() mDirty = false; } +gl::Error Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source) +{ + gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); + ASSERT(colorbuffer); + + RenderTarget *renderTarget = NULL; + gl::Error error = GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) + { + return error; + } + + ASSERT(renderTarget); + return copy(xoffset, yoffset, zoffset, area, renderTarget); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h index 3bfc663762..9071a88c67 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// Image.h: Defines the rx::Image class, an abstract base class for the +// Image.h: Defines the rx::Image class, an abstract base class for the // renderer-specific classes which will define the interface to the underlying // surfaces or resources. @@ -12,18 +12,22 @@ #define LIBGLESV2_RENDERER_IMAGE_H_ #include "common/debug.h" +#include "libGLESv2/Error.h" #include <GLES2/gl2.h> namespace gl { class Framebuffer; +struct Rectangle; +struct ImageIndex; } namespace rx { - -class Renderer; +class RendererD3D; +class RenderTarget; +class TextureStorage; class Image { @@ -43,14 +47,17 @@ class Image void markClean() {mDirty = false;} virtual bool isDirty() const = 0; - virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0; + virtual bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0; - virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input) = 0; - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input) = 0; + virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) = 0; + virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input) = 0; - virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; + gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0; + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, + const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0; protected: GLsizei mWidth; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp index f68ac383de..d472e1499e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp @@ -111,11 +111,7 @@ IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c) bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const { -#if defined(_MSC_VER) && _MSC_VER < 1600 - return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); -#else return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count); -#endif } IndexRangeCache::IndexBounds::IndexBounds() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp new file mode 100644 index 0000000000..f9fcad38a4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp @@ -0,0 +1,146 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. + +#include "libGLESv2/renderer/ProgramImpl.h" + +#include "common/utilities.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +namespace +{ + +unsigned int ParseAndStripArrayIndex(std::string* name) +{ + unsigned int subscript = GL_INVALID_INDEX; + + // Strip any trailing array operator and retrieve the subscript + size_t open = name->find_last_of('['); + size_t close = name->find_last_of(']'); + if (open != std::string::npos && close == name->length() - 1) + { + subscript = atoi(name->substr(open + 1).c_str()); + name->erase(open); + } + + return subscript; +} + +} + +ProgramImpl::~ProgramImpl() +{ + // Ensure that reset was called by the inherited class during destruction + ASSERT(mUniformIndex.size() == 0); +} + +gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const +{ + ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size()); + return mUniforms[mUniformIndex[location].index]; +} + +gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const +{ + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + if (mUniforms[uniformIndex]->name == name) + { + return mUniforms[uniformIndex]; + } + } + + return NULL; +} + +gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const +{ + ASSERT(blockIndex < mUniformBlocks.size()); + return mUniformBlocks[blockIndex]; +} + +GLint ProgramImpl::getUniformLocation(std::string name) +{ + unsigned int subscript = ParseAndStripArrayIndex(&name); + + unsigned int numUniforms = mUniformIndex.size(); + for (unsigned int location = 0; location < numUniforms; location++) + { + if (mUniformIndex[location].name == name) + { + const int index = mUniformIndex[location].index; + const bool isArray = mUniforms[index]->isArray(); + + if ((isArray && mUniformIndex[location].element == subscript) || + (subscript == GL_INVALID_INDEX)) + { + return location; + } + } + } + + return -1; +} + +GLuint ProgramImpl::getUniformIndex(std::string name) +{ + unsigned int subscript = ParseAndStripArrayIndex(&name); + + // The app is not allowed to specify array indices other than 0 for arrays of basic types + if (subscript != 0 && subscript != GL_INVALID_INDEX) + { + return GL_INVALID_INDEX; + } + + unsigned int numUniforms = mUniforms.size(); + for (unsigned int index = 0; index < numUniforms; index++) + { + if (mUniforms[index]->name == name) + { + if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) + { + return index; + } + } + } + + return GL_INVALID_INDEX; +} + +GLuint ProgramImpl::getUniformBlockIndex(std::string name) const +{ + unsigned int subscript = ParseAndStripArrayIndex(&name); + + unsigned int numUniformBlocks = mUniformBlocks.size(); + for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) + { + const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; + if (uniformBlock.name == name) + { + const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); + if (subscript == uniformBlock.elementIndex || arrayElementZero) + { + return blockIndex; + } + } + } + + return GL_INVALID_INDEX; +} + +void ProgramImpl::reset() +{ + SafeDeleteContainer(mUniforms); + mUniformIndex.clear(); + SafeDeleteContainer(mUniformBlocks); + mTransformFeedbackLinkedVaryings.clear(); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h index ba0955fdf8..6aaa23cf89 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h @@ -13,44 +13,113 @@ #include "libGLESv2/BinaryStream.h" #include "libGLESv2/Constants.h" #include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Shader.h" +#include "libGLESv2/renderer/Renderer.h" + +#include <map> namespace rx { -class DynamicHLSL; -class Renderer; - class ProgramImpl { -public: - virtual ~ProgramImpl() { } + public: + ProgramImpl() { } + virtual ~ProgramImpl(); + + const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; } + const std::vector<gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; } + const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; } + const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; } + const sh::Attribute *getShaderAttributes() const { return mShaderAttributes; } + + std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; } + std::vector<gl::VariableLocation> &getUniformIndices() { return mUniformIndex; } + std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; } + std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; } + sh::Attribute *getShaderAttributes() { return mShaderAttributes; } + + gl::LinkedUniform *getUniformByLocation(GLint location) const; + gl::LinkedUniform *getUniformByName(const std::string &name) const; + gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const; - // TODO: Temporary interfaces to ease migration. Remove soon! - virtual Renderer *getRenderer() = 0; - virtual DynamicHLSL *getDynamicHLSL() = 0; - virtual const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() = 0; + GLint getUniformLocation(std::string name); + GLuint getUniformIndex(std::string name); + GLuint getUniformBlockIndex(std::string name) const; + + virtual bool usesPointSize() const = 0; + virtual int getShaderVersion() const = 0; + virtual GLenum getTransformFeedbackBufferMode() const = 0; virtual GLenum getBinaryFormat() = 0; - virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; - virtual bool save(gl::BinaryOutputStream *stream) = 0; - - virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, - const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) = 0; - virtual rx::ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, - const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const sh::Attribute shaderAttributes[], - const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) = 0; - - virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector<std::string> &transformFeedbackVaryings, int *registers, - std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, - gl::VariableLocation> *outputVariables) = 0; - - virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0; - - virtual void reset() = 0; + virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; + virtual gl::Error save(gl::BinaryOutputStream *stream) = 0; + + virtual gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, + gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode, + int *registers, std::vector<gl::LinkedVarying> *linkedVaryings, + std::map<int, gl::VariableLocation> *outputVariables) = 0; + + virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform1iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform2iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform3iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform4iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + + virtual void getUniformfv(GLint location, GLfloat *params) = 0; + virtual void getUniformiv(GLint location, GLint *params) = 0; + virtual void getUniformuiv(GLint location, GLuint *params) = 0; + + virtual void reset(); + + // TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to + // determine if they can be removed from this interface. + virtual GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const = 0; + virtual GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const = 0; + virtual GLint getUsedSamplerRange(gl::SamplerType type) const = 0; + virtual void updateSamplerMapping() = 0; + virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0; + + virtual gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + int registers) = 0; + + virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps) = 0; + virtual bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, + const gl::Caps &caps) = 0; + + virtual gl::Error applyUniforms() = 0; + virtual gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps) = 0; + virtual bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, + unsigned int registerIndex, const gl::Caps &caps) = 0; + + protected: + DISALLOW_COPY_AND_ASSIGN(ProgramImpl); + + std::vector<gl::LinkedUniform*> mUniforms; + std::vector<gl::VariableLocation> mUniformIndex; + std::vector<gl::UniformBlock*> mUniformBlocks; + std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings; + + sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS]; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp new file mode 100644 index 0000000000..857fdc9dae --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget.cpp: Implements serial handling for rx::RenderTarget + +#include "libGLESv2/renderer/RenderTarget.h" + +namespace rx +{ +unsigned int RenderTarget::mCurrentSerial = 1; + +RenderTarget::RenderTarget() + : mSerial(issueSerials(1)) +{ +} + +RenderTarget::~RenderTarget() +{ +} + +unsigned int RenderTarget::getSerial() const +{ + return mSerial; +} + +unsigned int RenderTarget::issueSerials(unsigned int count) +{ + unsigned int firstSerial = mCurrentSerial; + mCurrentSerial += count; + return firstSerial; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h index 44637ec7de..3bdfb0cc98 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h @@ -18,28 +18,22 @@ namespace rx class RenderTarget { public: - RenderTarget() - { - mWidth = 0; - mHeight = 0; - mDepth = 0; - mInternalFormat = GL_NONE; - mActualFormat = GL_NONE; - mSamples = 0; - } + RenderTarget(); + virtual ~RenderTarget(); - virtual ~RenderTarget() {}; - - GLsizei getWidth() const { return mWidth; } - GLsizei getHeight() const { return mHeight; } - GLsizei getDepth() const { return mDepth; } - GLenum getInternalFormat() const { return mInternalFormat; } - GLenum getActualFormat() const { return mActualFormat; } - GLsizei getSamples() const { return mSamples; } - gl::Extents getExtents() const { return gl::Extents(mWidth, mHeight, mDepth); } + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLsizei getDepth() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLenum getActualFormat() const = 0; + virtual GLsizei getSamples() const = 0; + gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); } virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) = 0; + virtual unsigned int getSerial() const; + static unsigned int issueSerials(unsigned int count); + struct Desc { GLsizei width; GLsizei height; @@ -47,16 +41,11 @@ class RenderTarget GLenum format; }; - protected: - GLsizei mWidth; - GLsizei mHeight; - GLsizei mDepth; - GLenum mInternalFormat; - GLenum mActualFormat; - GLsizei mSamples; - private: DISALLOW_COPY_AND_ASSIGN(RenderTarget); + + const unsigned int mSerial; + static unsigned int mCurrentSerial; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp new file mode 100644 index 0000000000..770ae8e9c6 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp @@ -0,0 +1,21 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferImpl.h: Implements the shared methods of the abstract class gl::RenderbufferImpl + +#include "libGLESv2/renderer/RenderbufferImpl.h" + +namespace rx +{ +RenderbufferImpl::RenderbufferImpl() +{ +} + +RenderbufferImpl::~RenderbufferImpl() +{ +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h new file mode 100644 index 0000000000..52e070f1d3 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h @@ -0,0 +1,41 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferImpl.h: Defines the abstract class gl::RenderbufferImpl + +#ifndef LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_ +#define LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_ + +#include "angle_gl.h" + +#include "libGLESv2/Error.h" + +#include "common/angleutils.h" + +namespace rx +{ + +class RenderbufferImpl +{ + public: + RenderbufferImpl(); + virtual ~RenderbufferImpl() = 0; + + virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) = 0; + + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLenum getActualFormat() const = 0; + virtual GLsizei getSamples() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderbufferImpl); +}; + +} + +#endif // LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp index 910d0285f1..df3dae1e38 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp @@ -6,11 +6,12 @@ // Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. +#include "common/utilities.h" +#include "libEGL/AttributeMap.h" #include "libGLESv2/main.h" -#include "libGLESv2/Program.h" #include "libGLESv2/renderer/Renderer.h" -#include "common/utilities.h" -#include "libGLESv2/Shader.h" + +#include <EGL/eglext.h> #if defined (ANGLE_ENABLE_D3D9) #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" @@ -29,15 +30,12 @@ #define ANGLE_DEFAULT_D3D11 0 #endif -#include <EGL/eglext.h> - namespace rx { -Renderer::Renderer(egl::Display *display) - : mDisplay(display), - mCapsInitialized(false), - mCurrentClientVersion(2) +Renderer::Renderer() + : mCapsInitialized(false), + mWorkaroundsInitialized(false) { } @@ -78,12 +76,23 @@ const gl::Extensions &Renderer::getRendererExtensions() const return mExtensions; } -typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, EGLint); +const Workarounds &Renderer::getWorkarounds() const +{ + if (!mWorkaroundsInitialized) + { + mWorkarounds = generateWorkarounds(); + mWorkaroundsInitialized = true; + } + + return mWorkarounds; +} + +typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, const egl::AttributeMap &); template <typename RendererType> -Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType) +Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attributes) { - return new RendererType(display, nativeDisplay, requestedDisplayType); + return new RendererType(display, nativeDisplay, attributes); } } @@ -91,15 +100,16 @@ Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDispl extern "C" { -rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType) +rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap) { std::vector<rx::CreateRendererFunction> rendererCreationFunctions; + EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + # if defined(ANGLE_ENABLE_D3D11) if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE || - requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE || - requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE) + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) { rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>); } @@ -138,7 +148,7 @@ rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativ for (size_t i = 0; i < rendererCreationFunctions.size(); i++) { - rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, requestedDisplayType); + rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, attribMap); if (renderer->initialize() == EGL_SUCCESS) { return renderer; @@ -155,7 +165,8 @@ rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativ void glDestroyRenderer(rx::Renderer *renderer) { - delete renderer; + ASSERT(renderer); + SafeDelete(renderer); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h index b2249741ab..b85895a938 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h @@ -10,10 +10,13 @@ #ifndef LIBGLESV2_RENDERER_RENDERER_H_ #define LIBGLESV2_RENDERER_RENDERER_H_ -#include "libGLESv2/Uniform.h" -#include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" #include "libGLESv2/Error.h" +#include "libGLESv2/Uniform.h" +#include "libGLESv2/angletypes.h" +#include "libGLESv2/renderer/Workarounds.h" +#include "common/NativeWindow.h" +#include "common/mathutil.h" #include <cstdint> @@ -32,37 +35,26 @@ class Display; namespace gl { -class InfoLog; -class ProgramBinary; -struct LinkedVarying; -struct VertexAttribute; class Buffer; -class Texture; class Framebuffer; -struct VertexAttribCurrentValueData; +struct Data; } namespace rx { -class TextureStorage; -class VertexBuffer; -class IndexBuffer; class QueryImpl; -class FenceImpl; +class FenceNVImpl; +class FenceSyncImpl; class BufferImpl; class VertexArrayImpl; -class BufferStorage; -struct TranslatedIndexData; class ShaderImpl; class ProgramImpl; -class ShaderExecutable; -class SwapChain; -class RenderTarget; -class Image; -class TextureStorage; -class UniformStorage; class TextureImpl; class TransformFeedbackImpl; +class RenderbufferImpl; +struct TranslatedIndexData; +struct Workarounds; +class SwapChain; struct ConfigDesc { @@ -73,30 +65,10 @@ struct ConfigDesc bool es3Capable; }; -struct dx_VertexConstants -{ - float depthRange[4]; - float viewAdjust[4]; -}; - -struct dx_PixelConstants -{ - float depthRange[4]; - float viewCoords[4]; - float depthFront[4]; -}; - -enum ShaderType -{ - SHADER_VERTEX, - SHADER_PIXEL, - SHADER_GEOMETRY -}; - class Renderer { public: - explicit Renderer(egl::Display *display); + Renderer(); virtual ~Renderer(); virtual EGLint initialize() = 0; @@ -105,163 +77,116 @@ class Renderer virtual int generateConfigs(ConfigDesc **configDescList) = 0; virtual void deleteConfigs(ConfigDesc *configDescList) = 0; - virtual void sync(bool block) = 0; - - virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; + virtual gl::Error sync(bool block) = 0; - virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0; - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; + virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, + GLint first, GLsizei count, GLsizei instances) = 0; + virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instances, + const RangeUI &indexRange) = 0; - virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; + virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0; + virtual gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0; + virtual gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0; + virtual gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values) = 0; + virtual gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0; - virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0; - virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) = 0; - virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) = 0; + virtual gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, void* pixels) = 0; - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0; - virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport) = 0; - - virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; - virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) = 0; - virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary) = 0; - virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; - virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) = 0; - virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; - virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0; - - virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0; - virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; - - virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0; - - virtual void markAllStateDirty() = 0; - - // lost device - virtual void notifyDeviceLost() = 0; - virtual bool isDeviceLost() = 0; - virtual bool testDeviceLost(bool notify) = 0; - virtual bool testDeviceResettable() = 0; - - // Renderer capabilities (virtual because it is used by egl::Display, do not override) - virtual const gl::Caps &getRendererCaps() const; - virtual const gl::TextureCapsMap &getRendererTextureCaps() const; - virtual const gl::Extensions &getRendererExtensions() const; - - virtual DWORD getAdapterVendor() const = 0; - virtual std::string getRendererDescription() const = 0; - virtual GUID getAdapterIdentifier() const = 0; + virtual gl::Error blitFramebuffer(const gl::Data &data, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) = 0; - virtual unsigned int getReservedVertexUniformVectors() const = 0; - virtual unsigned int getReservedFragmentUniformVectors() const = 0; - virtual unsigned int getReservedVertexUniformBuffers() const = 0; - virtual unsigned int getReservedFragmentUniformBuffers() const = 0; + // TODO(jmadill): caps? and virtual for egl::Display virtual bool getShareHandleSupport() const = 0; virtual bool getPostSubBufferSupport() const = 0; - virtual int getMajorShaderModel() const = 0; - virtual int getMinSwapInterval() const = 0; - virtual int getMaxSwapInterval() const = 0; - - // Pixel operations - virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) = 0; - virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) = 0; - virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) = 0; - virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) = 0; - - virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0; - virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0; - virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; - virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; - - virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) = 0; - - virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0; - - // RenderTarget creation - virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0; - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples) = 0; - // Shader creation - virtual ShaderImpl *createShader(GLenum type) = 0; + virtual ShaderImpl *createShader(const gl::Data &data, GLenum type) = 0; virtual ProgramImpl *createProgram() = 0; // Shader operations virtual void releaseShaderCompiler() = 0; - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers) = 0; - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround) = 0; - virtual UniformStorage *createUniformStorage(size_t storageSize) = 0; - - // Image operations - virtual Image *createImage() = 0; - virtual void generateMipmap(Image *dest, Image *source) = 0; - virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0; - virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0; - virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0; - virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; - virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; // Texture creation virtual TextureImpl *createTexture(GLenum target) = 0; + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer() = 0; + virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth) = 0; + // Buffer creation virtual BufferImpl *createBuffer() = 0; - virtual VertexBuffer *createVertexBuffer() = 0; - virtual IndexBuffer *createIndexBuffer() = 0; // Vertex Array creation virtual VertexArrayImpl *createVertexArray() = 0; // Query and Fence creation virtual QueryImpl *createQuery(GLenum type) = 0; - virtual FenceImpl *createFence() = 0; + virtual FenceNVImpl *createFenceNV() = 0; + virtual FenceSyncImpl *createFenceSync() = 0; // Transform Feedback creation - virtual TransformFeedbackImpl* createTransformFeedback() = 0; + virtual TransformFeedbackImpl *createTransformFeedback() = 0; - // Current GLES client version - void setCurrentClientVersion(int clientVersion) { mCurrentClientVersion = clientVersion; } - int getCurrentClientVersion() const { return mCurrentClientVersion; } + // lost device + //TODO(jmadill): investigate if this stuff is necessary in GL + virtual void notifyDeviceLost() = 0; + virtual bool isDeviceLost() = 0; + virtual bool testDeviceLost(bool notify) = 0; + virtual bool testDeviceResettable() = 0; - // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; - virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0; + virtual DWORD getAdapterVendor() const = 0; + virtual std::string getRendererDescription() const = 0; + virtual GUID getAdapterIdentifier() const = 0; - virtual bool getLUID(LUID *adapterLuid) const = 0; - virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0; - virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0; + // Renderer capabilities (virtual because of egl::Display) + virtual const gl::Caps &getRendererCaps() const; + const gl::TextureCapsMap &getRendererTextureCaps() const; + virtual const gl::Extensions &getRendererExtensions() const; + const Workarounds &getWorkarounds() const; - protected: - egl::Display *mDisplay; + // TODO(jmadill): needed by egl::Display, probably should be removed + virtual int getMajorShaderModel() const = 0; + virtual int getMinSwapInterval() const = 0; + virtual int getMaxSwapInterval() const = 0; + virtual bool getLUID(LUID *adapterLuid) const = 0; private: DISALLOW_COPY_AND_ASSIGN(Renderer); virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0; + virtual Workarounds generateWorkarounds() const = 0; mutable bool mCapsInitialized; mutable gl::Caps mCaps; mutable gl::TextureCapsMap mTextureCaps; mutable gl::Extensions mExtensions; - int mCurrentClientVersion; + mutable bool mWorkaroundsInitialized; + mutable Workarounds mWorkarounds; +}; + +struct dx_VertexConstants +{ + float depthRange[4]; + float viewAdjust[4]; +}; + +struct dx_PixelConstants +{ + float depthRange[4]; + float viewCoords[4]; + float depthFront[4]; +}; + +enum ShaderType +{ + SHADER_VERTEX, + SHADER_PIXEL, + SHADER_GEOMETRY }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h index f17195673d..f1a96d74fb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h @@ -40,10 +40,21 @@ class ShaderExecutable return mFunctionBuffer.size(); } + const std::string &getDebugInfo() const + { + return mDebugInfo; + } + + void appendDebugInfo(const std::string &info) + { + mDebugInfo += info; + } + private: DISALLOW_COPY_AND_ASSIGN(ShaderExecutable); std::vector<uint8_t> mFunctionBuffer; + std::string mDebugInfo; }; class UniformStorage @@ -64,4 +75,4 @@ class UniformStorage } -#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ +#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h index de5d30e6fe..cb0d360f0b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h @@ -23,9 +23,10 @@ class ShaderImpl ShaderImpl() { } virtual ~ShaderImpl() { } - virtual bool compile(const std::string &source) = 0; + virtual bool compile(const gl::Data &data, const std::string &source) = 0; virtual const std::string &getInfoLog() const = 0; virtual const std::string &getTranslatedSource() const = 0; + virtual std::string getDebugInfo() const = 0; const std::vector<gl::PackedVarying> &getVaryings() const { return mVaryings; } const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h index 1ec702f299..1417e0bdf6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h @@ -11,28 +11,24 @@ #define LIBGLESV2_RENDERER_SWAPCHAIN_H_ #include "common/angleutils.h" +#include "common/NativeWindow.h" #include "common/platform.h" #include <GLES2/gl2.h> #include <EGL/egl.h> -#include <EGL/eglplatform.h> + +#if !defined(ANGLE_FORCE_VSYNC_OFF) +#define ANGLE_FORCE_VSYNC_OFF 0 +#endif namespace rx { -enum SwapFlags -{ - SWAP_NORMAL = 0, - SWAP_ROTATE_90 = 1, - SWAP_ROTATE_270 = 2, - SWAP_ROTATE_180 = SWAP_ROTATE_90|SWAP_ROTATE_270, -}; - class SwapChain { public: - SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) + SwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) + : mNativeWindow(nativeWindow), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) { } @@ -40,13 +36,16 @@ class SwapChain virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0; virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) = 0; + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; virtual void recreate() = 0; + GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; } + GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; } + virtual HANDLE getShareHandle() {return mShareHandle;}; protected: - const EGLNativeWindowType mWindow; // Window that the surface is created for. + rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. const GLenum mBackBufferFormat; const GLenum mDepthBufferFormat; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h index e3cc50d680..3e662557e4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_TEXTUREIMPL_H_ #include "common/angleutils.h" +#include "libGLESv2/Error.h" #include "angle_gl.h" @@ -31,19 +32,12 @@ namespace rx { class Image; -class Renderer; -class TextureStorage; class TextureImpl { public: virtual ~TextureImpl() {}; - // TODO: If this methods could go away that would be ideal; - // TextureStorage should only be necessary for the D3D backend, and as such - // higher level code should not rely on it. - virtual TextureStorage *getNativeTexture() = 0; - // Deprecated in favour of the ImageIndex method virtual Image *getImage(int level, int layer) const = 0; virtual Image *getImage(const gl::ImageIndex &index) const = 0; @@ -51,15 +45,15 @@ class TextureImpl virtual void setUsage(GLenum usage) = 0; - virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0; - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; + virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; + virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; + virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual void generateMipmaps() = 0; + virtual gl::Error generateMipmaps() = 0; virtual void bindTexImage(egl::Surface *surface) = 0; virtual void releaseTexImage() = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h new file mode 100644 index 0000000000..20a166fb7a --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angletypes.h: Workarounds for driver bugs and other issues. + +#ifndef LIBGLESV2_RENDERER_WORKAROUNDS_H_ +#define LIBGLESV2_RENDERER_WORKAROUNDS_H_ + +// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate +// independent of ANGLE's renderer. Workarounds should also be accessible +// outside of the Renderer. + +namespace rx +{ + +enum D3DWorkaroundType +{ + ANGLE_D3D_WORKAROUND_NONE, + ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION, + ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION +}; + +struct Workarounds +{ + Workarounds() + : mrtPerfWorkaround(false), + setDataFasterThanImageUpload(false) + {} + + bool mrtPerfWorkaround; + bool setDataFasterThanImageUpload; +}; + +} + +#endif // LIBGLESV2_RENDERER_WORKAROUNDS_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp index 004223d70f..aabc9f04e9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp @@ -6,7 +6,7 @@ // copyimage.cpp: Defines image copying functions -#include "libGLESv2/renderer/copyImage.h" +#include "libGLESv2/renderer/copyimage.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp index a34ef03fb8..dd0d3f52ad 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp @@ -9,7 +9,6 @@ #include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/d3d/VertexBuffer.h" #include "libGLESv2/renderer/d3d/IndexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/main.h" namespace rx @@ -37,6 +36,13 @@ BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer) return static_cast<BufferD3D*>(buffer); } +BufferD3D *BufferD3D::makeFromBuffer(gl::Buffer *buffer) +{ + BufferImpl *impl = buffer->getImplementation(); + ASSERT(impl); + return makeBufferD3D(impl); +} + void BufferD3D::updateSerial() { mSerial = mNextSerial++; @@ -46,11 +52,11 @@ void BufferD3D::initializeStaticData() { if (!mStaticVertexBuffer) { - mStaticVertexBuffer = new rx::StaticVertexBufferInterface(getRenderer()); + mStaticVertexBuffer = new StaticVertexBufferInterface(getRenderer()); } if (!mStaticIndexBuffer) { - mStaticIndexBuffer = new rx::StaticIndexBufferInterface(getRenderer()); + mStaticIndexBuffer = new StaticIndexBufferInterface(getRenderer()); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h index 44f14cee58..1a1308c545 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h @@ -12,10 +12,11 @@ #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/angletypes.h" +#include <cstdint> + namespace rx { - -class Renderer; +class RendererD3D; class StaticIndexBufferInterface; class StaticVertexBufferInterface; @@ -26,15 +27,17 @@ class BufferD3D : public BufferImpl virtual ~BufferD3D(); static BufferD3D *makeBufferD3D(BufferImpl *buffer); + static BufferD3D *makeFromBuffer(gl::Buffer *buffer); unsigned int getSerial() const { return mSerial; } + virtual gl::Error getData(const uint8_t **outData) = 0; virtual size_t getSize() const = 0; virtual bool supportsDirectBinding() const = 0; - virtual Renderer* getRenderer() = 0; + virtual RendererD3D *getRenderer() = 0; - rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; } - rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; } + StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; } + StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; } void initializeStaticData(); void invalidateStaticData(); @@ -46,8 +49,8 @@ class BufferD3D : public BufferImpl void updateSerial(); - rx::StaticVertexBufferInterface *mStaticVertexBuffer; - rx::StaticIndexBufferInterface *mStaticIndexBuffer; + StaticVertexBufferInterface *mStaticVertexBuffer; + StaticIndexBufferInterface *mStaticIndexBuffer; unsigned int mUnmodifiedDataUse; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp index 13411ebe64..3d5bfe0cbe 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp @@ -8,10 +8,10 @@ #include "libGLESv2/renderer/d3d/DynamicHLSL.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/Shader.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/Program.h" #include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Shader.h" #include "libGLESv2/formatutils.h" #include "common/utilities.h" @@ -22,6 +22,9 @@ META_ASSERT(GL_INVALID_INDEX == UINT_MAX); using namespace gl; +namespace rx +{ + namespace { @@ -70,7 +73,7 @@ std::string HLSLTypeString(GLenum type) return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type)); } -const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::PixelShaderOutputVariable> &outputVariables, +const PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables, unsigned int location) { for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex) @@ -85,15 +88,12 @@ const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::P return outputVariables[0]; } -} - -namespace rx -{ - const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; -DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer) +} + +DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) { } @@ -225,8 +225,8 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 // Returns the number of used varying registers, or -1 if unsuccesful -int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader, - rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings) +int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader, + ShaderD3D *vertexShader, const std::vector<std::string> &transformFeedbackVaryings) { // TODO (geofflang): Use context's caps const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; @@ -262,6 +262,13 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++) { const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex]; + + if (transformFeedbackVarying == "gl_Position" || transformFeedbackVarying == "gl_PointSize") + { + // do not pack builtin XFB varyings + continue; + } + if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end()) { bool found = false; @@ -281,7 +288,7 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad } } - if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize") + if (!found) { infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str()); return -1; @@ -400,7 +407,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s // data reinterpretation (eg for pure integer->float, float->pure integer) // TODO: issue warning with gl debug info extension, when supported if (IsMatrixType(shaderAttribute.type) || - (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0) + (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0) { initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute); } @@ -639,7 +646,7 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, } } -void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, +void DynamicHLSL::storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<LinkedVarying> *linkedVaryings) const { const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize); @@ -662,10 +669,11 @@ void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, } } -bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing, - std::string& pixelHLSL, std::string& vertexHLSL, - rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader, - const std::vector<std::string>& transformFeedbackVaryings, +bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, int registers, + const VaryingPacking packing, + std::string &pixelHLSL, std::string &vertexHLSL, + ShaderD3D *fragmentShader, ShaderD3D *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, std::vector<LinkedVarying> *linkedVaryings, std::map<int, VariableLocation> *programOutputVars, std::vector<PixelShaderOutputVariable> *outPixelShaderKey, @@ -691,21 +699,17 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const // Write the HLSL input/output declarations const int shaderModel = mRenderer->getMajorShaderModel(); - - // TODO (geofflang): Use context's caps - const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; - const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0); // Two cases when writing to gl_FragColor and using ESSL 1.0: // - with a 3.0 context, the output color is copied to channel 0 // - with a 2.0 context, the output color is broadcast to all channels - const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3); - const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getRendererCaps().maxDrawBuffers : 1); + const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3); + const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1); int shaderVersion = vertexShader->getShaderVersion(); - if (registersNeeded > maxVaryingVectors) + if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors) { infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); return false; @@ -772,7 +776,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const for (int row = 0; row < variableRows; row++) { - int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row; + int r = varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row; vertexHLSL += " output.v" + Str(r); vertexHLSL += " = _" + varying.name; @@ -920,7 +924,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); for (int row = 0; row < variableRows; row++) { - std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row); + std::string n = Str(varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row); pixelHLSL += " _" + varying.name; if (varying.isArray()) @@ -966,7 +970,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const return true; } -void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const +void DynamicHLSL::defineOutputVariables(ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const { const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables(); @@ -994,14 +998,14 @@ void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map< } } -std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const +std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const { // for now we only handle point sprite emulation ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4); return generatePointSpriteHLSL(registers, fragmentShader, vertexShader); } -std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const +std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const { ASSERT(registers >= 0); ASSERT(vertexShader->mUsesPointSize); @@ -1047,7 +1051,7 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *f "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n" "{\n" " GS_OUTPUT output = (GS_OUTPUT)0;\n" - " output.gl_Position = input[0].gl_Position;\n"; + " output.gl_Position = input[0].gl_Position;\n" " output.gl_PointSize = input[0].gl_PointSize;\n"; for (int r = 0; r < registers; r++) @@ -1135,7 +1139,7 @@ void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLen } else { - bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0); + bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0); signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h index f68ed98401..c46bbf6ce0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h @@ -10,18 +10,13 @@ #define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_ #include "common/angleutils.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "angle_gl.h" #include <vector> #include <map> -namespace rx -{ -class Renderer; -} - namespace sh { struct Attribute; @@ -36,11 +31,12 @@ struct LinkedVarying; struct VertexAttribute; struct VertexFormat; struct PackedVarying; +struct Data; } namespace rx { -class Renderer; +class RendererD3D; class ShaderD3D; typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4]; @@ -56,30 +52,31 @@ struct PixelShaderOutputVariable class DynamicHLSL { public: - explicit DynamicHLSL(rx::Renderer *const renderer); + explicit DynamicHLSL(RendererD3D *const renderer); - int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader, - rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings); + int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader, + ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings); std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[], const sh::Attribute shaderAttributes[]) const; std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables, bool usesFragDepth, const std::vector<GLenum> &outputLayout) const; - bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing, - std::string& pixelHLSL, std::string& vertexHLSL, - rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader, - const std::vector<std::string>& transformFeedbackVaryings, + bool generateShaderLinkHLSL(const gl::Data &data, gl::InfoLog &infoLog, int registers, + const VaryingPacking packing, + std::string &pixelHLSL, std::string &vertexHLSL, + ShaderD3D *fragmentShader, ShaderD3D *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *programOutputVars, std::vector<PixelShaderOutputVariable> *outPixelShaderKey, bool *outUsesFragDepth) const; - std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const; + std::string generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const; void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; private: DISALLOW_COPY_AND_ASSIGN(DynamicHLSL); - rx::Renderer *const mRenderer; + RendererD3D *const mRenderer; struct SemanticInfo; @@ -88,10 +85,10 @@ class DynamicHLSL bool pixelShader) const; std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; std::string generateVaryingHLSL(const ShaderD3D *shader) const; - void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const; + void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const; void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const; - void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const; - std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const; + void defineOutputVariables(ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const; + std::string generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const; // Prepend an underscore static std::string decorateVariable(const std::string &name); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp index d0131974ee..776d92b202 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp @@ -8,34 +8,116 @@ #include "libGLESv2/Program.h" #include "libGLESv2/main.h" +#include "common/features.h" #include "common/utilities.h" -#include "common/platform.h" -#if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL) +#ifndef QT_D3DCOMPILER_DLL +#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL +#endif +#ifndef D3DCOMPILE_RESERVED16 +#define D3DCOMPILE_RESERVED16 (1 << 16) +#endif +#ifndef D3DCOMPILE_RESERVED17 +#define D3DCOMPILE_RESERVED17 (1 << 17) +#endif -// Add define + typedefs for older MinGW-w64 headers (pre 5783) +// Definitions local to the translation unit +namespace +{ -#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" +#ifdef CREATE_COMPILER_FLAG_INFO + #undef CREATE_COMPILER_FLAG_INFO +#endif -HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, - const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); -typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, - const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); +#define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag } -#endif // __MINGW32__ && !D3DCOMPILER_DLL +struct CompilerFlagInfo +{ + UINT mFlag; + const char *mName; +}; -#ifndef QT_D3DCOMPILER_DLL -#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL -#endif +CompilerFlagInfo CompilerFlagInfos[] = +{ + // NOTE: The data below is copied from d3dcompiler.h + // If something changes there it should be changed here as well + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_DEBUG), // (1 << 0) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_VALIDATION), // (1 << 1) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_OPTIMIZATION), // (1 << 2) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR), // (1 << 3) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR), // (1 << 4) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PARTIAL_PRECISION), // (1 << 5) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT), // (1 << 6) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT), // (1 << 7) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_NO_PRESHADER), // (1 << 8) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_AVOID_FLOW_CONTROL), // (1 << 9) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PREFER_FLOW_CONTROL), // (1 << 10) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_STRICTNESS), // (1 << 11) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY), // (1 << 12) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_IEEE_STRICTNESS), // (1 << 13) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL0), // (1 << 14) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL1), // 0 + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL2), // ((1 << 14) | (1 << 15)) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL3), // (1 << 15) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED16), // (1 << 16) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED17), // (1 << 17) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_WARNINGS_ARE_ERRORS) // (1 << 18) +}; + +#undef CREATE_COMPILER_FLAG_INFO + +bool IsCompilerFlagSet(UINT mask, UINT flag) +{ + bool isFlagSet = IsMaskFlagSet(mask, flag); + + switch(flag) + { + case D3DCOMPILE_OPTIMIZATION_LEVEL0: + return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL3)); + + case D3DCOMPILE_OPTIMIZATION_LEVEL1: + return (mask & D3DCOMPILE_OPTIMIZATION_LEVEL2) == UINT(0); + + case D3DCOMPILE_OPTIMIZATION_LEVEL3: + return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL0)); + + default: + return isFlagSet; + } +} + +const char *GetCompilerFlagName(UINT mask, size_t flagIx) +{ + const CompilerFlagInfo &flagInfo = CompilerFlagInfos[flagIx]; + if (IsCompilerFlagSet(mask, flagInfo.mFlag)) + { + return flagInfo.mName; + } + + return nullptr; +} + +} namespace rx { +CompileConfig::CompileConfig() + : flags(0), + name() +{ +} + +CompileConfig::CompileConfig(UINT flags, const std::string &name) + : flags(flags), + name(name) +{ +} + HLSLCompiler::HLSLCompiler() : mD3DCompilerModule(NULL), - mD3DCompileFunc(NULL) + mD3DCompileFunc(NULL), + mD3DDisassembleFunc(NULL) { } @@ -46,7 +128,7 @@ HLSLCompiler::~HLSLCompiler() bool HLSLCompiler::initialize() { -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; @@ -85,15 +167,30 @@ bool HLSLCompiler::initialize() if (!mD3DCompilerModule) { + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. + mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL); + } + + if (!mD3DCompilerModule) + { ERR("No D3D compiler module found - aborting!\n"); return false; } - mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile")); + mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile")); ASSERT(mD3DCompileFunc); + + mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(GetProcAddress(mD3DCompilerModule, "D3DDisassemble")); + ASSERT(mD3DDisassembleFunc); + #else - mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(&D3DCompile); + // D3D Shader compiler is linked already into this module, so the export + // can be directly assigned. + mD3DCompilerModule = NULL; + mD3DCompileFunc = reinterpret_cast<pD3DCompile>(D3DCompile); + mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(D3DDisassemble); #endif + return mD3DCompileFunc != NULL; } @@ -104,61 +201,133 @@ void HLSLCompiler::release() FreeLibrary(mD3DCompilerModule); mD3DCompilerModule = NULL; mD3DCompileFunc = NULL; + mD3DDisassembleFunc = NULL; } } -ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, - const UINT optimizationFlags[], const char *flagNames[], int attempts) const +gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile, + const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros, + ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const { -#if !defined(ANGLE_PLATFORM_WINRT) - ASSERT(mD3DCompilerModule && mD3DCompileFunc); +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + ASSERT(mD3DCompilerModule); #endif + ASSERT(mD3DCompileFunc); - if (!hlsl) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + if (gl::perfActive()) { - return NULL; + std::string sourcePath = getTempPath(); + std::string sourceText = FormatString("#line 2 \"%s\"\n\n%s", sourcePath.c_str(), hlsl.c_str()); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } +#endif + + const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL; - pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); - for (int i = 0; i < attempts; ++i) + for (size_t i = 0; i < configs.size(); ++i) { ID3DBlob *errorMessage = NULL; ID3DBlob *binary = NULL; - HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage); + HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(), + configs[i].flags, 0, &binary, &errorMessage); if (errorMessage) { - const char *message = (const char*)errorMessage->GetBufferPointer(); + std::string message = reinterpret_cast<const char*>(errorMessage->GetBufferPointer()); + SafeRelease(errorMessage); - infoLog.appendSanitized(message); - TRACE("\n%s", hlsl); - TRACE("\n%s", message); + infoLog.appendSanitized(message.c_str()); + TRACE("\n%s", hlsl.c_str()); + TRACE("\n%s", message.c_str()); - SafeRelease(errorMessage); + if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute" + { + macros = NULL; // Disable [loop] and [flatten] + + // Retry without changing compiler flags + i--; + continue; + } } if (SUCCEEDED(result)) { - return (ShaderBlob*)binary; + *outCompiledBlob = binary; + +#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED + (*outDebugInfo) += "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n"; + (*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n"; + (*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n"; + for (size_t fIx = 0; fIx < ArraySize(CompilerFlagInfos); ++fIx) + { + const char *flagName = GetCompilerFlagName(configs[i].flags, fIx); + if (flagName != nullptr) + { + (*outDebugInfo) += std::string("// ") + flagName + "\n"; + } + } + + (*outDebugInfo) += "// Macros:\n"; + if (macros == nullptr) + { + (*outDebugInfo) += "// - : -\n"; + } + else + { + for (const D3D_SHADER_MACRO *mIt = macros; mIt->Name != nullptr; ++mIt) + { + (*outDebugInfo) += std::string("// ") + mIt->Name + " : " + mIt->Definition + "\n"; + } + } + + (*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n"; +#endif + + return gl::Error(GL_NO_ERROR); } else { if (result == E_OUTOFMEMORY) { - return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL); + *outCompiledBlob = NULL; + return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result); } - infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]); + infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str()); - if (i + 1 < attempts) + if (i + 1 < configs.size()) { - infoLog.append(" Retrying with %s.\n", flagNames[i + 1]); + infoLog.append(" Retrying with %s.\n", configs[i + 1].name.c_str()); } } } - return NULL; + // None of the configurations succeeded in compiling this shader but the compiler is still intact + *outCompiledBlob = NULL; + return gl::Error(GL_NO_ERROR); +} + +std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const +{ + // Retrieve disassembly + UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING; + ID3DBlob *disassembly = NULL; + pD3DDisassemble disassembleFunc = reinterpret_cast<pD3DDisassemble>(mD3DDisassembleFunc); + LPCVOID buffer = shaderBinary->GetBufferPointer(); + SIZE_T bufSize = shaderBinary->GetBufferSize(); + HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly); + + std::string asmSrc; + if (SUCCEEDED(result)) + { + asmSrc = reinterpret_cast<const char*>(disassembly->GetBufferPointer()); + } + + SafeRelease(disassembly); + + return asmSrc; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h index 0ce9e44be5..ff56f8035a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h @@ -1,7 +1,13 @@ #ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ #define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" +#include "common/platform.h" + +#include <vector> +#include <string> namespace gl { @@ -11,8 +17,14 @@ class InfoLog; namespace rx { -typedef void* ShaderBlob; -typedef void(*CompileFuncPtr)(); +struct CompileConfig +{ + UINT flags; + std::string name; + + CompileConfig(); + CompileConfig(UINT flags, const std::string &name); +}; class HLSLCompiler { @@ -23,14 +35,20 @@ class HLSLCompiler bool initialize(); void release(); - ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, - const UINT optimizationFlags[], const char *flagNames[], int attempts) const; + // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob + // even if no GL errors are returned. + gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile, + const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros, + ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const; + + std::string disassembleBinary(ID3DBlob* shaderBinary) const; private: DISALLOW_COPY_AND_ASSIGN(HLSLCompiler); HMODULE mD3DCompilerModule; - CompileFuncPtr mD3DCompileFunc; + pD3DCompile mD3DCompileFunc; + pD3DDisassemble mD3DDisassembleFunc; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp index 0854b968da..12b919ab5a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp @@ -19,8 +19,8 @@ ImageD3D::ImageD3D() ImageD3D *ImageD3D::makeImageD3D(Image *img) { - ASSERT(HAS_DYNAMIC_TYPE(rx::ImageD3D*, img)); - return static_cast<rx::ImageD3D*>(img); + ASSERT(HAS_DYNAMIC_TYPE(ImageD3D*, img)); + return static_cast<ImageD3D*>(img); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h index 60a6ffdf37..554ca0cee0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h @@ -17,6 +17,8 @@ namespace gl { class Framebuffer; +struct ImageIndex; +struct Box; } namespace rx @@ -33,14 +35,11 @@ class ImageD3D : public Image virtual bool isDirty() const = 0; - virtual void setManagedSurface2D(TextureStorage *storage, int level) {}; - virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {}; - virtual void setManagedSurface3D(TextureStorage *storage, int level) {}; - virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {}; - virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; - virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; - virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0; + virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) = 0; private: DISALLOW_COPY_AND_ASSIGN(ImageD3D); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp index 1dce1270d8..aa614f6cc4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp @@ -8,7 +8,7 @@ // class with derivations, classes that perform graphics API agnostic index buffer operations. #include "libGLESv2/renderer/d3d/IndexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" namespace rx { @@ -35,7 +35,7 @@ void IndexBuffer::updateSerial() } -IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) +IndexBufferInterface::IndexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer) { mIndexBuffer = renderer->createIndexBuffer(); @@ -130,7 +130,7 @@ gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum in } } -StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true) +StreamingIndexBufferInterface::StreamingIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, true) { } @@ -165,7 +165,7 @@ gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, G } -StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) +StaticIndexBufferInterface::StaticIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, false) { } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h index 1bb5ae2c4a..a34d30bbf3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h @@ -16,7 +16,7 @@ namespace rx { -class Renderer; +class RendererD3D; class IndexBuffer { @@ -50,7 +50,7 @@ class IndexBuffer class IndexBufferInterface { public: - IndexBufferInterface(Renderer *renderer, bool dynamic); + IndexBufferInterface(RendererD3D *renderer, bool dynamic); virtual ~IndexBufferInterface(); virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0; @@ -76,7 +76,7 @@ class IndexBufferInterface private: DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface); - rx::Renderer *const mRenderer; + RendererD3D *const mRenderer; IndexBuffer* mIndexBuffer; @@ -87,7 +87,7 @@ class IndexBufferInterface class StreamingIndexBufferInterface : public IndexBufferInterface { public: - StreamingIndexBufferInterface(Renderer *renderer); + StreamingIndexBufferInterface(RendererD3D *renderer); ~StreamingIndexBufferInterface(); virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType); @@ -96,7 +96,7 @@ class StreamingIndexBufferInterface : public IndexBufferInterface class StaticIndexBufferInterface : public IndexBufferInterface { public: - explicit StaticIndexBufferInterface(Renderer *renderer); + explicit StaticIndexBufferInterface(RendererD3D *renderer); ~StaticIndexBufferInterface(); virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp index 8d455b4bf3..eddd9de887 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp @@ -10,7 +10,7 @@ #include "libGLESv2/renderer/d3d/IndexDataManager.h" #include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/d3d/IndexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/main.h" #include "libGLESv2/formatutils.h" @@ -57,7 +57,7 @@ static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void else UNREACHABLE(); } -IndexDataManager::IndexDataManager(Renderer *renderer) +IndexDataManager::IndexDataManager(RendererD3D *renderer) : mRenderer(renderer), mStreamingBufferShort(NULL), mStreamingBufferInt(NULL) @@ -97,7 +97,14 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize()); - indices = static_cast<const GLubyte*>(storage->getData()) + offset; + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL; @@ -183,7 +190,16 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf return error; } - ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output); + const uint8_t *dataPointer = reinterpret_cast<const uint8_t*>(indices); + if (staticBuffer) + { + error = storage->getData(&dataPointer); + if (error.isError()) + { + return error; + } + } + ConvertIndices(type, destinationIndexType, dataPointer, convertCount, output); error = indexBuffer->unmapBuffer(); if (error.isError()) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h index 6d0b89e6d4..a1aee1588b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h @@ -33,7 +33,7 @@ class StaticIndexBufferInterface; class StreamingIndexBufferInterface; class IndexBuffer; class BufferD3D; -class Renderer; +class RendererD3D; struct TranslatedIndexData { @@ -50,7 +50,7 @@ struct TranslatedIndexData class IndexDataManager { public: - explicit IndexDataManager(Renderer *renderer); + explicit IndexDataManager(RendererD3D *renderer); virtual ~IndexDataManager(); gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); @@ -60,7 +60,7 @@ class IndexDataManager DISALLOW_COPY_AND_ASSIGN(IndexDataManager); - Renderer *const mRenderer; + RendererD3D *const mRenderer; StreamingIndexBufferInterface *mStreamingBufferShort; StreamingIndexBufferInterface *mStreamingBufferInt; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp index d7d97cc2bd..75da78110e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp @@ -8,27 +8,163 @@ #include "libGLESv2/renderer/d3d/ProgramD3D.h" +#include "common/features.h" #include "common/utilities.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/Program.h" #include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/main.h" #include "libGLESv2/renderer/ShaderExecutable.h" #include "libGLESv2/renderer/d3d/DynamicHLSL.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/main.h" namespace rx { -ProgramD3D::ProgramD3D(rx::Renderer *renderer) +namespace +{ + +GLenum GetTextureType(GLenum samplerType) +{ + switch (samplerType) + { + case GL_SAMPLER_2D: + case GL_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + return GL_TEXTURE_2D; + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_3D: + return GL_TEXTURE_3D; + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + return GL_TEXTURE_CUBE_MAP; + case GL_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + return GL_TEXTURE_CUBE_MAP; + case GL_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + return GL_TEXTURE_2D_ARRAY; + default: UNREACHABLE(); + } + + return GL_TEXTURE_2D; +} + +void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]) +{ + size_t layoutIndex = 0; + for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) + { + ASSERT(layoutIndex < gl::MAX_VERTEX_ATTRIBS); + + const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex]; + + if (shaderAttr.type != GL_NONE) + { + GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type); + + for (size_t rowIndex = 0; static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); rowIndex++, layoutIndex++) + { + gl::VertexFormat *defaultFormat = &inputLayout[layoutIndex]; + + defaultFormat->mType = gl::VariableComponentType(transposedType); + defaultFormat->mNormalized = false; + defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool + defaultFormat->mComponents = gl::VariableColumnCount(transposedType); + } + } + } +} + +std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<PixelShaderOutputVariable> &shaderOutputVars) +{ + std::vector<GLenum> defaultPixelOutput(1); + + ASSERT(!shaderOutputVars.empty()); + defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex; + + return defaultPixelOutput; +} + +bool IsRowMajorLayout(const sh::InterfaceBlockField &var) +{ + return var.isRowMajorLayout; +} + +bool IsRowMajorLayout(const sh::ShaderVariable &var) +{ + return false; +} + +} + +ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[], + const GLenum signature[], + ShaderExecutable *shaderExecutable) + : mShaderExecutable(shaderExecutable) +{ + for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + { + mInputs[attributeIndex] = inputLayout[attributeIndex]; + mSignature[attributeIndex] = signature[attributeIndex]; + } +} + +ProgramD3D::VertexExecutable::~VertexExecutable() +{ + SafeDelete(mShaderExecutable); +} + +bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) const +{ + for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + { + if (mSignature[attributeIndex] != signature[attributeIndex]) + { + return false; + } + } + + return true; +} + +ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable) + : mOutputSignature(outputSignature), + mShaderExecutable(shaderExecutable) +{ +} + +ProgramD3D::PixelExecutable::~PixelExecutable() +{ + SafeDelete(mShaderExecutable); +} + +ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D) +{ +} + +ProgramD3D::ProgramD3D(RendererD3D *renderer) : ProgramImpl(), mRenderer(renderer), mDynamicHLSL(NULL), - mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), - mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), + mGeometryExecutable(NULL), + mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE), + mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE), + mUsesPointSize(false), mVertexUniformStorage(NULL), - mFragmentUniformStorage(NULL) + mFragmentUniformStorage(NULL), + mUsedVertexSamplerRange(0), + mUsedPixelSamplerRange(0), + mDirtySamplerMapping(true), + mShaderVersion(100) { - mDynamicHLSL = new rx::DynamicHLSL(renderer); + mDynamicHLSL = new DynamicHLSL(renderer); } ProgramD3D::~ProgramD3D() @@ -49,13 +185,344 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl) return static_cast<const ProgramD3D*>(impl); } -bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +bool ProgramD3D::usesPointSpriteEmulation() const +{ + return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; +} + +bool ProgramD3D::usesGeometryShader() const +{ + return usesPointSpriteEmulation(); +} + +GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const +{ + GLint logicalTextureUnit = -1; + + switch (type) + { + case gl::SAMPLER_PIXEL: + ASSERT(samplerIndex < caps.maxTextureImageUnits); + if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) + { + logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; + } + break; + case gl::SAMPLER_VERTEX: + ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); + if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) + { + logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; + } + break; + default: UNREACHABLE(); + } + + if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits)) + { + return logicalTextureUnit; + } + + return -1; +} + +// Returns the texture type for a given Direct3D 9 sampler type and +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const +{ + switch (type) + { + case gl::SAMPLER_PIXEL: + ASSERT(samplerIndex < mSamplersPS.size()); + ASSERT(mSamplersPS[samplerIndex].active); + return mSamplersPS[samplerIndex].textureType; + case gl::SAMPLER_VERTEX: + ASSERT(samplerIndex < mSamplersVS.size()); + ASSERT(mSamplersVS[samplerIndex].active); + return mSamplersVS[samplerIndex].textureType; + default: UNREACHABLE(); + } + + return GL_TEXTURE_2D; +} + +GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const +{ + switch (type) + { + case gl::SAMPLER_PIXEL: + return mUsedPixelSamplerRange; + case gl::SAMPLER_VERTEX: + return mUsedVertexSamplerRange; + default: + UNREACHABLE(); + return 0; + } +} + +void ProgramD3D::updateSamplerMapping() +{ + if (!mDirtySamplerMapping) + { + return; + } + + mDirtySamplerMapping = false; + + // Retrieve sampler uniform values + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + gl::LinkedUniform *targetUniform = mUniforms[uniformIndex]; + + if (targetUniform->dirty) + { + if (gl::IsSampler(targetUniform->type)) + { + int count = targetUniform->elementCount(); + GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data); + + if (targetUniform->isReferencedByFragmentShader()) + { + unsigned int firstIndex = targetUniform->psRegisterIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < mSamplersPS.size()) + { + ASSERT(mSamplersPS[samplerIndex].active); + mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; + } + } + } + + if (targetUniform->isReferencedByVertexShader()) + { + unsigned int firstIndex = targetUniform->vsRegisterIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < mSamplersVS.size()) + { + ASSERT(mSamplersVS[samplerIndex].active); + mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; + } + } + } + } + } + } +} + +bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) { + // if any two active samplers in a program are of different types, but refer to the same + // texture image unit, and this is the current program, then ValidateProgram will fail, and + // DrawArrays and DrawElements will issue the INVALID_OPERATION error. + updateSamplerMapping(); + + std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE); + + for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) + { + if (mSamplersPS[i].active) + { + unsigned int unit = mSamplersPS[i].logicalTextureUnit; + + if (unit >= textureUnitTypes.size()) + { + if (infoLog) + { + infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); + } + + return false; + } + + if (textureUnitTypes[unit] != GL_NONE) + { + if (mSamplersPS[i].textureType != textureUnitTypes[unit]) + { + if (infoLog) + { + infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitTypes[unit] = mSamplersPS[i].textureType; + } + } + } + + for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) + { + if (mSamplersVS[i].active) + { + unsigned int unit = mSamplersVS[i].logicalTextureUnit; + + if (unit >= textureUnitTypes.size()) + { + if (infoLog) + { + infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); + } + + return false; + } + + if (textureUnitTypes[unit] != GL_NONE) + { + if (mSamplersVS[i].textureType != textureUnitTypes[unit]) + { + if (infoLog) + { + infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitTypes[unit] = mSamplersVS[i].textureType; + } + } + } + + return true; +} + +gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +{ + stream->readInt(&mShaderVersion); + + const unsigned int psSamplerCount = stream->readInt<unsigned int>(); + for (unsigned int i = 0; i < psSamplerCount; ++i) + { + Sampler sampler; + stream->readBool(&sampler.active); + stream->readInt(&sampler.logicalTextureUnit); + stream->readInt(&sampler.textureType); + mSamplersPS.push_back(sampler); + } + const unsigned int vsSamplerCount = stream->readInt<unsigned int>(); + for (unsigned int i = 0; i < vsSamplerCount; ++i) + { + Sampler sampler; + stream->readBool(&sampler.active); + stream->readInt(&sampler.logicalTextureUnit); + stream->readInt(&sampler.textureType); + mSamplersVS.push_back(sampler); + } + + stream->readInt(&mUsedVertexSamplerRange); + stream->readInt(&mUsedPixelSamplerRange); + + const unsigned int uniformCount = stream->readInt<unsigned int>(); + if (stream->error()) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + mUniforms.resize(uniformCount); + for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) + { + GLenum type = stream->readInt<GLenum>(); + GLenum precision = stream->readInt<GLenum>(); + std::string name = stream->readString(); + unsigned int arraySize = stream->readInt<unsigned int>(); + int blockIndex = stream->readInt<int>(); + + int offset = stream->readInt<int>(); + int arrayStride = stream->readInt<int>(); + int matrixStride = stream->readInt<int>(); + bool isRowMajorMatrix = stream->readBool(); + + const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); + + gl::LinkedUniform *uniform = new gl::LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); + + stream->readInt(&uniform->psRegisterIndex); + stream->readInt(&uniform->vsRegisterIndex); + stream->readInt(&uniform->registerCount); + stream->readInt(&uniform->registerElement); + + mUniforms[uniformIndex] = uniform; + } + + const unsigned int uniformIndexCount = stream->readInt<unsigned int>(); + if (stream->error()) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + mUniformIndex.resize(uniformIndexCount); + for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) + { + stream->readString(&mUniformIndex[uniformIndexIndex].name); + stream->readInt(&mUniformIndex[uniformIndexIndex].element); + stream->readInt(&mUniformIndex[uniformIndexIndex].index); + } + + unsigned int uniformBlockCount = stream->readInt<unsigned int>(); + if (stream->error()) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + mUniformBlocks.resize(uniformBlockCount); + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) + { + std::string name = stream->readString(); + unsigned int elementIndex = stream->readInt<unsigned int>(); + unsigned int dataSize = stream->readInt<unsigned int>(); + + gl::UniformBlock *uniformBlock = new gl::UniformBlock(name, elementIndex, dataSize); + + stream->readInt(&uniformBlock->psRegisterIndex); + stream->readInt(&uniformBlock->vsRegisterIndex); + + unsigned int numMembers = stream->readInt<unsigned int>(); + uniformBlock->memberUniformIndexes.resize(numMembers); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) + { + stream->readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); + } + + mUniformBlocks[uniformBlockIndex] = uniformBlock; + } + + stream->readInt(&mTransformFeedbackBufferMode); + const unsigned int transformFeedbackVaryingCount = stream->readInt<unsigned int>(); + mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); + for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) + { + gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; + + stream->readString(&varying.name); + stream->readInt(&varying.type); + stream->readInt(&varying.size); + stream->readString(&varying.semanticName); + stream->readInt(&varying.semanticIndex); + stream->readInt(&varying.semanticIndexCount); + } + stream->readString(&mVertexHLSL); stream->readInt(&mVertexWorkarounds); stream->readString(&mPixelHLSL); stream->readInt(&mPixelWorkarounds); stream->readBool(&mUsesFragDepth); + stream->readBool(&mUsesPointSize); const size_t pixelShaderKeySize = stream->readInt<unsigned int>(); mPixelShaderKey.resize(pixelShaderKeySize); @@ -67,109 +534,513 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); } - return true; + const unsigned char* binary = reinterpret_cast<const unsigned char*>(stream->data()); + + const unsigned int vertexShaderCount = stream->readInt<unsigned int>(); + for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) + { + gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; + + for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + { + gl::VertexFormat *vertexInput = &inputLayout[inputIndex]; + stream->readInt(&vertexInput->mType); + stream->readInt(&vertexInput->mNormalized); + stream->readInt(&vertexInput->mComponents); + stream->readBool(&vertexInput->mPureInteger); + } + + unsigned int vertexShaderSize = stream->readInt<unsigned int>(); + const unsigned char *vertexShaderFunction = binary + stream->offset(); + + ShaderExecutable *shaderExecutable = NULL; + gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, + SHADER_VERTEX, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + &shaderExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (!shaderExecutable) + { + infoLog.append("Could not create vertex shader."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + // generated converted input layout + GLenum signature[gl::MAX_VERTEX_ATTRIBS]; + getInputLayoutSignature(inputLayout, signature); + + // add new binary + mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable)); + + stream->skip(vertexShaderSize); + } + + const size_t pixelShaderCount = stream->readInt<unsigned int>(); + for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++) + { + const size_t outputCount = stream->readInt<unsigned int>(); + std::vector<GLenum> outputs(outputCount); + for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++) + { + stream->readInt(&outputs[outputIndex]); + } + + const size_t pixelShaderSize = stream->readInt<unsigned int>(); + const unsigned char *pixelShaderFunction = binary + stream->offset(); + ShaderExecutable *shaderExecutable = NULL; + gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + &shaderExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (!shaderExecutable) + { + infoLog.append("Could not create pixel shader."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + // add new binary + mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable)); + + stream->skip(pixelShaderSize); + } + + unsigned int geometryShaderSize = stream->readInt<unsigned int>(); + + if (geometryShaderSize > 0) + { + const unsigned char *geometryShaderFunction = binary + stream->offset(); + gl::Error error = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + &mGeometryExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (!mGeometryExecutable) + { + infoLog.append("Could not create geometry shader."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + stream->skip(geometryShaderSize); + } + + GUID binaryIdentifier = {0}; + stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID)); + + GUID identifier = mRenderer->getAdapterIdentifier(); + if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + initializeUniformStorage(); + + return gl::LinkResult(true, gl::Error(GL_NO_ERROR)); } -bool ProgramD3D::save(gl::BinaryOutputStream *stream) +gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) { + stream->writeInt(mShaderVersion); + + stream->writeInt(mSamplersPS.size()); + for (unsigned int i = 0; i < mSamplersPS.size(); ++i) + { + stream->writeInt(mSamplersPS[i].active); + stream->writeInt(mSamplersPS[i].logicalTextureUnit); + stream->writeInt(mSamplersPS[i].textureType); + } + + stream->writeInt(mSamplersVS.size()); + for (unsigned int i = 0; i < mSamplersVS.size(); ++i) + { + stream->writeInt(mSamplersVS[i].active); + stream->writeInt(mSamplersVS[i].logicalTextureUnit); + stream->writeInt(mSamplersVS[i].textureType); + } + + stream->writeInt(mUsedVertexSamplerRange); + stream->writeInt(mUsedPixelSamplerRange); + + stream->writeInt(mUniforms.size()); + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) + { + const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; + + stream->writeInt(uniform.type); + stream->writeInt(uniform.precision); + stream->writeString(uniform.name); + stream->writeInt(uniform.arraySize); + stream->writeInt(uniform.blockIndex); + + stream->writeInt(uniform.blockInfo.offset); + stream->writeInt(uniform.blockInfo.arrayStride); + stream->writeInt(uniform.blockInfo.matrixStride); + stream->writeInt(uniform.blockInfo.isRowMajorMatrix); + + stream->writeInt(uniform.psRegisterIndex); + stream->writeInt(uniform.vsRegisterIndex); + stream->writeInt(uniform.registerCount); + stream->writeInt(uniform.registerElement); + } + + stream->writeInt(mUniformIndex.size()); + for (size_t i = 0; i < mUniformIndex.size(); ++i) + { + stream->writeString(mUniformIndex[i].name); + stream->writeInt(mUniformIndex[i].element); + stream->writeInt(mUniformIndex[i].index); + } + + stream->writeInt(mUniformBlocks.size()); + for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) + { + const gl::UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; + + stream->writeString(uniformBlock.name); + stream->writeInt(uniformBlock.elementIndex); + stream->writeInt(uniformBlock.dataSize); + + stream->writeInt(uniformBlock.memberUniformIndexes.size()); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) + { + stream->writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); + } + + stream->writeInt(uniformBlock.psRegisterIndex); + stream->writeInt(uniformBlock.vsRegisterIndex); + } + + stream->writeInt(mTransformFeedbackBufferMode); + stream->writeInt(mTransformFeedbackLinkedVaryings.size()); + for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) + { + const gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; + + stream->writeString(varying.name); + stream->writeInt(varying.type); + stream->writeInt(varying.size); + stream->writeString(varying.semanticName); + stream->writeInt(varying.semanticIndex); + stream->writeInt(varying.semanticIndexCount); + } + stream->writeString(mVertexHLSL); stream->writeInt(mVertexWorkarounds); stream->writeString(mPixelHLSL); stream->writeInt(mPixelWorkarounds); stream->writeInt(mUsesFragDepth); + stream->writeInt(mUsesPointSize); - const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey; + const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey; stream->writeInt(pixelShaderKey.size()); for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++) { - const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; + const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; stream->writeInt(variable.type); stream->writeString(variable.name); stream->writeString(variable.source); stream->writeInt(variable.outputIndex); } - return true; + stream->writeInt(mVertexExecutables.size()); + for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) + { + VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; + + for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + { + const gl::VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; + stream->writeInt(vertexInput.mType); + stream->writeInt(vertexInput.mNormalized); + stream->writeInt(vertexInput.mComponents); + stream->writeInt(vertexInput.mPureInteger); + } + + size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); + stream->writeInt(vertexShaderSize); + + const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(vertexBlob, vertexShaderSize); + } + + stream->writeInt(mPixelExecutables.size()); + for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) + { + PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; + + const std::vector<GLenum> outputs = pixelExecutable->outputSignature(); + stream->writeInt(outputs.size()); + for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++) + { + stream->writeInt(outputs[outputIndex]); + } + + size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength(); + stream->writeInt(pixelShaderSize); + + const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(pixelBlob, pixelShaderSize); + } + + size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; + stream->writeInt(geometryShaderSize); + + if (mGeometryExecutable != NULL && geometryShaderSize > 0) + { + const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); + stream->writeBytes(geometryBlob, geometryShaderSize); + } + + GUID binaryIdentifier = mRenderer->getAdapterIdentifier(); + stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID)); + + return gl::Error(GL_NO_ERROR); } -rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, - const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) +gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExecutable) { + std::vector<GLenum> outputs; + + const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(mRenderer->getWorkarounds()); + + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) + { + const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; + + if (colorbuffer) + { + outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding()); + } + else + { + outputs.push_back(GL_NONE); + } + } + + return getPixelExecutableForOutputLayout(outputs, outExecutable); +} + +gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature, ShaderExecutable **outExectuable) +{ + for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) + { + if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature)) + { + *outExectuable = mPixelExecutables[executableIndex]->shaderExecutable(); + return gl::Error(GL_NO_ERROR); + } + } + std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth, outputSignature); // Generate new pixel executable - rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL, - transformFeedbackLinkedVaryings, separatedOutputBuffers, - mPixelWorkarounds); + gl::InfoLog tempInfoLog; + ShaderExecutable *pixelExecutable = NULL; + gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + mPixelWorkarounds, &pixelExecutable); + if (error.isError()) + { + return error; + } + + if (!pixelExecutable) + { + std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3); + tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); + } + else + { + mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable)); + } - return pixelExecutable; + *outExectuable = pixelExecutable; + return gl::Error(GL_NO_ERROR); } -rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog, - const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const sh::Attribute shaderAttributes[], - const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) +gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable) { + GLenum signature[gl::MAX_VERTEX_ATTRIBS]; + getInputLayoutSignature(inputLayout, signature); + + for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) + { + if (mVertexExecutables[executableIndex]->matchesSignature(signature)) + { + *outExectuable = mVertexExecutables[executableIndex]->shaderExecutable(); + return gl::Error(GL_NO_ERROR); + } + } + // Generate new dynamic layout with attribute conversions - std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes); + std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes); // Generate new vertex executable - rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(), - rx::SHADER_VERTEX, - transformFeedbackLinkedVaryings, separatedOutputBuffers, - mVertexWorkarounds); + gl::InfoLog tempInfoLog; + ShaderExecutable *vertexExecutable = NULL; + gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL, SHADER_VERTEX, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + mVertexWorkarounds, &vertexExecutable); + if (error.isError()) + { + return error; + } + + if (!vertexExecutable) + { + std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3); + tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); + } + else + { + mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable)); + } + + *outExectuable = vertexExecutable; + return gl::Error(GL_NO_ERROR); +} + +gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + int registers) +{ + ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); + ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + + gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS]; + GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); + ShaderExecutable *defaultVertexExecutable = NULL; + gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey()); + ShaderExecutable *defaultPixelExecutable = NULL; + error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (usesGeometryShader()) + { + std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); + + + error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + } + +#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED + if (usesGeometryShader() && mGeometryExecutable) + { + // Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level + // For now the geometry shader debug info is pre-pended to the vertex shader, this is a bit of a clutch + vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n"); + vertexShaderD3D->appendDebugInfo(mGeometryExecutable->getDebugInfo()); + vertexShaderD3D->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n"); + } + + if (defaultVertexExecutable) + { + vertexShaderD3D->appendDebugInfo(defaultVertexExecutable->getDebugInfo()); + } + + if (defaultPixelExecutable) + { + fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo()); + } +#endif - return vertexExecutable; + bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable)); + return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR)); } -bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector<std::string> &transformFeedbackVaryings, int *registers, - std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables) +gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog, + gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode, + int *registers, std::vector<gl::LinkedVarying> *linkedVaryings, + std::map<int, gl::VariableLocation> *outputVariables) { - rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); - rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); + ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + + mSamplersPS.resize(data.caps->maxTextureImageUnits); + mSamplersVS.resize(data.caps->maxVertexTextureImageUnits); + + mTransformFeedbackBufferMode = transformFeedbackBufferMode; mPixelHLSL = fragmentShaderD3D->getTranslatedSource(); mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds(); mVertexHLSL = vertexShaderD3D->getTranslatedSource(); mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds(); + mShaderVersion = vertexShaderD3D->getShaderVersion(); // Map the varyings to the register file - rx::VaryingPacking packing = { NULL }; + VaryingPacking packing = { NULL }; *registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings); if (*registers < 0) { - return false; + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); } if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader)) { - return false; + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); } - if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, + if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings, linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth)) { - return false; + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); } - return true; + mUsesPointSize = vertexShaderD3D->usesPointSize(); + + return gl::LinkResult(true, gl::Error(GL_NO_ERROR)); +} + +void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const +{ + mDynamicHLSL->getInputLayoutSignature(inputLayout, signature); } -void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) +void ProgramD3D::initializeUniformStorage() { // Compute total default block size unsigned int vertexRegisters = 0; unsigned int fragmentRegisters = 0; - for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++) + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { - const gl::LinkedUniform &uniform = *uniforms[uniformIndex]; + const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; if (!gl::IsSampler(uniform.type)) { @@ -188,18 +1059,867 @@ void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u); } +gl::Error ProgramD3D::applyUniforms() +{ + updateSamplerMapping(); + + gl::Error error = mRenderer->applyUniforms(*this, mUniforms); + if (error.isError()) + { + return error; + } + + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + mUniforms[uniformIndex]->dirty = false; + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps) +{ + ASSERT(boundBuffers.size() == mUniformBlocks.size()); + + const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL}; + const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL}; + + const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers(); + const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers(); + + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) + { + gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex]; + gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex]; + + ASSERT(uniformBlock && uniformBuffer); + + if (uniformBuffer->getSize() < uniformBlock->dataSize) + { + // undefined behaviour + return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."); + } + + // Unnecessary to apply an unreferenced standard or shared UBO + if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader()) + { + continue; + } + + if (uniformBlock->isReferencedByVertexShader()) + { + unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; + ASSERT(vertexUniformBuffers[registerIndex] == NULL); + ASSERT(registerIndex < caps.maxVertexUniformBlocks); + vertexUniformBuffers[registerIndex] = uniformBuffer; + } + + if (uniformBlock->isReferencedByFragmentShader()) + { + unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; + ASSERT(fragmentUniformBuffers[registerIndex] == NULL); + ASSERT(registerIndex < caps.maxFragmentUniformBlocks); + fragmentUniformBuffers[registerIndex] = uniformBuffer; + } + } + + return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers); +} + +bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, + unsigned int registerIndex, const gl::Caps &caps) +{ + if (shader == GL_VERTEX_SHADER) + { + uniformBlock->vsRegisterIndex = registerIndex; + if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) + { + infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks); + return false; + } + } + else if (shader == GL_FRAGMENT_SHADER) + { + uniformBlock->psRegisterIndex = registerIndex; + if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) + { + infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks); + return false; + } + } + else UNREACHABLE(); + + return true; +} + +void ProgramD3D::dirtyAllUniforms() +{ + unsigned int numUniforms = mUniforms.size(); + for (unsigned int index = 0; index < numUniforms; index++) + { + mUniforms[index]->dirty = true; + } +} + +void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) +{ + setUniform(location, count, v, GL_FLOAT); +} + +void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC2); +} + +void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC3); +} + +void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC4); +} + +void ProgramD3D::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); +} + +void ProgramD3D::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); +} + +void ProgramD3D::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); +} + +void ProgramD3D::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); +} + +void ProgramD3D::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); +} + +void ProgramD3D::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); +} + +void ProgramD3D::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); +} + +void ProgramD3D::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); +} + +void ProgramD3D::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); +} + +void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT); +} + +void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT_VEC2); +} + +void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT_VEC3); +} + +void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT_VEC4); +} + +void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT); +} + +void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); +} + +void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); +} + +void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); +} + +void ProgramD3D::getUniformfv(GLint location, GLfloat *params) +{ + getUniformv(location, params, GL_FLOAT); +} + +void ProgramD3D::getUniformiv(GLint location, GLint *params) +{ + getUniformv(location, params, GL_INT); +} + +void ProgramD3D::getUniformuiv(GLint location, GLuint *params) +{ + getUniformv(location, params, GL_UNSIGNED_INT); +} + +bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps) +{ + const ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader.getImplementation()); + const ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader.getImplementation()); + + const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms(); + const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms(); + + // Check that uniforms defined in the vertex and fragment shaders are identical + typedef std::map<std::string, const sh::Uniform*> UniformMap; + UniformMap linkedUniforms; + + for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) + { + const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; + linkedUniforms[vertexUniform.name] = &vertexUniform; + } + + for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) + { + const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; + UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); + if (entry != linkedUniforms.end()) + { + const sh::Uniform &vertexUniform = *entry->second; + const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; + if (!gl::ProgramBinary::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform)) + { + return false; + } + } + } + + for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) + { + const sh::Uniform &uniform = vertexUniforms[uniformIndex]; + + if (uniform.staticUse) + { + defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); + } + } + + for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) + { + const sh::Uniform &uniform = fragmentUniforms[uniformIndex]; + + if (uniform.staticUse) + { + defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); + } + } + + if (!indexUniforms(infoLog, caps)) + { + return false; + } + + initializeUniformStorage(); + + // special case for gl_DepthRange, the only built-in uniform (also a struct) + if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange()) + { + const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo(); + + mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo)); + mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo)); + mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo)); + } + + return true; +} + +void ProgramD3D::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister) +{ + ShShaderOutput outputType = ShaderD3D::getCompilerOutputType(shader); + sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); + encoder.skipRegisters(uniformRegister); + + defineUniform(shader, uniform, uniform.name, &encoder); +} + +void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, + const std::string &fullName, sh::HLSLBlockEncoder *encoder) +{ + if (uniform.isStruct()) + { + for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) + { + const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); + + encoder->enterAggregateType(); + + for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) + { + const sh::ShaderVariable &field = uniform.fields[fieldIndex]; + const std::string &fieldFullName = (fullName + elementString + "." + field.name); + + defineUniform(shader, field, fieldFullName, encoder); + } + + encoder->exitAggregateType(); + } + } + else // Not a struct + { + // Arrays are treated as aggregate types + if (uniform.isArray()) + { + encoder->enterAggregateType(); + } + + gl::LinkedUniform *linkedUniform = getUniformByName(fullName); + + if (!linkedUniform) + { + linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, + -1, sh::BlockMemberInfo::getDefaultBlockInfo()); + ASSERT(linkedUniform); + linkedUniform->registerElement = encoder->getCurrentElement(); + mUniforms.push_back(linkedUniform); + } + + ASSERT(linkedUniform->registerElement == encoder->getCurrentElement()); + + if (shader == GL_FRAGMENT_SHADER) + { + linkedUniform->psRegisterIndex = encoder->getCurrentRegister(); + } + else if (shader == GL_VERTEX_SHADER) + { + linkedUniform->vsRegisterIndex = encoder->getCurrentRegister(); + } + else UNREACHABLE(); + + // Advance the uniform offset, to track registers allocation for structs + encoder->encodeType(uniform.type, uniform.arraySize, false); + + // Arrays are treated as aggregate types + if (uniform.isArray()) + { + encoder->exitAggregateType(); + } + } +} + +template <typename T> +static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) +{ + ASSERT(dest != NULL); + ASSERT(dirtyFlag != NULL); + + *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); + *dest = source; +} + +template <typename T> +void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) +{ + const int components = gl::VariableComponentCount(targetUniformType); + const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType); + + gl::LinkedUniform *targetUniform = getUniformByLocation(location); + + int elementCount = targetUniform->elementCount(); + + count = std::min(elementCount - (int)mUniformIndex[location].element, count); + + if (targetUniform->type == targetUniformType) + { + T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + T *dest = target + (i * 4); + const T *source = v + (i * components); + + for (int c = 0; c < components; c++) + { + SetIfDirty(dest + c, source[c], &targetUniform->dirty); + } + for (int c = components; c < 4; c++) + { + SetIfDirty(dest + c, T(0), &targetUniform->dirty); + } + } + } + else if (targetUniform->type == targetBoolType) + { + GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + GLint *dest = boolParams + (i * 4); + const T *source = v + (i * components); + + for (int c = 0; c < components; c++) + { + SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); + } + for (int c = components; c < 4; c++) + { + SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty); + } + } + } + else if (gl::IsSampler(targetUniform->type)) + { + ASSERT(targetUniformType == GL_INT); + + GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4; + + bool wasDirty = targetUniform->dirty; + + for (int i = 0; i < count; i++) + { + GLint *dest = target + (i * 4); + const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components); + + SetIfDirty(dest + 0, source[0], &targetUniform->dirty); + SetIfDirty(dest + 1, 0, &targetUniform->dirty); + SetIfDirty(dest + 2, 0, &targetUniform->dirty); + SetIfDirty(dest + 3, 0, &targetUniform->dirty); + } + + if (!wasDirty && targetUniform->dirty) + { + mDirtySamplerMapping = true; + } + } + else UNREACHABLE(); +} + +template<typename T> +bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetHeight, srcWidth); + int copyHeight = std::min(targetWidth, srcHeight); + + for (int x = 0; x < copyWidth; x++) + { + for (int y = 0; y < copyHeight; y++) + { + SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty); + } + } + // clear unfilled right side + for (int y = 0; y < copyWidth; y++) + { + for (int x = copyHeight; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); + } + } + // clear unfilled bottom. + for (int y = copyWidth; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); + } + } + + return dirty; +} + +template<typename T> +bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetWidth, srcWidth); + int copyHeight = std::min(targetHeight, srcHeight); + + for (int y = 0; y < copyHeight; y++) + { + for (int x = 0; x < copyWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty); + } + } + // clear unfilled right side + for (int y = 0; y < copyHeight; y++) + { + for (int x = copyWidth; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); + } + } + // clear unfilled bottom. + for (int y = copyHeight; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); + } + } + + return dirty; +} + +template <int cols, int rows> +void ProgramD3D::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) +{ + gl::LinkedUniform *targetUniform = getUniformByLocation(location); + + int elementCount = targetUniform->elementCount(); + + count = std::min(elementCount - (int)mUniformIndex[location].element, count); + const unsigned int targetMatrixStride = (4 * rows); + GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); + + for (int i = 0; i < count; i++) + { + // Internally store matrices as transposed versions to accomodate HLSL matrix indexing + if (transpose == GL_FALSE) + { + targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty; + } + else + { + targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty; + } + target += targetMatrixStride; + value += cols * rows; + } +} + +template <typename T> +void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType) +{ + gl::LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; + + if (gl::IsMatrixType(targetUniform->type)) + { + const int rows = gl::VariableRowCount(targetUniform->type); + const int cols = gl::VariableColumnCount(targetUniform->type); + transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); + } + else if (uniformType == gl::VariableComponentType(targetUniform->type)) + { + unsigned int size = gl::VariableComponentCount(targetUniform->type); + memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), + size * sizeof(T)); + } + else + { + unsigned int size = gl::VariableComponentCount(targetUniform->type); + switch (gl::VariableComponentType(targetUniform->type)) + { + case GL_BOOL: + { + GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1); + } + } + break; + + case GL_FLOAT: + { + GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast<T>(floatParams[i]); + } + } + break; + + case GL_INT: + { + GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast<T>(intParams[i]); + } + } + break; + + case GL_UNSIGNED_INT: + { + GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast<T>(uintParams[i]); + } + } + break; + + default: UNREACHABLE(); + } + } +} + +template <typename VarT> +void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex, + sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, + bool inRowMajorLayout) +{ + for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) + { + const VarT &field = fields[uniformIndex]; + const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); + + if (field.isStruct()) + { + bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); + + for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) + { + encoder->enterAggregateType(); + + const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); + defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout); + + encoder->exitAggregateType(); + } + } + else + { + bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); + + sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); + + gl::LinkedUniform *newUniform = new gl::LinkedUniform(field.type, field.precision, fieldName, field.arraySize, + blockIndex, memberInfo); + + // add to uniform list, but not index, since uniform block uniforms have no location + blockUniformIndexes->push_back(mUniforms.size()); + mUniforms.push_back(newUniform); + } + } +} + +bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, + const gl::Caps &caps) +{ + const ShaderD3D* shaderD3D = ShaderD3D::makeShaderD3D(shader.getImplementation()); + + // create uniform block entries if they do not exist + if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) + { + std::vector<unsigned int> blockUniformIndexes; + const unsigned int blockIndex = mUniformBlocks.size(); + + // define member uniforms + sh::BlockLayoutEncoder *encoder = NULL; + + if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) + { + encoder = new sh::Std140BlockEncoder; + } + else + { + encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); + } + ASSERT(encoder); + + defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout); + + size_t dataSize = encoder->getBlockSize(); + + // create all the uniform blocks + if (interfaceBlock.arraySize > 0) + { + for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) + { + gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize); + newUniformBlock->memberUniformIndexes = blockUniformIndexes; + mUniformBlocks.push_back(newUniformBlock); + } + } + else + { + gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize); + newUniformBlock->memberUniformIndexes = blockUniformIndexes; + mUniformBlocks.push_back(newUniformBlock); + } + } + + if (interfaceBlock.staticUse) + { + // Assign registers to the uniform blocks + const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); + const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); + ASSERT(blockIndex != GL_INVALID_INDEX); + ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); + + unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name); + + for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) + { + gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; + ASSERT(uniformBlock->name == interfaceBlock.name); + + if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), + interfaceBlockRegister + uniformBlockElement, caps)) + { + return false; + } + } + } + + return true; +} + +bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex, + GLenum samplerType, + unsigned int samplerCount, + std::vector<Sampler> &outSamplers, + GLuint *outUsedRange) +{ + unsigned int samplerIndex = startSamplerIndex; + + do + { + if (samplerIndex < outSamplers.size()) + { + Sampler& sampler = outSamplers[samplerIndex]; + sampler.active = true; + sampler.textureType = GetTextureType(samplerType); + sampler.logicalTextureUnit = 0; + *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); + } + else + { + return false; + } + + samplerIndex++; + } while (samplerIndex < startSamplerIndex + samplerCount); + + return true; +} + +bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps) +{ + ASSERT(gl::IsSampler(uniform.type)); + ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX); + + if (uniform.vsRegisterIndex != GL_INVALID_INDEX) + { + if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS, + &mUsedVertexSamplerRange)) + { + infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", + mSamplersVS.size()); + return false; + } + + unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors; + if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors) + { + infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", + caps.maxVertexUniformVectors); + return false; + } + } + + if (uniform.psRegisterIndex != GL_INVALID_INDEX) + { + if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS, + &mUsedPixelSamplerRange)) + { + infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", + mSamplersPS.size()); + return false; + } + + unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors; + if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors) + { + infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", + caps.maxFragmentUniformVectors); + return false; + } + } + + return true; +} + +bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) +{ + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; + + if (gl::IsSampler(uniform.type)) + { + if (!indexSamplerUniform(uniform, infoLog, caps)) + { + return false; + } + } + + for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++) + { + mUniformIndex.push_back(gl::VariableLocation(uniform.name, arrayElementIndex, uniformIndex)); + } + } + + return true; +} + void ProgramD3D::reset() { + ProgramImpl::reset(); + + SafeDeleteContainer(mVertexExecutables); + SafeDeleteContainer(mPixelExecutables); + SafeDelete(mGeometryExecutable); + + mTransformFeedbackBufferMode = GL_NONE; + mVertexHLSL.clear(); - mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; + mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE; + mShaderVersion = 100; mPixelHLSL.clear(); - mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; + mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE; mUsesFragDepth = false; mPixelShaderKey.clear(); + mUsesPointSize = false; SafeDelete(mVertexUniformStorage); SafeDelete(mFragmentUniformStorage); + + mSamplersPS.clear(); + mSamplersVS.clear(); + + mUsedVertexSamplerRange = 0; + mUsedPixelSamplerRange = 0; + mDirtySamplerMapping = true; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h index d645c57daa..4baab9aa19 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_PROGRAMD3D_H_ #include "libGLESv2/renderer/ProgramImpl.h" +#include "libGLESv2/renderer/Workarounds.h" #include <string> #include <vector> @@ -23,63 +24,194 @@ struct VertexFormat; namespace rx { - +class RendererD3D; class UniformStorage; class ProgramD3D : public ProgramImpl { public: - ProgramD3D(rx::Renderer *renderer); + ProgramD3D(RendererD3D *renderer); virtual ~ProgramD3D(); static ProgramD3D *makeProgramD3D(ProgramImpl *impl); static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl); - Renderer *getRenderer() { return mRenderer; } - DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; } - const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; } - - GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; } - bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); - bool save(gl::BinaryOutputStream *stream); + const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; } + int getShaderVersion() const { return mShaderVersion; } + GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } - ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, - const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers); - ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, - const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const sh::Attribute shaderAttributes[], - const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers); + GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const; + GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const; + GLint getUsedSamplerRange(gl::SamplerType type) const; + void updateSamplerMapping(); + bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps); - bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector<std::string> &transformFeedbackVaryings, int *registers, - std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables); + bool usesPointSize() const { return mUsesPointSize; } + bool usesPointSpriteEmulation() const; + bool usesGeometryShader() const; - // D3D only - void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms); + GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; } + gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); + gl::Error save(gl::BinaryOutputStream *stream); + + gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable); + gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutable **outExectuable); + gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable); + ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; } + + gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + int registers); + + gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, + gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode, + int *registers, std::vector<gl::LinkedVarying> *linkedVaryings, + std::map<int, gl::VariableLocation> *outputVariables); + + void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; + + void initializeUniformStorage(); + gl::Error applyUniforms(); + gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps); + bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, + unsigned int registerIndex, const gl::Caps &caps); + void dirtyAllUniforms(); + + void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform1iv(GLint location, GLsizei count, const GLint *v); + void setUniform2iv(GLint location, GLsizei count, const GLint *v); + void setUniform3iv(GLint location, GLsizei count, const GLint *v); + void setUniform4iv(GLint location, GLsizei count, const GLint *v); + void setUniform1uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); + void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + + void getUniformfv(GLint location, GLfloat *params); + void getUniformiv(GLint location, GLint *params); + void getUniformuiv(GLint location, GLuint *params); const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; } const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } + bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps); + bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps); + void reset(); private: DISALLOW_COPY_AND_ASSIGN(ProgramD3D); - Renderer *mRenderer; + class VertexExecutable + { + public: + VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], + const GLenum signature[gl::MAX_VERTEX_ATTRIBS], + ShaderExecutable *shaderExecutable); + ~VertexExecutable(); + + bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const; + + const gl::VertexFormat *inputs() const { return mInputs; } + const GLenum *signature() const { return mSignature; } + ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } + + private: + gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS]; + GLenum mSignature[gl::MAX_VERTEX_ATTRIBS]; + ShaderExecutable *mShaderExecutable; + }; + + class PixelExecutable + { + public: + PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable); + ~PixelExecutable(); + + bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; } + + const std::vector<GLenum> &outputSignature() const { return mOutputSignature; } + ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } + + private: + std::vector<GLenum> mOutputSignature; + ShaderExecutable *mShaderExecutable; + }; + + struct Sampler + { + Sampler(); + + bool active; + GLint logicalTextureUnit; + GLenum textureType; + }; + + void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister); + void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, + sh::HLSLBlockEncoder *encoder); + bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps); + bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); + static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, + std::vector<Sampler> &outSamplers, GLuint *outUsedRange); + + template <typename T> + void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); + + template <int cols, int rows> + void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); + + template <typename T> + void getUniformv(GLint location, T *params, GLenum uniformType); + + template <typename VarT> + void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex, + sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, + bool inRowMajorLayout); + + RendererD3D *mRenderer; DynamicHLSL *mDynamicHLSL; + std::vector<VertexExecutable *> mVertexExecutables; + std::vector<PixelExecutable *> mPixelExecutables; + ShaderExecutable *mGeometryExecutable; + std::string mVertexHLSL; - rx::D3DWorkaroundType mVertexWorkarounds; + D3DWorkaroundType mVertexWorkarounds; std::string mPixelHLSL; - rx::D3DWorkaroundType mPixelWorkarounds; + D3DWorkaroundType mPixelWorkarounds; bool mUsesFragDepth; - std::vector<rx::PixelShaderOutputVariable> mPixelShaderKey; + std::vector& |