Преглед изворни кода

Added placeholder for shader resource view in Texture classes. Fixed shader creation from bytecode to use the correct bytecode size.

Lasse Öörni пре 10 година
родитељ
комит
1e1b44c4aa

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

@@ -1040,6 +1040,15 @@ void Graphics::SetTexture(unsigned index, Texture* texture)
     
     if (texture != textures_[index])
     {
+        if (firstDirtyTexture_ >= MAX_TEXTURE_UNITS)
+            firstDirtyTexture_ = lastDirtyTexture_ = index;
+        else
+        {
+            if (index < firstDirtyTexture_)
+                firstDirtyTexture_ = index;
+            if (index > lastDirtyTexture_)
+                lastDirtyTexture_ = index;
+        }
         textures_[index] = texture;
         texturesDirty_ = true;
     }
@@ -2117,6 +2126,7 @@ void Graphics::ResetCachedState()
     blendStateHash_ = M_MAX_UNSIGNED;
     depthStateHash_ = M_MAX_UNSIGNED;
     rasterizerStateHash_ = M_MAX_UNSIGNED;
+    firstDirtyTexture_ = lastDirtyTexture_ = M_MAX_UNSIGNED;
 }
 
 void Graphics::PrepareDraw()
@@ -2138,6 +2148,23 @@ void Graphics::PrepareDraw()
         renderTargetsDirty_ = false;
     }
 
+    if (texturesDirty_ && firstDirtyTexture_ < MAX_TEXTURE_UNITS)
+    {
+        static ID3D11ShaderResourceView* textureViews[MAX_TEXTURE_UNITS];
+
+        for (unsigned i = firstDirtyTexture_; i <= lastDirtyTexture_; ++i)
+            textureViews[i] = textures_[i] ? (ID3D11ShaderResourceView*)textures_[i]->GetShaderResourceView() : 0;
+        
+        // Set same textures for both vertex & pixel shaders
+        impl_->deviceContext_->VSSetShaderResources(firstDirtyTexture_, lastDirtyTexture_ - firstDirtyTexture_ + 1,
+            &textureViews[firstDirtyTexture_]);
+        impl_->deviceContext_->PSSetShaderResources(firstDirtyTexture_, lastDirtyTexture_ - firstDirtyTexture_ + 1,
+            &textureViews[firstDirtyTexture_]);
+
+        firstDirtyTexture_ = lastDirtyTexture_ = M_MAX_UNSIGNED;
+        texturesDirty_ = false;
+    }
+
     if (blendStateDirty_)
     {
         unsigned newBlendStateHash = (colorWrite_ ? 1 : 0) | (blendMode_ << 1);

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

@@ -589,6 +589,10 @@ private:
     unsigned depthStateHash_;
     /// Hash of current rasterizer state.
     unsigned rasterizerStateHash_;
+    /// First dirtied texture unit.
+    unsigned firstDirtyTexture_;
+    /// Last dirtied texture unit.
+    unsigned lastDirtyTexture_;
     /// Default texture filtering mode.
     TextureFilterMode defaultTextureFilterMode_;
     /// Shader parameters for all vertex/pixel shader combinations.

+ 24 - 24
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.cpp

@@ -70,31 +70,30 @@ bool ShaderVariation::Create()
     extension = type_ == VS ? ".vs4" : ".ps4";
     
     String binaryShaderName = path + "Cache/" + name + "_" + StringHash(defines_).ToString() + extension;
-    PODVector<unsigned> byteCode;
     
-    if (!LoadByteCode(byteCode, binaryShaderName))
+    if (!LoadByteCode(binaryShaderName))
     {
         // Compile shader if don't have valid bytecode
-        if (!Compile(byteCode))
+        if (!Compile())
             return false;
         // Save the bytecode after successful compile, but not if the source is from a package
         if (owner_->GetTimeStamp())
-            SaveByteCode(byteCode, binaryShaderName);
+            SaveByteCode(binaryShaderName);
     }
     
     // Then create shader from the bytecode
     ID3D11Device* device = graphics_->GetImpl()->GetDevice();
     if (type_ == VS)
     {
-        if (device && byteCode.Size())
-            device->CreateVertexShader(&byteCode[0], byteCode.Size(), 0, (ID3D11VertexShader**)&object_);
+        if (device && byteCode_.Size())
+            device->CreateVertexShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11VertexShader**)&object_);
         if (!object_)
             compilerOutput_ = "Could not create vertex shader";
     }
     else
     {
-        if (device && byteCode.Size())
-            device->CreatePixelShader(&byteCode[0], byteCode.Size(), 0, (ID3D11PixelShader**)&object_);
+        if (device && byteCode_.Size())
+            device->CreatePixelShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11PixelShader**)&object_);
         if (!object_)
             compilerOutput_ = "Could not create pixel shader";
     }
@@ -134,6 +133,7 @@ void ShaderVariation::Release()
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         useTextureUnit_[i] = false;
     parameters_.Clear();
+    byteCode_.Clear();
 }
 
 void ShaderVariation::SetName(const String& name)
@@ -151,7 +151,7 @@ Shader* ShaderVariation::GetOwner() const
     return owner_;
 }
 
-bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String& binaryShaderName)
+bool ShaderVariation::LoadByteCode(const String& binaryShaderName)
 {
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     if (!cache->Exists(binaryShaderName))
@@ -201,8 +201,8 @@ bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String&
     unsigned byteCodeSize = file->ReadUInt();
     if (byteCodeSize)
     {
-        byteCode.Resize(byteCodeSize >> 2);
-        file->Read(&byteCode[0], byteCodeSize);
+        byteCode_.Resize(byteCodeSize);
+        file->Read(&byteCode_[0], byteCodeSize);
         
         if (type_ == VS)
             LOGDEBUG("Loaded cached vertex shader " + GetFullName());
@@ -218,7 +218,7 @@ bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String&
     }
 }
 
-bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
+bool ShaderVariation::Compile()
 {
     const String& sourceCode = owner_->GetSourceCode(type_);
     Vector<String> defines = defines_.Split(' ');
@@ -293,8 +293,7 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
         
         unsigned char* bufData = (unsigned char*)shaderCode->GetBufferPointer();
         unsigned bufSize = shaderCode->GetBufferSize();
-        ParseParameters(bufData, bufSize);
-        CopyStrippedCode(byteCode, bufData, bufSize);
+        CopyStrippedCode(bufData, bufSize);
     }
 
     if (shaderCode)
@@ -302,20 +301,21 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
     if (errorMsgs)
         errorMsgs->Release();
     
-    return !byteCode.Empty();
+    return !byteCode_.Empty();
 }
 
-void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
+void ShaderVariation::ParseParameters()
 {
     /// \todo Implement
 }
 
-void ShaderVariation::CopyStrippedCode(PODVector<unsigned>& byteCode, unsigned char* bufData, unsigned bufSize)
+void ShaderVariation::CopyStrippedCode(unsigned char* bufData, unsigned bufSize)
 {
     unsigned const D3DSIO_COMMENT = 0xFFFE;
     unsigned* srcWords = (unsigned*)bufData;
     unsigned srcWordSize = bufSize >> 2;
-    
+    byteCode_.Clear();
+
     for (unsigned i = 0; i < srcWordSize; ++i)
     {
         unsigned opcode = srcWords[i] & 0xffff;
@@ -331,12 +331,13 @@ void ShaderVariation::CopyStrippedCode(PODVector<unsigned>& byteCode, unsigned c
         else
         {
             // Not a comment, copy the data
-            byteCode.Push(srcWords[i]);
+            byteCode_.Resize(byteCode_.Size() + sizeof(unsigned));
+            *((unsigned*)&byteCode_[byteCode_.Size() - 4]) = srcWords[i];
         }
     }
 }
 
-void ShaderVariation::SaveByteCode(const PODVector<unsigned>& byteCode, const String& binaryShaderName)
+void ShaderVariation::SaveByteCode(const String& binaryShaderName)
 {
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     FileSystem* fileSystem = owner_->GetSubsystem<FileSystem>();
@@ -379,10 +380,9 @@ void ShaderVariation::SaveByteCode(const PODVector<unsigned>& byteCode, const St
         }
     }
     
-    unsigned dataSize = byteCode.Size() << 2;
-    file->WriteUInt(dataSize);
-    if (dataSize)
-        file->Write(&byteCode[0], dataSize);
+    file->WriteUInt(byteCode_.Size());
+    if (byteCode_.Size())
+        file->Write(&byteCode_[0], byteCode_.Size());
 }
 
 }

+ 10 - 6
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.h

@@ -104,18 +104,20 @@ public:
     bool HasTextureUnit(TextureUnit unit) const { return useTextureUnit_[unit]; }
     /// Return all parameter definitions.
     const HashMap<StringHash, ShaderParameter>& GetParameters() const { return parameters_; }
+    /// Return shader bytecode.
+    const PODVector<unsigned char>& GetByteCode() const { return byteCode_; }
     
 private:
     /// Load bytecode from a file. Return true if successful.
-    bool LoadByteCode(PODVector<unsigned>& byteCode, const String& binaryShaderName);
+    bool LoadByteCode(const String& binaryShaderName);
     /// Compile from source. Return true if successful.
-    bool Compile(PODVector<unsigned>& byteCode);
-    /// Inspect the constant parameters of the shader bytecode using MojoShader.
-    void ParseParameters(unsigned char* bufData, unsigned bufSize);
+    bool Compile();
     /// Strip comments from shader bytecode and store it.
-    void CopyStrippedCode(PODVector<unsigned>& byteCode, unsigned char* bufData, unsigned bufSize);
+    void CopyStrippedCode(unsigned char* bufData, unsigned bufSize);
+    /// Inspect the constant parameters and input layout (if applicable) from the shader bytecode.
+    void ParseParameters();
     /// Save bytecode to a file.
-    void SaveByteCode(const PODVector<unsigned>& byteCode, const String& binaryShaderName);
+    void SaveByteCode(const String& binaryShaderName);
     
     /// Shader this variation belongs to.
     WeakPtr<Shader> owner_;
@@ -131,6 +133,8 @@ private:
     HashMap<StringHash, ShaderParameter> parameters_;
     /// Texture unit use flags.
     bool useTextureUnit_[MAX_TEXTURE_UNITS];
+    /// Bytecode. Needed for inspecting the input signature and parameters.
+    PODVector<unsigned char> byteCode_;
 };
 
 }

+ 1 - 0
Source/Urho3D/Graphics/Direct3D11/D3D11Texture.cpp

@@ -57,6 +57,7 @@ static const char* filterModeNames[] =
 Texture::Texture(Context* context) :
     Resource(context),
     GPUObject(GetSubsystem<Graphics>()),
+    shaderResourceView_(0),
     format_(DXGI_FORMAT_UNKNOWN),
     usage_(TEXTURE_STATIC),
     levels_(0),

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

@@ -102,11 +102,15 @@ public:
     void SetParameters(XMLFile* xml);
     /// Set additional parameters from an XML element.
     void SetParameters(const XMLElement& element);
+    /// Return shader resource view.
+    void* GetShaderResourceView() const { return shaderResourceView_; }
     
 protected:
     /// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
     void CheckTextureBudget(StringHash type);
     
+    /// Shader resource view.
+    void* shaderResourceView_;
     /// Texture format.
     unsigned format_;
     /// Texture usage type.

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

@@ -114,6 +114,12 @@ void Texture2D::Release()
         
         ((ID3D11Resource*)object_)->Release();
         object_ = 0;
+
+        if (shaderResourceView_)
+        {
+            ((ID3D11ShaderResourceView*)shaderResourceView_)->Release();
+            shaderResourceView_ = 0;
+        }
     }
     else
     {

+ 6 - 0
Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.cpp

@@ -158,6 +158,12 @@ void Texture3D::Release()
         
         ((ID3D11Resource*)object_)->Release();
         object_ = 0;
+
+        if (shaderResourceView_)
+        {
+            ((ID3D11ShaderResourceView*)shaderResourceView_)->Release();
+            shaderResourceView_ = 0;
+        }
     }
     else
     {

+ 6 - 0
Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.cpp

@@ -250,6 +250,12 @@ void TextureCube::Release()
         
         ((ID3D11Resource*)object_)->Release();
         object_ = 0;
+
+        if (shaderResourceView_)
+        {
+            ((ID3D11ShaderResourceView*)shaderResourceView_)->Release();
+            shaderResourceView_ = 0;
+        }
     }
 }