diff options
-rw-r--r-- | src/common/string_util.cpp | 4 | ||||
-rw-r--r-- | src/common/string_util.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 31 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 31 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 56 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 10 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 9 |
7 files changed, 72 insertions, 71 deletions
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 1d952874d..646400db0 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -64,6 +64,10 @@ std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces return oss.str(); } +std::string StringFromBuffer(const std::vector<u8>& data) { + return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); +} + // Turns " hej " into "hej". Also handles tabs. std::string StripSpaces(const std::string& str) { const size_t s = str.find_first_not_of(" \t\r\n"); diff --git a/src/common/string_util.h b/src/common/string_util.h index 65e4ea5d3..1f5a383cb 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -21,6 +21,8 @@ std::string ToUpper(std::string str); std::string ArrayToString(const u8* data, size_t size, int line_len = 20, bool spaces = true); +std::string StringFromBuffer(const std::vector<u8>& data); + std::string StripSpaces(const std::string& s); std::string StripQuotes(const std::string& s); diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 8a47bb7af..1cf97e876 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -4,6 +4,7 @@ #include <cinttypes> #include "common/logging/log.h" +#include "common/string_util.h" #include "core/core.h" #include "core/file_sys/directory.h" #include "core/file_sys/filesystem.h" @@ -258,9 +259,7 @@ public: IPC::RequestParser rp{ctx}; auto file_buffer = ctx.ReadBuffer(); - auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - - std::string name(file_buffer.begin(), end); + std::string name = Common::StringFromBuffer(file_buffer); u64 mode = rp.Pop<u64>(); u32 size = rp.Pop<u32>(); @@ -275,9 +274,7 @@ public: IPC::RequestParser rp{ctx}; auto file_buffer = ctx.ReadBuffer(); - auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - - std::string name(file_buffer.begin(), end); + std::string name = Common::StringFromBuffer(file_buffer); NGLOG_DEBUG(Service_FS, "called file {}", name); @@ -289,9 +286,7 @@ public: IPC::RequestParser rp{ctx}; auto file_buffer = ctx.ReadBuffer(); - auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - - std::string name(file_buffer.begin(), end); + std::string name = Common::StringFromBuffer(file_buffer); NGLOG_DEBUG(Service_FS, "called directory {}", name); @@ -305,13 +300,11 @@ public: std::vector<u8> buffer; buffer.resize(ctx.BufferDescriptorX()[0].Size()); Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size()); - auto end = std::find(buffer.begin(), buffer.end(), '\0'); - std::string src_name(buffer.begin(), end); + std::string src_name = Common::StringFromBuffer(buffer); buffer.resize(ctx.BufferDescriptorX()[1].Size()); Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size()); - end = std::find(buffer.begin(), buffer.end(), '\0'); - std::string dst_name(buffer.begin(), end); + std::string dst_name = Common::StringFromBuffer(buffer); NGLOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); @@ -323,9 +316,7 @@ public: IPC::RequestParser rp{ctx}; auto file_buffer = ctx.ReadBuffer(); - auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - - std::string name(file_buffer.begin(), end); + std::string name = Common::StringFromBuffer(file_buffer); auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>()); @@ -349,9 +340,7 @@ public: IPC::RequestParser rp{ctx}; auto file_buffer = ctx.ReadBuffer(); - auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - - std::string name(file_buffer.begin(), end); + std::string name = Common::StringFromBuffer(file_buffer); // TODO(Subv): Implement this filter. u32 filter_flags = rp.Pop<u32>(); @@ -376,9 +365,7 @@ public: IPC::RequestParser rp{ctx}; auto file_buffer = ctx.ReadBuffer(); - auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - - std::string name(file_buffer.begin(), end); + std::string name = Common::StringFromBuffer(file_buffer); NGLOG_DEBUG(Service_FS, "called file {}", name); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 56b837372..2dc251205 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -318,6 +318,7 @@ public: Equation equation_a; Factor factor_source_a; Factor factor_dest_a; + INSERT_PADDING_WORDS(1); }; union { @@ -432,7 +433,27 @@ public: }; } rt_control; - INSERT_PADDING_WORDS(0xCF); + INSERT_PADDING_WORDS(0x31); + + u32 independent_blend_enable; + + INSERT_PADDING_WORDS(0x15); + + struct { + u32 separate_alpha; + Blend::Equation equation_rgb; + Blend::Factor factor_source_rgb; + Blend::Factor factor_dest_rgb; + Blend::Equation equation_a; + Blend::Factor factor_source_a; + INSERT_PADDING_WORDS(1); + Blend::Factor factor_dest_a; + + u32 enable_common; + u32 enable[NumRenderTargets]; + } blend; + + INSERT_PADDING_WORDS(0x77); struct { u32 tsc_address_high; @@ -557,9 +578,7 @@ public: } vertex_array[NumVertexArrays]; - Blend blend; - - INSERT_PADDING_WORDS(0x39); + Blend independent_blend[NumRenderTargets]; struct { u32 limit_high; @@ -722,6 +741,8 @@ ASSERT_REG_POSITION(vertex_buffer, 0x35D); ASSERT_REG_POSITION(zeta, 0x3F8); ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); ASSERT_REG_POSITION(rt_control, 0x487); +ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); +ASSERT_REG_POSITION(blend, 0x4CF); ASSERT_REG_POSITION(tsc, 0x557); ASSERT_REG_POSITION(tic, 0x55D); ASSERT_REG_POSITION(code_address, 0x582); @@ -729,7 +750,7 @@ ASSERT_REG_POSITION(draw, 0x585); ASSERT_REG_POSITION(index_array, 0x5F2); ASSERT_REG_POSITION(query, 0x6C0); ASSERT_REG_POSITION(vertex_array[0], 0x700); -ASSERT_REG_POSITION(blend, 0x780); +ASSERT_REG_POSITION(independent_blend, 0x780); ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0); ASSERT_REG_POSITION(shader_config[0], 0x800); ASSERT_REG_POSITION(const_buffer, 0x8E0); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0bd235218..6f05f24a0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -218,6 +218,9 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { ubo.SetFromRegs(gpu.state.shader_stages[stage]); std::memcpy(buffer_ptr, &ubo, sizeof(ubo)); + // Flush the buffer so that the GPU can see the data we just wrote. + glFlushMappedBufferRange(GL_ARRAY_BUFFER, buffer_offset, sizeof(ubo)); + // Upload uniform data as one UBO per stage const GLintptr ubo_offset = buffer_offset; copy_buffer(uniform_buffers[stage].handle, ubo_offset, @@ -346,6 +349,9 @@ void RasterizerOpenGL::DrawArrays() { // Sync the viewport SyncViewport(surfaces_rect, res_scale); + // Sync the blend state registers + SyncBlendState(); + // TODO(bunnei): Sync framebuffer_scale uniform here // TODO(bunnei): Sync scissorbox uniform(s) here @@ -452,32 +458,7 @@ void RasterizerOpenGL::DrawArrays() { } } -void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) { - const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; - switch (method) { - case MAXWELL3D_REG_INDEX(blend.separate_alpha): - ASSERT_MSG(false, "unimplemented"); - break; - case MAXWELL3D_REG_INDEX(blend.equation_rgb): - state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.blend.equation_rgb); - break; - case MAXWELL3D_REG_INDEX(blend.factor_source_rgb): - state.blend.src_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb); - break; - case MAXWELL3D_REG_INDEX(blend.factor_dest_rgb): - state.blend.dst_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb); - break; - case MAXWELL3D_REG_INDEX(blend.equation_a): - state.blend.a_equation = MaxwellToGL::BlendEquation(regs.blend.equation_a); - break; - case MAXWELL3D_REG_INDEX(blend.factor_source_a): - state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_a); - break; - case MAXWELL3D_REG_INDEX(blend.factor_dest_a): - state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.blend.factor_dest_a); - break; - } -} +void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {} void RasterizerOpenGL::FlushAll() { MICROPROFILE_SCOPE(OpenGL_CacheManagement); @@ -757,14 +738,21 @@ void RasterizerOpenGL::SyncDepthOffset() { UNREACHABLE(); } -void RasterizerOpenGL::SyncBlendEnabled() { - UNREACHABLE(); -} +void RasterizerOpenGL::SyncBlendState() { + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + ASSERT_MSG(regs.independent_blend_enable == 1, "Only independent blending is implemented"); -void RasterizerOpenGL::SyncBlendFuncs() { - UNREACHABLE(); -} + // TODO(Subv): Support more than just render target 0. + state.blend.enabled = regs.blend.enable[0] != 0; -void RasterizerOpenGL::SyncBlendColor() { - UNREACHABLE(); + if (!state.blend.enabled) + return; + + ASSERT_MSG(!regs.independent_blend[0].separate_alpha, "Unimplemented"); + state.blend.rgb_equation = MaxwellToGL::BlendEquation(regs.independent_blend[0].equation_rgb); + state.blend.src_rgb_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_source_rgb); + state.blend.dst_rgb_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_dest_rgb); + state.blend.a_equation = MaxwellToGL::BlendEquation(regs.independent_blend[0].equation_a); + state.blend.src_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_source_a); + state.blend.dst_a_func = MaxwellToGL::BlendFunc(regs.independent_blend[0].factor_dest_a); } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index d3f0558ed..b7c8cf843 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -121,14 +121,8 @@ private: /// Syncs the depth offset to match the guest state void SyncDepthOffset(); - /// Syncs the blend enabled status to match the guest state - void SyncBlendEnabled(); - - /// Syncs the blend functions to match the guest state - void SyncBlendFuncs(); - - /// Syncs the blend color to match the guest state - void SyncBlendColor(); + /// Syncs the blend state to match the guest state + void SyncBlendState(); bool has_ARB_buffer_storage; bool has_ARB_direct_state_access; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index df2474ea2..ff48a2669 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1033,8 +1033,11 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu params.addr = config.tic.Address(); params.is_tiled = config.tic.IsTiled(); params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); - params.width = config.tic.Width() / params.GetCompresssionFactor(); - params.height = config.tic.Height() / params.GetCompresssionFactor(); + + params.width = Common::AlignUp(config.tic.Width(), params.GetCompresssionFactor()) / + params.GetCompresssionFactor(); + params.height = Common::AlignUp(config.tic.Height(), params.GetCompresssionFactor()) / + params.GetCompresssionFactor(); // TODO(Subv): Different types per component are not supported. ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && @@ -1045,6 +1048,8 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu if (config.tic.IsTiled()) { params.block_height = config.tic.BlockHeight(); + params.width = Common::AlignUp(params.width, params.block_height); + params.height = Common::AlignUp(params.height, params.block_height); } else { // Use the texture-provided stride value if the texture isn't tiled. params.stride = static_cast<u32>(params.PixelsInBytes(config.tic.Pitch())); |