diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_primitive_assembler.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 6 |
8 files changed, 67 insertions, 47 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 63a958f11..eb9bf1878 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -35,8 +35,10 @@ void DmaPusher::DispatchCalls() { | |||
| 35 | bool DmaPusher::Step() { | 35 | bool DmaPusher::Step() { |
| 36 | if (dma_get != dma_put) { | 36 | if (dma_get != dma_put) { |
| 37 | // Push buffer non-empty, read a word | 37 | // Push buffer non-empty, read a word |
| 38 | const CommandHeader command_header{ | 38 | const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get); |
| 39 | Memory::Read32(*gpu.MemoryManager().GpuToCpuAddress(dma_get))}; | 39 | ASSERT_MSG(address, "Invalid GPU address"); |
| 40 | |||
| 41 | const CommandHeader command_header{Memory::Read32(*address)}; | ||
| 40 | 42 | ||
| 41 | dma_get += sizeof(u32); | 43 | dma_get += sizeof(u32); |
| 42 | 44 | ||
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 80f70e332..9f1533263 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -42,8 +42,10 @@ void Fermi2D::HandleSurfaceCopy() { | |||
| 42 | // TODO(Subv): Only raw copies are implemented. | 42 | // TODO(Subv): Only raw copies are implemented. |
| 43 | ASSERT(regs.operation == Regs::Operation::SrcCopy); | 43 | ASSERT(regs.operation == Regs::Operation::SrcCopy); |
| 44 | 44 | ||
| 45 | const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source); | 45 | const auto source_cpu = memory_manager.GpuToCpuAddress(source); |
| 46 | const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest); | 46 | const auto dest_cpu = memory_manager.GpuToCpuAddress(dest); |
| 47 | ASSERT_MSG(source_cpu, "Invalid source GPU address"); | ||
| 48 | ASSERT_MSG(dest_cpu, "Invalid destination GPU address"); | ||
| 47 | 49 | ||
| 48 | u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format); | 50 | u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format); |
| 49 | u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format); | 51 | u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format); |
| @@ -52,22 +54,22 @@ void Fermi2D::HandleSurfaceCopy() { | |||
| 52 | // All copies here update the main memory, so mark all rasterizer states as invalid. | 54 | // All copies here update the main memory, so mark all rasterizer states as invalid. |
| 53 | Core::System::GetInstance().GPU().Maxwell3D().dirty_flags.OnMemoryWrite(); | 55 | Core::System::GetInstance().GPU().Maxwell3D().dirty_flags.OnMemoryWrite(); |
| 54 | 56 | ||
| 55 | rasterizer.FlushRegion(source_cpu, src_bytes_per_pixel * regs.src.width * regs.src.height); | 57 | rasterizer.FlushRegion(*source_cpu, src_bytes_per_pixel * regs.src.width * regs.src.height); |
| 56 | // We have to invalidate the destination region to evict any outdated surfaces from the | 58 | // We have to invalidate the destination region to evict any outdated surfaces from the |
| 57 | // cache. We do this before actually writing the new data because the destination address | 59 | // cache. We do this before actually writing the new data because the destination address |
| 58 | // might contain a dirty surface that will have to be written back to memory. | 60 | // might contain a dirty surface that will have to be written back to memory. |
| 59 | rasterizer.InvalidateRegion(dest_cpu, | 61 | rasterizer.InvalidateRegion(*dest_cpu, |
| 60 | dst_bytes_per_pixel * regs.dst.width * regs.dst.height); | 62 | dst_bytes_per_pixel * regs.dst.width * regs.dst.height); |
| 61 | 63 | ||
| 62 | if (regs.src.linear == regs.dst.linear) { | 64 | if (regs.src.linear == regs.dst.linear) { |
| 63 | // If the input layout and the output layout are the same, just perform a raw copy. | 65 | // If the input layout and the output layout are the same, just perform a raw copy. |
| 64 | ASSERT(regs.src.BlockHeight() == regs.dst.BlockHeight()); | 66 | ASSERT(regs.src.BlockHeight() == regs.dst.BlockHeight()); |
| 65 | Memory::CopyBlock(dest_cpu, source_cpu, | 67 | Memory::CopyBlock(*dest_cpu, *source_cpu, |
| 66 | src_bytes_per_pixel * regs.dst.width * regs.dst.height); | 68 | src_bytes_per_pixel * regs.dst.width * regs.dst.height); |
| 67 | return; | 69 | return; |
| 68 | } | 70 | } |
| 69 | u8* src_buffer = Memory::GetPointer(source_cpu); | 71 | u8* src_buffer = Memory::GetPointer(*source_cpu); |
| 70 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | 72 | u8* dst_buffer = Memory::GetPointer(*dest_cpu); |
| 71 | if (!regs.src.linear && regs.dst.linear) { | 73 | if (!regs.src.linear && regs.dst.linear) { |
| 72 | // If the input is tiled and the output is linear, deswizzle the input and copy it over. | 74 | // If the input is tiled and the output is linear, deswizzle the input and copy it over. |
| 73 | Texture::CopySwizzledData(regs.src.width, regs.src.height, regs.src.depth, | 75 | Texture::CopySwizzledData(regs.src.width, regs.src.height, regs.src.depth, |
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index 4880191fc..5c1029ddf 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp | |||
| @@ -39,16 +39,17 @@ void KeplerMemory::ProcessData(u32 data) { | |||
| 39 | ASSERT_MSG(regs.exec.linear, "Non-linear uploads are not supported"); | 39 | ASSERT_MSG(regs.exec.linear, "Non-linear uploads are not supported"); |
| 40 | ASSERT(regs.dest.x == 0 && regs.dest.y == 0 && regs.dest.z == 0); | 40 | ASSERT(regs.dest.x == 0 && regs.dest.y == 0 && regs.dest.z == 0); |
| 41 | 41 | ||
| 42 | GPUVAddr address = regs.dest.Address(); | 42 | const GPUVAddr address = regs.dest.Address(); |
| 43 | VAddr dest_address = | 43 | const auto dest_address = |
| 44 | *memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32)); | 44 | memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32)); |
| 45 | ASSERT_MSG(dest_address, "Invalid GPU address"); | ||
| 45 | 46 | ||
| 46 | // We have to invalidate the destination region to evict any outdated surfaces from the cache. | 47 | // We have to invalidate the destination region to evict any outdated surfaces from the cache. |
| 47 | // We do this before actually writing the new data because the destination address might contain | 48 | // We do this before actually writing the new data because the destination address might contain |
| 48 | // a dirty surface that will have to be written back to memory. | 49 | // a dirty surface that will have to be written back to memory. |
| 49 | rasterizer.InvalidateRegion(dest_address, sizeof(u32)); | 50 | rasterizer.InvalidateRegion(*dest_address, sizeof(u32)); |
| 50 | 51 | ||
| 51 | Memory::Write32(dest_address, data); | 52 | Memory::Write32(*dest_address, data); |
| 52 | Core::System::GetInstance().GPU().Maxwell3D().dirty_flags.OnMemoryWrite(); | 53 | Core::System::GetInstance().GPU().Maxwell3D().dirty_flags.OnMemoryWrite(); |
| 53 | 54 | ||
| 54 | state.write_offset++; | 55 | state.write_offset++; |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2cd6d6094..10eae6a65 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -273,7 +273,8 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 273 | GPUVAddr sequence_address = regs.query.QueryAddress(); | 273 | GPUVAddr sequence_address = regs.query.QueryAddress(); |
| 274 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application | 274 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application |
| 275 | // VAddr before writing. | 275 | // VAddr before writing. |
| 276 | std::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address); | 276 | const auto address = memory_manager.GpuToCpuAddress(sequence_address); |
| 277 | ASSERT_MSG(address, "Invalid GPU address"); | ||
| 277 | 278 | ||
| 278 | // TODO(Subv): Support the other query units. | 279 | // TODO(Subv): Support the other query units. |
| 279 | ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, | 280 | ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, |
| @@ -386,14 +387,14 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { | |||
| 386 | 387 | ||
| 387 | void Maxwell3D::ProcessCBData(u32 value) { | 388 | void Maxwell3D::ProcessCBData(u32 value) { |
| 388 | // Write the input value to the current const buffer at the current position. | 389 | // Write the input value to the current const buffer at the current position. |
| 389 | GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); | 390 | const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); |
| 390 | ASSERT(buffer_address != 0); | 391 | ASSERT(buffer_address != 0); |
| 391 | 392 | ||
| 392 | // Don't allow writing past the end of the buffer. | 393 | // Don't allow writing past the end of the buffer. |
| 393 | ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); | 394 | ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); |
| 394 | 395 | ||
| 395 | std::optional<VAddr> address = | 396 | const auto address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); |
| 396 | memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); | 397 | ASSERT_MSG(address, "Invalid GPU address"); |
| 397 | 398 | ||
| 398 | Memory::Write32(*address, value); | 399 | Memory::Write32(*address, value); |
| 399 | dirty_flags.OnMemoryWrite(); | 400 | dirty_flags.OnMemoryWrite(); |
| @@ -403,10 +404,11 @@ void Maxwell3D::ProcessCBData(u32 value) { | |||
| 403 | } | 404 | } |
| 404 | 405 | ||
| 405 | Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | 406 | Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { |
| 406 | GPUVAddr tic_base_address = regs.tic.TICAddress(); | 407 | const GPUVAddr tic_base_address = regs.tic.TICAddress(); |
| 407 | 408 | ||
| 408 | GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); | 409 | const GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); |
| 409 | std::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); | 410 | const auto tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); |
| 411 | ASSERT_MSG(tic_address_cpu, "Invalid GPU address"); | ||
| 410 | 412 | ||
| 411 | Texture::TICEntry tic_entry; | 413 | Texture::TICEntry tic_entry; |
| 412 | Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); | 414 | Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); |
| @@ -415,10 +417,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | |||
| 415 | tic_entry.header_version == Texture::TICHeaderVersion::Pitch, | 417 | tic_entry.header_version == Texture::TICHeaderVersion::Pitch, |
| 416 | "TIC versions other than BlockLinear or Pitch are unimplemented"); | 418 | "TIC versions other than BlockLinear or Pitch are unimplemented"); |
| 417 | 419 | ||
| 418 | auto r_type = tic_entry.r_type.Value(); | 420 | const auto r_type = tic_entry.r_type.Value(); |
| 419 | auto g_type = tic_entry.g_type.Value(); | 421 | const auto g_type = tic_entry.g_type.Value(); |
| 420 | auto b_type = tic_entry.b_type.Value(); | 422 | const auto b_type = tic_entry.b_type.Value(); |
| 421 | auto a_type = tic_entry.a_type.Value(); | 423 | const auto a_type = tic_entry.a_type.Value(); |
| 422 | 424 | ||
| 423 | // TODO(Subv): Different data types for separate components are not supported | 425 | // TODO(Subv): Different data types for separate components are not supported |
| 424 | ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | 426 | ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); |
| @@ -427,10 +429,11 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | |||
| 427 | } | 429 | } |
| 428 | 430 | ||
| 429 | Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { | 431 | Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { |
| 430 | GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); | 432 | const GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); |
| 431 | 433 | ||
| 432 | GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); | 434 | const GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); |
| 433 | std::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); | 435 | const auto tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); |
| 436 | ASSERT_MSG(tsc_address_cpu, "Invalid GPU address"); | ||
| 434 | 437 | ||
| 435 | Texture::TSCEntry tsc_entry; | 438 | Texture::TSCEntry tsc_entry; |
| 436 | Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); | 439 | Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); |
| @@ -452,8 +455,10 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt | |||
| 452 | for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; | 455 | for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; |
| 453 | current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { | 456 | current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { |
| 454 | 457 | ||
| 455 | Texture::TextureHandle tex_handle{ | 458 | const auto address = memory_manager.GpuToCpuAddress(current_texture); |
| 456 | Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))}; | 459 | ASSERT_MSG(address, "Invalid GPU address"); |
| 460 | |||
| 461 | const Texture::TextureHandle tex_handle{Memory::Read32(*address)}; | ||
| 457 | 462 | ||
| 458 | Texture::FullTextureInfo tex_info{}; | 463 | Texture::FullTextureInfo tex_info{}; |
| 459 | // TODO(Subv): Use the shader to determine which textures are actually accessed. | 464 | // TODO(Subv): Use the shader to determine which textures are actually accessed. |
| @@ -483,12 +488,15 @@ Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, | |||
| 483 | auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index]; | 488 | auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index]; |
| 484 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | 489 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); |
| 485 | 490 | ||
| 486 | GPUVAddr tex_info_address = tex_info_buffer.address + offset * sizeof(Texture::TextureHandle); | 491 | const GPUVAddr tex_info_address = |
| 492 | tex_info_buffer.address + offset * sizeof(Texture::TextureHandle); | ||
| 487 | 493 | ||
| 488 | ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size); | 494 | ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size); |
| 489 | 495 | ||
| 490 | std::optional<VAddr> tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address); | 496 | const auto tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address); |
| 491 | Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)}; | 497 | ASSERT_MSG(tex_address_cpu, "Invalid GPU address"); |
| 498 | |||
| 499 | const Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)}; | ||
| 492 | 500 | ||
| 493 | Texture::FullTextureInfo tex_info{}; | 501 | Texture::FullTextureInfo tex_info{}; |
| 494 | tex_info.index = static_cast<u32>(offset); | 502 | tex_info.index = static_cast<u32>(offset); |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 06462f570..d6c41a5ae 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -39,8 +39,10 @@ void MaxwellDMA::HandleCopy() { | |||
| 39 | const GPUVAddr source = regs.src_address.Address(); | 39 | const GPUVAddr source = regs.src_address.Address(); |
| 40 | const GPUVAddr dest = regs.dst_address.Address(); | 40 | const GPUVAddr dest = regs.dst_address.Address(); |
| 41 | 41 | ||
| 42 | const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source); | 42 | const auto source_cpu = memory_manager.GpuToCpuAddress(source); |
| 43 | const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest); | 43 | const auto dest_cpu = memory_manager.GpuToCpuAddress(dest); |
| 44 | ASSERT_MSG(source_cpu, "Invalid source GPU address"); | ||
| 45 | ASSERT_MSG(dest_cpu, "Invalid destination GPU address"); | ||
| 44 | 46 | ||
| 45 | // TODO(Subv): Perform more research and implement all features of this engine. | 47 | // TODO(Subv): Perform more research and implement all features of this engine. |
| 46 | ASSERT(regs.exec.enable_swizzle == 0); | 48 | ASSERT(regs.exec.enable_swizzle == 0); |
| @@ -64,7 +66,7 @@ void MaxwellDMA::HandleCopy() { | |||
| 64 | // buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count, | 66 | // buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count, |
| 65 | // y_count). | 67 | // y_count). |
| 66 | if (!regs.exec.enable_2d) { | 68 | if (!regs.exec.enable_2d) { |
| 67 | Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count); | 69 | Memory::CopyBlock(*dest_cpu, *source_cpu, regs.x_count); |
| 68 | return; | 70 | return; |
| 69 | } | 71 | } |
| 70 | 72 | ||
| @@ -73,8 +75,8 @@ void MaxwellDMA::HandleCopy() { | |||
| 73 | // rectangle. There is no need to manually flush/invalidate the regions because | 75 | // rectangle. There is no need to manually flush/invalidate the regions because |
| 74 | // CopyBlock does that for us. | 76 | // CopyBlock does that for us. |
| 75 | for (u32 line = 0; line < regs.y_count; ++line) { | 77 | for (u32 line = 0; line < regs.y_count; ++line) { |
| 76 | const VAddr source_line = source_cpu + line * regs.src_pitch; | 78 | const VAddr source_line = *source_cpu + line * regs.src_pitch; |
| 77 | const VAddr dest_line = dest_cpu + line * regs.dst_pitch; | 79 | const VAddr dest_line = *dest_cpu + line * regs.dst_pitch; |
| 78 | Memory::CopyBlock(dest_line, source_line, regs.x_count); | 80 | Memory::CopyBlock(dest_line, source_line, regs.x_count); |
| 79 | } | 81 | } |
| 80 | return; | 82 | return; |
| @@ -87,12 +89,12 @@ void MaxwellDMA::HandleCopy() { | |||
| 87 | const auto FlushAndInvalidate = [&](u32 src_size, u64 dst_size) { | 89 | const auto FlushAndInvalidate = [&](u32 src_size, u64 dst_size) { |
| 88 | // TODO(Subv): For now, manually flush the regions until we implement GPU-accelerated | 90 | // TODO(Subv): For now, manually flush the regions until we implement GPU-accelerated |
| 89 | // copying. | 91 | // copying. |
| 90 | rasterizer.FlushRegion(source_cpu, src_size); | 92 | rasterizer.FlushRegion(*source_cpu, src_size); |
| 91 | 93 | ||
| 92 | // We have to invalidate the destination region to evict any outdated surfaces from the | 94 | // We have to invalidate the destination region to evict any outdated surfaces from the |
| 93 | // cache. We do this before actually writing the new data because the destination address | 95 | // cache. We do this before actually writing the new data because the destination address |
| 94 | // might contain a dirty surface that will have to be written back to memory. | 96 | // might contain a dirty surface that will have to be written back to memory. |
| 95 | rasterizer.InvalidateRegion(dest_cpu, dst_size); | 97 | rasterizer.InvalidateRegion(*dest_cpu, dst_size); |
| 96 | }; | 98 | }; |
| 97 | 99 | ||
| 98 | if (regs.exec.is_dst_linear && !regs.exec.is_src_linear) { | 100 | if (regs.exec.is_dst_linear && !regs.exec.is_src_linear) { |
| @@ -105,8 +107,8 @@ void MaxwellDMA::HandleCopy() { | |||
| 105 | copy_size * src_bytes_per_pixel); | 107 | copy_size * src_bytes_per_pixel); |
| 106 | 108 | ||
| 107 | Texture::UnswizzleSubrect(regs.x_count, regs.y_count, regs.dst_pitch, | 109 | Texture::UnswizzleSubrect(regs.x_count, regs.y_count, regs.dst_pitch, |
| 108 | regs.src_params.size_x, src_bytes_per_pixel, source_cpu, dest_cpu, | 110 | regs.src_params.size_x, src_bytes_per_pixel, *source_cpu, |
| 109 | regs.src_params.BlockHeight(), regs.src_params.pos_x, | 111 | *dest_cpu, regs.src_params.BlockHeight(), regs.src_params.pos_x, |
| 110 | regs.src_params.pos_y); | 112 | regs.src_params.pos_y); |
| 111 | } else { | 113 | } else { |
| 112 | ASSERT(regs.dst_params.size_z == 1); | 114 | ASSERT(regs.dst_params.size_z == 1); |
| @@ -119,7 +121,7 @@ void MaxwellDMA::HandleCopy() { | |||
| 119 | 121 | ||
| 120 | // If the input is linear and the output is tiled, swizzle the input and copy it over. | 122 | // If the input is linear and the output is tiled, swizzle the input and copy it over. |
| 121 | Texture::SwizzleSubrect(regs.x_count, regs.y_count, regs.src_pitch, regs.dst_params.size_x, | 123 | Texture::SwizzleSubrect(regs.x_count, regs.y_count, regs.src_pitch, regs.dst_params.size_x, |
| 122 | src_bpp, dest_cpu, source_cpu, regs.dst_params.BlockHeight()); | 124 | src_bpp, *dest_cpu, *source_cpu, regs.dst_params.BlockHeight()); |
| 123 | } | 125 | } |
| 124 | } | 126 | } |
| 125 | 127 | ||
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index bd2b30e77..b3062e5ba 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -19,7 +19,8 @@ OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size) | |||
| 19 | GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, | 19 | GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, |
| 20 | std::size_t alignment, bool cache) { | 20 | std::size_t alignment, bool cache) { |
| 21 | auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); | 21 | auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); |
| 22 | const std::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; | 22 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; |
| 23 | ASSERT_MSG(cpu_addr, "Invalid GPU address"); | ||
| 23 | 24 | ||
| 24 | // Cache management is a big overhead, so only cache entries with a given size. | 25 | // Cache management is a big overhead, so only cache entries with a given size. |
| 25 | // TODO: Figure out which size is the best for given games. | 26 | // TODO: Figure out which size is the best for given games. |
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp index d9ed08437..77d5cedd2 100644 --- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp +++ b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp | |||
| @@ -46,7 +46,9 @@ GLintptr PrimitiveAssembler::MakeQuadIndexed(Tegra::GPUVAddr gpu_addr, std::size | |||
| 46 | auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size); | 46 | auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size); |
| 47 | 47 | ||
| 48 | auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); | 48 | auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); |
| 49 | const std::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; | 49 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; |
| 50 | ASSERT_MSG(cpu_addr, "Invalid GPU address"); | ||
| 51 | |||
| 50 | const u8* source{Memory::GetPointer(*cpu_addr)}; | 52 | const u8* source{Memory::GetPointer(*cpu_addr)}; |
| 51 | 53 | ||
| 52 | for (u32 primitive = 0; primitive < count / 4; ++primitive) { | 54 | for (u32 primitive = 0; primitive < count / 4; ++primitive) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 90eda7814..6174f7074 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -23,8 +23,10 @@ using VideoCommon::Shader::ProgramCode; | |||
| 23 | static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { | 23 | static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { |
| 24 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | 24 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |
| 25 | const auto& shader_config = gpu.regs.shader_config[static_cast<std::size_t>(program)]; | 25 | const auto& shader_config = gpu.regs.shader_config[static_cast<std::size_t>(program)]; |
| 26 | return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + | 26 | const auto address = gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + |
| 27 | shader_config.offset); | 27 | shader_config.offset); |
| 28 | ASSERT_MSG(address, "Invalid GPU address"); | ||
| 29 | return *address; | ||
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | /// Gets the shader program code from memory for the specified address | 32 | /// Gets the shader program code from memory for the specified address |