summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp1067
1 files changed, 475 insertions, 592 deletions
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 <sstream>
+#include <EGL/eglext.h>
+
#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 <sstream>
-#include <EGL/eglext.h>
#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<Renderer9*>(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<void**>(&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<void*>(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<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
- std::vector<gl::SamplerState> &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<TextureD3D>(texture);
- // Make sure to add the level offset for our tiny compressed texture workaround
- TextureD3D *textureD3D = GetImplAs<TextureD3D>(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<DWORD>(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<unsigned int> &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
+ std::vector<uintptr_t> &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<TextureStorage9>(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<uintptr_t>(d3dTexture))
{
mDevice->SetTexture(d3dSampler, d3dTexture);
}
- appliedSerials[index] = serial;
+ appliedTextures[index] = reinterpret_cast<uintptr_t>(d3dTexture);
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/,
- const GLint /*vertexUniformBuffers*/[],
- const GLint /*fragmentUniformBuffers*/[])
+ const std::vector<GLint> &/*vertexUniformBuffers*/,
+ const std::vector<GLint> &/*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<int>(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<DWORD>(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<int>(mRenderTargetDesc.width));
- rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
- rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
- rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(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<int>(mRenderTargetDesc.width));
- dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
- dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.X));
- dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(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<IndexBuffer9>(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<IndexBuffer9>(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<int>(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<int>(indexInfo.indexRange.length()) + 1;
- mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex,
+ static_cast<UINT>(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<unsigned short>(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<const GLuint*>(indices)[i];
+ data[i] = static_cast<unsigned short>(static_cast<const GLuint*>(indices)[i]);
}
- data[count] = static_cast<const GLuint*>(indices)[0];
+ data[count] = static_cast<unsigned short>(static_cast<const GLuint*>(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<IndexBuffer9>(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<unsigned int>(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<unsigned short*>(mappedMemory);
for (size_t i = 0; i < count; i++)
{
- data[i] = i;
+ data[i] = static_cast<unsigned short>(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<unsigned int>(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<unsigned int*>(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<ProgramD3D>(program);
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(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<ShaderExecutable9>(vertexExe)->getVertexShader() : nullptr);
+ IDirect3DPixelShader9 *pixelShader = (pixelExe ? GetAs<ShaderExecutable9>(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<gl::LinkedUniform*> &uniformArray)
+gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
+ GLenum /*drawMode*/,
+ const std::vector<D3DUniform *> &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<RenderTarget9>(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<RenderTarget9>(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<UINT>(mAdapterIdentifier.VendorId);
+ deviceIdentifier.DeviceId = static_cast<UINT>(mAdapterIdentifier.DeviceId);
+ deviceIdentifier.SubSysId = static_cast<UINT>(mAdapterIdentifier.SubSysId);
+ deviceIdentifier.Revision = static_cast<UINT>(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<RenderTarget9>(source);
+ RenderTarget9 *dest9 = GetAs<RenderTarget9>(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<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable)
+gl::Error Renderer9::loadExecutable(const void *function,
+ size_t length,
+ ShaderType type,
+ const std::vector<D3DVarying> &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<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ ShaderType type,
+ const std::vector<D3DVarying> &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<Image9>(src);
+ Image9 *dst9 = GetAs<Image9>(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<SwapChain9>(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<int>(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<void *>(mDevice),
+ EGL_D3D9_DEVICE_ANGLE, EGL_FALSE);
+
+ if (error.isError())
+ {
+ SafeDelete(mEGLDevice);
+ return error;
+ }
+ }
+
+ *device = static_cast<DeviceImpl *>(mEGLDevice);
+ return egl::Error(EGL_SUCCESS);
+}
+
+Renderer9::CurSamplerState::CurSamplerState()
+ : forceSet(true),
+ baseLevel(std::numeric_limits<size_t>::max()),
+ samplerState()
+{
+}
+
}