summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp49
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h34
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp87
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp97
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h58
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp75
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp23
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp415
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp215
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp11
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp107
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp30
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp60
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp96
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl11
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;
+}