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,318 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "gpu/gpu_renderer.h"
#include "gpu/gpu_shader_object.h"
#include "gpu/gpu_geometry.h"
#include "gpu/gpu_draw_context.h"
#include "core/renderer_environment_interface.h"
#include "core/geometry.h"
#include "core/terrain.h"
#include "core/camera.h"
#include "core/light.h"
#include "async/job.h"
#include "alloc/ialloc.h"
#include "platform.h"
using namespace GS;
using namespace GS::GPU;
//------------------------------------------------------------------------------
void Renderer::LightCullDisplayList(const Core::Light &light, const Stack <RenderPrimitive *> &in, Stack <RenderPrimitive *> &out)
{
for (uint n = 0; n < in.GetCount(); ++n)
{
RenderPrimitive *dl = in[n];
switch (light.model)
{
case Core::Light::Model_Point:
if (light.range > 0)
{
MinMax &mm = dl->dlst->minmax;
Vector4 dl_lpos = light.GetMatrix().GetRow(3) * dl->item->GetInverseMatrix();
if ( ((dl_lpos.x - light.range) < mm.mx.x) &&
((dl_lpos.x + light.range) > mm.mn.x) &&
((dl_lpos.y - light.range) < mm.mx.y) &&
((dl_lpos.y + light.range) > mm.mn.y) &&
((dl_lpos.z - light.range) < mm.mx.z) &&
((dl_lpos.z + light.range) > mm.mn.z) )
out.Push(dl);
}
else
out.Push(dl);
break;
case Core::Light::Model_Spot:
if (light.frustum.ClassifyMinMax(dl->dlst->minmax, &dl->item->GetMatrix()) != Frustum::Outside)
out.Push(dl);
break;
case Core::Light::Model_Linear:
default:
out.Push(dl);
break;
}
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Renderer::SetupForwardContext(const DrawContext::Context &ctx)
{
switch (ctx.draw)
{
case DrawContext::Base:
switch (ctx.render)
{
case DrawContext::Opaque:
EnableDepthTest(true);
break;
case DrawContext::Alpha:
EnableDepthWrite(false);
EnableBlending(true);
SetBlendFunc(BlendSrcAlpha, BlendOneMinusSrcAlpha);
break;
}
break;
case DrawContext::Light:
switch (ctx.render)
{
case DrawContext::Opaque:
EnableBlending(true);
SetBlendFunc(BlendSrcAlpha, BlendOne);
break;
case DrawContext::Alpha:
EnableDepthWrite(false);
EnableBlending(true);
SetBlendFunc(BlendSrcAlpha, BlendOne);
break;
}
break;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
class GPU::PrepareLightJob : public ASync::Job
{
const Renderer &renderer;
const Core::Light &light;
const Stack <RenderPrimitive *> &in;
Stack <RenderPrimitive *> &out;
DrawContext::Render rc;
public:
NPLACEMENT_NEW(RendererJob)
bool use_shadow;
bool CullPrimitive(const Render::Material *m, const MinMax &mm, const Core::Item *item) const
{
if (m->renderword & Core::Material::Render_Unlit)
return false; // exclude from lighting
switch (light.model)
{
case Core::Light::Model_Point:
if (light.range > 0)
{
Vector4 dl_lpos = light.GetMatrix().GetRow(3) * item->GetInverseMatrix();
if ( ((dl_lpos.x - light.range) < mm.mx.x) &&
((dl_lpos.y - light.range) < mm.mx.y) &&
((dl_lpos.z - light.range) < mm.mx.z) &&
((dl_lpos.x + light.range) > mm.mn.x) &&
((dl_lpos.y + light.range) > mm.mn.y) &&
((dl_lpos.z + light.range) > mm.mn.z) )
return true;
}
else
return true;
break;
case Core::Light::Model_Spot:
if (light.frustum.ClassifyMinMax(mm, &item->GetMatrix()) != Frustum::Outside)
return true;
break;
default:
case Core::Light::Model_Linear:
return true;
}
return false;
}
void Execute(uint)
{
for (uint n = 0; n < in.GetCount(); ++n)
{
RenderPrimitive *dl = in[n];
bool r = false;
switch (dl->type)
{
case RenderPrimitive::TypeDisplayList:
r = CullPrimitive(dl->dlst->material, dl->dlst->minmax, dl->item);
break;
case RenderPrimitive::TypeTerrainPatch:
r = CullPrimitive(dl->patch->terrain->render_data->material, dl->patch->minmax, dl->item);
break;
default:
case RenderPrimitive::TypeEmitter:
break;
}
if (r)
out.Push(dl);
}
// Prepare shadow map if required.
if (out.GetCount() == 0)
use_shadow = false;
else
{
use_shadow = renderer.gpu_config.enable_shadow && (light.shadow == Core::Light::Shadow_Map);
if ((rc == DrawContext::Alpha) && (light.shadow_cast_all == false))
use_shadow = false;
bool use_shadow_matrix = false;
if ((light.model == Core::Light::Model_Spot) && !light.projection_texture.IsEmpty())
use_shadow_matrix = true;
if (use_shadow || use_shadow_matrix)
renderer.PrepareShadowMap(light, use_shadow);
}
}
PrepareLightJob(const Renderer &_renderer, const Core::Light &_light, const Stack <RenderPrimitive *> &_in, Stack <RenderPrimitive *> &_out, DrawContext::Render _rc) : Job("Light Draw Setup"), renderer(_renderer), light(_light), in(_in), out(_out), rc(_rc) {}
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static MaterialShader::Variant DispatchLightShaderVariant(Core::Light::Model type, bool shadow, bool projection_map)
{
static MaterialShader::Variant table[2][2][Core::Light::Model_Last] =
{
{
{ MaterialShader::Last, MaterialShader::FS_PointLight, MaterialShader::FS_LinearLight, MaterialShader::FS_SpotLight },
{ MaterialShader::Last, MaterialShader::FS_PointLightShadowMapping, MaterialShader::FS_LinearLightShadowMapping, MaterialShader::FS_SpotLightShadowMapping }
},
{
{ MaterialShader::Last, MaterialShader::FS_PointLight, MaterialShader::FS_LinearLight, MaterialShader::FS_SpotLightProjection },
{ MaterialShader::Last, MaterialShader::FS_PointLightShadowMapping, MaterialShader::FS_LinearLightShadowMapping, MaterialShader::FS_SpotLightProjectionShadowMapping }
}
};
return table[projection_map ? 1 : 0][shadow ? 1 : 0][type];
}
void Renderer::DrawForwardBaseConstant(DrawContext::Render rc, const Stack <RenderPrimitive *> &dl_list)
{
ScopedPerfEvent event(this, __FUNCTION__, Color::Blue);
DrawContext dc(rc, DrawContext::Base, MaterialShader::FS_Constant);
SetupForwardContext(dc.ctx);
DrawList(dl_list, dc);
}
void Renderer::DrawForwardLightContribution(DrawContext::Render rc, const List <Core::Light *> &light_list, const AutoStack <PrepareLightJob *> &setup_jobs, const Array <Stack <RenderPrimitive *> > &dl_list)
{
ScopedPerfEvent event(this, "Render light contribution", Color::Blue);
DrawContext dc(rc, DrawContext::Light, MaterialShader::FS_Constant);
SetupForwardContext(dc.ctx);
EnableDepthWrite(false);
SetDepthFunc(DepthLessEqual);
uint job_count = 0;
ListForeachPtr(Core::Light *, l, light_list)
{
if (l->model == Core::Light::Model_None)
continue;
// Wait for the light setup job to complete.
Platform::Get().job_manager->JoinJob(setup_jobs[job_count]);
if (dl_list[job_count].GetCount())
{
bool use_shadow = setup_jobs[job_count]->use_shadow;
if (use_shadow)
{
PerfBeginEvent("Render shadow map", Color::Yellow);
EnableDepthWrite(true);
RenderShadowMap(*l);
EnableDepthWrite(false);
SetCurrentFBO(gpu_config.use_rtt ? render_fbo : NULL);
SetupForwardContext(dc.ctx);
PerfEndEvent();
}
// Add contribution.
dc.ctx.variant = DispatchLightShaderVariant(l->model, use_shadow, asbool(l->projection_texture));
dc.light = l;
DrawList(dl_list[job_count], dc);
}
++stats.light_processed;
++job_count;
}
}
void Renderer::RenderListForward(Stack <RenderPrimitive *> &dl_list, DrawContext::Render rc)
{
ScopedPerfEvent event(this, __FUNCTION__, Color::Red);
if (dl_list.GetCount() == 0)
return;
// Setup all lights.
List <Core::Light *> frustum_light_list;
environment_interface->GetLightsInFrustum(view_item->GetMatrix().GetRow(3), frustum, frustum_light_list);
Array <Stack <RenderPrimitive *> > light_dl_list(frustum_light_list.GetCount());
AutoStack <PrepareLightJob *> light_setup_job(frustum_light_list.GetCount());
uint job_count = 0;
ListForeachPtr(Core::Light *, l, frustum_light_list)
{
if (l->model == Core::Light::Model_None)
continue;
if (PrepareLightJob *job = new PrepareLightJob(*this, *l, dl_list, light_dl_list[job_count++], rc))
{
light_setup_job.Push(job);
Platform::Get().job_manager->EnqueueJob(job);
}
}
// Draw all passes.
DrawForwardBaseConstant(rc, dl_list);
DrawForwardLightContribution(rc, frustum_light_list, light_setup_job, light_dl_list);
//
CollectJobsPerf(light_setup_job, job_count, stats.bench_prepare_light);
// Restore default state.
SetCullFunc(CullFront);
SetDepthFunc(DepthLess);
EnableDepthWrite(true);
EnableBlending(false);
SetBlendFunc(BlendSrcAlpha, BlendOneMinusSrcAlpha);
}
//------------------------------------------------------------------------------