From cef16e94c391047bc4fb6b0e8fb4c731149acc8d Mon Sep 17 00:00:00 2001
From: Timothy Strelchun <Timothy.Strelchun@Intel.Com>
Date: Sun, 15 May 2011 02:32:40 -0700
Subject: [PATCH] GPU system memory support cache flushing mods.
 Made changes necessary in the dfb_surface_buffer_lock function to handle GPU based reading
 or writing support for local and system memory based surface buffers (as well ones in user
 pre-allocated memory).  Previously, when a GPU read/write was requested, the CPU memory
 cache was not flushed when the CPU had only read from the memory.  Changes require
 validation on traditional non-UMA based graphics drivers.

Updated the dfb_surface_pool_allocate function to alway mark brand new CoreSurfaceAllocations
as having been both read and written to by the CPU.  Updated the allocation_update_copy
function to track that the CPU wrote to the destination buffer allocation and that it read
from the source buffer allocation so that proper cache flushing will occur.
---
 src/core/surface_buffer.c |   28 +++++++++++++++++++++-------
 src/core/surface_pool.c   |    7 +++++++
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/src/core/surface_buffer.c b/src/core/surface_buffer.c
index dca6cf8..58892a7 100644
--- a/src/core/surface_buffer.c
+++ b/src/core/surface_buffer.c
@@ -1,5 +1,5 @@
 /*
-   (c) Copyright 2001-2010  The world wide DirectFB Open Source Community (directfb.org)
+   (c) Copyright 2001-2011  The world wide DirectFB Open Source Community (directfb.org)
    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
 
    All rights reserved.
@@ -333,16 +333,23 @@ dfb_surface_buffer_lock( CoreSurfaceBuffer      *buffer,
           }
      }
 
-     /* Hardware read access... */
-     if (accessor == CSAID_GPU && access & CSAF_READ) {
-          /* ...if software has written before... */
-          if (allocation->accessed[CSAID_CPU] & CSAF_WRITE) {
+     /* Hardware read or write access... */
+     if (accessor == CSAID_GPU && access & (CSAF_READ | CSAF_WRITE)) {
+          /* ...if software has read or written before... */
+          /* 
+               TODO:  For graphics drivers that do not support internal surface usage,
+               probably do NOT want to test the CSAF_WRITE flag in the following if
+               condition if the allocation's associated pool does NOT have the GPU
+               read/write flags set as supported.
+          */
+          if (allocation->accessed[CSAID_CPU] & (CSAF_READ | CSAF_WRITE)) {
                /* ...flush texture cache. */
+               /* TODO:  Optimize by providing "lock" to graphics driver flush function. */
                dfb_gfxcard_flush_texture_cache();
 
-               /* ...clear software write access. */
+               /* ...clear software read and write access. */
                if (!buffer->locked)
-                    allocation->accessed[CSAID_CPU] &= ~CSAF_WRITE;
+                    allocation->accessed[CSAID_CPU] &= ~(CSAF_READ | CSAF_WRITE);
           }
      }
 
@@ -1070,6 +1077,13 @@ allocation_update_copy( CoreSurfaceAllocation *allocation,
 
      transfer_buffer( buffer, src.addr, dst.addr, src.pitch, dst.pitch );
 
+     /*
+          Track that the CPU wrote to the destination buffer allocation and that it read
+          from the source buffer allocation so that proper cache flushing will occur.
+     */
+     allocation->accessed[CSAID_CPU] |= CSAF_WRITE;
+     source->accessed[CSAID_CPU] |= CSAF_READ;
+
      dfb_surface_pool_unlock( allocation->pool, allocation, &dst );
      dfb_surface_pool_unlock( source->pool, source, &src );
 
diff --git a/src/core/surface_pool.c b/src/core/surface_pool.c
index 388613b..34bb604 100644
--- a/src/core/surface_pool.c
+++ b/src/core/surface_pool.c
@@ -638,6 +638,13 @@ dfb_surface_pool_allocate( CoreSurfacePool        *pool,
           fusion_vector_add( &pool->allocs, allocation );
      }
 
+     /*
+          Mark the CoreSurfaceAllocation as having been read and written to by the CPU because it is
+          possible the CPU cache after allocation has some data due to a read/write performed as
+          part of allocation.
+     */
+     allocation->accessed[CSAID_CPU] |= CSAF_READ | CSAF_WRITE;
+
      direct_serial_init( &allocation->serial );
 
      fusion_skirmish_dismiss( &pool->lock );
-- 
1.6.0.6

