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