blob: b20c3704ce5276be38dda38fa68e49b2d8fdc1f0 [file] [log] [blame]
daniel@transgaming.comb5e1a272012-10-31 19:10:00 +00001//
2// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// TextureStorage.cpp: Implements the abstract gl::TextureStorage class and its concrete derived
8// classes TextureStorage2D and TextureStorageCubeMap, which act as the interface to the
9// D3D-side texture.
10
11#include "libGLESv2/main.h"
12#include "libGLESv2/renderer/TextureStorage.h"
13
14#include "common/debug.h"
15
16namespace gl
17{
18unsigned int TextureStorage::mCurrentTextureSerial = 1;
19
20TextureStorage::TextureStorage(DWORD usage)
21 : mD3DUsage(usage),
22 mD3DPool(getDisplay()->getRenderer()->getTexturePool(usage)), // D3D9_REPLACE
23 mTextureSerial(issueTextureSerial()),
24 mLodOffset(0)
25{
26}
27
28TextureStorage::~TextureStorage()
29{
30}
31
32bool TextureStorage::isRenderTarget() const
33{
34 return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
35}
36
37bool TextureStorage::isManaged() const
38{
39 return (mD3DPool == D3DPOOL_MANAGED);
40}
41
42D3DPOOL TextureStorage::getPool() const
43{
44 return mD3DPool;
45}
46
47DWORD TextureStorage::getUsage() const
48{
49 return mD3DUsage;
50}
51
52unsigned int TextureStorage::getTextureSerial() const
53{
54 return mTextureSerial;
55}
56
57unsigned int TextureStorage::issueTextureSerial()
58{
59 return mCurrentTextureSerial++;
60}
61
62int TextureStorage::getLodOffset() const
63{
64 return mLodOffset;
65}
66
67TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(D3DUSAGE_RENDERTARGET), mRenderTargetSerial(RenderbufferStorage::issueSerial())
68{
69 mTexture = surfaceTexture;
70}
71
72TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height)
73 : TextureStorage(usage), mRenderTargetSerial(RenderbufferStorage::issueSerial())
74{
75 mTexture = NULL;
76 // if the width or height is not positive this should be treated as an incomplete texture
77 // we handle that here by skipping the d3d texture creation
78 if (width > 0 && height > 0)
79 {
80 IDirect3DDevice9 *device = getDisplay()->getRenderer()->getDevice(); // D3D9_REPLACE
81 MakeValidSize(false, dx::IsCompressedFormat(format), &width, &height, &mLodOffset);
82 HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(), format, getPool(), &mTexture, NULL);
83
84 if (FAILED(result))
85 {
86 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
87 error(GL_OUT_OF_MEMORY);
88 }
89 }
90}
91
92TextureStorage2D::~TextureStorage2D()
93{
94 if (mTexture)
95 {
96 mTexture->Release();
97 }
98}
99
100// Increments refcount on surface.
101// caller must Release() the returned surface
102IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty)
103{
104 IDirect3DSurface9 *surface = NULL;
105
106 if (mTexture)
107 {
108 HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
109 ASSERT(SUCCEEDED(result));
110
111 // With managed textures the driver needs to be informed of updates to the lower mipmap levels
112 if (level != 0 && isManaged() && dirty)
113 {
114 mTexture->AddDirtyRect(NULL);
115 }
116 }
117
118 return surface;
119}
120
121IDirect3DBaseTexture9 *TextureStorage2D::getBaseTexture() const
122{
123 return mTexture;
124}
125
126unsigned int TextureStorage2D::getRenderTargetSerial(GLenum target) const
127{
128 return mRenderTargetSerial;
129}
130
131TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size)
132 : TextureStorage(usage), mFirstRenderTargetSerial(RenderbufferStorage::issueCubeSerials())
133{
134 mTexture = NULL;
135 // if the size is not positive this should be treated as an incomplete texture
136 // we handle that here by skipping the d3d texture creation
137 if (size > 0)
138 {
139 IDirect3DDevice9 *device = getDisplay()->getRenderer()->getDevice(); // D3D9_REPLACE
140 int height = size;
141 MakeValidSize(false, dx::IsCompressedFormat(format), &size, &height, &mLodOffset);
142 HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(), format, getPool(), &mTexture, NULL);
143
144 if (FAILED(result))
145 {
146 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
147 error(GL_OUT_OF_MEMORY);
148 }
149 }
150}
151
152TextureStorageCubeMap::~TextureStorageCubeMap()
153{
154 if (mTexture)
155 {
156 mTexture->Release();
157 }
158}
159
160// Increments refcount on surface.
161// caller must Release() the returned surface
162IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
163{
164 IDirect3DSurface9 *surface = NULL;
165
166 if (mTexture)
167 {
168 D3DCUBEMAP_FACES face = es2dx::ConvertCubeFace(faceTarget);
169 HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
170 ASSERT(SUCCEEDED(result));
171
172 // With managed textures the driver needs to be informed of updates to the lower mipmap levels
173 if (level != 0 && isManaged() && dirty)
174 {
175 mTexture->AddDirtyRect(face, NULL);
176 }
177 }
178
179 return surface;
180}
181
182IDirect3DBaseTexture9 *TextureStorageCubeMap::getBaseTexture() const
183{
184 return mTexture;
185}
186
187unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const
188{
189 return mFirstRenderTargetSerial + TextureCubeMap::faceIndex(target);
190}
191
192}