/// <summary>
            /// Uploads the specified device context. This function writes a external struct and writes remains byte buffer
            /// by offset = input struct size/>
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="deviceContext">The device context.</param>
            /// <param name="data">The data.</param>
            /// <returns></returns>
            public bool Upload <T>(DeviceContextProxy deviceContext, ref T data) where T : unmanaged
            {
                lock (lck)
                {
                    if (IsValid && IsAttached)
                    {
                        var structSize = UnsafeHelper.SizeOf <T>();
                        if (ModelConstBuffer.Buffer.Description.SizeInBytes < structSize)
                        {
#if DEBUG
                            throw new ArgumentOutOfRangeException($"Try to write value out of range. StructureSize {structSize}" +
                                                                  $" > Constant Buffer Size {ModelConstBuffer.StructureSize}");
#else
                            return(false);
#endif
                        }
                        var box = ModelConstBuffer.Map(deviceContext);
                        unsafe
                        {
                            var pBuf = (byte *)box.DataPointer.ToPointer();
                            *(T *)pBuf = data;
                        }
                        ModelConstBuffer.Unmap(deviceContext);
                        return(true);
                    }
                    return(false);
                }
            }
            public void WriteValueByName <T>(string name, T value) where T : unmanaged
            {
                if (IsValid && IsAttached)
                {
                    lock (lck)
                    {
                        if (IsValid && IsAttached)
                        {
                            if (ModelConstBuffer.TryGetVariableByName(name, out var variable))
                            {
                                if (UnsafeHelper.SizeOf <T>() > variable.Size)
                                {
                                    var structSize = UnsafeHelper.SizeOf <T>();
                                    throw new ArgumentException($"Input struct size {structSize} is larger than shader variable {variable.Name} size {variable.Size}");
                                }
                                if (!storage.Write(storageId, variable.StartOffset, ref value))
                                {
                                    throw new ArgumentException($"Failed to write value on {name}");
                                }
                            }
                            else
                            {
#if DEBUG
                                throw new ArgumentException($"Variable not found in constant buffer {bufferDesc.Name}. Variable = {name}");
#else
                                Technique.EffectsManager.Logger.Log(Logger.LogLevel.Warning, $"Variable not found in constant buffer {bufferDesc.Name}. Variable = {name}");
#endif
                            }
                        }
                    }
                }
            }
Exemple #3
0
        public bool Read <T>(int id, int offset, out T value) where T : unmanaged
        {
            if (id < 0)
            {
                value = default;
                return(false);
            }
            var size          = UnsafeHelper.SizeOf <T>();
            var offsetInArray = GetOffSet(id) + offset;

            if (offsetInArray + size > binaryArray.Count)
            {
                Debug.Assert(false);
                value = default;
                return(false);
            }
            var array = binaryArray.GetInternalArray();

            fixed(byte *pArray = &array[offsetInArray])
            {
                value = *(T *)pArray;
            }

            return(true);
        }
Exemple #4
0
            /// <summary>
            /// Updates the material structure. And upload data to constant buffer
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="context">The context.</param>
            /// <param name="model">The model.</param>
            public bool UpdateMaterialStruct <T>(DeviceContextProxy context, ref T model) where T : unmanaged
            {
                if (!initialized)
                {
                    return(false);
                }
                if (NeedUpdate)
                {
                    lock (updateLock)
                    {
                        if (NeedUpdate)
                        {
                            UpdateInternalVariables(context);
                            NeedUpdate = false;
                        }
                    }
                }
                var structSize = UnsafeHelper.SizeOf <T>();
                var box        = materialCB.Map(context);

                UnsafeHelper.Write(box.DataPointer, ref model);
                var succ = storage.Read(storageId, structSize,
                                        box.DataPointer + structSize,
                                        storage.StructSize - structSize);

                materialCB.Unmap(context);
                return(succ);
            }
Exemple #5
0
        public bool Write <T>(int id, int offset, ref T value) where T : unmanaged
        {
            var size = UnsafeHelper.SizeOf <T>();

            fixed(T *pValue = &value)
            {
                return(Write(id, offset, new IntPtr(pValue), size));
            }
        }
Exemple #6
0
            /// <summary>
            /// Updates the non material structure.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="context">The context.</param>
            /// <param name="model">The model.</param>
            /// <returns></returns>
            public bool UpdateNonMaterialStruct <T>(DeviceContextProxy context, ref T model) where T : unmanaged
            {
                if (!initialized)
                {
                    return(false);
                }
                if (UnsafeHelper.SizeOf <T>() != nonMaterialCB.StructureSize)
                {
                    Debug.Assert(false);
                    return(false);
                }
                var box = nonMaterialCB.Map(context);

                UnsafeHelper.Write(box.DataPointer, ref model);
                nonMaterialCB.Unmap(context);
                return(true);
            }
 public void UploadDataToBuffer <T>(DeviceContextProxy context, T[] data, int count, int offset) where T : unmanaged
 {
     lock (lockObj)
     {
         if (bufferDesc.Usage == ResourceUsage.Dynamic)
         {
             Debug.Assert(count * UnsafeHelper.SizeOf <T>() <= buffer.Description.SizeInBytes);
             var dataBox = context.MapSubresource(buffer, 0, MapMode.WriteDiscard, MapFlags.None);
             UnsafeHelper.Write(dataBox.DataPointer, data, offset, count);
             context.UnmapSubresource(buffer, 0);
         }
         else
         {
             context.UpdateSubresource(data, buffer);
         }
     }
 }
Exemple #8
0
            public void WriteValue <T>(string name, ref T value) where T : unmanaged
            {
                if (materialCB != null && materialCB.TryGetVariableByName(name, out var variable))
                {
                    if (UnsafeHelper.SizeOf <T>() > variable.Size)
                    {
                        var structSize = UnsafeHelper.SizeOf <T>();
                        throw new ArgumentException($"Input struct size {structSize} is larger than shader variable {variable.Name} size {variable.Size}");
                    }

                    if (!storage.Write(storageId, variable.StartOffset, ref value))
                    {
                        throw new ArgumentException($"Failed to write value on {name}");
                    }
                }
                else
                {
#if DEBUG
                    throw new ArgumentException($"Variable not found in constant buffer {materialCB.Name}. Variable = {name}");
#else
                    logger.LogWarning("Variable not found in constant buffer {}. Variable = {}", materialCB.Name, name);
#endif
                }
            }
Exemple #9
0
            public override void Render(RenderContext context, DeviceContextProxy deviceContext)
            {
                EnsureTextureResources((int)context.ActualWidth, (int)context.ActualHeight, deviceContext);
                int texScale = (int)offScreenTextureSize;
                var viewport = context.Viewport;

                using (var ds = context.GetOffScreenDS(offScreenTextureSize, DEPTHFORMAT))
                {
                    using (var rt0 = context.GetOffScreenRT(offScreenTextureSize, RENDERTARGETFORMAT))
                    {
                        using (var rt1 = context.GetOffScreenRT(offScreenTextureSize, SSAOTARGETFORMAT))
                        {
                            var w = (int)(context.ActualWidth / texScale);// Make sure to set correct viewport width/height by quality
                            var h = (int)(context.ActualHeight / texScale);
                            deviceContext.SetRenderTarget(ds, rt0, true, new Color4(0, 0, 0, 1), true, DepthStencilClearFlags.Depth);
                            deviceContext.SetViewport(0, 0, w, h);
                            deviceContext.SetScissorRectangle(0, 0, w, h);
                            IRenderTechnique currTechnique = null;
                            var ssaoPass1 = ShaderPass.NullPass;
                            var frustum   = context.BoundingFrustum;
                            for (var i = 0; i < context.RenderHost.PerFrameOpaqueNodesInFrustum.Count; ++i)
                            {
                                var node = context.RenderHost.PerFrameOpaqueNodesInFrustum[i];
                                if (currTechnique != node.EffectTechnique)
                                {
                                    currTechnique = node.EffectTechnique;
                                    ssaoPass1     = currTechnique[DefaultPassNames.MeshSSAOPass];
                                }
                                if (ssaoPass1.IsNULL)
                                {
                                    continue;
                                }
                                node.RenderDepth(context, deviceContext, ssaoPass1);
                            }

                            var invProjection = context.ProjectionMatrix.Inverted();
                            ssaoParam.InvProjection = invProjection;
                            ssaoParam.NoiseScale    = new Vector2(w / 4f, h / 4f);
                            ssaoParam.Radius        = radius;
                            ssaoParam.TextureScale  = texScale;
                            ssaoCB.ModelConstBuffer.UploadDataToBuffer(deviceContext, (dataBox) =>
                            {
                                Debug.Assert(UnsafeHelper.SizeOf(kernels)
                                             + UnsafeHelper.SizeOf(ref ssaoParam) <= ssaoCB.ModelConstBuffer.bufferDesc.SizeInBytes);
                                var nextPtr = UnsafeHelper.Write(dataBox.DataPointer, kernels, 0, kernels.Length);
                                UnsafeHelper.Write(nextPtr, ref ssaoParam);
                            });
                            deviceContext.SetRenderTarget(rt1);
                            ssaoPass.BindShader(deviceContext);
                            ssaoPass.BindStates(deviceContext, StateType.All);
                            ssaoPass.PixelShader.BindTexture(deviceContext, ssaoTexSlot, rt0);
                            ssaoPass.PixelShader.BindTexture(deviceContext, noiseTexSlot, ssaoNoiseView);
                            ssaoPass.PixelShader.BindTexture(deviceContext, depthSlot, ds);
                            ssaoPass.PixelShader.BindSampler(deviceContext, surfaceSampleSlot, surfaceSampler);
                            ssaoPass.PixelShader.BindSampler(deviceContext, noiseSamplerSlot, noiseSampler);
                            deviceContext.Draw(4, 0);

                            ssaoPass.PixelShader.BindTexture(deviceContext, depthSlot, null);

                            deviceContext.SetRenderTarget(ssaoView);
                            deviceContext.SetViewport(ref viewport);
                            deviceContext.SetScissorRectangle(ref viewport);
                            ssaoBlur.BindShader(deviceContext);
                            ssaoBlur.BindStates(deviceContext, StateType.All);
                            ssaoBlur.PixelShader.BindTexture(deviceContext, ssaoTexSlot, rt1);
                            ssaoBlur.PixelShader.BindSampler(deviceContext, surfaceSampleSlot, blurSampler);
                            deviceContext.Draw(4, 0);
                            context.SharedResource.SSAOMap = ssaoView;

                            context.RenderHost.SetDefaultRenderTargets(false);
                            deviceContext.SetShaderResource(PixelShader.Type, ssaoTexSlot, ssaoView);
                        }
                    }
                }
            }