blob: a3a3ebf5f330028aa65ad219ecc64e263e468c86 [file] [log] [blame]
daniel@transgaming.com4834ee22013-01-11 04:06:16 +00001//
2// Copyright (c) 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// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
8// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
9
10#include "libGLESv2/renderer/TextureStorage11.h"
11
12#include "libGLESv2/renderer/Renderer11.h"
13#include "libGLESv2/renderer/RenderTarget11.h"
14#include "libGLESv2/renderer/SwapChain11.h"
15#include "libGLESv2/renderer/renderer11_utils.h"
16
17#include "libGLESv2/main.h"
18
19namespace rx
20{
21
22TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
23 : mBindFlags(bindFlags),
daniel@transgaming.comb1154552013-01-11 04:11:02 +000024 mLodOffset(0),
25 mMipLevels(0)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000026{
27 mRenderer = Renderer11::makeRenderer11(renderer);
28}
29
30TextureStorage11::~TextureStorage11()
31{
daniel@transgaming.com1e1b5e92013-01-11 04:11:27 +000032}
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000033
34TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
35{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +000036 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000037 return static_cast<TextureStorage11*>(storage);
38}
39
40DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable)
41{
42 UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
43
44 if (format == DXGI_FORMAT_D24_UNORM_S8_UINT)
45 {
46 bindFlags |= D3D11_BIND_DEPTH_STENCIL;
47 }
48 else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
49 {
50 bindFlags |= D3D11_BIND_RENDER_TARGET;
51 }
52 return bindFlags;
53}
54
55bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format)
56{
57 switch(format)
58 {
59 case DXGI_FORMAT_R8G8B8A8_UNORM:
60 case DXGI_FORMAT_A8_UNORM:
61 case DXGI_FORMAT_R32G32B32A32_FLOAT:
62 case DXGI_FORMAT_R32G32B32_FLOAT:
63 case DXGI_FORMAT_R16G16B16A16_FLOAT:
64 case DXGI_FORMAT_B8G8R8A8_UNORM:
65 case DXGI_FORMAT_R8_UNORM:
66 case DXGI_FORMAT_R8G8_UNORM:
67 case DXGI_FORMAT_R16_FLOAT:
68 case DXGI_FORMAT_R16G16_FLOAT:
69 return true;
70 case DXGI_FORMAT_BC1_UNORM:
71 case DXGI_FORMAT_BC2_UNORM:
72 case DXGI_FORMAT_BC3_UNORM:
73 return false;
74 default:
75 UNREACHABLE();
76 return false;
77 }
78}
79
80UINT TextureStorage11::getBindFlags() const
81{
82 return mBindFlags;
83}
84
85int TextureStorage11::getLodOffset() const
86{
87 return mLodOffset;
88}
89
90bool TextureStorage11::isRenderTarget() const
91{
92 return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
93}
94
95bool TextureStorage11::isManaged() const
96{
97 return false;
98}
99
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000100int TextureStorage11::levelCount()
101{
102 int levels = 0;
103 if (getBaseTexture())
104 {
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000105 levels = mMipLevels - getLodOffset();
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000106 }
107 return levels;
108}
109
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000110UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex)
111{
112 UINT index = 0;
113 if (getBaseTexture())
114 {
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000115 index = D3D11CalcSubresource(level, faceIndex, mMipLevels);
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000116 }
117 return index;
118}
119
120bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, int level, int face, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
121{
122 if (srcTexture)
123 {
124 D3D11_BOX srcBox;
125 srcBox.left = xoffset;
126 srcBox.top = yoffset;
127 srcBox.right = xoffset + width;
128 srcBox.bottom = yoffset + height;
129 srcBox.front = 0;
130 srcBox.back = 1;
131
132 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
133
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000134 ASSERT(getBaseTexture());
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000135 context->CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level, face), xoffset, yoffset, 0, srcTexture, 0, &srcBox);
136 return true;
137 }
138
139 return false;
140}
141
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000142void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
143{
144 if (source && dest)
145 {
146 ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
147 ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
148
149 if (sourceSRV && destRTV)
150 {
151 gl::Rectangle sourceArea;
152 sourceArea.x = 0;
153 sourceArea.y = 0;
154 sourceArea.width = source->getWidth();
155 sourceArea.height = source->getHeight();
156
157 gl::Rectangle destArea;
158 destArea.x = 0;
159 destArea.y = 0;
160 destArea.width = dest->getWidth();
161 destArea.height = dest->getHeight();
162
163 mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(),
164 destRTV, destArea, dest->getWidth(), dest->getHeight(),
165 GL_RGBA);
166 }
167
168 if (sourceSRV)
169 {
170 sourceSRV->Release();
171 }
172 if (destRTV)
173 {
174 destRTV->Release();
175 }
176 }
177}
178
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000179TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
180 : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
181{
182 ID3D11Texture2D *surfaceTexture = swapchain->getOffscreenTexture();
183 mTexture = surfaceTexture;
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000184 mSRV = NULL;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000185
186 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
187 {
188 mRenderTarget[i] = NULL;
189 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000190
191 D3D11_TEXTURE2D_DESC desc;
192 surfaceTexture->GetDesc(&desc);
193
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000194 mMipLevels = desc.MipLevels;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000195 mTextureFormat = desc.Format;
196 mTextureWidth = desc.Width;
197 mTextureHeight = desc.Height;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000198}
199
200TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
201 : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
202{
203 mTexture = NULL;
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000204 mSRV = NULL;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000205 mTextureWidth = 0;
206 mTextureHeight = 0;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000207 DXGI_FORMAT format = gl_d3d11::ConvertTextureFormat(internalformat);
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000208
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000209 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
210 {
211 mRenderTarget[i] = NULL;
212 }
213
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000214 // if the width or height is not positive this should be treated as an incomplete texture
215 // we handle that here by skipping the d3d texture creation
216 if (width > 0 && height > 0)
217 {
218 // adjust size if needed for compressed textures
219 gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
220
221 ID3D11Device *device = mRenderer->getDevice();
222
223 D3D11_TEXTURE2D_DESC desc;
224 desc.Width = width; // Compressed texture size constraints?
225 desc.Height = height;
226 desc.MipLevels = levels + mLodOffset;
227 desc.ArraySize = 1;
228 desc.Format = format;
229 desc.SampleDesc.Count = 1;
230 desc.SampleDesc.Quality = 0;
231 desc.Usage = D3D11_USAGE_DEFAULT;
232 desc.BindFlags = getBindFlags();
233 desc.CPUAccessFlags = 0;
234 desc.MiscFlags = 0;
235
236 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
237
238 if (FAILED(result))
239 {
240 ASSERT(result == E_OUTOFMEMORY);
241 ERR("Creating image failed.");
242 error(GL_OUT_OF_MEMORY);
243 }
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000244 else
245 {
246 mTexture->GetDesc(&desc);
247 mMipLevels = desc.MipLevels;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000248 mTextureFormat = desc.Format;
249 mTextureWidth = desc.Width;
250 mTextureHeight = desc.Height;
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000251 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000252 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000253}
254
255TextureStorage11_2D::~TextureStorage11_2D()
256{
257 if (mTexture)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000258 {
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000259 mTexture->Release();
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000260 mTexture = NULL;
261 }
daniel@transgaming.com1e1b5e92013-01-11 04:11:27 +0000262
263 if (mSRV)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000264 {
daniel@transgaming.com1e1b5e92013-01-11 04:11:27 +0000265 mSRV->Release();
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000266 mSRV = NULL;
267 }
268
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000269 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000270 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000271 delete mRenderTarget[i];
272 mRenderTarget[i] = NULL;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000273 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000274}
275
276TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
277{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000278 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000279 return static_cast<TextureStorage11_2D*>(storage);
280}
281
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000282RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000283{
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000284 if (level >= 0 && level < static_cast<int>(mMipLevels))
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000285 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000286 if (!mRenderTarget[level])
287 {
288 ID3D11Device *device = mRenderer->getDevice();
289 HRESULT result;
290
291 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
292 rtvDesc.Format = mTextureFormat;
293 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
294 rtvDesc.Texture2D.MipSlice = level;
295
296 ID3D11RenderTargetView *rtv;
297 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
298
299 if (result == E_OUTOFMEMORY)
300 {
301 return error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
302 }
303 ASSERT(SUCCEEDED(result));
304
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000305 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
306 srvDesc.Format = mTextureFormat;
307 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
308 srvDesc.Texture2D.MostDetailedMip = level;
309 srvDesc.Texture2D.MipLevels = 1;
310
311 ID3D11ShaderResourceView *srv;
312 result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
313
314 if (result == E_OUTOFMEMORY)
315 {
316 rtv->Release();
317 return error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
318 }
319 ASSERT(SUCCEEDED(result));
320
321 mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, srv,
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000322 std::max(mTextureWidth >> level, 1U),
323 std::max(mTextureHeight >> level, 1U));
324 }
325
326 return mRenderTarget[level];
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000327 }
328 else
329 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000330 return NULL;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000331 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000332}
333
334ID3D11Texture2D *TextureStorage11_2D::getBaseTexture() const
335{
336 return mTexture;
337}
338
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000339ID3D11ShaderResourceView *TextureStorage11_2D::getSRV()
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000340{
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000341 if (!mSRV)
342 {
343 ID3D11Device *device = mRenderer->getDevice();
344
345 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
346 srvDesc.Format = mTextureFormat;
347 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
348 srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
349 srvDesc.Texture2D.MostDetailedMip = 0;
350
351 HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV);
352
353 if (result == E_OUTOFMEMORY)
354 {
355 return error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL));
356 }
357 ASSERT(SUCCEEDED(result));
358 }
359
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000360 return mSRV;
361}
362
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000363void TextureStorage11_2D::generateMipmap(int level)
364{
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000365 RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
366 RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
367
368 generateMipmapLayer(source, dest);
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000369}
370
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000371TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
372 : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
373{
374 mTexture = NULL;
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000375 mSRV = NULL;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000376 mTextureWidth = 0;
377 mTextureHeight = 0;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000378
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000379 for (unsigned int i = 0; i < 6; i++)
daniel@transgaming.com5cdd0582013-01-11 04:07:35 +0000380 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000381 for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
382 {
383 mRenderTarget[i][j] = NULL;
384 }
daniel@transgaming.com5cdd0582013-01-11 04:07:35 +0000385 }
386
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000387 DXGI_FORMAT format = gl_d3d11::ConvertTextureFormat(internalformat);
388 // if the size is not positive this should be treated as an incomplete texture
389 // we handle that here by skipping the d3d texture creation
390 if (size > 0)
391 {
392 // adjust size if needed for compressed textures
393 int height = size;
394 gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
395
396 ID3D11Device *device = mRenderer->getDevice();
397
398 D3D11_TEXTURE2D_DESC desc;
399 desc.Width = size;
400 desc.Height = size;
401 desc.MipLevels = levels + mLodOffset;
402 desc.ArraySize = 6;
403 desc.Format = format;
404 desc.SampleDesc.Count = 1;
405 desc.SampleDesc.Quality = 0;
406 desc.Usage = D3D11_USAGE_DEFAULT;
407 desc.BindFlags = getBindFlags();
408 desc.CPUAccessFlags = 0;
409 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
410
411 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
412
413 if (FAILED(result))
414 {
415 ASSERT(result == E_OUTOFMEMORY);
416 ERR("Creating image failed.");
417 error(GL_OUT_OF_MEMORY);
418 }
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000419 else
420 {
421 mTexture->GetDesc(&desc);
422 mMipLevels = desc.MipLevels;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000423 mTextureFormat = desc.Format;
424 mTextureWidth = desc.Width;
425 mTextureHeight = desc.Height;
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000426 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000427 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000428}
429
430TextureStorage11_Cube::~TextureStorage11_Cube()
431{
432 if (mTexture)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000433 {
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000434 mTexture->Release();
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000435 mTexture = NULL;
436 }
daniel@transgaming.com1e1b5e92013-01-11 04:11:27 +0000437
438 if (mSRV)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000439 {
daniel@transgaming.com1e1b5e92013-01-11 04:11:27 +0000440 mSRV->Release();
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000441 mSRV = NULL;
442 }
443
444 for (unsigned int i = 0; i < 6; i++)
445 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000446 for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000447 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000448 delete mRenderTarget[i][j];
449 mRenderTarget[i][j] = NULL;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000450 }
451 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000452}
453
454TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
455{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000456 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000457 return static_cast<TextureStorage11_Cube*>(storage);
458}
459
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000460RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level)
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000461{
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000462 unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget);
463 if (level >= 0 && level < static_cast<int>(mMipLevels))
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000464 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000465 if (!mRenderTarget[faceIdx][level])
466 {
467 ID3D11Device *device = mRenderer->getDevice();
468 HRESULT result;
469
470 if (getBindFlags() & D3D11_BIND_RENDER_TARGET)
471 {
472 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
473 rtvDesc.Format = mTextureFormat;
474 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
475 rtvDesc.Texture2DArray.MipSlice = level;
476 rtvDesc.Texture2DArray.FirstArraySlice = faceIdx;
477 rtvDesc.Texture2DArray.ArraySize = 1;
478
479 ID3D11RenderTargetView *rtv;
480 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
481
482 if (result == E_OUTOFMEMORY)
483 {
484 return error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
485 }
486 ASSERT(SUCCEEDED(result));
487
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000488 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
489 srvDesc.Format = mTextureFormat;
490 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
491 srvDesc.Texture2DArray.MostDetailedMip = level;
492 srvDesc.Texture2DArray.MipLevels = 1;
493 srvDesc.Texture2DArray.FirstArraySlice = faceIdx;
494 srvDesc.Texture2DArray.ArraySize = 1;
495
496 ID3D11ShaderResourceView *srv;
497 result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
498
499 if (result == E_OUTOFMEMORY)
500 {
501 rtv->Release();
502 return error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
503 }
504 ASSERT(SUCCEEDED(result));
505
506 mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, srv,
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000507 std::max(mTextureWidth >> level, 1U),
508 std::max(mTextureHeight >> level, 1U));
509 }
510 else if (getBindFlags() & D3D11_BIND_DEPTH_STENCIL)
511 {
512 // TODO
513 UNIMPLEMENTED();
514 }
515 else UNREACHABLE();
516 }
517
518 return mRenderTarget[faceIdx][level];
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000519 }
520 else
521 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000522 return NULL;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000523 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000524}
525
526ID3D11Texture2D *TextureStorage11_Cube::getBaseTexture() const
527{
528 return mTexture;
529}
530
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000531ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV()
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000532{
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000533 if (!mSRV)
534 {
535 ID3D11Device *device = mRenderer->getDevice();
536
537 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
538 srvDesc.Format = mTextureFormat;
539 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
540 srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
541 srvDesc.TextureCube.MostDetailedMip = 0;
542
543 HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV);
544
545 if (result == E_OUTOFMEMORY)
546 {
547 return error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL));
548 }
549 ASSERT(SUCCEEDED(result));
550 }
551
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000552 return mSRV;
553}
554
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000555void TextureStorage11_Cube::generateMipmap(int face, int level)
556{
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000557 RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1));
558 RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level));
559
560 generateMipmapLayer(source, dest);
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000561}
562
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000563}