public void summarize(ref eRenderPassFlags renderPasses, out eShaderMacros drawFeatures) { eRenderPassFlags flags = eRenderPassFlags.None; eShaderMacros macros = eShaderMacros.None; foreach (var m in meshes.read()) { flags |= m.mesh.drawInfo.renderPassFlags; } if (rectCommands.length > 0) { flags |= eRenderPassFlags.Opaque; } if (spriteCommands.length > 0) { flags |= eRenderPassFlags.Transparent; macros |= eShaderMacros.TextureAtlas; } if (textCommands.length > 0) { macros |= eShaderMacros.TextRendering; flags |= eRenderPassFlags.Transparent; } renderPasses |= flags; drawFeatures = macros; }
static void setupDepthState(ref PipelineStateDesc desc, eShaderMacros macros) { // Enable depth for both opaque and transparent passes.. desc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true; desc.GraphicsPipeline.DepthStencilDesc.DepthFunc = ComparisonFunction.Less; // ..and set it so the depth is written on opaque pass, but readonly on transparent one. // With some luck, this should allow early Z rejection on both passes, saving tremendous amount of pixel shader invocations and fillrate bandwidth. if (macros.HasFlag(eShaderMacros.OpaquePass)) { desc.GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = true; } else { desc.GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = false; // desc.premultipliedAlphaBlending(); RenderTargetBlendDesc blendDesc = new RenderTargetBlendDesc(false) { BlendEnable = true, SrcBlend = BlendFactor.One, DestBlend = BlendFactor.InvSrcAlpha, SrcBlendAlpha = BlendFactor.One, DestBlendAlpha = BlendFactor.One, BlendOpAlpha = BlendOperation.Max, }; desc.GraphicsPipeline.BlendDesc.setRenderTarget(blendDesc); } }
/// <summary>Produce #define values for a shader compiler</summary> public static IEnumerable <(string, string)> defines(this eShaderMacros vals) { yield return("OPAQUE_PASS", macroValue(vals, eShaderMacros.OpaquePass)); yield return("FEW_DRAW_CALLS", macroValue(vals, eShaderMacros.FewDrawCalls)); yield return("TEXTURE_ATLAS", macroValue(vals, eShaderMacros.TextureAtlas)); yield return("TEXT_RENDERING", macroValue(vals, eShaderMacros.TextRendering)); }
VrmacStateBase compileState(eShaderMacros macros) { using (var dev = resources.context.renderContext.device) using (var stateFactory = dev.CreatePipelineStateFactory()) { PipelineStateDesc desc = createStateDesc(); setupIdLayout(stateFactory); compileShaders(dev, stateFactory, "draw", macros); if (macros.HasFlag(eShaderMacros.FewDrawCalls)) { return(new FewDrawCallsState(resources, dev, ref desc, stateFactory, macros)); } return(new MoreDrawCallsState(resources, dev, ref desc, stateFactory, macros)); } }
public VrmacStateBase(GpuResources resources, IRenderDevice device, ref PipelineStateDesc desc, iPipelineStateFactory stateFactory, eShaderMacros macros) { this.resources = resources; shaderMacros = macros; layoutUniforms(stateFactory); stateFactory.setName($"2D state { macros }"); stateFactory.layoutVariable(ShaderType.Vertex, ShaderResourceVariableType.Mutable, varPaletteTexture); stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varPaletteTexture); if (macros.HasFlag(eShaderMacros.TextureAtlas)) { stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varSpriteAtlas); SamplerDesc samplerDesc = new SamplerDesc(false); stateFactory.layoutStaticSampler(ShaderType.Pixel, ref samplerDesc, varSpriteAtlas); resources.context.drawDevice.textureAtlas.resized.add(this, dropResourceBindings); } if (macros.HasFlag(eShaderMacros.TextRendering)) { stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varGrayscaleFontAtlas); SamplerDesc samplerDesc = new SamplerDesc(false); stateFactory.layoutStaticSampler(ShaderType.Pixel, ref samplerDesc, varGrayscaleFontAtlas); stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varCleartypeFontAtlas); resources.initTextCBuffer(); } declareResources(stateFactory); stateFactory.apply(ref desc); setupDepthState(ref desc, macros); pipelineState = device.CreatePipelineState(ref desc); resources.context.swapChainResized.add(this, (CSize s, double d) => dropResourceBindings()); resources.paletteTexture.textureResized.add(this, dropResourceBindings); }
public VrmacStateBase getState(int drawCallsCount, bool opaquePass, eShaderMacros drawFeatures) { eShaderMacros macros = drawFeatures; if (drawCallsCount <= FewDrawCallsState.smallCount) { macros |= eShaderMacros.FewDrawCalls; } if (opaquePass) { macros |= eShaderMacros.OpaquePass; } int idx = cacheIndex(macros); VrmacStateBase state = cache[idx]; if (null != state) { return(state); } state = compileState(macros); cache[idx] = state; return(state); }
public FewDrawCallsState(GpuResources res, IRenderDevice device, ref PipelineStateDesc desc, iPipelineStateFactory stateFactory, eShaderMacros macros) : base(res, device, ref desc, stateFactory, macros) { constantBuffer = res.fewDrawCalls; pipelineState.GetStaticVariableByName(ShaderType.Vertex, "DrawCallsCBuffer").Set(constantBuffer); }
public MoreDrawCallsState(GpuResources res, IRenderDevice device, ref PipelineStateDesc desc, iPipelineStateFactory stateFactory, eShaderMacros macros) : base(res, device, ref desc, stateFactory, macros) { drawCallsBuffer = res.moreDrawCalls; drawCallsBuffer.resized.add(this, (DynamicBuffer buffer, int capacity) => dropResourceBindings()); }
static int cacheIndex(eShaderMacros macros) { return((int)macros); }
static void compileShaders(IRenderDevice device, iPipelineStateFactory stateFactory, string name, eShaderMacros macros) { var compiler = device.GetShaderFactory(); iStorageFolder src = StorageFolder.embeddedResources(System.Reflection.Assembly.GetExecutingAssembly(), resourceFolder); var defines = macros.defines().ToArray(); stateFactory.graphicsVertexShader(compiler.compileShader(src, name, ShaderType.Vertex, defines)); stateFactory.graphicsPixelShader(compiler.compileShader(src, name, ShaderType.Pixel, defines)); }
static string macroValue(eShaderMacros vals, eShaderMacros bit) { return(vals.HasFlag(bit) ? "1" : "0"); }