diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 756 |
1 files changed, 397 insertions, 359 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp index d63f9b8582..601cd24b10 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp @@ -26,6 +26,7 @@ #include "libGLESv2/renderer/d3d/ShaderD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" #include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Texture.h" @@ -33,10 +34,12 @@ #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/State.h" #include "libGLESv2/angletypes.h" #include "libEGL/Display.h" +#include "common/features.h" #include "common/utilities.h" #include <sstream> @@ -44,14 +47,6 @@ // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros #define REF_RAST 0 -// The "Debug This Pixel..." feature in PIX often fails when using the -// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 -// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file. -#if !defined(ANGLE_ENABLE_D3D9EX) -// Enables use of the IDirect3D9Ex interface, when available -#define ANGLE_ENABLE_D3D9EX 1 -#endif // !defined(ANGLE_ENABLE_D3D9EX) - #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 #endif @@ -96,8 +91,8 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; -Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay) - : Renderer(display), +Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes) + : RendererD3D(display), mDc(hDc) { mD3d9Module = NULL; @@ -177,8 +172,8 @@ void Renderer9::release() Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer)); - return static_cast<rx::Renderer9*>(renderer); + ASSERT(HAS_DYNAMIC_TYPE(Renderer9*, renderer)); + return static_cast<Renderer9*>(renderer); } EGLint Renderer9::initialize() @@ -202,7 +197,7 @@ EGLint Renderer9::initialize() // Use Direct3D9Ex if available. Among other things, this version is less // inclined to report a lost context, for example when the user switches // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. - if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); @@ -386,10 +381,13 @@ void Renderer9::initializeDevice() mSceneStarted = false; - ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager); + ASSERT(!mBlit); mBlit = new Blit9(this); - mVertexDataManager = new rx::VertexDataManager(this); - mIndexDataManager = new rx::IndexDataManager(this); + mBlit->initialize(); + + ASSERT(!mVertexDataManager && !mIndexDataManager); + mVertexDataManager = new VertexDataManager(this); + mIndexDataManager = new IndexDataManager(this); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() @@ -481,68 +479,92 @@ void Renderer9::endScene() } } -void Renderer9::sync(bool block) +gl::Error Renderer9::sync(bool block) { - HRESULT result; + IDirect3DQuery9* query = NULL; + gl::Error error = allocateEventQuery(&query); + if (error.isError()) + { + return error; + } - IDirect3DQuery9* query = allocateEventQuery(); - if (!query) + HRESULT result = query->Issue(D3DISSUE_END); + if (FAILED(result)) { - return; + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result); } - result = query->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); + // Grab the query data once in blocking and non-blocking case + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + if (FAILED(result)) + { + if (d3d9::isDeviceLostError(result)) + { + notifyDeviceLost(); + } + + freeEventQuery(query); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + } - do + // If blocking, loop until the query completes + while (block && result == S_FALSE) { + // Keep polling, but allow other threads to do something useful first + Sleep(0); + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); - if(block && result == S_FALSE) + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (result == S_FALSE && testDeviceLost(false)) { - // Keep polling, but allow other threads to do something useful first - Sleep(0); - // explicitly check for device loss - // some drivers seem to return S_FALSE even if the device is lost - // instead of D3DERR_DEVICELOST like they should - if (testDeviceLost(false)) + result = D3DERR_DEVICELOST; + } + + if (FAILED(result)) + { + if (d3d9::isDeviceLostError(result)) { - result = D3DERR_DEVICELOST; + notifyDeviceLost(); } + + freeEventQuery(query); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); } + } - while(block && result == S_FALSE); freeEventQuery(query); - if (d3d9::isDeviceLostError(result)) - { - notifyDeviceLost(); - } + return gl::Error(GL_NO_ERROR); } -SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChain *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) { - return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat); + return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); } -IDirect3DQuery9* Renderer9::allocateEventQuery() +gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) { - IDirect3DQuery9 *query = NULL; - if (mEventQueryPool.empty()) { - HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, outQuery); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate event query, result: 0x%X.", result); + } } else { - query = mEventQueryPool.back(); + *outQuery = mEventQueryPool.back(); mEventQueryPool.pop_back(); } - return query; + return gl::Error(GL_NO_ERROR); } void Renderer9::freeEventQuery(IDirect3DQuery9* query) @@ -557,14 +579,14 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query) } } -IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length) +gl::Error Renderer9::createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader) { - return mVertexShaderCache.create(function, length); + return mVertexShaderCache.create(function, length, outShader); } -IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length) +gl::Error Renderer9::createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader) { - return mPixelShaderCache.create(function, length); + return mPixelShaderCache.create(function, length, outShader); } HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer) @@ -604,9 +626,16 @@ QueryImpl *Renderer9::createQuery(GLenum type) return new Query9(this, type); } -FenceImpl *Renderer9::createFence() +FenceNVImpl *Renderer9::createFenceNV() +{ + return new FenceNV9(this); +} + +FenceSyncImpl *Renderer9::createFenceSync() { - return new Fence9(this); + // Renderer9 doesn't support ES 3.0 and its sync objects. + UNREACHABLE(); + return NULL; } TransformFeedbackImpl* Renderer9::createTransformFeedback() @@ -620,12 +649,12 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const return false; } -bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION); } gl::Error Renderer9::generateSwizzle(gl::Texture *texture) @@ -635,7 +664,7 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture) return gl::Error(GL_INVALID_OPERATION); } -gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) { std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; @@ -645,6 +674,10 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl:: int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + DWORD baseLevel = samplerState.baseLevel + textureD3D->getNativeTexture()->getTopLevel(); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); @@ -653,7 +686,7 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl:: gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.baseLevel); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); if (getRendererExtensions().textureFilterAnisotropic) { mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); @@ -684,7 +717,12 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te if (texStorage) { TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage); - d3dTexture = storage9->getBaseTexture(); + + gl::Error error = storage9->getBaseTexture(&d3dTexture); + if (error.isError()) + { + return error; + } } // If we get NULL back from getBaseTexture here, something went wrong // in the texture class and we're unexpectedly missing the d3d texture @@ -751,7 +789,7 @@ gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, +gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) { bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; @@ -1097,13 +1135,9 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) } -gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer) +gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer) { - if (!depthbuffer) - { - ERR("Unexpected null depthbuffer for depth-only FBO."); - return NULL; - } + ASSERT(depthbuffer); GLsizei width = depthbuffer->getWidth(); GLsizei height = depthbuffer->getHeight(); @@ -1116,11 +1150,19 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme mNullColorbufferCache[i].height == height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; - return mNullColorbufferCache[i].buffer; + *outColorBuffer = mNullColorbufferCache[i].buffer; + return gl::Error(GL_NO_ERROR); } } - gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); + gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); + gl::Error error = nullRenderbuffer->setStorage(width, height, GL_NONE, 0); + if (error.isError()) + { + SafeDelete(nullRenderbuffer); + return error; + } + gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer); // add nullbuffer to the cache @@ -1139,40 +1181,40 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme oldest->width = width; oldest->height = height; - return nullbuffer; + *outColorBuffer = nullbuffer; + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) +gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) { // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0); if (!attachment) { - attachment = getNullColorbuffer(framebuffer->getDepthbuffer()); - } - if (!attachment) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO."); + gl::Error error = getNullColorbuffer(framebuffer->getDepthbuffer(), &attachment); + if (error.isError()) + { + return error; + } } + ASSERT(attachment); bool renderTargetChanged = false; unsigned int renderTargetSerial = GetAttachmentSerial(attachment); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device - IDirect3DSurface9 *renderTargetSurface = NULL; - - RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment); - if (renderTarget) + RenderTarget9 *renderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - renderTargetSurface = renderTarget->getSurface(); + return error; } + ASSERT(renderTarget); - if (!renderTargetSurface) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); - } + IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface(); + ASSERT(renderTargetSurface); mDevice->SetRenderTarget(0, renderTargetSurface); SafeRelease(renderTargetSurface); @@ -1204,18 +1246,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) // Apply the depth stencil on the device if (depthStencil) { - IDirect3DSurface9 *depthStencilSurface = NULL; - rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil); - - if (depthStencilRenderTarget) + RenderTarget9 *depthStencilRenderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget); + if (error.isError()) { - depthStencilSurface = depthStencilRenderTarget->getSurface(); + return error; } + ASSERT(depthStencilRenderTarget); - if (!depthStencilSurface) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null."); - } + IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface(); + ASSERT(depthStencilSurface); mDevice->SetDepthStencilSurface(depthStencilSurface); SafeRelease(depthStencilSurface); @@ -1260,17 +1300,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getCurrentProgramBinary(), instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device @@ -1296,7 +1335,7 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element return gl::Error(GL_NO_ERROR); } -void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) +void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) { UNREACHABLE(); } @@ -1373,10 +1412,15 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferImpl *storage = indexBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast<intptr_t>(indices); - indices = static_cast<const GLubyte*>(storage->getData()) + offset; + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + indices = bufferData + offset; } unsigned int startIndex = 0; @@ -1570,9 +1614,17 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid if (elementArrayBuffer) { - BufferImpl *storage = elementArrayBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast<intptr_t>(indices); - indices = static_cast<const GLubyte*>(storage->getData()) + offset; + + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } switch (type) @@ -1662,8 +1714,21 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve ASSERT(!transformFeedbackActive); ASSERT(!rasterizerDiscard); - ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); - ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); + ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation()); + + ShaderExecutable *vertexExe = NULL; + gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe); + if (error.isError()) + { + return error; + } + + ShaderExecutable *pixelExe = NULL; + error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + if (error.isError()) + { + return error; + } IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); @@ -1688,7 +1753,7 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve unsigned int programSerial = programBinary->getSerial(); if (programSerial != mAppliedProgramSerial) { - programBinary->dirtyAllUniforms(); + programD3D->dirtyAllUniforms(); mDxUniformsDirty = true; mAppliedProgramSerial = programSerial; } @@ -1696,10 +1761,8 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) { - const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) { gl::LinkedUniform *targetUniform = uniformArray[uniformIndex]; @@ -1797,7 +1860,7 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) { if (clearParams.colorClearType != GL_FLOAT) { @@ -2219,7 +2282,7 @@ bool Renderer9::isRemovedDeviceResettable() const { bool success = false; -#ifdef ANGLE_ENABLE_D3D9EX +#if ANGLE_D3D9EX == ANGLE_ENABLED IDirect3D9Ex *d3d9Ex = NULL; typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); @@ -2330,82 +2393,6 @@ int Renderer9::getMaxSwapInterval() const return mMaxSwapInterval; } -bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) -{ - bool result = false; - - if (source && dest) - { - TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source); - TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest); - - int levels = source9->getLevelCount(); - for (int i = 0; i < levels; ++i) - { - IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false); - IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false); - - result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - - SafeRelease(srcSurf); - SafeRelease(dstSurf); - - if (!result) - { - return false; - } - } - } - - return result; -} - -bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) -{ - bool result = false; - - if (source && dest) - { - TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source); - TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest); - int levels = source9->getLevelCount(); - for (int f = 0; f < 6; f++) - { - for (int i = 0; i < levels; i++) - { - IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false); - IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true); - - result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - - SafeRelease(srcSurf); - SafeRelease(dstSurf); - - if (!result) - { - return false; - } - } - } - } - - return result; -} - -bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) -{ - // 3D textures are not available in the D3D9 backend. - UNREACHABLE(); - return false; -} - -bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) -{ - // 2D array textures are not supported by the D3D9 backend. - UNREACHABLE(); - return false; -} - D3DPOOL Renderer9::getBufferPool(DWORD usage) const { if (mD3d9Ex != NULL) @@ -2423,8 +2410,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2435,8 +2422,8 @@ bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &s return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); } -bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2447,24 +2434,26 @@ bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); } -bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION); } -bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 2D array textures are not available in the D3D9 backend. UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION); } -bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) +gl::Error Renderer9::blitRect(const gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, + const gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, + bool blitDepth, bool blitStencil, GLenum filter) { ASSERT(filter == GL_NEAREST); @@ -2473,35 +2462,33 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (blitRenderTarget) { gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0); - gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0); - RenderTarget9 *readRenderTarget = NULL; - RenderTarget9 *drawRenderTarget = NULL; - IDirect3DSurface9* readSurface = NULL; - IDirect3DSurface9* drawSurface = NULL; + ASSERT(readBuffer); - if (readBuffer) - { - readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer); - } - if (drawBuffer) + RenderTarget9 *readRenderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + if (error.isError()) { - drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer); + return error; } + ASSERT(readRenderTarget); - if (readRenderTarget) - { - readSurface = readRenderTarget->getSurface(); - } - if (drawRenderTarget) - { - drawSurface = drawRenderTarget->getSurface(); - } + gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0); + ASSERT(drawBuffer); - if (!readSurface || !drawSurface) + RenderTarget9 *drawRenderTarget = NULL; + error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(drawRenderTarget); + + // The getSurface calls do an AddRef so save them until after no errors are possible + IDirect3DSurface9* readSurface = readRenderTarget->getSurface(); + ASSERT(readSurface); + + IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface(); + ASSERT(drawSurface); gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); @@ -2594,43 +2581,40 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (FAILED(result)) { - ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); } } if (blitDepth || blitStencil) { gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer(); - gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); - RenderTarget9 *readDepthStencil = NULL; - RenderTarget9 *drawDepthStencil = NULL; - IDirect3DSurface9* readSurface = NULL; - IDirect3DSurface9* drawSurface = NULL; + ASSERT(readBuffer); - if (readBuffer) - { - readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer); - } - if (drawBuffer) + RenderTarget9 *readDepthStencil = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil); + if (error.isError()) { - drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer); + return error; } + ASSERT(readDepthStencil); - if (readDepthStencil) - { - readSurface = readDepthStencil->getSurface(); - } - if (drawDepthStencil) - { - drawSurface = drawDepthStencil->getSurface(); - } + gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); + ASSERT(drawBuffer); - if (!readSurface || !drawSurface) + RenderTarget9 *drawDepthStencil = NULL; + error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil); + if (error.isError()) { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(drawDepthStencil); + + // The getSurface calls do an AddRef so save them until after no errors are possible + IDirect3DSurface9* readSurface = readDepthStencil->getSurface(); + ASSERT(readDepthStencil); + + IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface(); + ASSERT(drawDepthStencil); HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE); @@ -2639,38 +2623,31 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (FAILED(result)) { - ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); } } - return true; + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, +gl::Error Renderer9::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ASSERT(pack.pixelBuffer.get() == NULL); - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *surface = NULL; gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + ASSERT(colorbuffer); - if (colorbuffer) - { - renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); - } - - if (renderTarget) + RenderTarget9 *renderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) { - surface = renderTarget->getSurface(); + return error; } + ASSERT(renderTarget); - if (!surface) - { - // context must be lost - return gl::Error(GL_NO_ERROR); - } + IDirect3DSurface9 *surface = renderTarget->getSurface(); + ASSERT(surface); D3DSURFACE_DESC desc; surface->GetDesc(&desc); @@ -2825,33 +2802,67 @@ gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, return gl::Error(GL_NO_ERROR); } -RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) +gl::Error Renderer9::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) { SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); - IDirect3DSurface9 *surface = NULL; - if (depth) - { - surface = swapChain9->getDepthStencil(); - } - else + *outRT = new SurfaceRenderTarget9(swapChain9, depth); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) +{ + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); + + const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); + + IDirect3DSurface9 *renderTarget = NULL; + if (width > 0 && height > 0) { - surface = swapChain9->getRenderTarget(); - } + bool requiresInitialization = false; + HRESULT result = D3DERR_INVALIDCALL; + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + { + result = mDevice->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, NULL); + } + else + { + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); + result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, NULL); + } - RenderTarget9 *renderTarget = new RenderTarget9(this, surface); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target, result: 0x%X.", result); + } - return renderTarget; -} + if (requiresInitialization) + { + // This format requires that the data be initialized before the render target can be used + // Unfortunately this requires a Get call on the d3d device but it is far better than having + // to mark the render target as lockable and copy data to the gpu. + IDirect3DSurface9 *prevRenderTarget = NULL; + mDevice->GetRenderTarget(0, &prevRenderTarget); + mDevice->SetRenderTarget(0, renderTarget); + mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); + mDevice->SetRenderTarget(0, prevRenderTarget); + } + } -RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples) -{ - RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples); - return renderTarget; + *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples); + return gl::Error(GL_NO_ERROR); } -ShaderImpl *Renderer9::createShader(GLenum type) +ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type) { - return new ShaderD3D(type, this); + return new ShaderD3D(data, type, this); } ProgramImpl *Renderer9::createProgram() @@ -2864,64 +2875,69 @@ void Renderer9::releaseShaderCompiler() ShaderD3D::releaseCompiler(); } -ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers) +gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable) { // Transform feedback is not supported in ES2 or D3D9 ASSERT(transformFeedbackVaryings.size() == 0); - ShaderExecutable9 *executable = NULL; - switch (type) { - case rx::SHADER_VERTEX: + case SHADER_VERTEX: { - IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length); - if (vshader) + IDirect3DVertexShader9 *vshader = NULL; + gl::Error error = createVertexShader((DWORD*)function, length, &vshader); + if (error.isError()) { - executable = new ShaderExecutable9(function, length, vshader); + return error; } + *outExecutable = new ShaderExecutable9(function, length, vshader); } break; - case rx::SHADER_PIXEL: + case SHADER_PIXEL: { - IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length); - if (pshader) + IDirect3DPixelShader9 *pshader = NULL; + gl::Error error = createPixelShader((DWORD*)function, length, &pshader); + if (error.isError()) { - executable = new ShaderExecutable9(function, length, pshader); + return error; } + *outExecutable = new ShaderExecutable9(function, length, pshader); } break; default: UNREACHABLE(); - break; + return gl::Error(GL_INVALID_OPERATION); } - return executable; + return gl::Error(GL_NO_ERROR); } -ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround) +gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 ASSERT(transformFeedbackVaryings.size() == 0); - const char *profile = NULL; - + const char *profileType = NULL; switch (type) { - case rx::SHADER_VERTEX: - profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0"; + case SHADER_VERTEX: + profileType = "vs"; break; - case rx::SHADER_PIXEL: - profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0"; + case SHADER_PIXEL: + profileType = "ps"; break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } + unsigned int profileMajorVersion = (getMajorShaderModel() >= 3) ? 3 : 2; + unsigned int profileMinorVersion = 0; + std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL; @@ -2942,49 +2958,54 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha #endif flags |= D3DCOMPILE_DEBUG; - - std::string sourcePath = getTempPath(); - std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); - writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. // Try the default flags first and if compilation fails, try some alternatives. - const UINT extraFlags[] = + std::vector<CompileConfig> configs; + configs.push_back(CompileConfig(flags, "default" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control")); + + ID3DBlob *binary = NULL; + std::string debugInfo; + gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo); + if (error.isError()) { - flags, - flags | D3DCOMPILE_AVOID_FLOW_CONTROL, - flags | D3DCOMPILE_PREFER_FLOW_CONTROL - }; + return error; + } - const static char *extraFlagNames[] = + // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL + // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. + if (!binary) { - "default", - "avoid flow control", - "prefer flow control" - }; + *outExectuable = NULL; + return gl::Error(GL_NO_ERROR); + } - int attempts = ArraySize(extraFlags); + error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, + transformFeedbackVaryings, separatedOutputBuffers, outExectuable); - ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); - if (!binary) + SafeRelease(binary); + if (error.isError()) { - return NULL; + return error; } - ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers); - SafeRelease(binary); + if (!debugInfo.empty()) + { + (*outExectuable)->appendDebugInfo(debugInfo); + } - return executable; + return gl::Error(GL_NO_ERROR); } -rx::UniformStorage *Renderer9::createUniformStorage(size_t storageSize) +UniformStorage *Renderer9::createUniformStorage(size_t storageSize) { return new UniformStorage(storageSize); } -bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) +gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) { return mBlit->boxFilter(source, dest); } @@ -3006,41 +3027,40 @@ D3DPOOL Renderer9::getTexturePool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) +gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) { - if (source && dest) - { - HRESULT result = D3DERR_OUTOFVIDEOMEMORY; + ASSERT(source && dest); - if (fromManaged) - { - D3DSURFACE_DESC desc; - source->GetDesc(&desc); + HRESULT result = D3DERR_OUTOFVIDEOMEMORY; - IDirect3DSurface9 *surf = 0; - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + if (fromManaged) + { + D3DSURFACE_DESC desc; + source->GetDesc(&desc); - if (SUCCEEDED(result)) - { - Image9::copyLockableSurfaces(surf, source); - result = mDevice->UpdateSurface(surf, NULL, dest, NULL); - SafeRelease(surf); - } - } - else - { - endScene(); - result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); - } + IDirect3DSurface9 *surf = 0; + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); - if (FAILED(result)) + if (SUCCEEDED(result)) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return false; + Image9::copyLockableSurfaces(surf, source); + result = mDevice->UpdateSurface(surf, NULL, dest, NULL); + SafeRelease(surf); } } + else + { + endScene(); + result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); + } - return true; + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit internal texture, result: 0x%X.", result); + } + + return gl::Error(GL_NO_ERROR); } Image *Renderer9::createImage() @@ -3048,11 +3068,11 @@ Image *Renderer9::createImage() return new Image9(); } -void Renderer9::generateMipmap(Image *dest, Image *src) +gl::Error Renderer9::generateMipmap(Image *dest, Image *src) { Image9 *src9 = Image9::makeImage9(src); Image9 *dst9 = Image9::makeImage9(dest); - Image9::generateMipmap(dst9, src9); + return Image9::generateMipmap(dst9, src9); } TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain) @@ -3099,6 +3119,19 @@ TextureImpl *Renderer9::createTexture(GLenum target) return NULL; } +RenderbufferImpl *Renderer9::createRenderbuffer() +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + return renderbuffer; +} + +RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth) +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + renderbuffer->setStorage(swapChain, depth); + return renderbuffer; +} + bool Renderer9::getLUID(LUID *adapterLuid) const { adapterLuid->HighPart = 0; @@ -3113,7 +3146,7 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; } @@ -3128,4 +3161,9 @@ void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCa d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions); } +Workarounds Renderer9::generateWorkarounds() const +{ + return d3d9::GenerateWorkarounds(); +} + } |