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.
7 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
8 // retained by Renderbuffers.
10 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
11 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
12 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
13 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
14 #include "libGLESv2/main.h"
19 static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
21 ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
24 D3D11_TEXTURE1D_DESC texDesc;
25 texture1D->GetDesc(&texDesc);
26 SafeRelease(texture1D);
28 *mipLevels = texDesc.MipLevels;
34 ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
37 D3D11_TEXTURE2D_DESC texDesc;
38 texture2D->GetDesc(&texDesc);
39 SafeRelease(texture2D);
41 *mipLevels = texDesc.MipLevels;
42 *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
47 ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
50 D3D11_TEXTURE3D_DESC texDesc;
51 texture3D->GetDesc(&texDesc);
52 SafeRelease(texture3D);
54 *mipLevels = texDesc.MipLevels;
63 static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
65 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
66 view->GetDesc(&rtvDesc);
68 unsigned int mipSlice = 0;
69 unsigned int arraySlice = 0;
71 switch (rtvDesc.ViewDimension)
73 case D3D11_RTV_DIMENSION_TEXTURE1D:
74 mipSlice = rtvDesc.Texture1D.MipSlice;
78 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
79 mipSlice = rtvDesc.Texture1DArray.MipSlice;
80 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
83 case D3D11_RTV_DIMENSION_TEXTURE2D:
84 mipSlice = rtvDesc.Texture2D.MipSlice;
88 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
89 mipSlice = rtvDesc.Texture2DArray.MipSlice;
90 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
93 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
98 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
100 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
103 case D3D11_RTV_DIMENSION_TEXTURE3D:
104 mipSlice = rtvDesc.Texture3D.MipSlice;
108 case D3D11_RTV_DIMENSION_UNKNOWN:
109 case D3D11_RTV_DIMENSION_BUFFER:
118 unsigned int mipLevels, samples;
119 getTextureProperties(resource, &mipLevels, &samples);
121 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
124 static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
126 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
127 view->GetDesc(&dsvDesc);
129 unsigned int mipSlice = 0;
130 unsigned int arraySlice = 0;
132 switch (dsvDesc.ViewDimension)
134 case D3D11_DSV_DIMENSION_TEXTURE1D:
135 mipSlice = dsvDesc.Texture1D.MipSlice;
139 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
140 mipSlice = dsvDesc.Texture1DArray.MipSlice;
141 arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
144 case D3D11_DSV_DIMENSION_TEXTURE2D:
145 mipSlice = dsvDesc.Texture2D.MipSlice;
149 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
150 mipSlice = dsvDesc.Texture2DArray.MipSlice;
151 arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
154 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
159 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
161 arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
164 case D3D11_DSV_DIMENSION_UNKNOWN:
173 unsigned int mipLevels, samples;
174 getTextureProperties(resource, &mipLevels, &samples);
176 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
179 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource,
180 ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
182 mRenderer = Renderer11::makeRenderer11(renderer);
193 mRenderTarget->AddRef();
196 mDepthStencil = NULL;
198 mShaderResource = srv;
201 mShaderResource->AddRef();
204 mSubresourceIndex = 0;
206 if (mRenderTarget && mTexture)
208 D3D11_RENDER_TARGET_VIEW_DESC desc;
209 mRenderTarget->GetDesc(&desc);
211 unsigned int mipLevels, samples;
212 getTextureProperties(mTexture, &mipLevels, &samples);
214 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
220 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
221 mInternalFormat = dxgiFormatInfo.internalFormat;
222 mActualFormat = dxgiFormatInfo.internalFormat;
226 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
227 ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
229 mRenderer = Renderer11::makeRenderer11(renderer);
237 mRenderTarget = NULL;
242 mDepthStencil->AddRef();
245 mShaderResource = srv;
248 mShaderResource->AddRef();
251 mSubresourceIndex = 0;
253 if (mDepthStencil && mTexture)
255 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
256 mDepthStencil->GetDesc(&desc);
258 unsigned int mipLevels, samples;
259 getTextureProperties(mTexture, &mipLevels, &samples);
261 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
267 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
268 mInternalFormat = dxgiFormatInfo.internalFormat;
269 mActualFormat = dxgiFormatInfo.internalFormat;
273 RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
275 mRenderer = Renderer11::makeRenderer11(renderer);
277 mRenderTarget = NULL;
278 mDepthStencil = NULL;
279 mShaderResource = NULL;
281 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
282 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
284 const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
285 GLuint supportedSamples = textureCaps.getNearestSamples(samples);
287 if (width > 0 && height > 0)
289 // Create texture resource
290 D3D11_TEXTURE2D_DESC desc;
292 desc.Height = height;
295 desc.Format = formatInfo.texFormat;
296 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
297 desc.SampleDesc.Quality = 0;
298 desc.Usage = D3D11_USAGE_DEFAULT;
299 desc.CPUAccessFlags = 0;
302 // If a rendertarget or depthstencil format exists for this texture format,
303 // we'll flag it to allow binding that way. Shader resource views are a little
305 bool bindRTV = false, bindDSV = false, bindSRV = false;
306 bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
307 bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
308 if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
310 // Multisample targets flagged for binding as depth stencil cannot also be
311 // flagged for binding as SRV, so make certain not to add the SRV flag for
313 bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
316 desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
317 (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
318 (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
320 ID3D11Device *device = mRenderer->getDevice();
321 ID3D11Texture2D *texture = NULL;
322 HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
325 if (result == E_OUTOFMEMORY)
327 gl::error(GL_OUT_OF_MEMORY);
330 ASSERT(SUCCEEDED(result));
334 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
335 srvDesc.Format = formatInfo.srvFormat;
336 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
337 srvDesc.Texture2D.MostDetailedMip = 0;
338 srvDesc.Texture2D.MipLevels = 1;
339 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
341 if (result == E_OUTOFMEMORY)
343 SafeRelease(mTexture);
344 gl::error(GL_OUT_OF_MEMORY);
347 ASSERT(SUCCEEDED(result));
352 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
353 dsvDesc.Format = formatInfo.dsvFormat;
354 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
355 dsvDesc.Texture2D.MipSlice = 0;
357 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
359 if (result == E_OUTOFMEMORY)
361 SafeRelease(mTexture);
362 SafeRelease(mShaderResource);
363 gl::error(GL_OUT_OF_MEMORY);
366 ASSERT(SUCCEEDED(result));
371 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
372 rtvDesc.Format = formatInfo.rtvFormat;
373 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
374 rtvDesc.Texture2D.MipSlice = 0;
375 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
377 if (result == E_OUTOFMEMORY)
379 SafeRelease(mTexture);
380 SafeRelease(mShaderResource);
381 SafeRelease(mDepthStencil);
382 gl::error(GL_OUT_OF_MEMORY);
385 ASSERT(SUCCEEDED(result));
387 if (formatInfo.dataInitializerFunction != NULL)
389 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
391 const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
392 context->ClearRenderTargetView(mRenderTarget, clearValues);
401 mInternalFormat = internalFormat;
402 mSamples = supportedSamples;
403 mActualFormat = dxgiFormatInfo.internalFormat;
404 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
407 RenderTarget11::~RenderTarget11()
409 SafeRelease(mTexture);
410 SafeRelease(mRenderTarget);
411 SafeRelease(mDepthStencil);
412 SafeRelease(mShaderResource);
415 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
417 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
418 return static_cast<rx::RenderTarget11*>(target);
421 void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
426 ID3D11Resource *RenderTarget11::getTexture() const
431 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
433 return mRenderTarget;
436 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
438 return mDepthStencil;
441 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
443 return mShaderResource;
446 unsigned int RenderTarget11::getSubresourceIndex() const
448 return mSubresourceIndex;