public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var gen = new WaterGenerator(shaderOptions.Select(x => (byte)x).ToArray()); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public override string GenerateSharedPixelShader(ShaderStage stage, int methodIndex, int optionIndex) { var gen = new HalogramGenerator(); var bytecode = gen.GenerateSharedPixelShader(stage, methodIndex, optionIndex).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public override string GenerateSharedVertexShader(VertexType vertex, ShaderStage stage) { var gen = new HalogramGenerator(); var bytecode = gen.GenerateSharedVertexShader(vertex, stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
/// <summary> /// Compiles a new HLSL shader from the input source code. /// </summary> /// <param name="hlslSourceAscii">The HLSL source code to compile (in ASCII).</param> /// <param name="entryPointAscii">The entry point of the shader being compiled (in ASCII).</param> /// <param name="shaderProfile">The shader profile to use to compile the shader.</param> /// <param name="options">The compiler options to use to compile the shader.</param> /// <returns>The bytecode for the compiled shader.</returns> /// <exception cref="FxcCompilationException">Thrown if the compilation fails.</exception> public static unsafe ReadOnlyMemory <byte> Compile( ReadOnlySpan <byte> hlslSourceAscii, ReadOnlySpan <byte> entryPointAscii, D2D1ShaderProfile shaderProfile, D2D1CompileOptions options) { // Check linking support bool enableLinking = (options & D2D1CompileOptions.EnableLinking) == D2D1CompileOptions.EnableLinking; // Remove the linking flag to make the options blittable to flags options &= ~D2D1CompileOptions.EnableLinking; // Compile the standalone D2D1 full shader using ComPtr <ID3DBlob> d3DBlobFullShader = D3DCompiler.CompileShader( source: hlslSourceAscii, macro: D3DCompiler.ASCII.D2D_FULL_SHADER, d2DEntry: entryPointAscii, entryPoint: entryPointAscii, target: D3DCompiler.ASCII.GetPixelShaderProfile(shaderProfile), flags: (uint)options); if (!enableLinking) { void *blobFullShaderPtr = d3DBlobFullShader.Get()->GetBufferPointer(); nuint blobFullShaderSize = d3DBlobFullShader.Get()->GetBufferSize(); return(new Span <byte>(blobFullShaderPtr, (int)blobFullShaderSize).ToArray()); } // Compile the export function using ComPtr <ID3DBlob> d3DBlobFunction = D3DCompiler.CompileShader( source: hlslSourceAscii, macro: D3DCompiler.ASCII.D2D_FUNCTION, d2DEntry: entryPointAscii, entryPoint: default,
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var albedo = (Albedo)shaderOptions[0]; var alpha_test = (Alpha_Test)shaderOptions[1]; var material_model = (Material_Model)shaderOptions[2]; var gen = new FoliageGenerator(albedo, alpha_test, material_model); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
private static unsafe Span <byte> CreateBlob(out ID3DBlob *ppBlob, UIntPtr size) { ID3DBlob *p; ThrowIfFailed(D3DCompiler.D3DCreateBlob(size, &p)); ppBlob = p; return(new Span <byte>(ppBlob->GetBufferPointer(), (int)ppBlob->GetBufferSize())); }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var albedo = (Albedo)shaderOptions[0]; var blend_mode = (Blend_Mode)shaderOptions[1]; var fog = (Fog)shaderOptions[2]; var gen = new LightVolumeGenerator(albedo, blend_mode, fog); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
static void TestSharedVertexShader(ShaderType shaderType, VertexType vertexType, ShaderStage stage) { IShaderGenerator generator = GetShaderGenerator(shaderType); if (generator.IsEntryPointSupported(stage) && generator.IsVertexShaderShared(stage) && generator.IsVertexFormatSupported(vertexType)) { var bytecode = generator.GenerateSharedVertexShader(vertexType, stage).Bytecode; var disassembly = D3DCompiler.Disassemble(bytecode); WriteShaderFile($"generated_{stage.ToString().ToLower()}_{vertexType.ToString().ToLower()}.glvs", disassembly); } }
static void TestPixelShader(string name) { var bytecode = GenericPixelShaderGenerator.GeneratePixelShader(name, ShaderStage.Default.ToString()); var str = D3DCompiler.Disassemble(bytecode.Bytecode); using (FileStream test = new FileInfo($"generated_{name}.pixl").Create()) using (StreamWriter writer = new StreamWriter(test)) { writer.WriteLine(str); } Console.WriteLine(str); }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var warp = (Warp)shaderOptions[0]; var _base = (Base)shaderOptions[1]; var overlay_a = (Overlay_A)shaderOptions[2]; var overlay_b = (Overlay_B)shaderOptions[3]; var blend_type = (Blend_Mode)shaderOptions[4]; var gen = new ScreenGenerator(warp, _base, overlay_a, overlay_b, blend_type); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
static void TestSharedPixelShader(ShaderType shaderType, ShaderStage stage, int methodIndex, int optionIndex) { IShaderGenerator generator = GetShaderGenerator(shaderType); byte[] bytecode; string disassembly; if (generator.IsSharedPixelShaderUsingMethods(stage)) { if (methodIndex == -1 || optionIndex == -1) { for (int i = 0; i < generator.GetMethodCount(); i++) { if (generator.IsMethodSharedInEntryPoint(stage, i) && generator.IsPixelShaderShared(stage)) { for (int j = 0; j < generator.GetMethodOptionCount(i); j++) { var result = generator.GenerateSharedPixelShader(stage, i, j); if (result != null) { bytecode = generator.GenerateSharedPixelShader(stage, i, j).Bytecode; disassembly = D3DCompiler.Disassemble(bytecode); WriteShaderFile($"generated_{stage.ToString().ToLower()}_{i}_{j}.glps", disassembly); } } } } } else { var result = generator.GenerateSharedPixelShader(stage, -1, -1); if (result != null) { bytecode = result.Bytecode; disassembly = D3DCompiler.Disassemble(bytecode); WriteShaderFile($"generated_{stage.ToString().ToLower()}_{methodIndex}_{optionIndex}.glps", disassembly); } } } else { var result = generator.GenerateSharedPixelShader(stage, -1, -1); if (result != null) { bytecode = result.Bytecode; disassembly = D3DCompiler.Disassemble(bytecode); WriteShaderFile($"generated_{stage.ToString().ToLower()}.glps", disassembly); } } }
static void TestPixelShader(ShaderType shaderType, ShaderStage stage, List <int> methods) { IShaderGenerator generator = GetTemplateShaderGenerator(shaderType, methods); if (generator.IsEntryPointSupported(stage) && !generator.IsPixelShaderShared(stage)) { var bytecode = generator.GeneratePixelShader(stage).Bytecode; var parameters = generator.GetPixelShaderParameters(); var disassembly = D3DCompiler.Disassemble(bytecode); string filename = $"generated_{stage.ToString().ToLower()}_{string.Join("_", methods)}.pixl"; WriteShaderFile(filename, disassembly); } }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var albedo = (Albedo)shaderOptions[0]; var blend_mode = (Blend_Mode)shaderOptions[1]; var render_pass = (Render_Pass)shaderOptions[2]; var specular = (Specular)shaderOptions[3]; var bump_mapping = (Bump_Mapping)shaderOptions[4]; var tinting = (Tinting)shaderOptions[5]; var gen = new DecalGenerator(albedo, blend_mode, render_pass, specular, bump_mapping, tinting); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var blend_type = (Blending)shaderOptions[0]; var env_map = (Environment_Mapping)shaderOptions[1]; var material_0 = (Material)shaderOptions[2]; var material_1 = (Material)shaderOptions[3]; var material_2 = (Material)shaderOptions[4]; var material_3 = (Material_No_Detail_Bump)shaderOptions[5]; var gen = new TerrainGenerator(blend_type, env_map, material_0, material_1, material_2, material_3); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var albedo = (Albedo)shaderOptions[0]; var self_illumination = (Self_Illumination)shaderOptions[1]; var blend_mode = (Blend_Mode)shaderOptions[2]; var misc = (Misc)shaderOptions[3]; var warp = (Warp)shaderOptions[4]; var overlay = (Overlay)shaderOptions[5]; var edge_fade = (Edge_Fade)shaderOptions[6]; var gen = new HalogramGenerator(albedo, self_illumination, blend_mode, misc, warp, overlay, edge_fade); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public static byte[] GenerateSource(string template, IEnumerable <D3D.SHADER_MACRO> macros, string entry, string version) { // Macros should never be duplicated for (var i = 0; i < macros.Count(); i++) { for (var j = 0; j < macros.Count(); j++) { if (i == j) { continue; } if (macros.ElementAt(i).Name == macros.ElementAt(j).Name) { throw new Exception($"Macro {macros.ElementAt(i).Name} is defined multiple times"); } } } string fileName = template.Split('\\').Last(); IncludeManager include = new IncludeManager(template.Replace(fileName, "")); string shader_source = include.ReadResource(fileName); D3DCompiler.D3DCOMPILE flags = 0; #if DEBUG //flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_WARNINGS_ARE_ERRORS; #endif //flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_SKIP_VALIDATION; //flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_DEBUG; flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_OPTIMIZATION_LEVEL2; // if can't get shader to compile 1-1 add or remove this line byte[] shader_code = D3DCompiler.Compile( shader_source, entry, version, macros.ToArray(), flags, 0, template, include ); GC.KeepAlive(include?.NativePointer); return(shader_code); }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var albedo = (Albedo)shaderOptions[0]; var bump_mapping = (Bump_Mapping)shaderOptions[1]; var alpha_test = (Alpha_Test)shaderOptions[2]; var specular_mask = (Specular_Mask)shaderOptions[3]; var material_model = (Material_Model)shaderOptions[4]; var environment_mapping = (Environment_Mapping)shaderOptions[5]; var self_illumination = (Self_Illumination)shaderOptions[6]; var blend_mode = (Blend_Mode)shaderOptions[7]; var parallax = (Parallax)shaderOptions[8]; var misc = (Misc)shaderOptions[9]; var distortion = (Shared.Distortion)shaderOptions[10]; var gen = new ShaderGenerator(albedo, bump_mapping, alpha_test, specular_mask, material_model, environment_mapping, self_illumination, blend_mode, parallax, misc, distortion); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public override string GeneratePixelShader(ShaderStage stage, List <int> shaderOptions) { var albedo = (Albedo)shaderOptions[0]; var blend_mode = (Blend_Mode)shaderOptions[1]; var specialized_rendering = (Specialized_Rendering)shaderOptions[2]; var lighting = (Lighting)shaderOptions[3]; var render_targets = (Render_Targets)shaderOptions[4]; var depth_fade = (Depth_Fade)shaderOptions[5]; var black_point = (Black_Point)shaderOptions[6]; var fog = (Fog)shaderOptions[7]; var frame_blend = (Frame_Blend)shaderOptions[8]; var self_illumination = (Self_Illumination)shaderOptions[9]; var gen = new ParticleGenerator(albedo, blend_mode, specialized_rendering, lighting, render_targets, depth_fade, black_point, fog, frame_blend, self_illumination); var bytecode = gen.GeneratePixelShader(stage).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
public static byte[] GenerateSource(string template, IEnumerable <D3D.SHADER_MACRO> macros, string entry, string version) { // Macros should never be duplicated for (var i = 0; i < macros.Count(); i++) { for (var j = 0; j < macros.Count(); j++) { if (i == j) { continue; } if (macros.ElementAt(i).Name == macros.ElementAt(j).Name) { throw new Exception($"Macro {macros.ElementAt(i).Name} is defined multiple times"); } } } IncludeManager include = new IncludeManager(); string shader_source = include.ReadResource(template); D3DCompiler.D3DCOMPILE flags = 0; #if DEBUG //flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_WARNINGS_ARE_ERRORS; #endif //flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_SKIP_OPTIMIZATION; flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_SKIP_VALIDATION; //flags |= D3DCompiler.D3DCOMPILE.D3DCOMPILE_PREFER_FLOW_CONTROL; byte[] shader_code = D3DCompiler.Compile( shader_source, entry, version, macros.ToArray(), flags, 0, template, include ); return(shader_code); }
public static byte[]? Compile(string source, ShaderStage stage, string entryPoint = "", string fileName = "") { if (string.IsNullOrEmpty(entryPoint)) { entryPoint = GetDefaultEntryPoint(stage); } uint flags = 0; string shaderProfile = $"{GetShaderProfile(stage)}_5_0"; Result hr = D3DCompiler.D3DCompile( source, source.Length, fileName, null, 0, entryPoint, shaderProfile, flags, 0, out IDxcBlob blob, out IDxcBlob? errorMsgs); if (hr.Failure) { if (errorMsgs != null) { var errorText = GetStringFromBlob(errorMsgs); } } else { return(GetBytesFromBlob(blob)); } return(null); }
static void TestPixelBlack() { var gen = new ShaderBlackGenerator(); var bytecode = gen.GeneratePixelShader(ShaderStage.Albedo).Bytecode; WriteShaderFile($"generated_shader_black_{ShaderStage.Albedo.ToString().ToLower()}_0.pixl", D3DCompiler.Disassemble(bytecode)); }
/// <summary> /// Converts a new (1.235640+) pixel shader to one compatible with the 1.106708 pipeline. /// </summary> /// <param name="shaderData">The shader bytecode to convert.</param> /// <param name="mode">The drawing mode.</param> /// <returns>The new bytecode, or <c>null</c> if conversion failed.</returns> public static byte[] ConvertNewPixelShaderToOld(byte[] shaderData, int mode) { if (mode != 0 && mode != 1) { return(shaderData); // Only default albedo shaders need to be fixed (?) } // Disassemble the shader var disassembly = D3DCompiler.Disassemble(shaderData); if (disassembly == null) { return(null); } var lines = disassembly.Split('\n').ToList(); // Default pixel shaders need to have their inputs remapped (see // the vertex shader converter for more info). // // Albedo pixel shaders need to have sRGB color correction added. // The code is based off of the shader for the street cone. var highestConstant = -1; var addedConstants = false; var addedColorFix = false; var highestTexcoord = -1; var highestInput = -1; var wIn = -1; for (var i = 0; i < lines.Count; i++) { if (mode == 0) { // Default fixes var match = Regex.Match(lines[i], @"dcl_texcoord(\d*)"); if (match.Success) { var texGroup = match.Groups[1]; var index = (texGroup.Length > 0) ? int.Parse(texGroup.Value) : 0; highestTexcoord = Math.Max(highestTexcoord, index); if (index >= 1) { lines[i] = lines[i].Remove(texGroup.Index, texGroup.Length).Insert(texGroup.Index, (index + 1).ToString()); } } match = Regex.Match(lines[i], @"dcl_\S+ v(\d+)"); if (match.Success) { var inGroup = match.Groups[1]; highestInput = Math.Max(highestInput, int.Parse(inGroup.Value)); } else if (highestTexcoord >= 1 && highestInput >= 0) { wIn = highestInput + 1; lines.Insert(i, string.Format(" dcl_texcoord1 v{0}.x", wIn)); lines.Add(string.Format(" mov oC2, v{0}.x", wIn)); break; } } else if (mode == 1) { // Albedo fixes var match = Regex.Match(lines[i], @"dcl_texcoord1 v1\.xyz"); if (match.Success) { wIn = 1; lines[i] = lines[i].Remove(match.Index, match.Length).Insert(match.Index, "dcl_texcoord1 v1"); continue; } // Find the number of the highest-used constant register match = Regex.Match(lines[i], @"def c(\d+)"); if (match.Success) { highestConstant = Math.Max(highestConstant, int.Parse(match.Groups[1].Value)); continue; } if (!addedConstants) { // Add color correction constants before input/output declarations match = Regex.Match(lines[i], @"dcl_"); if (match.Success) { lines.Insert(i, string.Format(" def c{0}, 0.416666657, 1.05499995, -0.0549999997, 0.00313080009\n" + " def c{1}, 12.9200001, 0, 0, 0", highestConstant + 1, highestConstant + 2)); addedConstants = true; continue; } } if (!addedColorFix) { // Add color correction code before the output color is set match = Regex.Match(lines[i], @"\S+ (oC0)\.xyz"); if (match.Success) { // NOTE: This is really hacky and just assumes that // r29-r31 aren't used. It seems to work OK, but if we // run into issues then some sort of register // allocation may need to be done. var group = match.Groups[1]; lines[i] = lines[i].Remove(group.Index, group.Length).Insert(group.Index, "r31"); lines.Insert(++i, string.Format(" log r30.x, r31.x\n" + " log r30.y, r31.y\n" + " log r30.z, r31.z\n" + " mul r30.xyz, r30, c{0}.x\n" + " exp r29.x, r30.x\n" + " exp r29.y, r30.y\n" + " exp r29.z, r30.z\n" + " mad r30.xyz, r29, c{0}.y, c{0}.z\n" + " add r29.xyz, -r31, c{0}.w\n" + " mul r31.xyz, r31, c{1}.x\n" + " cmp oC0.xyz, r29, r31, r30", highestConstant + 1, highestConstant + 2)); if (wIn >= 0) { lines.Insert(++i, string.Format(" mov oC2, v{0}.w", wIn)); } addedColorFix = true; continue; } } } } // Reassemble the shader var newShader = string.Join("\n", lines); return(D3DCompiler.Assemble(newShader)); }
/// <summary> /// Converts a new (1.235640+) vertex shader to one compatible with the 1.106708 pipeline. /// Note that this requires that models have binormals set so that X = Position.W and Y = Tangent.W. /// </summary> /// <param name="shaderData">The shader bytecode to convert.</param> /// <param name="mode">The drawing mode.</param> /// <param name="type">The vertex type.</param> /// <returns>The new bytecode, or <c>null</c> if conversion failed.</returns> public static byte[] ConvertNewVertexShaderToOld(byte[] shaderData, int mode, VertexType type) { // Only applies to world, rigid, skinned, and dual quat if (type != VertexType.World && type != VertexType.Rigid && type != VertexType.Skinned && type != VertexType.DualQuat) { return(shaderData); } // Disassemble the shader var disassembly = D3DCompiler.Disassemble(shaderData); if (disassembly == null) { return(null); } var lines = disassembly.Split('\n').ToList(); // So, the reason that new vertex shaders don't work in 1.106708 // is because vertex declarations changed. For world, rigid, and // skinned meshes, the normal and binormal components were removed, // and the position and tangent vectors were extended to be 4D. // (The W components are used for various things.) To convert a new // vertex shader to use the old declaration format, we need to do // the following: // // 1. Add an input declaration for the binormal, so we can pull the // position.W and tangent.W values from it (assuming they're // stored that way in the model). // // 2. Remap the W component of the position to the X component of // the binormal. (The W component will never be used alongside // the other position components because it's technically // completely separate.) // // 3. The tangent will be unpacked by using a "mad" instruction. // However, in 1.106708, the tangent isn't packed to begin with. // So, we look for an instruction of the form // // mad [register], v[tangent], [constant], [constant] // // and replace it with instructions to load the components, // with the W component of the tangent in the Y component of the // binormal: // // mov [register].xyz, v[tangent] // mov [register].w, v[binormal].y // // 4. Insert code to handle v_squish_params and v_mesh_squished. // This is mainly needed for first-person models. // // 5. For albedo shaders only, o2 needs to be made 4D and the W // component must be set to the W component of the position so // that the pixel shader can pass it through to an output. This // appears to be necessary for objects to receive shadows. // // 6. For default shaders only, a texcoord1 output has to be added // for storing the W component of the position. This means that // the other texcoord outputs need to be remapped. var addedDeclarations = false; var fixedTangent = false; var lastInput = -1; var tangentRegister = -1; var binormalRegister = -1; var storedZ = false; var storedW = false; var addedSquishParams = false; string squishConstant1 = null; string squishConstant2 = null; var needSquishCheck = false; var wOut = -1; for (var i = 0; i < lines.Count; i++) { if (lines[i].StartsWith("//")) { continue; } // Find the tangent declaration and keep track of the highest input register var match = Regex.Match(lines[i], @"dcl_(\S+) v(\d+)"); if (match.Success) { var name = match.Groups[1].Value; var register = int.Parse(match.Groups[2].Value); if (name == "tangent") { tangentRegister = register; } lastInput = Math.Max(lastInput, register); } if (!addedDeclarations) { // Once the first output is found, add a definition for the binormal input before it match = Regex.Match(lines[i], @"dcl_(\S+) o\d+"); if (match.Success) { binormalRegister = lastInput + 1; lines.Insert(i++, string.Format(" dcl_binormal v{0}", binormalRegister)); addedDeclarations = true; continue; } } if (!fixedTangent && tangentRegister >= 0 && binormalRegister >= 0) { // Adjust tangent unpacking match = Regex.Match(lines[i], @"mad r(\d+), v" + tangentRegister); if (match.Success) { var index = int.Parse(match.Groups[1].Value); lines[i++] = string.Format(" mov r{0}.xyz, v{1}", index, tangentRegister); lines.Insert(i, string.Format(" mov r{0}.w, v{1}.y", index, binormalRegister)); fixedTangent = true; continue; } } // When the output Z is set, store it to r31.z instead (for v_squish_params) match = Regex.Match(lines[i], @"\S+ (o0)\.z"); if (match.Success) { var group = match.Groups[1]; lines[i] = lines[i].Remove(group.Index, group.Length).Insert(group.Index, "r31"); storedZ = true; } // When the output W is set, store it to r30.w instead (for v_squish_params) match = Regex.Match(lines[i], @"\S+ (o0)\.w"); if (match.Success) { var group = match.Groups[1]; lines[i] = lines[i].Remove(group.Index, group.Length).Insert(group.Index, "r30"); storedW = true; } // If b8 (v_mesh_squished) is checked, we need to remove most // of it and transform the previous instruction into a store to // r31.z (for the v_squish_params fix later on). match = Regex.Match(lines[i], @"if b8"); if (match.Success) { // Check that the previous instruction stores to a register match = Regex.Match(lines[i - 1], @"\S+ (r\d+\..),"); if (match.Success) { // Get squish constant 1 var constMatch = Regex.Match(lines[i + 1], @"mov r\d+\.., (c\d+\..)"); if (constMatch.Success) { squishConstant1 = constMatch.Groups[1].Value; } // Get squish constant 2 constMatch = Regex.Match(lines[i + 3], @"mov r\d+\.., (c\d+\..)"); if (constMatch.Success) { squishConstant2 = constMatch.Groups[1].Value; } if (squishConstant1 != null && squishConstant2 != null) { // Remove the if block lines.RemoveRange(i--, 6); // Transform the previous instruction var group = match.Groups[1]; lines[i] = lines[i].Remove(group.Index, group.Length).Insert(group.Index, "r31.z"); needSquishCheck = true; storedZ = true; } } } // v_squish_params fix if (storedZ && storedW && !addedSquishParams) { lines.Insert(++i, " mad r30.x, c250.x, r30.w, -c250.y\n" + " mad r30.x, r30.x, c250.z, -r31.z"); if (needSquishCheck) { // Check v_mesh_squished lines.Insert(++i, string.Format(" mad r31.z, c250.w, r30.x, r31.z\n" + " if b8\n" + " mov r30.x, {0}\n" + " else\n" + " mov r30.x, {1}\n" + " endif\n" + " add o0.z, -r30.x, r31.z", squishConstant1, squishConstant2)); } else { lines.Insert(++i, " mad o0.z, c250.w, r30.x, r31.z"); } lines.Insert(++i, " mov o0.w, r30.w"); // Needed for shadow receiving if (wOut >= 0) { if (mode == 0) { lines.Insert(++i, string.Format(" mov o{0}.x, r30.w", wOut)); } else if (mode == 1) { lines.Insert(++i, string.Format(" mov o{0}.w, r30.w", wOut)); } } addedSquishParams = true; continue; } if (mode == 0) { // Default-only: add a texcoord1 output and remap input registers match = Regex.Match(lines[i], @"dcl_texcoord(\d*) o(\d+)"); if (match.Success) { var texGroup = match.Groups[1]; var outGroup = match.Groups[2]; var outIndex = int.Parse(outGroup.Value); if (texGroup.Length == 0) { wOut = outIndex + 1; lines.Insert(++i, string.Format(" dcl_texcoord1 o{0}.x", outIndex + 1)); continue; } var texIndex = int.Parse(texGroup.Value); lines[i] = lines[i].Remove(texGroup.Index, texGroup.Length).Insert(texGroup.Index, (texIndex + 1).ToString()); lines[i] = lines[i].Remove(outGroup.Index, outGroup.Length).Insert(outGroup.Index, (outIndex + 1).ToString()); continue; } if (wOut >= 0) { foreach (Match m in Regex.Matches(lines[i], @" o(\d+)")) { var group = m.Groups[1]; var index = int.Parse(group.Value); if (index < wOut) { continue; } index++; lines[i] = lines[i].Remove(group.Index, group.Length).Insert(group.Index, index.ToString()); } } } // Albedo-only: make o2 be 4D if (mode == 1) { match = Regex.Match(lines[i], @"dcl_texcoord1 o2\.xyz"); if (match.Success) { wOut = 2; lines[i] = lines[i].Remove(match.Index, match.Length).Insert(match.Index, "dcl_texcoord1 o2"); continue; } } if (binormalRegister >= 0) { // Change the source of the position W component lines[i] = lines[i].Replace("v0.w", string.Format("v{0}.x", binormalRegister)); } } // Reassemble the shader var newShader = string.Join("\n", lines); return(D3DCompiler.Assemble(newShader)); }
public override string GenerateChudVertexShader(ChudShader chudShader, ShaderStage entry) { var bytecode = GenericVertexShaderGenerator.GenerateVertexShader(chudShader.ToString(), entry.ToString().ToLower(), true).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }
private string Disassemble(int shaderIndex) { string disassembly = null; if (typeof(T) == typeof(PixelShader) || typeof(T) == typeof(GlobalPixelShader)) { PixelShaderBlock shader_block = null; if (typeof(T) == typeof(PixelShader)) { var _definition = Definition as PixelShader; if (shaderIndex < _definition.Shaders.Count) { shader_block = _definition.Shaders[shaderIndex]; } else { return(null); } } if (typeof(T) == typeof(GlobalPixelShader)) { var _definition = Definition as GlobalPixelShader; if (shaderIndex < _definition.Shaders.Count) { shader_block = _definition.Shaders[shaderIndex]; } else { return(null); } } var pc_shader = shader_block.PCShaderBytecode; disassembly = D3DCompiler.Disassemble(pc_shader); if (pc_shader == null) { disassembly = null; } } if (typeof(T) == typeof(VertexShader) || typeof(T) == typeof(GlobalVertexShader)) { VertexShaderBlock shader_block = null; if (typeof(T) == typeof(VertexShader)) { var _definition = Definition as VertexShader; if (shaderIndex < _definition.Shaders.Count) { shader_block = _definition.Shaders[shaderIndex]; } else { return(null); } } if (typeof(T) == typeof(GlobalVertexShader)) { var _definition = Definition as GlobalVertexShader; if (shaderIndex < _definition.Shaders.Count) { shader_block = _definition.Shaders[shaderIndex]; } else { return(null); } } var pc_shader = shader_block.PCShaderBytecode; disassembly = D3DCompiler.Disassemble(pc_shader); if (pc_shader == null) { disassembly = null; } } return(disassembly); }
public ShaderGeneratorResult(byte[] bytecode) { Bytecode = bytecode; if (bytecode == null) { return; } var result = D3DCompiler.Disassemble(bytecode); if (result == null) { return; } var registers = GetRegisters(result); var parameters = GetRegisterParameters(result); foreach (var parameters_kp in parameters) { var name = parameters_kp.Key; var typename = parameters_kp.Value; ShaderRegister.RegisterType register_type; { ShaderRegister.RegisterType?_register_type = null; switch (typename) { case "float4": case "float3": case "float2": case "float": _register_type = ShaderRegister.RegisterType.Vector; break; case "int": _register_type = ShaderRegister.RegisterType.Integer; break; case "bool": _register_type = ShaderRegister.RegisterType.Boolean; break; } if (typename.StartsWith("sampler")) { _register_type = ShaderRegister.RegisterType.Sampler; } register_type = _register_type ?? ShaderRegister.RegisterType.Vector; } foreach (var register in registers) { if (register.Name == name && register.registerType == register_type) { // Integers have an associated Vector, find and add it if (register_type == ShaderRegister.RegisterType.Integer) { foreach (var register2 in registers) { if (register2.Name == name && register2.registerType == ShaderRegister.RegisterType.Vector) { Registers.Add(register2); break; } } } Registers.Add(register); break; } // slight hack, for int's that get compiled only as vector else if (register.Name == name && register_type == ShaderRegister.RegisterType.Integer) { foreach (var register2 in registers) { if (register2.Name == name && register2.registerType == ShaderRegister.RegisterType.Vector) { Registers.Add(register2); break; } } } } } }
public override object Execute(List <string> args) { if (args.Count != 1) { return(false); } if (typeof(T) == typeof(PixelShader) || typeof(T) == typeof(GlobalPixelShader)) { PixelShaderBlock shader_block = null; if (typeof(T) == typeof(PixelShader)) { var _definition = Definition as PixelShader; shader_block = _definition.Shaders[int.Parse(args[0])]; } if (typeof(T) == typeof(GlobalPixelShader)) { var _definition = Definition as GlobalPixelShader; shader_block = _definition.Shaders[int.Parse(args[0])]; } var pc_shader = shader_block.PCShaderBytecode; var disassembly = D3DCompiler.Disassemble(pc_shader); if (pc_shader != null) { Console.WriteLine(disassembly); } else { Console.WriteLine("Failed to disassemble shader"); } } if (typeof(T) == typeof(VertexShader) || typeof(T) == typeof(GlobalVertexShader)) { VertexShaderBlock shader_block = null; if (typeof(T) == typeof(VertexShader)) { var _definition = Definition as VertexShader; shader_block = _definition.Shaders[int.Parse(args[0])]; } if (typeof(T) == typeof(GlobalVertexShader)) { var _definition = Definition as GlobalVertexShader; shader_block = _definition.Shaders[int.Parse(args[0])]; } var pc_shader = shader_block.PCShaderBytecode; var disassembly = D3DCompiler.Disassemble(pc_shader); if (pc_shader != null) { Console.WriteLine(disassembly); } else { Console.WriteLine("Failed to disassemble shader"); } } return(true); }
public override object Execute(List <string> args) { if (args.Count < 2) { return(false); } bool use_assembly_compiler = args.Count >= 2 && args[0].ToLower() == "asm"; string file = args[args.Count - 1]; string shader_code = File.ReadAllText(file); if (use_assembly_compiler && args.Count < 3) { return(false); } int index = use_assembly_compiler ? int.Parse(args[1]) : int.Parse(args[0]); if (!use_assembly_compiler) { using (var reader = new StringReader(shader_code)) { for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) { var str = line.Trim(); if (str == "ps_3_0" || str == "vs_3_0") { use_assembly_compiler = true; break; } } } } byte[] bytecode = null; if (use_assembly_compiler) { bytecode = D3DCompiler.Assemble(shader_code); } else { var profile = IsVertexShader ? "vs_3_0" : "ps_3_0"; try { bytecode = D3DCompiler.CompileFromFile(shader_code, "main", profile); } catch (Exception e) { Console.WriteLine(e); return(true); } } var disassembly = D3DCompiler.Disassemble(bytecode); Console.WriteLine(disassembly); if (typeof(T) == typeof(PixelShader) || typeof(T) == typeof(GlobalPixelShader)) { var shader_data_block = new PixelShaderBlock { PCShaderBytecode = bytecode }; if (typeof(T) == typeof(PixelShader)) { var _definition = Definition as PixelShader; var existing_block = _definition.Shaders[index]; shader_data_block.PCParameters = existing_block.PCParameters; _definition.Shaders[index] = shader_data_block; } if (typeof(T) == typeof(GlobalPixelShader)) { var _definition = Definition as GlobalPixelShader; var existing_block = _definition.Shaders[index]; shader_data_block.PCParameters = existing_block.PCParameters; _definition.Shaders[index] = shader_data_block; } } if (typeof(T) == typeof(VertexShader) || typeof(T) == typeof(GlobalVertexShader)) { var shader_data_block = new VertexShaderBlock { PCShaderBytecode = bytecode }; if (typeof(T) == typeof(VertexShader)) { var _definition = Definition as VertexShader; var existing_block = _definition.Shaders[index]; shader_data_block.PCParameters = existing_block.PCParameters; _definition.Shaders[index] = shader_data_block; } if (typeof(T) == typeof(GlobalVertexShader)) { var _definition = Definition as GlobalVertexShader; var existing_block = _definition.Shaders[index]; shader_data_block.PCParameters = existing_block.PCParameters; _definition.Shaders[index] = shader_data_block; } } return(true); }
static void TestSharedVertexBlack(VertexType vertexType, ShaderStage stage) { var gen = new ShaderBlackGenerator(); var bytecode = gen.GenerateSharedVertexShader(vertexType, stage).Bytecode; WriteShaderFile($"generated_shader_black_{stage.ToString().ToLower()}_{vertexType.ToString().ToLower()}.glvs", D3DCompiler.Disassemble(bytecode)); }
public override string GenerateExplicitVertexShader(ExplicitShader explicitShader, ShaderStage entry) { var bytecode = GenericVertexShaderGenerator.GenerateVertexShader(explicitShader.ToString(), entry.ToString().ToLower(), false).Bytecode; return(D3DCompiler.Disassemble(bytecode)); }