|
|
@ -14,6 +14,7 @@ |
|
|
#include "common/alignment.h"
|
|
|
#include "common/alignment.h"
|
|
|
#include "common/assert.h"
|
|
|
#include "common/assert.h"
|
|
|
#include "common/common_types.h"
|
|
|
#include "common/common_types.h"
|
|
|
|
|
|
#include "common/logging/log.h"
|
|
|
#include "video_core/engines/maxwell_3d.h"
|
|
|
#include "video_core/engines/maxwell_3d.h"
|
|
|
#include "video_core/renderer_opengl/gl_device.h"
|
|
|
#include "video_core/renderer_opengl/gl_device.h"
|
|
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
|
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
|
|
@ -246,6 +247,8 @@ public: |
|
|
usage.is_read, usage.is_written); |
|
|
usage.is_read, usage.is_written); |
|
|
} |
|
|
} |
|
|
entries.clip_distances = ir.GetClipDistances(); |
|
|
entries.clip_distances = ir.GetClipDistances(); |
|
|
|
|
|
entries.shader_viewport_layer_array = |
|
|
|
|
|
stage == ShaderStage::Vertex && (ir.UsesLayer() || ir.UsesViewportIndex()); |
|
|
entries.shader_length = ir.GetLength(); |
|
|
entries.shader_length = ir.GetLength(); |
|
|
return entries; |
|
|
return entries; |
|
|
} |
|
|
} |
|
|
@ -282,21 +285,34 @@ private: |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void DeclareVertexRedeclarations() { |
|
|
void DeclareVertexRedeclarations() { |
|
|
bool clip_distances_declared = false; |
|
|
|
|
|
|
|
|
|
|
|
code.AddLine("out gl_PerVertex {{"); |
|
|
code.AddLine("out gl_PerVertex {{"); |
|
|
++code.scope; |
|
|
++code.scope; |
|
|
|
|
|
|
|
|
code.AddLine("vec4 gl_Position;"); |
|
|
code.AddLine("vec4 gl_Position;"); |
|
|
|
|
|
|
|
|
for (const auto o : ir.GetOutputAttributes()) { |
|
|
|
|
|
if (o == Attribute::Index::PointSize) |
|
|
|
|
|
code.AddLine("float gl_PointSize;"); |
|
|
|
|
|
if (!clip_distances_declared && (o == Attribute::Index::ClipDistances0123 || |
|
|
|
|
|
o == Attribute::Index::ClipDistances4567)) { |
|
|
|
|
|
|
|
|
for (const auto attribute : ir.GetOutputAttributes()) { |
|
|
|
|
|
if (attribute == Attribute::Index::ClipDistances0123 || |
|
|
|
|
|
attribute == Attribute::Index::ClipDistances4567) { |
|
|
code.AddLine("float gl_ClipDistance[];"); |
|
|
code.AddLine("float gl_ClipDistance[];"); |
|
|
clip_distances_declared = true; |
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (stage != ShaderStage::Vertex || device.HasVertexViewportLayer()) { |
|
|
|
|
|
if (ir.UsesLayer()) { |
|
|
|
|
|
code.AddLine("int gl_Layer;"); |
|
|
|
|
|
} |
|
|
|
|
|
if (ir.UsesViewportIndex()) { |
|
|
|
|
|
code.AddLine("int gl_ViewportIndex;"); |
|
|
} |
|
|
} |
|
|
|
|
|
} else if ((ir.UsesLayer() || ir.UsesViewportIndex()) && stage == ShaderStage::Vertex && |
|
|
|
|
|
!device.HasVertexViewportLayer()) { |
|
|
|
|
|
LOG_ERROR( |
|
|
|
|
|
Render_OpenGL, |
|
|
|
|
|
"GL_ARB_shader_viewport_layer_array is not available and its required by a shader"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ir.UsesPointSize()) { |
|
|
|
|
|
code.AddLine("float gl_PointSize;"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
--code.scope; |
|
|
--code.scope; |
|
|
@ -805,6 +821,45 @@ private: |
|
|
return CastOperand(VisitOperand(operation, operand_index), type); |
|
|
return CastOperand(VisitOperand(operation, operand_index), type); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, bool>> GetOutputAttribute(const AbufNode* abuf) { |
|
|
|
|
|
switch (const auto attribute = abuf->GetIndex()) { |
|
|
|
|
|
case Attribute::Index::Position: |
|
|
|
|
|
return std::make_pair("gl_Position"s + GetSwizzle(abuf->GetElement()), false); |
|
|
|
|
|
case Attribute::Index::LayerViewportPointSize: |
|
|
|
|
|
switch (abuf->GetElement()) { |
|
|
|
|
|
case 0: |
|
|
|
|
|
UNIMPLEMENTED(); |
|
|
|
|
|
return {}; |
|
|
|
|
|
case 1: |
|
|
|
|
|
if (stage == ShaderStage::Vertex && !device.HasVertexViewportLayer()) { |
|
|
|
|
|
return {}; |
|
|
|
|
|
} |
|
|
|
|
|
return std::make_pair("gl_Layer", true); |
|
|
|
|
|
case 2: |
|
|
|
|
|
if (stage == ShaderStage::Vertex && !device.HasVertexViewportLayer()) { |
|
|
|
|
|
return {}; |
|
|
|
|
|
} |
|
|
|
|
|
return std::make_pair("gl_ViewportIndex", true); |
|
|
|
|
|
case 3: |
|
|
|
|
|
UNIMPLEMENTED_MSG("Requires some state changes for gl_PointSize to work in shader"); |
|
|
|
|
|
return std::make_pair("gl_PointSize", false); |
|
|
|
|
|
} |
|
|
|
|
|
return {}; |
|
|
|
|
|
case Attribute::Index::ClipDistances0123: |
|
|
|
|
|
return std::make_pair(fmt::format("gl_ClipDistance[{}]", abuf->GetElement()), false); |
|
|
|
|
|
case Attribute::Index::ClipDistances4567: |
|
|
|
|
|
return std::make_pair(fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4), |
|
|
|
|
|
false); |
|
|
|
|
|
default: |
|
|
|
|
|
if (IsGenericAttribute(attribute)) { |
|
|
|
|
|
return std::make_pair( |
|
|
|
|
|
GetOutputAttribute(attribute) + GetSwizzle(abuf->GetElement()), false); |
|
|
|
|
|
} |
|
|
|
|
|
UNIMPLEMENTED_MSG("Unhandled output attribute: {}", static_cast<u32>(attribute)); |
|
|
|
|
|
return {}; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
std::string CastOperand(const std::string& value, Type type) const { |
|
|
std::string CastOperand(const std::string& value, Type type) const { |
|
|
switch (type) { |
|
|
switch (type) { |
|
|
case Type::Bool: |
|
|
case Type::Bool: |
|
|
@ -1001,6 +1056,8 @@ private: |
|
|
const Node& src = operation[1]; |
|
|
const Node& src = operation[1]; |
|
|
|
|
|
|
|
|
std::string target; |
|
|
std::string target; |
|
|
|
|
|
bool is_integer = false; |
|
|
|
|
|
|
|
|
if (const auto gpr = std::get_if<GprNode>(&*dest)) { |
|
|
if (const auto gpr = std::get_if<GprNode>(&*dest)) { |
|
|
if (gpr->GetIndex() == Register::ZeroIndex) { |
|
|
if (gpr->GetIndex() == Register::ZeroIndex) { |
|
|
// Writing to Register::ZeroIndex is a no op
|
|
|
// Writing to Register::ZeroIndex is a no op
|
|
|
@ -1009,26 +1066,12 @@ private: |
|
|
target = GetRegister(gpr->GetIndex()); |
|
|
target = GetRegister(gpr->GetIndex()); |
|
|
} else if (const auto abuf = std::get_if<AbufNode>(&*dest)) { |
|
|
} else if (const auto abuf = std::get_if<AbufNode>(&*dest)) { |
|
|
UNIMPLEMENTED_IF(abuf->IsPhysicalBuffer()); |
|
|
UNIMPLEMENTED_IF(abuf->IsPhysicalBuffer()); |
|
|
|
|
|
|
|
|
target = [&]() -> std::string { |
|
|
|
|
|
switch (const auto attribute = abuf->GetIndex(); abuf->GetIndex()) { |
|
|
|
|
|
case Attribute::Index::Position: |
|
|
|
|
|
return "gl_Position"s + GetSwizzle(abuf->GetElement()); |
|
|
|
|
|
case Attribute::Index::PointSize: |
|
|
|
|
|
return "gl_PointSize"; |
|
|
|
|
|
case Attribute::Index::ClipDistances0123: |
|
|
|
|
|
return fmt::format("gl_ClipDistance[{}]", abuf->GetElement()); |
|
|
|
|
|
case Attribute::Index::ClipDistances4567: |
|
|
|
|
|
return fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4); |
|
|
|
|
|
default: |
|
|
|
|
|
if (IsGenericAttribute(attribute)) { |
|
|
|
|
|
return GetOutputAttribute(attribute) + GetSwizzle(abuf->GetElement()); |
|
|
|
|
|
} |
|
|
|
|
|
UNIMPLEMENTED_MSG("Unhandled output attribute: {}", |
|
|
|
|
|
static_cast<u32>(attribute)); |
|
|
|
|
|
return "0"; |
|
|
|
|
|
|
|
|
const auto result = GetOutputAttribute(abuf); |
|
|
|
|
|
if (!result) { |
|
|
|
|
|
return {}; |
|
|
} |
|
|
} |
|
|
}(); |
|
|
|
|
|
|
|
|
target = result->first; |
|
|
|
|
|
is_integer = result->second; |
|
|
} else if (const auto lmem = std::get_if<LmemNode>(&*dest)) { |
|
|
} else if (const auto lmem = std::get_if<LmemNode>(&*dest)) { |
|
|
target = fmt::format("{}[ftou({}) / 4]", GetLocalMemory(), Visit(lmem->GetAddress())); |
|
|
target = fmt::format("{}[ftou({}) / 4]", GetLocalMemory(), Visit(lmem->GetAddress())); |
|
|
} else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { |
|
|
} else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { |
|
|
@ -1040,7 +1083,11 @@ private: |
|
|
UNREACHABLE_MSG("Assign called without a proper target"); |
|
|
UNREACHABLE_MSG("Assign called without a proper target"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (is_integer) { |
|
|
|
|
|
code.AddLine("{} = ftoi({});", target, Visit(src)); |
|
|
|
|
|
} else { |
|
|
code.AddLine("{} = {};", target, Visit(src)); |
|
|
code.AddLine("{} = {};", target, Visit(src)); |
|
|
|
|
|
} |
|
|
return {}; |
|
|
return {}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|