summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-25 22:35:30 -0500
committerGravatar GitHub2018-11-25 22:35:30 -0500
commit8ce90a4f0b9264405b2dda270be2d08a56362655 (patch)
tree8666d85138b9ca485b9cc02fa7fe77c95815e34c /src
parentMerge pull request #1796 from ReinUsesLisp/morton-move (diff)
parentgl_shader_decompiler: Implement clip distances (diff)
downloadyuzu-8ce90a4f0b9264405b2dda270be2d08a56362655.tar.gz
yuzu-8ce90a4f0b9264405b2dda270be2d08a56362655.tar.xz
yuzu-8ce90a4f0b9264405b2dda270be2d08a56362655.zip
Merge pull request #1783 from ReinUsesLisp/clip-distances
gl_shader_decompiler: Implement clip distances
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h2
-rw-r--r--src/video_core/engines/shader_header.h11
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp66
3 files changed, 58 insertions, 21 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 7e8449bc4..639bedb80 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -82,6 +82,8 @@ union Attribute {
82 Position = 7, 82 Position = 7,
83 Attribute_0 = 8, 83 Attribute_0 = 8,
84 Attribute_31 = 39, 84 Attribute_31 = 39,
85 ClipDistances0123 = 44,
86 ClipDistances4567 = 45,
85 PointCoord = 46, 87 PointCoord = 46,
86 // This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex 88 // This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex
87 // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval 89 // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval
diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h
index a0e015c4b..99c34649f 100644
--- a/src/video_core/engines/shader_header.h
+++ b/src/video_core/engines/shader_header.h
@@ -62,7 +62,16 @@ struct Header {
62 INSERT_PADDING_BYTES(1); // ImapSystemValuesB 62 INSERT_PADDING_BYTES(1); // ImapSystemValuesB
63 INSERT_PADDING_BYTES(16); // ImapGenericVector[32] 63 INSERT_PADDING_BYTES(16); // ImapGenericVector[32]
64 INSERT_PADDING_BYTES(2); // ImapColor 64 INSERT_PADDING_BYTES(2); // ImapColor
65 INSERT_PADDING_BYTES(2); // ImapSystemValuesC 65 union {
66 BitField<0, 8, u16> clip_distances;
67 BitField<8, 1, u16> point_sprite_s;
68 BitField<9, 1, u16> point_sprite_t;
69 BitField<10, 1, u16> fog_coordinate;
70 BitField<12, 1, u16> tessellation_eval_point_u;
71 BitField<13, 1, u16> tessellation_eval_point_v;
72 BitField<14, 1, u16> instance_id;
73 BitField<15, 1, u16> vertex_id;
74 };
66 INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10] 75 INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10]
67 INSERT_PADDING_BYTES(1); // ImapReserved 76 INSERT_PADDING_BYTES(1); // ImapReserved
68 INSERT_PADDING_BYTES(3); // OmapSystemValuesA 77 INSERT_PADDING_BYTES(3); // OmapSystemValuesA
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 97b9028c5..3b7841715 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -500,27 +500,42 @@ public:
500 const Register& buf_reg) { 500 const Register& buf_reg) {
501 const std::string dest = GetOutputAttribute(attribute); 501 const std::string dest = GetOutputAttribute(attribute);
502 const std::string src = GetRegisterAsFloat(val_reg); 502 const std::string src = GetRegisterAsFloat(val_reg);
503 if (dest.empty())
504 return;
503 505
504 if (!dest.empty()) { 506 // Can happen with unknown/unimplemented output attributes, in which case we ignore the
505 // Can happen with unknown/unimplemented output attributes, in which case we ignore the 507 // instruction for now.
506 // instruction for now. 508 if (stage == Maxwell3D::Regs::ShaderStage::Geometry) {
507 if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { 509 // TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry
508 // TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry 510 // shader. These instructions use a dirty register as buffer index, to avoid some
509 // shader. These instructions use a dirty register as buffer index, to avoid some 511 // drivers from complaining about out of boundary writes, guard them.
510 // drivers from complaining about out of boundary writes, guard them. 512 const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " +
511 const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + 513 std::to_string(MAX_GEOMETRY_BUFFERS) + ')'};
512 std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; 514 shader.AddLine("amem[" + buf_index + "][" +
513 shader.AddLine("amem[" + buf_index + "][" + 515 std::to_string(static_cast<u32>(attribute)) + ']' + GetSwizzle(elem) +
514 std::to_string(static_cast<u32>(attribute)) + ']' + 516 " = " + src + ';');
515 GetSwizzle(elem) + " = " + src + ';'); 517 return;
516 } else { 518 }
517 if (attribute == Attribute::Index::PointSize) { 519
518 fixed_pipeline_output_attributes_used.insert(attribute); 520 switch (attribute) {
519 shader.AddLine(dest + " = " + src + ';'); 521 case Attribute::Index::ClipDistances0123:
520 } else { 522 case Attribute::Index::ClipDistances4567: {
521 shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); 523 const u64 index = attribute == Attribute::Index::ClipDistances4567 ? 4 : 0 + elem;
522 } 524 UNIMPLEMENTED_IF_MSG(
523 } 525 ((header.vtg.clip_distances >> index) & 1) == 0,
526 "Shader is setting gl_ClipDistance{} without enabling it in the header", index);
527
528 fixed_pipeline_output_attributes_used.insert(attribute);
529 shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';');
530 break;
531 }
532 case Attribute::Index::PointSize:
533 fixed_pipeline_output_attributes_used.insert(attribute);
534 shader.AddLine(dest + " = " + src + ';');
535 break;
536 default:
537 shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';');
538 break;
524 } 539 }
525 } 540 }
526 541
@@ -740,12 +755,19 @@ private:
740 void GenerateVertex() { 755 void GenerateVertex() {
741 if (stage != Maxwell3D::Regs::ShaderStage::Vertex) 756 if (stage != Maxwell3D::Regs::ShaderStage::Vertex)
742 return; 757 return;
758 bool clip_distances_declared = false;
759
743 declarations.AddLine("out gl_PerVertex {"); 760 declarations.AddLine("out gl_PerVertex {");
744 ++declarations.scope; 761 ++declarations.scope;
745 declarations.AddLine("vec4 gl_Position;"); 762 declarations.AddLine("vec4 gl_Position;");
746 for (auto& o : fixed_pipeline_output_attributes_used) { 763 for (auto& o : fixed_pipeline_output_attributes_used) {
747 if (o == Attribute::Index::PointSize) 764 if (o == Attribute::Index::PointSize)
748 declarations.AddLine("float gl_PointSize;"); 765 declarations.AddLine("float gl_PointSize;");
766 if (!clip_distances_declared && (o == Attribute::Index::ClipDistances0123 ||
767 o == Attribute::Index::ClipDistances4567)) {
768 declarations.AddLine("float gl_ClipDistance[];");
769 clip_distances_declared = true;
770 }
749 } 771 }
750 --declarations.scope; 772 --declarations.scope;
751 declarations.AddLine("};"); 773 declarations.AddLine("};");
@@ -916,6 +938,10 @@ private:
916 return "gl_PointSize"; 938 return "gl_PointSize";
917 case Attribute::Index::Position: 939 case Attribute::Index::Position:
918 return "position"; 940 return "position";
941 case Attribute::Index::ClipDistances0123:
942 case Attribute::Index::ClipDistances4567: {
943 return "gl_ClipDistance";
944 }
919 default: 945 default:
920 const u32 index{static_cast<u32>(attribute) - 946 const u32 index{static_cast<u32>(attribute) -
921 static_cast<u32>(Attribute::Index::Attribute_0)}; 947 static_cast<u32>(Attribute::Index::Attribute_0)};