mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-07 14:26:36 +00:00
Some adjustments to EDS
This commit is contained in:
@@ -649,11 +649,17 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||||
scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) {
|
const bool dynamic_stride = !device.IsExtVertexInputDynamicStateSupported();
|
||||||
|
scheduler.Record([index, buffer, offset, size, stride,
|
||||||
|
dynamic_stride](vk::CommandBuffer cmdbuf) {
|
||||||
const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0;
|
const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0;
|
||||||
const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE;
|
const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE;
|
||||||
const VkDeviceSize vk_stride = stride;
|
const VkDeviceSize vk_stride = stride;
|
||||||
cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, &vk_stride);
|
const VkDeviceSize* strides = nullptr;
|
||||||
|
if (dynamic_stride) {
|
||||||
|
strides = &vk_stride;
|
||||||
|
}
|
||||||
|
cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, strides);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (!device.HasNullDescriptor() && buffer == VK_NULL_HANDLE) {
|
if (!device.HasNullDescriptor() && buffer == VK_NULL_HANDLE) {
|
||||||
@@ -688,10 +694,14 @@ void BufferCacheRuntime::RecordVertexBuffers(const VideoCommon::HostBindings<Buf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||||
scheduler.Record([vertex](vk::CommandBuffer cmdbuf) {
|
const bool dynamic_stride = !device.IsExtVertexInputDynamicStateSupported();
|
||||||
|
scheduler.Record([vertex, dynamic_stride](vk::CommandBuffer cmdbuf) {
|
||||||
|
const VkDeviceSize* strides = nullptr;
|
||||||
|
if (dynamic_stride) {
|
||||||
|
strides = vertex.strides.data();
|
||||||
|
}
|
||||||
cmdbuf.BindVertexBuffers2EXT(vertex.first, vertex.count, vertex.buffers.data(),
|
cmdbuf.BindVertexBuffers2EXT(vertex.first, vertex.count, vertex.buffers.data(),
|
||||||
vertex.offsets.data(), vertex.sizes.data(),
|
vertex.offsets.data(), vertex.sizes.data(), strides);
|
||||||
vertex.strides.data());
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,6 +306,11 @@ GraphicsPipeline::GraphicsPipeline(
|
|||||||
num_descriptor_entries += NumDescriptorEntries(*info);
|
num_descriptor_entries += NumDescriptorEntries(*info);
|
||||||
}
|
}
|
||||||
fragment_has_color0_output = stage_infos[NUM_STAGES - 1].stores_frag_color[0];
|
fragment_has_color0_output = stage_infos[NUM_STAGES - 1].stores_frag_color[0];
|
||||||
|
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||||
|
if (stage_infos[0].loads.Generic(index)) {
|
||||||
|
vertex_attribute_mask |= 1u << index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)};
|
DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)};
|
||||||
uses_push_descriptor = builder.CanUsePushDescriptor();
|
uses_push_descriptor = builder.CanUsePushDescriptor();
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ public:
|
|||||||
const std::array<const Shader::Info*, NUM_STAGES>& infos);
|
const std::array<const Shader::Info*, NUM_STAGES>& infos);
|
||||||
|
|
||||||
bool HasDynamicVertexInput() const noexcept { return key.state.dynamic_vertex_input; }
|
bool HasDynamicVertexInput() const noexcept { return key.state.dynamic_vertex_input; }
|
||||||
|
u32 VertexAttributeMask() const noexcept {
|
||||||
|
return vertex_attribute_mask;
|
||||||
|
}
|
||||||
bool SupportsAlphaToCoverage() const noexcept {
|
bool SupportsAlphaToCoverage() const noexcept {
|
||||||
return fragment_has_color0_output;
|
return fragment_has_color0_output;
|
||||||
}
|
}
|
||||||
@@ -168,6 +171,7 @@ private:
|
|||||||
size_t num_image_elements{};
|
size_t num_image_elements{};
|
||||||
u32 num_textures{};
|
u32 num_textures{};
|
||||||
bool fragment_has_color0_output{};
|
bool fragment_has_color0_output{};
|
||||||
|
u32 vertex_attribute_mask{};
|
||||||
|
|
||||||
vk::DescriptorSetLayout descriptor_set_layout;
|
vk::DescriptorSetLayout descriptor_set_layout;
|
||||||
DescriptorAllocator descriptor_allocator;
|
DescriptorAllocator descriptor_allocator;
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, bool skip_empty, Func&& draw
|
|||||||
if (!pipeline->Configure(is_indexed))
|
if (!pipeline->Configure(is_indexed))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateDynamicStates(pipeline->HasDynamicVertexInput());
|
UpdateDynamicStates(*pipeline);
|
||||||
|
|
||||||
query_cache.NotifySegment(true);
|
query_cache.NotifySegment(true);
|
||||||
HandleTransformFeedback();
|
HandleTransformFeedback();
|
||||||
@@ -383,13 +383,6 @@ void RasterizerVulkan::DrawTexture() {
|
|||||||
texture_cache.SynchronizeDescriptors(false);
|
texture_cache.SynchronizeDescriptors(false);
|
||||||
texture_cache.UpdateRenderTargets(false);
|
texture_cache.UpdateRenderTargets(false);
|
||||||
|
|
||||||
bool dynamic_vertex_input = false;
|
|
||||||
if (device.IsExtVertexInputDynamicStateSupported()) {
|
|
||||||
GraphicsPipeline* const gp = pipeline_cache.CurrentGraphicsPipeline();
|
|
||||||
dynamic_vertex_input = gp && gp->HasDynamicVertexInput();
|
|
||||||
}
|
|
||||||
UpdateDynamicStates(dynamic_vertex_input);
|
|
||||||
|
|
||||||
const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state;
|
const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state;
|
||||||
const auto& sampler = texture_cache.GetSampler(draw_texture_state.src_sampler, false);
|
const auto& sampler = texture_cache.GetSampler(draw_texture_state.src_sampler, false);
|
||||||
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
|
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
|
||||||
@@ -1078,7 +1071,7 @@ bool AccelerateDMA::BufferToImage(const Tegra::DMA::ImageCopy& copy_info,
|
|||||||
return DmaBufferImageCopy<true>(copy_info, buffer_operand, image_operand);
|
return DmaBufferImageCopy<true>(copy_info, buffer_operand, image_operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::UpdateDynamicStates(bool dynamic_vertex_input) {
|
void RasterizerVulkan::UpdateDynamicStates(const GraphicsPipeline& pipeline) {
|
||||||
auto& regs = maxwell3d->regs;
|
auto& regs = maxwell3d->regs;
|
||||||
auto& flags = maxwell3d->dirty.flags;
|
auto& flags = maxwell3d->dirty.flags;
|
||||||
const auto topology = maxwell3d->draw_manager.draw_state.topology;
|
const auto topology = maxwell3d->draw_manager.draw_state.topology;
|
||||||
@@ -1126,27 +1119,13 @@ void RasterizerVulkan::UpdateDynamicStates(bool dynamic_vertex_input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device.IsExtExtendedDynamicState3EnablesSupported()) {
|
if (device.IsExtExtendedDynamicState3EnablesSupported()) {
|
||||||
using namespace Tegra::Engines;
|
|
||||||
// AMD Workaround: LogicOp incompatible with float render targets
|
|
||||||
if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE ||
|
|
||||||
device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) {
|
|
||||||
const auto has_float = std::any_of(
|
|
||||||
regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(),
|
|
||||||
[](const auto& attrib) {
|
|
||||||
return attrib.type == Maxwell3D::Regs::VertexAttribute::Type::Float;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (regs.logic_op.enable) {
|
|
||||||
regs.logic_op.enable = static_cast<u32>(!has_float);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateLogicOpEnable(regs);
|
UpdateLogicOpEnable(regs);
|
||||||
UpdateDepthClampEnable(regs);
|
UpdateDepthClampEnable(regs);
|
||||||
UpdateLineRasterizationMode(regs);
|
UpdateLineRasterizationMode(regs);
|
||||||
UpdateLineStippleEnable(regs);
|
UpdateLineStippleEnable(regs);
|
||||||
UpdateConservativeRasterizationMode(regs);
|
UpdateConservativeRasterizationMode(regs);
|
||||||
UpdateAlphaToCoverageEnable(regs);
|
UpdateAlphaToCoverageEnable(regs, pipeline);
|
||||||
UpdateAlphaToOneEnable(regs);
|
UpdateAlphaToOneEnable(regs, pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.IsExtExtendedDynamicState3BlendingSupported()) {
|
if (device.IsExtExtendedDynamicState3BlendingSupported()) {
|
||||||
@@ -1155,8 +1134,8 @@ void RasterizerVulkan::UpdateDynamicStates(bool dynamic_vertex_input) {
|
|||||||
UpdateColorWriteEnable(regs);
|
UpdateColorWriteEnable(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_vertex_input) {
|
if (pipeline.HasDynamicVertexInput()) {
|
||||||
UpdateVertexInput(regs);
|
UpdateVertexInput(regs, pipeline.VertexAttributeMask());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1690,36 +1669,33 @@ void RasterizerVulkan::UpdateDepthClampEnable(Tegra::Engines::Maxwell3D::Regs& r
|
|||||||
[is_enabled](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthClampEnableEXT(is_enabled); });
|
[is_enabled](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthClampEnableEXT(is_enabled); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::UpdateAlphaToCoverageEnable(Tegra::Engines::Maxwell3D::Regs& regs) {
|
void RasterizerVulkan::UpdateAlphaToCoverageEnable(Tegra::Engines::Maxwell3D::Regs& regs,
|
||||||
if (!state_tracker.TouchAlphaToCoverageEnable()) {
|
const GraphicsPipeline& pipeline) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!device.SupportsDynamicState3AlphaToCoverageEnable()) {
|
if (!device.SupportsDynamicState3AlphaToCoverageEnable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GraphicsPipeline* const pipeline = pipeline_cache.CurrentGraphicsPipeline();
|
const bool enable =
|
||||||
const bool enable = pipeline != nullptr && pipeline->SupportsAlphaToCoverage() &&
|
pipeline.SupportsAlphaToCoverage() && regs.anti_alias_alpha_control.alpha_to_coverage != 0;
|
||||||
regs.anti_alias_alpha_control.alpha_to_coverage != 0;
|
if (!state_tracker.TouchAlphaToCoverageEnable() && enable == alpha_to_coverage_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
alpha_to_coverage_enabled = enable;
|
||||||
scheduler.Record([enable](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([enable](vk::CommandBuffer cmdbuf) {
|
||||||
cmdbuf.SetAlphaToCoverageEnableEXT(enable ? VK_TRUE : VK_FALSE);
|
cmdbuf.SetAlphaToCoverageEnableEXT(enable ? VK_TRUE : VK_FALSE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::UpdateAlphaToOneEnable(Tegra::Engines::Maxwell3D::Regs& regs) {
|
void RasterizerVulkan::UpdateAlphaToOneEnable(Tegra::Engines::Maxwell3D::Regs& regs,
|
||||||
if (!state_tracker.TouchAlphaToOneEnable()) {
|
const GraphicsPipeline& pipeline) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!device.SupportsDynamicState3AlphaToOneEnable()) {
|
if (!device.SupportsDynamicState3AlphaToOneEnable()) {
|
||||||
static std::once_flag warn_alpha_to_one;
|
|
||||||
std::call_once(warn_alpha_to_one, [] {
|
|
||||||
LOG_WARNING(Render_Vulkan,
|
|
||||||
"Alpha-to-one is not supported on this device; forcing it disabled");
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GraphicsPipeline* const pipeline = pipeline_cache.CurrentGraphicsPipeline();
|
const bool enable =
|
||||||
const bool enable = pipeline != nullptr && pipeline->SupportsAlphaToOne() &&
|
pipeline.SupportsAlphaToOne() && regs.anti_alias_alpha_control.alpha_to_one != 0;
|
||||||
regs.anti_alias_alpha_control.alpha_to_one != 0;
|
if (!state_tracker.TouchAlphaToOneEnable() && enable == alpha_to_one_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
alpha_to_one_enabled = enable;
|
||||||
scheduler.Record([enable](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([enable](vk::CommandBuffer cmdbuf) {
|
||||||
cmdbuf.SetAlphaToOneEnableEXT(enable ? VK_TRUE : VK_FALSE);
|
cmdbuf.SetAlphaToOneEnableEXT(enable ? VK_TRUE : VK_FALSE);
|
||||||
});
|
});
|
||||||
@@ -1793,7 +1769,17 @@ void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) {
|
void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) {
|
||||||
if (!state_tracker.TouchBlending()) {
|
u8 integer_targets = 0;
|
||||||
|
for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) {
|
||||||
|
const auto format = regs.rt[index].format;
|
||||||
|
if (format != Tegra::RenderTargetFormat::NONE &&
|
||||||
|
IsPixelFormatInteger(VideoCore::Surface::PixelFormatFromRenderTargetFormat(format))) {
|
||||||
|
integer_targets |= static_cast<u8>(1u << index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bool targets_changed =
|
||||||
|
std::exchange(blend_integer_targets, integer_targets) != integer_targets;
|
||||||
|
if (!state_tracker.TouchBlending() && !targets_changed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1820,17 +1806,12 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_tracker.TouchBlendEnable()) {
|
if (state_tracker.TouchBlendEnable() || targets_changed) {
|
||||||
std::array<VkBool32, Maxwell::NumRenderTargets> setup_enables{};
|
std::array<VkBool32, Maxwell::NumRenderTargets> setup_enables{};
|
||||||
for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) {
|
for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) {
|
||||||
bool is_integer = false;
|
const bool is_integer = ((integer_targets >> index) & 1) != 0;
|
||||||
if (regs.rt[index].format != Tegra::RenderTargetFormat::NONE) {
|
|
||||||
const auto format =
|
|
||||||
VideoCore::Surface::PixelFormatFromRenderTargetFormat(regs.rt[index].format);
|
|
||||||
is_integer = IsPixelFormatInteger(format);
|
|
||||||
}
|
|
||||||
setup_enables[index] =
|
setup_enables[index] =
|
||||||
(!is_integer && regs.blend.enable[index] != 0) ? VK_TRUE : VK_FALSE;
|
static_cast<VkBool32>(!is_integer && regs.blend.enable[index] != 0);
|
||||||
}
|
}
|
||||||
scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf) {
|
||||||
cmdbuf.SetColorBlendEnableEXT(0, setup_enables);
|
cmdbuf.SetColorBlendEnableEXT(0, setup_enables);
|
||||||
@@ -1903,18 +1884,9 @@ void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs&
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) {
|
void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs,
|
||||||
|
u32 attribute_mask) {
|
||||||
auto& dirty{maxwell3d->dirty.flags};
|
auto& dirty{maxwell3d->dirty.flags};
|
||||||
const bool vertex_input_dirty = dirty[Dirty::VertexInput];
|
|
||||||
const bool vertex_buffers_dirty = dirty[VideoCommon::Dirty::VertexBuffers];
|
|
||||||
if (!vertex_input_dirty && !vertex_buffers_dirty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dirty[Dirty::VertexInput] = false;
|
|
||||||
|
|
||||||
boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings;
|
|
||||||
boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes;
|
|
||||||
|
|
||||||
const u32 max_attributes =
|
const u32 max_attributes =
|
||||||
static_cast<u32>(std::min<size_t>(Maxwell::NumVertexAttributes,
|
static_cast<u32>(std::min<size_t>(Maxwell::NumVertexAttributes,
|
||||||
device.GetMaxVertexInputAttributes()));
|
device.GetMaxVertexInputAttributes()));
|
||||||
@@ -1922,11 +1894,25 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
|||||||
static_cast<u32>(std::min<size_t>(Maxwell::NumVertexArrays,
|
static_cast<u32>(std::min<size_t>(Maxwell::NumVertexArrays,
|
||||||
device.GetMaxVertexInputBindings()));
|
device.GetMaxVertexInputBindings()));
|
||||||
|
|
||||||
|
bool changed = dirty[Dirty::VertexInput] || vertex_input_attributes != attribute_mask;
|
||||||
|
dirty[Dirty::VertexInput] = false;
|
||||||
|
vertex_input_attributes = attribute_mask;
|
||||||
|
for (u32 binding = 0; binding < max_bindings; ++binding) {
|
||||||
|
const u32 stride = regs.vertex_streams[binding].stride;
|
||||||
|
changed |= vertex_input_strides[binding] != stride;
|
||||||
|
vertex_input_strides[binding] = stride;
|
||||||
|
}
|
||||||
|
if (!changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings;
|
||||||
|
boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes;
|
||||||
|
|
||||||
for (u32 index = 0; index < max_attributes; ++index) {
|
for (u32 index = 0; index < max_attributes; ++index) {
|
||||||
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
||||||
const u32 binding{attribute.buffer};
|
const u32 binding{attribute.buffer};
|
||||||
if (attribute.constant || binding >= max_bindings) {
|
if (((attribute_mask >> index) & 1) == 0 || attribute.constant || binding >= max_bindings) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
attributes.push_back({
|
attributes.push_back({
|
||||||
@@ -1941,17 +1927,19 @@ 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)};
|
VkVertexInputRate input_rate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
u32 divisor = 1;
|
u32 divisor = 1;
|
||||||
if (is_instanced) {
|
if (regs.vertex_stream_instances.IsInstancingEnabled(binding) &&
|
||||||
|
input_binding.frequency != 0) {
|
||||||
|
input_rate = VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||||
divisor = (std::min)(input_binding.frequency, device.GetMaxVertexAttribDivisor());
|
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 = vertex_input_strides[binding],
|
||||||
.inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
|
.inputRate = input_rate,
|
||||||
.divisor = divisor,
|
.divisor = divisor,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ private:
|
|||||||
|
|
||||||
void FlushWork();
|
void FlushWork();
|
||||||
|
|
||||||
void UpdateDynamicStates(bool dynamic_vertex_input);
|
void UpdateDynamicStates(const GraphicsPipeline& pipeline);
|
||||||
|
|
||||||
void HandleTransformFeedback();
|
void HandleTransformFeedback();
|
||||||
|
|
||||||
@@ -183,8 +183,10 @@ private:
|
|||||||
void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
void UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
void UpdateDepthClampEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateDepthClampEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
void UpdateAlphaToCoverageEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateAlphaToCoverageEnable(Tegra::Engines::Maxwell3D::Regs& regs,
|
||||||
void UpdateAlphaToOneEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
const GraphicsPipeline& pipeline);
|
||||||
|
void UpdateAlphaToOneEnable(Tegra::Engines::Maxwell3D::Regs& regs,
|
||||||
|
const GraphicsPipeline& pipeline);
|
||||||
void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
@@ -192,7 +194,7 @@ private:
|
|||||||
void UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
void UpdateColorWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateColorWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||||
|
|
||||||
void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs);
|
void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs, u32 attribute_mask);
|
||||||
|
|
||||||
Tegra::GPU& gpu;
|
Tegra::GPU& gpu;
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||||
@@ -226,6 +228,11 @@ private:
|
|||||||
|
|
||||||
u32 draw_counter = 0;
|
u32 draw_counter = 0;
|
||||||
Tegra::DepthFormat depth_bias_zeta_format{};
|
Tegra::DepthFormat depth_bias_zeta_format{};
|
||||||
|
std::array<u32, Tegra::Engines::Maxwell3D::Regs::NumVertexArrays> vertex_input_strides{};
|
||||||
|
u32 vertex_input_attributes{};
|
||||||
|
u8 blend_integer_targets{};
|
||||||
|
bool alpha_to_coverage_enabled{};
|
||||||
|
bool alpha_to_one_enabled{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -1127,6 +1127,9 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
|||||||
properties.properties = properties2.properties;
|
properties.properties = properties2.properties;
|
||||||
max_vertex_attrib_divisor =
|
max_vertex_attrib_divisor =
|
||||||
(std::max)(1U, properties.vertex_attribute_divisor.maxVertexAttribDivisor);
|
(std::max)(1U, properties.vertex_attribute_divisor.maxVertexAttribDivisor);
|
||||||
|
if (!features.vertex_attribute_divisor.vertexAttributeInstanceRateDivisor) {
|
||||||
|
max_vertex_attrib_divisor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Unload extensions if feature support is insufficient.
|
// Unload extensions if feature support is insufficient.
|
||||||
RemoveUnsuitableExtensions();
|
RemoveUnsuitableExtensions();
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
|||||||
FEATURE(EXT, Robustness2, ROBUSTNESS_2, robustness2) \
|
FEATURE(EXT, Robustness2, ROBUSTNESS_2, robustness2) \
|
||||||
FEATURE(EXT, TexelBufferAlignment, TEXEL_BUFFER_ALIGNMENT, texel_buffer_alignment) \
|
FEATURE(EXT, TexelBufferAlignment, TEXEL_BUFFER_ALIGNMENT, texel_buffer_alignment) \
|
||||||
FEATURE(EXT, TransformFeedback, TRANSFORM_FEEDBACK, transform_feedback) \
|
FEATURE(EXT, TransformFeedback, TRANSFORM_FEEDBACK, transform_feedback) \
|
||||||
|
FEATURE(EXT, VertexAttributeDivisor, VERTEX_ATTRIBUTE_DIVISOR, vertex_attribute_divisor) \
|
||||||
FEATURE(EXT, VertexInputDynamicState, VERTEX_INPUT_DYNAMIC_STATE, vertex_input_dynamic_state) \
|
FEATURE(EXT, VertexInputDynamicState, VERTEX_INPUT_DYNAMIC_STATE, vertex_input_dynamic_state) \
|
||||||
FEATURE(KHR, Maintenance5, MAINTENANCE_5, maintenance5) \
|
FEATURE(KHR, Maintenance5, MAINTENANCE_5, maintenance5) \
|
||||||
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
|
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
|
||||||
@@ -96,7 +97,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
|||||||
EXTENSION(EXT, SHADER_STENCIL_EXPORT, shader_stencil_export) \
|
EXTENSION(EXT, SHADER_STENCIL_EXPORT, shader_stencil_export) \
|
||||||
EXTENSION(EXT, SHADER_VIEWPORT_INDEX_LAYER, shader_viewport_index_layer) \
|
EXTENSION(EXT, SHADER_VIEWPORT_INDEX_LAYER, shader_viewport_index_layer) \
|
||||||
EXTENSION(EXT, TOOLING_INFO, tooling_info) \
|
EXTENSION(EXT, TOOLING_INFO, tooling_info) \
|
||||||
EXTENSION(EXT, VERTEX_ATTRIBUTE_DIVISOR, vertex_attribute_divisor) \
|
|
||||||
EXTENSION(KHR, COPY_COMMANDS_2, copy_commands2) \
|
EXTENSION(KHR, COPY_COMMANDS_2, copy_commands2) \
|
||||||
EXTENSION(KHR, CREATE_RENDERPASS_2, create_renderpass2) \
|
EXTENSION(KHR, CREATE_RENDERPASS_2, create_renderpass2) \
|
||||||
EXTENSION(KHR, DEPTH_STENCIL_RESOLVE, depth_stencil_resolve) \
|
EXTENSION(KHR, DEPTH_STENCIL_RESOLVE, depth_stencil_resolve) \
|
||||||
|
|||||||
Reference in New Issue
Block a user