iris: Defines for base addresses rather than numbers everywhere
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 21 Apr 2018 01:44:22 +0000 (18:44 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:06 +0000 (10:26 -0800)
src/gallium/drivers/iris/iris_binder.h
src/gallium/drivers/iris/iris_bufmgr.c
src/gallium/drivers/iris/iris_bufmgr.h
src/gallium/drivers/iris/iris_state.c

index 7a26602bf48ead39e98c6f480247e5667dec517f..5830288b5c570708f745fbc701fa02d46ba1ca92 100644 (file)
@@ -30,8 +30,6 @@
 struct iris_bo;
 struct iris_bufmgr;
 
-#define IRIS_BINDER_ADDRESS (1ull << 32)
-
 struct iris_binder
 {
    struct iris_bo *bo;
index 023d9720558c781d783d17b172b9c31a4368a18a..3c7ce9f5bcf2e336ba438b7e16234b5574c68996 100644 (file)
@@ -229,19 +229,22 @@ bucket_for_size(struct iris_bufmgr *bufmgr, uint64_t size)
 static enum iris_memory_zone
 memzone_for_address(uint64_t address)
 {
-   const uint64_t _4GB = 1ull << 32;
+   STATIC_ASSERT(IRIS_MEMZONE_OTHER_START > IRIS_MEMZONE_DYNAMIC_START);
+   STATIC_ASSERT(IRIS_MEMZONE_DYNAMIC_START > IRIS_MEMZONE_SURFACE_START);
+   STATIC_ASSERT(IRIS_MEMZONE_SURFACE_START > IRIS_MEMZONE_SHADER_START);
+   STATIC_ASSERT(IRIS_BINDER_ADDRESS == IRIS_MEMZONE_SURFACE_START);
 
-   if (address >= 3 * _4GB)
+   if (address >= IRIS_MEMZONE_OTHER_START)
       return IRIS_MEMZONE_OTHER;
 
-   if (address >= 2 * _4GB)
+   if (address >= IRIS_MEMZONE_DYNAMIC_START)
       return IRIS_MEMZONE_DYNAMIC;
 
-   if (address > 1 * _4GB)
+   /* Use > to exclude the binder */
+   if (address > IRIS_MEMZONE_SURFACE_START)
       return IRIS_MEMZONE_SURFACE;
 
-   /* The binder isn't in any memory zone. */
-   if (address == 1 * _4GB)
+   if (address == IRIS_BINDER_ADDRESS)
       return IRIS_MEMZONE_BINDER;
 
    return IRIS_MEMZONE_SHADER;
@@ -1537,16 +1540,18 @@ iris_bufmgr_init(struct gen_device_info *devinfo, int fd)
 
    bufmgr->has_llc = devinfo->has_llc;
 
+   STATIC_ASSERT(IRIS_MEMZONE_SHADER_START == 0ull);
    const uint64_t _4GB = 1ull << 32;
 
    util_vma_heap_init(&bufmgr->vma_allocator[IRIS_MEMZONE_SHADER],
                       PAGE_SIZE, _4GB);
    util_vma_heap_init(&bufmgr->vma_allocator[IRIS_MEMZONE_SURFACE],
-                      1 * _4GB, _4GB);
+                      IRIS_MEMZONE_SURFACE_START, _4GB);
    util_vma_heap_init(&bufmgr->vma_allocator[IRIS_MEMZONE_DYNAMIC],
-                      2 * _4GB, _4GB);
+                      IRIS_MEMZONE_DYNAMIC_START, _4GB);
    util_vma_heap_init(&bufmgr->vma_allocator[IRIS_MEMZONE_OTHER],
-                      3 * _4GB, (1ull << 48) - 3 * _4GB);
+                      IRIS_MEMZONE_OTHER_START,
+                      (1ull << 48) - IRIS_MEMZONE_OTHER_START);
 
    // XXX: driconf
    bufmgr->bo_reuse = env_var_as_boolean("bo_reuse", true);
index eb2148da3f59da0664676d6a3a8fa0c00c53e51f..48ea7da9a5ff2ca217c3268069841281aee24f5f 100644 (file)
 struct gen_device_info;
 struct pipe_debug_callback;
 
+/**
+ * Memory zones.  When allocating a buffer, you can request that it is
+ * placed into a specific region of the virtual address space (PPGTT).
+ *
+ * Most buffers can go anywhere (IRIS_MEMZONE_OTHER).  Some buffers are
+ * accessed via an offset from a base address.  STATE_BASE_ADDRESS has
+ * a maximum 4GB size for each region, so we need to restrict those
+ * buffers to be within 4GB of the base.  Each memory zone corresponds
+ * to a particular base address.
+ *
+ * We lay out the virtual address space as follows:
+ *
+ * - [0,   4K): Nothing  (empty page for null address)
+ * - [4K,  4G): Shaders  (Instruction Base Address)
+ * - [4G,  8G): Surfaces (Surface State Base Address, Bindless ...)
+ * - [8G, 12G): Dynamic  (Dynamic State Base Address)
+ * - [12G, *):  Other    (everything else in the full 48-bit VMA)
+ *
+ * A special 64kB "binder" buffer lives at the start of the surface memory
+ * zone, holding binding tables referring to objects in the rest of the zone.
+ *
+ * Each GL context uses a separate GEM context, which technically gives them
+ * each a separate VMA.  However, we assign address globally, so buffers will
+ * have the same address in all GEM contexts.  This lets us have a single BO
+ * field for the address, which is easy and cheap.
+ *
+ * One exception is the special "binder" BO.  Binders are context-local,
+ * so while there are many of them, all binders are stored at the same
+ * fixed address (in different VMAs).
+ */
 enum iris_memory_zone {
-   IRIS_MEMZONE_DYNAMIC,
-   IRIS_MEMZONE_SURFACE,
    IRIS_MEMZONE_SHADER,
+   IRIS_MEMZONE_SURFACE,
+   IRIS_MEMZONE_DYNAMIC,
    IRIS_MEMZONE_OTHER,
 
    IRIS_MEMZONE_BINDER,
@@ -48,6 +78,13 @@ enum iris_memory_zone {
 /* Intentionally exclude IRIS_MEMZONE_BINDER */
 #define IRIS_MEMZONE_COUNT (IRIS_MEMZONE_OTHER + 1)
 
+#define IRIS_MEMZONE_SHADER_START     (0 * (1ull << 32))
+#define IRIS_MEMZONE_SURFACE_START    (1 * (1ull << 32))
+#define IRIS_MEMZONE_DYNAMIC_START    (2 * (1ull << 32))
+#define IRIS_MEMZONE_OTHER_START      (3 * (1ull << 32))
+
+#define IRIS_BINDER_ADDRESS IRIS_MEMZONE_SURFACE_START
+
 struct iris_bo {
    /**
     * Size in bytes of the buffer object.
index f1ea9a49b132dd6c3a3ffe478e35f137150caf1e..38c5f9c03f383caae07ff566d369863fc5e592a3 100644 (file)
@@ -361,8 +361,9 @@ iris_init_render_context(struct iris_screen *screen,
       sba.IndirectObjectBufferSizeModifyEnable  = true;
       sba.InstructionBuffersizeModifyEnable     = true;
 
-      sba.SurfaceStateBaseAddress = ro_bo(NULL, 1ull << 32);
-      sba.DynamicStateBaseAddress = ro_bo(NULL, 2 * (1ull << 32));
+      sba.InstructionBaseAddress  = ro_bo(NULL, IRIS_MEMZONE_SHADER_START);
+      sba.SurfaceStateBaseAddress = ro_bo(NULL, IRIS_MEMZONE_SURFACE_START);
+      sba.DynamicStateBaseAddress = ro_bo(NULL, IRIS_MEMZONE_DYNAMIC_START);
 
       sba.GeneralStateBufferSize   = 0xfffff;
       sba.IndirectObjectBufferSize = 0xfffff;