mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-22 15:30:08 +00:00
vk_rasterizer: More robust attribute loading
This commit is contained in:
parent
fe724600ab
commit
dd71859818
@ -43,7 +43,7 @@ class RenderpassCache;
|
|||||||
|
|
||||||
constexpr u32 MAX_SHADER_STAGES = 3;
|
constexpr u32 MAX_SHADER_STAGES = 3;
|
||||||
constexpr u32 MAX_VERTEX_ATTRIBUTES = 16;
|
constexpr u32 MAX_VERTEX_ATTRIBUTES = 16;
|
||||||
constexpr u32 MAX_VERTEX_BINDINGS = 16;
|
constexpr u32 MAX_VERTEX_BINDINGS = 13;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pipeline state is tightly packed with bitfields to reduce
|
* The pipeline state is tightly packed with bitfields to reduce
|
||||||
@ -125,12 +125,12 @@ struct AttachmentInfo {
|
|||||||
* Information about a graphics/compute pipeline
|
* Information about a graphics/compute pipeline
|
||||||
*/
|
*/
|
||||||
struct PipelineInfo {
|
struct PipelineInfo {
|
||||||
VertexLayout vertex_layout;
|
|
||||||
BlendingState blending;
|
BlendingState blending;
|
||||||
AttachmentInfo attachments;
|
AttachmentInfo attachments;
|
||||||
RasterizationState rasterization;
|
RasterizationState rasterization;
|
||||||
DepthStencilState depth_stencil;
|
DepthStencilState depth_stencil;
|
||||||
DynamicState dynamic;
|
DynamicState dynamic;
|
||||||
|
VertexLayout vertex_layout;
|
||||||
|
|
||||||
[[nodiscard]] u64 Hash(const Instance& instance) const;
|
[[nodiscard]] u64 Hash(const Instance& instance) const;
|
||||||
|
|
||||||
|
@ -166,13 +166,12 @@ void RasterizerVulkan::SetupVertexArray() {
|
|||||||
* or interleave them in the same loader.
|
* or interleave them in the same loader.
|
||||||
**/
|
**/
|
||||||
const auto& vertex_attributes = regs.pipeline.vertex_attributes;
|
const auto& vertex_attributes = regs.pipeline.vertex_attributes;
|
||||||
PAddr base_address = vertex_attributes.GetPhysicalBaseAddress(); // GPUREG_ATTR_BUF_BASE
|
const PAddr base_address = vertex_attributes.GetPhysicalBaseAddress(); // GPUREG_ATTR_BUF_BASE
|
||||||
|
|
||||||
const u32 stride_alignment = instance.GetMinVertexStrideAlignment();
|
const u32 stride_alignment = instance.GetMinVertexStrideAlignment();
|
||||||
|
|
||||||
VertexLayout& layout = pipeline_info.vertex_layout;
|
VertexLayout& layout = pipeline_info.vertex_layout;
|
||||||
layout.attribute_count = 0;
|
|
||||||
layout.binding_count = 0;
|
layout.binding_count = 0;
|
||||||
|
layout.attribute_count = 16;
|
||||||
enable_attributes.fill(false);
|
enable_attributes.fill(false);
|
||||||
|
|
||||||
u32 buffer_offset = 0;
|
u32 buffer_offset = 0;
|
||||||
@ -184,32 +183,34 @@ void RasterizerVulkan::SetupVertexArray() {
|
|||||||
// Analyze the attribute loader by checking which attributes it provides
|
// Analyze the attribute loader by checking which attributes it provides
|
||||||
u32 offset = 0;
|
u32 offset = 0;
|
||||||
for (u32 comp = 0; comp < loader.component_count && comp < 12; comp++) {
|
for (u32 comp = 0; comp < loader.component_count && comp < 12; comp++) {
|
||||||
u32 attribute_index = loader.GetComponent(comp);
|
const u32 attribute_index = loader.GetComponent(comp);
|
||||||
if (attribute_index < 12) {
|
if (attribute_index >= 12) {
|
||||||
if (u32 size = vertex_attributes.GetNumElements(attribute_index); size != 0) {
|
// Attribute ids 12, to 15 signify 4, 8, 12 and 16-byte paddings respectively.
|
||||||
offset = Common::AlignUp(
|
|
||||||
offset, vertex_attributes.GetElementSizeInBytes(attribute_index));
|
|
||||||
|
|
||||||
const u32 input_reg = regs.vs.GetRegisterForAttribute(attribute_index);
|
|
||||||
const Pica::PipelineRegs::VertexAttributeFormat format =
|
|
||||||
vertex_attributes.GetFormat(attribute_index);
|
|
||||||
|
|
||||||
VertexAttribute& attribute = layout.attributes[layout.attribute_count++];
|
|
||||||
attribute.binding.Assign(layout.binding_count);
|
|
||||||
attribute.location.Assign(input_reg);
|
|
||||||
attribute.offset.Assign(offset);
|
|
||||||
attribute.type.Assign(format);
|
|
||||||
attribute.size.Assign(size);
|
|
||||||
|
|
||||||
enable_attributes[input_reg] = true;
|
|
||||||
offset += vertex_attributes.GetStride(attribute_index);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings
|
|
||||||
// respectively
|
|
||||||
offset = Common::AlignUp(offset, 4);
|
offset = Common::AlignUp(offset, 4);
|
||||||
offset += (attribute_index - 11) * 4;
|
offset += (attribute_index - 11) * 4;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u32 size = vertex_attributes.GetNumElements(attribute_index);
|
||||||
|
if (size == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset =
|
||||||
|
Common::AlignUp(offset, vertex_attributes.GetElementSizeInBytes(attribute_index));
|
||||||
|
|
||||||
|
const u32 input_reg = regs.vs.GetRegisterForAttribute(attribute_index);
|
||||||
|
const auto format = vertex_attributes.GetFormat(attribute_index);
|
||||||
|
|
||||||
|
VertexAttribute& attribute = layout.attributes[input_reg];
|
||||||
|
attribute.binding.Assign(layout.binding_count);
|
||||||
|
attribute.location.Assign(input_reg);
|
||||||
|
attribute.offset.Assign(offset);
|
||||||
|
attribute.type.Assign(format);
|
||||||
|
attribute.size.Assign(size);
|
||||||
|
|
||||||
|
enable_attributes[input_reg] = true;
|
||||||
|
offset += vertex_attributes.GetStride(attribute_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PAddr data_addr =
|
const PAddr data_addr =
|
||||||
@ -282,7 +283,7 @@ void RasterizerVulkan::SetupFixedAttribs() {
|
|||||||
const u32 data_size = sizeof(float) * static_cast<u32>(data.size());
|
const u32 data_size = sizeof(float) * static_cast<u32>(data.size());
|
||||||
std::memcpy(fixed_ptr + offset, data.data(), data_size);
|
std::memcpy(fixed_ptr + offset, data.data(), data_size);
|
||||||
|
|
||||||
VertexAttribute& attribute = layout.attributes[layout.attribute_count++];
|
VertexAttribute& attribute = layout.attributes[reg];
|
||||||
attribute.binding.Assign(layout.binding_count);
|
attribute.binding.Assign(layout.binding_count);
|
||||||
attribute.location.Assign(reg);
|
attribute.location.Assign(reg);
|
||||||
attribute.offset.Assign(offset);
|
attribute.offset.Assign(offset);
|
||||||
@ -300,7 +301,7 @@ void RasterizerVulkan::SetupFixedAttribs() {
|
|||||||
// errors if the shader ever decides to use it.
|
// errors if the shader ever decides to use it.
|
||||||
for (u32 i = 0; i < 16; i++) {
|
for (u32 i = 0; i < 16; i++) {
|
||||||
if (!enable_attributes[i]) {
|
if (!enable_attributes[i]) {
|
||||||
VertexAttribute& attribute = layout.attributes[layout.attribute_count++];
|
VertexAttribute& attribute = layout.attributes[i];
|
||||||
attribute.binding.Assign(layout.binding_count);
|
attribute.binding.Assign(layout.binding_count);
|
||||||
attribute.location.Assign(i);
|
attribute.location.Assign(i);
|
||||||
attribute.offset.Assign(0);
|
attribute.offset.Assign(0);
|
||||||
|
@ -153,7 +153,7 @@ private:
|
|||||||
std::array<bool, 16> enable_attributes{};
|
std::array<bool, 16> enable_attributes{};
|
||||||
std::array<vk::Buffer, 16> vertex_buffers;
|
std::array<vk::Buffer, 16> vertex_buffers;
|
||||||
VertexArrayInfo vertex_info;
|
VertexArrayInfo vertex_info;
|
||||||
PipelineInfo pipeline_info;
|
PipelineInfo pipeline_info{};
|
||||||
|
|
||||||
StreamBuffer stream_buffer; ///< Vertex+Index buffer
|
StreamBuffer stream_buffer; ///< Vertex+Index buffer
|
||||||
StreamBuffer uniform_buffer; ///< Uniform buffer
|
StreamBuffer uniform_buffer; ///< Uniform buffer
|
||||||
|
Loading…
Reference in New Issue
Block a user