Browse Source

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

Lasse Öörni 10 years ago
parent
commit
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 (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;
         textures_[index] = texture;
         texturesDirty_ = true;
         texturesDirty_ = true;
     }
     }
@@ -2117,6 +2126,7 @@ void Graphics::ResetCachedState()
     blendStateHash_ = M_MAX_UNSIGNED;
     blendStateHash_ = M_MAX_UNSIGNED;
     depthStateHash_ = M_MAX_UNSIGNED;
     depthStateHash_ = M_MAX_UNSIGNED;
     rasterizerStateHash_ = M_MAX_UNSIGNED;
     rasterizerStateHash_ = M_MAX_UNSIGNED;
+    firstDirtyTexture_ = lastDirtyTexture_ = M_MAX_UNSIGNED;
 }
 }
 
 
 void Graphics::PrepareDraw()
 void Graphics::PrepareDraw()
@@ -2138,6 +2148,23 @@ void Graphics::PrepareDraw()
         renderTargetsDirty_ = false;
         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_)
     if (blendStateDirty_)
     {
     {
         unsigned newBlendStateHash = (colorWrite_ ? 1 : 0) | (blendMode_ << 1);
         unsigned newBlendStateHash = (colorWrite_ ? 1 : 0) | (blendMode_ << 1);

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

@@ -589,6 +589,10 @@ private:
     unsigned depthStateHash_;
     unsigned depthStateHash_;
     /// Hash of current rasterizer state.
     /// Hash of current rasterizer state.
     unsigned rasterizerStateHash_;
     unsigned rasterizerStateHash_;
+    /// First dirtied texture unit.
+    unsigned firstDirtyTexture_;
+    /// Last dirtied texture unit.
+    unsigned lastDirtyTexture_;
     /// Default texture filtering mode.
     /// Default texture filtering mode.
     TextureFilterMode defaultTextureFilterMode_;
     TextureFilterMode defaultTextureFilterMode_;
     /// Shader parameters for all vertex/pixel shader combinations.
     /// 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";
     extension = type_ == VS ? ".vs4" : ".ps4";
     
     
     String binaryShaderName = path + "Cache/" + name + "_" + StringHash(defines_).ToString() + extension;
     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
         // Compile shader if don't have valid bytecode
-        if (!Compile(byteCode))
+        if (!Compile())
             return false;
             return false;
         // Save the bytecode after successful compile, but not if the source is from a package
         // Save the bytecode after successful compile, but not if the source is from a package
         if (owner_->GetTimeStamp())
         if (owner_->GetTimeStamp())
-            SaveByteCode(byteCode, binaryShaderName);
+            SaveByteCode(binaryShaderName);
     }
     }
     
     
     // Then create shader from the bytecode
     // Then create shader from the bytecode
     ID3D11Device* device = graphics_->GetImpl()->GetDevice();
     ID3D11Device* device = graphics_->GetImpl()->GetDevice();
     if (type_ == VS)
     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_)
         if (!object_)
             compilerOutput_ = "Could not create vertex shader";
             compilerOutput_ = "Could not create vertex shader";
     }
     }
     else
     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_)
         if (!object_)
             compilerOutput_ = "Could not create pixel shader";
             compilerOutput_ = "Could not create pixel shader";
     }
     }
@@ -134,6 +133,7 @@ void ShaderVariation::Release()
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         useTextureUnit_[i] = false;
         useTextureUnit_[i] = false;
     parameters_.Clear();
     parameters_.Clear();
+    byteCode_.Clear();
 }
 }
 
 
 void ShaderVariation::SetName(const String& name)
 void ShaderVariation::SetName(const String& name)
@@ -151,7 +151,7 @@ Shader* ShaderVariation::GetOwner() const
     return owner_;
     return owner_;
 }
 }
 
 
-bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String& binaryShaderName)
+bool ShaderVariation::LoadByteCode(const String& binaryShaderName)
 {
 {
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     if (!cache->Exists(binaryShaderName))
     if (!cache->Exists(binaryShaderName))
@@ -201,8 +201,8 @@ bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String&
     unsigned byteCodeSize = file->ReadUInt();
     unsigned byteCodeSize = file->ReadUInt();
     if (byteCodeSize)
     if (byteCodeSize)
     {
     {
-        byteCode.Resize(byteCodeSize >> 2);
-        file->Read(&byteCode[0], byteCodeSize);
+        byteCode_.Resize(byteCodeSize);
+        file->Read(&byteCode_[0], byteCodeSize);
         
         
         if (type_ == VS)
         if (type_ == VS)
             LOGDEBUG("Loaded cached vertex shader " + GetFullName());
             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_);
     const String& sourceCode = owner_->GetSourceCode(type_);
     Vector<String> defines = defines_.Split(' ');
     Vector<String> defines = defines_.Split(' ');
@@ -293,8 +293,7 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
         
         
         unsigned char* bufData = (unsigned char*)shaderCode->GetBufferPointer();
         unsigned char* bufData = (unsigned char*)shaderCode->GetBufferPointer();
         unsigned bufSize = shaderCode->GetBufferSize();
         unsigned bufSize = shaderCode->GetBufferSize();
-        ParseParameters(bufData, bufSize);
-        CopyStrippedCode(byteCode, bufData, bufSize);
+        CopyStrippedCode(bufData, bufSize);
     }
     }
 
 
     if (shaderCode)
     if (shaderCode)
@@ -302,20 +301,21 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
     if (errorMsgs)
     if (errorMsgs)
         errorMsgs->Release();
         errorMsgs->Release();
     
     
-    return !byteCode.Empty();
+    return !byteCode_.Empty();
 }
 }
 
 
-void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
+void ShaderVariation::ParseParameters()
 {
 {
     /// \todo Implement
     /// \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 const D3DSIO_COMMENT = 0xFFFE;
     unsigned* srcWords = (unsigned*)bufData;
     unsigned* srcWords = (unsigned*)bufData;
     unsigned srcWordSize = bufSize >> 2;
     unsigned srcWordSize = bufSize >> 2;
-    
+    byteCode_.Clear();
+
     for (unsigned i = 0; i < srcWordSize; ++i)
     for (unsigned i = 0; i < srcWordSize; ++i)
     {
     {
         unsigned opcode = srcWords[i] & 0xffff;
         unsigned opcode = srcWords[i] & 0xffff;
@@ -331,12 +331,13 @@ void ShaderVariation::CopyStrippedCode(PODVector<unsigned>& byteCode, unsigned c
         else
         else
         {
         {
             // Not a comment, copy the data
             // 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>();
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     FileSystem* fileSystem = owner_->GetSubsystem<FileSystem>();
     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]; }
     bool HasTextureUnit(TextureUnit unit) const { return useTextureUnit_[unit]; }
     /// Return all parameter definitions.
     /// Return all parameter definitions.
     const HashMap<StringHash, ShaderParameter>& GetParameters() const { return parameters_; }
     const HashMap<StringHash, ShaderParameter>& GetParameters() const { return parameters_; }
+    /// Return shader bytecode.
+    const PODVector<unsigned char>& GetByteCode() const { return byteCode_; }
     
     
 private:
 private:
     /// Load bytecode from a file. Return true if successful.
     /// 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.
     /// 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.
     /// 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.
     /// Save bytecode to a file.
-    void SaveByteCode(const PODVector<unsigned>& byteCode, const String& binaryShaderName);
+    void SaveByteCode(const String& binaryShaderName);
     
     
     /// Shader this variation belongs to.
     /// Shader this variation belongs to.
     WeakPtr<Shader> owner_;
     WeakPtr<Shader> owner_;
@@ -131,6 +133,8 @@ private:
     HashMap<StringHash, ShaderParameter> parameters_;
     HashMap<StringHash, ShaderParameter> parameters_;
     /// Texture unit use flags.
     /// Texture unit use flags.
     bool useTextureUnit_[MAX_TEXTURE_UNITS];
     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) :
 Texture::Texture(Context* context) :
     Resource(context),
     Resource(context),
     GPUObject(GetSubsystem<Graphics>()),
     GPUObject(GetSubsystem<Graphics>()),
+    shaderResourceView_(0),
     format_(DXGI_FORMAT_UNKNOWN),
     format_(DXGI_FORMAT_UNKNOWN),
     usage_(TEXTURE_STATIC),
     usage_(TEXTURE_STATIC),
     levels_(0),
     levels_(0),

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

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

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

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

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

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

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

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