Some adjustments to vertex attributes

This commit is contained in:
CamilleLaVey
2026-09-17 06:55:48 -04:00
parent d633c43aae
commit 8cdf552c28
6 changed files with 52 additions and 10 deletions
+29 -7
View File
@@ -14,6 +14,10 @@
namespace Tegra::Engines { namespace Tegra::Engines {
void Maxwell3D::DrawManager::ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument) { void Maxwell3D::DrawManager::ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument) {
if (draw_state.draw_mode == DrawMode::InstanceArray &&
method != MAXWELL3D_REG_INDEX(vertex_array_instance_subsequent)) {
DrawDeferred(maxwell3d);
}
switch (method) { switch (method) {
case MAXWELL3D_REG_INDEX(clear_surface): case MAXWELL3D_REG_INDEX(clear_surface):
return Clear(maxwell3d, 1); return Clear(maxwell3d, 1);
@@ -73,6 +77,15 @@ void Maxwell3D::DrawManager::Clear(Maxwell3D& maxwell3d, u32 layer_count) {
} }
void Maxwell3D::DrawManager::DrawDeferred(Maxwell3D& maxwell3d) { void Maxwell3D::DrawManager::DrawDeferred(Maxwell3D& maxwell3d) {
if (draw_state.draw_mode == DrawMode::InstanceArray) {
const u32 instance_count = draw_state.instance_count + 1;
draw_state.draw_mode = DrawMode::General;
draw_state.instance_count = 0;
if (maxwell3d.ShouldExecute()) {
maxwell3d.rasterizer->Draw(false, instance_count);
}
return;
}
if (draw_state.draw_mode != DrawMode::Instance || draw_state.instance_count == 0) { if (draw_state.draw_mode != DrawMode::Instance || draw_state.instance_count == 0) {
return; return;
} }
@@ -89,16 +102,25 @@ void Maxwell3D::DrawManager::DrawArray(Maxwell3D& maxwell3d, Maxwell3D::Regs::Pr
} }
void Maxwell3D::DrawManager::DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent) { void Maxwell3D::DrawManager::DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent) {
if (subsequent && draw_state.draw_mode == DrawMode::InstanceArray &&
instance_topology == topology && draw_state.vertex_buffer.first == vertex_first &&
draw_state.vertex_buffer.count == vertex_count) {
++draw_state.instance_count;
return;
}
u32 base_instance = 0;
if (subsequent) {
base_instance = draw_state.base_instance + draw_state.instance_count + 1;
}
DrawDeferred(maxwell3d);
instance_topology = topology;
draw_state.topology = topology; draw_state.topology = topology;
draw_state.vertex_buffer.first = vertex_first; draw_state.vertex_buffer.first = vertex_first;
draw_state.vertex_buffer.count = vertex_count; draw_state.vertex_buffer.count = vertex_count;
if (!subsequent) { draw_state.base_instance = base_instance;
draw_state.instance_count = 1; draw_state.instance_count = 0;
} draw_state.draw_mode = DrawMode::InstanceArray;
draw_state.base_instance = draw_state.instance_count - 1; UpdateTopology(maxwell3d);
draw_state.draw_mode = DrawMode::Instance;
draw_state.instance_count++;
ProcessDraw(maxwell3d, false, 1);
} }
void Maxwell3D::DrawManager::DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances) { void Maxwell3D::DrawManager::DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances) {
+2 -1
View File
@@ -3034,7 +3034,7 @@ public:
// clang-format on // clang-format on
struct DrawManager { struct DrawManager {
enum class DrawMode : u32 { General = 0, Instance, InlineIndex }; enum class DrawMode : u32 { General = 0, Instance, InlineIndex, InstanceArray };
struct State { struct State {
Maxwell3D::Regs::PrimitiveTopology topology{}; Maxwell3D::Regs::PrimitiveTopology topology{};
DrawMode draw_mode{}; DrawMode draw_mode{};
@@ -3086,6 +3086,7 @@ public:
void ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count); void ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count);
void ProcessDrawIndirect(Maxwell3D& maxwell3d); void ProcessDrawIndirect(Maxwell3D& maxwell3d);
State draw_state{}; State draw_state{};
Maxwell3D::Regs::PrimitiveTopology instance_topology{};
DrawTextureState draw_texture_state{}; DrawTextureState draw_texture_state{};
IndirectParams indirect_state{}; IndirectParams indirect_state{};
}; };
@@ -705,7 +705,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
if (instanced) { if (instanced) {
vertex_binding_divisors.push_back({ vertex_binding_divisors.push_back({
.binding = static_cast<u32>(index), .binding = static_cast<u32>(index),
.divisor = key.state.binding_divisors[index], .divisor = (std::min)(key.state.binding_divisors[index],
device.GetMaxVertexAttribDivisor()),
}); });
} }
} }
@@ -1918,13 +1918,17 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
for (u32 binding = 0; binding < max_bindings; ++binding) { for (u32 binding = 0; binding < max_bindings; ++binding) {
const auto& input_binding{regs.vertex_streams[binding]}; const auto& input_binding{regs.vertex_streams[binding]};
const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)}; const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)};
u32 divisor = 1;
if (is_instanced) {
divisor = (std::min)(input_binding.frequency, device.GetMaxVertexAttribDivisor());
}
bindings.push_back({ bindings.push_back({
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
.pNext = nullptr, .pNext = nullptr,
.binding = binding, .binding = binding,
.stride = input_binding.stride, .stride = input_binding.stride,
.inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, .inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
.divisor = is_instanced ? input_binding.frequency : 1, .divisor = divisor,
}); });
} }
@@ -1130,11 +1130,19 @@ bool Device::GetSuitability(bool requires_swapchain) {
SetNext(next, properties.custom_border_color); SetNext(next, properties.custom_border_color);
} }
if (extensions.vertex_attribute_divisor) {
properties.vertex_attribute_divisor.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
SetNext(next, properties.vertex_attribute_divisor);
}
// Perform the property fetch. // Perform the property fetch.
physical.GetProperties2(properties2); physical.GetProperties2(properties2);
// Store base properties // Store base properties
properties.properties = properties2.properties; properties.properties = properties2.properties;
max_vertex_attrib_divisor =
(std::max)(1U, properties.vertex_attribute_divisor.maxVertexAttribDivisor);
// Unload extensions if feature support is insufficient. // Unload extensions if feature support is insufficient.
RemoveUnsuitableExtensions(); RemoveUnsuitableExtensions();
@@ -984,6 +984,10 @@ FN_MAX_LIMIT_LIST
return properties.properties.limits.maxVertexInputBindings; return properties.properties.limits.maxVertexInputBindings;
} }
u32 GetMaxVertexAttribDivisor() const {
return max_vertex_attrib_divisor;
}
u32 GetMaxViewports() const { u32 GetMaxViewports() const {
return properties.properties.limits.maxViewports; return properties.properties.limits.maxViewports;
} }
@@ -1188,6 +1192,7 @@ private:
VkPhysicalDeviceMaintenance5PropertiesKHR maintenance5{}; VkPhysicalDeviceMaintenance5PropertiesKHR maintenance5{};
VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve{}; VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve{};
VkPhysicalDeviceCustomBorderColorPropertiesEXT custom_border_color{}; VkPhysicalDeviceCustomBorderColorPropertiesEXT custom_border_color{};
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_attribute_divisor{};
VkPhysicalDeviceProperties properties{}; VkPhysicalDeviceProperties properties{};
}; };
@@ -1195,6 +1200,7 @@ private:
Extensions extensions{}; Extensions extensions{};
Features features{}; Features features{};
Properties properties{}; Properties properties{};
u32 max_vertex_attrib_divisor{1};
VkPhysicalDeviceFeatures2 features2{}; VkPhysicalDeviceFeatures2 features2{};
VkPhysicalDeviceProperties2 properties2{}; VkPhysicalDeviceProperties2 properties2{};