diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2')
56 files changed, 1197 insertions, 628 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp index 8d5b4ef2a1..c007d5d9e9 100644 --- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp @@ -40,6 +40,7 @@ Buffer::~Buffer() void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) { mBufferStorage->clear(); + mIndexRangeCache.clear(); mBufferStorage->setData(data, size, 0); mUsage = usage; @@ -56,6 +57,7 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) { mBufferStorage->setData(data, size, offset); + mIndexRangeCache.invalidateRange(offset, size); if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) { @@ -70,7 +72,7 @@ rx::BufferStorage *Buffer::getStorage() const return mBufferStorage; } -unsigned int Buffer::size() +unsigned int Buffer::size() const { return mBufferStorage->getSize(); } @@ -116,4 +118,9 @@ void Buffer::promoteStaticUsage(int dataSize) } } +rx::IndexRangeCache *Buffer::getIndexRangeCache() +{ + return &mIndexRangeCache; +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h index 4376ada5c0..4048f4b906 100644 --- a/src/3rdparty/angle/src/libGLESv2/Buffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h @@ -13,6 +13,7 @@ #include "common/angleutils.h" #include "common/RefCountObject.h" +#include "libGLESv2/renderer/IndexRangeCache.h" namespace rx { @@ -38,13 +39,15 @@ class Buffer : public RefCountObject GLenum usage() const; rx::BufferStorage *getStorage() const; - unsigned int size(); + unsigned int size() const; rx::StaticVertexBufferInterface *getStaticVertexBuffer(); rx::StaticIndexBufferInterface *getStaticIndexBuffer(); void invalidateStaticData(); void promoteStaticUsage(int dataSize); + rx::IndexRangeCache *getIndexRangeCache(); + private: DISALLOW_COPY_AND_ASSIGN(Buffer); @@ -53,6 +56,8 @@ class Buffer : public RefCountObject rx::BufferStorage *mBufferStorage; + rx::IndexRangeCache mIndexRangeCache; + rx::StaticVertexBufferInterface *mStaticVertexBuffer; rx::StaticIndexBufferInterface *mStaticIndexBuffer; unsigned int mUnmodifiedDataUse; diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp index 90ba2539d8..e829d508a6 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp @@ -60,6 +60,7 @@ Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool n mState.rasterizer.polygonOffsetFactor = 0.0f; mState.rasterizer.polygonOffsetUnits = 0.0f; mState.rasterizer.pointDrawMode = false; + mState.rasterizer.multiSample = false; mState.scissorTest = false; mState.scissor.x = 0; mState.scissor.y = 0; @@ -1075,6 +1076,7 @@ void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum inter case GL_RGB565: case GL_RGB8_OES: case GL_RGBA8_OES: + case GL_BGRA8_EXT: renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples); break; case GL_STENCIL_INDEX8: @@ -1741,7 +1743,11 @@ bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport) // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device void Context::applyState(GLenum drawMode) { + Framebuffer *framebufferObject = getDrawFramebuffer(); + int samples = framebufferObject->getSamples(); + mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS); + mState.rasterizer.multiSample = (samples != 0); mRenderer->setRasterizerState(mState.rasterizer); unsigned int mask = 0; @@ -1749,10 +1755,10 @@ void Context::applyState(GLenum drawMode) { if (mState.sampleCoverageValue != 0) { - Framebuffer *framebufferObject = getDrawFramebuffer(); + float threshold = 0.5f; - for (int i = 0; i < framebufferObject->getSamples(); ++i) + for (int i = 0; i < samples; ++i) { mask <<= 1; @@ -2582,6 +2588,7 @@ void Context::initExtensionString() } extensionString += "GL_EXT_texture_storage "; + extensionString += "GL_EXT_frag_depth "; // ANGLE-specific extensions if (supportsDepthTextures()) diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp index 42fee3bbad..b0abba0ac4 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp @@ -303,6 +303,19 @@ bool Framebuffer::hasStencil() const return false; } +bool Framebuffer::usingExtendedDrawBuffers() const +{ + for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + if (isEnabledColorAttachment(colorAttachment)) + { + return true; + } + } + + return false; +} + GLenum Framebuffer::completeness() const { int width = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h index 66acdc4c37..b54e008dd8 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h @@ -68,6 +68,7 @@ class Framebuffer bool hasEnabledColorAttachment() const; bool hasStencil() const; int getSamples() const; + bool usingExtendedDrawBuffers() const; virtual GLenum completeness() const; diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp index 14e6c94ca4..bcd04b7157 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp @@ -1165,7 +1165,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying bool usesMRT = fragmentShader->mUsesMultipleRenderTargets; bool usesFragColor = fragmentShader->mUsesFragColor; bool usesFragData = fragmentShader->mUsesFragData; - if (usesMRT && usesFragColor && usesFragData) + if (usesFragColor && usesFragData) { infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader."); return false; @@ -1177,6 +1177,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0); + // The output color is broadcast to all enabled draw buffers when writing to gl_FragColor + const bool broadcast = fragmentShader->mUsesFragColor; + const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1); + if (registersNeeded > maxVaryingVectors) { infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); @@ -1221,8 +1225,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD"; std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR"; std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION"; - - const unsigned int renderTargetCount = usesMRT ? mRenderer->getMaxRenderTargets() : 1; + std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; // special varyings that use reserved registers int reservedRegisterIndex = registers; @@ -1472,9 +1475,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying "struct PS_OUTPUT\n" "{\n"; - for (unsigned int i = 0; i < renderTargetCount; i++) + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) + { + pixelHLSL += " float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n"; + } + + if (fragmentShader->mUsesFragDepth) { - pixelHLSL += " float4 gl_Color" + str(i) + " : " + targetSemantic + str(i) + ";\n"; + pixelHLSL += " float gl_Depth : " + depthSemantic + ";\n"; } pixelHLSL += "};\n" @@ -1583,11 +1591,16 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying "\n" " PS_OUTPUT output;\n"; - for (unsigned int i = 0; i < renderTargetCount; i++) + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) { - unsigned int sourceColor = fragmentShader->mUsesFragData ? i : 0; + unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex; + + pixelHLSL += " output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n"; + } - pixelHLSL += " output.gl_Color" + str(i) + " = gl_Color[" + str(sourceColor) + "];\n"; + if (fragmentShader->mUsesFragDepth) + { + pixelHLSL += " output.gl_Depth = gl_Depth;\n"; } pixelHLSL += "\n" @@ -1617,6 +1630,14 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) return false; } + int compileFlags = 0; + stream.read(&compileFlags); + if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) + { + infoLog.append("Mismatched compilation flags."); + return false; + } + for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) { stream.read(&mLinkedAttribute[i].type); @@ -1626,6 +1647,8 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) stream.read(&mSemanticIndex[i]); } + initAttributesByLayout(); + for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) { stream.read(&mSamplersPS[i].active); @@ -1769,6 +1792,7 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) stream.write(GL_PROGRAM_BINARY_ANGLE); stream.write(VERSION_DWORD); + stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL); for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) { @@ -1917,36 +1941,48 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin } bool success = true; - mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX); - mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL); - if (usesGeometryShader()) + if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader)) { - std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader); - mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY); + success = false; } - if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) + if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms())) { - infoLog.append("Failed to create D3D shaders."); success = false; - - delete mVertexExecutable; - mVertexExecutable = NULL; - delete mPixelExecutable; - mPixelExecutable = NULL; - delete mGeometryExecutable; - mGeometryExecutable = NULL; } - if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader)) + // special case for gl_DepthRange, the only built-in uniform (also a struct) + if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange) { - success = false; + mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0)); + mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0)); + mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0)); } - if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms())) + if (success) { - success = false; + mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX); + mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL); + + if (usesGeometryShader()) + { + std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader); + mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY); + } + + if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) + { + infoLog.append("Failed to create D3D shaders."); + success = false; + + delete mVertexExecutable; + mVertexExecutable = NULL; + delete mPixelExecutable; + mPixelExecutable = NULL; + delete mGeometryExecutable; + mGeometryExecutable = NULL; + } } return success; @@ -2019,6 +2055,8 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at } } + initAttributesByLayout(); + return true; } @@ -2545,12 +2583,6 @@ struct AttributeSorter AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS]) : originalIndices(semanticIndices) { - for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) - { - indices[i] = i; - } - - std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this); } bool operator()(int a, int b) @@ -2558,27 +2590,32 @@ struct AttributeSorter return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b]; } - int indices[MAX_VERTEX_ATTRIBS]; const int (&originalIndices)[MAX_VERTEX_ATTRIBS]; }; -void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const +void ProgramBinary::initAttributesByLayout() { - AttributeSorter sorter(mSemanticIndex); + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + mAttributesByLayout[i] = i; + } + + std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex)); +} - int oldIndices[MAX_VERTEX_ATTRIBS]; +void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const +{ rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS]; for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { - oldIndices[i] = mSemanticIndex[i]; oldTranslatedAttributes[i] = attributes[i]; } for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { - int oldIndex = sorter.indices[i]; - sortedSemanticIndices[i] = oldIndices[oldIndex]; + int oldIndex = mAttributesByLayout[i]; + sortedSemanticIndices[i] = mSemanticIndex[oldIndex]; attributes[i] = oldTranslatedAttributes[oldIndex]; } } diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h index 2386c0bd6f..d6320863f2 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h @@ -114,6 +114,7 @@ class ProgramBinary : public RefCountObject unsigned int getSerial() const; + void initAttributesByLayout(); void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const; static std::string decorateAttribute(const std::string &name); // Prepend an underscore @@ -142,6 +143,7 @@ class ProgramBinary : public RefCountObject Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS]; + int mAttributesByLayout[MAX_VERTEX_ATTRIBS]; struct Sampler { diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp index abddab427b..7dfdd0ba3a 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp @@ -247,6 +247,7 @@ void Shader::initializeCompiler() resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1; // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported. resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp + resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); @@ -304,6 +305,8 @@ void Shader::parseVaryings() mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL; mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL; mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL; + mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL; + mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL; } } @@ -335,6 +338,8 @@ void Shader::uncompile() mUsesFrontFacing = false; mUsesPointSize = false; mUsesPointCoord = false; + mUsesDepthRange = false; + mUsesFragDepth = false; mActiveUniforms.clear(); } diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h index f471968550..2afe2976c3 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.h +++ b/src/3rdparty/angle/src/libGLESv2/Shader.h @@ -105,6 +105,8 @@ class Shader bool mUsesFrontFacing; bool mUsesPointSize; bool mUsesPointCoord; + bool mUsesDepthRange; + bool mUsesFragDepth; static void *mFragmentCompiler; static void *mVertexCompiler; diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp index 461357a1ce..72c0a8ab79 100644 --- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp @@ -14,10 +14,10 @@ #include "libGLESv2/main.h" #include "libGLESv2/mathutil.h" #include "libGLESv2/utilities.h" -#if defined(ANGLE_ENABLE_D3D11) -# define D3DFMT_UNKNOWN DXGI_FORMAT_UNKNOWN +#ifndef ANGLE_ENABLE_D3D11 +# include "libGLESv2/renderer/Blit.h" #else -# include "libGLESv2/renderer/Blit.h" +# define D3DFMT_UNKNOWN DXGI_FORMAT_UNKNOWN #endif #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/renderer/Image.h" diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h index 37f67f41ac..b2f0cad265 100644 --- a/src/3rdparty/angle/src/libGLESv2/angletypes.h +++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 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. // @@ -54,6 +54,7 @@ struct RasterizerState GLfloat polygonOffsetUnits; bool pointDrawMode; + bool multiSample; }; struct BlendState diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp index 64f67d7d6d..320bbccc27 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp @@ -4893,6 +4893,7 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp case GL_RGB565: case GL_RGB8_OES: case GL_RGBA8_OES: + case GL_BGRA8_EXT: case GL_STENCIL_INDEX8: case GL_DEPTH24_STENCIL8_OES: context->setRenderbufferStorage(width, height, internalformat, samples); @@ -6977,17 +6978,14 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) if (context->getDrawFramebufferHandle() == 0) { - if (n > 1) + if (n != 1) { return gl::error(GL_INVALID_OPERATION); } - if (n == 1) + if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) { - if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) - { - return gl::error(GL_INVALID_OPERATION); - } + return gl::error(GL_INVALID_OPERATION); } } else @@ -7008,6 +7006,11 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) { framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]); } + + for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++) + { + framebuffer->setDrawBufferState(colorAttachment, GL_NONE); + } } } catch (std::bad_alloc&) diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def index 71398b3142..b8320c8f25 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def @@ -182,4 +182,7 @@ EXPORTS glGetProcAddress @148 NONAME glBindTexImage @158 NONAME glCreateRenderer @177 NONAME - glDestroyRenderer @178 NONAME
\ No newline at end of file + glDestroyRenderer @178 NONAME + + ; Setting up TRACE macro callbacks + SetTraceFunctionPointers @180 diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def index 0f6caf17a3..ef44917d71 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def @@ -172,6 +172,7 @@ EXPORTS glDrawElementsInstancedANGLE@20 @174 glProgramBinaryOES@16 @175 glGetProgramBinaryOES@20 @176 + glDrawBuffersEXT@8 @179 ; EGL dependencies glCreateContext @144 NONAME @@ -181,4 +182,7 @@ EXPORTS glGetProcAddress@4 @148 NONAME glBindTexImage@4 @158 NONAME glCreateRenderer @177 NONAME - glDestroyRenderer @178 NONAME
\ No newline at end of file + glDestroyRenderer @178 NONAME + + ; Setting up TRACE macro callbacks + SetTraceFunctionPointers@8 @180 diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def index 2b3b34009e..3dd5683b5f 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def @@ -172,6 +172,7 @@ EXPORTS glDrawElementsInstancedANGLE @174 glProgramBinaryOES @175 glGetProgramBinaryOES @176 + glDrawBuffersEXT @179 ; EGL dependencies glCreateContext @144 NONAME @@ -182,3 +183,6 @@ EXPORTS glBindTexImage @158 NONAME glCreateRenderer @177 NONAME glDestroyRenderer @178 NONAME + + ; Setting up TRACE macro callbacks + SetTraceFunctionPointers @180 diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def index dd92a2a12b..6c8d3ed630 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def @@ -172,6 +172,7 @@ EXPORTS glDrawElementsInstancedANGLE@20 @174 glProgramBinaryOES@16 @175 glGetProgramBinaryOES@20 @176 + glDrawBuffersEXT@8 @179 ; EGL dependencies glCreateContext @144 NONAME @@ -181,4 +182,7 @@ EXPORTS glGetProcAddress@4 @148 NONAME glBindTexImage@4 @158 NONAME glCreateRenderer @177 NONAME - glDestroyRenderer @178 NONAME
\ No newline at end of file + glDestroyRenderer @178 NONAME + + ; Setting up TRACE macro callbacks + SetTraceFunctionPointers@8 @180 diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp index 5d23e8e70f..730a6ac022 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.cpp +++ b/src/3rdparty/angle/src/libGLESv2/main.cpp @@ -71,30 +71,27 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved return TRUE; } -static gl::Current *current() -{ - return (gl::Current*)TlsGetValue(currentTLS); -} - -#else // !QT_OPENGL_ES_2_ANGLE_STATIC +#endif // !QT_OPENGL_ES_2_ANGLE_STATIC -static inline gl::Current *current() +namespace gl +{ +Current *getCurrent() { +#ifndef QT_OPENGL_ES_2_ANGLE_STATIC + return (Current*)TlsGetValue(currentTLS); +#else // No precautions for thread safety taken as ANGLE is used single-threaded in Qt. static gl::Current curr = { 0, 0 }; return &curr; +#endif } -#endif // QT_OPENGL_ES_2_ANGLE_STATIC - -namespace gl -{ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) { - Current *curr = current(); + Current *current = getCurrent(); - curr->context = context; - curr->display = display; + current->context = context; + current->display = display; if (context && display && surface) { @@ -104,7 +101,9 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) Context *getContext() { - return current()->context; + Current *current = getCurrent(); + + return current->context; } Context *getNonLostContext() @@ -128,7 +127,9 @@ Context *getNonLostContext() egl::Display *getDisplay() { - return current()->display; + Current *current = getCurrent(); + + return current->display; } // Records an error code diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h index 9168a2212e..196afaeab6 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.h +++ b/src/3rdparty/angle/src/libGLESv2/main.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -58,7 +58,7 @@ gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *rend 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, HDC hDc, bool softwareDevice); +rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId); void glDestroyRenderer(rx::Renderer *renderer); __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname); diff --git a/src/3rdparty/angle/src/libGLESv2/mathutil.h b/src/3rdparty/angle/src/libGLESv2/mathutil.h index bb48b94eaf..083548669a 100644 --- a/src/3rdparty/angle/src/libGLESv2/mathutil.h +++ b/src/3rdparty/angle/src/libGLESv2/mathutil.h @@ -93,6 +93,7 @@ inline bool supportsSSE2() return supports; } +#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid() int info[4]; __cpuid(info, 0); @@ -102,6 +103,7 @@ inline bool supportsSSE2() supports = (info[3] >> 26) & 1; } +#endif checked = true; diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h index b8b043c964..50dec6b084 100644 --- a/src/3rdparty/angle/src/libGLESv2/precompiled.h +++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h @@ -32,11 +32,11 @@ #include <unordered_map> #include <vector> -#if defined(ANGLE_ENABLE_D3D11) -# include <D3D11.h> -# include <dxgi.h> +#ifndef ANGLE_ENABLE_D3D11 +#include <d3d9.h> #else -# include <d3d9.h> +#include <D3D11.h> +#include <dxgi.h> #endif #include <D3Dcompiler.h> diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp index 7fe9e6b762..3647d8a898 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp @@ -160,12 +160,20 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int bufferDesc.MiscFlags = 0; bufferDesc.StructureByteStride = 0; - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = data; - initialData.SysMemPitch = size; - initialData.SysMemSlicePitch = 0; + if (data) + { + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = data; + initialData.SysMemPitch = size; + initialData.SysMemSlicePitch = 0; + + result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer); + } + else + { + result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer); + } - result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer); if (FAILED(result)) { return gl::error(GL_OUT_OF_MEMORY); @@ -173,7 +181,7 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int mStagingBufferSize = size; } - else + else if (data) { D3D11_MAPPED_SUBRESOURCE mappedResource; result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource); @@ -182,8 +190,7 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int return gl::error(GL_OUT_OF_MEMORY); } - if (data) - memcpy(mappedResource.pData, data, size); + memcpy(mappedResource.pData, data, size); context->Unmap(mStagingBuffer, 0); } @@ -212,7 +219,6 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int mBufferSize = 0; } - if (data) { D3D11_SUBRESOURCE_DATA initialData; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp index 4468461871..e69e7a8921 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp @@ -55,7 +55,9 @@ void BufferStorage9::setData(const void* data, unsigned int size, unsigned int o mSize = std::max(mSize, offset + size); if (data) + { memcpy(reinterpret_cast<char*>(mMemory) + offset, data, size); + } } void BufferStorage9::clear() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp index 8c78c7d750..09c8922d07 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp @@ -50,8 +50,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped; - dest->map(&destMapped); - src->map(&srcMapped); + dest->map(D3D11_MAP_WRITE, &destMapped); + src->map(D3D11_MAP_READ, &srcMapped); const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData); unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData); @@ -171,7 +171,7 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig GLint unpackAlignment, const void *input) { D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(&mappedImage); + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); if (FAILED(result)) { ERR("Could not map image for loading."); @@ -194,7 +194,7 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_LUMINANCE32F_EXT: - loadLuminanceFloatDataToRGB(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_ALPHA16F_EXT: loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); @@ -230,7 +230,7 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB32F_EXT: - loadRGBFloatDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB16F_EXT: loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); @@ -254,7 +254,7 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GL ASSERT(yoffset % 4 == 0); D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(&mappedImage); + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); if (FAILED(result)) { ERR("Could not map image for loading."); @@ -344,8 +344,8 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width { // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(&mappedImage); - + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + // determine the offset coordinate into the destination buffer GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset; void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset; @@ -402,7 +402,7 @@ void Image11::createStagingTexture() desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture); @@ -420,7 +420,7 @@ void Image11::createStagingTexture() mDirty = false; } -HRESULT Image11::map(D3D11_MAPPED_SUBRESOURCE *map) +HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) { createStagingTexture(); @@ -429,7 +429,7 @@ HRESULT Image11::map(D3D11_MAPPED_SUBRESOURCE *map) if (mStagingTexture) { ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - result = deviceContext->Map(mStagingTexture, mStagingSubresource, D3D11_MAP_WRITE, 0, map); + result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); // this can fail if the device is removed (from TDR) if (d3d11::isDeviceLostError(result)) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h index 4d5f1c1780..11a6492dc8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h @@ -54,7 +54,7 @@ class Image11 : public Image virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); protected: - HRESULT map(D3D11_MAPPED_SUBRESOURCE *map); + HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); void unmap(); private: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp index 16fd782315..37dbd3e195 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp @@ -67,18 +67,30 @@ unsigned int IndexBufferInterface::getSerial() const return mIndexBuffer->getSerial(); } -int IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory) +bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) { + // Protect against integer overflow + if (mWritePosition + size < mWritePosition) + { + return false; + } + if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory)) { - *outMappedMemory = NULL; - return -1; + if (outMappedMemory) + { + *outMappedMemory = NULL; + } + return false; } - int oldWritePos = static_cast<int>(mWritePosition); - mWritePosition += size; + if (streamOffset) + { + *streamOffset = mWritePosition; + } - return oldWritePos; + mWritePosition += size; + return true; } bool IndexBufferInterface::unmapBuffer() @@ -130,12 +142,13 @@ bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum { bool result = true; unsigned int curBufferSize = getBufferSize(); + unsigned int writePos = getWritePosition(); if (size > curBufferSize) { result = setBufferSize(std::max(size, 2 * curBufferSize), indexType); setWritePosition(0); } - else if (getWritePosition() + size > curBufferSize) + else if (writePos + size > curBufferSize || writePos + size < writePos) { if (!discard()) { @@ -175,27 +188,9 @@ bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum in } } -unsigned int StaticIndexBufferInterface::lookupRange(intptr_t offset, GLsizei count, unsigned int *minIndex, unsigned int *maxIndex) -{ - IndexRange range = {offset, count}; - - std::map<IndexRange, IndexResult>::iterator res = mCache.find(range); - - if (res == mCache.end()) - { - return -1; - } - - *minIndex = res->second.minIndex; - *maxIndex = res->second.maxIndex; - return res->second.streamOffset; -} - -void StaticIndexBufferInterface::addRange(intptr_t offset, GLsizei count, unsigned int minIndex, unsigned int maxIndex, unsigned int streamOffset) +IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() { - IndexRange indexRange = {offset, count}; - IndexResult indexResult = {minIndex, maxIndex, streamOffset}; - mCache[indexRange] = indexResult; + return &mIndexRangeCache; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h index 1afbd626fa..6fb885a1cd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_INDEXBUFFER_H_ #include "common/angleutils.h" +#include "libGLESv2/renderer/IndexRangeCache.h" namespace rx { @@ -58,7 +59,7 @@ class IndexBufferInterface unsigned int getSerial() const; - int mapBuffer(unsigned int size, void** outMappedMemory); + bool mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset); bool unmapBuffer(); IndexBuffer *getIndexBuffer() const; @@ -99,37 +100,10 @@ class StaticIndexBufferInterface : public IndexBufferInterface virtual bool reserveBufferSpace(unsigned int size, GLenum indexType); - unsigned int lookupRange(intptr_t offset, GLsizei count, unsigned int *minIndex, unsigned int *maxIndex); // Returns the offset into the index buffer, or -1 if not found - void addRange(intptr_t offset, GLsizei count, unsigned int minIndex, unsigned int maxIndex, unsigned int streamOffset); + IndexRangeCache *getIndexRangeCache(); private: - struct IndexRange - { - intptr_t offset; - GLsizei count; - - bool operator<(const IndexRange& rhs) const - { - if (offset != rhs.offset) - { - return offset < rhs.offset; - } - if (count != rhs.count) - { - return count < rhs.count; - } - return false; - } - }; - - struct IndexResult - { - unsigned int minIndex; - unsigned int maxIndex; - unsigned int streamOffset; - }; - - std::map<IndexRange, IndexResult> mCache; + IndexRangeCache mIndexRangeCache; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp index 2a442ecd1a..66604c4558 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp @@ -75,7 +75,8 @@ bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** out { if (mBuffer) { - if (offset + size > mBufferSize) + // Check for integer overflows and out-out-bounds map requests + if (offset + size < offset || offset + size > mBufferSize) { ERR("Index buffer map range is not inside the buffer."); return false; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp index 84b79b4109..49bace8193 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp @@ -13,6 +13,7 @@ #include "libGLESv2/Buffer.h" #include "libGLESv2/main.h" +#include "libGLESv2/utilities.h" #include "libGLESv2/renderer/IndexBuffer.h" namespace rx @@ -53,17 +54,6 @@ IndexDataManager::~IndexDataManager() delete mCountingBuffer; } -static unsigned int indexTypeSize(GLenum type) -{ - switch (type) - { - case GL_UNSIGNED_INT: return sizeof(GLuint); - case GL_UNSIGNED_SHORT: return sizeof(GLushort); - case GL_UNSIGNED_BYTE: return sizeof(GLubyte); - default: UNREACHABLE(); return sizeof(GLushort); - } -} - static void convertIndices(GLenum type, const void *input, GLsizei count, void *output) { if (type == GL_UNSIGNED_BYTE) @@ -125,13 +115,19 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer } GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; - intptr_t offset = reinterpret_cast<intptr_t>(indices); + unsigned int offset = 0; bool alignedOffset = false; BufferStorage *storage = NULL; if (buffer != NULL) { + if (reinterpret_cast<uintptr_t>(indices) > std::numeric_limits<unsigned int>::max()) + { + return GL_OUT_OF_MEMORY; + } + offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices)); + storage = buffer->getStorage(); switch (type) @@ -142,7 +138,16 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer default: UNREACHABLE(); alignedOffset = false; } - if (indexTypeSize(type) * count + offset > storage->getSize()) + unsigned int typeSize = gl::ComputeTypeSize(type); + + // check for integer overflows + if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeSize) || + typeSize * static_cast<unsigned int>(count) + offset < offset) + { + return GL_OUT_OF_MEMORY; + } + + if (typeSize * static_cast<unsigned int>(count) + offset > storage->getSize()) { return GL_INVALID_OPERATION; } @@ -156,37 +161,44 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer IndexBufferInterface *indexBuffer = streamingBuffer; bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() && destinationIndexType == type; - UINT streamOffset = 0; + unsigned int streamOffset = 0; if (directStorage) { indexBuffer = streamingBuffer; streamOffset = offset; storage->markBufferUsage(); - computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); + + if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex, + &translated->maxIndex, NULL)) + { + computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); + buffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, + translated->maxIndex, offset); + } } else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset) { indexBuffer = staticBuffer; - streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex); - - if (streamOffset == -1) + if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex, + &translated->maxIndex, &streamOffset)) { - streamOffset = (offset / indexTypeSize(type)) * indexTypeSize(destinationIndexType); + streamOffset = (offset / gl::ComputeTypeSize(type)) * gl::ComputeTypeSize(destinationIndexType); computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); - staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset); + staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, + translated->maxIndex, streamOffset); } } else { - int convertCount = count; + unsigned int convertCount = count; if (staticBuffer) { if (staticBuffer->getBufferSize() == 0 && alignedOffset) { indexBuffer = staticBuffer; - convertCount = storage->getSize() / indexTypeSize(type); + convertCount = storage->getSize() / gl::ComputeTypeSize(type); } else { @@ -201,12 +213,22 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer return GL_INVALID_OPERATION; } - unsigned int bufferSizeRequired = convertCount * indexTypeSize(destinationIndexType); - indexBuffer->reserveBufferSpace(bufferSizeRequired, type); + unsigned int indexTypeSize = gl::ComputeTypeSize(destinationIndexType); + if (convertCount > std::numeric_limits<unsigned int>::max() / indexTypeSize) + { + ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, indexTypeSize); + return GL_OUT_OF_MEMORY; + } + + unsigned int bufferSizeRequired = convertCount * indexTypeSize; + if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type)) + { + ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired); + return GL_OUT_OF_MEMORY; + } void* output = NULL; - streamOffset = indexBuffer->mapBuffer(bufferSizeRequired, &output); - if (streamOffset == -1 || output == NULL) + if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset)) { ERR("Failed to map index buffer."); return GL_OUT_OF_MEMORY; @@ -224,20 +246,21 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer if (staticBuffer) { - streamOffset = (offset / indexTypeSize(type)) * indexTypeSize(destinationIndexType); - staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset); + streamOffset = (offset / gl::ComputeTypeSize(type)) * gl::ComputeTypeSize(destinationIndexType); + staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, + translated->maxIndex, streamOffset); } } translated->storage = directStorage ? storage : NULL; translated->indexBuffer = indexBuffer->getIndexBuffer(); translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial(); - translated->startIndex = streamOffset / indexTypeSize(destinationIndexType); + translated->startIndex = streamOffset / gl::ComputeTypeSize(destinationIndexType); translated->startOffset = streamOffset; if (buffer) { - buffer->promoteStaticUsage(count * indexTypeSize(type)); + buffer->promoteStaticUsage(count * gl::ComputeTypeSize(type)); } return GL_NO_ERROR; @@ -256,7 +279,7 @@ StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count) mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); void* mappedMemory = NULL; - if (mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory) == -1 || mappedMemory == NULL) + if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL)) { ERR("Failed to map counting buffer."); return NULL; @@ -286,7 +309,7 @@ StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count) mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); void* mappedMemory = NULL; - if (mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory) == -1 || mappedMemory == NULL) + if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL)) { ERR("Failed to map counting buffer."); return NULL; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp new file mode 100644 index 0000000000..610a5efb9c --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp @@ -0,0 +1,97 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// IndexRangeCache.cpp: Defines the rx::IndexRangeCache class which stores information about +// ranges of indices. + +#include "libGLESv2/renderer/IndexRangeCache.h" +#include "common/debug.h" +#include "libGLESv2/utilities.h" +#include <tuple> + +namespace rx +{ + +void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx, + unsigned int streamOffset) +{ + mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(minIdx, maxIdx, streamOffset); +} + +void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size) +{ + unsigned int invalidateStart = offset; + unsigned int invalidateEnd = offset + size; + + IndexRangeMap::iterator i = mIndexRangeCache.begin(); + while (i != mIndexRangeCache.end()) + { + unsigned int rangeStart = i->second.streamOffset; + unsigned int rangeEnd = i->second.streamOffset + (gl::ComputeTypeSize(i->first.type) * i->first.count); + + if (invalidateEnd < rangeStart || invalidateStart > rangeEnd) + { + ++i; + } + else + { + i = mIndexRangeCache.erase(i); + } + } +} + +bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex, + unsigned int *outMaxIndex, unsigned int *outStreamOffset) const +{ + IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count)); + if (i != mIndexRangeCache.end()) + { + if (outMinIndex) *outMinIndex = i->second.minIndex; + if (outMaxIndex) *outMaxIndex = i->second.maxIndex; + if (outStreamOffset) *outStreamOffset = i->second.streamOffset; + return true; + } + else + { + if (outMinIndex) *outMinIndex = 0; + if (outMaxIndex) *outMaxIndex = 0; + if (outStreamOffset) *outStreamOffset = 0; + return false; + } +} + +void IndexRangeCache::clear() +{ + mIndexRangeCache.clear(); +} + +IndexRangeCache::IndexRange::IndexRange() + : type(GL_NONE), offset(0), count(0) +{ +} + +IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c) + : type(typ), offset(off), count(c) +{ +} + +bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const +{ + return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count); +} + +IndexRangeCache::IndexBounds::IndexBounds() + : minIndex(0), maxIndex(0), streamOffset(0) +{ +} + +IndexRangeCache::IndexBounds::IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset) + : minIndex(minIdx), maxIndex(maxIdx), streamOffset(offset) +{ +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h new file mode 100644 index 0000000000..56834306f2 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h @@ -0,0 +1,58 @@ +// +// Copyright (c) 2013 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. +// + +// IndexRangeCache.h: Defines the rx::IndexRangeCache class which stores information about +// ranges of indices. + +#ifndef LIBGLESV2_RENDERER_INDEXRANGECACHE_H_ +#define LIBGLESV2_RENDERER_INDEXRANGECACHE_H_ + +#include "common/angleutils.h" + +namespace rx +{ + +class IndexRangeCache +{ + public: + void addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx, + unsigned int streamOffset); + bool findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex, + unsigned int *outMaxIndex, unsigned int *outStreamOffset) const; + + void invalidateRange(unsigned int offset, unsigned int size); + void clear(); + + private: + struct IndexRange + { + GLenum type; + unsigned int offset; + GLsizei count; + + IndexRange(); + IndexRange(GLenum type, intptr_t offset, GLsizei count); + + bool operator<(const IndexRange& rhs) const; + }; + + struct IndexBounds + { + unsigned int minIndex; + unsigned int maxIndex; + unsigned int streamOffset; + + IndexBounds(); + IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset); + }; + + typedef std::map<IndexRange, IndexBounds> IndexRangeMap; + IndexRangeMap mIndexRangeCache; +}; + +} + +#endif LIBGLESV2_RENDERER_INDEXRANGECACHE_H diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp index 0402bb35ac..1552f3a326 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp @@ -28,6 +28,13 @@ InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInp mCounter = 0; mDevice = NULL; mDeviceContext = NULL; + mCurrentIL = NULL; + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mCurrentBuffers[i] = -1; + mCurrentVertexStrides[i] = -1; + mCurrentVertexOffsets[i] = -1; + } } InputLayoutCache::~InputLayoutCache() @@ -49,6 +56,18 @@ void InputLayoutCache::clear() i->second.inputLayout->Release(); } mInputLayoutMap.clear(); + markDirty(); +} + +void InputLayoutCache::markDirty() +{ + mCurrentIL = NULL; + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mCurrentBuffers[i] = -1; + mCurrentVertexStrides[i] = -1; + mCurrentVertexOffsets[i] = -1; + } } GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], @@ -66,6 +85,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M InputLayoutKey ilKey = { 0 }; ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL }; + unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 }; UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 }; UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 }; @@ -83,18 +103,19 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M // Record the type of the associated vertex shader vector in our key // This will prevent mismatched vertex shaders from using the same input layout GLint attributeSize; - programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.glslElementType[ilKey.elementCount], NULL); - - ilKey.elements[ilKey.elementCount].SemanticName = semanticName; - ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i]; - ilKey.elements[ilKey.elementCount].Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT; - ilKey.elements[ilKey.elementCount].InputSlot = i; - ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0; - ilKey.elements[ilKey.elementCount].InputSlotClass = inputClass; - ilKey.elements[ilKey.elementCount].InstanceDataStepRate = attributes[i].divisor; + programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL); + + ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; + ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i]; + ilKey.elements[ilKey.elementCount].desc.Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT; + ilKey.elements[ilKey.elementCount].desc.InputSlot = i; + ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; + ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; + ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor; ilKey.elementCount++; vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer(); + vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial(); vertexStrides[i] = attributes[i].stride; vertexOffsets[i] = attributes[i].offset; } @@ -112,7 +133,13 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M { ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); - HRESULT result = mDevice->CreateInputLayout(ilKey.elements, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); + D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; + for (unsigned int j = 0; j < ilKey.elementCount; ++j) + { + descs[j] = ilKey.elements[j].desc; + } + + HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); if (FAILED(result)) { ERR("Failed to crate input layout, result: 0x%08x", result); @@ -143,8 +170,23 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair)); } - mDeviceContext->IASetInputLayout(inputLayout); - mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, vertexBuffers, vertexStrides, vertexOffsets); + if (inputLayout != mCurrentIL) + { + mDeviceContext->IASetInputLayout(inputLayout); + mCurrentIL = inputLayout; + } + + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] || + vertexOffsets[i] != mCurrentVertexOffsets[i]) + { + mDeviceContext->IASetVertexBuffers(i, 1, &vertexBuffers[i], &vertexStrides[i], &vertexOffsets[i]); + mCurrentBuffers[i] = vertexBufferSerials[i]; + mCurrentVertexStrides[i] = vertexStrides[i]; + mCurrentVertexOffsets[i] = vertexOffsets[i]; + } + } return GL_NO_ERROR; } @@ -154,13 +196,18 @@ std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout) static const unsigned int seed = 0xDEADBEEF; std::size_t hash = 0; - MurmurHash3_x86_32(&inputLayout, sizeof(InputLayoutKey), seed, &hash); + MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash); return hash; } bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b) { - return memcmp(&a, &b, sizeof(InputLayoutKey)) == 0; + if (a.elementCount != b.elementCount) + { + return false; + } + + return std::equal(a.begin(), a.end(), b.begin()); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h index d95f39fae4..bb1a8eebcf 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h @@ -30,6 +30,7 @@ class InputLayoutCache void initialize(ID3D11Device *device, ID3D11DeviceContext *context); void clear(); + void markDirty(); GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], gl::ProgramBinary *programBinary); @@ -37,11 +38,26 @@ class InputLayoutCache private: DISALLOW_COPY_AND_ASSIGN(InputLayoutCache); + struct InputLayoutElement + { + D3D11_INPUT_ELEMENT_DESC desc; + GLenum glslElementType; + }; + struct InputLayoutKey { unsigned int elementCount; - D3D11_INPUT_ELEMENT_DESC elements[gl::MAX_VERTEX_ATTRIBS]; - GLenum glslElementType[gl::MAX_VERTEX_ATTRIBS]; + InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS]; + + const char *begin() const + { + return reinterpret_cast<const char*>(&elementCount); + } + + const char *end() const + { + return reinterpret_cast<const char*>(&elements[elementCount]); + } }; struct InputLayoutCounterPair @@ -50,6 +66,11 @@ class InputLayoutCache unsigned long long lastUsedTime; }; + ID3D11InputLayout *mCurrentIL; + unsigned int mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; + UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; + UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; + static std::size_t hashInputLayout(const InputLayoutKey &inputLayout); static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp index f60a88f97a..b3111af72b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp @@ -231,7 +231,7 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; rasterDesc.DepthClipEnable = TRUE; rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; - rasterDesc.MultisampleEnable = TRUE; + rasterDesc.MultisampleEnable = rasterState.multiSample; rasterDesc.AntialiasedLineEnable = FALSE; ID3D11RasterizerState *dx11RasterizerState = NULL; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp index cf226de17b..2667cc6fa7 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp @@ -329,44 +329,21 @@ RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) ID3D11Texture2D *RenderTarget11::getTexture() const { - if (mTexture) - { - mTexture->AddRef(); - } - return mTexture; } -// Adds reference, caller must call Release ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const { - if (mRenderTarget) - { - mRenderTarget->AddRef(); - } - return mRenderTarget; } -// Adds reference, caller must call Release ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const { - if (mDepthStencil) - { - mDepthStencil->AddRef(); - } - return mDepthStencil; } -// Adds reference, caller must call Release ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const { - if (mShaderResource) - { - mShaderResource->AddRef(); - } - return mShaderResource; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h index dc697cf0e3..97827f2639 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h @@ -27,16 +27,9 @@ class RenderTarget11 : public RenderTarget static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget); - // Adds reference, caller must call Release ID3D11Texture2D *getTexture() const; - - // Adds reference, caller must call Release ID3D11RenderTargetView *getRenderTargetView() const; - - // Adds reference, caller must call Release ID3D11DepthStencilView *getDepthStencilView() const; - - // Adds reference, caller must call Release ID3D11ShaderResourceView *getShaderResourceView() const; unsigned int getSubresourceIndex() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp index 218356c59b..21ad223467 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp @@ -7,19 +7,25 @@ // Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. +#include <EGL/eglext.h> #include "libGLESv2/main.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/Renderer.h" -#if defined(ANGLE_ENABLE_D3D11) -# include "libGLESv2/renderer/Renderer11.h" -# define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT( 1, 0x876, 380 ) +#ifndef ANGLE_ENABLE_D3D11 +#include "libGLESv2/renderer/Renderer9.h" #else -# include "libGLESv2/renderer/Renderer9.h" +#include "libGLESv2/renderer/Renderer11.h" #endif #include "libGLESv2/utilities.h" +#include "third_party/trace_event/trace_event.h" -#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) -#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +#if !defined(ANGLE_ENABLE_D3D11) +// Enables use of the Direct3D 11 API for a default display, when available +#define ANGLE_ENABLE_D3D11 0 +#endif + +#ifndef D3DERR_OUTOFVIDEOMEMORY +#define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380) #endif #ifdef __MINGW32__ @@ -61,6 +67,7 @@ Renderer::~Renderer() bool Renderer::initializeCompiler() { + TRACE_EVENT0("gpu", "initializeCompiler"); #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; @@ -188,14 +195,15 @@ ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, co extern "C" { -rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, bool softwareDevice) +rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId) { rx::Renderer *renderer = NULL; EGLint status = EGL_BAD_ALLOC; -#if defined(ANGLE_ENABLE_D3D11) +#if ANGLE_ENABLE_D3D11 renderer = new rx::Renderer11(display, hDc); #else + bool softwareDevice = (displayId == EGL_SOFTWARE_DISPLAY_ANGLE); renderer = new rx::Renderer9(display, hDc, softwareDevice); #endif @@ -217,4 +225,4 @@ void glDestroyRenderer(rx::Renderer *renderer) delete renderer; } -} +}
\ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h index 656cb0f1bf..04e877ba9e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h @@ -13,6 +13,10 @@ #include "libGLESv2/Uniform.h" #include "libGLESv2/angletypes.h" +#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) +#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + const int versionWindowsVista = MAKEWORD(0x00, 0x06); const int versionWindows7 = MAKEWORD(0x01, 0x06); @@ -221,6 +225,8 @@ class Renderer virtual QueryImpl *createQuery(GLenum type) = 0; virtual FenceImpl *createFence() = 0; + virtual bool getLUID(LUID *adapterLuid) const = 0; + protected: bool initializeCompiler(); ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp index cf083963e1..a43101807a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp @@ -35,7 +35,8 @@ #include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h" #include "libGLESv2/renderer/shaders/compiled/clear11vs.h" -#include "libGLESv2/renderer/shaders/compiled/clear11ps.h" +#include "libGLESv2/renderer/shaders/compiled/clearsingle11ps.h" +#include "libGLESv2/renderer/shaders/compiled/clearmultiple11ps.h" #include "libEGL/Display.h" @@ -87,7 +88,8 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc( mClearVB = NULL; mClearIL = NULL; mClearVS = NULL; - mClearPS = NULL; + mClearSinglePS = NULL; + mClearMultiplePS = NULL; mClearScissorRS = NULL; mClearNoScissorRS = NULL; @@ -161,25 +163,44 @@ EGLint Renderer11::initialize() D3D_FEATURE_LEVEL_10_0, }; - HRESULT result = D3D11CreateDevice(NULL, - D3D_DRIVER_TYPE_HARDWARE, - NULL, - #if defined(_DEBUG) - D3D11_CREATE_DEVICE_DEBUG, - #else - 0, - #endif - featureLevels, - ArraySize(featureLevels), - D3D11_SDK_VERSION, - &mDevice, - &mFeatureLevel, - &mDeviceContext); + HRESULT result = S_OK; + +#ifdef _DEBUG + result = D3D11CreateDevice(NULL, + D3D_DRIVER_TYPE_HARDWARE, + NULL, + D3D11_CREATE_DEVICE_DEBUG, + featureLevels, + ArraySize(featureLevels), + D3D11_SDK_VERSION, + &mDevice, + &mFeatureLevel, + &mDeviceContext); if (!mDevice || FAILED(result)) { - ERR("Could not create D3D11 device - aborting!\n"); - return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer + ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); + } + + if (!mDevice || FAILED(result)) +#endif + { + result = D3D11CreateDevice(NULL, + D3D_DRIVER_TYPE_HARDWARE, + NULL, + 0, + featureLevels, + ArraySize(featureLevels), + D3D11_SDK_VERSION, + &mDevice, + &mFeatureLevel, + &mDeviceContext); + + if (!mDevice || FAILED(result)) + { + ERR("Could not create D3D11 device - aborting!\n"); + return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer + } } IDXGIDevice *dxgiDevice = NULL; @@ -301,7 +322,6 @@ EGLint Renderer11::initialize() { DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, }; @@ -655,7 +675,23 @@ void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color "blend state."); } - const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha }; + float blendColors[4] = {0.0f}; + if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) + { + blendColors[0] = blendColor.red; + blendColors[1] = blendColor.green; + blendColors[2] = blendColor.blue; + blendColors[3] = blendColor.alpha; + } + else + { + blendColors[0] = blendColor.alpha; + blendColors[1] = blendColor.alpha; + blendColors[2] = blendColor.alpha; + blendColors[3] = blendColor.alpha; + } + mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); mCurBlendState = blendState; @@ -798,23 +834,29 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) { D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + GLsizei minCount = 0; + switch (mode) { - case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break; - case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break; - case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break; - case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break; - case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; - case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break; + case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; minCount = 1; break; + case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; minCount = 2; break; + case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; + case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; + case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; + case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break; // emulate fans via rewriting index buffer - case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; + case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; default: return gl::error(GL_INVALID_ENUM, false); } - mDeviceContext->IASetPrimitiveTopology(primitiveTopology); + if (primitiveTopology != mCurrentPrimitiveTopology) + { + mDeviceContext->IASetPrimitiveTopology(primitiveTopology); + mCurrentPrimitiveTopology = primitiveTopology; + } - return count > 0; + return count >= minCount; } bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) @@ -976,9 +1018,6 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) mDepthStencilInitialized = true; } - SafeRelease(framebufferRTVs); - SafeRelease(framebufferDSV); - return true; } @@ -1093,7 +1132,16 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } - const int spaceNeeded = (count + 1) * sizeof(unsigned int); + // Checked by Renderer11::applyPrimitiveType + ASSERT(count >= 0); + + if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int))) + { + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); @@ -1101,15 +1149,15 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } void* mappedMemory = NULL; - int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory); - if (offset == -1 || mappedMemory == NULL) + unsigned int offset; + if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) { ERR("Could not map index buffer for GL_LINE_LOOP."); return gl::error(GL_OUT_OF_MEMORY); } unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); - unsigned int indexBufferOffset = static_cast<unsigned int>(offset); + unsigned int indexBufferOffset = offset; switch (type) { @@ -1187,8 +1235,18 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } } - const int numTris = count - 2; - const int spaceNeeded = (numTris * 3) * sizeof(unsigned int); + // Checked by Renderer11::applyPrimitiveType + ASSERT(count >= 3); + + const unsigned int numTris = count - 2; + + if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3))) + { + ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int); if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); @@ -1196,20 +1254,20 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } void* mappedMemory = NULL; - int offset = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory); - if (offset == -1 || mappedMemory == NULL) + unsigned int offset; + if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) { ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN."); return gl::error(GL_OUT_OF_MEMORY); } unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); - unsigned int indexBufferOffset = static_cast<unsigned int>(offset); + unsigned int indexBufferOffset = offset; switch (type) { case GL_NONE: // Non-indexed draw - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = 0; data[i*3 + 1] = i + 1; @@ -1217,7 +1275,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } break; case GL_UNSIGNED_BYTE: - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0]; data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1]; @@ -1225,7 +1283,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } break; case GL_UNSIGNED_SHORT: - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = static_cast<const GLushort*>(indices)[0]; data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1]; @@ -1233,7 +1291,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } break; case GL_UNSIGNED_INT: - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = static_cast<const GLuint*>(indices)[0]; data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1]; @@ -1347,21 +1405,21 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra float (*mapVS)[4] = NULL; float (*mapPS)[4] = NULL; - if (totalRegisterCountVS > 0 && vertexUniformsDirty) - { - D3D11_MAPPED_SUBRESOURCE map = {0}; - HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - ASSERT(SUCCEEDED(result)); - mapVS = (float(*)[4])map.pData; - } - - if (totalRegisterCountPS > 0 && pixelUniformsDirty) - { - D3D11_MAPPED_SUBRESOURCE map = {0}; - HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - ASSERT(SUCCEEDED(result)); - mapPS = (float(*)[4])map.pData; - } + if (totalRegisterCountVS > 0 && vertexUniformsDirty) + { + D3D11_MAPPED_SUBRESOURCE map = {0}; + HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + ASSERT(SUCCEEDED(result)); + mapVS = (float(*)[4])map.pData; + } + + if (totalRegisterCountPS > 0 && pixelUniformsDirty) + { + D3D11_MAPPED_SUBRESOURCE map = {0}; + HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + ASSERT(SUCCEEDED(result)); + mapPS = (float(*)[4])map.pData; + } for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) { @@ -1392,9 +1450,18 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra { mDeviceContext->Unmap(pixelConstantBuffer, 0); } - - mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); - mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); + + if (mCurrentVertexConstantBuffer != vertexConstantBuffer) + { + mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); + mCurrentVertexConstantBuffer = vertexConstantBuffer; + } + + if (mCurrentPixelConstantBuffer != pixelConstantBuffer) + { + mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); + mCurrentPixelConstantBuffer = pixelConstantBuffer; + } // Driver uniforms if (!mDriverConstantBufferVS) @@ -1442,7 +1509,11 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra } // needed for the point sprite geometry shader - mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); + if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) + { + mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); + mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; + } } void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) @@ -1467,7 +1538,7 @@ void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer * if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear) { - maskedClear(clearParams); + maskedClear(clearParams, frameBuffer->usingExtendedDrawBuffers()); } else { @@ -1499,8 +1570,6 @@ void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer * clearParams.colorClearValue.blue, clearParams.colorClearValue.alpha }; mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues); - - framebufferRTV->Release(); } } } @@ -1538,20 +1607,18 @@ void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer * UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF; mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); - - framebufferDSV->Release(); } } } } -void Renderer11::maskedClear(const gl::ClearParameters &clearParams) +void Renderer11::maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers) { HRESULT result; if (!mClearResourcesInitialized) { - ASSERT(!mClearVB && !mClearVS && !mClearPS && !mClearScissorRS && !mClearNoScissorRS); + ASSERT(!mClearVB && !mClearVS && !mClearSinglePS && !mClearMultiplePS && !mClearScissorRS && !mClearNoScissorRS); D3D11_BUFFER_DESC vbDesc; vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4; @@ -1579,9 +1646,13 @@ void Renderer11::maskedClear(const gl::ClearParameters &clearParams) ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mClearVS, "Renderer11 masked clear vertex shader"); - result = mDevice->CreatePixelShader(g_PS_Clear, sizeof(g_PS_Clear), NULL, &mClearPS); + result = mDevice->CreatePixelShader(g_PS_ClearSingle, sizeof(g_PS_ClearSingle), NULL, &mClearSinglePS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearSinglePS, "Renderer11 masked clear pixel shader (1 RT)"); + + result = mDevice->CreatePixelShader(g_PS_ClearMultiple, sizeof(g_PS_ClearMultiple), NULL, &mClearMultiplePS); ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearPS, "Renderer11 masked clear pixel shader"); + d3d11::SetDebugName(mClearMultiplePS, "Renderer11 masked clear pixel shader (MRT)"); D3D11_RASTERIZER_DESC rsScissorDesc; rsScissorDesc.FillMode = D3D11_FILL_SOLID; @@ -1688,9 +1759,11 @@ void Renderer11::maskedClear(const gl::ClearParameters &clearParams) mDeviceContext->RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS); // Apply shaders + ID3D11PixelShader *pixelShader = usingExtendedDrawBuffers ? mClearMultiplePS : mClearSinglePS; + mDeviceContext->IASetInputLayout(mClearIL); mDeviceContext->VSSetShader(mClearVS, NULL, 0); - mDeviceContext->PSSetShader(mClearPS, NULL, 0); + mDeviceContext->PSSetShader(pixelShader, NULL, 0); mDeviceContext->GSSetShader(NULL, NULL, 0); // Apply vertex buffer @@ -1741,6 +1814,14 @@ void Renderer11::markAllStateDirty() mAppliedProgramBinarySerial = 0; memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants)); memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants)); + + mInputLayoutCache.markDirty(); + + mCurrentVertexConstantBuffer = NULL; + mCurrentPixelConstantBuffer = NULL; + mCurrentGeometryConstantBuffer = NULL; + + mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; } void Renderer11::releaseDeviceResources() @@ -1760,111 +1841,31 @@ void Renderer11::releaseDeviceResources() delete mTriangleFanIB; mTriangleFanIB = NULL; - if (mCopyVB) - { - mCopyVB->Release(); - mCopyVB = NULL; - } - - if (mCopySampler) - { - mCopySampler->Release(); - mCopySampler = NULL; - } - - if (mCopyIL) - { - mCopyIL->Release(); - mCopyIL = NULL; - } - - if (mCopyVS) - { - mCopyVS->Release(); - mCopyVS = NULL; - } - - if (mCopyRGBAPS) - { - mCopyRGBAPS->Release(); - mCopyRGBAPS = NULL; - } - - if (mCopyRGBPS) - { - mCopyRGBPS->Release(); - mCopyRGBPS = NULL; - } - - if (mCopyLumPS) - { - mCopyLumPS->Release(); - mCopyLumPS = NULL; - } - - if (mCopyLumAlphaPS) - { - mCopyLumAlphaPS->Release(); - mCopyLumAlphaPS = NULL; - } + SafeRelease(mCopyVB); + SafeRelease(mCopySampler); + SafeRelease(mCopyIL); + SafeRelease(mCopyIL); + SafeRelease(mCopyVS); + SafeRelease(mCopyRGBAPS); + SafeRelease(mCopyRGBPS); + SafeRelease(mCopyLumPS); + SafeRelease(mCopyLumAlphaPS); mCopyResourcesInitialized = false; - if (mClearVB) - { - mClearVB->Release(); - mClearVB = NULL; - } - - if (mClearIL) - { - mClearIL->Release(); - mClearIL = NULL; - } - - if (mClearVS) - { - mClearVS->Release(); - mClearVS = NULL; - } - - if (mClearPS) - { - mClearPS->Release(); - mClearPS = NULL; - } - - if (mClearScissorRS) - { - mClearScissorRS->Release(); - mClearScissorRS = NULL; - } - - if (mClearNoScissorRS) - { - mClearNoScissorRS->Release(); - mClearNoScissorRS = NULL; - } + SafeRelease(mClearVB); + SafeRelease(mClearIL); + SafeRelease(mClearVS); + SafeRelease(mClearSinglePS); + SafeRelease(mClearMultiplePS); + SafeRelease(mClearScissorRS); + SafeRelease(mClearNoScissorRS); mClearResourcesInitialized = false; - if (mDriverConstantBufferVS) - { - mDriverConstantBufferVS->Release(); - mDriverConstantBufferVS = NULL; - } - - if (mDriverConstantBufferPS) - { - mDriverConstantBufferPS->Release(); - mDriverConstantBufferPS = NULL; - } - - if (mSyncQuery) - { - mSyncQuery->Release(); - mSyncQuery = NULL; - } + SafeRelease(mDriverConstantBufferVS); + SafeRelease(mDriverConstantBufferPS); + SafeRelease(mSyncQuery); } void Renderer11::notifyDeviceLost() @@ -2153,12 +2154,12 @@ unsigned int Renderer11::getMaxCombinedTextureImageUnits() const unsigned int Renderer11::getReservedVertexUniformVectors() const { - return 0; // Driver uniforms are stored in a separate constant buffer + return 0; // Driver uniforms are stored in a separate constant buffer } unsigned int Renderer11::getReservedFragmentUniformVectors() const { - return 0; // Driver uniforms are stored in a separate constant buffer + return 0; // Driver uniforms are stored in a separate constant buffer } unsigned int Renderer11::getMaxVertexUniformVectors() const @@ -2448,7 +2449,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); if (!storage11) { - source->Release(); ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } @@ -2456,7 +2456,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level)); if (!destRenderTarget) { - source->Release(); ERR("Failed to retrieve the render target from the destination storage."); return gl::error(GL_OUT_OF_MEMORY, false); } @@ -2464,7 +2463,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); if (!dest) { - source->Release(); ERR("Failed to retrieve the render target view from the destination render target."); return gl::error(GL_OUT_OF_MEMORY, false); } @@ -2478,9 +2476,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); - source->Release(); - dest->Release(); - return ret; } @@ -2511,7 +2506,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); if (!storage11) { - source->Release(); ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } @@ -2519,7 +2513,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level)); if (!destRenderTarget) { - source->Release(); ERR("Failed to retrieve the render target from the destination storage."); return gl::error(GL_OUT_OF_MEMORY, false); } @@ -2527,7 +2520,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); if (!dest) { - source->Release(); ERR("Failed to retrieve the render target view from the destination render target."); return gl::error(GL_OUT_OF_MEMORY, false); } @@ -2541,9 +2533,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); - source->Release(); - dest->Release(); - return ret; } @@ -2893,7 +2882,6 @@ bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned { ID3D11Resource *textureResource = NULL; colorBufferRTV->GetResource(&textureResource); - colorBufferRTV->Release(); if (textureResource) { @@ -3428,6 +3416,16 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R { ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height); + RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); + if (!drawRenderTarget) + { + ERR("Failed to retrieve the draw render target from the draw framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture(); + unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); + RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); if (!readRenderTarget) { @@ -3439,16 +3437,13 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R unsigned int readSubresource = 0; if (readRenderTarget->getSamples() > 0) { - ID3D11Texture2D *unresolvedTexture = readRenderTarget11->getTexture(); - - readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex()); + readTexture = resolveMultisampledTexture(readRenderTarget11->getTexture(), readRenderTarget11->getSubresourceIndex()); readSubresource = 0; - - unresolvedTexture->Release(); } else { readTexture = readRenderTarget11->getTexture(); + readTexture->AddRef(); readSubresource = readRenderTarget11->getSubresourceIndex(); } @@ -3458,17 +3453,6 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); - if (!drawRenderTarget) - { - readTexture->Release(); - ERR("Failed to retrieve the draw render target from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture(); - unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); - D3D11_BOX readBox; readBox.left = readRect.x; readBox.right = readRect.x + readRect.width; @@ -3484,8 +3468,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0, readTexture, readSubresource, pSrcBox); - readTexture->Release(); - drawTexture->Release(); + SafeRelease(readTexture); return true; } @@ -3528,4 +3511,24 @@ ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, } } +bool Renderer11::getLUID(LUID *adapterLuid) const +{ + adapterLuid->HighPart = 0; + adapterLuid->LowPart = 0; + + if (!mDxgiAdapter) + { + return false; + } + + DXGI_ADAPTER_DESC adapterDesc; + if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc))) + { + return false; + } + + *adapterLuid = adapterDesc.AdapterLuid; + return true; +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h index a3e42e9048..f024855f97 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h @@ -182,6 +182,8 @@ class Renderer11 : public Renderer void unapplyRenderTargets(); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); + virtual bool getLUID(LUID *adapterLuid) const; + private: DISALLOW_COPY_AND_ASSIGN(Renderer11); @@ -192,7 +194,7 @@ class Renderer11 : public Renderer GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void *pixels); - void maskedClear(const gl::ClearParameters &clearParams); + void maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers); rx::Range getViewportBounds() const; bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, @@ -286,6 +288,9 @@ class Renderer11 : public Renderer float mCurNear; float mCurFar; + // Currently applied primitive topology + D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; + unsigned int mAppliedIBSerial; unsigned int mAppliedStorageIBSerial; unsigned int mAppliedIBOffset; @@ -296,10 +301,14 @@ class Renderer11 : public Renderer dx_VertexConstants mVertexConstants; dx_VertexConstants mAppliedVertexConstants; ID3D11Buffer *mDriverConstantBufferVS; + ID3D11Buffer *mCurrentVertexConstantBuffer; dx_PixelConstants mPixelConstants; dx_PixelConstants mAppliedPixelConstants; ID3D11Buffer *mDriverConstantBufferPS; + ID3D11Buffer *mCurrentPixelConstantBuffer; + + ID3D11Buffer *mCurrentGeometryConstantBuffer; // Vertex, index and input layouts VertexDataManager *mVertexDataManager; @@ -325,7 +334,8 @@ class Renderer11 : public Renderer ID3D11Buffer *mClearVB; ID3D11InputLayout *mClearIL; ID3D11VertexShader *mClearVS; - ID3D11PixelShader *mClearPS; + ID3D11PixelShader *mClearSinglePS; + ID3D11PixelShader *mClearMultiplePS; ID3D11RasterizerState *mClearScissorRS; ID3D11RasterizerState *mClearNoScissorRS; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp index 8acbce4be7..d3f3814ae5 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp @@ -30,6 +30,8 @@ #include "libEGL/Display.h" +#include "third_party/trace_event/trace_event.h" + // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros #define REF_RAST 0 @@ -41,10 +43,6 @@ #define ANGLE_ENABLE_D3D9EX 1 #endif // !defined(ANGLE_ENABLE_D3D9EX) -#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) -#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 -#endif - namespace rx { static const D3DFORMAT RenderTargetFormats[] = @@ -188,10 +186,12 @@ EGLint Renderer9::initialize() if (mSoftwareDevice) { + TRACE_EVENT0("gpu", "GetModuleHandle_swiftshader"); mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); } else { + TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); } @@ -209,12 +209,14 @@ EGLint Renderer9::initialize() // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { + TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else { + TRACE_EVENT0("gpu", "Direct3DCreate9"); mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } @@ -232,21 +234,24 @@ EGLint Renderer9::initialize() HRESULT result; // Give up on getting device caps after about one second. - for (int i = 0; i < 10; ++i) { - result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); - if (SUCCEEDED(result)) - { - break; - } - else if (result == D3DERR_NOTAVAILABLE) - { - Sleep(100); // Give the driver some time to initialize/recover - } - else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from + TRACE_EVENT0("gpu", "GetDeviceCaps"); + for (int i = 0; i < 10; ++i) { - ERR("failed to get device caps (0x%x)\n", result); - return EGL_NOT_INITIALIZED; + result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); + if (SUCCEEDED(result)) + { + break; + } + else if (result == D3DERR_NOTAVAILABLE) + { + Sleep(100); // Give the driver some time to initialize/recover + } + else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from + { + ERR("failed to get device caps (0x%x)\n", result); + return EGL_NOT_INITIALIZED; + } } } @@ -264,7 +269,10 @@ EGLint Renderer9::initialize() return EGL_NOT_INITIALIZED; } - mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); + { + TRACE_EVENT0("gpu", "GetAdapterIdentifier"); + mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); + } // ATI cards on XP have problems with non-power-of-two textures. mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && @@ -305,35 +313,41 @@ EGLint Renderer9::initialize() } int max = 0; - for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i) { - bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - getMultiSampleSupport(RenderTargetFormats[i], multisampleArray); - mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray; - - for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) + TRACE_EVENT0("gpu", "getMultiSampleSupport"); + for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i) { - if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) + bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; + getMultiSampleSupport(RenderTargetFormats[i], multisampleArray); + mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray; + + for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) { - max = j; + if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) + { + max = j; + } } } } - for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i) { - if (DepthStencilFormats[i] == D3DFMT_UNKNOWN) - continue; + TRACE_EVENT0("gpu", "getMultiSampleSupport2"); + for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i) + { + if (DepthStencilFormats[i] == D3DFMT_UNKNOWN) + continue; - bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - getMultiSampleSupport(DepthStencilFormats[i], multisampleArray); - mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray; + bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; + getMultiSampleSupport(DepthStencilFormats[i], multisampleArray); + mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray; - for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) - { - if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) + for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) { - max = j; + if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) + { + max = j; + } } } } @@ -343,12 +357,18 @@ EGLint Renderer9::initialize() static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); - mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + { + TRACE_EVENT0("gpu", "CreateWindowEx"); + mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + } D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES; - result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); + { + TRACE_EVENT0("gpu", "D3d9_CreateDevice"); + result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); + } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) { return EGL_BAD_ALLOC; @@ -356,6 +376,7 @@ EGLint Renderer9::initialize() if (FAILED(result)) { + TRACE_EVENT0("gpu", "D3d9_CreateDevice2"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); if (FAILED(result)) @@ -367,35 +388,45 @@ EGLint Renderer9::initialize() if (mD3d9Ex) { + TRACE_EVENT0("gpu", "mDevice_QueryInterface"); result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx); ASSERT(SUCCEEDED(result)); } - mVertexShaderCache.initialize(mDevice); - mPixelShaderCache.initialize(mDevice); + { + TRACE_EVENT0("gpu", "ShaderCache initialize"); + mVertexShaderCache.initialize(mDevice); + mPixelShaderCache.initialize(mDevice); + } // Check occlusion query support IDirect3DQuery9 *occlusionQuery = NULL; - if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery) { - occlusionQuery->Release(); - mOcclusionQuerySupport = true; - } - else - { - mOcclusionQuerySupport = false; + TRACE_EVENT0("gpu", "device_CreateQuery"); + if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery) + { + occlusionQuery->Release(); + mOcclusionQuerySupport = true; + } + else + { + mOcclusionQuerySupport = false; + } } // Check event query support IDirect3DQuery9 *eventQuery = NULL; - if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery) - { - eventQuery->Release(); - mEventQuerySupport = true; - } - else { - mEventQuerySupport = false; + TRACE_EVENT0("gpu", "device_CreateQuery2"); + if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery) + { + eventQuery->Release(); + mEventQuerySupport = true; + } + else + { + mEventQuerySupport = false; + } } D3DDISPLAYMODE currentDisplayMode; @@ -1080,8 +1111,10 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF return false; // Nothing to render } + float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); + bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar; + actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront; if (viewportChanged) { mDevice->SetViewport(&dxViewport); @@ -1089,6 +1122,7 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF mCurViewport = actualViewport; mCurNear = actualZNear; mCurFar = actualZFar; + mCurDepthFront = depthFront; dx_VertexConstants vc = {0}; dx_PixelConstants pc = {0}; @@ -1105,7 +1139,7 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - pc.depthFront[2] = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);; + pc.depthFront[2] = depthFront; vc.depthRange[0] = actualZNear; vc.depthRange[1] = actualZFar; @@ -1458,7 +1492,7 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, indices = static_cast<const GLubyte*>(storage->getData()) + offset; } - UINT startIndex = 0; + unsigned int startIndex = 0; if (get32BitIndexSupport()) { @@ -1475,7 +1509,16 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } - const int spaceNeeded = (count + 1) * sizeof(unsigned int); + if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int))) + { + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + + const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); @@ -1483,14 +1526,14 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } void* mappedMemory = NULL; - int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory); - if (offset == -1 || mappedMemory == NULL) + unsigned int offset = 0; + if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) { ERR("Could not map index buffer for GL_LINE_LOOP."); return gl::error(GL_OUT_OF_MEMORY); } - startIndex = static_cast<UINT>(offset) / 4; + startIndex = static_cast<unsigned int>(offset) / 4; unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); switch (type) @@ -1547,7 +1590,16 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } - const int spaceNeeded = (count + 1) * sizeof(unsigned short); + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + + if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned short>::max() / sizeof(unsigned short))) + { + ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned short); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)) { ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); @@ -1555,14 +1607,14 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } void* mappedMemory = NULL; - int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory); - if (offset == -1 || mappedMemory == NULL) + unsigned int offset; + if (mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) { ERR("Could not map index buffer for GL_LINE_LOOP."); return gl::error(GL_OUT_OF_MEMORY); } - startIndex = static_cast<UINT>(offset) / 2; + startIndex = static_cast<unsigned int>(offset) / 2; unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory); switch (type) @@ -2042,23 +2094,6 @@ bool Renderer9::testDeviceLost(bool notify) if (mDeviceEx) { status = mDeviceEx->CheckDeviceState(NULL); - - if (status == S_PRESENT_MODE_CHANGED) - { - // Reset the device so that D3D stops reporting S_PRESENT_MODE_CHANGED. Otherwise it will report - // it continuously, potentially masking a lost device. D3D resources are not lost on a mode change with WDDM. - D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - mDeviceEx->Reset(&presentParameters); - - // Existing swap chains sometimes crash on the next present after a reset. - mDisplay->recreateSwapChains(); - - // Reset will not always cause the device loss to be reported so issue a dummy present. - mDeviceEx->Present(NULL, NULL, NULL, NULL); - - // Retest the device status to see if the mode change really indicated a lost device. - status = mDeviceEx->CheckDeviceState(NULL); - } } else if (mDevice) { @@ -3208,4 +3243,18 @@ TextureStorage *Renderer9::createTextureStorageCube(int levels, GLenum internalf return new TextureStorage9_Cube(this, levels, internalformat, usage, forceRenderable, size); } -}
\ No newline at end of file +bool Renderer9::getLUID(LUID *adapterLuid) const +{ + adapterLuid->HighPart = 0; + adapterLuid->LowPart = 0; + + if (mD3d9Ex) + { + mD3d9Ex->GetAdapterLUID(mAdapter, adapterLuid); + return true; + } + + return false; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h index 527a5010ae..f8932c4fd4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h @@ -193,6 +193,8 @@ class Renderer9 : public Renderer D3DPOOL getTexturePool(DWORD usage) const; + virtual bool getLUID(LUID *adapterLuid) const; + private: DISALLOW_COPY_AND_ASSIGN(Renderer9); @@ -296,6 +298,7 @@ class Renderer9 : public Renderer gl::Rectangle mCurViewport; float mCurNear; float mCurFar; + float mCurDepthFront; bool mForceSetBlendState; gl::BlendState mCurBlendState; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h index 128d123fbe..293e340845 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h @@ -26,7 +26,7 @@ class ShaderExecutable virtual ~ShaderExecutable() { - delete mFunction; + delete[] mFunction; } void *getFunction() const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp index 98f887587c..0da58cbe2e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp @@ -275,6 +275,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei else { result = offscreenTextureResource->GetSharedHandle(&mShareHandle); + offscreenTextureResource->Release(); if (FAILED(result)) { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp index 667dbff175..408b48ebab 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp @@ -69,7 +69,6 @@ bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format) case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_R8_UNORM: @@ -80,6 +79,7 @@ bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format) case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_R32G32B32_FLOAT: // not renderable on all devices return false; default: UNREACHABLE(); @@ -187,15 +187,6 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1 destRTV, destArea, dest->getWidth(), dest->getHeight(), GL_RGBA); } - - if (sourceSRV) - { - sourceSRV->Release(); - } - if (destRTV) - { - destRTV->Release(); - } } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp index 16e1486511..a073d95033 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp @@ -87,52 +87,97 @@ bool VertexBufferInterface::discard() return mVertexBuffer->discard(); } -int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances) +bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, + unsigned int *outStreamOffset) { + unsigned int spaceRequired; + if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired)) + { + return false; + } + + if (mWritePosition + spaceRequired < mWritePosition) + { + return false; + } + if (!reserveSpace(mReservedSpace)) { - return -1; + return false; } mReservedSpace = 0; if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition)) { - return -1; + return false; } - int oldWritePos = static_cast<int>(mWritePosition); - mWritePosition += mVertexBuffer->getSpaceRequired(attrib, count, instances); + if (outStreamOffset) + { + *outStreamOffset = mWritePosition; + } + + mWritePosition += spaceRequired; - return oldWritePos; + return true; } -int VertexBufferInterface::storeRawData(const void* data, unsigned int size) +bool VertexBufferInterface::storeRawData(const void* data, unsigned int size, unsigned int *outStreamOffset) { + if (mWritePosition + size < mWritePosition) + { + return false; + } + if (!reserveSpace(mReservedSpace)) { - return -1; + return false; } mReservedSpace = 0; if (!mVertexBuffer->storeRawData(data, size, mWritePosition)) { - return -1; + return false; + } + + if (outStreamOffset) + { + *outStreamOffset = mWritePosition; } - int oldWritePos = static_cast<int>(mWritePosition); mWritePosition += size; - return oldWritePos; + return true; } -void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances) +bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances) { - mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances); + unsigned int requiredSpace; + if (!mVertexBuffer->getSpaceRequired(attribute, count, instances, &requiredSpace)) + { + return false; + } + + // Protect against integer overflow + if (mReservedSpace + requiredSpace < mReservedSpace) + { + return false; + } + + mReservedSpace += requiredSpace; + return true; } -void VertexBufferInterface::reserveRawDataSpace(unsigned int size) +bool VertexBufferInterface::reserveRawDataSpace(unsigned int size) { + // Protect against integer overflow + if (mReservedSpace + size < mReservedSpace) + { + return false; + } + mReservedSpace += size; + return true; } VertexBuffer* VertexBufferInterface::getVertexBuffer() const @@ -179,7 +224,7 @@ StaticVertexBufferInterface::~StaticVertexBufferInterface() { } -int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute) +bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute, unsigned int *outStreamOffset) { for (unsigned int element = 0; element < mCache.size(); element++) { @@ -190,12 +235,16 @@ int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attr { if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride()) { - return mCache[element].streamOffset; + if (outStreamOffset) + { + *outStreamOffset = mCache[element].streamOffset; + } + return true; } } } - return -1; + return false; } bool StaticVertexBufferInterface::reserveSpace(unsigned int size) @@ -217,13 +266,27 @@ bool StaticVertexBufferInterface::reserveSpace(unsigned int size) } } -int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances) +bool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, + unsigned int *outStreamOffset) { - int attributeOffset = attrib.mOffset % attrib.stride(); - VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() }; - mCache.push_back(element); + unsigned int streamOffset; + if (VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances, &streamOffset)) + { + int attributeOffset = attrib.mOffset % attrib.stride(); + VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, streamOffset }; + mCache.push_back(element); - return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances); + if (outStreamOffset) + { + *outStreamOffset = streamOffset; + } + + return true; + } + else + { + return false; + } } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h index 6ecffd0c0b..cbafdd20f6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h @@ -33,8 +33,8 @@ class VertexBuffer GLsizei instances, unsigned int offset) = 0; virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset) = 0; - virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances) const = 0; + virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const = 0; virtual bool requiresConversion(const gl::VertexAttribute &attrib) const = 0; @@ -60,15 +60,16 @@ class VertexBufferInterface VertexBufferInterface(rx::Renderer *renderer, bool dynamic); virtual ~VertexBufferInterface(); - void reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); - void reserveRawDataSpace(unsigned int size); + bool reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); + bool reserveRawDataSpace(unsigned int size); unsigned int getBufferSize() const; unsigned int getSerial() const; - virtual int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances); - virtual int storeRawData(const void* data, unsigned int size); + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, + unsigned int *outStreamOffset); + virtual bool storeRawData(const void* data, unsigned int size, unsigned int *outStreamOffset); VertexBuffer* getVertexBuffer() const; @@ -110,10 +111,10 @@ class StaticVertexBufferInterface : public VertexBufferInterface explicit StaticVertexBufferInterface(rx::Renderer *renderer); ~StaticVertexBufferInterface(); - int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances); + bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, + unsigned int *outStreamOffset); - // Returns the offset into the vertex buffer, or -1 if not found - int lookupAttribute(const gl::VertexAttribute &attribute); + bool lookupAttribute(const gl::VertexAttribute &attribute, unsigned int* outStreamOffset); protected: bool reserveSpace(unsigned int size); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp index 92c8755e22..521da80c3d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp @@ -152,18 +152,40 @@ bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned } } -unsigned int VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances) const +bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, + GLsizei instances, unsigned int *outSpaceRequired) const { unsigned int elementSize = getVertexConversion(attrib).outputElementSize; + unsigned int elementCount = 0; if (instances == 0 || attrib.mDivisor == 0) { - return elementSize * count; + elementCount = count; } else { - return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor); + if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) + { + // Round up + elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; + } + else + { + elementCount = instances / attrib.mDivisor; + } + } + + if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) + { + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * elementCount; + } + return true; + } + else + { + return false; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h index 75e025075e..eceb426e82 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h @@ -26,10 +26,11 @@ class VertexBuffer11 : public VertexBuffer static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer); virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int offset); + unsigned int offset); virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); - virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const; + virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const; virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; @@ -70,4 +71,4 @@ class VertexBuffer11 : public VertexBuffer } -#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
\ No newline at end of file +#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp index 76dc73e391..b017b3af33 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp @@ -95,7 +95,14 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLi DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; void *mapPtr = NULL; - HRESULT result = mVertexBuffer->Lock(offset, spaceRequired(attrib, count, instances), &mapPtr, lockFlags); + + unsigned int mapSize; + if (!spaceRequired(attrib, count, instances, &mapSize)) + { + return false; + } + + HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); if (FAILED(result)) { @@ -167,9 +174,10 @@ bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned i } } -unsigned int VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const +bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const { - return spaceRequired(attrib, count, instances); + return spaceRequired(attrib, count, instances, outSpaceRequired); } bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const @@ -179,7 +187,8 @@ bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const { - return spaceRequired(attrib, 1, 0); + unsigned int spaceRequired; + return getSpaceRequired(attrib, 1, 0, &spaceRequired) ? spaceRequired : 0; } D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const @@ -469,17 +478,52 @@ const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::V return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1]; } -unsigned int VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances) +bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) { unsigned int elementSize = formatConverter(attrib).outputElementSize; - if (instances == 0 || attrib.mDivisor == 0) + if (attrib.mArrayEnabled) { - return elementSize * count; + unsigned int elementCount = 0; + if (instances == 0 || attrib.mDivisor == 0) + { + elementCount = count; + } + else + { + if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) + { + // Round up + elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; + } + else + { + elementCount = static_cast<unsigned int>(instances) / attrib.mDivisor; + } + } + + if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) + { + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * elementCount; + } + return true; + } + else + { + return false; + } } else { - return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor); + const unsigned int elementSize = 4; + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * 4; + } + return true; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h index f771635bda..2f88117bda 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h @@ -29,7 +29,7 @@ class VertexBuffer9 : public VertexBuffer unsigned int offset); virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); - virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const; + virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; @@ -82,7 +82,8 @@ class VertexBuffer9 : public VertexBuffer static unsigned int typeIndex(GLenum type); static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); - static unsigned int spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances); + static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired); }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp index ec85857264..7ff5171fca 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp @@ -26,12 +26,32 @@ namespace namespace rx { -static int elementsInBuffer(const gl::VertexAttribute &attribute, int size) +static int elementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size) { - int stride = attribute.stride(); + // Size cannot be larger than a GLsizei + if (size > static_cast<unsigned int>(std::numeric_limits<int>::max())) + { + size = static_cast<unsigned int>(std::numeric_limits<int>::max()); + } + + GLsizei stride = attribute.stride(); return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride; } +static int StreamingBufferElementCount(const gl::VertexAttribute &attribute, int vertexDrawCount, int instanceDrawCount) +{ + // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices. + // + // A vertex attribute with a positive divisor loads one instanced vertex for every set of + // non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances. + if (instanceDrawCount > 0 && attribute.mDivisor > 0) + { + return instanceDrawCount / attribute.mDivisor; + } + + return vertexDrawCount; +} + VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer) { for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) @@ -92,7 +112,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], gl::Buffer *buffer = attribs[i].mBoundBuffer.get(); StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; - if (staticBuffer && staticBuffer->getBufferSize() > 0 && staticBuffer->lookupAttribute(attribs[i]) == -1 && + if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) && !directStoragePossible(staticBuffer, attribs[i])) { buffer->invalidateStaticData(); @@ -116,12 +136,27 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], if (staticBuffer->getBufferSize() == 0) { int totalCount = elementsInBuffer(attribs[i], buffer->size()); - staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0); + if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0)) + { + return GL_OUT_OF_MEMORY; + } } } else { - mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances); + int totalCount = StreamingBufferElementCount(attribs[i], count, instances); + + // Undefined behaviour: + // We can return INVALID_OPERATION if our vertex attribute does not have enough backing data. + if (buffer && elementsInBuffer(attribs[i], buffer->size()) < totalCount) + { + return GL_INVALID_OPERATION; + } + + if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances)) + { + return GL_OUT_OF_MEMORY; + } } } } @@ -149,7 +184,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], BufferStorage *storage = buffer ? buffer->getStorage() : NULL; bool directStorage = directStoragePossible(vertexBuffer, attribs[i]); - std::size_t streamOffset = -1; + unsigned int streamOffset = 0; unsigned int outputElementSize = 0; if (directStorage) @@ -160,37 +195,40 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], } else if (staticBuffer) { - streamOffset = staticBuffer->lookupAttribute(attribs[i]); - outputElementSize = staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0); + if (!staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize)) + { + return GL_OUT_OF_MEMORY; + } - if (streamOffset == -1) + if (!staticBuffer->lookupAttribute(attribs[i], &streamOffset)) { // Convert the entire buffer int totalCount = elementsInBuffer(attribs[i], storage->getSize()); int startIndex = attribs[i].mOffset / attribs[i].stride(); - streamOffset = staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0); + if (!staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0, &streamOffset)) + { + return GL_OUT_OF_MEMORY; + } } - if (streamOffset != -1) + unsigned int firstElementOffset = (attribs[i].mOffset / attribs[i].stride()) * outputElementSize; + unsigned int startOffset = (instances == 0 || attribs[i].mDivisor == 0) ? start * outputElementSize : 0; + if (streamOffset + firstElementOffset + startOffset < streamOffset) { - streamOffset += (attribs[i].mOffset / attribs[i].stride()) * outputElementSize; - - if (instances == 0 || attribs[i].mDivisor == 0) - { - streamOffset += start * outputElementSize; - } + return GL_OUT_OF_MEMORY; } + + streamOffset += firstElementOffset + startOffset; } else { - outputElementSize = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0); - streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], start, count, instances); - } - - if (streamOffset == -1) - { - return GL_OUT_OF_MEMORY; + int totalCount = StreamingBufferElementCount(attribs[i], count, instances); + if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) || + !mStreamingBuffer->storeVertexAttributes(attribs[i], start, totalCount, instances, &streamOffset)) + { + return GL_OUT_OF_MEMORY; + } } translated[i].storage = directStorage ? storage : NULL; @@ -217,9 +255,13 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], mCurrentValue[i][3] != attribs[i].mCurrentValue[3]) { unsigned int requiredSpace = sizeof(float) * 4; - buffer->reserveRawDataSpace(requiredSpace); - int streamOffset = buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace); - if (streamOffset == -1) + if (!buffer->reserveRawDataSpace(requiredSpace)) + { + return GL_OUT_OF_MEMORY; + } + + unsigned int streamOffset; + if (!buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace, &streamOffset)) { return GL_OUT_OF_MEMORY; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h index 28387e6baf..1a8786552a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h @@ -31,8 +31,8 @@ struct TranslatedAttribute bool active; const gl::VertexAttribute *attribute; - UINT offset; - UINT stride; // 0 means not to advance the read pointer at all + unsigned int offset; + unsigned int stride; // 0 means not to advance the read pointer at all VertexBuffer *vertexBuffer; BufferStorage *storage; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp index 5f01dc12ed..13800da258 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp @@ -356,7 +356,7 @@ DXGI_FORMAT ConvertTextureFormat(GLenum internalformat) return DXGI_FORMAT_R32G32B32A32_FLOAT; case GL_RGB32F_EXT: case GL_LUMINANCE32F_EXT: - return DXGI_FORMAT_R32G32B32_FLOAT; + return DXGI_FORMAT_R32G32B32A32_FLOAT; case GL_RGBA16F_EXT: case GL_ALPHA16F_EXT: case GL_LUMINANCE_ALPHA16F_EXT: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl index d2752601e9..042ac699b6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl +++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl @@ -6,7 +6,7 @@ void VS_Clear( in float3 inPosition : POSITION, in float4 inColor : COLOR, } // Assume we are in SM4+, which has 8 color outputs -struct PS_Output +struct PS_OutputMultiple { float4 color0 : SV_TARGET0; float4 color1 : SV_TARGET1; @@ -18,9 +18,9 @@ struct PS_Output float4 color7 : SV_TARGET7; }; -PS_Output PS_Clear(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) +PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) { - PS_Output outColor; + PS_OutputMultiple outColor; outColor.color0 = inColor; outColor.color1 = inColor; outColor.color2 = inColor; @@ -31,3 +31,8 @@ PS_Output PS_Clear(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR outColor.color7 = inColor; return outColor; } + +float4 PS_ClearSingle(in float4 inPosition : SV_Position, in float4 inColor : COLOR) : SV_Target0 +{ + return inColor; +} diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp index 9809b9d8e8..32df49e672 100644 --- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp +++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp @@ -218,6 +218,29 @@ GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum internalform } } +GLsizei ComputeTypeSize(GLenum type) +{ + switch (type) + { + case GL_BYTE: return 1; + case GL_UNSIGNED_BYTE: return 1; + case GL_SHORT: return 2; + case GL_UNSIGNED_SHORT: return 2; + case GL_INT: return 4; + case GL_UNSIGNED_INT: return 4; + case GL_FLOAT: return 4; + case GL_HALF_FLOAT_OES: return 2; + case GL_UNSIGNED_SHORT_5_6_5: return 2; + case GL_UNSIGNED_SHORT_4_4_4_4: return 2; + case GL_UNSIGNED_SHORT_5_5_5_1: return 2; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return 2; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return 2; + case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: return 4; + case GL_UNSIGNED_INT_24_8_OES: return 4; + default: UNREACHABLE(); return 0; + } +} + bool IsCompressed(GLenum format) { if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.h b/src/3rdparty/angle/src/libGLESv2/utilities.h index 7a10767086..ed663ebca2 100644 --- a/src/3rdparty/angle/src/libGLESv2/utilities.h +++ b/src/3rdparty/angle/src/libGLESv2/utilities.h @@ -34,6 +34,7 @@ int ComputePixelSize(GLint internalformat); GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment); GLsizei ComputeCompressedPitch(GLsizei width, GLenum format); GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format); +GLsizei ComputeTypeSize(GLenum type); bool IsCompressed(GLenum format); bool IsDepthTexture(GLenum format); bool IsStencilTexture(GLenum format); |