diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9')
27 files changed, 1317 insertions, 1546 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp index f486e5a4cc..f061a32c52 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,8 +7,6 @@ // Blit9.cpp: Surface copy utility class. #include "libGLESv2/renderer/d3d/d3d9/Blit9.h" - -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" @@ -17,9 +14,11 @@ #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/main.h" namespace { +// Precompiled shaders #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h" #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h" #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h" @@ -209,7 +208,7 @@ bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) return true; } -bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *source = NULL; @@ -217,9 +216,9 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } - + if (renderTarget) { source = renderTarget->getSurface(); @@ -231,10 +230,10 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true); bool result = false; - + if (destSurface) { result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); @@ -245,7 +244,7 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de return result; } -bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *source = NULL; @@ -253,9 +252,9 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } - + if (renderTarget) { source = renderTarget->getSurface(); @@ -267,7 +266,7 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true); bool result = false; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h index 3635bca932..46a3ee1cf3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h @@ -11,6 +11,8 @@ #include "common/angleutils.h" +#include <GLES2/gl2.h> + namespace gl { class Framebuffer; @@ -19,8 +21,7 @@ class Framebuffer; namespace rx { class Renderer9; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; +class TextureStorage; class Blit9 { @@ -30,8 +31,8 @@ class Blit9 // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); + bool copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + bool copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp index 347bde0c65..c02db515a2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,8 +7,8 @@ // Buffer9.cpp Defines the Buffer9 class. #include "libGLESv2/renderer/d3d/d3d9/Buffer9.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/main.h" namespace rx { @@ -18,13 +17,11 @@ Buffer9::Buffer9(rx::Renderer9 *renderer) : BufferD3D(), mRenderer(renderer), mSize(0) -{ - -} +{} Buffer9::~Buffer9() { - + mSize = 0; } Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer) @@ -33,18 +30,13 @@ Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer) return static_cast<Buffer9*>(buffer); } -void Buffer9::clear() -{ - mSize = 0; -} - -void Buffer9::setData(const void* data, size_t size, GLenum usage) +gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) { if (size > mMemory.size()) { if (!mMemory.resize(size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); } } @@ -54,14 +46,14 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage) memcpy(mMemory.data(), data, size); } - mIndexRangeCache.clear(); - invalidateStaticData(); if (usage == GL_STATIC_DRAW) { initializeStaticData(); } + + return gl::Error(GL_NO_ERROR); } void *Buffer9::getData() @@ -69,13 +61,13 @@ void *Buffer9::getData() return mMemory.data(); } -void Buffer9::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) { if (offset + size > mMemory.size()) { if (!mMemory.resize(offset + size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); } } @@ -85,32 +77,35 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset) memcpy(mMemory.data() + offset, data, size); } - mIndexRangeCache.invalidateRange(offset, size); - invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -void Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { + // Note: this method is currently unreachable Buffer9* sourceBuffer = makeBuffer9(source); - if (sourceBuffer) - { - memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); - } + ASSERT(sourceBuffer); + + memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -// We do not suppot buffer mapping in D3D9 -GLvoid* Buffer9::map(size_t offset, size_t length, GLbitfield access) +// We do not support buffer mapping in D3D9 +gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } -void Buffer9::unmap() +gl::Error Buffer9::unmap() { UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); } void Buffer9::markTransformFeedbackUsage() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h index ec25ec30c9..e78182f905 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h @@ -27,17 +27,16 @@ class Buffer9 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } - virtual void clear(); virtual bool supportsDirectBinding() const { return false; } virtual Renderer* getRenderer(); // BufferImpl implementation - virtual void setData(const void* data, size_t size, GLenum usage); + virtual gl::Error setData(const void* data, size_t size, GLenum usage); virtual void *getData(); - virtual void setSubData(const void* data, size_t size, size_t offset); - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access); - virtual void unmap(); + virtual gl::Error setSubData(const void* data, size_t size, size_t offset); + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); + virtual gl::Error unmap(); virtual void markTransformFeedbackUsage(); private: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp index d2437cadf3..e352a5f50a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp @@ -1,4 +1,3 @@ -#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 @@ -8,9 +7,9 @@ // Fence9.cpp: Defines the rx::Fence9 class. #include "libGLESv2/renderer/d3d/d3d9/Fence9.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/main.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp index e237c3b6e1..18383fba78 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp @@ -1,5 +1,3 @@ - -#include "precompiled.h" // // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -10,17 +8,16 @@ // the actual underlying surfaces of a Texture. #include "libGLESv2/renderer/d3d/d3d9/Image9.h" - +#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" #include "libGLESv2/main.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" -#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" -#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" -#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" -#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" namespace rx { @@ -53,8 +50,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); - MipGenerationFunction mipFunction = d3d9::GetMipGenerationFunction(sourceDesc.Format); - ASSERT(mipFunction != NULL); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); + ASSERT(d3dFormatInfo.mipGenerationFunction != NULL); D3DLOCKED_RECT sourceLocked = {0}; result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); @@ -69,8 +66,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour if (sourceData && destData) { - mipFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, - destData, destLocked.Pitch, 0); + d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, + destData, destLocked.Pitch, 0); } destSurface->UnlockRect(); @@ -99,22 +96,23 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so { D3DLOCKED_RECT sourceLock = {0}; D3DLOCKED_RECT destLock = {0}; - + source->LockRect(&sourceLock, NULL, 0); dest->LockRect(&destLock, NULL, 0); - + if (sourceLock.pBits && destLock.pBits) { D3DSURFACE_DESC desc; source->GetDesc(&desc); - int blockHeight = d3d9::GetBlockHeight(desc.Format); - int rows = desc.Height / blockHeight; + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + unsigned int rows = desc.Height / d3dFormatInfo.blockHeight; - int bytes = d3d9::GetBlockSize(desc.Format, desc.Width, blockHeight); - ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch); + unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight); + ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) && + bytes <= static_cast<unsigned int>(destLock.Pitch)); - for(int i = 0; i < rows; i++) + for(unsigned int i = 0; i < rows; i++) { memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); } @@ -147,12 +145,14 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform mInternalFormat = internalformat; // compute the d3d format that will be used - mD3DFormat = gl_d3d9::GetTextureFormat(internalformat); - mActualFormat = d3d9_gl::GetInternalFormat(mD3DFormat); - mRenderable = gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN; + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat); + mD3DFormat = d3d9FormatInfo.texFormat; + mActualFormat = d3dFormatInfo.internalFormat; + mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN); SafeRelease(mSurface); - mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat); + mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL); return true; } @@ -194,10 +194,9 @@ void Image9::createSurface() newTexture->GetSurfaceLevel(levelToFetch, &newSurface); SafeRelease(newTexture); - if (gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + if (d3dFormatInfo.dataInitializerFunction != NULL) { - InitializeTextureDataFunction initializeFunc = gl_d3d9::GetTextureDataInitializationFunction(mInternalFormat); - RECT entireRect; entireRect.left = 0; entireRect.right = mWidth; @@ -208,7 +207,8 @@ void Image9::createSurface() result = newSurface->LockRect(&lockedRect, &entireRect, 0); ASSERT(SUCCEEDED(result)); - initializeFunc(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits), lockedRect.Pitch, 0); + d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits), + lockedRect.Pitch, 0); result = newSurface->UnlockRect(); ASSERT(SUCCEEDED(result)); @@ -260,7 +260,7 @@ bool Image9::isDirty() const { // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet // if initialization is required before use. - return (mSurface || gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) && mDirty; + return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty; } IDirect3DSurface9 *Image9::getSurface() @@ -270,15 +270,15 @@ IDirect3DSurface9 *Image9::getSurface() return mSurface; } -void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level) +void Image9::setManagedSurface2D(TextureStorage *storage, int level) { - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); setManagedSurface(storage9->getSurfaceLevel(level, false)); } -void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) +void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) { - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false)); } @@ -301,28 +301,28 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface) } } -bool Image9::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { ASSERT(getSurface() != NULL); - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); } -bool Image9::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { ASSERT(getSurface() != NULL); - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height); } -bool Image9::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +bool Image9::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) { // 3D textures are not supported by the D3D9 backend. UNREACHABLE(); return false; } -bool Image9::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) { // 2D array textures are not supported by the D3D9 backend. UNREACHABLE(); @@ -368,7 +368,7 @@ bool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint } else { - // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools + // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); @@ -387,10 +387,11 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width // 3D textures are not supported by the D3D9 backend. ASSERT(zoffset == 0 && depth == 1); - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, width, unpackAlignment); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); - LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat); - ASSERT(loadFunction != NULL); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + ASSERT(d3dFormatInfo.loadFunction != NULL); RECT lockRect = { @@ -405,9 +406,9 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width return; } - loadFunction(width, height, depth, - reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0, - reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); + d3dFormatInfo.loadFunction(width, height, depth, + reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0, + reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); unlock(); } @@ -418,14 +419,16 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs // 3D textures are not supported by the D3D9 backend. ASSERT(zoffset == 0 && depth == 1); - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, 1); - GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, height, 1); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); - ASSERT(xoffset % d3d9::GetBlockWidth(mD3DFormat) == 0); - ASSERT(yoffset % d3d9::GetBlockHeight(mD3DFormat) == 0); + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); - LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat); - ASSERT(loadFunction != NULL); + ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0); + ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0); + + ASSERT(d3d9FormatInfo.loadFunction != NULL); RECT lockRect = { @@ -440,9 +443,9 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs return; } - loadFunction(width, height, depth, - reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch, - reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); + d3d9FormatInfo.loadFunction(width, height, depth, + reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch, + reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); unlock(); } @@ -459,9 +462,9 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } - + if (renderTarget) { surface = renderTarget->getSurface(); @@ -478,7 +481,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, IDirect3DSurface9 *renderTargetData = NULL; D3DSURFACE_DESC description; surface->GetDesc(&description); - + HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); if (FAILED(result)) @@ -514,7 +517,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, D3DLOCKED_RECT destLock = {0}; result = lock(&destLock, &destRect); - + if (FAILED(result)) { ERR("Failed to lock the destination surface (rectangle might be invalid)."); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h index 2d1536f24b..08d8ee3545 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h @@ -22,8 +22,6 @@ namespace rx { class Renderer; class Renderer9; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; class Image9 : public ImageD3D { @@ -44,12 +42,12 @@ class Image9 : public ImageD3D virtual bool isDirty() const; IDirect3DSurface9 *getSurface(); - virtual void setManagedSurface(TextureStorageInterface2D *storage, int level); - virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level); - virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); - virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height); + virtual void setManagedSurface2D(TextureStorage *storage, int level); + virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level); + virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height); virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint unpackAlignment, GLenum type, const void *input); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp index 472e6981a8..1c51b9e985 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -26,7 +25,7 @@ IndexBuffer9::~IndexBuffer9() SafeRelease(mIndexBuffer); } -bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) +gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { SafeRelease(mIndexBuffer); @@ -34,28 +33,17 @@ bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dy if (bufferSize > 0) { - D3DFORMAT format; + D3DFORMAT format = D3DFMT_UNKNOWN; if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE) { format = D3DFMT_INDEX16; } else if (indexType == GL_UNSIGNED_INT) { - if (mRenderer->getRendererExtensions().elementIndexUint) - { - format = D3DFMT_INDEX32; - } - else - { - ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices."); - return false; - } - } - else - { - ERR("Invalid index type %u.", indexType); - return false; + ASSERT(mRenderer->getRendererExtensions().elementIndexUint); + format = D3DFMT_INDEX32; } + else UNREACHABLE(); DWORD usageFlags = D3DUSAGE_WRITEONLY; if (dynamic) @@ -66,8 +54,7 @@ bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dy HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); if (FAILED(result)) { - ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); } } @@ -75,7 +62,7 @@ bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dy mIndexType = indexType; mDynamic = dynamic; - return true; + return gl::Error(GL_NO_ERROR); } IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) @@ -84,48 +71,40 @@ IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) return static_cast<IndexBuffer9*>(indexBuffer); } -bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) +gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { - if (mIndexBuffer) + if (!mIndexBuffer) { - DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - void *mapPtr = NULL; - HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); - if (FAILED(result)) - { - ERR("Index buffer lock failed with error 0x%08x", result); - return false; - } + DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; - *outMappedMemory = mapPtr; - return true; - } - else + void *mapPtr = NULL; + HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); } + + *outMappedMemory = mapPtr; + return gl::Error(GL_NO_ERROR); } -bool IndexBuffer9::unmapBuffer() +gl::Error IndexBuffer9::unmapBuffer() { - if (mIndexBuffer) + if (!mIndexBuffer) { - HRESULT result = mIndexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Index buffer unlock failed with error 0x%08x", result); - return false; - } - - return true; + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); } - else + + HRESULT result = mIndexBuffer->Unlock(); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); } + + return gl::Error(GL_NO_ERROR); } GLenum IndexBuffer9::getIndexType() const @@ -138,7 +117,7 @@ unsigned int IndexBuffer9::getBufferSize() const return mBufferSize; } -bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) +gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) { if (bufferSize > mBufferSize || indexType != mIndexType) { @@ -146,38 +125,33 @@ bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool IndexBuffer9::discard() +gl::Error IndexBuffer9::discard() { - if (mIndexBuffer) + if (!mIndexBuffer) { - void *dummy; - HRESULT result; - - result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); - if (FAILED(result)) - { - ERR("Discard lock failed with error 0x%08x", result); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - result = mIndexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } + void *dummy; + HRESULT result; - return true; + result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); } - else + + result = mIndexBuffer->Unlock(); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); } + + return gl::Error(GL_NO_ERROR); } D3DFORMAT IndexBuffer9::getIndexFormat() const @@ -196,4 +170,4 @@ IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const return mIndexBuffer; } -}
\ No newline at end of file +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h index cfc20e1c64..d0970d6ac5 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h @@ -21,18 +21,18 @@ class IndexBuffer9 : public IndexBuffer explicit IndexBuffer9(Renderer9 *const renderer); virtual ~IndexBuffer9(); - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer); - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual bool unmapBuffer(); + virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); + virtual gl::Error unmapBuffer(); virtual GLenum getIndexType() const; virtual unsigned int getBufferSize() const; - virtual bool setSize(unsigned int bufferSize, GLenum indexType); + virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); - virtual bool discard(); + virtual gl::Error discard(); D3DFORMAT getIndexFormat() const; IDirect3DIndexBuffer9 *getBuffer() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp index 3c6f1d0d43..815fc01a9b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp @@ -1,4 +1,3 @@ -#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 @@ -7,19 +6,22 @@ // Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. - #include "libGLESv2/renderer/d3d/d3d9/Query9.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/main.h" + +#include <GLES2/gl2ext.h> namespace rx { - -Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type) +Query9::Query9(rx::Renderer9 *renderer, GLenum type) + : QueryImpl(type), + mResult(GL_FALSE), + mQueryFinished(false), + mRenderer(renderer), + mQuery(NULL) { - mRenderer = renderer; - mQuery = NULL; } Query9::~Query9() @@ -27,73 +29,91 @@ Query9::~Query9() SafeRelease(mQuery); } -void Query9::begin() +gl::Error Query9::begin() { if (mQuery == NULL) { - if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) + HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); } } HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to begin internal query, result: 0x%X.", result); + } + + return gl::Error(GL_NO_ERROR); } -void Query9::end() +gl::Error Query9::end() { ASSERT(mQuery); HRESULT result = mQuery->Issue(D3DISSUE_END); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to end internal query, result: 0x%X.", result); + } - mStatus = GL_FALSE; + mQueryFinished = false; mResult = GL_FALSE; + + return gl::Error(GL_NO_ERROR); } -GLuint Query9::getResult() +gl::Error Query9::getResult(GLuint *params) { - if (mQuery != NULL) + while (!mQueryFinished) { - while (!testQuery()) + gl::Error error = testQuery(); + if (error.isError()) + { + return error; + } + + if (!mQueryFinished) { Sleep(0); - // explicitly check for device loss - // some drivers seem to return S_FALSE even if the device is lost - // instead of D3DERR_DEVICELOST like they should - if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, 0); - } } } - return mResult; + ASSERT(mQueryFinished); + *params = mResult; + + return gl::Error(GL_NO_ERROR); } -GLboolean Query9::isResultAvailable() +gl::Error Query9::isResultAvailable(GLuint *available) { - if (mQuery != NULL) + gl::Error error = testQuery(); + if (error.isError()) { - testQuery(); + return error; } - return mStatus; + *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + + return gl::Error(GL_NO_ERROR); } -GLboolean Query9::testQuery() +gl::Error Query9::testQuery() { - if (mQuery != NULL && mStatus != GL_TRUE) + if (!mQueryFinished) { + ASSERT(mQuery); + DWORD numPixels = 0; HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); if (hres == S_OK) { - mStatus = GL_TRUE; + mQueryFinished = true; switch (getType()) { @@ -101,25 +121,24 @@ GLboolean Query9::testQuery() case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; break; + default: - ASSERT(false); + UNREACHABLE(); + break; } } else if (d3d9::isDeviceLostError(hres)) { mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + } + else if (mRenderer->testDeviceLost(true)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); } - - return mStatus; } - return GL_TRUE; // prevent blocking when query is null -} - -bool Query9::isStarted() const -{ - return (mQuery != NULL); + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h index 62906230c4..513e0ba6fd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h @@ -21,16 +21,18 @@ class Query9 : public QueryImpl Query9(rx::Renderer9 *renderer, GLenum type); virtual ~Query9(); - virtual void begin(); - virtual void end(); - virtual GLuint getResult(); - virtual GLboolean isResultAvailable(); - virtual bool isStarted() const; + virtual gl::Error begin(); + virtual gl::Error end(); + virtual gl::Error getResult(GLuint *params); + virtual gl::Error isResultAvailable(GLuint *available); private: DISALLOW_COPY_AND_ASSIGN(Query9); - GLboolean testQuery(); + gl::Error testQuery(); + + GLuint mResult; + bool mQueryFinished; rx::Renderer9 *mRenderer; IDirect3DQuery9 *mQuery; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp index 49bd9b4000..13321ac8cd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -10,7 +9,6 @@ #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" - #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/main.h" @@ -33,8 +31,9 @@ RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) mHeight = description.Height; mDepth = 1; - mInternalFormat = d3d9_gl::GetInternalFormat(description.Format); - mActualFormat = d3d9_gl::GetInternalFormat(description.Format); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format); + mInternalFormat = d3dFormatInfo.internalFormat; + mActualFormat = d3dFormatInfo.internalFormat; mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType); } } @@ -44,15 +43,11 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, mRenderer = Renderer9::makeRenderer9(renderer); mRenderTarget = NULL; - D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); - int supportedSamples = mRenderer->getNearestSupportedSamples(renderFormat, samples); + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat); - if (supportedSamples == -1) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } + const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); HRESULT result = D3DERR_INVALIDCALL; @@ -62,18 +57,17 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, bool requiresInitialization = false; - if (gl::GetDepthBits(internalFormat) > 0 || - gl::GetStencilBits(internalFormat) > 0) + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { - result = device->CreateDepthStencilSurface(width, height, renderFormat, + result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &mRenderTarget, NULL); } else { - requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat); - - result = device->CreateRenderTarget(width, height, renderFormat, + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); + result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &mRenderTarget, NULL); } @@ -105,7 +99,7 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, mDepth = 1; mInternalFormat = internalFormat; mSamples = supportedSamples; - mActualFormat = d3d9_gl::GetInternalFormat(renderFormat); + mActualFormat = d3dFormatInfo.internalFormat; } RenderTarget9::~RenderTarget9() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp index 2c8a79f964..d63f9b8582 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -7,17 +6,6 @@ // Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer. -#include "common/utilities.h" - -#include "libGLESv2/main.h" -#include "libGLESv2/Buffer.h" -#include "libGLESv2/Texture.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/FramebufferAttachment.h" -#include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/renderer/d3d/IndexDataManager.h" -#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" @@ -33,11 +21,25 @@ #include "libGLESv2/renderer/d3d/d3d9/Query9.h" #include "libGLESv2/renderer/d3d/d3d9/Fence9.h" #include "libGLESv2/renderer/d3d/d3d9/VertexArray9.h" +#include "libGLESv2/renderer/d3d/IndexDataManager.h" +#include "libGLESv2/renderer/d3d/ProgramD3D.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" +#include "libGLESv2/main.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/angletypes.h" #include "libEGL/Display.h" -#include "third_party/trace_event/trace_event.h" +#include "common/utilities.h" + +#include <sstream> // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros #define REF_RAST 0 @@ -117,13 +119,12 @@ Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint req mDeviceLost = false; - mMaxSupportedSamples = 0; - mMaskedClearSavedState = NULL; mVertexDataManager = NULL; mIndexDataManager = NULL; mLineLoopIB = NULL; + mCountingIB = NULL; mMaxNullColorbufferLRU = 0; for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) @@ -155,6 +156,7 @@ Renderer9::~Renderer9() void Renderer9::release() { + releaseShaderCompiler(); releaseDeviceResources(); SafeRelease(mDevice); @@ -186,7 +188,6 @@ EGLint Renderer9::initialize() return EGL_NOT_INITIALIZED; } - TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); if (mD3d9Module == NULL) @@ -203,14 +204,12 @@ 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); } @@ -229,7 +228,6 @@ EGLint Renderer9::initialize() // Give up on getting device caps after about one second. { - TRACE_EVENT0("gpu", "GetDeviceCaps"); for (int i = 0; i < 10; ++i) { result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); @@ -264,7 +262,6 @@ EGLint Renderer9::initialize() } { - TRACE_EVENT0("gpu", "GetAdapterIdentifier"); mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); } @@ -297,22 +294,10 @@ EGLint Renderer9::initialize() mMaxSwapInterval = std::max(mMaxSwapInterval, 4); } - mMaxSupportedSamples = 0; - - const d3d9::D3DFormatSet &d3d9Formats = d3d9::GetAllUsedD3DFormats(); - for (d3d9::D3DFormatSet::const_iterator i = d3d9Formats.begin(); i != d3d9Formats.end(); ++i) - { - TRACE_EVENT0("gpu", "getMultiSampleSupport"); - MultisampleSupportInfo support = getMultiSampleSupport(*i); - mMultiSampleSupport[*i] = support; - mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples); - } - static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); { - 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); } @@ -324,7 +309,6 @@ EGLint Renderer9::initialize() behaviorFlags |= D3DCREATE_MULTITHREADED; { - 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) @@ -334,7 +318,6 @@ 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)) @@ -346,13 +329,11 @@ EGLint Renderer9::initialize() if (mD3d9Ex) { - TRACE_EVENT0("gpu", "mDevice_QueryInterface"); result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); ASSERT(SUCCEEDED(result)); } { - TRACE_EVENT0("gpu", "ShaderCache initialize"); mVertexShaderCache.initialize(mDevice); mPixelShaderCache.initialize(mDevice); } @@ -369,8 +350,6 @@ EGLint Renderer9::initialize() initializeDevice(); - d3d9::InitializeVertexTranslations(this); - return EGL_SUCCESS; } @@ -392,6 +371,17 @@ void Renderer9::initializeDevice() mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f } + const gl::Caps &rendererCaps = getRendererCaps(); + + mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + + mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + + mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits); + markAllStateDirty(); mSceneStarted = false; @@ -436,40 +426,24 @@ int Renderer9::generateConfigs(ConfigDesc **configDescList) for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) { - D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; - - HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); - - if (SUCCEEDED(result)) + const d3d9::D3DFormat &renderTargetFormatInfo = d3d9::GetD3DFormatInfo(RenderTargetFormats[formatIndex]); + const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat); + if (renderTargetFormatCaps.renderable) { for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) { - D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; - HRESULT result = D3D_OK; - - if(depthStencilFormat != D3DFMT_UNKNOWN) - { - result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); - } - - if (SUCCEEDED(result)) + const d3d9::D3DFormat &depthStencilFormatInfo = d3d9::GetD3DFormatInfo(DepthStencilFormats[depthStencilIndex]); + const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat); + if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == D3DFMT_UNKNOWN) { - if(depthStencilFormat != D3DFMT_UNKNOWN) - { - result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); - } - - if (SUCCEEDED(result)) - { - ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d9_gl::GetInternalFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d9_gl::GetInternalFormat(depthStencilFormat); - newConfig.multiSample = 0; // FIXME: enumerate multi-sampling - newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat); - newConfig.es3Capable = false; - - (*configDescList)[numConfigs++] = newConfig; - } + ConfigDesc newConfig; + newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat; + newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat; + newConfig.multiSample = 0; // FIXME: enumerate multi-sampling + newConfig.fastConfig = (currentDisplayMode.Format == RenderTargetFormats[formatIndex]); + newConfig.es3Capable = false; + + (*configDescList)[numConfigs++] = newConfig; } } } @@ -635,6 +609,11 @@ FenceImpl *Renderer9::createFence() return new Fence9(this); } +TransformFeedbackImpl* Renderer9::createTransformFeedback() +{ + return new TransformFeedbackD3D(); +} + bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const { // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. @@ -649,16 +628,17 @@ bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsi return false; } -void Renderer9::generateSwizzle(gl::Texture *texture) +gl::Error Renderer9::generateSwizzle(gl::Texture *texture) { // Swizzled textures are not available in ES2 or D3D9 UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); } -void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) { - bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; - gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; + std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; + std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) { @@ -682,9 +662,11 @@ void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::Sampl forceSetSamplers[index] = false; appliedSamplers[index] = samplerState; + + return gl::Error(GL_NO_ERROR); } -void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; @@ -692,14 +674,16 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture unsigned int serial = 0; bool forceSetTexture = false; - unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; + std::vector<unsigned int> &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; if (texture) { - TextureStorageInterface *texStorage = texture->getNativeTexture(); + TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); + + TextureStorage *texStorage = textureImpl->getNativeTexture(); if (texStorage) { - TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInstance()); + TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage); d3dTexture = storage9->getBaseTexture(); } // If we get NULL back from getBaseTexture here, something went wrong @@ -707,7 +691,8 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture ASSERT(d3dTexture != NULL); serial = texture->getTextureSerial(); - forceSetTexture = texture->hasDirtyImages(); + forceSetTexture = textureImpl->hasDirtyImages(); + textureImpl->resetDirty(); } if (forceSetTexture || appliedSerials[index] != serial) @@ -716,15 +701,17 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture } appliedSerials[index] = serial; + + return gl::Error(GL_NO_ERROR); } -bool Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[]) +gl::Error Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[]) { // No effect in ES2/D3D9 - return true; + return gl::Error(GL_NO_ERROR); } -void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) +gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) { bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; @@ -760,10 +747,12 @@ void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) } mForceSetRasterState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) { bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0; @@ -828,10 +817,11 @@ void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState // drawing is done. // http://code.google.com/p/angleproject/issues/detail?id=169 - DWORD colorMask = gl_d3d9::ConvertColorMask(gl::GetRedBits(internalFormat) > 0 && blendState.colorMaskRed, - gl::GetGreenBits(internalFormat) > 0 && blendState.colorMaskGreen, - gl::GetBlueBits(internalFormat) > 0 && blendState.colorMaskBlue, - gl::GetAlphaBits(internalFormat) > 0 && blendState.colorMaskAlpha); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits > 0 && blendState.colorMaskRed, + formatInfo.greenBits > 0 && blendState.colorMaskGreen, + formatInfo.blueBits > 0 && blendState.colorMaskBlue, + formatInfo.alphaBits > 0 && blendState.colorMaskAlpha); if (colorMask == 0 && !zeroColorMaskAllowed) { // Enable green channel, but set blending so nothing will be drawn. @@ -863,10 +853,12 @@ void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState } mForceSetBlendState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) +gl::Error Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) { bool depthStencilStateChanged = mForceSetDepthStencilState || memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; @@ -955,6 +947,8 @@ void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilSt } mForceSetDepthStencilState = false; + + return gl::Error(GL_NO_ERROR); } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -984,7 +978,7 @@ void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) mForceSetScissor = false; } -bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) { gl::Rectangle actualViewport = viewport; @@ -1008,11 +1002,6 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF dxViewport.MinZ = actualZNear; dxViewport.MaxZ = actualZFar; - if (dxViewport.Width <= 0 || dxViewport.Height <= 0) - { - 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 || @@ -1065,7 +1054,6 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF } mForceSetViewport = false; - return true; } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) @@ -1133,7 +1121,7 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme } gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); - gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(nullRenderbuffer); + gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1154,7 +1142,7 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme return nullbuffer; } -bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) +gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) { // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. @@ -1165,27 +1153,25 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) } if (!attachment) { - ERR("unable to locate renderbuffer for FBO."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO."); } bool renderTargetChanged = false; - unsigned int renderTargetSerial = attachment->getSerial(); + unsigned int renderTargetSerial = GetAttachmentSerial(attachment); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device IDirect3DSurface9 *renderTargetSurface = NULL; - RenderTarget *renderTarget = attachment->getRenderTarget(); + RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment); if (renderTarget) { - renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface(); + renderTargetSurface = renderTarget->getSurface(); } if (!renderTargetSurface) { - ERR("render target pointer unexpectedly null."); - return false; // Context must be lost + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); } mDevice->SetRenderTarget(0, renderTargetSurface); @@ -1200,12 +1186,12 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) unsigned int stencilbufferSerial = 0; if (depthStencil) { - depthbufferSerial = depthStencil->getSerial(); + depthbufferSerial = GetAttachmentSerial(depthStencil); } else if (framebuffer->getStencilbuffer()) { depthStencil = framebuffer->getStencilbuffer(); - stencilbufferSerial = depthStencil->getSerial(); + stencilbufferSerial = GetAttachmentSerial(depthStencil); } if (depthbufferSerial != mAppliedDepthbufferSerial || @@ -1219,17 +1205,16 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) if (depthStencil) { IDirect3DSurface9 *depthStencilSurface = NULL; - RenderTarget *depthStencilRenderTarget = depthStencil->getDepthStencil(); + rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil); if (depthStencilRenderTarget) { - depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)->getSurface(); + depthStencilSurface = depthStencilRenderTarget->getSurface(); } if (!depthStencilSurface) { - ERR("depth stencil pointer unexpectedly null."); - return false; // Context must be lost + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null."); } mDevice->SetDepthStencilSurface(depthStencilSurface); @@ -1272,42 +1257,43 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) mRenderTargetDescInitialized = true; } - return true; + return gl::Error(GL_NO_ERROR); } -GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); - if (err != GL_NO_ERROR) + gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + if (error.isError()) { - return err; + return error; } return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); - - if (err == GL_NO_ERROR) + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + if (error.isError()) { - // Directly binding the storage buffer is not supported for d3d9 - ASSERT(indexInfo->storage == NULL); + return error; + } - if (indexInfo->serial != mAppliedIBSerial) - { - IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + // Directly binding the storage buffer is not supported for d3d9 + ASSERT(indexInfo->storage == NULL); - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = indexInfo->serial; - } + if (indexInfo->serial != mAppliedIBSerial) + { + IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = indexInfo->serial; } - return err; + return gl::Error(GL_NO_ERROR); } void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) @@ -1315,7 +1301,7 @@ void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffe UNREACHABLE(); } -void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) +gl::Error Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) { ASSERT(!transformFeedbackActive); @@ -1323,62 +1309,66 @@ void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool t if (mode == GL_LINE_LOOP) { - drawLineLoop(count, GL_NONE, NULL, 0, NULL); + return drawLineLoop(count, GL_NONE, NULL, 0, NULL); } else if (instances > 0) { - StaticIndexBufferInterface *countingIB = mIndexDataManager->getCountingIndices(count); - if (countingIB) + StaticIndexBufferInterface *countingIB = NULL; + gl::Error error = getCountingIB(count, &countingIB); + if (error.isError()) { - if (mAppliedIBSerial != countingIB->getSerial()) - { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); + return error; + } - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = countingIB->getSerial(); - } + if (mAppliedIBSerial != countingIB->getSerial()) + { + IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); - for (int i = 0; i < mRepeatDraw; i++) - { - mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); - } + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = countingIB->getSerial(); } - else + + for (int i = 0; i < mRepeatDraw; i++) { - ERR("Could not create a counting index buffer for glDrawArraysInstanced."); - return gl::error(GL_OUT_OF_MEMORY); + mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); } + + return gl::Error(GL_NO_ERROR); } else // Regular case { mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); + return gl::Error(GL_NO_ERROR); } } -void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) { startScene(); + int minIndex = static_cast<int>(indexInfo.indexRange.start); + if (mode == GL_POINTS) { - drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); } else if (mode == GL_LINE_LOOP) { - drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); } else { for (int i = 0; i < mRepeatDraw; i++) { - GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; - mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); + GLsizei vertexCount = static_cast<int>(indexInfo.indexRange.length()) + 1; + mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); } + return gl::Error(GL_NO_ERROR); } } -void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) @@ -1396,13 +1386,11 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) + gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + if (error.isError()) { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mLineLoopIB); + return error; } } @@ -1411,23 +1399,22 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, 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); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } - const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) + const unsigned int spaceNeeded = (static_cast<unsigned int>(count)+1) * sizeof(unsigned int); + gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + if (error.isError()) { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset = 0; - if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } startIndex = static_cast<unsigned int>(offset) / 4; @@ -1466,10 +1453,10 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, default: UNREACHABLE(); } - if (!mLineLoopIB->unmapBuffer()) + error = mLineLoopIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } } else @@ -1477,13 +1464,11 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT)) + gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); + if (error.isError()) { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mLineLoopIB); + return error; } } @@ -1492,23 +1477,22 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, 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); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned short); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)) + gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); + if (error.isError()) { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset; - if (mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } startIndex = static_cast<unsigned int>(offset) / 2; @@ -1547,10 +1531,10 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, default: UNREACHABLE(); } - if (!mLineLoopIB->unmapBuffer()) + error = mLineLoopIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } } @@ -1563,19 +1547,23 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); + + return gl::Error(GL_NO_ERROR); } template <typename T> -static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) +static gl::Error drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) { for (int i = 0; i < count; i++) { unsigned int indexValue = static_cast<unsigned int>(static_cast<const T*>(indices)[i]) - minIndex; device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); } + + return gl::Error(GL_NO_ERROR); } -void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call // for each individual point. This call is not expected to happen often. @@ -1589,15 +1577,87 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi switch (type) { - case GL_UNSIGNED_BYTE: drawPoints<GLubyte>(mDevice, count, indices, minIndex); break; - case GL_UNSIGNED_SHORT: drawPoints<GLushort>(mDevice, count, indices, minIndex); break; - case GL_UNSIGNED_INT: drawPoints<GLuint>(mDevice, count, indices, minIndex); break; - default: UNREACHABLE(); + case GL_UNSIGNED_BYTE: return drawPoints<GLubyte>(mDevice, count, indices, minIndex); + case GL_UNSIGNED_SHORT: return drawPoints<GLushort>(mDevice, count, indices, minIndex); + case GL_UNSIGNED_INT: return drawPoints<GLuint>(mDevice, count, indices, minIndex); + default: UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); } } -void Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **outIB) +{ + // Update the counting index buffer if it is not large enough or has not been created yet. + if (count <= 65536) // 16-bit indices + { + const unsigned int spaceNeeded = count * sizeof(unsigned short); + + if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) + { + SafeDelete(mCountingIB); + mCountingIB = new StaticIndexBufferInterface(this); + mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); + + void *mappedMemory = NULL; + gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); + if (error.isError()) + { + return error; + } + + unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory); + for (size_t i = 0; i < count; i++) + { + data[i] = i; + } + + error = mCountingIB->unmapBuffer(); + if (error.isError()) + { + return error; + } + } + } + else if (getRendererExtensions().elementIndexUint) + { + const unsigned int spaceNeeded = count * sizeof(unsigned int); + + if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) + { + SafeDelete(mCountingIB); + mCountingIB = new StaticIndexBufferInterface(this); + mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + + void *mappedMemory = NULL; + gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); + if (error.isError()) + { + return error; + } + + unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); + for (size_t i = 0; i < count; i++) + { + data[i] = i; + } + + error = mCountingIB->unmapBuffer(); + if (error.isError()) + { + return error; + } + } + } + else + { + return gl::Error(GL_OUT_OF_MEMORY, "Could not create a counting index buffer for glDrawArraysInstanced."); + } + + *outIB = mCountingIB; + return gl::Error(GL_NO_ERROR); +} + +gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive) { ASSERT(!transformFeedbackActive); ASSERT(!rasterizerDiscard); @@ -1632,9 +1692,11 @@ void Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexF mDxUniformsDirty = true; mAppliedProgramSerial = programSerial; } + + return gl::Error(GL_NO_ERROR); } -void Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) { const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); @@ -1686,6 +1748,8 @@ void Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); mDxUniformsDirty = false; } + + return gl::Error(GL_NO_ERROR); } void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v) @@ -1733,13 +1797,13 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { if (clearParams.colorClearType != GL_FLOAT) { // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0 UNREACHABLE(); - return; + return gl::Error(GL_INVALID_OPERATION); } bool clearColor = clearParams.clearColor[0]; @@ -1749,7 +1813,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f { // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0 UNREACHABLE(); - return; + return gl::Error(GL_INVALID_OPERATION); } } @@ -1759,7 +1823,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f unsigned int stencilUnmasked = 0x0; if (clearParams.clearStencil && frameBuffer->hasStencil()) { - unsigned int stencilSize = gl::GetStencilBits(frameBuffer->getStencilbuffer()->getActualFormat()); + unsigned int stencilSize = gl::GetInternalFormatInfo((frameBuffer->getStencilbuffer()->getActualFormat())).stencilBits; stencilUnmasked = (0x1 << stencilSize) - 1; } @@ -1770,29 +1834,19 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); if (clearColor) { - gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment->getInternalFormat(); - GLenum actualFormat = attachment->getActualFormat(); - - GLuint internalRedBits = gl::GetRedBits(internalFormat); - GLuint internalGreenBits = gl::GetGreenBits(internalFormat); - GLuint internalBlueBits = gl::GetBlueBits(internalFormat); - GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat); + const gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer(); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); - GLuint actualRedBits = gl::GetRedBits(actualFormat); - GLuint actualGreenBits = gl::GetGreenBits(actualFormat); - GLuint actualBlueBits = gl::GetBlueBits(actualFormat); - GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat); + color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), + gl::unorm<8>((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), + gl::unorm<8>((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), + gl::unorm<8>((formatInfo.blueBits == 0 && actualFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); - color = D3DCOLOR_ARGB(gl::unorm<8>((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), - gl::unorm<8>((internalRedBits == 0 && actualRedBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - gl::unorm<8>((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - gl::unorm<8>((internalBlueBits == 0 && actualBlueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); - - if ((internalRedBits > 0 && !clearParams.colorMaskRed) || - (internalGreenBits > 0 && !clearParams.colorMaskGreen) || - (internalBlueBits > 0 && !clearParams.colorMaskBlue) || - (internalAlphaBits > 0 && !clearParams.colorMaskAlpha)) + if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { needMaskedColorClear = true; } @@ -1956,6 +2010,8 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil); } + + return gl::Error(GL_NO_ERROR); } void Renderer9::markAllStateDirty() @@ -1972,12 +2028,15 @@ void Renderer9::markAllStateDirty() mForceSetViewport = true; mForceSetBlendState = true; - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) + ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size()); + for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++) { mForceSetVertexSamplerStates[i] = true; mCurVertexTextureSerials[i] = 0; } - for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) + + ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size()); + for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++) { mForceSetPixelSamplerStates[i] = true; mCurPixelTextureSerials[i] = 0; @@ -2009,6 +2068,7 @@ void Renderer9::releaseDeviceResources() SafeDelete(mVertexDataManager); SafeDelete(mIndexDataManager); SafeDelete(mLineLoopIB); + SafeDelete(mCountingIB); for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { @@ -2219,43 +2279,6 @@ GUID Renderer9::getAdapterIdentifier() const return mAdapterIdentifier.DeviceIdentifier; } -Renderer9::MultisampleSupportInfo Renderer9::getMultiSampleSupport(D3DFORMAT format) -{ - MultisampleSupportInfo support = { 0 }; - - for (unsigned int multiSampleIndex = 0; multiSampleIndex < ArraySize(support.supportedSamples); multiSampleIndex++) - { - HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, TRUE, - (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL); - - if (SUCCEEDED(result)) - { - support.supportedSamples[multiSampleIndex] = true; - if (multiSampleIndex != D3DMULTISAMPLE_NONMASKABLE) - { - support.maxSupportedSamples = std::max(support.maxSupportedSamples, multiSampleIndex); - } - } - else - { - support.supportedSamples[multiSampleIndex] = false; - } - } - - return support; -} - -unsigned int Renderer9::getMaxVertexTextureImageUnits() const -{ - META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0; -} - -unsigned int Renderer9::getMaxCombinedTextureImageUnits() const -{ - return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); -} - unsigned int Renderer9::getReservedVertexUniformVectors() const { return 2; // dx_ViewAdjust and dx_DepthRange. @@ -2266,33 +2289,6 @@ unsigned int Renderer9::getReservedFragmentUniformVectors() const return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. } -unsigned int Renderer9::getMaxVertexUniformVectors() const -{ - return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors(); -} - -unsigned int Renderer9::getMaxFragmentUniformVectors() const -{ - const int maxPixelConstantVectors = (getMajorShaderModel() >= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2; - - return maxPixelConstantVectors - getReservedFragmentUniformVectors(); -} - -unsigned int Renderer9::getMaxVaryingVectors() const -{ - return (getMajorShaderModel() >= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2; -} - -unsigned int Renderer9::getMaxVertexShaderUniformBuffers() const -{ - return 0; -} - -unsigned int Renderer9::getMaxFragmentShaderUniformBuffers() const -{ - return 0; -} - unsigned int Renderer9::getReservedVertexUniformBuffers() const { return 0; @@ -2303,26 +2299,6 @@ unsigned int Renderer9::getReservedFragmentUniformBuffers() const return 0; } -unsigned int Renderer9::getMaxTransformFeedbackBuffers() const -{ - return 0; -} - -unsigned int Renderer9::getMaxTransformFeedbackSeparateComponents() const -{ - return 0; -} - -unsigned int Renderer9::getMaxTransformFeedbackInterleavedComponents() const -{ - return 0; -} - -unsigned int Renderer9::getMaxUniformBufferSize() const -{ - return 0; -} - bool Renderer9::getShareHandleSupport() const { // PIX doesn't seem to support using share handles, so disable them. @@ -2334,25 +2310,6 @@ bool Renderer9::getPostSubBufferSupport() const return true; } -int Renderer9::getMaxRecommendedElementsIndices() const -{ - // ES3 only - UNREACHABLE(); - return 0; -} - -int Renderer9::getMaxRecommendedElementsVertices() const -{ - // ES3 only - UNREACHABLE(); - return 0; -} - -bool Renderer9::getSRGBTextureSupport() const -{ - return false; -} - int Renderer9::getMajorShaderModel() const { return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); @@ -2373,92 +2330,14 @@ int Renderer9::getMaxSwapInterval() const return mMaxSwapInterval; } -int Renderer9::getMaxSupportedSamples() const -{ - return mMaxSupportedSamples; -} - -GLsizei Renderer9::getMaxSupportedFormatSamples(GLenum internalFormat) const -{ - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat); - MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format); - return (itr != mMultiSampleSupport.end()) ? mMaxSupportedSamples : 0; -} - -GLsizei Renderer9::getNumSampleCounts(GLenum internalFormat) const -{ - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat); - MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format); - - unsigned int numCounts = 0; - if (iter != mMultiSampleSupport.end()) - { - const MultisampleSupportInfo& info = iter->second; - for (int i = 0; i < D3DMULTISAMPLE_16_SAMPLES; i++) - { - if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i]) - { - numCounts++; - } - } - } - - return numCounts; -} - -void Renderer9::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const -{ - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat); - MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format); - - if (iter != mMultiSampleSupport.end()) - { - const MultisampleSupportInfo& info = iter->second; - int bufPos = 0; - for (int i = D3DMULTISAMPLE_16_SAMPLES; i >= 0 && bufPos < bufSize; i--) - { - if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i]) - { - params[bufPos++] = i; - } - } - } -} - -int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const -{ - if (requested == 0) - { - return requested; - } - - MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format); - if (itr == mMultiSampleSupport.end()) - { - if (format == D3DFMT_UNKNOWN) - return 0; - return -1; - } - - for (unsigned int i = requested; i < ArraySize(itr->second.supportedSamples); ++i) - { - if (itr->second.supportedSamples[i] && i != D3DMULTISAMPLE_NONMASKABLE) - { - return i; - } - } - - return -1; -} - -bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) +bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) { bool result = false; if (source && dest) { - TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance()); - TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance()); + TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source); + TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest); int levels = source9->getLevelCount(); for (int i = 0; i < levels; ++i) @@ -2481,14 +2360,14 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStora return result; } -bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) +bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) { bool result = false; if (source && dest) { - TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance()); - TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance()); + TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source); + TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest); int levels = source9->getLevelCount(); for (int f = 0; f < 6; f++) { @@ -2513,14 +2392,14 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSto return result; } -bool Renderer9::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) +bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); return false; } -bool Renderer9::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) +bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) { // 2D array textures are not supported by the D3D9 backend. UNREACHABLE(); @@ -2544,8 +2423,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2553,11 +2432,11 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); + return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); } -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2565,19 +2444,19 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); + return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); } -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) +bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); return false; } -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) +bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 2D array textures are not available in the D3D9 backend. UNREACHABLE(); @@ -2602,11 +2481,11 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (readBuffer) { - readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer->getRenderTarget()); + readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer); } if (drawBuffer) { - drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer->getRenderTarget()); + drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer); } if (readRenderTarget) @@ -2731,11 +2610,11 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (readBuffer) { - readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer->getDepthStencil()); + readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer); } if (drawBuffer) { - drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer->getDepthStencil()); + drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer); } if (readDepthStencil) @@ -2768,8 +2647,8 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & return true; } -void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) +gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ASSERT(pack.pixelBuffer.get() == NULL); @@ -2779,7 +2658,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } if (renderTarget) @@ -2790,7 +2669,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (!surface) { // context must be lost - return; + return gl::Error(GL_NO_ERROR); } D3DSURFACE_DESC desc; @@ -2800,7 +2679,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments."); } HRESULT result; @@ -2812,7 +2691,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { // Use the pixels ptr as a shared handle to write directly into client's memory result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, - D3DPOOL_SYSTEMMEM, &systemSurface, &pixels); + D3DPOOL_SYSTEMMEM, &systemSurface, reinterpret_cast<void**>(&pixels)); if (FAILED(result)) { // Try again without the shared handle @@ -2828,7 +2707,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for ReadPixels."); } } @@ -2844,20 +2723,19 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (d3d9::isDeviceLostError(result)) { notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY); } else { UNREACHABLE(); - return; } + return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data."); } if (directToPixels) { SafeRelease(systemSurface); - return; + return gl::Error(GL_NO_ERROR); } RECT rect; @@ -2874,44 +2752,40 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz UNREACHABLE(); SafeRelease(systemSurface); - return; // No sensible error to generate + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target."); } - unsigned char *source; + uint8_t *source; int inputPitch; if (pack.reverseRowOrder) { - source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); + source = reinterpret_cast<uint8_t*>(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); inputPitch = -lock.Pitch; } else { - source = (unsigned char*)lock.pBits; + source = reinterpret_cast<uint8_t*>(lock.pBits); inputPitch = lock.Pitch; } - GLenum sourceInternalFormat = d3d9_gl::GetInternalFormat(desc.Format); - GLenum sourceFormat = gl::GetFormat(sourceInternalFormat); - GLenum sourceType = gl::GetType(sourceInternalFormat); - - GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat); - - if (sourceFormat == format && sourceType == type) + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat); + if (sourceFormatInfo.format == format && sourceFormatInfo.type == type) { // Direct copy possible - unsigned char *dest = static_cast<unsigned char*>(pixels); for (int y = 0; y < rect.bottom - rect.top; y++) { - memcpy(dest + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourcePixelSize); + memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes); } } else { - GLenum destInternalFormat = gl::GetSizedInternalFormat(format, type); - GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat); - GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat); + const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type); + + const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(format, type); + const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat); - ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type); if (fastCopyFunc) { // Fast copy is possible through some special function @@ -2919,8 +2793,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { for (int x = 0; x < rect.right - rect.left; x++) { - void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize; - void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; + uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; fastCopyFunc(src, dest); } @@ -2928,22 +2802,18 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz } else { - ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format); - ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type); - - gl::ColorF temp; - + uint8_t temp[sizeof(gl::ColorF)]; for (int y = 0; y < rect.bottom - rect.top; y++) { for (int x = 0; x < rect.right - rect.left; x++) { - void *dest = reinterpret_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize; - void *src = source + y * inputPitch + x * sourcePixelSize; + uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; // readFunc and writeFunc will be using the same type of color, CopyTexImage // will not allow the copy otherwise. - readFunc(src, &temp); - writeFunc(&temp, dest); + sourceD3DFormatInfo.colorReadFunction(src, temp); + destFormatTypeInfo.colorWriteFunction(temp, dest); } } } @@ -2951,6 +2821,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz systemSurface->UnlockRect(); SafeRelease(systemSurface); + + return gl::Error(GL_NO_ERROR); } RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) @@ -2977,6 +2849,21 @@ RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format return renderTarget; } +ShaderImpl *Renderer9::createShader(GLenum type) +{ + return new ShaderD3D(type, this); +} + +ProgramImpl *Renderer9::createProgram() +{ + return new ProgramD3D(this); +} + +void Renderer9::releaseShaderCompiler() +{ + ShaderD3D::releaseCompiler(); +} + ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers) @@ -3200,24 +3087,16 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo return NULL; } -Texture2DImpl *Renderer9::createTexture2D() -{ - return new TextureD3D_2D(this); -} - -TextureCubeImpl *Renderer9::createTextureCube() -{ - return new TextureD3D_Cube(this); -} - -Texture3DImpl *Renderer9::createTexture3D() +TextureImpl *Renderer9::createTexture(GLenum target) { - return new TextureD3D_3D(this); -} + switch(target) + { + case GL_TEXTURE_2D: return new TextureD3D_2D(this); + case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); + default: UNREACHABLE(); + } -Texture2DArrayImpl *Renderer9::createTexture2DArray() -{ - return new TextureD3D_2DArray(this); + return NULL; } bool Renderer9::getLUID(LUID *adapterLuid) const @@ -3234,20 +3113,14 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -GLenum Renderer9::getNativeTextureFormat(GLenum internalFormat) const -{ - return d3d9_gl::GetInternalFormat(gl_d3d9::GetTextureFormat(internalFormat)); -} - rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { - return d3d9::GetVertexConversionType(vertexFormat); + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; } GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const { - D3DDECLTYPE declType = d3d9::GetNativeVertexFormat(vertexFormat); - return d3d9::GetDeclTypeComponentType(declType); + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType; } void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h index 070623c9db..dd5f30268a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h @@ -27,6 +27,7 @@ namespace rx class VertexDataManager; class IndexDataManager; class StreamingIndexBufferInterface; +class StaticIndexBufferInterface; struct TranslatedAttribute; class Blit9; @@ -59,38 +60,38 @@ class Renderer9 : public Renderer IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length); HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); - virtual void generateSwizzle(gl::Texture *texture); - virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); - virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); + virtual gl::Error generateSwizzle(gl::Texture *texture); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); - virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); + virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); - virtual void setRasterizerState(const gl::RasterizerState &rasterState); - virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask); - virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); + virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); + virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask); + virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW); virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - virtual void applyUniforms(const gl::ProgramBinary &programBinary); + virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive); + virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances); - virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances); + virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); + virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); virtual void markAllStateDirty(); @@ -105,63 +106,49 @@ class Renderer9 : public Renderer virtual std::string getRendererDescription() const; virtual GUID getAdapterIdentifier() const; - virtual unsigned int getMaxVertexTextureImageUnits() const; - virtual unsigned int getMaxCombinedTextureImageUnits() const; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getMaxVertexUniformVectors() const; - virtual unsigned int getMaxFragmentUniformVectors() const; - virtual unsigned int getMaxVaryingVectors() const; - virtual unsigned int getMaxVertexShaderUniformBuffers() const; - virtual unsigned int getMaxFragmentShaderUniformBuffers() const; virtual unsigned int getReservedVertexUniformBuffers() const; virtual unsigned int getReservedFragmentUniformBuffers() const; - virtual unsigned int getMaxTransformFeedbackBuffers() const; - virtual unsigned int getMaxTransformFeedbackSeparateComponents() const; - virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const; - virtual unsigned int getMaxUniformBufferSize() const; virtual bool getShareHandleSupport() const; virtual bool getPostSubBufferSupport() const; - virtual int getMaxRecommendedElementsIndices() const; - virtual int getMaxRecommendedElementsVertices() const; - virtual bool getSRGBTextureSupport() const; virtual int getMajorShaderModel() const; DWORD getCapsDeclTypes() const; virtual int getMinSwapInterval() const; virtual int getMaxSwapInterval() const; - virtual GLsizei getMaxSupportedSamples() const; - virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const; - virtual GLsizei getNumSampleCounts(GLenum internalFormat) const; - virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const; - int getNearestSupportedSamples(D3DFORMAT format, int requested) const; - // Pixel operations - virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); - virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); - virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source); - virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source); - - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); + virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source); + + virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter); - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels); + + virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); + // Shader creation + virtual ShaderImpl *createShader(GLenum type); + virtual ProgramImpl *createProgram(); + // Shader operations + virtual void releaseShaderCompiler(); virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers); @@ -180,10 +167,7 @@ class Renderer9 : public Renderer virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); // Texture creation - virtual Texture2DImpl *createTexture2D(); - virtual TextureCubeImpl *createTextureCube(); - virtual Texture3DImpl *createTexture3D(); - virtual Texture2DArrayImpl *createTexture2DArray(); + virtual TextureImpl *createTexture(GLenum target); // Buffer creation virtual BufferImpl *createBuffer(); @@ -197,6 +181,9 @@ class Renderer9 : public Renderer virtual QueryImpl *createQuery(GLenum type); virtual FenceImpl *createFence(); + // Transform Feedback creation + virtual TransformFeedbackImpl* createTransformFeedback(); + // Buffer-to-texture and Texture-to-buffer copies virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, @@ -208,7 +195,6 @@ class Renderer9 : public Renderer D3DPOOL getTexturePool(DWORD usage) const; virtual bool getLUID(LUID *adapterLuid) const; - virtual GLenum getNativeTextureFormat(GLenum internalFormat) const; virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; @@ -223,8 +209,10 @@ class Renderer9 : public Renderer void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v); void applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v); - void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + + gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB); bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer); @@ -269,17 +257,6 @@ class Renderer9 : public Renderer bool mVertexTextureSupport; - struct MultisampleSupportInfo - { - bool supportedSamples[D3DMULTISAMPLE_16_SAMPLES + 1]; - unsigned int maxSupportedSamples; - }; - typedef std::map<D3DFORMAT, MultisampleSupportInfo> MultisampleSupportMap; - MultisampleSupportMap mMultiSampleSupport; - unsigned int mMaxSupportedSamples; - - MultisampleSupportInfo getMultiSampleSupport(D3DFORMAT format); - // current render target states unsigned int mAppliedRenderTargetSerial; unsigned int mAppliedDepthbufferSerial; @@ -318,15 +295,15 @@ class Renderer9 : public Renderer GLuint mCurSampleMask; // Currently applied sampler states - bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetVertexSamplerStates; + std::vector<gl::SamplerState> mCurVertexSamplerStates; - bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetPixelSamplerStates; + std::vector<gl::SamplerState> mCurPixelSamplerStates; // Currently applied textures - unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<unsigned int> mCurVertexTextureSerials; + std::vector<unsigned int> mCurPixelTextureSerials; unsigned int mAppliedIBSerial; IDirect3DVertexShader9 *mAppliedVertexShader; @@ -347,6 +324,7 @@ class Renderer9 : public Renderer IndexDataManager *mIndexDataManager; StreamingIndexBufferInterface *mLineLoopIB; + StaticIndexBufferInterface *mCountingIB; enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 }; struct NullColorbufferCacheEntry diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h index a03528c9b5..2ad3022839 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h @@ -12,6 +12,10 @@ #include "common/debug.h" +#include <cstddef> +#include <unordered_map> +#include <string> + namespace rx { template <typename ShaderObject> diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp index c10ddbf6ce..bc7120461b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp index c6567b635f..0aeaabb1ca 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -50,7 +49,7 @@ void SwapChain9::release() static DWORD convertInterval(EGLint interval) { -#if ANGLE_FORCE_VSYNC_OFF +#ifdef ANGLE_FORCE_VSYNC_OFF return D3DPRESENT_INTERVAL_IMMEDIATE; #else switch(interval) @@ -101,9 +100,10 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI pShareHandle = &mShareHandle; } + const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat); result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, - gl_d3d9::GetTextureFormat(mBackBufferFormat), - D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, + pShareHandle); if (FAILED(result)) { ERR("Could not create offscreen texture: %08lX", result); @@ -150,12 +150,14 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI SafeRelease(oldRenderTarget); } + const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat); + if (mWindow) { D3DPRESENT_PARAMETERS presentParameters = {0}; - presentParameters.AutoDepthStencilFormat = gl_d3d9::GetRenderFormat(mDepthBufferFormat); + presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat; presentParameters.BackBufferCount = 1; - presentParameters.BackBufferFormat = gl_d3d9::GetRenderFormat(mBackBufferFormat); + presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat; presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = mWindow; @@ -207,7 +209,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI if (mDepthBufferFormat != GL_NONE) { result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, - gl_d3d9::GetRenderFormat(mDepthBufferFormat), + depthBufferd3dFormatInfo.renderFormat, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); if (FAILED(result)) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp index b065ee80fe..f44e33db18 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -9,15 +8,15 @@ // classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the // D3D9 texture. -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/d3d/TextureD3D.h" -#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h" #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/Texture.h" +#include "libGLESv2/main.h" namespace rx { @@ -43,12 +42,13 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) { DWORD d3dusage = 0; - if (gl::GetDepthBits(internalformat) > 0 || - gl::GetStencilBits(internalformat) > 0) + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { d3dusage |= D3DUSAGE_DEPTHSTENCIL; } - else if (renderTarget && (gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN)) + else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN)) { d3dusage |= D3DUSAGE_RENDERTARGET; } @@ -95,6 +95,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain mRenderTarget = NULL; initializeRenderTarget(); + initializeSerials(1, 1); } TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) @@ -107,11 +108,11 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat if (width > 0 && height > 0) { IDirect3DDevice9 *device = mRenderer->getDevice(); - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat); - d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel); UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; - HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); + HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -121,6 +122,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat } initializeRenderTarget(); + initializeSerials(getLevelCount(), 1); } TextureStorage9_2D::~TextureStorage9_2D() @@ -157,23 +159,28 @@ IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) return surface; } -RenderTarget *TextureStorage9_2D::getRenderTarget(int level) +RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/) { return mRenderTarget; } -void TextureStorage9_2D::generateMipmap(int level) +void TextureStorage9_2D::generateMipmaps() { - IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); - IDirect3DSurface9 *lower = getSurfaceLevel(level, true); + // Base level must already be defined - if (upper != NULL && lower != NULL) + for (int level = 1; level < getLevelCount(); level++) { - mRenderer->boxFilter(upper, lower); - } + IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); + IDirect3DSurface9 *lower = getSurfaceLevel(level, true); + + if (upper != NULL && lower != NULL) + { + mRenderer->boxFilter(upper, lower); + } - SafeRelease(upper); - SafeRelease(lower); + SafeRelease(upper); + SafeRelease(lower); + } } IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const @@ -208,11 +215,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo { IDirect3DDevice9 *device = mRenderer->getDevice(); int height = size; - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat); - d3d9::MakeValidSize(false, format, &size, &height, &mTopLevel); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel); UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; - HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); + HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -222,6 +229,7 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo } initializeRenderTarget(); + initializeSerials(getLevelCount() * 6, 6); } TextureStorage9_Cube::~TextureStorage9_Cube() @@ -263,23 +271,31 @@ IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, in return surface; } -RenderTarget *TextureStorage9_Cube::getRenderTargetFace(GLenum faceTarget, int level) +RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index) { - return mRenderTarget[TextureD3D_Cube::targetToIndex(faceTarget)]; + return mRenderTarget[index.layerIndex]; } -void TextureStorage9_Cube::generateMipmap(int faceIndex, int level) +void TextureStorage9_Cube::generateMipmaps() { - IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false); - IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true); + // Base level must already be defined - if (upper != NULL && lower != NULL) + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - mRenderer->boxFilter(upper, lower); - } + for (int level = 1; level < getLevelCount(); level++) + { + IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false); + IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true); + + if (upper != NULL && lower != NULL) + { + mRenderer->boxFilter(upper, lower); + } - SafeRelease(upper); - SafeRelease(lower); + SafeRelease(upper); + SafeRelease(lower); + } + } } IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h index cc7c155d34..e698c7dd56 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h @@ -34,11 +34,8 @@ class TextureStorage9 : public TextureStorage DWORD getUsage() const; virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; - virtual RenderTarget *getRenderTarget(int level) { return NULL; } - virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) { return NULL; } - virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) { return NULL; } - virtual void generateMipmap(int level) {}; - virtual void generateMipmap(int face, int level) {}; + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual void generateMipmaps() = 0; virtual int getTopLevel() const; virtual bool isRenderTarget() const; @@ -68,9 +65,9 @@ class TextureStorage9_2D : public TextureStorage9 static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); - virtual RenderTarget *getRenderTarget(int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int level); + virtual void generateMipmaps(); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D); @@ -90,9 +87,9 @@ class TextureStorage9_Cube : public TextureStorage9 static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); - virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int faceIndex, int level); + virtual void generateMipmaps(); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp index d260640dbe..4cf7779118 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,18 +7,17 @@ // VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. #include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/renderer/vertexconversion.h" #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" -#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" - #include "libGLESv2/Buffer.h" namespace rx { -VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) +VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer) { mVertexBuffer = NULL; mBufferSize = 0; @@ -31,7 +29,7 @@ VertexBuffer9::~VertexBuffer9() SafeRelease(mVertexBuffer); } -bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) +gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) { SafeRelease(mVertexBuffer); @@ -49,14 +47,13 @@ bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) if (FAILED(result)) { - ERR("Out of memory allocating a vertex buffer of size %lu.", size); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); } } mBufferSize = size; mDynamicUsage = dynamicUsage; - return true; + return gl::Error(GL_NO_ERROR); } VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) @@ -65,84 +62,80 @@ VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) return static_cast<VertexBuffer9*>(vertexBuffer); } -bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset) +gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) { - if (mVertexBuffer) + if (!mVertexBuffer) { - gl::Buffer *buffer = attrib.buffer.get(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - int inputStride = gl::ComputeVertexAttributeStride(attrib); - int elementSize = gl::ComputeVertexAttributeTypeSize(attrib); + gl::Buffer *buffer = attrib.buffer.get(); - DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; + int inputStride = gl::ComputeVertexAttributeStride(attrib); + int elementSize = gl::ComputeVertexAttributeTypeSize(attrib); - void *mapPtr = NULL; + DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - unsigned int mapSize; - if (!spaceRequired(attrib, count, instances, &mapSize)) - { - return false; - } + uint8_t *mapPtr = NULL; - HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); + unsigned int mapSize; + gl::Error error = spaceRequired(attrib, count, instances, &mapSize); + if (error.isError()) + { + return error; + } - if (FAILED(result)) - { - ERR("Lock failed with error 0x%08x", result); - return false; - } + HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void**>(&mapPtr), lockFlags); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result); + } - const char *input = NULL; - if (attrib.enabled) + const uint8_t *input = NULL; + if (attrib.enabled) + { + if (buffer) { - if (buffer) - { - BufferImpl *storage = buffer->getImplementation(); - input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset); - } - else - { - input = static_cast<const char*>(attrib.pointer); - } + BufferImpl *storage = buffer->getImplementation(); + input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset); } else { - input = reinterpret_cast<const char*>(currentValue.FloatValues); + input = static_cast<const uint8_t*>(attrib.pointer); } + } + else + { + input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues); + } - if (instances == 0 || attrib.divisor == 0) - { - input += inputStride * start; - } - - gl::VertexFormat vertexFormat(attrib, currentValue.Type); - bool needsConversion = (d3d9::GetVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) > 0; - - if (!needsConversion && inputStride == elementSize) - { - size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride); - memcpy(mapPtr, input, copySize); - } - else - { - VertexCopyFunction copyFunction = d3d9::GetVertexCopyFunction(vertexFormat); - copyFunction(input, inputStride, count, mapPtr); - } + if (instances == 0 || attrib.divisor == 0) + { + input += inputStride * start; + } - mVertexBuffer->Unlock(); + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); + bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0; - return true; + if (!needsConversion && inputStride == elementSize) + { + size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride); + memcpy(mapPtr, input, copySize); } else { - ERR("Vertex buffer not initialized."); - return false; + d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr); } + + mVertexBuffer->Unlock(); + + return gl::Error(GL_NO_ERROR); } -bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const +gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const { return spaceRequired(attrib, count, instances, outSpaceRequired); } @@ -152,7 +145,7 @@ unsigned int VertexBuffer9::getBufferSize() const return mBufferSize; } -bool VertexBuffer9::setBufferSize(unsigned int size) +gl::Error VertexBuffer9::setBufferSize(unsigned int size) { if (size > mBufferSize) { @@ -160,38 +153,33 @@ bool VertexBuffer9::setBufferSize(unsigned int size) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool VertexBuffer9::discard() +gl::Error VertexBuffer9::discard() { - if (mVertexBuffer) + if (!mVertexBuffer) { - void *dummy; - HRESULT result; - - result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); - if (FAILED(result)) - { - ERR("Discard lock failed with error 0x%08x", result); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - result = mVertexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } + void *dummy; + HRESULT result; - return true; + result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal buffer for discarding, HRESULT: 0x%08x", result); } - else + + result = mVertexBuffer->Unlock(); + if (FAILED(result)) { - ERR("Vertex buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal buffer for discarding, HRESULT: 0x%08x", result); } + + return gl::Error(GL_NO_ERROR); } IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const @@ -199,11 +187,11 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const return mVertexBuffer; } -bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) +gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) const { gl::VertexFormat vertexFormat(attrib, GL_FLOAT); - unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); if (attrib.enabled) { @@ -214,28 +202,21 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t } else { - if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1)) - { - // Round up - elementCount = (static_cast<unsigned int>(instances) + (attrib.divisor - 1)) / attrib.divisor; - } - else - { - elementCount = static_cast<unsigned int>(instances) / attrib.divisor; - } + // Round up to divisor, if possible + elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); } - if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) + if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount) { if (outSpaceRequired) { - *outSpaceRequired = elementSize * elementCount; + *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount; } - return true; + return gl::Error(GL_NO_ERROR); } else { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); } } else @@ -245,7 +226,7 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t { *outSpaceRequired = elementSize * 4; } - return true; + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h index fc4b6b6d26..bdcf4bb64a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h @@ -18,35 +18,35 @@ class Renderer9; class VertexBuffer9 : public VertexBuffer { public: - explicit VertexBuffer9(rx::Renderer9 *const renderer); + explicit VertexBuffer9(rx::Renderer9 *renderer); virtual ~VertexBuffer9(); - virtual bool initialize(unsigned int size, bool dynamicUsage); + virtual gl::Error initialize(unsigned int size, bool dynamicUsage); static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer); - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset); + virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset); - virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; + virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; virtual unsigned int getBufferSize() const; - virtual bool setBufferSize(unsigned int size); - virtual bool discard(); + virtual gl::Error setBufferSize(unsigned int size); + virtual gl::Error discard(); IDirect3DVertexBuffer9 *getBuffer() const; private: DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); - rx::Renderer9 *const mRenderer; + rx::Renderer9 *mRenderer; IDirect3DVertexBuffer9 *mVertexBuffer; unsigned int mBufferSize; bool mDynamicUsage; - static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired); + gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) const; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp index 303d8ad299..cefd786f11 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -7,11 +6,11 @@ // VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h" #include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/VertexAttribute.h" namespace rx { @@ -41,13 +40,27 @@ VertexDeclarationCache::~VertexDeclarationCache() } } -GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) +gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) { *repeatDraw = 1; int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; + if (instances == 0) + { + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) + { + if (attributes[i].divisor != 0) + { + // If a divisor is set, it still applies even if an instanced draw was not used, so treat + // as a single-instance draw. + instances = 1; + break; + } + } + } + if (instances > 0) { // Find an indexed attribute to be mapped to D3D stream 0 @@ -68,12 +81,14 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl } } - if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS) - { - return GL_INVALID_OPERATION; - } + // The validation layer checks that there is at least one active attribute with a zero divisor as per + // the GL_ANGLE_instanced_arrays spec. + ASSERT(indexedAttribute != gl::MAX_VERTEX_ATTRIBS); } + D3DCAPS9 caps; + device->GetDeviceCaps(&caps); + D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 *element = &elements[0]; @@ -133,10 +148,11 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl } gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat); element->Stream = stream; element->Offset = 0; - element->Type = d3d9::GetNativeVertexFormat(vertexFormat); + element->Type = d3d9VertexInfo.nativeFormat; element->Method = D3DDECLMETHOD_DEFAULT; element->Usage = D3DDECLUSAGE_TEXCOORD; element->UsageIndex = programBinary->getSemanticIndex(i); @@ -172,7 +188,7 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl mLastSetVDecl = entry->vertexDeclaration; } - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } } @@ -194,12 +210,17 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl } memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); - device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal vertex declaration, result: 0x%X.", result); + } + device->SetVertexDeclaration(lastCache->vertexDeclaration); mLastSetVDecl = lastCache->vertexDeclaration; lastCache->lruCount = ++mMaxLru; - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } void VertexDeclarationCache::markStateDirty() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h index 004e28df4f..9af36e0d7a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -9,6 +9,7 @@ #ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ #define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ +#include "libGLESv2/Error.h" #include "libGLESv2/renderer/d3d/VertexDataManager.h" namespace gl @@ -25,7 +26,7 @@ class VertexDeclarationCache VertexDeclarationCache(); ~VertexDeclarationCache(); - GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw); + gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw); void markStateDirty(); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp index f5d1da62b3..f3acaf7987 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -18,255 +17,134 @@ namespace rx { -// Each GL internal format corresponds to one D3D format and data loading function. -// Due to not all formats being available all the time, some of the function/format types are wrapped -// in templates that perform format support queries on a Renderer9 object which is supplied -// when requesting the function or format. - -typedef bool(*FallbackPredicateFunction)(); - -template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> -static void FallbackLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - if (pred()) - { - prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } - else - { - fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } -} - -static void UnreachableLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) +namespace d3d9 { - UNREACHABLE(); -} const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); -struct D3D9FormatInfo +struct D3D9FastCopyFormat { - D3DFORMAT mTexFormat; - D3DFORMAT mRenderFormat; - LoadImageFunction mLoadFunction; + GLenum destFormat; + GLenum destType; + ColorCopyFunction copyFunction; - D3D9FormatInfo() - : mTexFormat(D3DFMT_NULL), mRenderFormat(D3DFMT_NULL), mLoadFunction(NULL) + D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) + : destFormat(destFormat), destType(destType), copyFunction(copyFunction) { } - D3D9FormatInfo(D3DFORMAT textureFormat, D3DFORMAT renderFormat, LoadImageFunction loadFunc) - : mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc) - { } + bool operator<(const D3D9FastCopyFormat& other) const + { + return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; + } }; -typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair; -typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap; +typedef std::multimap<D3DFORMAT, D3D9FastCopyFormat> D3D9FastCopyMap; -static D3D9FormatMap BuildD3D9FormatMap() +static D3D9FastCopyMap BuildFastCopyMap() { - D3D9FormatMap map; + D3D9FastCopyMap map; - // | Internal format | Texture format | Render format | Load function | - map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ))); - - map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ))); - map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D32, UnreachableLoad ))); - map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ))); - map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ))); // TODO: What's the texture format? - - map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> ))); - map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>))); - map.insert(D3D9FormatPair(GL_RG32F_EXT, D3D9FormatInfo(D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> ))); - map.insert(D3D9FormatPair(GL_R32F_EXT, D3D9FormatInfo(D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> ))); - map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F ))); - - map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> ))); - map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> ))); - map.insert(D3D9FormatPair(GL_RG16F_EXT, D3D9FormatInfo(D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> ))); - map.insert(D3D9FormatPair(GL_R16F_EXT, D3D9FormatInfo(D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> ))); - map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ))); - - map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>))); - - map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ))); - map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>))); - map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_R8_EXT, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ))); - map.insert(D3D9FormatPair(GL_RG8_EXT, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 ))); - - map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> ))); - map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ))); - - map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ))); - map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ))); - map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ))); - map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ))); - - // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and - // then changing the format and loading function appropriately. - map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT, D3D9FormatInfo(D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> ))); - map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> ))); + map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); return map; } -static bool GetD3D9FormatInfo(GLenum internalFormat, D3D9FormatInfo *outFormatInfo) +// A map to determine the pixel size and mip generation function of a given D3D format +typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap; + +D3DFormat::D3DFormat() + : pixelBytes(0), + blockWidth(0), + blockHeight(0), + internalFormat(GL_NONE), + mipGenerationFunction(NULL), + colorReadFunction(NULL), + fastCopyFunctions() { - static const D3D9FormatMap formatMap = BuildD3D9FormatMap(); - D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat); - if (iter != formatMap.end()) - { - if (outFormatInfo) - { - *outFormatInfo = iter->second; - } - return true; - } - else - { - return false; - } } -// A map to determine the pixel size and mip generation function of a given D3D format -struct D3DFormatInfo +ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const { - GLuint mPixelBits; - GLuint mBlockWidth; - GLuint mBlockHeight; - GLenum mInternalFormat; - - MipGenerationFunction mMipGenerationFunction; - ColorReadFunction mColorReadFunction; + FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); + return (iter != fastCopyFunctions.end()) ? iter->second : NULL; +} - D3DFormatInfo() - : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL), - mColorReadFunction(NULL) - { } +static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth, + GLuint blockHeight, GLenum internalFormat, MipGenerationFunction mipFunc, + ColorReadFunction colorReadFunc) +{ + D3DFormat info; + info.pixelBytes = bits / 8; + info.blockWidth = blockWidth; + info.blockHeight = blockHeight; + info.internalFormat = internalFormat; + info.mipGenerationFunction = mipFunc; + info.colorReadFunction = colorReadFunc; - D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum internalFormat, - MipGenerationFunction mipFunc, ColorReadFunction readFunc) - : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat), - mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc) - { } -}; + static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); + std::pair<D3D9FastCopyMap::const_iterator, D3D9FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(format); + for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) + { + info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); + } -typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair; -typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap; + map->insert(std::make_pair(format, info)); +} static D3D9FormatInfoMap BuildD3D9FormatInfoMap() { D3D9FormatInfoMap map; - // | D3DFORMAT | | S |W |H | Internal format | Mip generation function | Color read function | - map.insert(D3D9FormatInfoPair(D3DFMT_NULL, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); - map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); - - map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A8, D3DFormatInfo( 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4, D3DFormatInfo( 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5, D3DFormatInfo( 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_R16F, D3DFormatInfo( 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_G16R16F, D3DFormatInfo( 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>))); - map.insert(D3D9FormatInfoPair(D3DFMT_R32F, D3DFormatInfo( 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_G32R32F, D3DFormatInfo( 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ))); - map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>))); - - map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); - map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); - map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); - map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL ))); - - map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); - - map.insert(D3D9FormatInfoPair(D3DFMT_DXT1, D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ))); - map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ))); - map.insert(D3D9FormatInfoPair(D3DFMT_DXT5, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ))); + // | D3DFORMAT | S |W |H | Internal format | Mip generation function | Color read function | + InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, GL_NONE, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL ); + + InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>); + InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>); + + InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL ); + + InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); + + InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ); return map; } -static const D3D9FormatInfoMap &GetD3D9FormatInfoMap() +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format) { static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); - return infoMap; -} - -static bool GetD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo) -{ - const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap(); D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); if (iter != infoMap.end()) { - if (outFormatInfo) - { - *outFormatInfo = iter->second; - } - return true; + return iter->second; } else { - return false; + static const D3DFormat defaultInfo; + return defaultInfo; } } -static d3d9::D3DFormatSet BuildAllD3DFormatSet() -{ - d3d9::D3DFormatSet set; - - const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap(); - for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i) - { - set.insert(i->first); - } - - return set; -} - -struct D3D9FastCopyFormat -{ - D3DFORMAT mSourceFormat; - GLenum mDestFormat; - GLenum mDestType; - - D3D9FastCopyFormat(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType) - : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType) - { } - - bool operator<(const D3D9FastCopyFormat& other) const - { - return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; - } -}; -typedef std::map<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyMap; -typedef std::pair<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyPair; -static D3D9FastCopyMap BuildFastCopyMap() -{ - D3D9FastCopyMap map; - - map.insert(D3D9FastCopyPair(D3D9FastCopyFormat(D3DFMT_A8R8G8B8, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte)); - - return map; -} typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair; typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap; @@ -275,160 +153,148 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() { InternalFormatInitialzerMap map; - map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); - map.insert(InternalFormatInitialzerPair(GL_RGB32F, Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>)); + map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); + map.insert(InternalFormatInitialzerPair(GL_RGB32F, Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>)); return map; } -static const InternalFormatInitialzerMap &GetInternalFormatInitialzerMap() -{ - static const InternalFormatInitialzerMap map = BuildInternalFormatInitialzerMap(); - return map; -} +// Each GL internal format corresponds to one D3D format and data loading function. +// Due to not all formats being available all the time, some of the function/format types are wrapped +// in templates that perform format support queries on a Renderer9 object which is supplied +// when requesting the function or format. -namespace d3d9 -{ +typedef bool(*FallbackPredicateFunction)(); -MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format) +template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> +static void FallbackLoad(size_t width, size_t height, size_t depth, + const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, + uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + if (pred()) { - return d3dFormatInfo.mMipGenerationFunction; + prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); } else { - UNREACHABLE(); - return NULL; + fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); } } -LoadImageFunction GetImageLoadFunction(GLenum internalFormat) +static void UnreachableLoad(size_t width, size_t height, size_t depth, + const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, + uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { - D3D9FormatInfo d3d9FormatInfo; - if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) - { - return d3d9FormatInfo.mLoadFunction; - } - else - { - UNREACHABLE(); - return NULL; - } + UNREACHABLE(); } -GLuint GetFormatPixelBytes(D3DFORMAT format) -{ - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - return d3dFormatInfo.mPixelBits / 8; - } - else - { - UNREACHABLE(); - return 0; - } -} +typedef std::pair<GLenum, TextureFormat> D3D9FormatPair; +typedef std::map<GLenum, TextureFormat> D3D9FormatMap; -GLuint GetBlockWidth(D3DFORMAT format) +TextureFormat::TextureFormat() + : texFormat(D3DFMT_NULL), + renderFormat(D3DFMT_NULL), + dataInitializerFunction(NULL), + loadFunction(UnreachableLoad) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - return d3dFormatInfo.mBlockWidth; - } - else - { - UNREACHABLE(); - return 0; - } } -GLuint GetBlockHeight(D3DFORMAT format) +static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalFormat, D3DFORMAT texFormat, + D3DFORMAT renderFormat, LoadImageFunction loadFunction) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - return d3dFormatInfo.mBlockHeight; - } - else - { - UNREACHABLE(); - return 0; - } -} + TextureFormat info; + info.texFormat = texFormat; + info.renderFormat = renderFormat; -GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height) -{ - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth; - GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight; + static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap(); + InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat); + info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL; - return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8; - } - else - { - UNREACHABLE(); - return 0; - } + info.loadFunction = loadFunction; + + map->insert(std::make_pair(internalFormat, info)); } -void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +static D3D9FormatMap BuildD3D9FormatMap() { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - int upsampleCount = 0; + D3D9FormatMap map; - GLsizei blockWidth = d3dFormatInfo.mBlockWidth; - GLsizei blockHeight = d3dFormatInfo.mBlockHeight; + // | Internal format | Texture format | Render format | Load function | + InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ); + + // We choose to downsample the GL_DEPTH_COMPONENT32_OES format to a 24-bit format because D3DFMT_D32 is not widely + // supported. We're allowed to do this because: + // - The ES spec 2.0.25 sec 3.7.1 states that we're allowed to store texture formats with internal format + // resolutions of our own choosing. + // - OES_depth_texture states that downsampling of the depth formats is allowed. + // - ANGLE_depth_texture does not state minimum required resolutions of the depth texture formats it + // introduces. + // In ES3 however, there are minimum resolutions for the texture formats and this would not be allowed. + + InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, D3DFMT_INTZ, D3DFMT_D24X8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8, D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ); // TODO: What's the texture format? + + InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> ); + InsertD3D9FormatInfo(&map, GL_RGB32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>); + InsertD3D9FormatInfo(&map, GL_RG32F_EXT, D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> ); + InsertD3D9FormatInfo(&map, GL_R32F_EXT, D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> ); + InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F ); + + InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> ); + InsertD3D9FormatInfo(&map, GL_RGB16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> ); + InsertD3D9FormatInfo(&map, GL_RG16F_EXT, D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> ); + InsertD3D9FormatInfo(&map, GL_R16F_EXT, D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> ); + InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ); + + InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>); + + InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>); + InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_RG8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 ); + + InsertD3D9FormatInfo(&map, GL_BGRA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> ); + InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ); + + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ); - // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. - if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight) - { - while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) - { - *requestWidth <<= 1; - *requestHeight <<= 1; - upsampleCount++; - } - } - *levelOffset = upsampleCount; - } -} + // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and + // then changing the format and loading function appropriately. + InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> ); -const D3DFormatSet &GetAllUsedD3DFormats() -{ - static const D3DFormatSet formatSet = BuildAllD3DFormatSet(); - return formatSet; + return map; } -ColorReadFunction GetColorReadFunction(D3DFORMAT format) +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + static const D3D9FormatMap formatMap = BuildD3D9FormatMap(); + D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) { - return d3dFormatInfo.mColorReadFunction; + return iter->second; } else { - UNREACHABLE(); - return NULL; + static const TextureFormat defaultInfo; + return defaultInfo; } } -ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType) -{ - static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); - D3D9FastCopyMap::const_iterator iter = fastCopyMap.find(D3D9FastCopyFormat(sourceFormat, destFormat, destType)); - return (iter != fastCopyMap.end()) ? iter->second : NULL; -} - -GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) +static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) { switch (declType) { @@ -451,27 +317,13 @@ GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) // Attribute format conversion enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; -struct FormatConverter -{ - bool identity; - std::size_t outputElementSize; - void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); - D3DDECLTYPE d3dDeclType; -}; - struct TranslationDescription { DWORD capsFlag; - FormatConverter preferredConversion; - FormatConverter fallbackConversion; + VertexFormat preferredConversion; + VertexFormat fallbackConversion; }; -static unsigned int typeIndex(GLenum type); -static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); - -bool mTranslationsInitialized = false; -FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - // Mapping from OpenGL-ES vertex attrib type to D3D decl type: // // BYTE SHORT (Cast) @@ -623,14 +475,35 @@ public: enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag }; }; +VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), + outputElementSize(0), + copyFunction(NULL), + nativeFormat(D3DDECLTYPE_UNUSED), + componentType(GL_NONE) +{ +} + // Initialize a TranslationInfo +VertexFormat CreateVertexFormatInfo(bool identity, size_t elementSize, VertexCopyFunction copyFunc, D3DDECLTYPE nativeFormat) +{ + VertexFormat formatInfo; + formatInfo.conversionType = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU; + formatInfo.outputElementSize = elementSize; + formatInfo.copyFunction = copyFunc; + formatInfo.nativeFormat = nativeFormat; + formatInfo.componentType = GetDeclTypeComponentType(nativeFormat); + return formatInfo; +} + #define TRANSLATION(type, norm, size, preferred) \ - { \ + CreateVertexFormatInfo \ + ( \ Converter<type, norm, size, preferred>::identity, \ Converter<type, norm, size, preferred>::finalSize, \ Converter<type, norm, size, preferred>::convertArray, \ static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \ - } + ) #define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ { \ @@ -651,168 +524,63 @@ public: { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ } -const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] +static inline unsigned int ComputeTypeIndex(GLenum type) { - TRANSLATIONS_FOR_TYPE(GL_BYTE), - TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), - TRANSLATIONS_FOR_TYPE(GL_SHORT), - TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), - TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), - TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) -}; + switch (type) + { + case GL_BYTE: return 0; + case GL_UNSIGNED_BYTE: return 1; + case GL_SHORT: return 2; + case GL_UNSIGNED_SHORT: return 3; + case GL_FIXED: return 4; + case GL_FLOAT: return 5; -void InitializeVertexTranslations(const rx::Renderer9 *renderer) -{ - DWORD declTypes = renderer->getCapsDeclTypes(); + default: UNREACHABLE(); return 5; + } +} - for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat) +{ + static bool initialized = false; + static DWORD intializedDeclTypes = 0; + static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + if (!initialized) { - for (unsigned int j = 0; j < 2; j++) + const TranslationDescription translations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] { - for (unsigned int k = 0; k < 4; k++) + TRANSLATIONS_FOR_TYPE(GL_BYTE), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), + TRANSLATIONS_FOR_TYPE(GL_SHORT), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) + }; + for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) + { + for (unsigned int j = 0; j < 2; j++) { - if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) - { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; - } - else + for (unsigned int k = 0; k < 4; k++) { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; + if (translations[i][j][k].capsFlag == 0 || (supportedDeclTypes & translations[i][j][k].capsFlag) != 0) + { + formatConverters[i][j][k] = translations[i][j][k].preferredConversion; + } + else + { + formatConverters[i][j][k] = translations[i][j][k].fallbackConversion; + } } } } + initialized = true; + intializedDeclTypes = supportedDeclTypes; } -} - -unsigned int typeIndex(GLenum type) -{ - switch (type) - { - case GL_BYTE: return 0; - case GL_UNSIGNED_BYTE: return 1; - case GL_SHORT: return 2; - case GL_UNSIGNED_SHORT: return 3; - case GL_FIXED: return 4; - case GL_FLOAT: return 5; - default: UNREACHABLE(); return 5; - } -} + ASSERT(intializedDeclTypes == supportedDeclTypes); -const FormatConverter &formatConverter(const gl::VertexFormat &vertexFormat) -{ // Pure integer attributes only supported in ES3.0 ASSERT(!vertexFormat.mPureInteger); - return mFormatConverters[typeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; -} - -VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat) -{ - return formatConverter(vertexFormat).convertArray; -} - -size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat) -{ - return formatConverter(vertexFormat).outputElementSize; -} - -VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat) -{ - return (formatConverter(vertexFormat).identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU); -} - -D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat) -{ - return formatConverter(vertexFormat).d3dDeclType; -} - -} - -namespace gl_d3d9 -{ - -D3DFORMAT GetTextureFormat(GLenum internalFormat) -{ - D3D9FormatInfo d3d9FormatInfo; - if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) - { - return d3d9FormatInfo.mTexFormat; - } - else - { - return D3DFMT_UNKNOWN; - } -} - -D3DFORMAT GetRenderFormat(GLenum internalFormat) -{ - D3D9FormatInfo d3d9FormatInfo; - if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) - { - return d3d9FormatInfo.mRenderFormat; - } - else - { - return D3DFMT_UNKNOWN; - } -} - -D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples) -{ - return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE; -} - -bool RequiresTextureDataInitialization(GLint internalFormat) -{ - const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap(); - return map.find(internalFormat) != map.end(); -} - -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat) -{ - const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap(); - InternalFormatInitialzerMap::const_iterator iter = map.find(internalFormat); - if (iter != map.end()) - { - return iter->second; - } - else - { - UNREACHABLE(); - return NULL; - } -} - -} - -namespace d3d9_gl -{ - -GLenum GetInternalFormat(D3DFORMAT format) -{ - static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); - D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); - if (iter != infoMap.end()) - { - return iter->second.mInternalFormat; - } - else - { - UNREACHABLE(); - return GL_NONE; - } -} - -GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) -{ - return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; -} - -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) -{ - GLenum internalFormat = d3d9_gl::GetInternalFormat(d3dformat); - GLenum convertedFormat = gl::GetFormat(internalFormat); - return convertedFormat == format; + return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h index 26388794e0..f26fe43b36 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h @@ -12,6 +12,8 @@ #include "libGLESv2/formatutils.h" +#include <map> + namespace rx { @@ -20,55 +22,50 @@ class Renderer9; namespace d3d9 { -typedef std::set<D3DFORMAT> D3DFormatSet; - -MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format); -LoadImageFunction GetImageLoadFunction(GLenum internalFormat); - -GLuint GetFormatPixelBytes(D3DFORMAT format); -GLuint GetBlockWidth(D3DFORMAT format); -GLuint GetBlockHeight(D3DFORMAT format); -GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height); +typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap; -void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); - -const D3DFormatSet &GetAllUsedD3DFormats(); +struct D3DFormat +{ + D3DFormat(); -ColorReadFunction GetColorReadFunction(D3DFORMAT format); -ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType); + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; -VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat); -size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat); -VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat); -D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat); + GLenum internalFormat; -GLenum GetDeclTypeComponentType(D3DDECLTYPE declType); -int GetDeclTypeComponentCount(D3DDECLTYPE declType); -bool IsDeclTypeNormalized(D3DDECLTYPE declType); + MipGenerationFunction mipGenerationFunction; + ColorReadFunction colorReadFunction; -void InitializeVertexTranslations(const rx::Renderer9 *renderer); + FastCopyFunctionMap fastCopyFunctions; + ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; +}; +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); -} - -namespace gl_d3d9 +struct VertexFormat { + VertexFormat(); -D3DFORMAT GetTextureFormat(GLenum internalForma); -D3DFORMAT GetRenderFormat(GLenum internalFormat); + VertexConversionType conversionType; + size_t outputElementSize; + VertexCopyFunction copyFunction; + D3DDECLTYPE nativeFormat; + GLenum componentType; +}; +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat); -D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples); +struct TextureFormat +{ + TextureFormat(); -bool RequiresTextureDataInitialization(GLint internalFormat); -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); + D3DFORMAT texFormat; + D3DFORMAT renderFormat; -} - -namespace d3d9_gl -{ + InitializeTextureDataFunction dataInitializerFunction; -GLenum GetInternalFormat(D3DFORMAT format); -GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); + LoadImageFunction loadFunction; +}; +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp index 68e5378fbb..e7a91e62d6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -11,9 +10,10 @@ #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/formatutils.h" -#include "common/mathutil.h" -#include "libGLESv2/Context.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" +#include "common/mathutil.h" #include "common/debug.h" #include "third_party/systeminfo/SystemInfo.h" @@ -246,40 +246,55 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT } } +D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) +{ + return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE; +} + } namespace d3d9_gl { +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) +{ + return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; +} + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) +{ + GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat; + GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format; + return convertedFormat == format; +} + static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3D9 *d3d9, D3DDEVTYPE deviceType, UINT adapter, D3DFORMAT adapterFormat) { gl::TextureCaps textureCaps; - D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); - if (gl::GetDepthBits(internalFormat) > 0 || gl::GetStencilBits(internalFormat) > 0) + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { - textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, renderFormat)); - textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, renderFormat)); - textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, renderFormat)) || - SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, renderFormat)); + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)); } else { - D3DFORMAT textureFormat = gl_d3d9::GetTextureFormat(internalFormat); - textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, textureFormat)) && - SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, textureFormat)); - textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, textureFormat)); - textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, textureFormat)) || - SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, textureFormat)); + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat)); } + textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)); + textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)) || + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)); + textureCaps.sampleCounts.insert(1); for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) { D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); - HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, renderFormat, TRUE, multisampleType, NULL); + HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL); if (SUCCEEDED(result)) { textureCaps.sampleCounts.insert(i); @@ -302,12 +317,20 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT D3DDISPLAYMODE currentDisplayMode; d3d9->GetAdapterDisplayMode(adapter, ¤tDisplayMode); + GLuint maxSamples = 0; const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) { gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter, currentDisplayMode.Format); textureCapsMap->insert(*internalFormat, textureCaps); + + maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); + + if (gl::GetInternalFormatInfo(*internalFormat).compressed) + { + caps->compressedTextureFormats.push_back(*internalFormat); + } } // GL core feature limits @@ -347,6 +370,77 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT caps->minAliasedLineWidth = 1.0f; caps->maxAliasedLineWidth = 1.0f; + // Primitive count limits (unused in ES2) + caps->maxElementsIndices = 0; + caps->maxElementsVertices = 0; + + // Program and shader binary formats (no supported shader binary formats) + caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); + + // WaitSync is ES3-only, set to zero + caps->maxServerWaitTimeout = 0; + + // Vertex shader limits + caps->maxVertexAttributes = 16; + + const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange. + const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; + caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors; + caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4; + + caps->maxVertexUniformBlocks = 0; + + const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 10; + const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 8; + caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3 + : MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4; + + // Only Direct3D 10 ready devices support all the necessary vertex texture formats. + // We test this using D3D9 by checking support for the R16F format. + if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F))) + { + const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4; + caps->maxVertexTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3; + } + else + { + caps->maxVertexTextureImageUnits = 0; + } + + // Fragment shader limits + const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. + + const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224; + const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32; + caps->maxFragmentUniformVectors = ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 + : MAX_PIXEL_CONSTANT_VECTORS_SM2) - reservedPixelUniformVectors; + caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4; + caps->maxFragmentUniformBlocks = 0; + caps->maxFragmentInputComponents = caps->maxVertexOutputComponents; + caps->maxTextureImageUnits = 16; + caps->minProgramTexelOffset = 0; + caps->maxProgramTexelOffset = 0; + + // Aggregate shader limits (unused in ES2) + caps->maxUniformBufferBindings = 0; + caps->maxUniformBlockSize = 0; + caps->uniformBufferOffsetAlignment = 0; + caps->maxCombinedUniformBlocks = 0; + caps->maxCombinedVertexUniformComponents = 0; + caps->maxCombinedFragmentUniformComponents = 0; + caps->maxVaryingComponents = 0; + + // Aggregate shader limits + caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4; + caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; + + // Transform feedback limits + caps->maxTransformFeedbackInterleavedComponents = 0; + caps->maxTransformFeedbackSeparateAttributes = 0; + caps->maxTransformFeedbackSeparateComponents = 0; + // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16); @@ -394,6 +488,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; + extensions->maxSamples = maxSamples; extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); extensions->packReverseRowOrder = true; extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; @@ -406,4 +501,42 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT } +namespace d3d9 +{ + +GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height) +{ + const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format); + GLuint numBlocksWide = (width + d3dFormatInfo.blockWidth - 1) / d3dFormatInfo.blockWidth; + GLuint numBlocksHight = (height + d3dFormatInfo.blockHeight - 1) / d3dFormatInfo.blockHeight; + return (d3dFormatInfo.pixelBytes * numBlocksWide * numBlocksHight); +} + +void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +{ + const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format); + + int upsampleCount = 0; + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < static_cast<GLsizei>(d3dFormatInfo.blockWidth) || + *requestHeight < static_cast<GLsizei>(d3dFormatInfo.blockHeight)) + { + while (*requestWidth % d3dFormatInfo.blockWidth != 0 || *requestHeight % d3dFormatInfo.blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; +} + +RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +{ + RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); + return RenderTarget9::makeRenderTarget9(renderTarget); +} + +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h index 7f3c65d3e0..b0a940e60a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// renderer9_utils.h: Conversion functions and other utility routines +// renderer9_utils.h: Conversion functions and other utility routines // specific to the D3D9 renderer #ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H @@ -13,8 +13,14 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +namespace gl +{ +class FramebufferAttachment; +} + namespace rx { +class RenderTarget9; namespace gl_d3d9 { @@ -31,11 +37,17 @@ DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy); +D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); + } namespace d3d9_gl { +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); + void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions); @@ -44,6 +56,10 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT namespace d3d9 { +GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height); + +void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + inline bool isDeviceLostError(HRESULT errorCode) { switch (errorCode) @@ -58,6 +74,8 @@ inline bool isDeviceLostError(HRESULT errorCode) } } +RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); + } } |