Browse Source

Check HRESULT and log error with it included in case of failure in D3D9/D3D11 code. Clean up releasing GPU objects. Clean up Texture3D to not have a RenderSurface, since it can't be rendered to. Fixed missing Lua Texture3D binding. Fixed binding of Texture3D SetSize() in AngelScript. Added checks to Texture2D/3D SetSize() that zero or negative size is not specified. Closes #1092.

Lasse Öörni 10 years ago
parent
commit
a3ba4d8ff6
30 changed files with 579 additions and 645 deletions
  1. 1 2
      Source/Urho3D/AngelScript/GraphicsAPI.cpp
  2. 5 12
      Source/Urho3D/Graphics/Direct3D11/D3D11ConstantBuffer.cpp
  3. 97 98
      Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp
  4. 4 0
      Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.h
  5. 13 18
      Source/Urho3D/Graphics/Direct3D11/D3D11IndexBuffer.cpp
  6. 5 13
      Source/Urho3D/Graphics/Direct3D11/D3D11RenderSurface.cpp
  7. 35 22
      Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.cpp
  8. 7 9
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture.cpp
  9. 55 66
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.cpp
  10. 41 73
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.cpp
  11. 0 7
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.h
  12. 41 53
      Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.cpp
  13. 13 15
      Source/Urho3D/Graphics/Direct3D11/D3D11VertexBuffer.cpp
  14. 9 13
      Source/Urho3D/Graphics/Direct3D11/D3D11VertexDeclaration.cpp
  15. 30 21
      Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp
  16. 4 0
      Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.h
  17. 11 15
      Source/Urho3D/Graphics/Direct3D9/D3D9IndexBuffer.cpp
  18. 3 7
      Source/Urho3D/Graphics/Direct3D9/D3D9RenderSurface.cpp
  19. 28 26
      Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.cpp
  20. 46 31
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture2D.cpp
  21. 25 48
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.cpp
  22. 0 7
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.h
  23. 35 27
      Source/Urho3D/Graphics/Direct3D9/D3D9TextureCube.cpp
  24. 11 12
      Source/Urho3D/Graphics/Direct3D9/D3D9VertexBuffer.cpp
  25. 7 9
      Source/Urho3D/Graphics/Direct3D9/D3D9VertexDeclaration.cpp
  26. 6 0
      Source/Urho3D/Graphics/OpenGL/OGLTexture2D.cpp
  27. 8 33
      Source/Urho3D/Graphics/OpenGL/OGLTexture3D.cpp
  28. 0 8
      Source/Urho3D/Graphics/OpenGL/OGLTexture3D.h
  29. 38 0
      Source/Urho3D/LuaScript/pkgs/Graphics/Texture3D.pkg
  30. 1 0
      Source/Urho3D/LuaScript/pkgs/GraphicsLuaAPI.pkg

+ 1 - 2
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -508,9 +508,8 @@ static void RegisterTextures(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Texture2D", "Image@+ GetImage() const", asFUNCTION(Texture2DGetImage), asCALL_CDECL_OBJLAST);
 
     RegisterTexture<Texture3D>(engine, "Texture3D");
-    engine->RegisterObjectMethod("Texture3D", "bool SetSize(int, int, uint, TextureUsage usage = TEXTURE_STATIC)", asMETHOD(Texture3D, SetSize), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Texture3D", "bool SetSize(int, int, int, uint, TextureUsage usage = TEXTURE_STATIC)", asMETHOD(Texture3D, SetSize), asCALL_THISCALL);
     engine->RegisterObjectMethod("Texture3D", "bool SetData(Image@+, bool useAlpha = false)", asFUNCTION(Texture3DSetData), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Texture3D", "RenderSurface@+ get_renderSurface() const", asMETHOD(Texture3D, GetRenderSurface), asCALL_THISCALL);
 
     RegisterTexture<TextureCube>(engine, "TextureCube");
     engine->RegisterObjectMethod("TextureCube", "bool SetSize(int, uint, TextureUsage usage = TEXTURE_STATIC)", asMETHOD(TextureCube, SetSize), asCALL_THISCALL);

+ 5 - 12
Source/Urho3D/Graphics/Direct3D11/D3D11ConstantBuffer.cpp

@@ -45,14 +45,7 @@ ConstantBuffer::~ConstantBuffer()
 
 void ConstantBuffer::Release()
 {
-    if (object_)
-    {
-        if (!graphics_)
-            return;
-
-        ((ID3D11Buffer*)object_)->Release();
-        object_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(object_);
 
     shadowData_.Reset();
     size_ = 0;
@@ -87,11 +80,11 @@ bool ConstantBuffer::SetSize(unsigned size)
         bufferDesc.CPUAccessFlags = 0;
         bufferDesc.Usage = D3D11_USAGE_DEFAULT;
 
-        graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
-
-        if (!object_)
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Failed to create constant buffer");
+            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_LOGD3DERROR("Failed to create constant buffer", hr);
             return false;
         }
     }

+ 97 - 98
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -279,61 +279,31 @@ Graphics::~Graphics()
 
     for (HashMap<unsigned, ID3D11BlendState*>::Iterator i = impl_->blendStates_.Begin(); i != impl_->blendStates_.End(); ++i)
     {
-        if (i->second_)
-            i->second_->Release();
+        URHO3D_SAFE_RELEASE(i->second_);
     }
     impl_->blendStates_.Clear();
 
     for (HashMap<unsigned, ID3D11DepthStencilState*>::Iterator i = impl_->depthStates_.Begin(); i != impl_->depthStates_.End(); ++i)
     {
-        if (i->second_)
-            i->second_->Release();
+        URHO3D_SAFE_RELEASE(i->second_);
     }
     impl_->depthStates_.Clear();
 
     for (HashMap<unsigned, ID3D11RasterizerState*>::Iterator i = impl_->rasterizerStates_.Begin();
          i != impl_->rasterizerStates_.End(); ++i)
     {
-        if (i->second_)
-            i->second_->Release();
+        URHO3D_SAFE_RELEASE(i->second_);
     }
     impl_->rasterizerStates_.Clear();
 
-    if (impl_->defaultRenderTargetView_)
-    {
-        impl_->defaultRenderTargetView_->Release();
-        impl_->defaultRenderTargetView_ = 0;
-    }
-    if (impl_->defaultDepthStencilView_)
-    {
-        impl_->defaultDepthStencilView_->Release();
-        impl_->defaultDepthStencilView_ = 0;
-    }
-    if (impl_->defaultDepthTexture_)
-    {
-        impl_->defaultDepthTexture_->Release();
-        impl_->defaultDepthTexture_ = 0;
-    }
-    if (impl_->resolveTexture_)
-    {
-        impl_->resolveTexture_->Release();
-        impl_->resolveTexture_ = 0;
-    }
-    if (impl_->swapChain_)
-    {
-        impl_->swapChain_->Release();
-        impl_->swapChain_ = 0;
-    }
-    if (impl_->deviceContext_)
-    {
-        impl_->deviceContext_->Release();
-        impl_->deviceContext_ = 0;
-    }
-    if (impl_->device_)
-    {
-        impl_->device_->Release();
-        impl_->device_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(impl_->defaultRenderTargetView_);
+    URHO3D_SAFE_RELEASE(impl_->defaultDepthStencilView_);
+    URHO3D_SAFE_RELEASE(impl_->defaultDepthTexture_);
+    URHO3D_SAFE_RELEASE(impl_->resolveTexture_);
+    URHO3D_SAFE_RELEASE(impl_->swapChain_);
+    URHO3D_SAFE_RELEASE(impl_->deviceContext_);
+    URHO3D_SAFE_RELEASE(impl_->device_);
+
     if (impl_->window_)
     {
         SDL_ShowCursor(SDL_TRUE);
@@ -580,10 +550,11 @@ bool Graphics::TakeScreenShot(Image& destImage)
     textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
 
     ID3D11Texture2D* stagingTexture = 0;
-    impl_->device_->CreateTexture2D(&textureDesc, 0, &stagingTexture);
-    if (!stagingTexture)
+    HRESULT hr = impl_->device_->CreateTexture2D(&textureDesc, 0, &stagingTexture);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not create staging texture for screenshot");
+        URHO3D_SAFE_RELEASE(stagingTexture);
+        URHO3D_LOGD3DERROR("Could not create staging texture for screenshot", hr);
         return false;
     }
 
@@ -597,7 +568,6 @@ bool Graphics::TakeScreenShot(Image& destImage)
 
         if (!impl_->resolveTexture_)
         {
-            URHO3D_LOGERROR("Could not create intermediate texture for multisampled screenshot");
             stagingTexture->Release();
             source->Release();
             return false;
@@ -613,33 +583,31 @@ bool Graphics::TakeScreenShot(Image& destImage)
 
     D3D11_MAPPED_SUBRESOURCE mappedData;
     mappedData.pData = 0;
-    impl_->deviceContext_->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
+    hr = impl_->deviceContext_->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
+    if (FAILED(hr) || !mappedData.pData)
+    {
+        URHO3D_LOGD3DERROR("Could not map staging texture for screenshot", hr);
+        stagingTexture->Release();
+        return false;
+    }
 
     destImage.SetSize(width_, height_, 3);
     unsigned char* destData = destImage.GetData();
-    if (mappedData.pData)
+    for (int y = 0; y < height_; ++y)
     {
-        for (int y = 0; y < height_; ++y)
+        unsigned char* src = (unsigned char*)mappedData.pData + y * mappedData.RowPitch;
+        for (int x = 0; x < width_; ++x)
         {
-            unsigned char* src = (unsigned char*)mappedData.pData + y * mappedData.RowPitch;
-            for (int x = 0; x < width_; ++x)
-            {
-                *destData++ = *src++;
-                *destData++ = *src++;
-                *destData++ = *src++;
-                ++src;
-            }
+            *destData++ = *src++;
+            *destData++ = *src++;
+            *destData++ = *src++;
+            ++src;
         }
-        impl_->deviceContext_->Unmap(stagingTexture, 0);
-        stagingTexture->Release();
-        return true;
-    }
-    else
-    {
-        URHO3D_LOGERROR("Could not map staging texture for screenshot");
-        stagingTexture->Release();
-        return false;
     }
+
+    impl_->deviceContext_->Unmap(stagingTexture, 0);
+    stagingTexture->Release();
+    return true;
 }
 
 bool Graphics::BeginFrame()
@@ -675,7 +643,6 @@ bool Graphics::BeginFrame()
     numBatches_ = 0;
 
     SendEvent(E_BEGINRENDERING);
-
     return true;
 }
 
@@ -688,7 +655,6 @@ void Graphics::EndFrame()
         URHO3D_PROFILE(Present);
 
         SendEvent(E_ENDRENDERING);
-
         impl_->swapChain_->Present(vsync_ ? 1 : 0, 0);
     }
 
@@ -2257,7 +2223,7 @@ bool Graphics::CreateDevice(int width, int height, int multiSample)
     // Device needs only to be created once
     if (!impl_->device_)
     {
-        D3D11CreateDevice(
+        HRESULT hr = D3D11CreateDevice(
             0,
             D3D_DRIVER_TYPE_HARDWARE,
             0,
@@ -2270,9 +2236,11 @@ bool Graphics::CreateDevice(int width, int height, int multiSample)
             &impl_->deviceContext_
         );
 
-        if (!impl_->device_ || !impl_->deviceContext_)
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Failed to create D3D11 device");
+            URHO3D_SAFE_RELEASE(impl_->device_);
+            URHO3D_SAFE_RELEASE(impl_->deviceContext_);
+            URHO3D_LOGD3DERROR("Failed to create D3D11 device", hr);
             return false;
         }
 
@@ -2312,7 +2280,7 @@ bool Graphics::CreateDevice(int width, int height, int multiSample)
     dxgiDevice->GetParent(IID_IDXGIAdapter, (void**)&dxgiAdapter);
     IDXGIFactory* dxgiFactory = 0;
     dxgiAdapter->GetParent(IID_IDXGIFactory, (void**)&dxgiFactory);
-    dxgiFactory->CreateSwapChain(impl_->device_, &swapChainDesc, &impl_->swapChain_);
+    HRESULT hr = dxgiFactory->CreateSwapChain(impl_->device_, &swapChainDesc, &impl_->swapChain_);
     // After creating the swap chain, disable automatic Alt-Enter fullscreen/windowed switching
     // (the application will switch manually if it wants to)
     dxgiFactory->MakeWindowAssociation(GetWindowHandle(impl_->window_), DXGI_MWA_NO_ALT_ENTER);
@@ -2321,15 +2289,16 @@ bool Graphics::CreateDevice(int width, int height, int multiSample)
     dxgiAdapter->Release();
     dxgiDevice->Release();
 
-    if (impl_->swapChain_)
+    if (FAILED(hr))
     {
-        multiSample_ = multiSample;
-        return true;
+        URHO3D_SAFE_RELEASE(impl_->swapChain_);
+        URHO3D_LOGD3DERROR("Failed to create D3D11 swap chain", hr);
+        return false;
     }
-    else
+    else if (impl_->swapChain_)
     {
-        URHO3D_LOGERROR("Failed to create D3D11 swap chain");
-        return false;
+        multiSample_ = multiSample;
+        return true;
     }
 }
 
@@ -2369,16 +2338,23 @@ bool Graphics::UpdateSwapChain(int width, int height)
 
     // Create default rendertarget view representing the backbuffer
     ID3D11Texture2D* backbufferTexture;
-    impl_->swapChain_->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backbufferTexture);
-    if (backbufferTexture)
+    HRESULT hr = impl_->swapChain_->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backbufferTexture);
+    if (FAILED(hr))
     {
-        impl_->device_->CreateRenderTargetView(backbufferTexture, 0, &impl_->defaultRenderTargetView_);
-        backbufferTexture->Release();
+        URHO3D_SAFE_RELEASE(backbufferTexture);
+        URHO3D_LOGD3DERROR("Failed to get backbuffer texture", hr);
+        success = false;
     }
     else
     {
-        URHO3D_LOGERROR("Failed to get backbuffer texture");
-        success = false;
+        hr = impl_->device_->CreateRenderTargetView(backbufferTexture, 0, &impl_->defaultRenderTargetView_);
+        backbufferTexture->Release();
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(impl_->defaultRenderTargetView_);
+            URHO3D_LOGD3DERROR("Failed to create backbuffer rendertarget view", hr);
+            success = false;
+        }
     }
 
     // Create default depth-stencil texture and view
@@ -2395,14 +2371,23 @@ bool Graphics::UpdateSwapChain(int width, int height)
     depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
     depthDesc.CPUAccessFlags = 0;
     depthDesc.MiscFlags = 0;
-    impl_->device_->CreateTexture2D(&depthDesc, 0, &impl_->defaultDepthTexture_);
-    if (impl_->defaultDepthTexture_)
-        impl_->device_->CreateDepthStencilView(impl_->defaultDepthTexture_, 0, &impl_->defaultDepthStencilView_);
-    else
+    hr = impl_->device_->CreateTexture2D(&depthDesc, 0, &impl_->defaultDepthTexture_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create backbuffer depth-stencil texture");
+        URHO3D_SAFE_RELEASE(impl_->defaultDepthTexture_);
+        URHO3D_LOGD3DERROR("Failed to create backbuffer depth-stencil texture", hr);
         success = false;
     }
+    else
+    {
+        hr = impl_->device_->CreateDepthStencilView(impl_->defaultDepthTexture_, 0, &impl_->defaultDepthStencilView_);
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(impl_->defaultDepthStencilView_);
+            URHO3D_LOGD3DERROR("Failed to create backbuffer depth-stencil view", hr);
+            success = false;
+        }
+    }
 
     // Update internally held backbuffer size
     width_ = width;
@@ -2603,9 +2588,12 @@ void Graphics::PrepareDraw()
                 stateDesc.RenderTarget[0].RenderTargetWriteMask = colorWrite_ ? D3D11_COLOR_WRITE_ENABLE_ALL : 0x0;
 
                 ID3D11BlendState* newBlendState = 0;
-                impl_->device_->CreateBlendState(&stateDesc, &newBlendState);
-                if (!newBlendState)
-                    URHO3D_LOGERROR("Failed to create blend state");
+                HRESULT hr = impl_->device_->CreateBlendState(&stateDesc, &newBlendState);
+                if (FAILED(hr))
+                {
+                    URHO3D_SAFE_RELEASE(newBlendState);
+                    URHO3D_LOGD3DERROR("Failed to create blend state", hr);
+                }
 
                 i = impl_->blendStates_.Insert(MakePair(newBlendStateHash, newBlendState));
             }
@@ -2648,9 +2636,12 @@ void Graphics::PrepareDraw()
                 stateDesc.BackFace.StencilFunc = d3dCmpFunc[stencilTestMode_];
 
                 ID3D11DepthStencilState* newDepthState = 0;
-                impl_->device_->CreateDepthStencilState(&stateDesc, &newDepthState);
-                if (!newDepthState)
-                    URHO3D_LOGERROR("Failed to create depth state");
+                HRESULT hr = impl_->device_->CreateDepthStencilState(&stateDesc, &newDepthState);
+                if (FAILED(hr))
+                {
+                    URHO3D_SAFE_RELEASE(newDepthState);
+                    URHO3D_LOGD3DERROR("Failed to create depth state", hr);
+                }
 
                 i = impl_->depthStates_.Insert(MakePair(newDepthStateHash, newDepthState));
             }
@@ -2694,9 +2685,12 @@ void Graphics::PrepareDraw()
                 stateDesc.AntialiasedLineEnable = FALSE;
 
                 ID3D11RasterizerState* newRasterizerState = 0;
-                impl_->device_->CreateRasterizerState(&stateDesc, &newRasterizerState);
-                if (!newRasterizerState)
-                    URHO3D_LOGERROR("Failed to create rasterizer state");
+                HRESULT hr = impl_->device_->CreateRasterizerState(&stateDesc, &newRasterizerState);
+                if (FAILED(hr))
+                {
+                    URHO3D_SAFE_RELEASE(newRasterizerState);
+                    URHO3D_LOGD3DERROR("Failed to create rasterizer state", hr);
+                }
 
                 i = impl_->rasterizerStates_.Insert(MakePair(newRasterizerStateHash, newRasterizerState));
             }
@@ -2741,7 +2735,12 @@ void Graphics::CreateResolveTexture()
     textureDesc.Usage = D3D11_USAGE_DEFAULT;
     textureDesc.CPUAccessFlags = 0;
 
-    impl_->device_->CreateTexture2D(&textureDesc, 0, &impl_->resolveTexture_);
+    HRESULT hr = impl_->device_->CreateTexture2D(&textureDesc, 0, &impl_->resolveTexture_);
+    if (FAILED(hr))
+    {
+        URHO3D_SAFE_RELEASE(impl_->resolveTexture_);
+        URHO3D_LOGD3DERROR("Could not create resolve texture", hr);
+    }
 }
 
 void Graphics::SetTextureUnitMappings()

+ 4 - 0
Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.h

@@ -32,6 +32,10 @@
 namespace Urho3D
 {
 
+#define URHO3D_SAFE_RELEASE(p) if (p) { ((IUnknown*)p)->Release();  p = 0; }
+
+#define URHO3D_LOGD3DERROR(msg, hr) URHO3D_LOGERRORF("%s (HRESULT %x)", msg, (unsigned)hr)
+
 /// %Graphics implementation. Holds API-specific objects.
 class URHO3D_API GraphicsImpl
 {

+ 13 - 18
Source/Urho3D/Graphics/Direct3D11/D3D11IndexBuffer.cpp

@@ -59,17 +59,10 @@ void IndexBuffer::Release()
 {
     Unlock();
 
-    if (object_)
-    {
-        if (!graphics_)
-            return;
+    if (graphics_ && graphics_->GetIndexBuffer() == this)
+        graphics_->SetIndexBuffer(0);
 
-        if (graphics_->GetIndexBuffer() == this)
-            graphics_->SetIndexBuffer(0);
-
-        ((ID3D11Buffer*)object_)->Release();
-        object_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(object_);
 }
 
 void IndexBuffer::SetShadowed(bool enable)
@@ -342,11 +335,11 @@ bool IndexBuffer::Create()
         bufferDesc.Usage = dynamic_ ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
         bufferDesc.ByteWidth = (UINT)(indexCount_ * indexSize_);
 
-        graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
-
-        if (!object_)
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Failed to create index buffer");
+            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_LOGD3DERROR("Failed to create index buffer", hr);
             return false;
         }
     }
@@ -371,13 +364,15 @@ void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
             D3D11_MAP_WRITE, 0, &mappedData);
-        hwData = mappedData.pData;
-        if (!hwData)
-            URHO3D_LOGERROR("Failed to map index buffer");
+        if (FAILED(hr) || !mappedData.pData)
+            URHO3D_LOGD3DERROR("Failed to map index buffer", hr);
         else
+        {
+            hwData = mappedData.pData;
             lockState_ = LOCK_HARDWARE;
+        }
     }
 
     return hwData;

+ 5 - 13
Source/Urho3D/Graphics/Direct3D11/D3D11RenderSurface.cpp

@@ -109,28 +109,20 @@ void RenderSurface::QueueUpdate()
 void RenderSurface::Release()
 {
     Graphics* graphics = parentTexture_->GetGraphics();
-    if (!graphics)
-        return;
-
-    if (renderTargetView_)
+    if (graphics && renderTargetView_)
     {
         for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
         {
             if (graphics->GetRenderTarget(i) == this)
                 graphics->ResetRenderTarget(i);
         }
-
+        
         if (graphics->GetDepthStencil() == this)
             graphics->ResetDepthStencil();
-
-        ((ID3D11View*)renderTargetView_)->Release();
-        renderTargetView_ = 0;
-        if (readOnlyView_)
-        {
-            ((ID3D11View*)readOnlyView_)->Release();
-            readOnlyView_ = 0;
-        }
     }
+
+    URHO3D_SAFE_RELEASE(renderTargetView_);
+    URHO3D_SAFE_RELEASE(readOnlyView_);
 }
 
 int RenderSurface::GetWidth() const

+ 35 - 22
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.cpp

@@ -90,16 +90,30 @@ bool ShaderVariation::Create()
     if (type_ == VS)
     {
         if (device && byteCode_.Size())
-            device->CreateVertexShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11VertexShader**)&object_);
-        if (!object_)
-            compilerOutput_ = "Could not create vertex shader";
+        {
+            HRESULT hr = device->CreateVertexShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11VertexShader**)&object_);
+            if (FAILED(hr))
+            {
+                URHO3D_SAFE_RELEASE(object_);
+                compilerOutput_ = "Could not create vertex shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
+            }
+        }
+        else
+            compilerOutput_ = "Could not create vertex shader, empty bytecode";
     }
     else
     {
         if (device && byteCode_.Size())
-            device->CreatePixelShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11PixelShader**)&object_);
-        if (!object_)
-            compilerOutput_ = "Could not create pixel shader";
+        {
+            HRESULT hr = device->CreatePixelShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11PixelShader**)&object_);
+            if (FAILED(hr))
+            {
+                URHO3D_SAFE_RELEASE(object_);
+                compilerOutput_ = "Could not create pixel shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
+            }
+        }
+        else
+            compilerOutput_ = "Could not create pixel shader, empty bytecode";
     }
 
     return object_ != 0;
@@ -118,18 +132,14 @@ void ShaderVariation::Release()
         {
             if (graphics_->GetVertexShader() == this)
                 graphics_->SetShaders(0, 0);
-
-            ((ID3D11VertexShader*)object_)->Release();
         }
         else
         {
             if (graphics_->GetPixelShader() == this)
                 graphics_->SetShaders(0, 0);
-
-            ((ID3D11PixelShader*)object_)->Release();
         }
 
-        object_ = 0;
+        URHO3D_SAFE_RELEASE(object_);
     }
 
     compilerOutput_.Clear();
@@ -292,9 +302,13 @@ bool ShaderVariation::Compile()
     ID3DBlob* shaderCode = 0;
     ID3DBlob* errorMsgs = 0;
 
-    if (FAILED(D3DCompile(sourceCode.CString(), sourceCode.Length(), owner_->GetName().CString(), &macros.Front(), 0,
-        entryPoint, profile, flags, 0, &shaderCode, &errorMsgs)))
-        compilerOutput_ = String((const char*)errorMsgs->GetBufferPointer(), (unsigned)errorMsgs->GetBufferSize());
+    HRESULT hr = D3DCompile(sourceCode.CString(), sourceCode.Length(), owner_->GetName().CString(), &macros.Front(), 0,
+        entryPoint, profile, flags, 0, &shaderCode, &errorMsgs);
+    if (FAILED(hr))
+    {
+        // Do not include end zero unnecessarily
+        compilerOutput_ = String((const char*)errorMsgs->GetBufferPointer(), (unsigned)errorMsgs->GetBufferSize() - 1);
+    }
     else
     {
         if (type_ == VS)
@@ -317,11 +331,9 @@ bool ShaderVariation::Compile()
         strippedCode->Release();
     }
 
-    if (shaderCode)
-        shaderCode->Release();
-    if (errorMsgs)
-        errorMsgs->Release();
-
+    URHO3D_SAFE_RELEASE(shaderCode);
+    URHO3D_SAFE_RELEASE(errorMsgs);
+    
     return !byteCode_.Empty();
 }
 
@@ -330,10 +342,11 @@ void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
     ID3D11ShaderReflection* reflection = 0;
     D3D11_SHADER_DESC shaderDesc;
 
-    D3DReflect(bufData, bufSize, IID_ID3D11ShaderReflection, (void**)&reflection);
-    if (!reflection)
+    HRESULT hr = D3DReflect(bufData, bufSize, IID_ID3D11ShaderReflection, (void**)&reflection);
+    if (FAILED(hr) || !reflection)
     {
-        URHO3D_LOGERROR("Failed to reflect vertex shader's input signature");
+        URHO3D_SAFE_RELEASE(reflection);
+        URHO3D_LOGD3DERROR("Failed to reflect vertex shader's input signature", hr);
         return;
     }
 

+ 7 - 9
Source/Urho3D/Graphics/Direct3D11/D3D11Texture.cpp

@@ -325,11 +325,7 @@ void Texture::UpdateParameters()
         return;
 
     // Release old sampler
-    if (sampler_)
-    {
-        ((ID3D11SamplerState*)sampler_)->Release();
-        sampler_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(sampler_);
 
     D3D11_SAMPLER_DESC samplerDesc;
     memset(&samplerDesc, 0, sizeof samplerDesc);
@@ -346,10 +342,12 @@ void Texture::UpdateParameters()
     samplerDesc.MaxLOD = M_INFINITY;
     memcpy(&samplerDesc.BorderColor, borderColor_.Data(), 4 * sizeof(float));
 
-    graphics_->GetImpl()->GetDevice()->CreateSamplerState(&samplerDesc, (ID3D11SamplerState**)&sampler_);
-
-    if (!sampler_)
-        URHO3D_LOGERROR("Failed to create sampler state");
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateSamplerState(&samplerDesc, (ID3D11SamplerState**)&sampler_);
+    if (FAILED(hr))
+    {
+        URHO3D_SAFE_RELEASE(sampler_);
+        URHO3D_LOGD3DERROR("Failed to create sampler state", hr);
+    }
 
     parametersDirty_ = false;
 }

+ 55 - 66
Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.cpp

@@ -100,44 +100,31 @@ bool Texture2D::EndLoad()
 
 void Texture2D::Release()
 {
-    if (object_)
+    if (graphics_ && object_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
             if (graphics_->GetTexture(i) == this)
                 graphics_->SetTexture(i, 0);
         }
+    }
 
-        if (renderSurface_)
-            renderSurface_->Release();
-
-        ((ID3D11Resource*)object_)->Release();
-        object_ = 0;
-
-        if (shaderResourceView_)
-        {
-            ((ID3D11ShaderResourceView*)shaderResourceView_)->Release();
-            shaderResourceView_ = 0;
-        }
+    if (renderSurface_)
+        renderSurface_->Release();
 
-        if (sampler_)
-        {
-            ((ID3D11SamplerState*)sampler_)->Release();
-            sampler_ = 0;
-        }
-    }
-    else
-    {
-        if (renderSurface_)
-            renderSurface_->Release();
-    }
+    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(shaderResourceView_);
+    URHO3D_SAFE_RELEASE(sampler_);
 }
 
 bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
 {
+    if (width <= 0 || height <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative texture dimensions");
+        return false;
+    }
+
     // Delete the old rendersurface if any
     renderSurface_.Reset();
     usage_ = usage;
@@ -145,6 +132,7 @@ bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usa
     if (usage_ == TEXTURE_RENDERTARGET || usage_ == TEXTURE_DEPTHSTENCIL)
     {
         renderSurface_ = new RenderSurface(this);
+
         // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
         addressMode_[COORD_U] = ADDRESS_CLAMP;
         addressMode_[COORD_V] = ADDRESS_CLAMP;
@@ -221,18 +209,18 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
-        if (mappedData.pData)
+        if (FAILED(hr) || !mappedData.pData)
         {
-            for (int row = 0; row < height; ++row)
-                memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
-            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
+            URHO3D_LOGD3DERROR("Failed to map texture for update", hr);
+            return false;
         }
         else
         {
-            URHO3D_LOGERROR("Failed to map texture for update");
-            return false;
+            for (int row = 0; row < height; ++row)
+                memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
+            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
         }
     }
     else
@@ -409,10 +397,11 @@ bool Texture2D::GetData(unsigned level, void* dest) const
     textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
 
     ID3D11Texture2D* stagingTexture = 0;
-    graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, &stagingTexture);
-    if (!stagingTexture)
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, &stagingTexture);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create staging texture for GetData");
+        URHO3D_SAFE_RELEASE(stagingTexture);
+        URHO3D_LOGD3DERROR("Failed to create staging texture for GetData", hr);
         return false;
     }
 
@@ -432,20 +421,20 @@ bool Texture2D::GetData(unsigned level, void* dest) const
     unsigned rowSize = GetRowDataSize(levelWidth);
     unsigned numRows = (unsigned)(IsCompressed() ? (levelHeight + 3) >> 2 : levelHeight);
 
-    graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
-    if (mappedData.pData)
+    hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
+    if (FAILED(hr) || !mappedData.pData)
     {
-        for (unsigned row = 0; row < numRows; ++row)
-            memcpy((unsigned char*)dest + row * rowSize, (unsigned char*)mappedData.pData + row * mappedData.RowPitch, rowSize);
-        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)stagingTexture, 0);
+        URHO3D_LOGD3DERROR("Failed to map staging texture for GetData", hr);
         stagingTexture->Release();
-        return true;
+        return false;
     }
     else
     {
-        URHO3D_LOGERROR("Failed to map staging texture for GetData");
+        for (unsigned row = 0; row < numRows; ++row)
+            memcpy((unsigned char*)dest + row * rowSize, (unsigned char*)mappedData.pData + row * mappedData.RowPitch, rowSize);
+        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)stagingTexture, 0);
         stagingTexture->Release();
-        return false;
+        return true;
     }
 }
 
@@ -475,10 +464,11 @@ bool Texture2D::Create()
         textureDesc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
     textureDesc.CPUAccessFlags = usage_ == TEXTURE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0;
 
-    graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
-    if (!object_)
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create texture");
+        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_LOGD3DERROR("Failed to create texture", hr);
         return false;
     }
 
@@ -488,57 +478,56 @@ bool Texture2D::Create()
     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
     resourceViewDesc.Texture2D.MipLevels = (UINT)levels_;
 
-    graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
-    if (!shaderResourceView_)
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create shader resource view for texture");
+        URHO3D_SAFE_RELEASE(shaderResourceView_);
+        URHO3D_LOGD3DERROR("Failed to create shader resource view for texture", hr);
         return false;
     }
 
     if (usage_ == TEXTURE_RENDERTARGET)
     {
-        renderSurface_ = new RenderSurface(this);
-
         D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
         memset(&renderTargetViewDesc, 0, sizeof renderTargetViewDesc);
         renderTargetViewDesc.Format = textureDesc.Format;
         renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
 
-        graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
             (ID3D11RenderTargetView**)&renderSurface_->renderTargetView_);
-
-        if (!renderSurface_->renderTargetView_)
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Failed to create rendertarget view for texture");
+            URHO3D_SAFE_RELEASE(renderSurface_->renderTargetView_);
+            URHO3D_LOGD3DERROR("Failed to create rendertarget view for texture", hr);
             return false;
         }
     }
     else if (usage_ == TEXTURE_DEPTHSTENCIL)
     {
-        renderSurface_ = new RenderSurface(this);
-
         D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
         memset(&depthStencilViewDesc, 0, sizeof depthStencilViewDesc);
         depthStencilViewDesc.Format = (DXGI_FORMAT)GetDSVFormat(textureDesc.Format);
         depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
 
-        graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_, &depthStencilViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_, &depthStencilViewDesc,
             (ID3D11DepthStencilView**)&renderSurface_->renderTargetView_);
-
-        if (!renderSurface_->renderTargetView_)
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Failed to create depth-stencil view for texture");
+            URHO3D_SAFE_RELEASE(renderSurface_->renderTargetView_);
+            URHO3D_LOGD3DERROR("Failed to create depth-stencil view for texture", hr);
             return false;
         }
 
         // Create also a read-only version of the view for simultaneous depth testing and sampling in shader
         depthStencilViewDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH;
-        graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_, &depthStencilViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_, &depthStencilViewDesc,
             (ID3D11DepthStencilView**)&renderSurface_->readOnlyView_);
-
-        if (!renderSurface_->readOnlyView_)
-            URHO3D_LOGWARNING("Failed to create read-only depth-stencil view for texture");
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(renderSurface_->readOnlyView_);
+            URHO3D_LOGD3DERROR("Failed to create read-only depth-stencil view for texture", hr);
+        }
     }
 
     return true;

+ 41 - 73
Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.cpp

@@ -144,63 +144,34 @@ bool Texture3D::EndLoad()
 
 void Texture3D::Release()
 {
-    if (object_)
+    if (graphics_ && object_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
             if (graphics_->GetTexture(i) == this)
                 graphics_->SetTexture(i, 0);
         }
-
-        if (renderSurface_)
-            renderSurface_->Release();
-
-        ((ID3D11Resource*)object_)->Release();
-        object_ = 0;
-
-        if (shaderResourceView_)
-        {
-            ((ID3D11ShaderResourceView*)shaderResourceView_)->Release();
-            shaderResourceView_ = 0;
-        }
-
-        if (sampler_)
-        {
-            ((ID3D11SamplerState*)sampler_)->Release();
-            sampler_ = 0;
-        }
-    }
-    else
-    {
-        if (renderSurface_)
-            renderSurface_->Release();
     }
+
+    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(shaderResourceView_);
+    URHO3D_SAFE_RELEASE(sampler_);
 }
 
 bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
 {
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
-    usage_ = usage;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
+    if (width <= 0 || height <= 0 || depth <= 0)
     {
-        renderSurface_ = new RenderSurface(this);
-
-        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
-        addressMode_[COORD_U] = ADDRESS_CLAMP;
-        addressMode_[COORD_V] = ADDRESS_CLAMP;
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
+        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
+        return false;
+    }
+    if (usage >= TEXTURE_RENDERTARGET)
+    {
+        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
+        return false;
     }
 
-    if (usage_ == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture3D, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
+    usage_ = usage;
 
     width_ = width;
     height_ = height;
@@ -269,9 +240,14 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
-        if (mappedData.pData)
+        if (FAILED(hr) || !mappedData.pData)
+        {
+            URHO3D_LOGD3DERROR("Failed to map texture for update", hr);
+            return false;
+        }
+        else
         {
             for (int page = 0; page < depth; ++page)
             {
@@ -284,11 +260,6 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
 
             graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
         }
-        else
-        {
-            URHO3D_LOGERROR("Failed to map texture for update");
-            return false;
-        }
     }
     else
     {
@@ -471,10 +442,11 @@ bool Texture3D::GetData(unsigned level, void* dest) const
     textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
 
     ID3D11Texture3D* stagingTexture = 0;
-    graphics_->GetImpl()->GetDevice()->CreateTexture3D(&textureDesc, 0, &stagingTexture);
-    if (!stagingTexture)
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture3D(&textureDesc, 0, &stagingTexture);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create staging texture for GetData");
+        URHO3D_SAFE_RELEASE(stagingTexture);
+        URHO3D_LOGD3DERROR("Failed to create staging texture for GetData", hr);
         return false;
     }
 
@@ -494,8 +466,14 @@ bool Texture3D::GetData(unsigned level, void* dest) const
     unsigned rowSize = GetRowDataSize(levelWidth);
     unsigned numRows = (unsigned)(IsCompressed() ? (levelHeight + 3) >> 2 : levelHeight);
 
-    graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
-    if (mappedData.pData)
+    hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
+    if (FAILED(hr) || !mappedData.pData)
+    {
+        URHO3D_LOGD3DERROR("Failed to map staging texture for GetData", hr);
+        stagingTexture->Release();
+        return false;
+    }
+    else
     {
         for (int page = 0; page < levelDepth; ++page)
         {
@@ -509,12 +487,6 @@ bool Texture3D::GetData(unsigned level, void* dest) const
         stagingTexture->Release();
         return true;
     }
-    else
-    {
-        URHO3D_LOGERROR("Failed to map staging texture for GetData");
-        stagingTexture->Release();
-        return false;
-    }
 }
 
 bool Texture3D::Create()
@@ -537,10 +509,11 @@ bool Texture3D::Create()
     textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
     textureDesc.CPUAccessFlags = usage_ == TEXTURE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0;
 
-    graphics_->GetImpl()->GetDevice()->CreateTexture3D(&textureDesc, 0, (ID3D11Texture3D**)&object_);
-    if (!object_)
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture3D(&textureDesc, 0, (ID3D11Texture3D**)&object_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create texture");
+        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_LOGD3DERROR("Failed to create texture", hr);
         return false;
     }
 
@@ -550,21 +523,16 @@ bool Texture3D::Create()
     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
     resourceViewDesc.Texture3D.MipLevels = (UINT)levels_;
 
-    graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
-    if (!shaderResourceView_)
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create shader resource view for texture");
+        URHO3D_SAFE_RELEASE(shaderResourceView_);
+        URHO3D_LOGD3DERROR("Failed to create shader resource view for texture", hr);
         return false;
     }
 
     return true;
 }
 
-void Texture3D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS)
-        renderSurface_->QueueUpdate();
-}
-
 }

+ 0 - 7
Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.h

@@ -61,17 +61,10 @@ public:
     /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
     bool GetData(unsigned level, void* dest) const;
 
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
 private:
     /// Create texture.
     bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
 
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
     /// Image file acquired during BeginLoad.
     SharedPtr<Image> loadImage_;
     /// Parameter file acquired during BeginLoad.

+ 41 - 53
Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.cpp

@@ -249,38 +249,24 @@ bool TextureCube::EndLoad()
 
 void TextureCube::Release()
 {
-    if (object_)
+    if (graphics_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
             if (graphics_->GetTexture(i) == this)
                 graphics_->SetTexture(i, 0);
         }
+    }
 
-        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-        {
-            if (renderSurfaces_[i])
-                renderSurfaces_[i]->Release();
-        }
-
-        ((ID3D11Resource*)object_)->Release();
-        object_ = 0;
-
-        if (shaderResourceView_)
-        {
-            ((ID3D11ShaderResourceView*)shaderResourceView_)->Release();
-            shaderResourceView_ = 0;
-        }
-
-        if (sampler_)
-        {
-            ((ID3D11SamplerState*)sampler_)->Release();
-            sampler_ = 0;
-        }
+    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+    {
+        if (renderSurfaces_[i])
+            renderSurfaces_[i]->Release();
     }
+
+    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(shaderResourceView_);
+    URHO3D_SAFE_RELEASE(sampler_);
 }
 
 bool TextureCube::SetSize(int size, unsigned format, TextureUsage usage)
@@ -383,18 +369,18 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
-        if (mappedData.pData)
+        if (FAILED(hr) || !mappedData.pData)
         {
-            for (int row = 0; row < height; ++row)
-                memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
-            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
+            URHO3D_LOGD3DERROR("Failed to map texture for update", hr);
+            return false;
         }
         else
         {
-            URHO3D_LOGERROR("Failed to map texture for update");
-            return false;
+            for (int row = 0; row < height; ++row)
+                memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
+            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
         }
     }
     else
@@ -631,10 +617,11 @@ bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
     textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
 
     ID3D11Texture2D* stagingTexture = 0;
-    graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, &stagingTexture);
-    if (!stagingTexture)
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, &stagingTexture);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create staging texture for GetData");
+        URHO3D_SAFE_RELEASE(stagingTexture);
+        URHO3D_LOGD3DERROR("Failed to create staging texture for GetData", hr);
         return false;
     }
 
@@ -654,20 +641,20 @@ bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
     unsigned rowSize = GetRowDataSize(levelWidth);
     unsigned numRows = (unsigned)(IsCompressed() ? (levelHeight + 3) >> 2 : levelHeight);
 
-    graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
-    if (mappedData.pData)
+    hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
+    if (FAILED(hr) || !mappedData.pData)
     {
-        for (unsigned row = 0; row < numRows; ++row)
-            memcpy((unsigned char*)dest + row * rowSize, (unsigned char*)mappedData.pData + row * mappedData.RowPitch, rowSize);
-        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)stagingTexture, 0);
+        URHO3D_LOGD3DERROR("Failed to map staging texture for GetData", hr);
         stagingTexture->Release();
-        return true;
+        return false;
     }
     else
     {
-        URHO3D_LOGERROR("Failed to map staging texture for GetData");
+        for (unsigned row = 0; row < numRows; ++row)
+            memcpy((unsigned char*)dest + row * rowSize, (unsigned char*)mappedData.pData + row * mappedData.RowPitch, rowSize);
+        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)stagingTexture, 0);
         stagingTexture->Release();
-        return false;
+        return true;
     }
 }
 
@@ -698,10 +685,11 @@ bool TextureCube::Create()
     textureDesc.CPUAccessFlags = usage_ == TEXTURE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0;
     textureDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
 
-    graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
-    if (!object_)
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create texture");
+        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_LOGD3DERROR("Failed to create texture", hr);
         return false;
     }
 
@@ -711,11 +699,12 @@ bool TextureCube::Create()
     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
     resourceViewDesc.Texture2D.MipLevels = (UINT)levels_;
 
-    graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
-    if (!shaderResourceView_)
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Failed to create shader resource view for texture");
+        URHO3D_SAFE_RELEASE(shaderResourceView_);
+        URHO3D_LOGD3DERROR("Failed to create shader resource view for texture", hr);
         return false;
     }
 
@@ -723,8 +712,6 @@ bool TextureCube::Create()
     {
         for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
         {
-            renderSurfaces_[i] = new RenderSurface(this);
-
             D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
             memset(&renderTargetViewDesc, 0, sizeof renderTargetViewDesc);
             renderTargetViewDesc.Format = textureDesc.Format;
@@ -733,12 +720,13 @@ bool TextureCube::Create()
             renderTargetViewDesc.Texture2DArray.FirstArraySlice = i;
             renderTargetViewDesc.Texture2DArray.MipSlice = 0;
 
-            graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
+            hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
                 (ID3D11RenderTargetView**)&renderSurfaces_[i]->renderTargetView_);
 
-            if (!renderSurfaces_[i]->renderTargetView_)
+            if (FAILED(hr))
             {
-                URHO3D_LOGERROR("Failed to create rendertarget view for texture");
+                URHO3D_SAFE_RELEASE(renderSurfaces_[i]->renderTargetView_);
+                URHO3D_LOGD3DERROR("Failed to create rendertarget view for texture", hr);
                 return false;
             }
         }

+ 13 - 15
Source/Urho3D/Graphics/Direct3D11/D3D11VertexBuffer.cpp

@@ -132,20 +132,16 @@ void VertexBuffer::Release()
 {
     Unlock();
 
-    if (object_)
+    if (graphics_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
         {
             if (graphics_->GetVertexBuffer(i) == this)
                 graphics_->SetVertexBuffer(0);
         }
-
-        ((ID3D11Buffer*)object_)->Release();
-        object_ = 0;
     }
+
+    URHO3D_SAFE_RELEASE(object_);
 }
 
 void VertexBuffer::SetShadowed(bool enable)
@@ -434,11 +430,11 @@ bool VertexBuffer::Create()
         bufferDesc.Usage = dynamic_ ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
         bufferDesc.ByteWidth = (UINT)(vertexCount_ * vertexSize_);
 
-        graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
-
-        if (!object_)
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Failed to create vertex buffer");
+            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_LOGD3DERROR("Failed to create vertex buffer", hr);
             return false;
         }
     }
@@ -463,13 +459,15 @@ void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
             D3D11_MAP_WRITE, 0, &mappedData);
-        hwData = mappedData.pData;
-        if (!hwData)
-            URHO3D_LOGERROR("Failed to map vertex buffer");
+        if (FAILED(hr) || !mappedData.pData)
+            URHO3D_LOGD3DERROR("Failed to map vertex buffer", hr);
         else
+        {
+            hwData = mappedData.pData;
             lockState_ = LOCK_HARDWARE;
+        }
     }
 
     return hwData;

+ 9 - 13
Source/Urho3D/Graphics/Direct3D11/D3D11VertexDeclaration.cpp

@@ -68,25 +68,21 @@ VertexDeclaration::VertexDeclaration(Graphics* graphics, ShaderVariation* vertex
     if (elementDescs.Empty())
         return;
 
-    ID3D11InputLayout* d3dInputLayout = 0;
     const PODVector<unsigned char>& byteCode = vertexShader->GetByteCode();
 
-    graphics->GetImpl()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0],
-        byteCode.Size(), &d3dInputLayout);
-    if (d3dInputLayout)
-        inputLayout_ = d3dInputLayout;
-    else
-        URHO3D_LOGERRORF("Failed to create input layout for shader %s, missing element mask %d",
-            vertexShader->GetFullName().CString(), vertexShader->GetElementMask() & ~vbElementMask);
+    HRESULT hr = graphics->GetImpl()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0],
+        byteCode.Size(), (ID3D11InputLayout**)&inputLayout_);
+    if (FAILED(hr))
+    {
+        URHO3D_SAFE_RELEASE(inputLayout_);
+        URHO3D_LOGERRORF("Failed to create input layout for shader %s, missing element mask %d (HRESULT %x)",
+            vertexShader->GetFullName().CString(), vertexShader->GetElementMask() & ~vbElementMask, (unsigned)hr);
+    }
 }
 
 VertexDeclaration::~VertexDeclaration()
 {
-    if (inputLayout_)
-    {
-        ((ID3D11InputLayout*)inputLayout_)->Release();
-        inputLayout_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(inputLayout_);
 }
 
 }

+ 30 - 21
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -644,17 +644,24 @@ bool Graphics::TakeScreenShot(Image& destImage)
     }
 
     IDirect3DSurface9* surface = 0;
-    impl_->device_->CreateOffscreenPlainSurface(surfaceWidth, surfaceHeight, surfaceDesc.Format, D3DPOOL_SYSTEMMEM, &surface, 0);
-    if (!surface)
+    HRESULT hr = impl_->device_->CreateOffscreenPlainSurface(surfaceWidth, surfaceHeight, surfaceDesc.Format, D3DPOOL_SYSTEMMEM, &surface, 0);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not create surface for taking a screenshot");
+        URHO3D_SAFE_RELEASE(surface);
+        URHO3D_LOGD3DERROR("Could not create surface for taking a screenshot", hr);
         return false;
     }
 
     if (useBackBuffer)
-        impl_->device_->GetRenderTargetData(impl_->defaultColorSurface_, surface);
+        hr = impl_->device_->GetRenderTargetData(impl_->defaultColorSurface_, surface);
     else
-        impl_->device_->GetFrontBufferData(0, surface);
+        hr = impl_->device_->GetFrontBufferData(0, surface);
+    if (FAILED(hr))
+    {
+        URHO3D_SAFE_RELEASE(surface);
+        URHO3D_LOGD3DERROR("Could not get rendertarget data for taking a screenshot", hr);
+        return false;
+    }
 
     // If capturing the whole screen, determine the window rect
     RECT sourceRect;
@@ -674,11 +681,11 @@ bool Graphics::TakeScreenShot(Image& destImage)
 
     D3DLOCKED_RECT lockedRect;
     lockedRect.pBits = 0;
-    surface->LockRect(&lockedRect, &sourceRect, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
-    if (!lockedRect.pBits)
+    hr = surface->LockRect(&lockedRect, &sourceRect, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
+    if (FAILED(hr) || !lockedRect.pBits)
     {
-        URHO3D_LOGERROR("Could not lock surface for taking a screenshot");
-        surface->Release();
+        URHO3D_SAFE_RELEASE(surface);
+        URHO3D_LOGD3DERROR("Could not lock surface for taking a screenshot", hr);
         return false;
     }
 
@@ -869,8 +876,10 @@ bool Graphics::ResolveToTexture(Texture2D* destination, const IntRect& viewport)
     destRect.right = destination->GetWidth();
     destRect.bottom = destination->GetHeight();
 
-    return SUCCEEDED(impl_->device_->StretchRect(impl_->defaultColorSurface_, &rect,
-        (IDirect3DSurface9*)destination->GetRenderSurface()->GetSurface(), &destRect, D3DTEXF_NONE));
+    HRESULT hr = impl_->device_->StretchRect(impl_->defaultColorSurface_, &rect,
+        (IDirect3DSurface9*)destination->GetRenderSurface()->GetSurface(), &destRect, D3DTEXF_NONE);
+    if (FAILED(hr))
+        URHO3D_LOGD3DERROR("Failed to resolve to texture", hr);
 }
 
 void Graphics::Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount)
@@ -976,10 +985,7 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, const P
         {
             SharedPtr<VertexDeclaration> newDeclaration(new VertexDeclaration(this, buffers, elementMasks));
             if (!newDeclaration->GetDeclaration())
-            {
-                URHO3D_LOGERROR("Failed to create vertex declaration");
                 return false;
-            }
 
             vertexDeclarations_[hash] = newDeclaration;
         }
@@ -2442,15 +2448,17 @@ bool Graphics::CreateInterface()
         return false;
     }
 
-    if (FAILED(impl_->interface_->GetDeviceCaps(impl_->adapter_, impl_->deviceType_, &impl_->deviceCaps_)))
+    HRESULT hr = impl_->interface_->GetDeviceCaps(impl_->adapter_, impl_->deviceType_, &impl_->deviceCaps_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not get Direct3D capabilities");
+        URHO3D_LOGD3DERROR("Could not get Direct3D capabilities", hr);
         return false;
     }
 
-    if (FAILED(impl_->interface_->GetAdapterIdentifier(impl_->adapter_, 0, &impl_->adapterIdentifier_)))
+    hr = impl_->interface_->GetAdapterIdentifier(impl_->adapter_, 0, &impl_->adapterIdentifier_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not get Direct3D adapter identifier");
+        URHO3D_LOGD3DERROR("Could not get Direct3D adapter identifier", hr);
         return false;
     }
 
@@ -2479,15 +2487,16 @@ bool Graphics::CreateDevice(unsigned adapter, unsigned deviceType)
     else
         behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
 
-    if (FAILED(impl_->interface_->CreateDevice(
+    HRESULT hr = impl_->interface_->CreateDevice(
         adapter,
         (D3DDEVTYPE)deviceType,
         GetWindowHandle(impl_->window_),
         behaviorFlags,
         &impl_->presentParams_,
-        &impl_->device_)))
+        &impl_->device_);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not create Direct3D9 device");
+        URHO3D_LOGD3DERROR("Could not create Direct3D9 device", hr);
         return false;
     }
 

+ 4 - 0
Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.h

@@ -30,6 +30,10 @@
 namespace Urho3D
 {
 
+#define URHO3D_SAFE_RELEASE(p) if (p) { ((IUnknown*)p)->Release();  p = 0; }
+
+#define URHO3D_LOGD3DERROR(msg, hr) URHO3D_LOGERRORF("%s (HRESULT %x)", msg, (unsigned)hr)
+
 /// %Graphics implementation. Holds API-specific objects.
 class URHO3D_API GraphicsImpl
 {

+ 11 - 15
Source/Urho3D/Graphics/Direct3D9/D3D9IndexBuffer.cpp

@@ -79,17 +79,10 @@ void IndexBuffer::Release()
 {
     Unlock();
 
-    if (object_)
-    {
-        if (!graphics_)
-            return;
+    if (graphics_ && graphics_->GetIndexBuffer() == this)
+        graphics_->SetIndexBuffer(0);
 
-        if (graphics_->GetIndexBuffer() == this)
-            graphics_->SetIndexBuffer(0);
-
-        ((IDirect3DIndexBuffer9*)object_)->Release();
-        object_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(object_);
 }
 
 void IndexBuffer::SetShadowed(bool enable)
@@ -362,15 +355,17 @@ bool IndexBuffer::Create()
         }
 
         IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-        if (!device || FAILED(device->CreateIndexBuffer(
+        HRESULT hr = device->CreateIndexBuffer(
             indexCount_ * indexSize_,
             usage_,
             indexSize_ == sizeof(unsigned) ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
             (D3DPOOL)pool_,
             (IDirect3DIndexBuffer9**)&object_,
-            0)))
+            0);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not create index buffer");
+            URHO3D_SAFE_RELEASE(object_)
+            URHO3D_LOGD3DERROR("Could not create index buffer", hr);
             return false;
         }
     }
@@ -397,8 +392,9 @@ void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
         if (discard && usage_ & D3DUSAGE_DYNAMIC)
             flags = D3DLOCK_DISCARD;
 
-        if (FAILED(((IDirect3DIndexBuffer9*)object_)->Lock(start * indexSize_, count * indexSize_, &hwData, flags)))
-            URHO3D_LOGERROR("Could not lock index buffer");
+        HRESULT hr = ((IDirect3DIndexBuffer9*)object_)->Lock(start * indexSize_, count * indexSize_, &hwData, flags);
+        if (FAILED(hr))
+            URHO3D_LOGD3DERROR("Could not lock index buffer", hr);
         else
             lockState_ = LOCK_HARDWARE;
     }

+ 3 - 7
Source/Urho3D/Graphics/Direct3D9/D3D9RenderSurface.cpp

@@ -108,10 +108,7 @@ void RenderSurface::QueueUpdate()
 void RenderSurface::Release()
 {
     Graphics* graphics = parentTexture_->GetGraphics();
-    if (!graphics)
-        return;
-
-    if (surface_)
+    if (graphics)
     {
         for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
         {
@@ -121,10 +118,9 @@ void RenderSurface::Release()
 
         if (graphics->GetDepthStencil() == this)
             graphics->ResetDepthStencil();
-
-        ((IDirect3DSurface9*)surface_)->Release();
-        surface_ = 0;
     }
+
+    URHO3D_SAFE_RELEASE(surface_);
 }
 
 int RenderSurface::GetWidth() const

+ 28 - 26
Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.cpp

@@ -88,17 +88,25 @@ bool ShaderVariation::Create()
     IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
     if (type_ == VS)
     {
-        if (!device || FAILED(device->CreateVertexShader(
+        HRESULT hr = device->CreateVertexShader(
             (const DWORD*)&byteCode[0],
-            (IDirect3DVertexShader9**)&object_)))
-            compilerOutput_ = "Could not create vertex shader";
+            (IDirect3DVertexShader9**)&object_);
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(object_);
+            compilerOutput_ = "Could not create vertex shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
+        }
     }
     else
     {
-        if (!device || FAILED(device->CreatePixelShader(
+        HRESULT hr = device->CreatePixelShader(
             (const DWORD*)&byteCode[0],
-            (IDirect3DPixelShader9**)&object_)))
-            compilerOutput_ = "Could not create pixel shader";
+            (IDirect3DPixelShader9**)&object_);
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(object_);
+            compilerOutput_ = "Could not create pixel shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
+        }
     }
 
     return object_ != 0;
@@ -106,31 +114,24 @@ bool ShaderVariation::Create()
 
 void ShaderVariation::Release()
 {
-    if (object_)
+    if (object_ && graphics_)
     {
-        if (!graphics_)
-            return;
-
         graphics_->CleanupShaderPrograms(this);
 
         if (type_ == VS)
         {
             if (graphics_->GetVertexShader() == this)
                 graphics_->SetShaders(0, 0);
-
-            ((IDirect3DVertexShader9*)object_)->Release();
         }
         else
         {
             if (graphics_->GetPixelShader() == this)
                 graphics_->SetShaders(0, 0);
-
-            ((IDirect3DPixelShader9*)object_)->Release();
         }
-
-        object_ = 0;
     }
 
+    URHO3D_SAFE_RELEASE(object_);
+
     compilerOutput_.Clear();
 
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
@@ -279,13 +280,16 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
     macros.Push(endMacro);
 
     // Compile using D3DCompile
+    ID3DBlob* shaderCode = 0;
+    ID3DBlob* errorMsgs = 0;
 
-    LPD3DBLOB shaderCode = 0;
-    LPD3DBLOB errorMsgs = 0;
-
-    if (FAILED(D3DCompile(sourceCode.CString(), sourceCode.Length(), owner_->GetName().CString(), &macros.Front(), 0,
-        entryPoint, profile, flags, 0, &shaderCode, &errorMsgs)))
-        compilerOutput_ = String((const char*)errorMsgs->GetBufferPointer(), (unsigned)errorMsgs->GetBufferSize());
+    HRESULT hr = D3DCompile(sourceCode.CString(), sourceCode.Length(), owner_->GetName().CString(), &macros.Front(), 0,
+        entryPoint, profile, flags, 0, &shaderCode, &errorMsgs);
+    if (FAILED(hr))
+    {
+        // Do not include end zero unnecessarily
+        compilerOutput_ = String((const char*)errorMsgs->GetBufferPointer(), (unsigned)errorMsgs->GetBufferSize() - 1);
+    }
     else
     {
         if (type_ == VS)
@@ -300,10 +304,8 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
         CopyStrippedCode(byteCode, bufData, bufSize);
     }
 
-    if (shaderCode)
-        shaderCode->Release();
-    if (errorMsgs)
-        errorMsgs->Release();
+    URHO3D_SAFE_RELEASE(shaderCode);
+    URHO3D_SAFE_RELEASE(errorMsgs);
 
     return !byteCode.Empty();
 }

+ 46 - 31
Source/Urho3D/Graphics/Direct3D9/D3D9Texture2D.cpp

@@ -133,32 +133,29 @@ void Texture2D::OnDeviceReset()
 
 void Texture2D::Release()
 {
-    if (object_)
+    if (graphics_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
             if (graphics_->GetTexture(i) == this)
                 graphics_->SetTexture(i, 0);
         }
+    }
 
-        if (renderSurface_)
-            renderSurface_->Release();
+    if (renderSurface_)
+        renderSurface_->Release();
 
-        ((IDirect3DTexture9*)object_)->Release();
-        object_ = 0;
-    }
-    else
-    {
-        if (renderSurface_)
-            renderSurface_->Release();
-    }
+    URHO3D_SAFE_RELEASE(object_);
 }
 
 bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
 {
+    if (width <= 0 || height <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative texture dimensions");
+        return false;
+    }
+
     // Delete the old rendersurface if any
     renderSurface_.Reset();
     pool_ = D3DPOOL_MANAGED;
@@ -251,9 +248,10 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
     if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && pool_ == D3DPOOL_DEFAULT)
         flags |= D3DLOCK_DISCARD;
 
-    if (FAILED(((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags)))
+    HRESULT hr = ((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not lock texture");
+        URHO3D_LOGD3DERROR("Could not lock texture", hr);
         return false;
     }
 
@@ -486,26 +484,35 @@ bool Texture2D::GetData(unsigned level, void* dest) const
         }
 
         IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-        device->CreateOffscreenPlainSurface((UINT)width_, (UINT)height_, (D3DFORMAT)format_,
+        HRESULT hr = device->CreateOffscreenPlainSurface((UINT)width_, (UINT)height_, (D3DFORMAT)format_,
             D3DPOOL_SYSTEMMEM, &offscreenSurface, 0);
-        if (!offscreenSurface)
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(offscreenSurface);
+            URHO3D_LOGD3DERROR("Could not create surface for getting rendertarget data", hr);
+            return false;
+        }
+        hr = device->GetRenderTargetData((IDirect3DSurface9*)renderSurface_->GetSurface(), offscreenSurface);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not create surface for getting rendertarget data");
+            URHO3D_LOGD3DERROR("Could not get rendertarget data", hr);
+            offscreenSurface->Release();
             return false;
         }
-        device->GetRenderTargetData((IDirect3DSurface9*)renderSurface_->GetSurface(), offscreenSurface);
-        if (FAILED(offscreenSurface->LockRect(&d3dLockedRect, &d3dRect, D3DLOCK_READONLY)))
+        hr = offscreenSurface->LockRect(&d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not lock surface for getting rendertarget data");
+            URHO3D_LOGD3DERROR("Could not lock surface for getting rendertarget data", hr);
             offscreenSurface->Release();
             return false;
         }
     }
     else
     {
-        if (FAILED(((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY)))
+        HRESULT hr = ((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not lock texture");
+            URHO3D_LOGD3DERROR("Could not lock texture", hr);
             return false;
         }
     }
@@ -591,7 +598,7 @@ bool Texture2D::Create()
     // If creating a depth-stencil texture, and it is not supported, create a depth-stencil surface instead
     if (usage_ & D3DUSAGE_DEPTHSTENCIL && !graphics_->GetImpl()->CheckFormatSupport((D3DFORMAT)format_, usage_, D3DRTYPE_TEXTURE))
     {
-        if (!device || FAILED(device->CreateDepthStencilSurface(
+        HRESULT hr = device->CreateDepthStencilSurface(
             (UINT)width_,
             (UINT)height_,
             (D3DFORMAT)format_,
@@ -599,9 +606,11 @@ bool Texture2D::Create()
             0,
             FALSE,
             (IDirect3DSurface9**)&renderSurface_->surface_,
-            0)))
+            0);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not create depth-stencil surface");
+            URHO3D_SAFE_RELEASE(renderSurface_->surface_);
+            URHO3D_LOGD3DERROR("Could not create depth-stencil surface", hr);
             return false;
         }
 
@@ -609,7 +618,7 @@ bool Texture2D::Create()
     }
     else
     {
-        if (!device || FAILED(graphics_->GetImpl()->GetDevice()->CreateTexture(
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture(
             (UINT)width_,
             (UINT)height_,
             requestedLevels_,
@@ -617,16 +626,22 @@ bool Texture2D::Create()
             (D3DFORMAT)format_,
             (D3DPOOL)pool_,
             (IDirect3DTexture9**)&object_,
-            0)))
+            0);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not create texture");
+            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_LOGD3DERROR("Could not create texture", hr);
             return false;
         }
 
         levels_ = ((IDirect3DTexture9*)object_)->GetLevelCount();
 
         if (usage_ & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
-            ((IDirect3DTexture9*)object_)->GetSurfaceLevel(0, (IDirect3DSurface9**)&renderSurface_->surface_);
+        {
+            hr = ((IDirect3DTexture9*)object_)->GetSurfaceLevel(0, (IDirect3DSurface9**)&renderSurface_->surface_);
+            if (FAILED(hr))
+                URHO3D_LOGD3DERROR("Could not get rendertarget surface", hr);
+        }
     }
 
     return true;

+ 25 - 48
Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.cpp

@@ -177,60 +177,40 @@ void Texture3D::OnDeviceReset()
 
 void Texture3D::Release()
 {
-    if (object_)
+    if (graphics_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
             if (graphics_->GetTexture(i) == this)
                 graphics_->SetTexture(i, 0);
         }
+    }
 
-        if (renderSurface_)
-            renderSurface_->Release();
+    URHO3D_SAFE_RELEASE(object_);
+}
 
-        ((IDirect3DVolumeTexture9*)object_)->Release();
-        object_ = 0;
+bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
+{
+    if (width <= 0 || height <= 0 || depth <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
+        return false;
     }
-    else
+    if (usage >= TEXTURE_RENDERTARGET)
     {
-        if (renderSurface_)
-            renderSurface_->Release();
+        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
+        return false;
     }
-}
 
-bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
-{
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
     pool_ = D3DPOOL_MANAGED;
     usage_ = 0;
 
-    if (usage == TEXTURE_RENDERTARGET)
-    {
-        renderSurface_ = new RenderSurface(this);
-        usage_ |= D3DUSAGE_RENDERTARGET;
-        pool_ = D3DPOOL_DEFAULT;
-
-        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
-        addressMode_[COORD_U] = ADDRESS_CLAMP;
-        addressMode_[COORD_V] = ADDRESS_CLAMP;
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage == TEXTURE_DYNAMIC)
+    if (usage == TEXTURE_DYNAMIC)
     {
         usage_ |= D3DUSAGE_DYNAMIC;
         pool_ = D3DPOOL_DEFAULT;
     }
 
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture3D, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
     width_ = width;
     height_ = height;
     depth_ = depth;
@@ -298,9 +278,10 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
         pool_ == D3DPOOL_DEFAULT)
         flags |= D3DLOCK_DISCARD;
 
-    if (FAILED(((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags)))
+    HRESULT hr = ((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not lock texture");
+        URHO3D_LOGD3DERROR("Could not lock texture", hr);
         return false;
     }
 
@@ -542,9 +523,10 @@ bool Texture3D::GetData(unsigned level, void* dest) const
     d3dBox.Bottom = (UINT)levelHeight;
     d3dBox.Back = (UINT)levelDepth;
 
-    if (FAILED(((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, &d3dBox, D3DLOCK_READONLY)))
+    HRESULT hr = ((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, &d3dBox, D3DLOCK_READONLY);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not lock texture");
+        URHO3D_LOGD3DERROR("Could not lock texture", hr);
         return false;
     }
 
@@ -628,8 +610,7 @@ bool Texture3D::Create()
     }
 
     IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-
-    if (!device || FAILED(graphics_->GetImpl()->GetDevice()->CreateVolumeTexture(
+    HRESULT hr = device->CreateVolumeTexture(
         (UINT)width_,
         (UINT)height_,
         (UINT)depth_,
@@ -638,9 +619,11 @@ bool Texture3D::Create()
         (D3DFORMAT)format_,
         (D3DPOOL)pool_,
         (IDirect3DVolumeTexture9**)&object_,
-        0)))
+        0);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not create texture");
+        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_LOGD3DERROR("Could not create texture", hr);
         return false;
     }
 
@@ -649,10 +632,4 @@ bool Texture3D::Create()
     return true;
 }
 
-void Texture3D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS)
-        renderSurface_->QueueUpdate();
-}
-
 }

+ 0 - 7
Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.h

@@ -65,17 +65,10 @@ public:
     /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
     bool GetData(unsigned level, void* dest) const;
 
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
 private:
     /// Create texture.
     bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
 
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
     /// Image file acquired during BeginLoad.
     SharedPtr<Image> loadImage_;
     /// Parameter file acquired during BeginLoad.

+ 35 - 27
Source/Urho3D/Graphics/Direct3D9/D3D9TextureCube.cpp

@@ -279,26 +279,22 @@ void TextureCube::OnDeviceReset()
 
 void TextureCube::Release()
 {
-    if (object_)
+    if (graphics_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
             if (graphics_->GetTexture(i) == this)
                 graphics_->SetTexture(i, 0);
         }
+    }
 
-        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-        {
-            if (renderSurfaces_[i])
-                renderSurfaces_[i]->Release();
-        }
-
-        ((IDirect3DCubeTexture9*)object_)->Release();
-        object_ = 0;
+    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+    {
+        if (renderSurfaces_[i])
+            renderSurfaces_[i]->Release();
     }
+
+    URHO3D_SAFE_RELEASE(object_);
 }
 
 bool TextureCube::SetSize(int size, unsigned format, TextureUsage usage)
@@ -408,10 +404,11 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
     if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && pool_ == D3DPOOL_DEFAULT)
         flags |= D3DLOCK_DISCARD;
 
-    if (FAILED(((IDirect3DCubeTexture9*)object_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect,
-        (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags)))
+    HRESULT hr = ((IDirect3DCubeTexture9*)object_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect,
+        (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not lock texture");
+        URHO3D_LOGD3DERROR("Could not lock texture", hr);
         return false;
     }
 
@@ -704,26 +701,33 @@ bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
         }
 
         IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-        device->CreateOffscreenPlainSurface((UINT)width_, (UINT)height_, (D3DFORMAT)format_, D3DPOOL_SYSTEMMEM, &offscreenSurface, 0);
-        if (!offscreenSurface)
+        HRESULT hr = device->CreateOffscreenPlainSurface((UINT)width_, (UINT)height_, (D3DFORMAT)format_, D3DPOOL_SYSTEMMEM, &offscreenSurface, 0);
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(offscreenSurface);
+            URHO3D_LOGD3DERROR("Could not create surface for getting rendertarget data", hr);
+            return false;
+        }
+        hr = device->GetRenderTargetData((IDirect3DSurface9*)renderSurfaces_[face]->GetSurface(), offscreenSurface);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not create surface for getting rendertarget data");
+            URHO3D_LOGD3DERROR("Could not get rendertarget data", hr);
+            offscreenSurface->Release();
             return false;
         }
-        device->GetRenderTargetData((IDirect3DSurface9*)renderSurfaces_[face]->GetSurface(), offscreenSurface);
         if (FAILED(offscreenSurface->LockRect(&d3dLockedRect, &d3dRect, D3DLOCK_READONLY)))
         {
-            URHO3D_LOGERROR("Could not lock surface for getting rendertarget data");
+            URHO3D_LOGD3DERROR("Could not lock surface for getting rendertarget data", hr);
             offscreenSurface->Release();
             return false;
         }
     }
     else
     {
-        if (FAILED(
-            ((IDirect3DCubeTexture9*)object_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY)))
+        HRESULT hr = ((IDirect3DCubeTexture9*)object_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not lock texture");
+            URHO3D_LOGD3DERROR("Could not lock texture", hr);
             return false;
         }
     }
@@ -806,16 +810,18 @@ bool TextureCube::Create()
     }
 
     IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-    if (!device || FAILED(device->CreateCubeTexture(
+    HRESULT hr = device->CreateCubeTexture(
         (UINT)width_,
         requestedLevels_,
         usage_,
         (D3DFORMAT)format_,
         (D3DPOOL)pool_,
         (IDirect3DCubeTexture9**)&object_,
-        0)))
+        0);
+    if (FAILED(hr))
     {
-        URHO3D_LOGERROR("Could not create cube texture");
+        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_LOGD3DERROR("Could not create cube texture", hr);
         return false;
     }
 
@@ -825,8 +831,10 @@ bool TextureCube::Create()
     {
         for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
         {
-            ((IDirect3DCubeTexture9*)object_)->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0,
+            hr = ((IDirect3DCubeTexture9*)object_)->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0,
                 (IDirect3DSurface9**)&renderSurfaces_[i]->surface_);
+            if (FAILED(hr))
+                URHO3D_LOGD3DERROR("Could not get rendertarget surface", hr);
         }
     }
 

+ 11 - 12
Source/Urho3D/Graphics/Direct3D9/D3D9VertexBuffer.cpp

@@ -98,20 +98,16 @@ void VertexBuffer::Release()
 {
     Unlock();
 
-    if (object_)
+    if (graphics_)
     {
-        if (!graphics_)
-            return;
-
         for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
         {
             if (graphics_->GetVertexBuffer(i) == this)
                 graphics_->SetVertexBuffer(0);
         }
-
-        ((IDirect3DVertexBuffer9*)object_)->Release();
-        object_ = 0;
     }
+
+    URHO3D_SAFE_RELEASE(object_);
 }
 
 void VertexBuffer::SetShadowed(bool enable)
@@ -400,15 +396,17 @@ bool VertexBuffer::Create()
         }
 
         IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-        if (!device || FAILED(device->CreateVertexBuffer(
+        HRESULT hr = device->CreateVertexBuffer(
             vertexCount_ * vertexSize_,
             usage_,
             0,
             (D3DPOOL)pool_,
             (IDirect3DVertexBuffer9**)&object_,
-            0)))
+            0);
+        if (FAILED(hr))
         {
-            URHO3D_LOGERROR("Could not create vertex buffer");
+            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_LOGD3DERROR("Could not create vertex buffer", hr);
             return false;
         }
     }
@@ -435,8 +433,9 @@ void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
         if (discard && usage_ & D3DUSAGE_DYNAMIC)
             flags = D3DLOCK_DISCARD;
 
-        if (FAILED(((IDirect3DVertexBuffer9*)object_)->Lock(start * vertexSize_, count * vertexSize_, &hwData, flags)))
-            URHO3D_LOGERROR("Could not lock vertex buffer");
+        HRESULT hr = ((IDirect3DVertexBuffer9*)object_)->Lock(start * vertexSize_, count * vertexSize_, &hwData, flags);
+        if (FAILED(hr))
+            URHO3D_LOGD3DERROR("Could not lock vertex buffer", hr);
         else
             lockState_ = LOCK_HARDWARE;
     }

+ 7 - 9
Source/Urho3D/Graphics/Direct3D9/D3D9VertexDeclaration.cpp

@@ -231,19 +231,17 @@ void VertexDeclaration::Create(Graphics* graphics, const PODVector<VertexDeclara
     dest->UsageIndex = 0;
 
     IDirect3DDevice9* device = graphics->GetImpl()->GetDevice();
-    if (!device)
-        return;
-
-    device->CreateVertexDeclaration(elementArray, &declaration_);
+    HRESULT hr = device->CreateVertexDeclaration(elementArray, &declaration_);
+    if (FAILED(hr))
+    {
+        URHO3D_SAFE_RELEASE(declaration_);
+        URHO3D_LOGD3DERROR("Failed to create vertex declaration", hr);
+    }
 }
 
 void VertexDeclaration::Release()
 {
-    if (declaration_)
-    {
-        declaration_->Release();
-        declaration_ = 0;
-    }
+    URHO3D_SAFE_RELEASE(declaration_);
 }
 
 }

+ 6 - 0
Source/Urho3D/Graphics/OpenGL/OGLTexture2D.cpp

@@ -166,6 +166,12 @@ void Texture2D::Release()
 
 bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
 {
+    if (width <= 0 || height <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative texture dimensions");
+        return false;
+    }
+
     // Delete the old rendersurface if any
     renderSurface_.Reset();
 

+ 8 - 33
Source/Urho3D/Graphics/OpenGL/OGLTexture3D.cpp

@@ -159,9 +159,6 @@ bool Texture3D::EndLoad()
 void Texture3D::OnDeviceLost()
 {
     GPUObject::OnDeviceLost();
-
-    if (renderSurface_)
-        renderSurface_->OnDeviceLost();
 }
 
 void Texture3D::OnDeviceReset()
@@ -196,41 +193,25 @@ void Texture3D::Release()
                 graphics_->SetTexture(i, 0);
         }
 
-        if (renderSurface_)
-            renderSurface_->Release();
-
         glDeleteTextures(1, &object_);
         object_ = 0;
     }
-    else
-    {
-        if (renderSurface_)
-            renderSurface_->Release();
-    }
 }
 
 bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
 {
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
-
-    usage_ = usage;
-
+    if (width <= 0 || height <= 0 || depth <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
+        return false;
+    }
     if (usage >= TEXTURE_RENDERTARGET)
     {
-        renderSurface_ = new RenderSurface(this);
-
-        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
-        addressMode_[COORD_U] = ADDRESS_CLAMP;
-        addressMode_[COORD_V] = ADDRESS_CLAMP;
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
+        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
+        return false;
     }
 
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture3D, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
+    usage_ = usage;
 
     width_ = width;
     height_ = height;
@@ -555,10 +536,4 @@ bool Texture3D::Create()
 #endif
 }
 
-void Texture3D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS)
-        renderSurface_->QueueUpdate();
-}
-
 }

+ 0 - 8
Source/Urho3D/Graphics/OpenGL/OGLTexture3D.h

@@ -64,19 +64,11 @@ public:
     /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
     bool GetData(unsigned level, void* dest) const;
 
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
 protected:
     /// Create texture.
     virtual bool Create();
 
 private:
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
     /// Image file acquired during BeginLoad.
     SharedPtr<Image> loadImage_;
     /// Parameter file acquired during BeginLoad.

+ 38 - 0
Source/Urho3D/LuaScript/pkgs/Graphics/Texture3D.pkg

@@ -0,0 +1,38 @@
+$#include "Graphics/Texture3D.h"
+
+enum TextureUsage{};
+
+class Texture3D : public Texture
+{
+    Texture3D();
+    ~Texture3D();
+
+    bool SetSize(int width, int height, int depth, unsigned format, TextureUsage usage = TEXTURE_STATIC);
+
+    // bool SetData(SharedPtr<Image> image, bool useAlpha = false);
+    tolua_outside bool Texture3DSetData @ SetData(Image* image, bool useAlpha = false);
+};
+
+${
+#define TOLUA_DISABLE_tolua_GraphicsLuaAPI_Texture3D_new00
+static int tolua_GraphicsLuaAPI_Texture3D_new00(lua_State* tolua_S)
+{
+    return ToluaNewObject<Texture3D>(tolua_S);
+}
+
+#define TOLUA_DISABLE_tolua_GraphicsLuaAPI_Texture3D_new00_local
+static int tolua_GraphicsLuaAPI_Texture3D_new00_local(lua_State* tolua_S)
+{
+    return ToluaNewObjectGC<Texture3D>(tolua_S);
+}
+
+static bool Texture3DSetData(Texture3D* texture, Image* image, bool useAlpha)
+{
+    SharedPtr<Image> imagePtr(image);
+    bool ret = texture->SetData(imagePtr, useAlpha);
+    // Need to safely detach the object from the shared pointer so that the Lua script can manually
+    // delete the object once done
+    imagePtr.Detach();
+    return ret;
+}
+$}

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/GraphicsLuaAPI.pkg

@@ -32,6 +32,7 @@ $pfile "Graphics/Terrain.pkg"
 $pfile "Graphics/TerrainPatch.pkg"
 $pfile "Graphics/Texture.pkg"
 $pfile "Graphics/Texture2D.pkg"
+$pfile "Graphics/Texture3D.pkg"
 $pfile "Graphics/TextureCube.pkg"
 $pfile "Graphics/Viewport.pkg"
 $pfile "Graphics/Zone.pkg"