diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/shader_header.h | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 66 |
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 83a6fd875..c0275afb5 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 90a88b91a..1ae25c7b3 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -485,27 +485,42 @@ public: | |||
| 485 | const Register& buf_reg) { | 485 | const Register& buf_reg) { |
| 486 | const std::string dest = GetOutputAttribute(attribute); | 486 | const std::string dest = GetOutputAttribute(attribute); |
| 487 | const std::string src = GetRegisterAsFloat(val_reg); | 487 | const std::string src = GetRegisterAsFloat(val_reg); |
| 488 | if (dest.empty()) | ||
| 489 | return; | ||
| 488 | 490 | ||
| 489 | if (!dest.empty()) { | 491 | // Can happen with unknown/unimplemented output attributes, in which case we ignore the |
| 490 | // Can happen with unknown/unimplemented output attributes, in which case we ignore the | 492 | // instruction for now. |
| 491 | // instruction for now. | 493 | if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { |
| 492 | if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { | 494 | // TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry |
| 493 | // TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry | 495 | // shader. These instructions use a dirty register as buffer index, to avoid some |
| 494 | // shader. These instructions use a dirty register as buffer index, to avoid some | 496 | // drivers from complaining about out of boundary writes, guard them. |
| 495 | // drivers from complaining about out of boundary writes, guard them. | 497 | const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + |
| 496 | const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + | 498 | std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; |
| 497 | std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; | 499 | shader.AddLine("amem[" + buf_index + "][" + |
| 498 | shader.AddLine("amem[" + buf_index + "][" + | 500 | std::to_string(static_cast<u32>(attribute)) + ']' + GetSwizzle(elem) + |
| 499 | std::to_string(static_cast<u32>(attribute)) + ']' + | 501 | " = " + src + ';'); |
| 500 | GetSwizzle(elem) + " = " + src + ';'); | 502 | return; |
| 501 | } else { | 503 | } |
| 502 | if (attribute == Attribute::Index::PointSize) { | 504 | |
| 503 | fixed_pipeline_output_attributes_used.insert(attribute); | 505 | switch (attribute) { |
| 504 | shader.AddLine(dest + " = " + src + ';'); | 506 | case Attribute::Index::ClipDistances0123: |
| 505 | } else { | 507 | case Attribute::Index::ClipDistances4567: { |
| 506 | shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); | 508 | const u64 index = attribute == Attribute::Index::ClipDistances4567 ? 4 : 0 + elem; |
| 507 | } | 509 | UNIMPLEMENTED_IF_MSG( |
| 508 | } | 510 | ((header.vtg.clip_distances >> index) & 1) == 0, |
| 511 | "Shader is setting gl_ClipDistance{} without enabling it in the header", index); | ||
| 512 | |||
| 513 | fixed_pipeline_output_attributes_used.insert(attribute); | ||
| 514 | shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';'); | ||
| 515 | break; | ||
| 516 | } | ||
| 517 | case Attribute::Index::PointSize: | ||
| 518 | fixed_pipeline_output_attributes_used.insert(attribute); | ||
| 519 | shader.AddLine(dest + " = " + src + ';'); | ||
| 520 | break; | ||
| 521 | default: | ||
| 522 | shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); | ||
| 523 | break; | ||
| 509 | } | 524 | } |
| 510 | } | 525 | } |
| 511 | 526 | ||
| @@ -725,12 +740,19 @@ private: | |||
| 725 | void GenerateVertex() { | 740 | void GenerateVertex() { |
| 726 | if (stage != Maxwell3D::Regs::ShaderStage::Vertex) | 741 | if (stage != Maxwell3D::Regs::ShaderStage::Vertex) |
| 727 | return; | 742 | return; |
| 743 | bool clip_distances_declared = false; | ||
| 744 | |||
| 728 | declarations.AddLine("out gl_PerVertex {"); | 745 | declarations.AddLine("out gl_PerVertex {"); |
| 729 | ++declarations.scope; | 746 | ++declarations.scope; |
| 730 | declarations.AddLine("vec4 gl_Position;"); | 747 | declarations.AddLine("vec4 gl_Position;"); |
| 731 | for (auto& o : fixed_pipeline_output_attributes_used) { | 748 | for (auto& o : fixed_pipeline_output_attributes_used) { |
| 732 | if (o == Attribute::Index::PointSize) | 749 | if (o == Attribute::Index::PointSize) |
| 733 | declarations.AddLine("float gl_PointSize;"); | 750 | declarations.AddLine("float gl_PointSize;"); |
| 751 | if (!clip_distances_declared && (o == Attribute::Index::ClipDistances0123 || | ||
| 752 | o == Attribute::Index::ClipDistances4567)) { | ||
| 753 | declarations.AddLine("float gl_ClipDistance[];"); | ||
| 754 | clip_distances_declared = true; | ||
| 755 | } | ||
| 734 | } | 756 | } |
| 735 | --declarations.scope; | 757 | --declarations.scope; |
| 736 | declarations.AddLine("};"); | 758 | declarations.AddLine("};"); |
| @@ -901,6 +923,10 @@ private: | |||
| 901 | return "gl_PointSize"; | 923 | return "gl_PointSize"; |
| 902 | case Attribute::Index::Position: | 924 | case Attribute::Index::Position: |
| 903 | return "position"; | 925 | return "position"; |
| 926 | case Attribute::Index::ClipDistances0123: | ||
| 927 | case Attribute::Index::ClipDistances4567: { | ||
| 928 | return "gl_ClipDistance"; | ||
| 929 | } | ||
| 904 | default: | 930 | default: |
| 905 | const u32 index{static_cast<u32>(attribute) - | 931 | const u32 index{static_cast<u32>(attribute) - |
| 906 | static_cast<u32>(Attribute::Index::Attribute_0)}; | 932 | static_cast<u32>(Attribute::Index::Attribute_0)}; |