summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache.h
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-04-24 02:45:03 -0300
committerGravatar ReinUsesLisp2019-06-20 21:36:11 -0300
commit5f3aacdc3760f0e9e0daeda3ee4c55e42fc9397e (patch)
tree6c95776e1de8c347544745df1784424cafaeb414 /src/video_core/texture_cache.h
parenttexture_cache: Flush 3D textures in the order they are drawn (diff)
downloadyuzu-5f3aacdc3760f0e9e0daeda3ee4c55e42fc9397e.tar.gz
yuzu-5f3aacdc3760f0e9e0daeda3ee4c55e42fc9397e.tar.xz
yuzu-5f3aacdc3760f0e9e0daeda3ee4c55e42fc9397e.zip
texture_cache: Move staging buffer into a generic implementation
Diffstat (limited to 'src/video_core/texture_cache.h')
-rw-r--r--src/video_core/texture_cache.h161
1 files changed, 94 insertions, 67 deletions
diff --git a/src/video_core/texture_cache.h b/src/video_core/texture_cache.h
index f22e8e776..90c72cb15 100644
--- a/src/video_core/texture_cache.h
+++ b/src/video_core/texture_cache.h
@@ -273,37 +273,11 @@ struct hash<VideoCommon::ViewKey> {
273 273
274namespace VideoCommon { 274namespace VideoCommon {
275 275
276template <typename TTextureCache, typename TView, typename TExecutionContext> 276class SurfaceBaseImpl {
277class SurfaceBase {
278 static_assert(std::is_trivially_copyable_v<TExecutionContext>);
279
280public: 277public:
281 virtual void LoadBuffer() = 0; 278 void LoadBuffer();
282
283 virtual TExecutionContext FlushBuffer(TExecutionContext exctx) = 0;
284
285 virtual TExecutionContext UploadTexture(TExecutionContext exctx) = 0;
286
287 TView* TryGetView(GPUVAddr view_addr, const SurfaceParams& view_params) {
288 if (view_addr < gpu_addr || !params.IsFamiliar(view_params)) {
289 // It can't be a view if it's in a prior address.
290 return {};
291 }
292
293 const auto relative_offset{static_cast<u64>(view_addr - gpu_addr)};
294 const auto it{view_offset_map.find(relative_offset)};
295 if (it == view_offset_map.end()) {
296 // Couldn't find an aligned view.
297 return {};
298 }
299 const auto [layer, level] = it->second;
300
301 if (!params.IsViewValid(view_params, layer, level)) {
302 return {};
303 }
304 279
305 return GetView(layer, view_params.GetNumLayers(), level, view_params.GetNumLevels()); 280 void FlushBuffer();
306 }
307 281
308 GPUVAddr GetGpuAddr() const { 282 GPUVAddr GetGpuAddr() const {
309 ASSERT(is_registered); 283 ASSERT(is_registered);
@@ -325,27 +299,10 @@ public:
325 return cache_addr; 299 return cache_addr;
326 } 300 }
327 301
328 std::size_t GetSizeInBytes() const {
329 return params.GetGuestSizeInBytes();
330 }
331
332 void MarkAsModified(bool is_modified_) {
333 is_modified = is_modified_;
334 if (is_modified_) {
335 modification_tick = texture_cache.Tick();
336 }
337 }
338
339 const SurfaceParams& GetSurfaceParams() const { 302 const SurfaceParams& GetSurfaceParams() const {
340 return params; 303 return params;
341 } 304 }
342 305
343 TView* GetView(GPUVAddr view_addr, const SurfaceParams& view_params) {
344 TView* view{TryGetView(view_addr, view_params)};
345 ASSERT(view != nullptr);
346 return view;
347 }
348
349 void Register(GPUVAddr gpu_addr_, VAddr cpu_addr_, u8* host_ptr_) { 306 void Register(GPUVAddr gpu_addr_, VAddr cpu_addr_, u8* host_ptr_) {
350 ASSERT(!is_registered); 307 ASSERT(!is_registered);
351 is_registered = true; 308 is_registered = true;
@@ -361,30 +318,95 @@ public:
361 is_registered = false; 318 is_registered = false;
362 } 319 }
363 320
364 u64 GetModificationTick() const {
365 return modification_tick;
366 }
367
368 bool IsRegistered() const { 321 bool IsRegistered() const {
369 return is_registered; 322 return is_registered;
370 } 323 }
371 324
372protected: 325 std::size_t GetSizeInBytes() const {
373 explicit SurfaceBase(TTextureCache& texture_cache, const SurfaceParams& params) 326 return params.GetGuestSizeInBytes();
374 : params{params}, texture_cache{texture_cache}, view_offset_map{ 327 }
375 params.CreateViewOffsetMap()} {}
376 328
377 ~SurfaceBase() = default; 329 u8* GetStagingBufferLevelData(u32 level) {
330 return staging_buffer.data() + params.GetHostMipmapLevelOffset(level);
331 }
332
333protected:
334 explicit SurfaceBaseImpl(const SurfaceParams& params);
335 ~SurfaceBaseImpl(); // non-virtual is intended
378 336
379 virtual void DecorateSurfaceName() = 0; 337 virtual void DecorateSurfaceName() = 0;
380 338
381 virtual std::unique_ptr<TView> CreateView(const ViewKey& view_key) = 0; 339 const SurfaceParams params;
340
341private:
342 GPUVAddr gpu_addr{};
343 VAddr cpu_addr{};
344 u8* host_ptr{};
345 CacheAddr cache_addr{};
346 bool is_registered{};
347
348 std::vector<u8> staging_buffer;
349};
350
351template <typename TTextureCache, typename TView, typename TExecutionContext>
352class SurfaceBase : public SurfaceBaseImpl {
353 static_assert(std::is_trivially_copyable_v<TExecutionContext>);
354
355public:
356 virtual TExecutionContext UploadTexture(TExecutionContext exctx) = 0;
357
358 virtual TExecutionContext DownloadTexture(TExecutionContext exctx) = 0;
359
360 TView* TryGetView(GPUVAddr view_addr, const SurfaceParams& view_params) {
361 if (view_addr < GetGpuAddr() || !params.IsFamiliar(view_params)) {
362 // It can't be a view if it's in a prior address.
363 return {};
364 }
365
366 const auto relative_offset{static_cast<u64>(view_addr - GetGpuAddr())};
367 const auto it{view_offset_map.find(relative_offset)};
368 if (it == view_offset_map.end()) {
369 // Couldn't find an aligned view.
370 return {};
371 }
372 const auto [layer, level] = it->second;
373
374 if (!params.IsViewValid(view_params, layer, level)) {
375 return {};
376 }
377
378 return GetView(layer, view_params.GetNumLayers(), level, view_params.GetNumLevels());
379 }
380
381 void MarkAsModified(bool is_modified_) {
382 is_modified = is_modified_;
383 if (is_modified_) {
384 modification_tick = texture_cache.Tick();
385 }
386 }
387
388 TView* GetView(GPUVAddr view_addr, const SurfaceParams& view_params) {
389 TView* view{TryGetView(view_addr, view_params)};
390 ASSERT(view != nullptr);
391 return view;
392 }
382 393
383 bool IsModified() const { 394 bool IsModified() const {
384 return is_modified; 395 return is_modified;
385 } 396 }
386 397
387 const SurfaceParams params; 398 u64 GetModificationTick() const {
399 return modification_tick;
400 }
401
402protected:
403 explicit SurfaceBase(TTextureCache& texture_cache, const SurfaceParams& params)
404 : SurfaceBaseImpl{params}, texture_cache{texture_cache},
405 view_offset_map{params.CreateViewOffsetMap()} {}
406
407 ~SurfaceBase() = default;
408
409 virtual std::unique_ptr<TView> CreateView(const ViewKey& view_key) = 0;
388 410
389private: 411private:
390 TView* GetView(u32 base_layer, u32 num_layers, u32 base_level, u32 num_levels) { 412 TView* GetView(u32 base_layer, u32 num_layers, u32 base_level, u32 num_levels) {
@@ -400,13 +422,8 @@ private:
400 TTextureCache& texture_cache; 422 TTextureCache& texture_cache;
401 const std::map<u64, std::pair<u32, u32>> view_offset_map; 423 const std::map<u64, std::pair<u32, u32>> view_offset_map;
402 424
403 GPUVAddr gpu_addr{};
404 VAddr cpu_addr{};
405 u8* host_ptr{};
406 CacheAddr cache_addr{};
407 u64 modification_tick{};
408 bool is_modified{}; 425 bool is_modified{};
409 bool is_registered{}; 426 u64 modification_tick{};
410 std::unordered_map<ViewKey, std::unique_ptr<TView>> views; 427 std::unordered_map<ViewKey, std::unique_ptr<TView>> views;
411}; 428};
412 429
@@ -560,7 +577,7 @@ private:
560 if (!fast_view) { 577 if (!fast_view) {
561 // Flush even when we don't care about the contents, to preserve memory not 578 // Flush even when we don't care about the contents, to preserve memory not
562 // written by the new surface. 579 // written by the new surface.
563 exctx = surface->FlushBuffer(exctx); 580 exctx = FlushSurface(exctx, surface);
564 } 581 }
565 Unregister(surface); 582 Unregister(surface);
566 } 583 }
@@ -590,6 +607,16 @@ private:
590 return exctx; 607 return exctx;
591 } 608 }
592 609
610 TExecutionContext FlushSurface(TExecutionContext exctx,
611 const std::shared_ptr<TSurface>& surface) {
612 if (!surface->IsModified()) {
613 return exctx;
614 }
615 exctx = surface->DownloadTexture(exctx);
616 surface->FlushBuffer();
617 return exctx;
618 }
619
593 std::vector<std::shared_ptr<TSurface>> GetSurfacesInRegion(CacheAddr cache_addr, 620 std::vector<std::shared_ptr<TSurface>> GetSurfacesInRegion(CacheAddr cache_addr,
594 std::size_t size) const { 621 std::size_t size) const {
595 if (size == 0) { 622 if (size == 0) {
@@ -701,8 +728,8 @@ private:
701template <typename TTextureCache, typename TView> 728template <typename TTextureCache, typename TView>
702class SurfaceBaseContextless : public SurfaceBase<TTextureCache, TView, DummyExecutionContext> { 729class SurfaceBaseContextless : public SurfaceBase<TTextureCache, TView, DummyExecutionContext> {
703public: 730public:
704 DummyExecutionContext FlushBuffer(DummyExecutionContext) { 731 DummyExecutionContext DownloadTexture(DummyExecutionContext) {
705 FlushBufferImpl(); 732 DownloadTextureImpl();
706 return {}; 733 return {};
707 } 734 }
708 735
@@ -715,7 +742,7 @@ protected:
715 explicit SurfaceBaseContextless(TTextureCache& texture_cache, const SurfaceParams& params) 742 explicit SurfaceBaseContextless(TTextureCache& texture_cache, const SurfaceParams& params)
716 : SurfaceBase<TTextureCache, TView, DummyExecutionContext>{texture_cache, params} {} 743 : SurfaceBase<TTextureCache, TView, DummyExecutionContext>{texture_cache, params} {}
717 744
718 virtual void FlushBufferImpl() = 0; 745 virtual void DownloadTextureImpl() = 0;
719 746
720 virtual void UploadTextureImpl() = 0; 747 virtual void UploadTextureImpl() = 0;
721}; 748};