VertexManagerBase resource changes

This commit is contained in:
iwubcode 2025-08-03 16:55:23 -05:00
commit 43523b6e9f
2 changed files with 91 additions and 135 deletions

View file

@ -38,6 +38,7 @@
#include "VideoCommon/PerfQueryBase.h" #include "VideoCommon/PerfQueryBase.h"
#include "VideoCommon/PixelShaderGen.h" #include "VideoCommon/PixelShaderGen.h"
#include "VideoCommon/PixelShaderManager.h" #include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/Resources/MeshResource.h"
#include "VideoCommon/Statistics.h" #include "VideoCommon/Statistics.h"
#include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/TextureInfo.h" #include "VideoCommon/TextureInfo.h"
@ -113,29 +114,6 @@ static bool IsNormalProjection(const Projection::Raw& projection, const Viewport
config.widescreen_heuristic_aspect_ratio_slop; config.widescreen_heuristic_aspect_ratio_slop;
} }
static void GetTextureAndSamplerFromResource(
const GraphicsModSystem::MaterialResource::TextureLikeResource& texture_like_resource,
VideoCommon::CameraManager& camera_manager, const AbstractTexture** texture,
const SamplerState** sampler, u32* sampler_index, std::string_view* texture_hash)
{
std::visit(
overloaded{[&](const GraphicsModSystem::TextureResource& texture_resource) {
*sampler = texture_resource.sampler;
*sampler_index = texture_resource.sampler_index;
*texture = texture_resource.texture;
*texture_hash = texture_resource.texture_hash_for_sampler;
},
[&](const GraphicsModSystem::InputRenderTargetResource& render_target_resource) {
*sampler = render_target_resource.sampler;
*sampler_index = render_target_resource.sampler_index;
*texture = camera_manager.GetRenderTarget(
render_target_resource.camera_originating_draw_call,
render_target_resource.render_target_name);
*texture_hash = render_target_resource.texture_hash_for_sampler;
}},
texture_like_resource);
}
VertexManagerBase::VertexManagerBase() VertexManagerBase::VertexManagerBase()
: m_cpu_vertex_buffer(MAXVBUFFERSIZE), m_cpu_index_buffer(MAXIBUFFERSIZE) : m_cpu_vertex_buffer(MAXVBUFFERSIZE), m_cpu_index_buffer(MAXIBUFFERSIZE)
{ {
@ -1208,7 +1186,7 @@ void VertexManagerBase::DrawEmulatedMesh(VideoCommon::CameraManager& camera_mana
memcpy(vertex_shader_manager.constants.custom_transform.data(), custom_transform.data.data(), memcpy(vertex_shader_manager.constants.custom_transform.data(), custom_transform.data.data(),
4 * sizeof(float4)); 4 * sizeof(float4));
const auto camera_view = camera_manager.GetCurrentCameraView({}); const auto camera_view = camera_manager.GetCurrentCameraView();
if (camera_view.transform) if (camera_view.transform)
{ {
@ -1257,7 +1235,7 @@ void VertexManagerBase::DrawEmulatedMesh(VideoCommon::CameraManager& camera_mana
// Do we have any other views? If so we need to redraw with those // Do we have any other views? If so we need to redraw with those
// frame buffers... // frame buffers...
const auto camera_views = camera_manager.GetAdditionalViews({}); const auto camera_views = camera_manager.GetAdditionalViews();
for (const auto additional_camera_view : camera_views) for (const auto additional_camera_view : camera_views)
{ {
if (xfmem.projection.type == ProjectionType::Orthographic && if (xfmem.projection.type == ProjectionType::Orthographic &&
@ -1297,44 +1275,37 @@ void VertexManagerBase::DrawEmulatedMesh(VideoCommon::CameraManager& camera_mana
} }
} }
void VertexManagerBase::DrawEmulatedMesh(GraphicsModSystem::MaterialResource* material_resource, void VertexManagerBase::DrawEmulatedMesh(const VideoCommon::MaterialResource::Data& material_data,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
const Common::Matrix44& custom_transform, const Common::Matrix44& custom_transform,
VideoCommon::CameraManager& camera_manager) VideoCommon::CameraManager& camera_manager)
{ {
if (material_resource) auto& system = Core::System::GetInstance();
auto& vertex_shader_manager = system.GetVertexShaderManager();
memcpy(vertex_shader_manager.constants.custom_transform.data(), custom_transform.data.data(),
4 * sizeof(float4));
u32 base_vertex, base_index;
CommitBuffer(m_index_generator.GetNumVerts(),
VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
m_index_generator.GetIndexLen(), &base_vertex, &base_index);
if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
(m_current_primitive_type == PrimitiveType::Points ||
m_current_primitive_type == PrimitiveType::Lines))
{ {
auto& system = Core::System::GetInstance(); // VS point/line expansion puts the vertex id at gl_VertexID << 2
auto& vertex_shader_manager = system.GetVertexShaderManager(); // That means the base vertex has to be adjusted to match
memcpy(vertex_shader_manager.constants.custom_transform.data(), custom_transform.data.data(), // (The shader adds this after shifting right on D3D, so no need to do this)
4 * sizeof(float4)); base_vertex <<= 2;
u32 base_vertex, base_index;
CommitBuffer(m_index_generator.GetNumVerts(),
VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
m_index_generator.GetIndexLen(), &base_vertex, &base_index);
if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
(m_current_primitive_type == PrimitiveType::Points ||
m_current_primitive_type == PrimitiveType::Lines))
{
// VS point/line expansion puts the vertex id at gl_VertexID << 2
// That means the base vertex has to be adjusted to match
// (The shader adds this after shifting right on D3D, so no need to do this)
base_vertex <<= 2;
}
DrawViewsWithMaterial(base_vertex, base_index, m_index_generator.GetIndexLen(),
m_current_primitive_type, draw_data, material_resource, camera_manager);
}
else
{
DrawEmulatedMesh(camera_manager, custom_transform);
} }
DrawViewsWithMaterial(base_vertex, base_index, m_index_generator.GetIndexLen(),
m_current_primitive_type, draw_data, material_data, camera_manager);
} }
void VertexManagerBase::DrawCustomMesh(GraphicsModSystem::DrawCallID draw_call, void VertexManagerBase::DrawCustomMesh(GraphicsModSystem::DrawCallID draw_call,
GraphicsModSystem::MeshResource* mesh_resource, const VideoCommon::MeshResource::Data& mesh_data,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
const Common::Matrix44& custom_transform, const Common::Matrix44& custom_transform,
bool ignore_mesh_transform, bool ignore_mesh_transform,
@ -1343,81 +1314,65 @@ void VertexManagerBase::DrawCustomMesh(GraphicsModSystem::DrawCallID draw_call,
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& vertex_shader_manager = system.GetVertexShaderManager(); auto& vertex_shader_manager = system.GetVertexShaderManager();
const auto process_mesh_chunk = [&](const GraphicsModSystem::MeshChunkResource& mesh_chunk, const auto process_mesh_chunk = [&](const VideoCommon::MeshResource::MeshChunk& mesh_chunk) {
std::span<const u16> index_data) {
// TODO: draw with a generic material? // TODO: draw with a generic material?
if (!mesh_chunk.material) [[unlikely]] if (!mesh_chunk.GetMaterial()) [[unlikely]]
return; return;
if (!mesh_chunk.material->pipeline || !mesh_chunk.material->pipeline->m_config.vertex_shader || const auto material_data = mesh_chunk.GetMaterial()->GetData();
!mesh_chunk.material->pipeline->m_config.pixel_shader) [[unlikely]] if (!material_data) [[unlikely]]
{
return;
}
if (mesh_chunk.vertex_data.empty() || index_data.empty()) [[unlikely]]
return; return;
vertex_shader_manager.SetVertexFormat(mesh_chunk.components_available, const auto pipeline = material_data->GetPipeline();
mesh_chunk.vertex_format->GetVertexDeclaration()); if (!pipeline->m_config.vertex_shader || !pipeline->m_config.pixel_shader) [[unlikely]]
return;
const auto vertex_data = mesh_chunk.GetVertexData();
const auto index_data = mesh_chunk.GetIndexData();
if (vertex_data.empty() || index_data.empty()) [[unlikely]]
return;
vertex_shader_manager.SetVertexFormat(
mesh_chunk.GetComponentsAvailable(),
mesh_chunk.GetNativeVertexFormat()->GetVertexDeclaration());
Common::Matrix44 computed_transform; Common::Matrix44 computed_transform;
computed_transform = Common::Matrix44::Translate(mesh_resource->pivot_point) * custom_transform; computed_transform = Common::Matrix44::Translate(mesh_chunk.GetPivotPoint()) * custom_transform;
if (!ignore_mesh_transform) if (!ignore_mesh_transform)
{ {
computed_transform *= mesh_chunk.transform; computed_transform *= mesh_chunk.GetTransform();
} }
memcpy(vertex_shader_manager.constants.custom_transform.data(), computed_transform.data.data(), memcpy(vertex_shader_manager.constants.custom_transform.data(), computed_transform.data.data(),
4 * sizeof(float4)); 4 * sizeof(float4));
u32 base_vertex, base_index; u32 base_vertex, base_index;
UploadUtilityVertices(mesh_chunk.vertex_data.data(), mesh_chunk.vertex_stride, UploadUtilityVertices(vertex_data.data(), mesh_chunk.GetVertexStride(),
static_cast<u32>(mesh_chunk.vertex_data.size()), index_data.data(), static_cast<u32>(vertex_data.size()), index_data.data(),
static_cast<u32>(index_data.size()), &base_vertex, &base_index); static_cast<u32>(index_data.size()), &base_vertex, &base_index);
DrawViewsWithMaterial(base_vertex, base_index, static_cast<u32>(index_data.size()), DrawViewsWithMaterial(base_vertex, base_index, static_cast<u32>(index_data.size()),
mesh_chunk.primitive_type, draw_data, mesh_chunk.material, mesh_chunk.GetPrimitiveType(), draw_data, *material_data, camera_manager);
camera_manager);
}; };
if (mesh_resource->draw_call_to_gpu_skinning_mesh_chunk.empty()) for (const auto& mesh_chunk : mesh_data.GetMeshChunks(draw_call))
{ {
for (const auto& mesh_chunk : mesh_resource->mesh_chunks) process_mesh_chunk(mesh_chunk);
{
process_mesh_chunk(mesh_chunk, mesh_chunk.index_data);
}
}
else
{
if (const auto iter = mesh_resource->draw_call_to_gpu_skinning_mesh_chunk.find(draw_call);
iter != mesh_resource->draw_call_to_gpu_skinning_mesh_chunk.end())
{
auto& gpu_skinning_chunks = iter->second;
for (const auto& skinning_chunk : gpu_skinning_chunks)
{
process_mesh_chunk(skinning_chunk, skinning_chunk.index_data);
}
}
} }
} }
void VertexManagerBase::DrawViewsWithMaterial( void VertexManagerBase::DrawViewsWithMaterial(
u32 base_vertex, u32 base_index, u32 index_size, PrimitiveType primitive_type, u32 base_vertex, u32 base_index, u32 index_size, PrimitiveType primitive_type,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
GraphicsModSystem::MaterialResource* material_resource, const VideoCommon::MaterialResource::Data& material_data,
VideoCommon::CameraManager& camera_manager) VideoCommon::CameraManager& camera_manager)
{ {
if (!material_resource) [[unlikely]]
return;
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& vertex_shader_manager = system.GetVertexShaderManager(); auto& vertex_shader_manager = system.GetVertexShaderManager();
AbstractFramebuffer* frame_buffer_to_restore = nullptr; AbstractFramebuffer* frame_buffer_to_restore = nullptr;
const auto camera_view = camera_manager.GetCurrentCameraView(material_resource->render_targets); const auto camera_view = camera_manager.GetCurrentCameraView();
const auto additional_camera_views = const auto additional_camera_views = camera_manager.GetAdditionalViews();
camera_manager.GetAdditionalViews(material_resource->render_targets);
if (camera_view.framebuffer || !additional_camera_views.empty()) if (camera_view.framebuffer || !additional_camera_views.empty())
{ {
frame_buffer_to_restore = g_gfx->GetCurrentFramebuffer(); frame_buffer_to_restore = g_gfx->GetCurrentFramebuffer();
@ -1430,6 +1385,8 @@ void VertexManagerBase::DrawViewsWithMaterial(
if (camera_view.transform) if (camera_view.transform)
{ {
// Get the current camera id, if it changed
// we need to reload our projection matrix
const u64 camera_id = Common::ToUnderlying<>(camera_view.id); const u64 camera_id = Common::ToUnderlying<>(camera_view.id);
if (m_last_camera_id != camera_id) if (m_last_camera_id != camera_id)
{ {
@ -1440,6 +1397,7 @@ void VertexManagerBase::DrawViewsWithMaterial(
} }
else else
{ {
// If we had a camera last draw but none this draw we need to reload our projection matrix
if (m_last_camera_id) if (m_last_camera_id)
{ {
vertex_shader_manager.ForceProjectionMatrixUpdate(system.GetXFStateManager(), vertex_shader_manager.ForceProjectionMatrixUpdate(system.GetXFStateManager(),
@ -1447,10 +1405,10 @@ void VertexManagerBase::DrawViewsWithMaterial(
} }
m_last_camera_id.reset(); m_last_camera_id.reset();
} }
DrawWithMaterial(base_vertex, base_index, index_size, primitive_type, draw_data, DrawWithMaterial(base_vertex, base_index, index_size, primitive_type, draw_data, material_data,
material_resource, camera_manager); camera_manager);
// Do we have any other views? If so we need to redraw with the current material to those // Do we have any other views? If so, we need to redraw with the current material to those
// frame buffers... // frame buffers...
for (const auto additional_camera_view : additional_camera_views) for (const auto additional_camera_view : additional_camera_views)
{ {
@ -1479,8 +1437,8 @@ void VertexManagerBase::DrawViewsWithMaterial(
} }
m_last_camera_id.reset(); m_last_camera_id.reset();
} }
DrawWithMaterial(base_vertex, base_index, index_size, primitive_type, draw_data, DrawWithMaterial(base_vertex, base_index, index_size, primitive_type, draw_data, material_data,
material_resource, camera_manager); camera_manager);
} }
if (frame_buffer_to_restore) if (frame_buffer_to_restore)
@ -1488,22 +1446,20 @@ void VertexManagerBase::DrawViewsWithMaterial(
g_gfx->SetFramebuffer(frame_buffer_to_restore); g_gfx->SetFramebuffer(frame_buffer_to_restore);
} }
if (material_resource->next) if (auto next_material = material_data.GetNextMaterial())
{ {
DrawViewsWithMaterial(base_vertex, base_index, index_size, primitive_type, draw_data, const auto data = next_material->GetData();
material_resource->next, camera_manager); DrawViewsWithMaterial(base_vertex, base_index, index_size, primitive_type, draw_data, *data,
camera_manager);
} }
} }
void VertexManagerBase::DrawWithMaterial(u32 base_vertex, u32 base_index, u32 index_size, void VertexManagerBase::DrawWithMaterial(u32 base_vertex, u32 base_index, u32 index_size,
PrimitiveType primitive_type, PrimitiveType primitive_type,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
GraphicsModSystem::MaterialResource* material_resource, const VideoCommon::MaterialResource::Data& material_data,
VideoCommon::CameraManager& camera_manager) VideoCommon::CameraManager& camera_manager)
{ {
if (!material_resource) [[unlikely]]
return;
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& geometry_shader_manager = system.GetGeometryShaderManager(); auto& geometry_shader_manager = system.GetGeometryShaderManager();
auto& pixel_shader_manager = system.GetPixelShaderManager(); auto& pixel_shader_manager = system.GetPixelShaderManager();
@ -1511,36 +1467,36 @@ void VertexManagerBase::DrawWithMaterial(u32 base_vertex, u32 base_index, u32 in
// Now we can upload uniforms, as nothing else will override them. // Now we can upload uniforms, as nothing else will override them.
geometry_shader_manager.SetConstants(primitive_type); geometry_shader_manager.SetConstants(primitive_type);
pixel_shader_manager.SetConstants(); pixel_shader_manager.SetConstants();
if (!material_resource->pixel_uniform_data.empty()) const auto pixel_uniforms = material_data.GetPixelUniforms();
if (!pixel_uniforms.empty())
{ {
pixel_shader_manager.custom_constants = material_resource->pixel_uniform_data; pixel_shader_manager.custom_constants = pixel_uniforms;
pixel_shader_manager.custom_constants_dirty = true; pixel_shader_manager.custom_constants_dirty = true;
} }
UploadUniforms(); UploadUniforms();
g_gfx->SetPipeline(material_resource->pipeline); g_gfx->SetPipeline(material_data.GetPipeline());
const std::size_t custom_sampler_index_offset = 8; for (const auto& texture_like : material_data.GetTextures())
for (std::size_t i = 0; i < material_resource->textures.size(); i++)
{ {
auto& texture_like_resource = material_resource->textures[i];
const AbstractTexture* texture = nullptr;
const SamplerState* sampler = nullptr; const SamplerState* sampler = nullptr;
std::string_view texture_hash = ""; if (texture_like.texture == nullptr) [[unlikely]]
u32 sampler_index = 0;
GetTextureAndSamplerFromResource(texture_like_resource, camera_manager, &texture, &sampler,
&sampler_index, &texture_hash);
if ((sampler == nullptr && texture_hash.empty()) || texture == nullptr) [[unlikely]]
continue; continue;
if (!texture_hash.empty()) if (texture_like.sampler_origin == VideoCommon::TextureSamplerValue::SamplerOrigin::Asset)
{ {
for (const auto& texture_view : draw_data.textures) sampler = &texture_like.sampler;
}
else
{
if (!texture_like.texture_hash.empty())
{ {
if (texture_view.hash_name == texture_hash) for (const auto& texture_view : draw_data.textures)
{ {
sampler = &draw_data.samplers[texture_view.unit]; if (texture_view.hash_name == texture_like.texture_hash)
break; {
sampler = &draw_data.samplers[texture_view.unit];
break;
}
} }
} }
} }
@ -1548,8 +1504,8 @@ void VertexManagerBase::DrawWithMaterial(u32 base_vertex, u32 base_index, u32 in
if (!sampler) if (!sampler)
continue; continue;
g_gfx->SetTexture(sampler_index + custom_sampler_index_offset, texture); g_gfx->SetTexture(texture_like.sampler_index, texture_like.texture);
g_gfx->SetSamplerState(sampler_index + custom_sampler_index_offset, *sampler); g_gfx->SetSamplerState(texture_like.sampler_index, *sampler);
} }
DrawCurrentBatch(base_index, index_size, base_vertex); DrawCurrentBatch(base_index, index_size, base_vertex);

View file

@ -15,6 +15,8 @@
#include "VideoCommon/CPUCull.h" #include "VideoCommon/CPUCull.h"
#include "VideoCommon/IndexGenerator.h" #include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/RenderState.h" #include "VideoCommon/RenderState.h"
#include "VideoCommon/Resources/MaterialResource.h"
#include "VideoCommon/Resources/MeshResource.h"
#include "VideoCommon/ShaderCache.h" #include "VideoCommon/ShaderCache.h"
#include "VideoCommon/VideoEvents.h" #include "VideoCommon/VideoEvents.h"
@ -31,14 +33,12 @@ namespace GraphicsModSystem
enum class DrawCallID : unsigned long long; enum class DrawCallID : unsigned long long;
struct DrawDataView; struct DrawDataView;
struct MaterialResource;
struct MeshResource;
} // namespace GraphicsModSystem } // namespace GraphicsModSystem
namespace VideoCommon namespace VideoCommon
{ {
class CameraManager; class CameraManager;
} } // namespace VideoCommon
struct Slope struct Slope
{ {
@ -195,14 +195,14 @@ public:
const Common::Matrix44& custom_transform = Common::Matrix44::Identity()); const Common::Matrix44& custom_transform = Common::Matrix44::Identity());
// Draws the normal mesh sourced from emulation, with a custom shader and/or transform // Draws the normal mesh sourced from emulation, with a custom shader and/or transform
void DrawEmulatedMesh(GraphicsModSystem::MaterialResource* material_resource, void DrawEmulatedMesh(const VideoCommon::MaterialResource::Data& material_data,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
const Common::Matrix44& custom_transform, const Common::Matrix44& custom_transform,
VideoCommon::CameraManager& camera_manager); VideoCommon::CameraManager& camera_manager);
// Draw a custom mesh sourced from a mod, with a custom shader and custom vertex information // Draw a custom mesh sourced from a mod, with a custom shader and custom vertex information
void DrawCustomMesh(GraphicsModSystem::DrawCallID draw_call, void DrawCustomMesh(GraphicsModSystem::DrawCallID draw_call,
GraphicsModSystem::MeshResource* mesh_resource, const VideoCommon::MeshResource::Data& mesh_data,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
const Common::Matrix44& custom_transform, bool ignore_mesh_transform, const Common::Matrix44& custom_transform, bool ignore_mesh_transform,
VideoCommon::CameraManager& camera_manager); VideoCommon::CameraManager& camera_manager);
@ -213,14 +213,14 @@ protected:
void DrawViewsWithMaterial(u32 base_vertex, u32 base_index, u32 index_size, void DrawViewsWithMaterial(u32 base_vertex, u32 base_index, u32 index_size,
PrimitiveType primitive_type, PrimitiveType primitive_type,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
GraphicsModSystem::MaterialResource* material_resource, const VideoCommon::MaterialResource::Data& material_data,
VideoCommon::CameraManager& camera_manager); VideoCommon::CameraManager& camera_manager);
// Draws the current mesh data with a material // Draws the current mesh data with a material
void DrawWithMaterial(u32 base_vertex, u32 base_index, u32 index_size, void DrawWithMaterial(u32 base_vertex, u32 base_index, u32 index_size,
PrimitiveType primitive_type, PrimitiveType primitive_type,
const GraphicsModSystem::DrawDataView& draw_data, const GraphicsModSystem::DrawDataView& draw_data,
GraphicsModSystem::MaterialResource* material_resource, const VideoCommon::MaterialResource::Data& material_data,
VideoCommon::CameraManager& camera_manager); VideoCommon::CameraManager& camera_manager);
; ;