render parity unit G: 40250 tiling selection + verbatim STP terrain

- PythonApplication::Create mirrors 40250 :1196-1251 (SOFTWARE_TILING cfg,
  auto tiling IsFastTNL ? HTP : STP, MinLOD on !IsFastTNL)
- RecordingDevice caps: VertexShaderVersion 1.1 + CLIPTLVERTS (fast T&L -> HTP)
- MapOutdoorRenderSTP.cpp replaced by the full 40250 source (native gate only)
- native_render XYZRHW: fix inverted screen->NDC Y, negative rhw clip,
  no texture transform on TL vertices, specular-alpha vertex fog (capture v9)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-28 13:54:11 +09:00
co-authored by Claude Opus 5.5
parent 91ce13c3cf
commit 863f3771af
10 changed files with 864 additions and 66 deletions
+11 -6
View File
@@ -59,6 +59,7 @@ struct Vertex {
float weights[4];
float mask_uv[2];
float rhw = 1.0f;
float vertex_fog = 1.0f;
};
struct PushConstants {
@@ -166,7 +167,7 @@ FixedFunctionState make_fixed_function_state(const Render3DDraw& draw) {
state.fog_params = {draw.fog_start, draw.fog_end, draw.fog_density,
draw.fog_range_enable ? 1.0f : 0.0f};
const std::uint32_t fog_mode = draw.fog_enable
? (draw.fog_table_mode ? draw.fog_table_mode : draw.fog_vertex_mode) : 0;
? (draw.fog_table_mode ? draw.fog_table_mode : (draw.pretransformed ? 4u : draw.fog_vertex_mode)) : 0;
state.flags = {1u, !draw.texture0.empty() ? 1u : 0u, !draw.texture1.empty() ? 1u : 0u, fog_mode};
state.lighting_flags = {draw.lighting, draw.color_vertex, draw.diffuse.empty() ? 0u : 1u,
draw.normalize_normals};
@@ -221,6 +222,7 @@ std::uint64_t geometry_hash(const Render3DDraw& draw) {
hash = hash_bytes(hash, &flags, sizeof(flags));
hash = hash_bytes(hash, draw.positions.data(), draw.positions.size() * sizeof(float));
hash = hash_bytes(hash, draw.rhw.data(), draw.rhw.size() * sizeof(float));
hash = hash_bytes(hash, draw.vertex_fog.data(), draw.vertex_fog.size() * sizeof(float));
hash = hash_bytes(hash, draw.normals.data(), draw.normals.size() * sizeof(float));
hash = hash_bytes(hash, draw.uv0.data(), draw.uv0.size() * sizeof(float));
hash = hash_bytes(hash, draw.uv1.data(), draw.uv1.size() * sizeof(float));
@@ -1422,10 +1424,11 @@ public:
if (draw.pretransformed) {
const float screen_width = float(logical_width());
const float screen_height = float(logical_height());
// Screen pixels (y down) to D3D NDC (y up); the shader's Y flip then maps to Vulkan.
constants.mvp = {2.0f / screen_width, 0, 0, 0,
0, 2.0f / screen_height, 0, 0,
0, -2.0f / screen_height, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1};
-1, 1, 0, 1};
}
PreparedDraw prepared_draw{};
prepared_draw.geometry = &geometry;
@@ -2354,7 +2357,7 @@ private:
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; stages[1].module = fragment_module_; stages[1].pName = "main";
VkVertexInputBindingDescription binding{0, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX};
VkVertexInputAttributeDescription attributes[8] = {
VkVertexInputAttributeDescription attributes[9] = {
{0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, position)},
{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal)},
{2, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv)},
@@ -2362,10 +2365,11 @@ private:
{4, 0, VK_FORMAT_R8G8B8A8_UINT, offsetof(Vertex, joints)},
{5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(Vertex, weights)},
{6, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, mask_uv)},
{7, 0, VK_FORMAT_R32_SFLOAT, offsetof(Vertex, rhw)}};
{7, 0, VK_FORMAT_R32_SFLOAT, offsetof(Vertex, rhw)},
{8, 0, VK_FORMAT_R32_SFLOAT, offsetof(Vertex, vertex_fog)}};
VkPipelineVertexInputStateCreateInfo input{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
input.vertexBindingDescriptionCount = 1; input.pVertexBindingDescriptions = &binding;
input.vertexAttributeDescriptionCount = 8; input.pVertexAttributeDescriptions = attributes;
input.vertexAttributeDescriptionCount = 9; input.pVertexAttributeDescriptions = attributes;
VkPipelineInputAssemblyStateCreateInfo assembly{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
assembly.topology = lines ? VK_PRIMITIVE_TOPOLOGY_LINE_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
@@ -2867,6 +2871,7 @@ private:
vertices[i].position[1] = draw.positions[3*i+1];
vertices[i].position[2] = draw.positions[3*i+2];
vertices[i].rhw = i < draw.rhw.size() ? draw.rhw[i] : 1.0f;
vertices[i].vertex_fog = i < draw.vertex_fog.size() ? draw.vertex_fog[i] : 1.0f;
if (3*i + 2 < draw.normals.size()) {
vertices[i].normal[0] = draw.normals[3*i];
vertices[i].normal[1] = draw.normals[3*i+1];