Browse Source

Multisampled texture on D3D11.

Lasse Öörni 9 years ago
parent
commit
a7f3c61bdf

+ 29 - 0
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -730,6 +730,20 @@ bool Graphics::ResolveToTexture(Texture2D* destination, const IntRect& viewport)
     return true;
     return true;
 }
 }
 
 
+bool Graphics::ResolveToTexture(Texture2D* texture)
+{
+    if (!texture)
+        return false;
+
+    ID3D11Resource* source = (ID3D11Resource*)texture->GetGPUObject();
+    ID3D11Resource* dest = (ID3D11Resource*)texture->GetResolveTexture();
+    if (!source || !dest)
+        return false;
+
+    impl_->deviceContext_->ResolveSubresource(dest, 0, source, 0, (DXGI_FORMAT)texture->GetFormat());
+    return true;
+}
+
 void Graphics::Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount)
 void Graphics::Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount)
 {
 {
     if (!vertexCount || !impl_->shaderProgram_)
     if (!vertexCount || !impl_->shaderProgram_)
@@ -1280,6 +1294,16 @@ void Graphics::SetTexture(unsigned index, Texture* texture)
     {
     {
         if (renderTargets_[0] && renderTargets_[0]->GetParentTexture() == texture)
         if (renderTargets_[0] && renderTargets_[0]->GetParentTexture() == texture)
             texture = texture->GetBackupTexture();
             texture = texture->GetBackupTexture();
+        else
+        {
+            // Resolve multisampled texture now as necessary
+            if (texture->GetMultiSample() > 1 && texture->GetAutoResolve() && texture->IsResolveDirty())
+            {
+                if (texture->GetType() == Texture2D::GetTypeStatic())
+                    ResolveToTexture(static_cast<Texture2D*>(texture));
+                texture->SetResolveDirty(false);
+            }
+        }
     }
     }
 
 
     if (texture && texture->GetParametersDirty())
     if (texture && texture->GetParametersDirty())
@@ -1387,6 +1411,11 @@ void Graphics::SetRenderTarget(unsigned index, RenderSurface* renderTarget)
                 if (textures_[i] == parentTexture)
                 if (textures_[i] == parentTexture)
                     SetTexture(i, textures_[i]->GetBackupTexture());
                     SetTexture(i, textures_[i]->GetBackupTexture());
             }
             }
+            
+
+            // If multisampled, mark the texture needing resolve
+            if (parentTexture->GetMultiSample() > 1 && parentTexture->GetAutoResolve())
+                parentTexture->SetResolveDirty(true);
         }
         }
     }
     }
 }
 }

+ 24 - 6
Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.cpp

@@ -64,6 +64,7 @@ void Texture2D::Release()
         renderSurface_->Release();
         renderSurface_->Release();
 
 
     URHO3D_SAFE_RELEASE(object_.ptr_);
     URHO3D_SAFE_RELEASE(object_.ptr_);
+    URHO3D_SAFE_RELEASE(resolveTexture_);
     URHO3D_SAFE_RELEASE(shaderResourceView_);
     URHO3D_SAFE_RELEASE(shaderResourceView_);
     URHO3D_SAFE_RELEASE(sampler_);
     URHO3D_SAFE_RELEASE(sampler_);
 }
 }
@@ -371,8 +372,8 @@ bool Texture2D::Create()
     textureDesc.MipLevels = levels_;
     textureDesc.MipLevels = levels_;
     textureDesc.ArraySize = 1;
     textureDesc.ArraySize = 1;
     textureDesc.Format = (DXGI_FORMAT)(sRGB_ ? GetSRGBFormat(format_) : format_);
     textureDesc.Format = (DXGI_FORMAT)(sRGB_ ? GetSRGBFormat(format_) : format_);
-    textureDesc.SampleDesc.Count = 1;
-    textureDesc.SampleDesc.Quality = 0;
+    textureDesc.SampleDesc.Count = (UINT)multiSample_;
+    textureDesc.SampleDesc.Quality = multiSample_ > 1 ? 0xffffffff : 0;
     textureDesc.Usage = usage_ == TEXTURE_DYNAMIC ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
     textureDesc.Usage = usage_ == TEXTURE_DYNAMIC ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
     textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
     textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
     if (usage_ == TEXTURE_RENDERTARGET)
     if (usage_ == TEXTURE_RENDERTARGET)
@@ -389,13 +390,30 @@ bool Texture2D::Create()
         return false;
         return false;
     }
     }
 
 
+    // Create resolve texture for multisampling if necessary
+    if (multiSample_ > 1 && autoResolve_)
+    {
+        textureDesc.SampleDesc.Count = 1;
+        textureDesc.SampleDesc.Quality = 0;
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&resolveTexture_);
+        if (FAILED(hr))
+        {
+            URHO3D_SAFE_RELEASE(resolveTexture_);
+            URHO3D_LOGD3DERROR("Failed to create resolve texture", hr);
+            return false;
+        }
+    }
+
     D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
     D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
     memset(&resourceViewDesc, 0, sizeof resourceViewDesc);
     memset(&resourceViewDesc, 0, sizeof resourceViewDesc);
     resourceViewDesc.Format = (DXGI_FORMAT)GetSRVFormat(textureDesc.Format);
     resourceViewDesc.Format = (DXGI_FORMAT)GetSRVFormat(textureDesc.Format);
-    resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+    resourceViewDesc.ViewDimension = (multiSample_ > 1 && !autoResolve_) ? D3D11_SRV_DIMENSION_TEXTURE2DMS :
+        D3D11_SRV_DIMENSION_TEXTURE2D;
     resourceViewDesc.Texture2D.MipLevels = (UINT)levels_;
     resourceViewDesc.Texture2D.MipLevels = (UINT)levels_;
 
 
-    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_.ptr_, &resourceViewDesc,
+    // Sample the resolve texture if created, otherwise the original
+    ID3D11Resource* viewObject = resolveTexture_ ? (ID3D11Resource*)resolveTexture_ : (ID3D11Resource*)object_.ptr_;
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView(viewObject, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
         (ID3D11ShaderResourceView**)&shaderResourceView_);
     if (FAILED(hr))
     if (FAILED(hr))
     {
     {
@@ -409,7 +427,7 @@ bool Texture2D::Create()
         D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
         D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
         memset(&renderTargetViewDesc, 0, sizeof renderTargetViewDesc);
         memset(&renderTargetViewDesc, 0, sizeof renderTargetViewDesc);
         renderTargetViewDesc.Format = textureDesc.Format;
         renderTargetViewDesc.Format = textureDesc.Format;
-        renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+        renderTargetViewDesc.ViewDimension = multiSample_ > 1 ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
 
 
         hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_.ptr_, &renderTargetViewDesc,
         hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_.ptr_, &renderTargetViewDesc,
             (ID3D11RenderTargetView**)&renderSurface_->renderTargetView_);
             (ID3D11RenderTargetView**)&renderSurface_->renderTargetView_);
@@ -425,7 +443,7 @@ bool Texture2D::Create()
         D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
         D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
         memset(&depthStencilViewDesc, 0, sizeof depthStencilViewDesc);
         memset(&depthStencilViewDesc, 0, sizeof depthStencilViewDesc);
         depthStencilViewDesc.Format = (DXGI_FORMAT)GetDSVFormat(textureDesc.Format);
         depthStencilViewDesc.Format = (DXGI_FORMAT)GetDSVFormat(textureDesc.Format);
-        depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+        depthStencilViewDesc.ViewDimension = multiSample_ > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
 
 
         hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_.ptr_, &depthStencilViewDesc,
         hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_.ptr_, &depthStencilViewDesc,
             (ID3D11DepthStencilView**)&renderSurface_->renderTargetView_);
             (ID3D11DepthStencilView**)&renderSurface_->renderTargetView_);

+ 1 - 0
Source/Urho3D/Graphics/Texture.cpp

@@ -59,6 +59,7 @@ Texture::Texture(Context* context) :
     GPUObject(GetSubsystem<Graphics>()),
     GPUObject(GetSubsystem<Graphics>()),
     shaderResourceView_(0),
     shaderResourceView_(0),
     sampler_(0),
     sampler_(0),
+    resolveTexture_(0),
     format_(0),
     format_(0),
     usage_(TEXTURE_STATIC),
     usage_(TEXTURE_STATIC),
     levels_(0),
     levels_(0),

+ 5 - 0
Source/Urho3D/Graphics/Texture.h

@@ -150,6 +150,9 @@ public:
     /// Return sampler state object. Only used on Direct3D11.
     /// Return sampler state object. Only used on Direct3D11.
     void* GetSampler() const { return sampler_; }
     void* GetSampler() const { return sampler_; }
 
 
+    /// Return resolve texture. Only used on Direct3D11.
+    void* GetResolveTexture() const { return resolveTexture_; }
+
     /// Return texture's target. Only used on OpenGL.
     /// Return texture's target. Only used on OpenGL.
     unsigned GetTarget() const { return target_; }
     unsigned GetTarget() const { return target_; }
 
 
@@ -188,6 +191,8 @@ protected:
 
 
     /// Direct3D11 sampler state object.
     /// Direct3D11 sampler state object.
     void* sampler_;
     void* sampler_;
+    /// Direct3D11 resolve texture object when multisample with autoresolve is used.
+    void* resolveTexture_;
 
 
     /// Texture format.
     /// Texture format.
     unsigned format_;
     unsigned format_;