1 #include "precompiled.h"
3 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
8 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
9 // retained by Renderbuffers.
11 #include "libGLESv2/renderer/d3d11/RenderTarget11.h"
12 #include "libGLESv2/renderer/d3d11/Renderer11.h"
14 #include "libGLESv2/renderer/d3d11/renderer11_utils.h"
15 #include "libGLESv2/renderer/d3d11/formatutils11.h"
16 #include "libGLESv2/main.h"
21 static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
23 ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
26 D3D11_TEXTURE1D_DESC texDesc;
27 texture1D->GetDesc(&texDesc);
28 SafeRelease(texture1D);
30 *mipLevels = texDesc.MipLevels;
36 ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
39 D3D11_TEXTURE2D_DESC texDesc;
40 texture2D->GetDesc(&texDesc);
41 SafeRelease(texture2D);
43 *mipLevels = texDesc.MipLevels;
44 *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
49 ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
52 D3D11_TEXTURE3D_DESC texDesc;
53 texture3D->GetDesc(&texDesc);
54 SafeRelease(texture3D);
56 *mipLevels = texDesc.MipLevels;
65 static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
67 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
68 view->GetDesc(&rtvDesc);
70 unsigned int mipSlice = 0;
71 unsigned int arraySlice = 0;
73 switch (rtvDesc.ViewDimension)
75 case D3D11_RTV_DIMENSION_TEXTURE1D:
76 mipSlice = rtvDesc.Texture1D.MipSlice;
80 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
81 mipSlice = rtvDesc.Texture1DArray.MipSlice;
82 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
85 case D3D11_RTV_DIMENSION_TEXTURE2D:
86 mipSlice = rtvDesc.Texture2D.MipSlice;
90 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
91 mipSlice = rtvDesc.Texture2DArray.MipSlice;
92 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
95 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
100 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
102 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
105 case D3D11_RTV_DIMENSION_TEXTURE3D:
106 mipSlice = rtvDesc.Texture3D.MipSlice;
110 case D3D11_RTV_DIMENSION_UNKNOWN:
111 case D3D11_RTV_DIMENSION_BUFFER:
120 unsigned int mipLevels, samples;
121 getTextureProperties(resource, &mipLevels, &samples);
123 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
126 static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
128 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
129 view->GetDesc(&dsvDesc);
131 unsigned int mipSlice = 0;
132 unsigned int arraySlice = 0;
134 switch (dsvDesc.ViewDimension)
136 case D3D11_DSV_DIMENSION_TEXTURE1D:
137 mipSlice = dsvDesc.Texture1D.MipSlice;
141 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
142 mipSlice = dsvDesc.Texture1DArray.MipSlice;
143 arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
146 case D3D11_DSV_DIMENSION_TEXTURE2D:
147 mipSlice = dsvDesc.Texture2D.MipSlice;
151 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
152 mipSlice = dsvDesc.Texture2DArray.MipSlice;
153 arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
156 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
161 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
163 arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
166 case D3D11_DSV_DIMENSION_UNKNOWN:
175 unsigned int mipLevels, samples;
176 getTextureProperties(resource, &mipLevels, &samples);
178 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
181 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource,
182 ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
184 mRenderer = Renderer11::makeRenderer11(renderer);
195 mRenderTarget->AddRef();
198 mDepthStencil = NULL;
200 mShaderResource = srv;
203 mShaderResource->AddRef();
206 mSubresourceIndex = 0;
208 if (mRenderTarget && mTexture)
210 D3D11_RENDER_TARGET_VIEW_DESC desc;
211 mRenderTarget->GetDesc(&desc);
213 unsigned int mipLevels, samples;
214 getTextureProperties(mTexture, &mipLevels, &samples);
216 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
222 mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
223 mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
227 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
228 ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
230 mRenderer = Renderer11::makeRenderer11(renderer);
238 mRenderTarget = NULL;
243 mDepthStencil->AddRef();
246 mShaderResource = srv;
249 mShaderResource->AddRef();
252 mSubresourceIndex = 0;
254 if (mDepthStencil && mTexture)
256 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
257 mDepthStencil->GetDesc(&desc);
259 unsigned int mipLevels, samples;
260 getTextureProperties(mTexture, &mipLevels, &samples);
262 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
268 mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
269 mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
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 GLuint clientVersion = mRenderer->getCurrentClientVersion();
283 DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion);
284 DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat, clientVersion);
285 DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat, clientVersion);
286 DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat, clientVersion);
288 DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat);
289 int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples);
290 if (supportedSamples < 0)
292 gl::error(GL_OUT_OF_MEMORY);
296 if (width > 0 && height > 0)
298 // Create texture resource
299 D3D11_TEXTURE2D_DESC desc;
301 desc.Height = height;
304 desc.Format = texFormat;
305 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
306 desc.SampleDesc.Quality = 0;
307 desc.Usage = D3D11_USAGE_DEFAULT;
308 desc.CPUAccessFlags = 0;
311 // If a rendertarget or depthstencil format exists for this texture format,
312 // we'll flag it to allow binding that way. Shader resource views are a little
314 bool bindRTV = false, bindDSV = false, bindSRV = false;
315 bindRTV = (rtvFormat != DXGI_FORMAT_UNKNOWN);
316 bindDSV = (dsvFormat != DXGI_FORMAT_UNKNOWN);
317 if (srvFormat != DXGI_FORMAT_UNKNOWN)
319 // Multisample targets flagged for binding as depth stencil cannot also be
320 // flagged for binding as SRV, so make certain not to add the SRV flag for
322 bindSRV = !(dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
325 desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
326 (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
327 (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
329 ID3D11Device *device = mRenderer->getDevice();
330 ID3D11Texture2D *texture = NULL;
331 HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
334 if (result == E_OUTOFMEMORY)
336 gl::error(GL_OUT_OF_MEMORY);
339 ASSERT(SUCCEEDED(result));
343 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
344 srvDesc.Format = srvFormat;
345 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
346 srvDesc.Texture2D.MostDetailedMip = 0;
347 srvDesc.Texture2D.MipLevels = 1;
348 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
350 if (result == E_OUTOFMEMORY)
352 SafeRelease(mTexture);
353 gl::error(GL_OUT_OF_MEMORY);
356 ASSERT(SUCCEEDED(result));
361 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
362 dsvDesc.Format = dsvFormat;
363 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
364 dsvDesc.Texture2D.MipSlice = 0;
366 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
368 if (result == E_OUTOFMEMORY)
370 SafeRelease(mTexture);
371 SafeRelease(mShaderResource);
372 gl::error(GL_OUT_OF_MEMORY);
375 ASSERT(SUCCEEDED(result));
380 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
381 rtvDesc.Format = rtvFormat;
382 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
383 rtvDesc.Texture2D.MipSlice = 0;
384 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
386 if (result == E_OUTOFMEMORY)
388 SafeRelease(mTexture);
389 SafeRelease(mShaderResource);
390 SafeRelease(mDepthStencil);
391 gl::error(GL_OUT_OF_MEMORY);
394 ASSERT(SUCCEEDED(result));
396 if (gl_d3d11::RequiresTextureDataInitialization(internalFormat))
398 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
400 const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
401 context->ClearRenderTargetView(mRenderTarget, clearValues);
409 mInternalFormat = internalFormat;
410 mSamples = supportedSamples;
411 mActualFormat = d3d11_gl::GetInternalFormat(texFormat, renderer->getCurrentClientVersion());
412 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
415 RenderTarget11::~RenderTarget11()
417 SafeRelease(mTexture);
418 SafeRelease(mRenderTarget);
419 SafeRelease(mDepthStencil);
420 SafeRelease(mShaderResource);
423 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
425 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
426 return static_cast<rx::RenderTarget11*>(target);
429 void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
434 ID3D11Resource *RenderTarget11::getTexture() const
439 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
441 return mRenderTarget;
444 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
446 return mDepthStencil;
449 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
451 return mShaderResource;
454 unsigned int RenderTarget11::getSubresourceIndex() const
456 return mSubresourceIndex;