From e12ba07322cd61c5cf50c25ed8d1f08f6b1ff879 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 24 Mar 2016 12:38:18 +0100 Subject: Update ANGLE to chromium/2651 Change-Id: I1cd32b780b1a0b913fab870e155ae1f4f9ac40d7 Reviewed-by: Maurice Kalinowski --- .../src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 1067 +++++++++----------- 1 file changed, 475 insertions(+), 592 deletions(-) (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp') diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index bf1c367693..6bb975b0e4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -8,49 +8,50 @@ #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include +#include + #include "common/utilities.h" +#include "libANGLE/angletypes.h" #include "libANGLE/Buffer.h" #include "libANGLE/Display.h" +#include "libANGLE/features.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Program.h" #include "libANGLE/Renderbuffer.h" -#include "libANGLE/State.h" -#include "libANGLE/Surface.h" -#include "libANGLE/Texture.h" -#include "libANGLE/angletypes.h" -#include "libANGLE/features.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/renderer/d3d/CompilerD3D.h" -#include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/d3d/IndexDataManager.h" -#include "libANGLE/renderer/d3d/ProgramD3D.h" -#include "libANGLE/renderer/d3d/RenderbufferD3D.h" -#include "libANGLE/renderer/d3d/ShaderD3D.h" -#include "libANGLE/renderer/d3d/SurfaceD3D.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/d3d9/Blit9.h" #include "libANGLE/renderer/d3d/d3d9/Buffer9.h" #include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" #include "libANGLE/renderer/d3d/d3d9/Image9.h" #include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" #include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" #include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" #include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" - +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" #include "third_party/trace_event/trace_event.h" -#include -#include #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 @@ -76,12 +77,8 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; -Renderer9::Renderer9(egl::Display *display) - : RendererD3D(display) +Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this) { - // Initialize global annotator - gl::InitializeDebugAnnotations(&mAnnotator); - mD3d9Module = NULL; mD3d9 = NULL; @@ -133,6 +130,10 @@ Renderer9::Renderer9(egl::Display *display) mAppliedVertexShader = NULL; mAppliedPixelShader = NULL; mAppliedProgramSerial = 0; + + initializeDebugAnnotator(); + + mEGLDevice = nullptr; } Renderer9::~Renderer9() @@ -147,8 +148,6 @@ Renderer9::~Renderer9() } release(); - - gl::UninitializeDebugAnnotations(); } void Renderer9::release() @@ -157,6 +156,7 @@ void Renderer9::release() releaseDeviceResources(); + SafeDelete(mEGLDevice); SafeRelease(mDevice); SafeRelease(mDeviceEx); SafeRelease(mD3d9); @@ -173,22 +173,9 @@ void Renderer9::release() mD3d9Module = NULL; } -Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) -{ - ASSERT(HAS_DYNAMIC_TYPE(Renderer9*, renderer)); - return static_cast(renderer); -} - egl::Error Renderer9::initialize() { - if (!mCompiler.initialize()) - { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_COMPILER_ERROR, - "Compiler failed to initialize."); - } - - TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); + TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); if (mD3d9Module == NULL) @@ -204,14 +191,14 @@ egl::Error Renderer9::initialize() // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { - TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); + TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); ASSERT(mD3d9); } else { - TRACE_EVENT0("gpu", "Direct3DCreate9"); + TRACE_EVENT0("gpu.angle", "Direct3DCreate9"); mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } @@ -229,7 +216,7 @@ egl::Error Renderer9::initialize() // Give up on getting device caps after about one second. { - TRACE_EVENT0("gpu", "GetDeviceCaps"); + TRACE_EVENT0("gpu.angle", "GetDeviceCaps"); for (int i = 0; i < 10; ++i) { result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); @@ -273,7 +260,7 @@ egl::Error Renderer9::initialize() } { - TRACE_EVENT0("gpu", "GetAdapterIdentifier"); + TRACE_EVENT0("gpu.angle", "GetAdapterIdentifier"); mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); } @@ -281,7 +268,7 @@ egl::Error Renderer9::initialize() static const TCHAR className[] = TEXT("STATIC"); { - TRACE_EVENT0("gpu", "CreateWindowEx"); + TRACE_EVENT0("gpu.angle", "CreateWindowEx"); mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); } @@ -289,7 +276,7 @@ egl::Error Renderer9::initialize() DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; { - TRACE_EVENT0("gpu", "D3d9_CreateDevice"); + TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) @@ -300,7 +287,7 @@ egl::Error Renderer9::initialize() if (FAILED(result)) { - TRACE_EVENT0("gpu", "D3d9_CreateDevice2"); + TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice2"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); if (FAILED(result)) @@ -313,13 +300,13 @@ egl::Error Renderer9::initialize() if (mD3d9Ex) { - TRACE_EVENT0("gpu", "mDevice_QueryInterface"); + TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface"); result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); ASSERT(SUCCEEDED(result)); } { - TRACE_EVENT0("gpu", "ShaderCache initialize"); + TRACE_EVENT0("gpu.angle", "ShaderCache initialize"); mVertexShaderCache.initialize(mDevice); mPixelShaderCache.initialize(mDevice); } @@ -359,14 +346,11 @@ void Renderer9::initializeDevice() const gl::Caps &rendererCaps = getRendererCaps(); - mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); - - mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); - mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits); - mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits); + mCurVertexTextures.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelTextures.resize(rendererCaps.maxTextureImageUnits); markAllStateDirty(); @@ -379,6 +363,9 @@ void Renderer9::initializeDevice() ASSERT(!mVertexDataManager && !mIndexDataManager); mVertexDataManager = new VertexDataManager(this); mIndexDataManager = new IndexDataManager(this, getRendererClass()); + + // TODO(jmadill): use context caps, and place in common D3D location + mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() @@ -523,6 +510,31 @@ egl::ConfigSet Renderer9::generateConfigs() const return configs; } +void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + if (getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = true; + } + + outExtensions->querySurfacePointer = true; + outExtensions->windowFixedSize = true; + outExtensions->postSubBuffer = true; + outExtensions->createContext = true; + outExtensions->deviceQuery = true; + outExtensions->createContextNoError = true; + + outExtensions->image = true; + outExtensions->imageBase = true; + outExtensions->glTexture2DImage = true; + outExtensions->glRenderbufferImage = true; + + outExtensions->flexibleSurfaceCompatibility = true; +} + void Renderer9::startScene() { if (!mSceneStarted) @@ -612,7 +624,7 @@ gl::Error Renderer9::finish() while (result == S_FALSE) { // Keep polling, but allow other threads to do something useful first - Sleep(0); + ScheduleYield(); result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); @@ -642,9 +654,24 @@ gl::Error Renderer9::finish() return gl::Error(GL_NO_ERROR); } -SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) +{ + return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, + orientation); +} + +CompilerImpl *Renderer9::createCompiler() +{ + return new CompilerD3D(SH_HLSL_3_0_OUTPUT); +} + +void *Renderer9::getD3DDevice() { - return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); + return reinterpret_cast(mDevice); } gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) @@ -716,9 +743,9 @@ BufferImpl *Renderer9::createBuffer() return new Buffer9(this); } -VertexArrayImpl *Renderer9::createVertexArray() +VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArray::Data &data) { - return new VertexArray9(this); + return new VertexArray9(data); } QueryImpl *Renderer9::createQuery(GLenum type) @@ -766,46 +793,52 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture) gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) { - std::vector &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; - std::vector &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; + CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index] + : mCurVertexSamplerStates[index]; - if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) - { - 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 = GetImplAs(texture); - // Make sure to add the level offset for our tiny compressed texture workaround - TextureD3D *textureD3D = GetImplAs(texture); + TextureStorage *storage = nullptr; + gl::Error error = textureD3D->getNativeTexture(&storage); + if (error.isError()) + { + return error; + } - TextureStorage *storage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&storage); - if (error.isError()) - { - return error; - } + // Storage should exist, texture should be complete + ASSERT(storage); - // Storage should exist, texture should be complete - ASSERT(storage); + DWORD baseLevel = texture->getBaseLevel() + storage->getTopLevel(); - DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel(); + if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel || + memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0) + { + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); + D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; - gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); + float lodBias; + gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, &lodBias, + samplerState.maxAnisotropy, baseLevel); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast(lodBias)); if (getRendererExtensions().textureFilterAnisotropic) { mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); } } - forceSetSamplers[index] = false; - appliedSamplers[index] = samplerState; + appliedSampler.forceSet = false; + appliedSampler.samplerState = samplerState; + appliedSampler.baseLevel = baseLevel; return gl::Error(GL_NO_ERROR); } @@ -815,10 +848,9 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; IDirect3DBaseTexture9 *d3dTexture = NULL; - unsigned int serial = 0; bool forceSetTexture = false; - std::vector &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; + std::vector &appliedTextures = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; if (texture) { @@ -834,7 +866,7 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te // Texture should be complete and have a storage ASSERT(texStorage); - TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage); + TextureStorage9 *storage9 = GetAs(texStorage); error = storage9->getBaseTexture(&d3dTexture); if (error.isError()) { @@ -845,372 +877,99 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te // in the texture class and we're unexpectedly missing the d3d texture ASSERT(d3dTexture != NULL); - serial = texture->getTextureSerial(); forceSetTexture = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); } - if (forceSetTexture || appliedSerials[index] != serial) + if (forceSetTexture || appliedTextures[index] != reinterpret_cast(d3dTexture)) { mDevice->SetTexture(d3dSampler, d3dTexture); } - appliedSerials[index] = serial; + appliedTextures[index] = reinterpret_cast(d3dTexture); return gl::Error(GL_NO_ERROR); } gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/, - const GLint /*vertexUniformBuffers*/[], - const GLint /*fragmentUniformBuffers*/[]) + const std::vector &/*vertexUniformBuffers*/, + const std::vector &/*fragmentUniformBuffers*/) { // No effect in ES2/D3D9 return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) +void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) { - bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; - - if (rasterStateChanged) - { - // Set the cull mode - if (rasterState.cullFace) - { - mDevice->SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace)); - } - else - { - mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - } - - if (rasterState.polygonOffsetFill) - { - if (mCurDepthSize > 0) - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&rasterState.polygonOffsetFactor); - - float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast(mCurDepthSize)); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); - } - } - else - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); - } - - mCurRasterState = rasterState; - } - - mForceSetRasterState = false; - - return gl::Error(GL_NO_ERROR); + mStateManager.syncState(state, bitmask); } -gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) { - bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; - bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0; - bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask; - - if (blendStateChanged || blendColorChanged) - { - if (blendState.blend) - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && - blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor)); - } - else - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha))); - } - - mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); - mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); - mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); - - if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || - blendState.destBlendRGB != blendState.destBlendAlpha || - blendState.blendEquationRGB != blendState.blendEquationAlpha) - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); - mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); - mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); - } - else - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); - } - } - else - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - - if (blendState.sampleAlphaToCoverage) - { - FIXME("Sample alpha to coverage is unimplemented."); - } - - gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; + // Applies the render target surface, depth stencil surface, viewport rectangle and + // scissor rectangle to the renderer + const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); + ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); - // Set the color mask - bool zeroColorMaskAllowed = getVendorId() != VENDOR_ID_AMD; - // Apparently some ATI cards have a bug where a draw with a zero color - // write mask can cause later draws to have incorrect results. Instead, - // set a nonzero color write mask but modify the blend state so that no - // drawing is done. - // http://code.google.com/p/angleproject/issues/detail?id=169 - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits > 0 && blendState.colorMaskRed, - formatInfo.greenBits > 0 && blendState.colorMaskGreen, - formatInfo.blueBits > 0 && blendState.colorMaskBlue, - formatInfo.alphaBits > 0 && blendState.colorMaskAlpha); - if (colorMask == 0 && !zeroColorMaskAllowed) - { - // Enable green channel, but set blending so nothing will be drawn. - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); - mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - } - else - { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); - } - - mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE); - - mCurBlendState = blendState; - mCurBlendColor = blendColor; - } - - if (sampleMaskChanged) + gl::Error error = applyRenderTarget(framebufferObject); + if (error.isError()) { - // Set the multisample mask - mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast(sampleMask)); - - mCurSampleMask = sampleMask; + return error; } - mForceSetBlendState = false; + // Setting viewport state + setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), + data.state->getFarPlane(), drawMode, data.state->getRasterizerState().frontFace, + false); - return gl::Error(GL_NO_ERROR); -} + // Setting scissors state + setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); -gl::Error Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) -{ - bool depthStencilStateChanged = mForceSetDepthStencilState || - memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; - bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef || - stencilBackRef != mCurStencilBackRef; - bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW; + // Setting blend, depth stencil, and rasterizer states + int samples = framebufferObject->getSamples(data); + gl::RasterizerState rasterizer = data.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - if (depthStencilStateChanged) - { - if (depthStencilState.depthTest) - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); - mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc)); - } - else - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - } + unsigned int mask = GetBlendSampleMask(data, samples); + error = setBlendDepthRasterStates(data, mask); - mCurDepthStencilState = depthStencilState; - } - - if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged) + if (error.isError()) { - if (depthStencilState.stencilTest && mCurStencilSize > 0) - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); - - // FIXME: Unsupported by D3D9 - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; - - ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask); - ASSERT(stencilRef == stencilBackRef); - ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask); - - // get the maximum size of the stencil ref - unsigned int maxStencil = (1 << mCurStencilSize) - 1; - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilWritemask); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilFunc)); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilRef < (int)maxStencil) ? stencilRef : maxStencil); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilMask); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilBackWritemask); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilBackMask); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass)); - } - else - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE); - - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; - mCurFrontFaceCCW = frontFaceCCW; + return error; } - mForceSetDepthStencilState = false; + mStateManager.resetDirtyBits(); - return gl::Error(GL_NO_ERROR); + return error; } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) { - bool scissorChanged = mForceSetScissor || - memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || - enabled != mScissorEnabled; - - if (scissorChanged) - { - if (enabled) - { - RECT rect; - rect.left = gl::clamp(scissor.x, 0, static_cast(mRenderTargetDesc.width)); - rect.top = gl::clamp(scissor.y, 0, static_cast(mRenderTargetDesc.height)); - rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast(mRenderTargetDesc.width)); - rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast(mRenderTargetDesc.height)); - mDevice->SetScissorRect(&rect); - } - - mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE); + mStateManager.setScissorState(scissor, enabled); +} - mScissorEnabled = enabled; - mCurScissor = scissor; - } +gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode) +{ + int samples = glData.state->getDrawFramebuffer()->getSamples(glData); + gl::RasterizerState rasterizer = glData.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - mForceSetScissor = false; + unsigned int mask = GetBlendSampleMask(glData, samples); + return mStateManager.setBlendDepthRasterStates(*glData.state, mask); } -void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer9::setViewport(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, bool ignoreViewport) { - gl::Rectangle actualViewport = viewport; - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - if (ignoreViewport) - { - actualViewport.x = 0; - actualViewport.y = 0; - actualViewport.width = mRenderTargetDesc.width; - actualViewport.height = mRenderTargetDesc.height; - actualZNear = 0.0f; - actualZFar = 1.0f; - } - - D3DVIEWPORT9 dxViewport; - dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast(mRenderTargetDesc.width)); - dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast(mRenderTargetDesc.height)); - dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast(mRenderTargetDesc.width) - static_cast(dxViewport.X)); - dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast(mRenderTargetDesc.height) - static_cast(dxViewport.Y)); - dxViewport.MinZ = actualZNear; - dxViewport.MaxZ = actualZFar; - - float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); - - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront; - if (viewportChanged) - { - mDevice->SetViewport(&dxViewport); - - mCurViewport = actualViewport; - mCurNear = actualZNear; - mCurFar = actualZFar; - mCurDepthFront = depthFront; - - dx_VertexConstants vc = {0}; - dx_PixelConstants pc = {0}; - - vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width; - vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height; - vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width; - vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height; - - pc.viewCoords[0] = actualViewport.width * 0.5f; - pc.viewCoords[1] = actualViewport.height * 0.5f; - pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); - pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); - - pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; - pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - pc.depthFront[2] = depthFront; - - vc.depthRange[0] = actualZNear; - vc.depthRange[1] = actualZFar; - vc.depthRange[2] = actualZFar - actualZNear; - - pc.depthRange[0] = actualZNear; - pc.depthRange[1] = actualZFar; - pc.depthRange[2] = actualZFar - actualZNear; - - if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0) - { - mVertexConstants = vc; - mDxUniformsDirty = true; - } - - if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0) - { - mPixelConstants = pc; - mDxUniformsDirty = true; - } - } - - mForceSetViewport = false; + mStateManager.setViewportState(caps, viewport, zNear, zFar, drawMode, frontFace, + ignoreViewport); } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) @@ -1258,15 +1017,14 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu { ASSERT(depthbuffer); - GLsizei width = depthbuffer->getWidth(); - GLsizei height = depthbuffer->getHeight(); + const gl::Extents &size = depthbuffer->getSize(); // search cached nullcolorbuffers for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { if (mNullColorbufferCache[i].buffer != NULL && - mNullColorbufferCache[i].width == width && - mNullColorbufferCache[i].height == height) + mNullColorbufferCache[i].width == size.width && + mNullColorbufferCache[i].height == size.height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; *outColorBuffer = mNullColorbufferCache[i].buffer; @@ -1275,14 +1033,14 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu } gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); - gl::Error error = nullRenderbuffer->setStorage(GL_NONE, width, height); + gl::Error error = nullRenderbuffer->setStorage(GL_NONE, size.width, size.height); if (error.isError()) { SafeDelete(nullRenderbuffer); return error; } - gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer); + gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1297,44 +1055,48 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu delete oldest->buffer; oldest->buffer = nullbuffer; oldest->lruCount = ++mMaxNullColorbufferLRU; - oldest->width = width; - oldest->height = height; + oldest->width = size.width; + oldest->height = size.height; *outColorBuffer = nullbuffer; return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer) +gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, + const gl::FramebufferAttachment *depthStencilAttachment) { + const gl::FramebufferAttachment *renderAttachment = colorAttachment; + gl::Error error(GL_NO_ERROR); + // 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. - if (!colorBuffer) + if (renderAttachment == nullptr) { - gl::Error error = getNullColorbuffer(depthStencilBuffer, &colorBuffer); + error = getNullColorbuffer(depthStencilAttachment, &renderAttachment); if (error.isError()) { return error; } } - ASSERT(colorBuffer); + ASSERT(renderAttachment != nullptr); size_t renderTargetWidth = 0; size_t renderTargetHeight = 0; D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN; + RenderTarget9 *renderTarget = nullptr; + error = renderAttachment->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + ASSERT(renderTarget); + bool renderTargetChanged = false; - unsigned int renderTargetSerial = GetAttachmentSerial(colorBuffer); + unsigned int renderTargetSerial = renderTarget->getSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device - RenderTarget9 *renderTarget = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(colorBuffer, &renderTarget); - if (error.isError()) - { - return error; - } - ASSERT(renderTarget); - IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface(); ASSERT(renderTargetSurface); @@ -1349,48 +1111,45 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuf renderTargetChanged = true; } - unsigned int depthStencilSerial = (depthStencilBuffer != nullptr) ? GetAttachmentSerial(depthStencilBuffer) : 0; + RenderTarget9 *depthStencilRenderTarget = nullptr; + unsigned int depthStencilSerial = 0; + + if (depthStencilAttachment != nullptr) + { + error = depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(depthStencilRenderTarget); + + depthStencilSerial = depthStencilRenderTarget->getSerial(); + } + if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized) { unsigned int depthSize = 0; unsigned int stencilSize = 0; // Apply the depth stencil on the device - if (depthStencilBuffer) + if (depthStencilRenderTarget) { - RenderTarget9 *depthStencilRenderTarget = NULL; - gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencilBuffer, &depthStencilRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(depthStencilRenderTarget); - IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface(); ASSERT(depthStencilSurface); mDevice->SetDepthStencilSurface(depthStencilSurface); SafeRelease(depthStencilSurface); - depthSize = depthStencilBuffer->getDepthSize(); - stencilSize = depthStencilBuffer->getStencilSize(); + depthSize = depthStencilAttachment->getDepthSize(); + stencilSize = depthStencilAttachment->getStencilSize(); } else { mDevice->SetDepthStencilSurface(NULL); } - if (!mDepthStencilInitialized || depthSize != mCurDepthSize) - { - mCurDepthSize = depthSize; - mForceSetRasterState = true; - } - - if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) - { - mCurStencilSize = stencilSize; - mForceSetDepthStencilState = true; - } + mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); + mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); mAppliedDepthStencilSerial = depthStencilSerial; mDepthStencilInitialized = true; @@ -1398,13 +1157,9 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuf if (renderTargetChanged || !mRenderTargetDescInitialized) { - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; - - mRenderTargetDesc.width = renderTargetWidth; - mRenderTargetDesc.height = renderTargetHeight; - mRenderTargetDesc.format = renderTargetFormat; + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight); mRenderTargetDescInitialized = true; } @@ -1416,22 +1171,34 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer()); } -gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData * /*indexInfo*/) { - TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getProgram(), instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration(mDevice, mTranslatedAttribCache, state.getProgram(), instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) -{ - gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); +gl::Error Renderer9::applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) +{ + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, + indexInfo, false); if (error.isError()) { return error; @@ -1442,7 +1209,7 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element if (indexInfo->serial != mAppliedIBSerial) { - IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + IndexBuffer9* indexBuffer = GetAs(indexInfo->indexBuffer); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = indexInfo->serial; @@ -1456,7 +1223,10 @@ void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) ASSERT(!state.isTransformFeedbackActiveUnpaused()); } -gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) +gl::Error Renderer9::drawArraysImpl(const gl::Data &data, + GLenum mode, + GLsizei count, + GLsizei instances) { ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); @@ -1477,7 +1247,7 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count if (mAppliedIBSerial != countingIB->getSerial()) { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); + IndexBuffer9 *indexBuffer = GetAs(countingIB->getIndexBuffer()); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = countingIB->getSerial(); @@ -1497,13 +1267,21 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count } } -gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +gl::Error Renderer9::drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei /*instances*/) { startScene(); int minIndex = static_cast(indexInfo.indexRange.start); + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + if (mode == GL_POINTS) { return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); @@ -1514,10 +1292,12 @@ gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const } else { + size_t vertexCount = indexInfo.indexRange.vertexCount(); for (int i = 0; i < mRepeatDraw; i++) { - GLsizei vertexCount = static_cast(indexInfo.indexRange.length()) + 1; - mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); + mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, + static_cast(vertexCount), indexInfo.startIndex, + mPrimitiveCount); } return gl::Error(GL_NO_ERROR); } @@ -1663,7 +1443,7 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi case GL_NONE: // Non-indexed draw for (int i = 0; i < count; i++) { - data[i] = i; + data[i] = static_cast(i); } data[count] = 0; break; @@ -1684,9 +1464,9 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi case GL_UNSIGNED_INT: for (int i = 0; i < count; i++) { - data[i] = static_cast(indices)[i]; + data[i] = static_cast(static_cast(indices)[i]); } - data[count] = static_cast(indices)[0]; + data[count] = static_cast(static_cast(indices)[0]); break; default: UNREACHABLE(); } @@ -1700,7 +1480,7 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi if (mAppliedIBSerial != mLineLoopIB->getSerial()) { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB->getIndexBuffer()); + IndexBuffer9 *indexBuffer = GetAs(mLineLoopIB->getIndexBuffer()); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = mLineLoopIB->getSerial(); @@ -1757,7 +1537,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou // Update the counting index buffer if it is not large enough or has not been created yet. if (count <= 65536) // 16-bit indices { - const unsigned int spaceNeeded = count * sizeof(unsigned short); + const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned short); if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) { @@ -1775,7 +1555,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou unsigned short *data = reinterpret_cast(mappedMemory); for (size_t i = 0; i < count; i++) { - data[i] = i; + data[i] = static_cast(i); } error = mCountingIB->unmapBuffer(); @@ -1787,7 +1567,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou } else if (getRendererExtensions().elementIndexUint) { - const unsigned int spaceNeeded = count * sizeof(unsigned int); + const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned int); if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) { @@ -1803,7 +1583,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou } unsigned int *data = reinterpret_cast(mappedMemory); - for (size_t i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { data[i] = i; } @@ -1824,13 +1604,10 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) { - ASSERT(!transformFeedbackActive); - ASSERT(!rasterizerDiscard); - - ProgramD3D *programD3D = GetImplAs(program); + ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); + const auto &inputLayout = programD3D->getCachedInputLayout(); ShaderExecutableD3D *vertexExe = NULL; gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); @@ -1839,15 +1616,16 @@ gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat i return error; } + const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); if (error.isError()) { return error; } - IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); - IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); + IDirect3DVertexShader9 *vertexShader = (vertexExe ? GetAs(vertexExe)->getVertexShader() : nullptr); + IDirect3DPixelShader9 *pixelShader = (pixelExe ? GetAs(pixelExe)->getPixelShader() : nullptr); if (vertexShader != mAppliedVertexShader) { @@ -1870,68 +1648,63 @@ gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat i if (programSerial != mAppliedProgramSerial) { programD3D->dirtyAllUniforms(); - mDxUniformsDirty = true; + mStateManager.forceSetDXUniformsState(); mAppliedProgramSerial = programSerial; } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) +gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, + GLenum /*drawMode*/, + const std::vector &uniformArray) { - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) + for (const D3DUniform *targetUniform : uniformArray) { - gl::LinkedUniform *targetUniform = uniformArray[uniformIndex]; + if (!targetUniform->dirty) + continue; - if (targetUniform->dirty) - { - GLfloat *f = (GLfloat*)targetUniform->data; - GLint *i = (GLint*)targetUniform->data; + GLfloat *f = (GLfloat *)targetUniform->data; + GLint *i = (GLint *)targetUniform->data; - switch (targetUniform->type) - { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: + switch (targetUniform->type) + { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: break; - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: applyUniformnbv(targetUniform, i); break; - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f); break; - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: applyUniformniv(targetUniform, i); break; - default: + default: UNREACHABLE(); - } } } // Driver uniforms - if (mDxUniformsDirty) - { - mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4])); - mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); - mDxUniformsDirty = false; - } + mStateManager.setShaderConstants(); return gl::Error(GL_NO_ERROR); } -void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v) +void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) { if (targetUniform->isReferencedByFragmentShader()) { @@ -1944,7 +1717,7 @@ void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat } } -void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v) +void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) { ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; @@ -1960,7 +1733,7 @@ void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v) +void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) { ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; @@ -2004,14 +1777,16 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, unsigned int stencilUnmasked = 0x0; if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0) { - RenderTargetD3D *stencilRenderTarget = NULL; - gl::Error error = GetAttachmentRenderTarget(depthStencilBuffer, &stencilRenderTarget); + ASSERT(depthStencilBuffer != nullptr); + + RenderTargetD3D *stencilRenderTarget = nullptr; + gl::Error error = depthStencilBuffer->getRenderTarget(&stencilRenderTarget); if (error.isError()) { return error; } - RenderTarget9 *stencilRenderTarget9 = RenderTarget9::makeRenderTarget9(stencilRenderTarget); + RenderTarget9 *stencilRenderTarget9 = GetAs(stencilRenderTarget); ASSERT(stencilRenderTarget9); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat()); @@ -2025,14 +1800,16 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); if (clearColor) { + ASSERT(colorBuffer != nullptr); + RenderTargetD3D *colorRenderTarget = NULL; - gl::Error error = GetAttachmentRenderTarget(colorBuffer, &colorRenderTarget); + gl::Error error = colorBuffer->getRenderTarget(&colorRenderTarget); if (error.isError()) { return error; } - RenderTarget9 *colorRenderTarget9 = RenderTarget9::makeRenderTarget9(colorRenderTarget); + RenderTarget9 *colorRenderTarget9 = GetAs(colorRenderTarget); ASSERT(colorRenderTarget9); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat()); @@ -2156,14 +1933,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetStreamSourceFreq(i, 1); } + int renderTargetWidth = mStateManager.getRenderTargetWidth(); + int renderTargetHeight = mStateManager.getRenderTargetHeight(); + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges quad[0][0] = -0.5f; - quad[0][1] = mRenderTargetDesc.height - 0.5f; + quad[0][1] = renderTargetHeight - 0.5f; quad[0][2] = 0.0f; quad[0][3] = 1.0f; - quad[1][0] = mRenderTargetDesc.width - 0.5f; - quad[1][1] = mRenderTargetDesc.height - 0.5f; + quad[1][0] = renderTargetWidth - 0.5f; + quad[1][1] = renderTargetHeight - 0.5f; quad[1][2] = 0.0f; quad[1][3] = 1.0f; @@ -2172,7 +1952,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, quad[2][2] = 0.0f; quad[2][3] = 1.0f; - quad[3][0] = mRenderTargetDesc.width - 0.5f; + quad[3][0] = renderTargetWidth - 0.5f; quad[3][1] = -0.5f; quad[3][2] = 0.0f; quad[3][3] = 1.0f; @@ -2221,31 +2001,31 @@ void Renderer9::markAllStateDirty() mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; - mForceSetDepthStencilState = true; - mForceSetRasterState = true; - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; + mStateManager.forceSetRasterState(); + mStateManager.forceSetDepthStencilState(); + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.forceSetViewportState(); - ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size()); - for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++) + ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); + for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) { - mForceSetVertexSamplerStates[i] = true; - mCurVertexTextureSerials[i] = 0; + mCurVertexSamplerStates[i].forceSet = true; + mCurVertexTextures[i] = angle::DirtyPointer; } - ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size()); - for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++) + ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size()); + for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++) { - mForceSetPixelSamplerStates[i] = true; - mCurPixelTextureSerials[i] = 0; + mCurPixelSamplerStates[i].forceSet = true; + mCurPixelTextures[i] = angle::DirtyPointer; } mAppliedIBSerial = 0; mAppliedVertexShader = NULL; mAppliedPixelShader = NULL; mAppliedProgramSerial = 0; - mDxUniformsDirty = true; + mStateManager.forceSetDXUniformsState(); mVertexDeclarationCache.markStateDirty(); } @@ -2458,19 +2238,26 @@ std::string Renderer9::getRendererDescription() const return rendererString.str(); } -GUID Renderer9::getAdapterIdentifier() const +DeviceIdentifier Renderer9::getAdapterIdentifier() const { - return mAdapterIdentifier.DeviceIdentifier; + DeviceIdentifier deviceIdentifier = { 0 }; + deviceIdentifier.VendorId = static_cast(mAdapterIdentifier.VendorId); + deviceIdentifier.DeviceId = static_cast(mAdapterIdentifier.DeviceId); + deviceIdentifier.SubSysId = static_cast(mAdapterIdentifier.SubSysId); + deviceIdentifier.Revision = static_cast(mAdapterIdentifier.Revision); + deviceIdentifier.FeatureLevel = 0; + + return deviceIdentifier; } unsigned int Renderer9::getReservedVertexUniformVectors() const { - return 2; // dx_ViewAdjust and dx_DepthRange. + return d3d9_gl::GetReservedVertexUniformVectors(); } unsigned int Renderer9::getReservedFragmentUniformVectors() const { - return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. + return d3d9_gl::GetReservedFragmentUniformVectors(); } unsigned int Renderer9::getReservedVertexUniformBuffers() const @@ -2489,11 +2276,6 @@ bool Renderer9::getShareHandleSupport() const return (mD3d9Ex != NULL) && !gl::DebugAnnotationsActive(); } -bool Renderer9::getPostSubBufferSupport() const -{ - return true; -} - int Renderer9::getMajorShaderModel() const { return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); @@ -2578,6 +2360,7 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); GLuint supportedSamples = textureCaps.getNearestSamples(samples); + IDirect3DTexture9 *texture = nullptr; IDirect3DSurface9 *renderTarget = NULL; if (width > 0 && height > 0) { @@ -2593,10 +2376,23 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL } else { - requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); - result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &renderTarget, NULL); + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != nullptr); + if (supportedSamples > 0) + { + result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, nullptr); + } + else + { + result = mDevice->CreateTexture( + width, height, 1, D3DUSAGE_RENDERTARGET, d3d9FormatInfo.texFormat, + getTexturePool(D3DUSAGE_RENDERTARGET), &texture, nullptr); + if (!FAILED(result)) + { + result = texture->GetSurfaceLevel(0, &renderTarget); + } + } } if (FAILED(result)) @@ -2618,13 +2414,36 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL } } - *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1, + supportedSamples); return gl::Error(GL_NO_ERROR); } -FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) { - return createFramebuffer(data); + ASSERT(source != nullptr); + + RenderTargetD3D *newRT = nullptr; + gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT); + if (error.isError()) + { + return error; + } + + RenderTarget9 *source9 = GetAs(source); + RenderTarget9 *dest9 = GetAs(newRT); + + HRESULT result = mDevice->StretchRect(source9->getSurface(), nullptr, dest9->getSurface(), + nullptr, D3DTEXF_NONE); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy render target, result: 0x%X.", result); + } + + *outRT = newRT; + return gl::Error(GL_NO_ERROR); } FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) @@ -2632,27 +2451,25 @@ FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) return new Framebuffer9(data, this); } -CompilerImpl *Renderer9::createCompiler(const gl::Data &data) +ShaderImpl *Renderer9::createShader(const gl::Shader::Data &data) { - return new CompilerD3D(data, SH_HLSL9_OUTPUT); + return new ShaderD3D(data); } -ShaderImpl *Renderer9::createShader(GLenum type) +ProgramImpl *Renderer9::createProgram(const gl::Program::Data &data) { - return new ShaderD3D(type); + return new ProgramD3D(data, this); } -ProgramImpl *Renderer9::createProgram() -{ - return new ProgramD3D(this); -} - -gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) +gl::Error Renderer9::loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) { // Transform feedback is not supported in ES2 or D3D9 - ASSERT(transformFeedbackVaryings.size() == 0); + ASSERT(streamOutVaryings.empty()); switch (type) { @@ -2686,13 +2503,16 @@ gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderT return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, +gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, ShaderExecutableD3D **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 - ASSERT(transformFeedbackVaryings.size() == 0); + ASSERT(streamOutVaryings.empty()); const char *profileType = NULL; switch (type) @@ -2755,7 +2575,7 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string } error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + streamOutVaryings, separatedOutputBuffers, outExectuable); SafeRelease(binary); if (error.isError()) @@ -2841,17 +2661,29 @@ ImageD3D *Renderer9::createImage() gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src) { - Image9 *src9 = Image9::makeImage9(src); - Image9 *dst9 = Image9::makeImage9(dest); + Image9 *src9 = GetAs(src); + Image9 *dst9 = GetAs(dest); return Image9::generateMipmap(dst9, src9); } +gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) +{ + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) { - SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); + SwapChain9 *swapChain9 = GetAs(swapChain); return new TextureStorage9_2D(this, swapChain9); } +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage) +{ + return new TextureStorage9_EGLImage(this, eglImage); +} + TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) { return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels); @@ -2910,24 +2742,75 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer9::getVertexConversionType(gl::VertexFormatType vertexFormatType) const { - return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).conversionType; } -GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const +GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) const { - return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType; + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType; } -void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const +void Renderer9::generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const { - d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions); + d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, + outExtensions, outLimitations); } -Workarounds Renderer9::generateWorkarounds() const +WorkaroundsD3D Renderer9::generateWorkarounds() const { return d3d9::GenerateWorkarounds(); } +void Renderer9::createAnnotator() +{ + mAnnotator = new DebugAnnotator9(); +} + +gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) +{ + // TODO(jmadill): faster way? + for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; samplerIndex++) + { + gl::Error error = setTexture(samplerType, static_cast(samplerIndex), nullptr); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +egl::Error Renderer9::getEGLDevice(DeviceImpl **device) +{ + if (mEGLDevice == nullptr) + { + ASSERT(mDevice != nullptr); + mEGLDevice = new DeviceD3D(); + egl::Error error = mEGLDevice->initialize(reinterpret_cast(mDevice), + EGL_D3D9_DEVICE_ANGLE, EGL_FALSE); + + if (error.isError()) + { + SafeDelete(mEGLDevice); + return error; + } + } + + *device = static_cast(mEGLDevice); + return egl::Error(EGL_SUCCESS); +} + +Renderer9::CurSamplerState::CurSamplerState() + : forceSet(true), + baseLevel(std::numeric_limits::max()), + samplerState() +{ +} + } -- cgit v1.2.3