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 // RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
9 // pointers retained by renderbuffers.
11 #include "libGLESv2/renderer/d3d9/RenderTarget9.h"
12 #include "libGLESv2/renderer/d3d9/Renderer9.h"
14 #include "libGLESv2/renderer/d3d9/renderer9_utils.h"
15 #include "libGLESv2/renderer/d3d9/formatutils9.h"
16 #include "libGLESv2/main.h"
21 // TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given.
22 RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
24 mRenderer = Renderer9::makeRenderer9(renderer);
25 mRenderTarget = surface;
29 D3DSURFACE_DESC description;
30 mRenderTarget->GetDesc(&description);
32 mWidth = description.Width;
33 mHeight = description.Height;
36 mInternalFormat = d3d9_gl::GetInternalFormat(description.Format);
37 mActualFormat = d3d9_gl::GetInternalFormat(description.Format);
38 mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
42 RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
44 mRenderer = Renderer9::makeRenderer9(renderer);
47 D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat, mRenderer);
48 int supportedSamples = mRenderer->getNearestSupportedSamples(renderFormat, samples);
50 if (supportedSamples == -1)
52 gl::error(GL_OUT_OF_MEMORY);
57 HRESULT result = D3DERR_INVALIDCALL;
59 GLuint clientVersion = mRenderer->getCurrentClientVersion();
61 if (width > 0 && height > 0)
63 IDirect3DDevice9 *device = mRenderer->getDevice();
65 bool requiresInitialization = false;
67 if (gl::GetDepthBits(internalFormat, clientVersion) > 0 ||
68 gl::GetStencilBits(internalFormat, clientVersion) > 0)
70 result = device->CreateDepthStencilSurface(width, height, renderFormat,
71 gl_d3d9::GetMultisampleType(supportedSamples),
72 0, FALSE, &mRenderTarget, NULL);
76 requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat);
78 result = device->CreateRenderTarget(width, height, renderFormat,
79 gl_d3d9::GetMultisampleType(supportedSamples),
80 0, FALSE, &mRenderTarget, NULL);
83 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
85 gl::error(GL_OUT_OF_MEMORY);
90 ASSERT(SUCCEEDED(result));
92 if (requiresInitialization)
94 // This format requires that the data be initialized before the render target can be used
95 // Unfortunately this requires a Get call on the d3d device but it is far better than having
96 // to mark the render target as lockable and copy data to the gpu.
97 IDirect3DSurface9 *prevRenderTarget = NULL;
98 device->GetRenderTarget(0, &prevRenderTarget);
99 device->SetRenderTarget(0, mRenderTarget);
100 device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
101 device->SetRenderTarget(0, prevRenderTarget);
108 mInternalFormat = internalFormat;
109 mSamples = supportedSamples;
110 mActualFormat = d3d9_gl::GetInternalFormat(renderFormat);
113 RenderTarget9::~RenderTarget9()
115 SafeRelease(mRenderTarget);
118 RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
120 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target));
121 return static_cast<rx::RenderTarget9*>(target);
124 void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
129 IDirect3DSurface9 *RenderTarget9::getSurface()
131 // Caller is responsible for releasing the returned surface reference.
132 // TODO: remove the AddRef to match RenderTarget11
135 mRenderTarget->AddRef();
138 return mRenderTarget;