diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.h | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 91 |
4 files changed, 88 insertions, 27 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 85d309d9b..b1e640dd1 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -51,6 +51,7 @@ public: | |||
| 51 | static constexpr std::size_t NumCBData = 16; | 51 | static constexpr std::size_t NumCBData = 16; |
| 52 | static constexpr std::size_t NumVertexArrays = 32; | 52 | static constexpr std::size_t NumVertexArrays = 32; |
| 53 | static constexpr std::size_t NumVertexAttributes = 32; | 53 | static constexpr std::size_t NumVertexAttributes = 32; |
| 54 | static constexpr std::size_t NumVaryings = 31; | ||
| 54 | static constexpr std::size_t NumTextureSamplers = 32; | 55 | static constexpr std::size_t NumTextureSamplers = 32; |
| 55 | static constexpr std::size_t NumClipDistances = 8; | 56 | static constexpr std::size_t NumClipDistances = 8; |
| 56 | static constexpr std::size_t MaxShaderProgram = 6; | 57 | static constexpr std::size_t MaxShaderProgram = 6; |
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index b6d9e0ddb..38497678a 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -21,9 +21,18 @@ T GetInteger(GLenum pname) { | |||
| 21 | 21 | ||
| 22 | Device::Device() { | 22 | Device::Device() { |
| 23 | uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); | 23 | uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); |
| 24 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); | ||
| 25 | max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); | ||
| 24 | has_variable_aoffi = TestVariableAoffi(); | 26 | has_variable_aoffi = TestVariableAoffi(); |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 29 | Device::Device(std::nullptr_t) { | ||
| 30 | uniform_buffer_alignment = 0; | ||
| 31 | max_vertex_attributes = 16; | ||
| 32 | max_varyings = 15; | ||
| 33 | has_variable_aoffi = true; | ||
| 34 | } | ||
| 35 | |||
| 27 | bool Device::TestVariableAoffi() { | 36 | bool Device::TestVariableAoffi() { |
| 28 | const GLchar* AOFFI_TEST = R"(#version 430 core | 37 | const GLchar* AOFFI_TEST = R"(#version 430 core |
| 29 | uniform sampler2D tex; | 38 | uniform sampler2D tex; |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 78ff5ee58..de8490682 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -5,17 +5,27 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstddef> | 7 | #include <cstddef> |
| 8 | #include "common/common_types.h" | ||
| 8 | 9 | ||
| 9 | namespace OpenGL { | 10 | namespace OpenGL { |
| 10 | 11 | ||
| 11 | class Device { | 12 | class Device { |
| 12 | public: | 13 | public: |
| 13 | Device(); | 14 | explicit Device(); |
| 15 | explicit Device(std::nullptr_t); | ||
| 14 | 16 | ||
| 15 | std::size_t GetUniformBufferAlignment() const { | 17 | std::size_t GetUniformBufferAlignment() const { |
| 16 | return uniform_buffer_alignment; | 18 | return uniform_buffer_alignment; |
| 17 | } | 19 | } |
| 18 | 20 | ||
| 21 | u32 GetMaxVertexAttributes() const { | ||
| 22 | return max_vertex_attributes; | ||
| 23 | } | ||
| 24 | |||
| 25 | u32 GetMaxVaryings() const { | ||
| 26 | return max_varyings; | ||
| 27 | } | ||
| 28 | |||
| 19 | bool HasVariableAoffi() const { | 29 | bool HasVariableAoffi() const { |
| 20 | return has_variable_aoffi; | 30 | return has_variable_aoffi; |
| 21 | } | 31 | } |
| @@ -24,6 +34,8 @@ private: | |||
| 24 | static bool TestVariableAoffi(); | 34 | static bool TestVariableAoffi(); |
| 25 | 35 | ||
| 26 | std::size_t uniform_buffer_alignment{}; | 36 | std::size_t uniform_buffer_alignment{}; |
| 37 | u32 max_vertex_attributes{}; | ||
| 38 | u32 max_varyings{}; | ||
| 27 | bool has_variable_aoffi{}; | 39 | bool has_variable_aoffi{}; |
| 28 | }; | 40 | }; |
| 29 | 41 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 33c0edca9..8df91a4c6 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -316,55 +316,85 @@ private: | |||
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | void DeclareInputAttributes() { | 318 | void DeclareInputAttributes() { |
| 319 | if (ir.HasPhysicalAttributes()) { | ||
| 320 | const u32 num_inputs{stage == ShaderStage::Vertex ? GetNumPhysicalAttributes() | ||
| 321 | : GetNumPhysicalVaryings()}; | ||
| 322 | for (u32 i = 0; i < num_inputs; ++i) { | ||
| 323 | constexpr auto generic_base{static_cast<u32>(Attribute::Index::Attribute_0)}; | ||
| 324 | const auto index{static_cast<Attribute::Index>(generic_base + i)}; | ||
| 325 | DeclareInputAttribute(index); | ||
| 326 | } | ||
| 327 | code.AddNewLine(); | ||
| 328 | return; | ||
| 329 | } | ||
| 330 | |||
| 319 | const auto& attributes = ir.GetInputAttributes(); | 331 | const auto& attributes = ir.GetInputAttributes(); |
| 320 | for (const auto index : attributes) { | 332 | for (const auto index : attributes) { |
| 321 | if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { | 333 | if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { |
| 322 | // Skip when it's not a generic attribute | 334 | // Skip when it's not a generic attribute |
| 323 | continue; | 335 | continue; |
| 324 | } | 336 | } |
| 325 | 337 | DeclareInputAttribute(index); | |
| 326 | // TODO(bunnei): Use proper number of elements for these | ||
| 327 | u32 idx = static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0); | ||
| 328 | if (stage != ShaderStage::Vertex) { | ||
| 329 | // If inputs are varyings, add an offset | ||
| 330 | idx += GENERIC_VARYING_START_LOCATION; | ||
| 331 | } | ||
| 332 | |||
| 333 | std::string attr = GetInputAttribute(index); | ||
| 334 | if (stage == ShaderStage::Geometry) { | ||
| 335 | attr = "gs_" + attr + "[]"; | ||
| 336 | } | ||
| 337 | std::string suffix; | ||
| 338 | if (stage == ShaderStage::Fragment) { | ||
| 339 | const auto input_mode = | ||
| 340 | header.ps.GetAttributeUse(idx - GENERIC_VARYING_START_LOCATION); | ||
| 341 | suffix = GetInputFlags(input_mode); | ||
| 342 | } | ||
| 343 | code.AddLine("layout (location = " + std::to_string(idx) + ") " + suffix + "in vec4 " + | ||
| 344 | attr + ';'); | ||
| 345 | } | 338 | } |
| 346 | if (!attributes.empty()) | 339 | if (!attributes.empty()) |
| 347 | code.AddNewLine(); | 340 | code.AddNewLine(); |
| 348 | } | 341 | } |
| 349 | 342 | ||
| 343 | void DeclareInputAttribute(Attribute::Index index) { | ||
| 344 | const u32 generic_index{static_cast<u32>(index) - | ||
| 345 | static_cast<u32>(Attribute::Index::Attribute_0)}; | ||
| 346 | |||
| 347 | std::string name{GetInputAttribute(index)}; | ||
| 348 | if (stage == ShaderStage::Geometry) { | ||
| 349 | name = "gs_" + name + "[]"; | ||
| 350 | } | ||
| 351 | std::string suffix; | ||
| 352 | if (stage == ShaderStage::Fragment) { | ||
| 353 | const auto input_mode{header.ps.GetAttributeUse(generic_index)}; | ||
| 354 | suffix = GetInputFlags(input_mode); | ||
| 355 | } | ||
| 356 | |||
| 357 | u32 location = generic_index; | ||
| 358 | if (stage != ShaderStage::Vertex) { | ||
| 359 | // If inputs are varyings, add an offset | ||
| 360 | location += GENERIC_VARYING_START_LOCATION; | ||
| 361 | } | ||
| 362 | |||
| 363 | code.AddLine("layout (location = " + std::to_string(location) + ") " + suffix + "in vec4 " + | ||
| 364 | name + ';'); | ||
| 365 | } | ||
| 366 | |||
| 350 | void DeclareOutputAttributes() { | 367 | void DeclareOutputAttributes() { |
| 368 | if (ir.HasPhysicalAttributes()) { | ||
| 369 | for (u32 i = 0; i < GetNumPhysicalVaryings(); ++i) { | ||
| 370 | constexpr auto generic_base{static_cast<u32>(Attribute::Index::Attribute_0)}; | ||
| 371 | const auto index{static_cast<Attribute::Index>(generic_base + i)}; | ||
| 372 | DeclareOutputAttribute(index); | ||
| 373 | } | ||
| 374 | code.AddNewLine(); | ||
| 375 | return; | ||
| 376 | } | ||
| 377 | |||
| 351 | const auto& attributes = ir.GetOutputAttributes(); | 378 | const auto& attributes = ir.GetOutputAttributes(); |
| 352 | for (const auto index : attributes) { | 379 | for (const auto index : attributes) { |
| 353 | if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { | 380 | if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { |
| 354 | // Skip when it's not a generic attribute | 381 | // Skip when it's not a generic attribute |
| 355 | continue; | 382 | continue; |
| 356 | } | 383 | } |
| 357 | // TODO(bunnei): Use proper number of elements for these | 384 | DeclareOutputAttribute(index); |
| 358 | const auto idx = static_cast<u32>(index) - | ||
| 359 | static_cast<u32>(Attribute::Index::Attribute_0) + | ||
| 360 | GENERIC_VARYING_START_LOCATION; | ||
| 361 | code.AddLine("layout (location = " + std::to_string(idx) + ") out vec4 " + | ||
| 362 | GetOutputAttribute(index) + ';'); | ||
| 363 | } | 385 | } |
| 364 | if (!attributes.empty()) | 386 | if (!attributes.empty()) |
| 365 | code.AddNewLine(); | 387 | code.AddNewLine(); |
| 366 | } | 388 | } |
| 367 | 389 | ||
| 390 | void DeclareOutputAttribute(Attribute::Index index) { | ||
| 391 | const auto location{static_cast<u32>(index) - | ||
| 392 | static_cast<u32>(Attribute::Index::Attribute_0) + | ||
| 393 | GENERIC_VARYING_START_LOCATION}; | ||
| 394 | code.AddLine("layout (location = " + std::to_string(location) + ") out vec4 " + | ||
| 395 | GetOutputAttribute(index) + ';'); | ||
| 396 | } | ||
| 397 | |||
| 368 | void DeclareConstantBuffers() { | 398 | void DeclareConstantBuffers() { |
| 369 | for (const auto& entry : ir.GetConstantBuffers()) { | 399 | for (const auto& entry : ir.GetConstantBuffers()) { |
| 370 | const auto [index, size] = entry; | 400 | const auto [index, size] = entry; |
| @@ -1650,6 +1680,15 @@ private: | |||
| 1650 | return name + '_' + std::to_string(index) + '_' + suffix; | 1680 | return name + '_' + std::to_string(index) + '_' + suffix; |
| 1651 | } | 1681 | } |
| 1652 | 1682 | ||
| 1683 | u32 GetNumPhysicalAttributes() const { | ||
| 1684 | return std::min<u32>(device.GetMaxVertexAttributes(), Maxwell::NumVertexAttributes); | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | u32 GetNumPhysicalVaryings() const { | ||
| 1688 | return std::min<u32>(device.GetMaxVaryings() - GENERIC_VARYING_START_LOCATION, | ||
| 1689 | Maxwell::NumVaryings); | ||
| 1690 | } | ||
| 1691 | |||
| 1653 | const Device& device; | 1692 | const Device& device; |
| 1654 | const ShaderIR& ir; | 1693 | const ShaderIR& ir; |
| 1655 | const ShaderStage stage; | 1694 | const ShaderStage stage; |