Compare commits

...

3 commits

7 changed files with 32 additions and 13 deletions

View file

@ -101,12 +101,14 @@ RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory, Pica::PicaCore&
hw_vao.Create();
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_buffer_alignment);
const GLint max_alignment = std::max(uniform_buffer_alignment, ssbo_buffer_alignment);
uniform_size_aligned_vs_pica =
Common::AlignUp<std::size_t>(sizeof(VSPicaUniformData), uniform_buffer_alignment);
Common::AlignUp<std::size_t>(sizeof(VSPicaUniformData), max_alignment);
uniform_size_aligned_vs =
Common::AlignUp<std::size_t>(sizeof(VSUniformData), uniform_buffer_alignment);
Common::AlignUp<std::size_t>(sizeof(VSUniformData), max_alignment);
uniform_size_aligned_fs =
Common::AlignUp<std::size_t>(sizeof(FSUniformData), uniform_buffer_alignment);
Common::AlignUp<std::size_t>(sizeof(FSUniformData), max_alignment);
// Set vertex attributes for software shader path
state.draw.vertex_array = sw_vao.handle;
@ -1018,8 +1020,9 @@ void RasterizerOpenGL::UploadUniforms(bool accelerate_draw) {
uniform_size_aligned_vs_pica + uniform_size_aligned_vs + uniform_size_aligned_fs;
std::size_t used_bytes = 0;
const GLint max_alignment = std::max(uniform_buffer_alignment, ssbo_buffer_alignment);
const auto [uniforms, offset, invalidate] =
uniform_buffer.Map(uniform_size, uniform_buffer_alignment);
uniform_buffer.Map(uniform_size, max_alignment);
if (vs_data_dirty || invalidate) {
std::memcpy(uniforms + used_bytes, &vs_data, sizeof(vs_data));
@ -1041,7 +1044,7 @@ void RasterizerOpenGL::UploadUniforms(bool accelerate_draw) {
VSPicaUniformData vs_uniforms;
vs_uniforms.SetFromRegs(pica.vs_setup);
std::memcpy(uniforms + used_bytes, &vs_uniforms, sizeof(vs_uniforms));
glBindBufferRange(GL_UNIFORM_BUFFER, UniformBindings::VSPicaData,
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, UniformBindings::VSPicaData,
uniform_buffer.GetHandle(), offset + used_bytes, sizeof(vs_uniforms));
pica.vs_setup.uniforms_dirty = false;
used_bytes += uniform_size_aligned_vs_pica;

View file

@ -121,6 +121,7 @@ private:
OGLStreamBuffer texture_buffer;
OGLStreamBuffer texture_lf_buffer;
GLint uniform_buffer_alignment;
GLint ssbo_buffer_alignment;
std::size_t uniform_size_aligned_vs_pica;
std::size_t uniform_size_aligned_vs;
std::size_t uniform_size_aligned_fs;

View file

@ -231,6 +231,10 @@ public:
return properties.limits.minUniformBufferOffsetAlignment;
}
vk::DeviceSize StorageMinAlignment() const {
return properties.limits.minStorageBufferOffsetAlignment;
}
/// Returns the minimum alignemt required for accessing host-mapped device memory
vk::DeviceSize NonCoherentAtomSize() const {
return properties.limits.nonCoherentAtomSize;

View file

@ -57,7 +57,7 @@ AttribLoadFlags MakeAttribLoadFlag(Pica::PipelineRegs::VertexAttributeFormat for
}
constexpr std::array<vk::DescriptorSetLayoutBinding, 6> BUFFER_BINDINGS = {{
{0, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex},
{0, vk::DescriptorType::eStorageBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex},
{1, vk::DescriptorType::eUniformBufferDynamic, 1,
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eGeometry},
{2, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eFragment},

View file

@ -68,7 +68,9 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, Pica::PicaCore&
runtime{instance, scheduler, renderpass_cache, update_queue, image_count},
res_cache{memory, custom_tex_manager, runtime, regs, renderer},
stream_buffer{instance, scheduler, BUFFER_USAGE, STREAM_BUFFER_SIZE},
uniform_buffer{instance, scheduler, vk::BufferUsageFlagBits::eUniformBuffer,
uniform_buffer{instance, scheduler,
vk::BufferUsageFlagBits::eUniformBuffer |
vk::BufferUsageFlagBits::eStorageBuffer,
UNIFORM_BUFFER_SIZE},
texture_buffer{instance, scheduler, vk::BufferUsageFlagBits::eUniformTexelBuffer,
TextureBufferSize(instance)},
@ -78,10 +80,12 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, Pica::PicaCore&
vertex_buffers.fill(stream_buffer.Handle());
// Query uniform buffer alignment.
// Query buffer alignments.
const vk::DeviceSize vs_pica_alignment =
std::max(instance.UniformMinAlignment(), instance.StorageMinAlignment());
uniform_buffer_alignment = instance.UniformMinAlignment();
uniform_size_aligned_vs_pica =
Common::AlignUp<u32>(sizeof(VSPicaUniformData), uniform_buffer_alignment);
Common::AlignUp<u32>(sizeof(VSPicaUniformData), vs_pica_alignment);
uniform_size_aligned_vs = Common::AlignUp<u32>(sizeof(VSUniformData), uniform_buffer_alignment);
uniform_size_aligned_fs = Common::AlignUp<u32>(sizeof(FSUniformData), uniform_buffer_alignment);
@ -113,7 +117,8 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, Pica::PicaCore&
// Prepare the static buffer descriptor set.
const auto buffer_set = pipeline_cache.Acquire(DescriptorHeapType::Buffer);
update_queue.AddBuffer(buffer_set, 0, uniform_buffer.Handle(), 0, sizeof(VSPicaUniformData));
update_queue.AddBuffer(buffer_set, 0, uniform_buffer.Handle(), 0, sizeof(VSPicaUniformData),
vk::DescriptorType::eStorageBufferDynamic);
update_queue.AddBuffer(buffer_set, 1, uniform_buffer.Handle(), 0, sizeof(VSUniformData));
update_queue.AddBuffer(buffer_set, 2, uniform_buffer.Handle(), 0, sizeof(FSUniformData));
update_queue.AddTexelBuffer(buffer_set, 3, *texture_lf_view);

View file

@ -16,9 +16,9 @@ namespace Pica::Shader::Generator::GLSL {
constexpr std::string_view VSPicaUniformBlockDef = R"(
#ifdef VULKAN
layout (set = 0, binding = 0, std140) uniform vs_pica_data {
layout (set = 0, binding = 0, std430) readonly buffer vs_pica_data {
#else
layout (binding = 0, std140) uniform vs_pica_data {
layout (binding = 0, std430) readonly buffer vs_pica_data {
#endif
uint b;
uvec4 i[4];

View file

@ -72,6 +72,7 @@ void FragmentModule::Generate() {
break;
case TexturingRegs::FogMode::Gas:
WriteGas();
// Return early due to unimplemented gas mode
return;
default:
break;
@ -196,7 +197,12 @@ void FragmentModule::WriteFog() {
void FragmentModule::WriteGas() {
// TODO: Implement me
LOG_CRITICAL(Render, "Unimplemented gas mode");
OpKill();
// Replace the output color with a transparent pixel,
// (just discarding the pixel causes graphical issues
// in some MH games).
OpStore(color_id, ConstF32(0.f, 0.f, 0.f, 0.f));
OpReturn();
OpFunctionEnd();
}