Moves TextureStorage class to TextureStorage9, mostly.
TRAC #22300
Author: Shannon Woods
Signed-off-by: Geoff Lang
Signed-off-by: Daniel Koch
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1612 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index addf12d..be48066 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -298,6 +298,8 @@
'libGLESv2/renderer/SwapChain11.h',
'libGLESv2/renderer/TextureStorage.cpp',
'libGLESv2/renderer/TextureStorage.h',
+ 'libGLESv2/renderer/TextureStorage9.cpp',
+ 'libGLESv2/renderer/TextureStorage9.h',
'libGLESv2/renderer/VertexBuffer.cpp',
'libGLESv2/renderer/VertexBuffer.h',
'libGLESv2/renderer/VertexBuffer9.cpp',
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 10736be..a110e26 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -857,6 +857,7 @@
{
return NULL;
}
+
return mTexStorage->getRenderTarget();
}
diff --git a/src/libGLESv2/libGLESv2.vcxproj b/src/libGLESv2/libGLESv2.vcxproj
index 5350bb7..25a9368 100644
--- a/src/libGLESv2/libGLESv2.vcxproj
+++ b/src/libGLESv2/libGLESv2.vcxproj
@@ -267,6 +267,7 @@
<ClCompile Include="renderer\SwapChain11.cpp" />
<ClCompile Include="renderer\SwapChain9.cpp" />
<ClCompile Include="renderer\TextureStorage.cpp" />
+ <ClCompile Include="renderer\TextureStorage9.cpp" />
<ClCompile Include="renderer\VertexBuffer.cpp" />
<ClCompile Include="renderer\VertexBuffer11.cpp" />
<ClCompile Include="renderer\VertexBuffer9.cpp" />
@@ -325,6 +326,7 @@
<ClInclude Include="renderer\SwapChain11.h" />
<ClInclude Include="renderer\SwapChain9.h" />
<ClInclude Include="renderer\TextureStorage.h" />
+ <ClInclude Include="renderer\TextureStorage9.h" />
<ClInclude Include="renderer\VertexBuffer.h" />
<ClInclude Include="renderer\VertexBuffer11.h" />
<ClInclude Include="renderer\VertexBuffer9.h" />
@@ -357,5 +359,5 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
- </ImportGroup>
+ </ImportGroup>
</Project>
diff --git a/src/libGLESv2/libGLESv2.vcxproj.filters b/src/libGLESv2/libGLESv2.vcxproj.filters
index 0cd9b68..140bc1a 100644
--- a/src/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/libGLESv2/libGLESv2.vcxproj.filters
@@ -170,6 +170,9 @@
<ClCompile Include="Uniform.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="renderer\TextureStorage9.cpp">
+ <Filter>Renderer</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BinaryStream.h">
@@ -349,6 +352,9 @@
<ClInclude Include="Uniform.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="renderer\TextureStorage9.h">
+ <Filter>Renderer</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="libGLESv2.def">
@@ -358,4 +364,4 @@
<ItemGroup>
<ResourceCompile Include="libGLESv2.rc" />
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/src/libGLESv2/renderer/Blit.cpp b/src/libGLESv2/renderer/Blit.cpp
index 4da5fc7..978426f 100644
--- a/src/libGLESv2/renderer/Blit.cpp
+++ b/src/libGLESv2/renderer/Blit.cpp
@@ -13,8 +13,8 @@
#include "libGLESv2/main.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/renderer/renderer9_utils.h" // D3D9_REPLACE
-#include "libGLESv2/renderer/TextureStorage.h"
-#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/TextureStorage9.h" // D3D9_REPLACE
+#include "libGLESv2/renderer/RenderTarget9.h" // D3D9_REPLACE
#include "libGLESv2/Framebuffer.h"
namespace
@@ -236,7 +236,8 @@
return error(GL_OUT_OF_MEMORY, false);
}
- IDirect3DSurface9 *destSurface = storage->getSurfaceLevel(level, true);
+ TextureStorage2D9 *storage9 = TextureStorage2D9::makeTextureStorage2D9(storage->getStorageInterface());
+ IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
bool result = false;
if (destSurface)
@@ -272,7 +273,8 @@
return error(GL_OUT_OF_MEMORY, false);
}
- IDirect3DSurface9 *destSurface = storage->getCubeMapSurface(target, level, true);
+ TextureStorageCubeMap9 *storage9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(storage->getStorageInterface());
+ IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
bool result = false;
if (destSurface)
diff --git a/src/libGLESv2/renderer/Image9.cpp b/src/libGLESv2/renderer/Image9.cpp
index b106659..e54e378 100644
--- a/src/libGLESv2/renderer/Image9.cpp
+++ b/src/libGLESv2/renderer/Image9.cpp
@@ -17,6 +17,7 @@
#include "libGLESv2/Texture.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
#include "libGLESv2/renderer/renderer9_utils.h"
#include "libGLESv2/renderer/generatemip.h"
@@ -239,7 +240,7 @@
bool Image9::isRenderableFormat() const
{
- return TextureStorage::IsTextureFormatRenderable(getD3DFormat());
+ return TextureStorage9::IsTextureFormatRenderable(getD3DFormat());
}
D3DFORMAT Image9::getD3DFormat() const
@@ -260,12 +261,14 @@
void Image9::setManagedSurface(TextureStorage2D *storage, int level)
{
- setManagedSurface(storage->getSurfaceLevel(level, false));
+ TextureStorage2D9 *storage9 = TextureStorage2D9::makeTextureStorage2D9(storage->getStorageInterface());
+ setManagedSurface(storage9->getSurfaceLevel(level, false));
}
void Image9::setManagedSurface(TextureStorageCubeMap *storage, int face, int level)
{
- setManagedSurface(storage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
+ TextureStorageCubeMap9 *storage9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(storage->getStorageInterface());
+ setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
}
void Image9::setManagedSurface(IDirect3DSurface9 *surface)
@@ -290,13 +293,15 @@
bool Image9::updateSurface(TextureStorage2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
ASSERT(getSurface() != NULL);
- return updateSurface(storage->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
+ TextureStorage2D9 *storage9 = TextureStorage2D9::makeTextureStorage2D9(storage->getStorageInterface());
+ return updateSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
}
bool Image9::updateSurface(TextureStorageCubeMap *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
ASSERT(getSurface() != NULL);
- return updateSurface(storage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
+ TextureStorageCubeMap9 *storage9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(storage->getStorageInterface());
+ return updateSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
}
bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index b974965..b2a3b4a 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -20,7 +20,7 @@
#include "libGLESv2/renderer/renderer9_utils.h"
#include "libGLESv2/renderer/ShaderExecutable9.h"
#include "libGLESv2/renderer/SwapChain9.h"
-#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
#include "libGLESv2/renderer/Image9.h"
#include "libGLESv2/renderer/Blit.h"
#include "libGLESv2/renderer/RenderTarget9.h"
@@ -637,7 +637,8 @@
TextureStorage *texStorage = texture->getNativeTexture();
if (texStorage)
{
- d3dTexture = texStorage->getBaseTexture();
+ TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInterface());
+ d3dTexture = storage9->getBaseTexture();
}
// If we get NULL back from getBaseTexture here, something went wrong
// in the texture class and we're unexpectedly missing the d3d texture
@@ -2375,13 +2376,16 @@
if (source && dest)
{
- int levels = source->levelCount();
+ TextureStorage2D9 *source9 = TextureStorage2D9::makeTextureStorage2D9(source->getStorageInterface());
+ TextureStorage2D9 *dest9 = TextureStorage2D9::makeTextureStorage2D9(dest->getStorageInterface());
+
+ int levels = source9->levelCount();
for (int i = 0; i < levels; ++i)
{
- IDirect3DSurface9 *srcSurf = source->getSurfaceLevel(i, false);
- IDirect3DSurface9 *dstSurf = dest->getSurfaceLevel(i, false);
+ IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false);
+ IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false);
- result = copyToRenderTarget(dstSurf, srcSurf, source->isManaged());
+ result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
if (srcSurf) srcSurf->Release();
if (dstSurf) dstSurf->Release();
@@ -2400,15 +2404,17 @@
if (source && dest)
{
- int levels = source->levelCount();
+ TextureStorageCubeMap9 *source9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(source->getStorageInterface());
+ TextureStorageCubeMap9 *dest9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(dest->getStorageInterface());
+ int levels = source9->levelCount();
for (int f = 0; f < 6; f++)
{
for (int i = 0; i < levels; i++)
{
- IDirect3DSurface9 *srcSurf = source->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
- IDirect3DSurface9 *dstSurf = dest->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
+ IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
+ IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
- result = copyToRenderTarget(dstSurf, srcSurf, source->isManaged());
+ result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
if (srcSurf) srcSurf->Release();
if (dstSurf) dstSurf->Release();
diff --git a/src/libGLESv2/renderer/TextureStorage.cpp b/src/libGLESv2/renderer/TextureStorage.cpp
index 7b5d0f5..9e001f3 100644
--- a/src/libGLESv2/renderer/TextureStorage.cpp
+++ b/src/libGLESv2/renderer/TextureStorage.cpp
@@ -6,10 +6,11 @@
// TextureStorage.cpp: Implements the abstract rx::TextureStorage class and its concrete derived
// classes TextureStorage2D and TextureStorageCubeMap, which act as the interface to the
-// D3D-side texture.
+// GPU-side texture.
#include "libGLESv2/main.h"
#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
#include "libGLESv2/renderer/SwapChain9.h"
#include "libGLESv2/renderer/Blit.h"
#include "libGLESv2/renderer/RenderTarget9.h"
@@ -21,12 +22,8 @@
{
unsigned int TextureStorage::mCurrentTextureSerial = 1;
-TextureStorage::TextureStorage(Renderer *renderer, DWORD usage)
- : mLodOffset(0),
- mRenderer(Renderer9::makeRenderer9(renderer)),
- mD3DUsage(usage),
- mD3DPool(mRenderer->getTexturePool(usage)),
- mTextureSerial(issueTextureSerial()),
+TextureStorage::TextureStorage()
+ : mTextureSerial(issueTextureSerial()),
mInterface(NULL)
{
}
@@ -36,65 +33,15 @@
delete mInterface;
}
-DWORD TextureStorage::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
-{
- DWORD d3dusage = 0;
-
- if (d3dfmt == D3DFMT_INTZ)
- {
- d3dusage |= D3DUSAGE_DEPTHSTENCIL;
- }
- else if(forceRenderable || (TextureStorage::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
- {
- d3dusage |= D3DUSAGE_RENDERTARGET;
- }
- return d3dusage;
-}
-
-bool TextureStorage::IsTextureFormatRenderable(D3DFORMAT format)
-{
- if (format == D3DFMT_INTZ)
- {
- return true;
- }
- switch(format)
- {
- case D3DFMT_L8:
- case D3DFMT_A8L8:
- case D3DFMT_DXT1:
- case D3DFMT_DXT3:
- case D3DFMT_DXT5:
- return false;
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A16B16G16R16F:
- case D3DFMT_A32B32G32R32F:
- return true;
- default:
- UNREACHABLE();
- }
-
- return false;
-}
-
bool TextureStorage::isRenderTarget() const
{
- return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+ return mInterface->isRenderTarget();
}
+
bool TextureStorage::isManaged() const
{
- return (mD3DPool == D3DPOOL_MANAGED);
-}
-
-D3DPOOL TextureStorage::getPool() const
-{
- return mD3DPool;
-}
-
-DWORD TextureStorage::getUsage() const
-{
- return mD3DUsage;
+ return mInterface->isManaged();
}
unsigned int TextureStorage::getTextureSerial() const
@@ -109,99 +56,41 @@
int TextureStorage::getLodOffset() const
{
- return mLodOffset;
+ return mInterface->getLodOffset();
}
+
int TextureStorage::levelCount()
{
- return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
+ return mInterface->levelCount();
}
-TextureStorage2D::TextureStorage2D(Renderer *renderer, rx::SwapChain9 *swapchain) : TextureStorage(renderer, D3DUSAGE_RENDERTARGET), mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
+TextureStorage2D::TextureStorage2D(Renderer *renderer, SwapChain9 *swapchain)
+ : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
{
- IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
- mTexture = surfaceTexture;
-
- initializeRenderTarget();
+ TextureStorage2D9 *newInterface = new TextureStorage2D9(renderer, swapchain);
+ mInterface = newInterface;
}
TextureStorage2D::TextureStorage2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
- : TextureStorage(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)),
- mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
+ : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
{
- mTexture = NULL;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice(); // D3D9_REPLACE
- gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
- HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(),
- mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- error(GL_OUT_OF_MEMORY);
- }
- }
-
- initializeRenderTarget();
+ TextureStorage2D9 *newInterface = new TextureStorage2D9(renderer, levels, internalformat, usage, forceRenderable, width, height); // D3D9_REPLACE
+ mInterface = newInterface;
}
TextureStorage2D::~TextureStorage2D()
{
- if (mTexture)
- {
- mTexture->Release();
- }
-
- delete mRenderTarget;
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty)
-{
- IDirect3DSurface9 *surface = NULL;
-
- if (mTexture)
- {
- HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
- ASSERT(SUCCEEDED(result));
-
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
- {
- mTexture->AddDirtyRect(NULL);
- }
- }
-
- return surface;
}
RenderTarget *TextureStorage2D::getRenderTarget() const
{
- return mRenderTarget;
+ return mInterface->getRenderTarget();
}
void TextureStorage2D::generateMipmap(int level)
{
- IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
- IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
-
- if (upper != NULL && lower != NULL)
- {
- mRenderer->boxFilter(upper, lower);
- }
-
- if (upper != NULL) upper->Release();
- if (lower != NULL) lower->Release();
-}
-
-IDirect3DBaseTexture9 *TextureStorage2D::getBaseTexture() const
-{
- return mTexture;
+ mInterface->generateMipmap(level);
}
unsigned int TextureStorage2D::getRenderTargetSerial(GLenum target) const
@@ -209,102 +98,25 @@
return mRenderTargetSerial;
}
-void TextureStorage2D::initializeRenderTarget()
-{
- if (mTexture != NULL && isRenderTarget())
- {
- IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
-
- mRenderTarget = new RenderTarget9(mRenderer, surface);
- }
- else
- {
- mRenderTarget = NULL;
- }
-}
-
TextureStorageCubeMap::TextureStorageCubeMap(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
- : TextureStorage(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)),
- mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
+ : mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
{
- mTexture = NULL;
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- int height = size;
- gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
- HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(),
- mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- error(GL_OUT_OF_MEMORY);
- }
- }
-
- initializeRenderTarget();
+ TextureStorageCubeMap9 *newInterface = new TextureStorageCubeMap9(renderer, levels, internalformat, usage, forceRenderable, size); // D3D9_REPLACE
+ mInterface = newInterface;
}
TextureStorageCubeMap::~TextureStorageCubeMap()
{
- if (mTexture)
- {
- mTexture->Release();
- }
-
- for (int i = 0; i < 6; ++i)
- {
- delete mRenderTarget[i];
- }
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
-{
- IDirect3DSurface9 *surface = NULL;
-
- if (mTexture)
- {
- D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
- HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
- ASSERT(SUCCEEDED(result));
-
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
- {
- mTexture->AddDirtyRect(face, NULL);
- }
- }
-
- return surface;
}
RenderTarget *TextureStorageCubeMap::getRenderTarget(GLenum faceTarget) const
{
- return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)];
+ return mInterface->getRenderTarget(faceTarget);
}
void TextureStorageCubeMap::generateMipmap(int face, int level)
{
- IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false);
- IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
-
- if (upper != NULL && lower != NULL)
- {
- mRenderer->boxFilter(upper, lower);
- }
-
- if (upper != NULL) upper->Release();
- if (lower != NULL) lower->Release();
-}
-
-IDirect3DBaseTexture9 *TextureStorageCubeMap::getBaseTexture() const
-{
- return mTexture;
+ mInterface->generateMipmap(face, level);
}
unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const
@@ -312,26 +124,4 @@
return mFirstRenderTargetSerial + gl::TextureCubeMap::faceIndex(target);
}
-void TextureStorageCubeMap::initializeRenderTarget()
-{
- if (mTexture != NULL && isRenderTarget())
- {
- IDirect3DSurface9 *surface = NULL;
-
- for (int i = 0; i < 6; ++i)
- {
- surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
-
- mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
- }
- }
- else
- {
- for (int i = 0; i < 6; ++i)
- {
- mRenderTarget[i] = NULL;
- }
- }
-}
-
}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/TextureStorage.h b/src/libGLESv2/renderer/TextureStorage.h
index 7231c5f..c4c922a 100644
--- a/src/libGLESv2/renderer/TextureStorage.h
+++ b/src/libGLESv2/renderer/TextureStorage.h
@@ -6,10 +6,10 @@
// TextureStorage.h: Defines the abstract rx::TextureStorage class and its concrete derived
// classes TextureStorage2D and TextureStorageCubeMap, which act as the interface to the
-// D3D-side texture.
+// GPU-side texture.
-#ifndef LIBGLESV2_TEXTURESTORAGE_H_
-#define LIBGLESV2_TEXTURESTORAGE_H_
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
#define GL_APICALL
#include <GLES2/gl2.h>
@@ -28,8 +28,18 @@
class TextureStorageInterface
{
public:
- TextureStorageInterface();
- virtual ~TextureStorageInterface();
+ TextureStorageInterface() {};
+ virtual ~TextureStorageInterface() {};
+
+ virtual int getLodOffset() const = 0;
+ virtual bool isRenderTarget() const = 0;
+ virtual bool isManaged() const = 0;
+ virtual int levelCount() = 0;
+
+ virtual RenderTarget *getRenderTarget() const = 0;
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget) const = 0;
+ virtual void generateMipmap(int level) = 0;
+ virtual void generateMipmap(int face, int level) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface);
@@ -39,36 +49,25 @@
class TextureStorage
{
public:
- TextureStorage(rx::Renderer *renderer, DWORD usage);
-
+ TextureStorage();
virtual ~TextureStorage();
- static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable);
- static bool IsTextureFormatRenderable(D3DFORMAT format);
-
TextureStorageInterface *getStorageInterface() { return mInterface; }
- bool isRenderTarget() const;
- bool isManaged() const;
- D3DPOOL getPool() const;
- DWORD getUsage() const;
unsigned int getTextureSerial() const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
- int getLodOffset() const;
- int levelCount();
+
+ virtual int getLodOffset() const;
+ virtual bool isRenderTarget() const;
+ virtual bool isManaged() const;
+ virtual int levelCount();
protected:
- int mLodOffset;
- rx::Renderer9 *mRenderer;
TextureStorageInterface *mInterface;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
- const DWORD mD3DUsage;
- const D3DPOOL mD3DPool;
-
const unsigned int mTextureSerial;
static unsigned int issueTextureSerial();
@@ -78,53 +77,39 @@
class TextureStorage2D : public TextureStorage
{
public:
- explicit TextureStorage2D(rx::Renderer *renderer, rx::SwapChain9 *swapchain);
- TextureStorage2D(rx::Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
-
+ TextureStorage2D(Renderer *renderer, SwapChain9 *swapchain);
+ TextureStorage2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
virtual ~TextureStorage2D();
- IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
- RenderTarget *getRenderTarget() const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
void generateMipmap(int level);
+ RenderTarget *getRenderTarget() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
- void initializeRenderTarget();
-
- IDirect3DTexture9 *mTexture;
- RenderTarget9 *mRenderTarget;
const unsigned int mRenderTargetSerial;
};
class TextureStorageCubeMap : public TextureStorage
{
public:
- TextureStorageCubeMap(rx::Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
-
+ TextureStorageCubeMap(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
virtual ~TextureStorageCubeMap();
- IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
- RenderTarget *getRenderTarget(GLenum faceTarget) const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
void generateMipmap(int face, int level);
+ RenderTarget *getRenderTarget(GLenum faceTarget) const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
- void initializeRenderTarget();
-
- IDirect3DCubeTexture9 *mTexture;
- RenderTarget9 *mRenderTarget[6];
const unsigned int mFirstRenderTargetSerial;
};
}
-#endif // LIBGLESV2_TEXTURESTORAGE_H_
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
diff --git a/src/libGLESv2/renderer/TextureStorage9.cpp b/src/libGLESv2/renderer/TextureStorage9.cpp
new file mode 100644
index 0000000..6d84ff3
--- /dev/null
+++ b/src/libGLESv2/renderer/TextureStorage9.cpp
@@ -0,0 +1,328 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage2D9 and TextureStorageCubeMap9, which act as the interface to the
+// D3D9 texture.
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
+#include "libGLESv2/renderer/SwapChain9.h"
+#include "libGLESv2/renderer/Blit.h"
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+ : mLodOffset(0),
+ mRenderer(Renderer9::makeRenderer9(renderer)),
+ mD3DUsage(usage),
+ mD3DPool(mRenderer->getTexturePool(usage))
+{
+}
+
+TextureStorage9::~TextureStorage9()
+{
+}
+
+TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorageInterface *storage)
+{
+ ASSERT(dynamic_cast<TextureStorage9*>(storage) != NULL);
+ return static_cast<TextureStorage9*>(storage);
+}
+
+DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
+{
+ DWORD d3dusage = 0;
+
+ if (d3dfmt == D3DFMT_INTZ)
+ {
+ d3dusage |= D3DUSAGE_DEPTHSTENCIL;
+ }
+ else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
+ {
+ d3dusage |= D3DUSAGE_RENDERTARGET;
+ }
+ return d3dusage;
+}
+
+bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format)
+{
+ if (format == D3DFMT_INTZ)
+ {
+ return true;
+ }
+ switch(format)
+ {
+ case D3DFMT_L8:
+ case D3DFMT_A8L8:
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT5:
+ return false;
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A32B32G32R32F:
+ return true;
+ default:
+ UNREACHABLE();
+ }
+
+ return false;
+}
+
+bool TextureStorage9::isRenderTarget() const
+{
+ return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+}
+
+bool TextureStorage9::isManaged() const
+{
+ return (mD3DPool == D3DPOOL_MANAGED);
+}
+
+D3DPOOL TextureStorage9::getPool() const
+{
+ return mD3DPool;
+}
+
+DWORD TextureStorage9::getUsage() const
+{
+ return mD3DUsage;
+}
+
+int TextureStorage9::getLodOffset() const
+{
+ return mLodOffset;
+}
+
+int TextureStorage9::levelCount()
+{
+ return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
+}
+
+TextureStorage2D9::TextureStorage2D9(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
+{
+ IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
+ mTexture = surfaceTexture;
+
+ initializeRenderTarget();
+}
+
+TextureStorage2D9::TextureStorage2D9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+ : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+ mTexture = NULL;
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (width > 0 && height > 0)
+ {
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
+ HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(),
+ mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ initializeRenderTarget();
+}
+
+TextureStorage2D9::~TextureStorage2D9()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ }
+
+ delete mRenderTarget;
+}
+
+TextureStorage2D9 *TextureStorage2D9::makeTextureStorage2D9(TextureStorageInterface *storage)
+{
+ ASSERT(dynamic_cast<TextureStorage2D9*>(storage) != NULL);
+ return static_cast<TextureStorage2D9*>(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorage2D9::getSurfaceLevel(int level, bool dirty)
+{
+ IDirect3DSurface9 *surface = NULL;
+
+ if (mTexture)
+ {
+ HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
+ ASSERT(SUCCEEDED(result));
+
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ mTexture->AddDirtyRect(NULL);
+ }
+ }
+
+ return surface;
+}
+
+RenderTarget *TextureStorage2D9::getRenderTarget() const
+{
+ return mRenderTarget;
+}
+
+void TextureStorage2D9::generateMipmap(int level)
+{
+ IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
+ IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+
+ if (upper != NULL && lower != NULL)
+ {
+ mRenderer->boxFilter(upper, lower);
+ }
+
+ if (upper != NULL) upper->Release();
+ if (lower != NULL) lower->Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorage2D9::getBaseTexture() const
+{
+ return mTexture;
+}
+
+void TextureStorage2D9::initializeRenderTarget()
+{
+ if (mTexture != NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+
+ mRenderTarget = new RenderTarget9(mRenderer, surface);
+ }
+ else
+ {
+ mRenderTarget = NULL;
+ }
+}
+
+TextureStorageCubeMap9::TextureStorageCubeMap9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+ : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+ mTexture = NULL;
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (size > 0)
+ {
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ int height = size;
+ gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
+ HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(),
+ mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ initializeRenderTarget();
+}
+
+TextureStorageCubeMap9::~TextureStorageCubeMap9()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ }
+
+ for (int i = 0; i < 6; ++i)
+ {
+ delete mRenderTarget[i];
+ }
+}
+
+TextureStorageCubeMap9 *TextureStorageCubeMap9::makeTextureStorageCubeMap9(TextureStorageInterface *storage)
+{
+ ASSERT(dynamic_cast<TextureStorageCubeMap9*>(storage) != NULL);
+ return static_cast<TextureStorageCubeMap9*>(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorageCubeMap9::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+{
+ IDirect3DSurface9 *surface = NULL;
+
+ if (mTexture)
+ {
+ D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+ HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
+ ASSERT(SUCCEEDED(result));
+
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ mTexture->AddDirtyRect(face, NULL);
+ }
+ }
+
+ return surface;
+}
+
+RenderTarget *TextureStorageCubeMap9::getRenderTarget(GLenum faceTarget) const
+{
+ return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)];
+}
+
+void TextureStorageCubeMap9::generateMipmap(int face, int level)
+{
+ IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false);
+ IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
+
+ if (upper != NULL && lower != NULL)
+ {
+ mRenderer->boxFilter(upper, lower);
+ }
+
+ if (upper != NULL) upper->Release();
+ if (lower != NULL) lower->Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorageCubeMap9::getBaseTexture() const
+{
+ return mTexture;
+}
+
+void TextureStorageCubeMap9::initializeRenderTarget()
+{
+ if (mTexture != NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+
+ for (int i = 0; i < 6; ++i)
+ {
+ surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+
+ mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 6; ++i)
+ {
+ mRenderTarget[i] = NULL;
+ }
+ }
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/TextureStorage9.h b/src/libGLESv2/renderer/TextureStorage9.h
new file mode 100644
index 0000000..41ce1b8
--- /dev/null
+++ b/src/libGLESv2/renderer/TextureStorage9.h
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage2D9 and TextureStorageCubeMap9, which act as the interface to the
+// D3D9 texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+#include <d3d9.h>
+
+#include "libGLESv2/renderer/TextureStorage.h"
+#include "common/debug.h"
+
+namespace rx
+{
+class Renderer9;
+class SwapChain9;
+class RenderTarget;
+class RenderTarget9;
+class Blit;
+
+class TextureStorage9 : public TextureStorageInterface
+{
+ public:
+ TextureStorage9(Renderer *renderer, DWORD usage);
+ virtual ~TextureStorage9();
+
+ static TextureStorage9 *makeTextureStorage9(TextureStorageInterface *storage);
+
+ static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable);
+ static bool IsTextureFormatRenderable(D3DFORMAT format);
+
+ D3DPOOL getPool() const;
+ DWORD getUsage() const;
+
+ virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
+ virtual RenderTarget *getRenderTarget() const { return NULL; }
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget) const { return NULL; }
+ virtual void generateMipmap(int level) {};
+ virtual void generateMipmap(int face, int level) {};
+
+ virtual int getLodOffset() const;
+ virtual bool isRenderTarget() const;
+ virtual bool isManaged() const;
+ virtual int levelCount();
+
+ protected:
+ int mLodOffset;
+ Renderer9 *mRenderer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
+
+ const DWORD mD3DUsage;
+ const D3DPOOL mD3DPool;
+};
+
+class TextureStorage2D9 : public TextureStorage9
+{
+ public:
+ TextureStorage2D9(Renderer *renderer, SwapChain9 *swapchain);
+ TextureStorage2D9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+ virtual ~TextureStorage2D9();
+
+ static TextureStorage2D9 *makeTextureStorage2D9(TextureStorageInterface *storage);
+
+ IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
+ virtual RenderTarget *getRenderTarget() const;
+ virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+ virtual void generateMipmap(int level);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage2D9);
+
+ void initializeRenderTarget();
+
+ IDirect3DTexture9 *mTexture;
+ RenderTarget9 *mRenderTarget;
+};
+
+class TextureStorageCubeMap9 : public TextureStorage9
+{
+ public:
+ TextureStorageCubeMap9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+ virtual ~TextureStorageCubeMap9();
+
+ static TextureStorageCubeMap9 *makeTextureStorageCubeMap9(TextureStorageInterface *storage);
+
+ IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget) const;
+ virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+ virtual void generateMipmap(int face, int level);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap9);
+
+ void initializeRenderTarget();
+
+ IDirect3DCubeTexture9 *mTexture;
+ RenderTarget9 *mRenderTarget[6];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+