Compare commits
1 Commits
i-hate-cli
...
gs-uniform
Author | SHA1 | Date | |
---|---|---|---|
|
d42d094bc6 |
@@ -256,6 +256,10 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
|
|||||||
|
|
||||||
case PICA_REG_INDEX(vs.bool_uniforms):
|
case PICA_REG_INDEX(vs.bool_uniforms):
|
||||||
vs_setup.WriteUniformBoolReg(regs.internal.vs.bool_uniforms.Value());
|
vs_setup.WriteUniformBoolReg(regs.internal.vs.bool_uniforms.Value());
|
||||||
|
if (!regs.internal.pipeline.gs_unit_exclusive_configuration &&
|
||||||
|
regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No) {
|
||||||
|
gs_setup.WriteUniformBoolReg(regs.internal.vs.bool_uniforms.Value());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICA_REG_INDEX(vs.int_uniforms[0]):
|
case PICA_REG_INDEX(vs.int_uniforms[0]):
|
||||||
@@ -264,6 +268,10 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
|
|||||||
case PICA_REG_INDEX(vs.int_uniforms[3]): {
|
case PICA_REG_INDEX(vs.int_uniforms[3]): {
|
||||||
const u32 index = (id - PICA_REG_INDEX(vs.int_uniforms[0]));
|
const u32 index = (id - PICA_REG_INDEX(vs.int_uniforms[0]));
|
||||||
vs_setup.WriteUniformIntReg(index, regs.internal.vs.GetIntUniform(index));
|
vs_setup.WriteUniformIntReg(index, regs.internal.vs.GetIntUniform(index));
|
||||||
|
if (!regs.internal.pipeline.gs_unit_exclusive_configuration &&
|
||||||
|
regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No) {
|
||||||
|
gs_setup.WriteUniformIntReg(index, regs.internal.vs.GetIntUniform(index));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +283,11 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
|
|||||||
case PICA_REG_INDEX(vs.uniform_setup.set_value[5]):
|
case PICA_REG_INDEX(vs.uniform_setup.set_value[5]):
|
||||||
case PICA_REG_INDEX(vs.uniform_setup.set_value[6]):
|
case PICA_REG_INDEX(vs.uniform_setup.set_value[6]):
|
||||||
case PICA_REG_INDEX(vs.uniform_setup.set_value[7]): {
|
case PICA_REG_INDEX(vs.uniform_setup.set_value[7]): {
|
||||||
vs_setup.WriteUniformFloatReg(regs.internal.vs, value);
|
const auto index = vs_setup.WriteUniformFloatReg(regs.internal.vs, value);
|
||||||
|
if (!regs.internal.pipeline.gs_unit_exclusive_configuration &&
|
||||||
|
regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No && index) {
|
||||||
|
gs_setup.uniforms.f[index.value()] = vs_setup.uniforms.f[index.value()];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,21 +27,23 @@ void ShaderSetup::WriteUniformIntReg(u32 index, const Common::Vec4<u8> values) {
|
|||||||
uniforms.i[index] = values;
|
uniforms.i[index] = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderSetup::WriteUniformFloatReg(ShaderRegs& config, u32 value) {
|
std::optional<u32> ShaderSetup::WriteUniformFloatReg(ShaderRegs& config, u32 value) {
|
||||||
auto& uniform_setup = config.uniform_setup;
|
auto& uniform_setup = config.uniform_setup;
|
||||||
const bool is_float32 = uniform_setup.IsFloat32();
|
const bool is_float32 = uniform_setup.IsFloat32();
|
||||||
if (!uniform_queue.Push(value, is_float32)) {
|
if (!uniform_queue.Push(value, is_float32)) {
|
||||||
return;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto uniform = uniform_queue.Get(is_float32);
|
const auto uniform = uniform_queue.Get(is_float32);
|
||||||
if (uniform_setup.index >= uniforms.f.size()) {
|
if (uniform_setup.index >= uniforms.f.size()) {
|
||||||
LOG_ERROR(HW_GPU, "Invalid float uniform index {}", uniform_setup.index.Value());
|
LOG_ERROR(HW_GPU, "Invalid float uniform index {}", uniform_setup.index.Value());
|
||||||
return;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
uniforms.f[uniform_setup.index] = uniform;
|
const u32 index = uniform_setup.index.Value();
|
||||||
uniform_setup.index.Assign(uniform_setup.index + 1);
|
uniforms.f[index] = uniform;
|
||||||
|
uniform_setup.index.Assign(index + 1);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 ShaderSetup::GetProgramCodeHash() {
|
u64 ShaderSetup::GetProgramCodeHash() {
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "common/vector_math.h"
|
#include "common/vector_math.h"
|
||||||
#include "video_core/pica/packed_attribute.h"
|
#include "video_core/pica/packed_attribute.h"
|
||||||
#include "video_core/pica_types.h"
|
#include "video_core/pica_types.h"
|
||||||
@@ -58,7 +59,7 @@ public:
|
|||||||
|
|
||||||
void WriteUniformIntReg(u32 index, const Common::Vec4<u8> values);
|
void WriteUniformIntReg(u32 index, const Common::Vec4<u8> values);
|
||||||
|
|
||||||
void WriteUniformFloatReg(ShaderRegs& config, u32 value);
|
std::optional<u32> WriteUniformFloatReg(ShaderRegs& config, u32 value);
|
||||||
|
|
||||||
u64 GetProgramCodeHash();
|
u64 GetProgramCodeHash();
|
||||||
|
|
||||||
|
@@ -39,19 +39,6 @@ layout (binding = 1, std140) uniform vs_data {
|
|||||||
bool enable_clip1;
|
bool enable_clip1;
|
||||||
vec4 clip_coef;
|
vec4 clip_coef;
|
||||||
};
|
};
|
||||||
|
|
||||||
const vec2 EPSILON_Z = vec2(0.00000001f, -1.00001f);
|
|
||||||
|
|
||||||
vec4 SanitizeVertex(vec4 vtx_pos) {
|
|
||||||
float ndc_z = vtx_pos.z / vtx_pos.w;
|
|
||||||
if (ndc_z > 0.f && ndc_z < EPSILON_Z[0]) {
|
|
||||||
vtx_pos.z = 0.f;
|
|
||||||
}
|
|
||||||
if (ndc_z < -1.f && ndc_z > EPSILON_Z[1]) {
|
|
||||||
vtx_pos.z = -vtx_pos.w;
|
|
||||||
}
|
|
||||||
return vtx_pos;
|
|
||||||
}
|
|
||||||
)";
|
)";
|
||||||
|
|
||||||
static std::string GetVertexInterfaceDeclaration(bool is_output, bool use_clip_planes,
|
static std::string GetVertexInterfaceDeclaration(bool is_output, bool use_clip_planes,
|
||||||
@@ -107,7 +94,13 @@ std::string GenerateTrivialVertexShader(bool use_clip_planes, bool separable_sha
|
|||||||
out += GetVertexInterfaceDeclaration(true, use_clip_planes, separable_shader);
|
out += GetVertexInterfaceDeclaration(true, use_clip_planes, separable_shader);
|
||||||
out += VSUniformBlockDef;
|
out += VSUniformBlockDef;
|
||||||
|
|
||||||
|
// Certain games render 2D elements very close to clip plane 0 resulting in very tiny
|
||||||
|
// negative/positive z values when computing with f32 precision,
|
||||||
|
// causing some vertices to get erroneously clipped. To workaround this problem,
|
||||||
|
// we can use a very small epsilon value for clip plane comparison.
|
||||||
out += R"(
|
out += R"(
|
||||||
|
const float EPSILON_Z = 0.00000001f;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
primary_color = vert_color;
|
primary_color = vert_color;
|
||||||
texcoord0 = vert_texcoord0;
|
texcoord0 = vert_texcoord0;
|
||||||
@@ -116,7 +109,10 @@ void main() {
|
|||||||
texcoord0_w = vert_texcoord0_w;
|
texcoord0_w = vert_texcoord0_w;
|
||||||
normquat = vert_normquat;
|
normquat = vert_normquat;
|
||||||
view = vert_view;
|
view = vert_view;
|
||||||
vec4 vtx_pos = SanitizeVertex(vert_position);
|
vec4 vtx_pos = vert_position;
|
||||||
|
if (abs(vtx_pos.z) < EPSILON_Z) {
|
||||||
|
vtx_pos.z = 0.f;
|
||||||
|
}
|
||||||
gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);
|
gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);
|
||||||
)";
|
)";
|
||||||
if (use_clip_planes) {
|
if (use_clip_planes) {
|
||||||
@@ -219,6 +215,7 @@ std::string GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& c
|
|||||||
return "1.0";
|
return "1.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
out += "const float EPSILON_Z = 0.00000001f;\n\n";
|
||||||
out += "vec4 GetVertexQuaternion() {\n";
|
out += "vec4 GetVertexQuaternion() {\n";
|
||||||
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
|
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
|
||||||
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
|
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
|
||||||
@@ -231,7 +228,9 @@ std::string GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& c
|
|||||||
semantic(VSOutputAttributes::POSITION_Y) + ", " +
|
semantic(VSOutputAttributes::POSITION_Y) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
||||||
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
|
out += " if (abs(vtx_pos.z) < EPSILON_Z) {\n";
|
||||||
|
out += " vtx_pos.z = 0.f;\n";
|
||||||
|
out += " }\n";
|
||||||
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
||||||
if (config.state.use_clip_planes) {
|
if (config.state.use_clip_planes) {
|
||||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||||
@@ -313,6 +312,7 @@ struct Vertex {
|
|||||||
return "1.0";
|
return "1.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
out += "const float EPSILON_Z = 0.00000001f;\n\n";
|
||||||
out += "vec4 GetVertexQuaternion(Vertex vtx) {\n";
|
out += "vec4 GetVertexQuaternion(Vertex vtx) {\n";
|
||||||
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
|
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
|
||||||
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
|
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
|
||||||
@@ -325,7 +325,9 @@ struct Vertex {
|
|||||||
semantic(VSOutputAttributes::POSITION_Y) + ", " +
|
semantic(VSOutputAttributes::POSITION_Y) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
||||||
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
|
out += " if (abs(vtx_pos.z) < EPSILON_Z) {\n";
|
||||||
|
out += " vtx_pos.z = 0.f;\n";
|
||||||
|
out += " }\n";
|
||||||
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
||||||
if (state.use_clip_planes) {
|
if (state.use_clip_planes) {
|
||||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||||
|
Reference in New Issue
Block a user