|
|
@ -485,27 +485,42 @@ public: |
|
|
const Register& buf_reg) { |
|
|
const Register& buf_reg) { |
|
|
const std::string dest = GetOutputAttribute(attribute); |
|
|
const std::string dest = GetOutputAttribute(attribute); |
|
|
const std::string src = GetRegisterAsFloat(val_reg); |
|
|
const std::string src = GetRegisterAsFloat(val_reg); |
|
|
|
|
|
if (dest.empty()) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
if (!dest.empty()) { |
|
|
|
|
|
// Can happen with unknown/unimplemented output attributes, in which case we ignore the
|
|
|
|
|
|
// instruction for now.
|
|
|
|
|
|
if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { |
|
|
|
|
|
// TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry
|
|
|
|
|
|
// shader. These instructions use a dirty register as buffer index, to avoid some
|
|
|
|
|
|
// drivers from complaining about out of boundary writes, guard them.
|
|
|
|
|
|
const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + |
|
|
|
|
|
std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; |
|
|
|
|
|
shader.AddLine("amem[" + buf_index + "][" + |
|
|
|
|
|
std::to_string(static_cast<u32>(attribute)) + ']' + |
|
|
|
|
|
GetSwizzle(elem) + " = " + src + ';'); |
|
|
|
|
|
} else { |
|
|
|
|
|
if (attribute == Attribute::Index::PointSize) { |
|
|
|
|
|
fixed_pipeline_output_attributes_used.insert(attribute); |
|
|
|
|
|
shader.AddLine(dest + " = " + src + ';'); |
|
|
|
|
|
} else { |
|
|
|
|
|
shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Can happen with unknown/unimplemented output attributes, in which case we ignore the
|
|
|
|
|
|
// instruction for now.
|
|
|
|
|
|
if (stage == Maxwell3D::Regs::ShaderStage::Geometry) { |
|
|
|
|
|
// TODO(Rodrigo): nouveau sets some attributes after setting emitting a geometry
|
|
|
|
|
|
// shader. These instructions use a dirty register as buffer index, to avoid some
|
|
|
|
|
|
// drivers from complaining about out of boundary writes, guard them.
|
|
|
|
|
|
const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " + |
|
|
|
|
|
std::to_string(MAX_GEOMETRY_BUFFERS) + ')'}; |
|
|
|
|
|
shader.AddLine("amem[" + buf_index + "][" + |
|
|
|
|
|
std::to_string(static_cast<u32>(attribute)) + ']' + GetSwizzle(elem) + |
|
|
|
|
|
" = " + src + ';'); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (attribute) { |
|
|
|
|
|
case Attribute::Index::ClipDistances0123: |
|
|
|
|
|
case Attribute::Index::ClipDistances4567: { |
|
|
|
|
|
const u64 index = attribute == Attribute::Index::ClipDistances4567 ? 4 : 0 + elem; |
|
|
|
|
|
UNIMPLEMENTED_IF_MSG( |
|
|
|
|
|
((header.vtg.clip_distances >> index) & 1) == 0, |
|
|
|
|
|
"Shader is setting gl_ClipDistance{} without enabling it in the header", index); |
|
|
|
|
|
|
|
|
|
|
|
fixed_pipeline_output_attributes_used.insert(attribute); |
|
|
|
|
|
shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';'); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
case Attribute::Index::PointSize: |
|
|
|
|
|
fixed_pipeline_output_attributes_used.insert(attribute); |
|
|
|
|
|
shader.AddLine(dest + " = " + src + ';'); |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); |
|
|
|
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -725,12 +740,19 @@ private: |
|
|
void GenerateVertex() { |
|
|
void GenerateVertex() { |
|
|
if (stage != Maxwell3D::Regs::ShaderStage::Vertex) |
|
|
if (stage != Maxwell3D::Regs::ShaderStage::Vertex) |
|
|
return; |
|
|
return; |
|
|
|
|
|
bool clip_distances_declared = false; |
|
|
|
|
|
|
|
|
declarations.AddLine("out gl_PerVertex {"); |
|
|
declarations.AddLine("out gl_PerVertex {"); |
|
|
++declarations.scope; |
|
|
++declarations.scope; |
|
|
declarations.AddLine("vec4 gl_Position;"); |
|
|
declarations.AddLine("vec4 gl_Position;"); |
|
|
for (auto& o : fixed_pipeline_output_attributes_used) { |
|
|
for (auto& o : fixed_pipeline_output_attributes_used) { |
|
|
if (o == Attribute::Index::PointSize) |
|
|
if (o == Attribute::Index::PointSize) |
|
|
declarations.AddLine("float gl_PointSize;"); |
|
|
declarations.AddLine("float gl_PointSize;"); |
|
|
|
|
|
if (!clip_distances_declared && (o == Attribute::Index::ClipDistances0123 || |
|
|
|
|
|
o == Attribute::Index::ClipDistances4567)) { |
|
|
|
|
|
declarations.AddLine("float gl_ClipDistance[];"); |
|
|
|
|
|
clip_distances_declared = true; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
--declarations.scope; |
|
|
--declarations.scope; |
|
|
declarations.AddLine("};"); |
|
|
declarations.AddLine("};"); |
|
|
@ -901,6 +923,10 @@ private: |
|
|
return "gl_PointSize"; |
|
|
return "gl_PointSize"; |
|
|
case Attribute::Index::Position: |
|
|
case Attribute::Index::Position: |
|
|
return "position"; |
|
|
return "position"; |
|
|
|
|
|
case Attribute::Index::ClipDistances0123: |
|
|
|
|
|
case Attribute::Index::ClipDistances4567: { |
|
|
|
|
|
return "gl_ClipDistance"; |
|
|
|
|
|
} |
|
|
default: |
|
|
default: |
|
|
const u32 index{static_cast<u32>(attribute) - |
|
|
const u32 index{static_cast<u32>(attribute) - |
|
|
static_cast<u32>(Attribute::Index::Attribute_0)}; |
|
|
static_cast<u32>(Attribute::Index::Attribute_0)}; |
|
|
|