forked from eden-emu/eden
		
	Merge pull request #1783 from ReinUsesLisp/clip-distances
gl_shader_decompiler: Implement clip distances
This commit is contained in:
		
						commit
						8ce90a4f0b
					
				
					 3 changed files with 58 additions and 21 deletions
				
			
		|  | @ -82,6 +82,8 @@ union Attribute { | |||
|         Position = 7, | ||||
|         Attribute_0 = 8, | ||||
|         Attribute_31 = 39, | ||||
|         ClipDistances0123 = 44, | ||||
|         ClipDistances4567 = 45, | ||||
|         PointCoord = 46, | ||||
|         // This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex
 | ||||
|         // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval
 | ||||
|  |  | |||
|  | @ -62,7 +62,16 @@ struct Header { | |||
|             INSERT_PADDING_BYTES(1);  // ImapSystemValuesB
 | ||||
|             INSERT_PADDING_BYTES(16); // ImapGenericVector[32]
 | ||||
|             INSERT_PADDING_BYTES(2);  // ImapColor
 | ||||
|             INSERT_PADDING_BYTES(2);  // ImapSystemValuesC
 | ||||
|             union { | ||||
|                 BitField<0, 8, u16> clip_distances; | ||||
|                 BitField<8, 1, u16> point_sprite_s; | ||||
|                 BitField<9, 1, u16> point_sprite_t; | ||||
|                 BitField<10, 1, u16> fog_coordinate; | ||||
|                 BitField<12, 1, u16> tessellation_eval_point_u; | ||||
|                 BitField<13, 1, u16> tessellation_eval_point_v; | ||||
|                 BitField<14, 1, u16> instance_id; | ||||
|                 BitField<15, 1, u16> vertex_id; | ||||
|             }; | ||||
|             INSERT_PADDING_BYTES(5);  // ImapFixedFncTexture[10]
 | ||||
|             INSERT_PADDING_BYTES(1);  // ImapReserved
 | ||||
|             INSERT_PADDING_BYTES(3);  // OmapSystemValuesA
 | ||||
|  |  | |||
|  | @ -500,27 +500,42 @@ public: | |||
|                                       const Register& buf_reg) { | ||||
|         const std::string dest = GetOutputAttribute(attribute); | ||||
|         const std::string src = GetRegisterAsFloat(val_reg); | ||||
|         if (dest.empty()) | ||||
|             return; | ||||
| 
 | ||||
|         if (!dest.empty()) { | ||||
|             // Can happen with unknown/unimplemented output attributes, in which case we ignore the
 | ||||
|             // instruction for now.
 | ||||
|             if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { | ||||
|                 // TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry
 | ||||
|                 // shader. These instructions use a dirty register as buffer index, to avoid some
 | ||||
|                 // drivers from complaining about out of boundary writes, guard them.
 | ||||
|                 const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + | ||||
|                                             std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; | ||||
|                 shader.AddLine("amem[" + buf_index + "][" + | ||||
|                                std::to_string(static_cast<u32>(attribute)) + ']' + | ||||
|                                GetSwizzle(elem) + " = " + src + ';'); | ||||
|             } else { | ||||
|                 if (attribute == Attribute::Index::PointSize) { | ||||
|                     fixed_pipeline_output_attributes_used.insert(attribute); | ||||
|                     shader.AddLine(dest + " = " + src + ';'); | ||||
|                 } else { | ||||
|                     shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); | ||||
|                 } | ||||
|             } | ||||
|         // Can happen with unknown/unimplemented output attributes, in which case we ignore the
 | ||||
|         // instruction for now.
 | ||||
|         if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { | ||||
|             // TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry
 | ||||
|             // shader. These instructions use a dirty register as buffer index, to avoid some
 | ||||
|             // drivers from complaining about out of boundary writes, guard them.
 | ||||
|             const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + | ||||
|                                         std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; | ||||
|             shader.AddLine("amem[" + buf_index + "][" + | ||||
|                            std::to_string(static_cast<u32>(attribute)) + ']' + GetSwizzle(elem) + | ||||
|                            " = " + src + ';'); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         switch (attribute) { | ||||
|         case Attribute::Index::ClipDistances0123: | ||||
|         case Attribute::Index::ClipDistances4567: { | ||||
|             const u64 index = attribute == Attribute::Index::ClipDistances4567 ? 4 : 0 + elem; | ||||
|             UNIMPLEMENTED_IF_MSG( | ||||
|                 ((header.vtg.clip_distances >> index) & 1) == 0, | ||||
|                 "Shader is setting gl_ClipDistance{} without enabling it in the header", index); | ||||
| 
 | ||||
|             fixed_pipeline_output_attributes_used.insert(attribute); | ||||
|             shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';'); | ||||
|             break; | ||||
|         } | ||||
|         case Attribute::Index::PointSize: | ||||
|             fixed_pipeline_output_attributes_used.insert(attribute); | ||||
|             shader.AddLine(dest + " = " + src + ';'); | ||||
|             break; | ||||
|         default: | ||||
|             shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -740,12 +755,19 @@ private: | |||
|     void GenerateVertex() { | ||||
|         if (stage != Maxwell3D::Regs::ShaderStage::Vertex) | ||||
|             return; | ||||
|         bool clip_distances_declared = false; | ||||
| 
 | ||||
|         declarations.AddLine("out gl_PerVertex {"); | ||||
|         ++declarations.scope; | ||||
|         declarations.AddLine("vec4 gl_Position;"); | ||||
|         for (auto& o : fixed_pipeline_output_attributes_used) { | ||||
|             if (o == Attribute::Index::PointSize) | ||||
|                 declarations.AddLine("float gl_PointSize;"); | ||||
|             if (!clip_distances_declared && (o == Attribute::Index::ClipDistances0123 || | ||||
|                                              o == Attribute::Index::ClipDistances4567)) { | ||||
|                 declarations.AddLine("float gl_ClipDistance[];"); | ||||
|                 clip_distances_declared = true; | ||||
|             } | ||||
|         } | ||||
|         --declarations.scope; | ||||
|         declarations.AddLine("};"); | ||||
|  | @ -916,6 +938,10 @@ private: | |||
|             return "gl_PointSize"; | ||||
|         case Attribute::Index::Position: | ||||
|             return "position"; | ||||
|         case Attribute::Index::ClipDistances0123: | ||||
|         case Attribute::Index::ClipDistances4567: { | ||||
|             return "gl_ClipDistance"; | ||||
|         } | ||||
|         default: | ||||
|             const u32 index{static_cast<u32>(attribute) - | ||||
|                             static_cast<u32>(Attribute::Index::Attribute_0)}; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei