Merge pull request #1783 from ReinUsesLisp/clip-distances
gl_shader_decompiler: Implement clip distances
This commit is contained in:
commit
8ce90a4f0b
3 changed files with 58 additions and 21 deletions
|
@ -82,6 +82,8 @@ union Attribute {
|
||||||
Position = 7,
|
Position = 7,
|
||||||
Attribute_0 = 8,
|
Attribute_0 = 8,
|
||||||
Attribute_31 = 39,
|
Attribute_31 = 39,
|
||||||
|
ClipDistances0123 = 44,
|
||||||
|
ClipDistances4567 = 45,
|
||||||
PointCoord = 46,
|
PointCoord = 46,
|
||||||
// This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex
|
// This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex
|
||||||
// shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval
|
// shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval
|
||||||
|
|
|
@ -62,7 +62,16 @@ struct Header {
|
||||||
INSERT_PADDING_BYTES(1); // ImapSystemValuesB
|
INSERT_PADDING_BYTES(1); // ImapSystemValuesB
|
||||||
INSERT_PADDING_BYTES(16); // ImapGenericVector[32]
|
INSERT_PADDING_BYTES(16); // ImapGenericVector[32]
|
||||||
INSERT_PADDING_BYTES(2); // ImapColor
|
INSERT_PADDING_BYTES(2); // ImapColor
|
||||||
INSERT_PADDING_BYTES(2); // ImapSystemValuesC
|
union {
|
||||||
|
BitField<0, 8, u16> clip_distances;
|
||||||
|
BitField<8, 1, u16> point_sprite_s;
|
||||||
|
BitField<9, 1, u16> point_sprite_t;
|
||||||
|
BitField<10, 1, u16> fog_coordinate;
|
||||||
|
BitField<12, 1, u16> tessellation_eval_point_u;
|
||||||
|
BitField<13, 1, u16> tessellation_eval_point_v;
|
||||||
|
BitField<14, 1, u16> instance_id;
|
||||||
|
BitField<15, 1, u16> vertex_id;
|
||||||
|
};
|
||||||
INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10]
|
INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10]
|
||||||
INSERT_PADDING_BYTES(1); // ImapReserved
|
INSERT_PADDING_BYTES(1); // ImapReserved
|
||||||
INSERT_PADDING_BYTES(3); // OmapSystemValuesA
|
INSERT_PADDING_BYTES(3); // OmapSystemValuesA
|
||||||
|
|
|
@ -500,27 +500,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
|
||||||
// Can happen with unknown/unimplemented output attributes, in which case we ignore the
|
// instruction for now.
|
||||||
// instruction for now.
|
if (stage == Maxwell3D::Regs::ShaderStage::Geometry) {
|
||||||
if (stage == Maxwell3D::Regs::ShaderStage::Geometry) {
|
// TODO(Rodrigo): nouveau sets some attributes after setting emitting a 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
|
||||||
// shader. These instructions use a dirty register as buffer index, to avoid some
|
// drivers from complaining about out of boundary writes, guard them.
|
||||||
// drivers from complaining about out of boundary writes, guard them.
|
const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " +
|
||||||
const std::string buf_index{"((" + GetRegisterAsInteger(buf_reg) + ") % " +
|
std::to_string(MAX_GEOMETRY_BUFFERS) + ')'};
|
||||||
std::to_string(MAX_GEOMETRY_BUFFERS) + ')'};
|
shader.AddLine("amem[" + buf_index + "][" +
|
||||||
shader.AddLine("amem[" + buf_index + "][" +
|
std::to_string(static_cast<u32>(attribute)) + ']' + GetSwizzle(elem) +
|
||||||
std::to_string(static_cast<u32>(attribute)) + ']' +
|
" = " + src + ';');
|
||||||
GetSwizzle(elem) + " = " + src + ';');
|
return;
|
||||||
} else {
|
}
|
||||||
if (attribute == Attribute::Index::PointSize) {
|
|
||||||
fixed_pipeline_output_attributes_used.insert(attribute);
|
switch (attribute) {
|
||||||
shader.AddLine(dest + " = " + src + ';');
|
case Attribute::Index::ClipDistances0123:
|
||||||
} else {
|
case Attribute::Index::ClipDistances4567: {
|
||||||
shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';');
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,12 +755,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("};");
|
||||||
|
@ -916,6 +938,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)};
|
||||||
|
|
Loading…
Reference in a new issue