commit x64 compilation from lulu cause the other branch dont seems to compile properly at home

This commit is contained in:
2026-07-17 16:08:20 +02:00
parent c0f3eeb00d
commit 0efa4ee6f7
625 changed files with 117283 additions and 4426 deletions

View File

@ -0,0 +1,264 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "gpu/gpu_renderer.h"
#include "core/terrain.h"
#include "log/log.h"
using namespace GS::GPU;
// Terrain patch size.
#define _PatchSize 64
// Terrain page count.
#if __PLATFORM_ANDROID_NDK__ || __PLATFORM_IOS__
#define _PageCount 4
#else
#define _PageCount 32
#endif
//-----------------------------------------------------------------------------
bool Renderer::CreateTerrainPatch()
{
// Allocate terrain cache.
if (!terrain_patch_cache.Allocate(_PageCount))
__ERR__(__LOG_E__ << "Failed to allocate terrain cache.\n", false)
// Compute page stride.
size_t stride = 0;
size_t vertex_offset = stride;
stride += 3 * 4; // Vertex buffer (3x float).
size_t normal_offset = stride;
stride += (3 + 1) * 1; // Normal buffer (3x byte + 1 padding).
size_t uv_offset = stride;
stride += 2 * 4; // Large UV (2x float).
// Setup default page layout.
size_t byte_size = stride * (_PatchSize + 1) * (_PatchSize + 1);
__LOG_H__ << "Setup terrain cache: " << terrain_patch_cache.GetCount() << " pages (" << uint(byte_size * terrain_patch_cache.GetCount()) << " bytes).\n";
terrain_patch_vtx.Allocate((uint)byte_size);
if (char *p = terrain_patch_vtx)
{
Vector4 wp(0, 0, 0);
for (int v = 0; v < (_PatchSize + 1); ++v)
{
for (int u = 0; u < (_PatchSize + 1); ++u)
{
float *pv = (float *)p;
pv[0] = wp.x; pv[1] = 0; pv[2] = wp.z;
p += stride;
wp.x += 1.f;
}
wp.x = 0.f;
wp.z += 1.f;
}
}
// Allocate pages.
for (uint n = 0; n < terrain_patch_cache.GetCount(); ++n)
{
DisplayList *patch = terrain_patch_cache[n].patch = NewDisplayList();
// Create the patch index buffer.
patch->idx = NewVBO();
if (patch->idx->Create(6 * _PatchSize * _PatchSize * sizeof(ushort), VBO::Index, VBO::Static))
{
SetIndexSource(patch->idx);
if (ushort *p_idx = (ushort *)patch->idx->Map())
{
for (int v = 0; v < _PatchSize; ++v)
for (int u = 0; u < _PatchSize; ++u)
{
*p_idx++ = (ushort)(u + v * (_PatchSize + 1));
*p_idx++ = (ushort)(u + (v + 1) * (_PatchSize + 1) + 1);
*p_idx++ = (ushort)(u + v * (_PatchSize + 1) + 1);
*p_idx++ = (ushort)(u + v * (_PatchSize + 1));
*p_idx++ = (ushort)(u + (v + 1) * (_PatchSize + 1));
*p_idx++ = (ushort)(u + (v + 1) * (_PatchSize + 1) + 1);
}
patch->idx->Unmap();
patch->index_count = 6 * _PatchSize * _PatchSize;
}
SetIndexSource(NULL);
}
// Create the patch vertex buffer.
patch->vertex_offset = vertex_offset;
patch->normal_offset = normal_offset;
patch->uv_offset[0] = uv_offset;
patch->stride = stride;
patch->vtx = NewVBO();
if (patch->vtx->Create(byte_size, VBO::Vertex, VBO::Dynamic))
{
SetVertexSource(patch->vtx, patch->stride);
patch->vtx->Update(terrain_patch_vtx);
SetVertexSource(NULL, 0);
}
}
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Renderer::InvalidateTerrainCache(int, int, int, int)
{
// Very naive invalidation that ignores the input region.
for (uint n = 0; n < terrain_patch_cache.GetCount(); ++n)
terrain_patch_cache[n].terrain = NULL;
}
void Renderer::DecayTerrainCache()
{
for (uint n = 0; n < terrain_patch_cache.GetCount(); ++n)
if (terrain_patch_cache[n].score > 0)
--terrain_patch_cache[n].score;
}
void Renderer::UploadTerrainPatchToPage(CachedTerrainPatch &page, const GS::Core::Item &item, const GS::Core::Patch &patch, const DrawContext &dc)
{
if (!patch.terrain || !page.patch)
return;
Core::Terrain &terrain = *patch.terrain;
DisplayList &terrain_patch = *page.patch;
float pixel_size = terrain.GetUnit();
Vector4 patch_scale(pixel_size * patch.decimation, 1, pixel_size * patch.decimation);
#if 1
// Update patch CPU-side data.
Core::Terrain::Attrib *psa = terrain.GetAttributesMap() + patch.v * terrain.GetHeightmapPitch() + patch.u;
float *psh = terrain.GetHeightmap() + patch.v * terrain.GetHeightmapPitch() + patch.u;
char *p = terrain_patch_vtx;
Vector4 uv(0, 0, patch.v * pixel_size);
for (int v = 0; v < (_PatchSize + 1); ++v)
{
uv.x = patch.u * pixel_size;
Core::Terrain::Attrib *pa = psa;
float *ph = psh;
for (int u = 0; u < (_PatchSize + 1); ++u)
{
// Vertex.
float *pv = (float *)(p + terrain_patch.vertex_offset);
pv[1] = ph[0];
// Normal.
char *pn = (char *)(p + terrain_patch.normal_offset);
pn[0] = pa[0].nx;
pn[1] = pa[0].ny;
pn[2] = pa[0].nz;
// UV.
float *pu = (float *)(p + terrain_patch.uv_offset[0]);
pu[0] = uv.x / terrain.GetWidth();
uv.x += patch_scale.x;
pu[1] = uv.z / terrain.GetDepth();
p += terrain_patch.stride;
pa += patch.decimation;
ph += patch.decimation;
}
uv.z += patch_scale.z;
psa += terrain.GetHeightmapPitch() * patch.decimation;
psh += terrain.GetHeightmapPitch() * patch.decimation;
}
// Update VBO.
SetVertexSource(terrain_patch.vtx, terrain_patch.stride);
terrain_patch.vtx->Update(terrain_patch_vtx);
// [EJ 9 Mar] the display list cache MUST be reset here otherwise an invalid
// VBO reference will be used by the next draw calls for this patch.
dls_cache.dls = NULL;
#endif
// Synchronize cache.
page.terrain = patch.terrain;
page.u = patch.u; page.v = patch.v;
page.w = patch.w; page.h = patch.h;
page.decimation = patch.decimation;
}
void Renderer::RenderTerrainPatch(const GS::Core::Patch &patch, const GS::Core::Item &item, const DrawContext &dc)
{
// Cache query.
++gpu_stats.terrain_page_query_count;
DisplayList *dlist = NULL;
CachedTerrainPatch *page = NULL;
uint lowest_score = (uint)~0;
for (uint n = 0; n < terrain_patch_cache.GetCount(); ++n)
if (CachedTerrainPatch *c_page = &terrain_patch_cache[n])
{
if (
(c_page->terrain == patch.terrain) &&
(c_page->u == patch.u) && (c_page->v == patch.v) &&
(c_page->w == patch.w) && (c_page->h == patch.h) &&
(c_page->decimation == patch.decimation)
)
{
dlist = c_page->patch;
c_page->score++; // Increase score.
break;
}
// Track the lowest scoring page.
if (c_page->score <= lowest_score)
{
lowest_score = c_page->score;
page = c_page;
}
}
// Cache miss.
if (!dlist)
{
++gpu_stats.terrain_page_query_miss;
if (!page || !page->patch)
__ERRRAW__(__LOG_E__ << "No page to upload terrain patch.\n") // Unexpected...
// Create new page.
UploadTerrainPatchToPage(*page, item, patch, dc);
dlist = page->patch;
page->score = 1; // Reset score (+1 for being used).
}
// Draw patch scaled and translated on the GPU.
float pixel_size = patch.terrain->GetUnit();
Vector4 patch_scale(pixel_size * patch.decimation, 1, pixel_size * patch.decimation);
Matrix4 patch_matrix =
Matrix4::TranslationMatrix(Vector4(patch.u * pixel_size - patch.terrain->GetWidth() * 0.5f, 0, patch.v * pixel_size - patch.terrain->GetDepth() * 0.5f)) *
Matrix4::ScaleMatrix(patch_scale);
SetWorldMatrix(item.GetMatrix() * patch_matrix);
m_previous_world = item.GetPreviousMatrix() * patch_matrix;
dls_cache.item = NULL; // Force matrices upload to program.
// Draw.
if (patch.terrain->render_data)
{
dlist->material = patch.terrain->render_data->material;
DrawDisplayListCached(*dlist, item, dc);
}
}
//-----------------------------------------------------------------------------