aboutsummaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/engines/maxwell_3d.h7
-rw-r--r--src/video_core/engines/maxwell_dma.cpp6
-rw-r--r--src/video_core/memory_manager.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp22
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp5
5 files changed, 32 insertions, 12 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index b8fb49ddf..ff67f2a58 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -493,7 +493,11 @@ public:
u32 enable[NumRenderTargets];
} blend;
- INSERT_PADDING_WORDS(0x77);
+ INSERT_PADDING_WORDS(0x2D);
+
+ u32 vb_element_base;
+
+ INSERT_PADDING_WORDS(0x49);
struct {
u32 tsc_address_high;
@@ -792,6 +796,7 @@ ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
ASSERT_REG_POSITION(depth_test_func, 0x4C3);
ASSERT_REG_POSITION(blend, 0x4CF);
+ASSERT_REG_POSITION(vb_element_base, 0x50D);
ASSERT_REG_POSITION(tsc, 0x557);
ASSERT_REG_POSITION(tic, 0x55D);
ASSERT_REG_POSITION(code_address, 0x582);
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 442138988..c298f0bfb 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -49,7 +49,11 @@ void MaxwellDMA::HandleCopy() {
ASSERT(regs.src_params.pos_y == 0);
ASSERT(regs.dst_params.pos_x == 0);
ASSERT(regs.dst_params.pos_y == 0);
- ASSERT(regs.exec.is_dst_linear != regs.exec.is_src_linear);
+
+ if (regs.exec.is_dst_linear == regs.exec.is_src_linear) {
+ Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count * regs.y_count);
+ return;
+ }
u8* src_buffer = Memory::GetPointer(source_cpu);
u8* dst_buffer = Memory::GetPointer(dest_cpu);
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 5cefce9fc..2f814a184 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -100,9 +100,9 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
VAddr base_addr = PageSlot(gpu_addr);
- ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
- if (base_addr == static_cast<u64>(PageStatus::Allocated)) {
+ if (base_addr == static_cast<u64>(PageStatus::Allocated) ||
+ base_addr == static_cast<u64>(PageStatus::Unmapped)) {
return {};
}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a3c5ad2a9..ca3814cfc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -415,14 +415,16 @@ void RasterizerOpenGL::DrawArrays() {
const GLenum primitive_mode{MaxwellToGL::PrimitiveTopology(regs.draw.topology)};
if (is_indexed) {
- const GLint index_min{static_cast<GLint>(regs.index_array.first)};
- const GLint index_max{static_cast<GLint>(regs.index_array.first + regs.index_array.count)};
- glDrawRangeElementsBaseVertex(primitive_mode, index_min, index_max, regs.index_array.count,
- MaxwellToGL::IndexFormat(regs.index_array.format),
- reinterpret_cast<const void*>(index_buffer_offset),
- -index_min);
+ const GLint base_vertex{static_cast<GLint>(regs.vb_element_base)};
+
+ // Adjust the index buffer offset so it points to the first desired index.
+ index_buffer_offset += regs.index_array.first * regs.index_array.FormatSizeInBytes();
+
+ glDrawElementsBaseVertex(primitive_mode, regs.index_array.count,
+ MaxwellToGL::IndexFormat(regs.index_array.format),
+ reinterpret_cast<const void*>(index_buffer_offset), base_vertex);
} else {
- glDrawArrays(primitive_mode, 0, regs.vertex_buffer.count);
+ glDrawArrays(primitive_mode, regs.vertex_buffer.first, regs.vertex_buffer.count);
}
// Disable scissor test
@@ -639,7 +641,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program,
glProgramUniform1i(program, uniform, current_bindpoint);
const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset());
- ASSERT(texture.enabled);
+
+ if (!texture.enabled) {
+ state.texture_units[current_bindpoint].texture_2d = 0;
+ continue;
+ }
texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);
Surface surface = res_cache.GetTextureSurface(texture);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 35ad4f161..851ebc263 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -470,6 +470,11 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
return {};
}
+ const auto& gpu = Core::System::GetInstance().GPU();
+ // Don't try to create any entries in the cache if the address of the texture is invalid.
+ if (gpu.memory_manager->GpuToCpuAddress(params.addr) == boost::none)
+ return {};
+
// Check for an exact match in existing surfaces
const auto& surface_key{SurfaceKey::Create(params)};
const auto& search{surface_cache.find(surface_key)};