summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.h1
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp9
-rw-r--r--src/video_core/renderer_opengl/gl_device.h14
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp91
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
22Device::Device() { 22Device::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
29Device::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
27bool Device::TestVariableAoffi() { 36bool Device::TestVariableAoffi() {
28 const GLchar* AOFFI_TEST = R"(#version 430 core 37 const GLchar* AOFFI_TEST = R"(#version 430 core
29uniform sampler2D tex; 38uniform 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
9namespace OpenGL { 10namespace OpenGL {
10 11
11class Device { 12class Device {
12public: 13public:
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;