diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer')
34 files changed, 994 insertions, 550 deletions
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; +} |