#define VG(x)
#endif
+#include "common/gen_clflush.h"
#include "common/gen_device_info.h"
#include "blorp/blorp.h"
#include "compiler/brw_compiler.h"
#include "util/macros.h"
#include "util/list.h"
+#include "util/u_atomic.h"
#include "util/u_vector.h"
-#include "util/vk_alloc.h"
+#include "vk_alloc.h"
/* Pre-declarations needed for WSI entrypoints */
struct wl_surface;
struct anv_buffer;
struct anv_buffer_view;
struct anv_image_view;
+struct anv_instance;
+struct anv_debug_report_callback;
struct gen_l3_config;
*/
#define ANV_HZ_FC_VAL 1.0f
-#define MAX_VBS 31
+#define MAX_VBS 28
#define MAX_SETS 8
#define MAX_RTS 8
#define MAX_VIEWPORTS 16
memcpy((dest), (src), (count) * sizeof(*(src))); \
})
+/* Mapping from anv object to VkDebugReportObjectTypeEXT. New types need
+ * to be added here in order to utilize mapping in debug/error/perf macros.
+ */
+#define REPORT_OBJECT_TYPE(o) \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_instance*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_physical_device*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_device*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), const struct anv_device*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_queue*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_semaphore*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_cmd_buffer*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_fence*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_device_memory*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_buffer*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_image*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), const struct anv_image*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_event*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_query_pool*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_buffer_view*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_image_view*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_shader_module*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_pipeline_cache*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_pipeline_layout*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_render_pass*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_pipeline*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_descriptor_set_layout*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_sampler*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_descriptor_pool*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_descriptor_set*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_framebuffer*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_cmd_pool*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_surface*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct wsi_swapchain*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), struct anv_debug_callback*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, \
+ __builtin_choose_expr ( \
+ __builtin_types_compatible_p (__typeof (o), void*), \
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, \
+ /* The void expression results in a compile-time error \
+ when assigning the result to something. */ \
+ (void)0)))))))))))))))))))))))))))))))
+
/* Whenever we generate an error, pass it through this function. Useful for
* debugging, where we can break on it. Only call at error site, not when
* propagating errors. Might be useful to plug in a stack trace here.
*/
-VkResult __vk_errorf(VkResult error, const char *file, int line, const char *format, ...);
+VkResult __vk_errorf(struct anv_instance *instance, const void *object,
+ VkDebugReportObjectTypeEXT type, VkResult error,
+ const char *file, int line, const char *format, ...);
#ifdef DEBUG
-#define vk_error(error) __vk_errorf(error, __FILE__, __LINE__, NULL);
-#define vk_errorf(error, format, ...) __vk_errorf(error, __FILE__, __LINE__, format, ## __VA_ARGS__);
+#define vk_error(error) __vk_errorf(NULL, NULL,\
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,\
+ error, __FILE__, __LINE__, NULL);
+#define vk_errorf(instance, obj, error, format, ...)\
+ __vk_errorf(instance, obj, REPORT_OBJECT_TYPE(obj), error,\
+ __FILE__, __LINE__, format, ## __VA_ARGS__);
#define anv_debug(format, ...) fprintf(stderr, "debug: " format, ##__VA_ARGS__)
#else
#define vk_error(error) error
void __anv_finishme(const char *file, int line, const char *format, ...)
anv_printflike(3, 4);
-void __anv_perf_warn(const char *file, int line, const char *format, ...)
- anv_printflike(3, 4);
+void __anv_perf_warn(struct anv_instance *instance, const void *object,
+ VkDebugReportObjectTypeEXT type, const char *file,
+ int line, const char *format, ...)
+ anv_printflike(6, 7);
void anv_loge(const char *format, ...) anv_printflike(1, 2);
void anv_loge_v(const char *format, va_list va);
+void anv_debug_report(struct anv_instance *instance,
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT object_type,
+ uint64_t handle,
+ size_t location,
+ int32_t messageCode,
+ const char* pLayerPrefix,
+ const char *pMessage);
+
/**
* Print a FINISHME message, including its source location.
*/
/**
* Print a perf warning message. Set INTEL_DEBUG=perf to see these.
*/
-#define anv_perf_warn(format, ...) \
+#define anv_perf_warn(instance, obj, format, ...) \
do { \
static bool reported = false; \
if (!reported && unlikely(INTEL_DEBUG & DEBUG_PERF)) { \
- __anv_perf_warn(__FILE__, __LINE__, format, ##__VA_ARGS__); \
+ __anv_perf_warn(instance, obj, REPORT_OBJECT_TYPE(obj), __FILE__, __LINE__,\
+ format, ##__VA_ARGS__); \
reported = true; \
} \
} while (0)
return anv_multialloc_alloc(ma, alloc ? alloc : parent_alloc, scope);
}
-/**
- * A dynamically growable, circular buffer. Elements are added at head and
- * removed from tail. head and tail are free-running uint32_t indices and we
- * only compute the modulo with size when accessing the array. This way,
- * number of bytes in the queue is always head - tail, even in case of
- * wraparound.
- */
-
struct anv_bo {
uint32_t gem_handle;
*/
struct u_vector mmap_cleanups;
- union anv_free_list free_list;
struct anv_block_state state;
- union anv_free_list back_free_list;
struct anv_block_state back_state;
};
#define ANV_STATE_BUCKETS (ANV_MAX_STATE_SIZE_LOG2 - ANV_MIN_STATE_SIZE_LOG2 + 1)
struct anv_state_pool {
- struct anv_block_pool *block_pool;
+ struct anv_block_pool block_pool;
/* The size of blocks which will be allocated from the block pool */
uint32_t block_size;
struct anv_state_stream_block *block_list;
};
-#define CACHELINE_SIZE 64
-#define CACHELINE_MASK 63
-
-static inline void
-anv_clflush_range(void *start, size_t size)
-{
- void *p = (void *) (((uintptr_t) start) & ~CACHELINE_MASK);
- void *end = start + size;
-
- while (p < end) {
- __builtin_ia32_clflush(p);
- p += CACHELINE_SIZE;
- }
-}
-
-static inline void
-anv_flush_range(void *start, size_t size)
-{
- __builtin_ia32_mfence();
- anv_clflush_range(start, size);
-}
-
-static inline void
-anv_invalidate_range(void *start, size_t size)
-{
- anv_clflush_range(start, size);
- __builtin_ia32_mfence();
-}
-
+/* The block_pool functions exported for testing only. The block pool should
+ * only be used via a state pool (see below).
+ */
VkResult anv_block_pool_init(struct anv_block_pool *pool,
struct anv_device *device,
uint32_t initial_size);
uint32_t block_size);
int32_t anv_block_pool_alloc_back(struct anv_block_pool *pool,
uint32_t block_size);
-void anv_block_pool_free(struct anv_block_pool *pool, int32_t offset);
-void anv_state_pool_init(struct anv_state_pool *pool,
- struct anv_block_pool *block_pool,
- uint32_t block_size);
+
+VkResult anv_state_pool_init(struct anv_state_pool *pool,
+ struct anv_device *device,
+ uint32_t block_size);
void anv_state_pool_finish(struct anv_state_pool *pool);
struct anv_state anv_state_pool_alloc(struct anv_state_pool *pool,
uint32_t state_size, uint32_t alignment);
struct anv_bo_cache *cache,
struct anv_bo *bo);
+struct anv_memory_type {
+ /* Standard bits passed on to the client */
+ VkMemoryPropertyFlags propertyFlags;
+ uint32_t heapIndex;
+
+ /* Driver-internal book-keeping */
+ VkBufferUsageFlags valid_buffer_usage;
+};
+
+struct anv_memory_heap {
+ /* Standard bits passed on to the client */
+ VkDeviceSize size;
+ VkMemoryHeapFlags flags;
+
+ /* Driver-internal book-keeping */
+ bool supports_48bit_addresses;
+};
+
struct anv_physical_device {
VK_LOADER_DATA _loader_data;
* practically unlimited. However, we will never report more than 3/4 of
* the total system ram to try and avoid running out of RAM.
*/
- uint64_t heap_size;
bool supports_48bit_addresses;
struct brw_compiler * compiler;
struct isl_device isl_dev;
int cmd_parser_version;
bool has_exec_async;
+ bool has_exec_fence;
+ bool has_syncobj;
+ bool has_syncobj_wait;
uint32_t eu_total;
uint32_t subslice_total;
+ struct {
+ uint32_t type_count;
+ struct anv_memory_type types[VK_MAX_MEMORY_TYPES];
+ uint32_t heap_count;
+ struct anv_memory_heap heaps[VK_MAX_MEMORY_HEAPS];
+ } memory;
+
uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
uint8_t driver_uuid[VK_UUID_SIZE];
uint8_t device_uuid[VK_UUID_SIZE];
int local_fd;
};
+struct anv_debug_report_callback {
+ /* Link in the 'callbacks' list in anv_instance struct. */
+ struct list_head link;
+ VkDebugReportFlagsEXT flags;
+ PFN_vkDebugReportCallbackEXT callback;
+ void * data;
+};
+
struct anv_instance {
VK_LOADER_DATA _loader_data;
uint32_t apiVersion;
int physicalDeviceCount;
struct anv_physical_device physicalDevice;
+
+ /* VK_EXT_debug_report debug callbacks */
+ pthread_mutex_t callbacks_mutex;
+ struct list_head callbacks;
+ struct anv_debug_report_callback destroy_debug_cb;
};
VkResult anv_init_wsi(struct anv_physical_device *physical_device);
void anv_finish_wsi(struct anv_physical_device *physical_device);
+bool anv_instance_extension_supported(const char *name);
+uint32_t anv_physical_device_api_version(struct anv_physical_device *dev);
+bool anv_physical_device_extension_supported(struct anv_physical_device *dev,
+ const char *name);
+
struct anv_queue {
VK_LOADER_DATA _loader_data;
struct anv_bo_cache bo_cache;
- struct anv_block_pool dynamic_state_block_pool;
struct anv_state_pool dynamic_state_pool;
-
- struct anv_block_pool instruction_block_pool;
struct anv_state_pool instruction_state_pool;
-
- struct anv_block_pool surface_state_block_pool;
struct anv_state_pool surface_state_pool;
struct anv_bo workaround_bo;
+ struct anv_bo trivial_batch_bo;
struct anv_pipeline_cache blorp_shader_cache;
struct blorp_context blorp;
if (device->info.has_llc)
return;
- anv_flush_range(state.map, state.alloc_size);
+ gen_flush_range(state.map, state.alloc_size);
}
void anv_device_init_blorp(struct anv_device *device);
int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching);
int anv_gem_set_domain(struct anv_device *device, uint32_t gem_handle,
uint32_t read_domains, uint32_t write_domain);
+int anv_gem_sync_file_merge(struct anv_device *device, int fd1, int fd2);
+uint32_t anv_gem_syncobj_create(struct anv_device *device, uint32_t flags);
+void anv_gem_syncobj_destroy(struct anv_device *device, uint32_t handle);
+int anv_gem_syncobj_handle_to_fd(struct anv_device *device, uint32_t handle);
+uint32_t anv_gem_syncobj_fd_to_handle(struct anv_device *device, int fd);
+int anv_gem_syncobj_export_sync_file(struct anv_device *device,
+ uint32_t handle);
+int anv_gem_syncobj_import_sync_file(struct anv_device *device,
+ uint32_t handle, int fd);
+void anv_gem_syncobj_reset(struct anv_device *device, uint32_t handle);
+bool anv_gem_supports_syncobj_wait(int fd);
+int anv_gem_syncobj_wait(struct anv_device *device,
+ uint32_t *handles, uint32_t num_handles,
+ int64_t abs_timeout_ns, bool wait_all);
VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);
.IndextoMOCSTables = 1 \
}
+/* Cannonlake MOCS defines are duplicates of Skylake MOCS defines. */
+#define GEN10_MOCS (struct GEN10_MEMORY_OBJECT_CONTROL_STATE) { \
+ /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */ \
+ .IndextoMOCSTables = 2 \
+ }
+
+#define GEN10_MOCS_PTE { \
+ /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */ \
+ .IndextoMOCSTables = 1 \
+ }
+
struct anv_device_memory {
struct anv_bo * bo;
- uint32_t type_index;
+ struct anv_memory_type * type;
VkDeviceSize map_size;
void * map;
};
union {
struct {
+ VkImageLayout layout;
struct anv_image_view *image_view;
struct anv_sampler *sampler;
-
- /* Used to determine whether or not we need the surface state to have
- * the auxiliary buffer enabled.
- */
- enum isl_aux_usage aux_usage;
};
struct {
uint8_t set;
/* Binding in the descriptor set */
- uint8_t binding;
+ uint32_t binding;
/* Index in the binding */
- uint8_t index;
+ uint32_t index;
/* Input attachment index (relative to the subpass) */
uint8_t input_attachment_index;
bool fast_clear;
VkClearValue clear_value;
bool clear_color_is_zero_one;
+ bool clear_color_is_zero;
};
/** State required while building cmd buffer */
*
* initialized by anv_cmd_buffer_init_batch_bo_chain()
*/
- struct u_vector bt_blocks;
+ struct u_vector bt_block_states;
uint32_t bt_next;
struct anv_reloc_list surface_relocs;
const VkSemaphore *in_semaphores,
uint32_t num_in_semaphores,
const VkSemaphore *out_semaphores,
- uint32_t num_out_semaphores);
+ uint32_t num_out_semaphores,
+ VkFence fence);
VkResult anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer);
void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
-enum anv_fence_state {
+enum anv_fence_type {
+ ANV_FENCE_TYPE_NONE = 0,
+ ANV_FENCE_TYPE_BO,
+ ANV_FENCE_TYPE_SYNCOBJ,
+};
+
+enum anv_bo_fence_state {
/** Indicates that this is a new (or newly reset fence) */
- ANV_FENCE_STATE_RESET,
+ ANV_BO_FENCE_STATE_RESET,
/** Indicates that this fence has been submitted to the GPU but is still
* (as far as we know) in use by the GPU.
*/
- ANV_FENCE_STATE_SUBMITTED,
+ ANV_BO_FENCE_STATE_SUBMITTED,
- ANV_FENCE_STATE_SIGNALED,
+ ANV_BO_FENCE_STATE_SIGNALED,
+};
+
+struct anv_fence_impl {
+ enum anv_fence_type type;
+
+ union {
+ /** Fence implementation for BO fences
+ *
+ * These fences use a BO and a set of CPU-tracked state flags. The BO
+ * is added to the object list of the last execbuf call in a QueueSubmit
+ * and is marked EXEC_WRITE. The state flags track when the BO has been
+ * submitted to the kernel. We need to do this because Vulkan lets you
+ * wait on a fence that has not yet been submitted and I915_GEM_BUSY
+ * will say it's idle in this case.
+ */
+ struct {
+ struct anv_bo bo;
+ enum anv_bo_fence_state state;
+ } bo;
+
+ /** DRM syncobj handle for syncobj-based fences */
+ uint32_t syncobj;
+ };
};
struct anv_fence {
- struct anv_bo bo;
- struct drm_i915_gem_execbuffer2 execbuf;
- struct drm_i915_gem_exec_object2 exec2_objects[1];
- enum anv_fence_state state;
+ /* Permanent fence state. Every fence has some form of permanent state
+ * (type != ANV_SEMAPHORE_TYPE_NONE). This may be a BO to fence on (for
+ * cross-process fences0 or it could just be a dummy for use internally.
+ */
+ struct anv_fence_impl permanent;
+
+ /* Temporary fence state. A fence *may* have temporary state. That state
+ * is added to the fence by an import operation and is reset back to
+ * ANV_SEMAPHORE_TYPE_NONE when the fence is reset. A fence with temporary
+ * state cannot be signaled because the fence must already be signaled
+ * before the temporary state can be exported from the fence in the other
+ * process and imported here.
+ */
+ struct anv_fence_impl temporary;
};
struct anv_event {
ANV_SEMAPHORE_TYPE_NONE = 0,
ANV_SEMAPHORE_TYPE_DUMMY,
ANV_SEMAPHORE_TYPE_BO,
+ ANV_SEMAPHORE_TYPE_SYNC_FILE,
+ ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
};
struct anv_semaphore_impl {
enum anv_semaphore_type type;
- /* A BO representing this semaphore when type == ANV_SEMAPHORE_TYPE_BO.
- * This BO will be added to the object list on any execbuf2 calls for
- * which this semaphore is used as a wait or signal fence. When used as
- * a signal fence, the EXEC_OBJECT_WRITE flag will be set.
- */
- struct anv_bo *bo;
+ union {
+ /* A BO representing this semaphore when type == ANV_SEMAPHORE_TYPE_BO.
+ * This BO will be added to the object list on any execbuf2 calls for
+ * which this semaphore is used as a wait or signal fence. When used as
+ * a signal fence, the EXEC_OBJECT_WRITE flag will be set.
+ */
+ struct anv_bo *bo;
+
+ /* The sync file descriptor when type == AKV_SEMAPHORE_TYPE_SYNC_FILE.
+ * If the semaphore is in the unsignaled state due to either just being
+ * created or because it has been used for a wait, fd will be -1.
+ */
+ int fd;
+
+ /* Sync object handle when type == AKV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
+ * Unlike GEM BOs, DRM sync objects aren't deduplicated by the kernel on
+ * import so we don't need to bother with a userspace cache.
+ */
+ uint32_t syncobj;
+ };
};
struct anv_semaphore {
struct anv_semaphore_impl temporary;
};
+void anv_semaphore_reset_temporary(struct anv_device *device,
+ struct anv_semaphore *semaphore);
+
struct anv_shader_module {
unsigned char sha1[20];
uint32_t size;
anv_shader_bin_ref(struct anv_shader_bin *shader)
{
assert(shader && shader->ref_cnt >= 1);
- __sync_fetch_and_add(&shader->ref_cnt, 1);
+ p_atomic_inc(&shader->ref_cnt);
}
static inline void
anv_shader_bin_unref(struct anv_device *device, struct anv_shader_bin *shader)
{
assert(shader && shader->ref_cnt >= 1);
- if (__sync_fetch_and_add(&shader->ref_cnt, -1) == 1)
+ if (p_atomic_dec_zero(&shader->ref_cnt))
anv_shader_bin_destroy(device, shader);
}
struct anv_surface aux_surface;
};
+/* Returns the number of auxiliary buffer levels attached to an image. */
+static inline uint8_t
+anv_image_aux_levels(const struct anv_image * const image)
+{
+ assert(image);
+ return image->aux_surface.isl.size > 0 ? image->aux_surface.isl.levels : 0;
+}
+
+/* Returns the number of auxiliary buffer layers attached to an image. */
+static inline uint32_t
+anv_image_aux_layers(const struct anv_image * const image,
+ const uint8_t miplevel)
+{
+ assert(image);
+
+ /* The miplevel must exist in the main buffer. */
+ assert(miplevel < image->levels);
+
+ if (miplevel >= anv_image_aux_levels(image)) {
+ /* There are no layers with auxiliary data because the miplevel has no
+ * auxiliary data.
+ */
+ return 0;
+ } else {
+ return MAX2(image->aux_surface.isl.logical_level0_px.array_len,
+ image->aux_surface.isl.logical_level0_px.depth >> miplevel);
+ }
+}
+
+static inline unsigned
+anv_fast_clear_state_entry_size(const struct anv_device *device)
+{
+ assert(device);
+ /* Entry contents:
+ * +--------------------------------------------+
+ * | clear value dword(s) | needs resolve dword |
+ * +--------------------------------------------+
+ */
+
+ /* Ensure that the needs resolve dword is in fact dword-aligned to enable
+ * GPU memcpy operations.
+ */
+ assert(device->isl_dev.ss.clear_value_size % 4 == 0);
+ return device->isl_dev.ss.clear_value_size + 4;
+}
+
/* Returns true if a HiZ-enabled depth buffer can be sampled from. */
static inline bool
anv_can_sample_with_hiz(const struct gen_device_info * const devinfo,
anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
enum blorp_hiz_op op);
+void
+anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,
+ const struct anv_state surface_state,
+ const struct anv_image * const image,
+ const uint8_t level, const uint32_t layer_count,
+ const enum blorp_fast_clear_op op);
+
+void
+anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_image *image,
+ const uint32_t base_level, const uint32_t level_count,
+ const uint32_t base_layer, uint32_t layer_count);
enum isl_aux_usage
anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
VkFormat vk_format;
VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
- /** RENDER_SURFACE_STATE when using image as a sampler surface. */
- struct anv_state sampler_surface_state;
+ /**
+ * RENDER_SURFACE_STATE when using image as a sampler surface with an image
+ * layout of SHADER_READ_ONLY_OPTIMAL or DEPTH_STENCIL_READ_ONLY_OPTIMAL.
+ */
+ enum isl_aux_usage optimal_sampler_aux_usage;
+ struct anv_state optimal_sampler_surface_state;
/**
- * RENDER_SURFACE_STATE when using image as a sampler surface with the
- * auxiliary buffer disabled.
+ * RENDER_SURFACE_STATE when using image as a sampler surface with an image
+ * layout of GENERAL.
*/
- struct anv_state no_aux_sampler_surface_state;
+ enum isl_aux_usage general_sampler_aux_usage;
+ struct anv_state general_sampler_surface_state;
/**
* RENDER_SURFACE_STATE when using image as a storage image. Separate states
uint32_t offset, uint32_t range,
uint32_t stride);
-void anv_image_view_fill_image_param(struct anv_device *device,
- struct anv_image_view *view,
- struct brw_image_param *param);
-void anv_buffer_view_fill_image_param(struct anv_device *device,
- struct anv_buffer_view *view,
- struct brw_image_param *param);
-
struct anv_sampler {
uint32_t state[4];
};
return MAX2(1, _mesa_bitcount(subpass->view_mask));
}
-enum anv_subpass_usage {
- ANV_SUBPASS_USAGE_DRAW = (1 << 0),
- ANV_SUBPASS_USAGE_INPUT = (1 << 1),
- ANV_SUBPASS_USAGE_RESOLVE_SRC = (1 << 2),
- ANV_SUBPASS_USAGE_RESOLVE_DST = (1 << 3),
-};
-
struct anv_render_pass_attachment {
/* TODO: Consider using VkAttachmentDescription instead of storing each of
* its members individually.
VkAttachmentLoadOp stencil_load_op;
VkImageLayout initial_layout;
VkImageLayout final_layout;
-
- /* An array, indexed by subpass id, of how the attachment will be used. */
- enum anv_subpass_usage * subpass_usage;
+ VkImageLayout first_subpass_layout;
/* The subpass id in which the attachment will be used last. */
uint32_t last_subpass_idx;
ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, VkSampler)
ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_semaphore, VkSemaphore)
ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, VkShaderModule)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_debug_report_callback, VkDebugReportCallbackEXT)
/* Gen-specific function declarations */
#ifdef genX
# define genX(x) gen9_##x
# include "anv_genX.h"
# undef genX
+# define genX(x) gen10_##x
+# include "anv_genX.h"
+# undef genX
#endif
#endif /* ANV_PRIVATE_H */