From d35aeff4bb0b03450b2c3c08bd7f84db5bf43283 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 18 Apr 2011 02:39:50 +0200 Subject: r300g/winsys: rename r300->radeon and do a little cleanup Renaming a few files, types, and functions. Also make the winsys independent of r300g. --- src/gallium/winsys/radeon/drm/Makefile | 5 +- src/gallium/winsys/radeon/drm/SConscript | 8 +- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 76 ++--- src/gallium/winsys/radeon/drm/radeon_drm_bo.h | 8 +- src/gallium/winsys/radeon/drm/radeon_drm_common.c | 248 --------------- src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 48 +-- src/gallium/winsys/radeon/drm/radeon_drm_cs.h | 6 +- src/gallium/winsys/radeon/drm/radeon_drm_public.h | 4 +- src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 247 +++++++++++++++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 67 ++++ src/gallium/winsys/radeon/drm/radeon_winsys.h | 352 +++++++++++++++++++--- 11 files changed, 692 insertions(+), 377 deletions(-) delete mode 100644 src/gallium/winsys/radeon/drm/radeon_drm_common.c create mode 100644 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c create mode 100644 src/gallium/winsys/radeon/drm/radeon_drm_winsys.h (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/radeon/drm/Makefile b/src/gallium/winsys/radeon/drm/Makefile index e63ae6f5006..d44b7c14250 100644 --- a/src/gallium/winsys/radeon/drm/Makefile +++ b/src/gallium/winsys/radeon/drm/Makefile @@ -7,10 +7,9 @@ LIBNAME = radeonwinsys C_SOURCES = \ radeon_drm_bo.c \ radeon_drm_cs.c \ - radeon_drm_common.c + radeon_drm_winsys.c -LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \ - $(shell pkg-config libdrm --cflags-only-I) +LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I) include ../../../Makefile.template diff --git a/src/gallium/winsys/radeon/drm/SConscript b/src/gallium/winsys/radeon/drm/SConscript index b16e03556d3..39a8c711b84 100644 --- a/src/gallium/winsys/radeon/drm/SConscript +++ b/src/gallium/winsys/radeon/drm/SConscript @@ -5,17 +5,15 @@ env = env.Clone() radeon_sources = [ 'radeon_drm_bo.c', 'radeon_drm_cs.c', - 'radeon_drm_common.c', + 'radeon_drm_winsys.c', ] try: - env.ParseConfig('pkg-config --cflags libdrm_radeon') + env.ParseConfig('pkg-config --cflags libdrm') except: - print 'warning: not building r300g' + print 'warning: not building Gallium Radeon' Return() -env.Append(CPPPATH = '#/src/gallium/drivers/r300') - radeonwinsys = env.ConvenienceLibrary( target ='radeonwinsys', source = radeon_sources, diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index 2b8ebf975e4..b6f12727e81 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -87,7 +87,7 @@ static struct radeon_bo *get_radeon_bo(struct pb_buffer *_buf) return bo; } -static void radeon_bo_wait(struct r300_winsys_bo *_buf) +static void radeon_bo_wait(struct pb_buffer *_buf) { struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); struct drm_radeon_gem_wait_idle args = {}; @@ -103,7 +103,7 @@ static void radeon_bo_wait(struct r300_winsys_bo *_buf) bo->busy_for_write = FALSE; } -static boolean radeon_bo_is_busy(struct r300_winsys_bo *_buf) +static boolean radeon_bo_is_busy(struct pb_buffer *_buf) { struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); struct drm_radeon_gem_busy args = {}; @@ -173,11 +173,11 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */ if (flags & PB_USAGE_DONTBLOCK) { if (radeon_bo_is_referenced_by_cs(cs, bo)) { - cs->flush_cs(cs->flush_data, R300_FLUSH_ASYNC); + cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC); return NULL; } - if (radeon_bo_is_busy((struct r300_winsys_bo*)bo)) { + if (radeon_bo_is_busy((struct pb_buffer*)bo)) { return NULL; } } else { @@ -191,12 +191,12 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, * Only check whether the buffer is being used for write. */ if (radeon_bo_is_referenced_by_cs_for_write(cs, bo)) { cs->flush_cs(cs->flush_data, 0); - radeon_bo_wait((struct r300_winsys_bo*)bo); + radeon_bo_wait((struct pb_buffer*)bo); } else if (bo->busy_for_write) { /* Update the busy_for_write field (done by radeon_bo_is_busy) * and wait if needed. */ - if (radeon_bo_is_busy((struct r300_winsys_bo*)bo)) { - radeon_bo_wait((struct r300_winsys_bo*)bo); + if (radeon_bo_is_busy((struct pb_buffer*)bo)) { + radeon_bo_wait((struct pb_buffer*)bo); } } } else { @@ -209,7 +209,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, radeon_drm_cs_sync_flush(cs); } - radeon_bo_wait((struct r300_winsys_bo*)bo); + radeon_bo_wait((struct pb_buffer*)bo); } } } @@ -345,7 +345,7 @@ static boolean radeon_bomgr_is_buffer_busy(struct pb_manager *_mgr, return TRUE; } - if (radeon_bo_is_busy((struct r300_winsys_bo*)bo)) { + if (radeon_bo_is_busy((struct pb_buffer*)bo)) { return TRUE; } @@ -391,8 +391,8 @@ struct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws) return &mgr->base; } -static void *radeon_bo_map(struct r300_winsys_bo *buf, - struct r300_winsys_cs *cs, +static void *radeon_bo_map(struct pb_buffer *buf, + struct radeon_winsys_cs *cs, enum pipe_transfer_usage usage) { struct pb_buffer *_buf = pb_buffer(buf); @@ -400,9 +400,9 @@ static void *radeon_bo_map(struct r300_winsys_bo *buf, return pb_map(_buf, get_pb_usage_from_transfer_flags(usage), cs); } -static void radeon_bo_get_tiling(struct r300_winsys_bo *_buf, - enum r300_buffer_tiling *microtiled, - enum r300_buffer_tiling *macrotiled) +static void radeon_bo_get_tiling(struct pb_buffer *_buf, + enum radeon_bo_layout *microtiled, + enum radeon_bo_layout *macrotiled) { struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); struct drm_radeon_gem_set_tiling args = {}; @@ -414,19 +414,19 @@ static void radeon_bo_get_tiling(struct r300_winsys_bo *_buf, &args, sizeof(args)); - *microtiled = R300_BUFFER_LINEAR; - *macrotiled = R300_BUFFER_LINEAR; + *microtiled = RADEON_LAYOUT_LINEAR; + *macrotiled = RADEON_LAYOUT_LINEAR; if (args.tiling_flags & RADEON_BO_FLAGS_MICRO_TILE) - *microtiled = R300_BUFFER_TILED; + *microtiled = RADEON_LAYOUT_TILED; if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE) - *macrotiled = R300_BUFFER_TILED; + *macrotiled = RADEON_LAYOUT_TILED; } -static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf, - struct r300_winsys_cs *rcs, - enum r300_buffer_tiling microtiled, - enum r300_buffer_tiling macrotiled, +static void radeon_bo_set_tiling(struct pb_buffer *_buf, + struct radeon_winsys_cs *rcs, + enum radeon_bo_layout microtiled, + enum radeon_bo_layout macrotiled, uint32_t pitch) { struct radeon_bo *bo = get_radeon_bo(pb_buffer(_buf)); @@ -443,12 +443,12 @@ static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf, sched_yield(); } - if (microtiled == R300_BUFFER_TILED) + if (microtiled == RADEON_LAYOUT_TILED) args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE; - else if (microtiled == R300_BUFFER_SQUARETILED) + else if (microtiled == RADEON_LAYOUT_SQUARETILED) args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE; - if (macrotiled == R300_BUFFER_TILED) + if (macrotiled == RADEON_LAYOUT_TILED) args.tiling_flags |= RADEON_BO_FLAGS_MACRO_TILE; args.handle = bo->handle; @@ -460,35 +460,35 @@ static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf, sizeof(args)); } -static struct r300_winsys_cs_handle *radeon_drm_get_cs_handle( - struct r300_winsys_bo *_buf) +static struct radeon_winsys_cs_handle *radeon_drm_get_cs_handle( + struct pb_buffer *_buf) { /* return radeon_bo. */ - return (struct r300_winsys_cs_handle*) + return (struct radeon_winsys_cs_handle*) get_radeon_bo(pb_buffer(_buf)); } static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage, - enum r300_buffer_domain domain) + enum radeon_bo_domain domain) { unsigned res = 0; - if (domain & R300_DOMAIN_GTT) + if (domain & RADEON_DOMAIN_GTT) res |= RADEON_PB_USAGE_DOMAIN_GTT; - if (domain & R300_DOMAIN_VRAM) + if (domain & RADEON_DOMAIN_VRAM) res |= RADEON_PB_USAGE_DOMAIN_VRAM; return res; } -static struct r300_winsys_bo * -radeon_winsys_bo_create(struct r300_winsys_screen *rws, +static struct pb_buffer * +radeon_winsys_bo_create(struct radeon_winsys *rws, unsigned size, unsigned alignment, unsigned bind, unsigned usage, - enum r300_buffer_domain domain) + enum radeon_bo_domain domain) { struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); struct pb_desc desc; @@ -509,10 +509,10 @@ radeon_winsys_bo_create(struct r300_winsys_screen *rws, if (!buffer) return NULL; - return (struct r300_winsys_bo*)buffer; + return (struct pb_buffer*)buffer; } -static struct r300_winsys_bo *radeon_winsys_bo_from_handle(struct r300_winsys_screen *rws, +static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws, struct winsys_handle *whandle, unsigned *stride, unsigned *size) @@ -575,14 +575,14 @@ done: if (size) *size = bo->base.base.size; - return (struct r300_winsys_bo*)bo; + return (struct pb_buffer*)bo; fail: pipe_mutex_unlock(mgr->bo_handles_mutex); return NULL; } -static boolean radeon_winsys_bo_get_handle(struct r300_winsys_bo *buffer, +static boolean radeon_winsys_bo_get_handle(struct pb_buffer *buffer, unsigned stride, struct winsys_handle *whandle) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h index b20a0996c93..b94881bc4ce 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h @@ -29,10 +29,10 @@ * Jérôme Glisse * Marek Olšák */ -#ifndef RADEON_DRM_BUFFER_H -#define RADEON_DRM_BUFFER_H +#ifndef RADEON_DRM_BO_H +#define RADEON_DRM_BO_H -#include "radeon_winsys.h" +#include "radeon_drm_winsys.h" #include "pipebuffer/pb_bufmgr.h" #include "os/os_thread.h" @@ -81,7 +81,7 @@ void radeon_bo_reference(struct radeon_bo **dst, struct radeon_bo *src) } static INLINE struct pb_buffer * -pb_buffer(struct r300_winsys_bo *buffer) +pb_buffer(struct pb_buffer *buffer) { return (struct pb_buffer *)buffer; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_common.c b/src/gallium/winsys/radeon/drm/radeon_drm_common.c deleted file mode 100644 index 72c2ff11125..00000000000 --- a/src/gallium/winsys/radeon/drm/radeon_drm_common.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright © 2009 Corbin Simpson - * Copyright © 2011 Marek Olšák - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS - * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * Corbin Simpson - * Joakim Sindholt - * Marek Olšák - */ - -#include "radeon_winsys.h" -#include "radeon_drm_bo.h" -#include "radeon_drm_cs.h" -#include "radeon_drm_public.h" - -#include "pipebuffer/pb_bufmgr.h" -#include "util/u_memory.h" - -#include -#include - -#ifndef RADEON_INFO_WANT_HYPERZ -#define RADEON_INFO_WANT_HYPERZ 7 -#endif -#ifndef RADEON_INFO_WANT_CMASK -#define RADEON_INFO_WANT_CMASK 8 -#endif - -/* Enable/disable feature access. Return TRUE on success. */ -static boolean radeon_set_fd_access(int fd, unsigned request, boolean enable) -{ - struct drm_radeon_info info = {0}; - unsigned value = enable ? 1 : 0; - - info.value = (unsigned long)&value; - info.request = request; - - if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) - return FALSE; - - if (enable && !value) - return FALSE; - - return TRUE; -} - -/* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(struct radeon_drm_winsys *winsys) -{ - struct drm_radeon_gem_info gem_info = {0}; - struct drm_radeon_info info = {0}; - int target = 0; - int retval; - drmVersionPtr version; - - info.value = (unsigned long)⌖ - - /* We do things in a specific order here. - * - * DRM version first. We need to be sure we're running on a KMS chipset. - * This is also for some features. - * - * Then, the PCI ID. This is essential and should return usable numbers - * for all Radeons. If this fails, we probably got handed an FD for some - * non-Radeon card. - * - * The GB and Z pipe requests should always succeed, but they might not - * return sensical values for all chipsets, but that's alright because - * the pipe drivers already know that. - * - * The GEM info is actually bogus on the kernel side, as well as our side - * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because - * we don't actually use the info for anything yet. */ - - version = drmGetVersion(winsys->fd); - if (version->version_major != 2 || - version->version_minor < 3) { - fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " - "only compatible with 2.3.x (kernel 2.6.34) and later.\n", - __FUNCTION__, - version->version_major, - version->version_minor, - version->version_patchlevel); - drmFreeVersion(version); - exit(1); - } - - winsys->drm_major = version->version_major; - winsys->drm_minor = version->version_minor; - winsys->drm_patchlevel = version->version_patchlevel; - - info.request = RADEON_INFO_DEVICE_ID; - retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info)); - if (retval) { - fprintf(stderr, "%s: Failed to get PCI ID, " - "error number %d\n", __FUNCTION__, retval); - exit(1); - } - winsys->pci_id = target; - - info.request = RADEON_INFO_NUM_GB_PIPES; - retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info)); - if (retval) { - fprintf(stderr, "%s: Failed to get GB pipe count, " - "error number %d\n", __FUNCTION__, retval); - exit(1); - } - winsys->gb_pipes = target; - - info.request = RADEON_INFO_NUM_Z_PIPES; - retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info)); - if (retval) { - fprintf(stderr, "%s: Failed to get Z pipe count, " - "error number %d\n", __FUNCTION__, retval); - exit(1); - } - winsys->z_pipes = target; - - if (debug_get_bool_option("RADEON_HYPERZ", FALSE)) { - winsys->hyperz = radeon_set_fd_access(winsys->fd, - RADEON_INFO_WANT_HYPERZ, TRUE); - } - - if (debug_get_bool_option("RADEON_CMASK", FALSE)) { - winsys->aacompress = radeon_set_fd_access(winsys->fd, - RADEON_INFO_WANT_CMASK, TRUE); - } - - retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_GEM_INFO, - &gem_info, sizeof(gem_info)); - if (retval) { - fprintf(stderr, "%s: Failed to get MM info, error number %d\n", - __FUNCTION__, retval); - exit(1); - } - winsys->gart_size = gem_info.gart_size; - winsys->vram_size = gem_info.vram_size; - - drmFreeVersion(version); - - winsys->num_cpus = sysconf(_SC_NPROCESSORS_ONLN); -} - -static void radeon_winsys_destroy(struct r300_winsys_screen *rws) -{ - struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; - - ws->cman->destroy(ws->cman); - ws->kman->destroy(ws->kman); - FREE(rws); -} - -static uint32_t radeon_get_value(struct r300_winsys_screen *rws, - enum r300_value_id id) -{ - struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws; - - switch(id) { - case R300_VID_PCI_ID: - return ws->pci_id; - case R300_VID_GB_PIPES: - return ws->gb_pipes; - case R300_VID_Z_PIPES: - return ws->z_pipes; - case R300_VID_GART_SIZE: - return ws->gart_size; - case R300_VID_VRAM_SIZE: - return ws->vram_size; - case R300_VID_DRM_MAJOR: - return ws->drm_major; - case R300_VID_DRM_MINOR: - return ws->drm_minor; - case R300_VID_DRM_PATCHLEVEL: - return ws->drm_patchlevel; - case R300_VID_DRM_2_6_0: - return ws->drm_major*100 + ws->drm_minor >= 206; - case R300_VID_DRM_2_8_0: - return ws->drm_major*100 + ws->drm_minor >= 208; - case R300_CAN_HYPERZ: - return ws->hyperz; - case R300_CAN_AACOMPRESS: - return ws->aacompress; - } - return 0; -} - -struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd) -{ - struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys); - if (!ws) { - return NULL; - } - - ws->fd = fd; - do_ioctls(ws); - - if (!is_r3xx(ws->pci_id)) { - goto fail; - } - - /* Create managers. */ - ws->kman = radeon_bomgr_create(ws); - if (!ws->kman) - goto fail; - ws->cman = pb_cache_manager_create(ws->kman, 1000000); - if (!ws->cman) - goto fail; - - /* Set functions. */ - ws->base.destroy = radeon_winsys_destroy; - ws->base.get_value = radeon_get_value; - - radeon_bomgr_init_functions(ws); - radeon_drm_cs_init_functions(ws); - - return &ws->base; - -fail: - if (ws->cman) - ws->cman->destroy(ws->cman); - if (ws->kman) - ws->kman->destroy(ws->kman); - FREE(ws); - return NULL; -} diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index f23533622df..0139de1973a 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -36,7 +36,7 @@ /* This file replaces libdrm's radeon_cs_gem with our own implemention. - It's optimized specifically for r300g, but r600g could use it as well. + It's optimized specifically for Radeon DRM. Reloc writes and space checking are faster and simpler than their counterparts in libdrm (the time complexity of all the functions is O(1) in nearly all scenarios, thanks to hashing). @@ -129,7 +129,7 @@ static void radeon_destroy_cs_context(struct radeon_cs_context *csc) FREE(csc->relocs); } -static struct r300_winsys_cs *radeon_drm_cs_create(struct r300_winsys_screen *rws) +static struct radeon_winsys_cs *radeon_drm_cs_create(struct radeon_winsys *rws) { struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); struct radeon_drm_cs *cs; @@ -163,9 +163,9 @@ static struct r300_winsys_cs *radeon_drm_cs_create(struct r300_winsys_screen *rw #define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value) static INLINE void update_domains(struct drm_radeon_cs_reloc *reloc, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd, - enum r300_buffer_domain *added_domains) + enum radeon_bo_domain rd, + enum radeon_bo_domain wd, + enum radeon_bo_domain *added_domains) { *added_domains = (rd | wd) & ~(reloc->read_domains | reloc->write_domain); @@ -220,9 +220,9 @@ int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo) static void radeon_add_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd, - enum r300_buffer_domain *added_domains) + enum radeon_bo_domain rd, + enum radeon_bo_domain wd, + enum radeon_bo_domain *added_domains) { struct drm_radeon_cs_reloc *reloc; unsigned i; @@ -284,27 +284,27 @@ static void radeon_add_reloc(struct radeon_cs_context *csc, *added_domains = rd | wd; } -static void radeon_drm_cs_add_reloc(struct r300_winsys_cs *rcs, - struct r300_winsys_cs_handle *buf, - enum r300_buffer_domain rd, - enum r300_buffer_domain wd) +static void radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs, + struct radeon_winsys_cs_handle *buf, + enum radeon_bo_domain rd, + enum radeon_bo_domain wd) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_bo *bo = (struct radeon_bo*)buf; - enum r300_buffer_domain added_domains; + enum radeon_bo_domain added_domains; radeon_add_reloc(cs->csc, bo, rd, wd, &added_domains); if (!added_domains) return; - if (added_domains & R300_DOMAIN_GTT) + if (added_domains & RADEON_DOMAIN_GTT) cs->csc->used_gart += bo->size; - if (added_domains & R300_DOMAIN_VRAM) + if (added_domains & RADEON_DOMAIN_VRAM) cs->csc->used_vram += bo->size; } -static boolean radeon_drm_cs_validate(struct r300_winsys_cs *rcs) +static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); @@ -312,8 +312,8 @@ static boolean radeon_drm_cs_validate(struct r300_winsys_cs *rcs) cs->csc->used_vram < cs->ws->vram_size * 0.8; } -static void radeon_drm_cs_write_reloc(struct r300_winsys_cs *rcs, - struct r300_winsys_cs_handle *buf) +static void radeon_drm_cs_write_reloc(struct radeon_winsys_cs *rcs, + struct radeon_winsys_cs_handle *buf) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_bo *bo = (struct radeon_bo*)buf; @@ -365,7 +365,7 @@ void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs) DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE) -static void radeon_drm_cs_flush(struct r300_winsys_cs *rcs, unsigned flags) +static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_cs_context *tmp; @@ -389,7 +389,7 @@ static void radeon_drm_cs_flush(struct r300_winsys_cs *rcs, unsigned flags) } if (cs->ws->num_cpus > 1 && debug_get_option_thread() && - (flags & R300_FLUSH_ASYNC)) { + (flags & RADEON_FLUSH_ASYNC)) { cs->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, cs->csc); assert(cs->thread); } else { @@ -409,7 +409,7 @@ static void radeon_drm_cs_flush(struct r300_winsys_cs *rcs, unsigned flags) cs->base.cdw = 0; } -static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) +static void radeon_drm_cs_destroy(struct radeon_winsys_cs *rcs) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); radeon_drm_cs_sync_flush(cs); @@ -421,7 +421,7 @@ static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) FREE(cs); } -static void radeon_drm_cs_set_flush(struct r300_winsys_cs *rcs, +static void radeon_drm_cs_set_flush(struct radeon_winsys_cs *rcs, void (*flush)(void *ctx, unsigned flags), void *user) { @@ -430,8 +430,8 @@ static void radeon_drm_cs_set_flush(struct r300_winsys_cs *rcs, cs->flush_data = user; } -static boolean radeon_bo_is_referenced(struct r300_winsys_cs *rcs, - struct r300_winsys_cs_handle *_buf) +static boolean radeon_bo_is_referenced(struct radeon_winsys_cs *rcs, + struct radeon_winsys_cs_handle *_buf) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_bo *bo = (struct radeon_bo*)_buf; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h index dc2050a27eb..339beedc6ab 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h @@ -31,7 +31,7 @@ #include struct radeon_cs_context { - uint32_t buf[R300_MAX_CMDBUF_DWORDS]; + uint32_t buf[RADEON_MAX_CMDBUF_DWORDS]; int fd; struct drm_radeon_cs cs; @@ -54,7 +54,7 @@ struct radeon_cs_context { }; struct radeon_drm_cs { - struct r300_winsys_cs base; + struct radeon_winsys_cs base; /* We flip between these two CS. While one is being consumed * by the kernel in another thread, the other one is being filled @@ -79,7 +79,7 @@ struct radeon_drm_cs { int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo); static INLINE struct radeon_drm_cs * -radeon_drm_cs(struct r300_winsys_cs *base) +radeon_drm_cs(struct radeon_winsys_cs *base) { return (struct radeon_drm_cs*)base; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_public.h b/src/gallium/winsys/radeon/drm/radeon_drm_public.h index 3a208cdd4c4..76d9dda422d 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_public.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_public.h @@ -3,9 +3,9 @@ #include "pipe/p_defines.h" -struct r300_winsys_screen; +struct radeon_winsys; -struct r300_winsys_screen *r300_drm_winsys_screen_create(int fd); +struct radeon_winsys *radeon_drm_winsys_create(int fd); static INLINE boolean is_r3xx(int pciid) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c new file mode 100644 index 00000000000..37f6d18689d --- /dev/null +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -0,0 +1,247 @@ +/* + * Copyright © 2009 Corbin Simpson + * Copyright © 2011 Marek Olšák + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS + * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Corbin Simpson + * Joakim Sindholt + * Marek Olšák + */ + +#include "radeon_drm_bo.h" +#include "radeon_drm_cs.h" +#include "radeon_drm_public.h" + +#include "pipebuffer/pb_bufmgr.h" +#include "util/u_memory.h" + +#include +#include + +#ifndef RADEON_INFO_WANT_HYPERZ +#define RADEON_INFO_WANT_HYPERZ 7 +#endif +#ifndef RADEON_INFO_WANT_CMASK +#define RADEON_INFO_WANT_CMASK 8 +#endif + +/* Enable/disable feature access. Return TRUE on success. */ +static boolean radeon_set_fd_access(int fd, unsigned request, boolean enable) +{ + struct drm_radeon_info info = {0}; + unsigned value = enable ? 1 : 0; + + info.value = (unsigned long)&value; + info.request = request; + + if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) + return FALSE; + + if (enable && !value) + return FALSE; + + return TRUE; +} + +/* Helper function to do the ioctls needed for setup and init. */ +static void do_ioctls(struct radeon_drm_winsys *winsys) +{ + struct drm_radeon_gem_info gem_info = {0}; + struct drm_radeon_info info = {0}; + int target = 0; + int retval; + drmVersionPtr version; + + info.value = (unsigned long)⌖ + + /* We do things in a specific order here. + * + * DRM version first. We need to be sure we're running on a KMS chipset. + * This is also for some features. + * + * Then, the PCI ID. This is essential and should return usable numbers + * for all Radeons. If this fails, we probably got handed an FD for some + * non-Radeon card. + * + * The GB and Z pipe requests should always succeed, but they might not + * return sensical values for all chipsets, but that's alright because + * the pipe drivers already know that. + * + * The GEM info is actually bogus on the kernel side, as well as our side + * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because + * we don't actually use the info for anything yet. */ + + version = drmGetVersion(winsys->fd); + if (version->version_major != 2 || + version->version_minor < 3) { + fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " + "only compatible with 2.3.x (kernel 2.6.34) and later.\n", + __FUNCTION__, + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + exit(1); + } + + winsys->drm_major = version->version_major; + winsys->drm_minor = version->version_minor; + winsys->drm_patchlevel = version->version_patchlevel; + + info.request = RADEON_INFO_DEVICE_ID; + retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (retval) { + fprintf(stderr, "%s: Failed to get PCI ID, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } + winsys->pci_id = target; + + info.request = RADEON_INFO_NUM_GB_PIPES; + retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (retval) { + fprintf(stderr, "%s: Failed to get GB pipe count, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } + winsys->gb_pipes = target; + + info.request = RADEON_INFO_NUM_Z_PIPES; + retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (retval) { + fprintf(stderr, "%s: Failed to get Z pipe count, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } + winsys->z_pipes = target; + + if (debug_get_bool_option("RADEON_HYPERZ", FALSE)) { + winsys->hyperz = radeon_set_fd_access(winsys->fd, + RADEON_INFO_WANT_HYPERZ, TRUE); + } + + if (debug_get_bool_option("RADEON_CMASK", FALSE)) { + winsys->aacompress = radeon_set_fd_access(winsys->fd, + RADEON_INFO_WANT_CMASK, TRUE); + } + + retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_GEM_INFO, + &gem_info, sizeof(gem_info)); + if (retval) { + fprintf(stderr, "%s: Failed to get MM info, error number %d\n", + __FUNCTION__, retval); + exit(1); + } + winsys->gart_size = gem_info.gart_size; + winsys->vram_size = gem_info.vram_size; + + drmFreeVersion(version); + + winsys->num_cpus = sysconf(_SC_NPROCESSORS_ONLN); +} + +static void radeon_winsys_destroy(struct radeon_winsys *rws) +{ + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; + + ws->cman->destroy(ws->cman); + ws->kman->destroy(ws->kman); + FREE(rws); +} + +static uint32_t radeon_get_value(struct radeon_winsys *rws, + enum radeon_value_id id) +{ + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws; + + switch(id) { + case RADEON_VID_PCI_ID: + return ws->pci_id; + case RADEON_VID_R300_GB_PIPES: + return ws->gb_pipes; + case RADEON_VID_R300_Z_PIPES: + return ws->z_pipes; + case RADEON_VID_GART_SIZE: + return ws->gart_size; + case RADEON_VID_VRAM_SIZE: + return ws->vram_size; + case RADEON_VID_DRM_MAJOR: + return ws->drm_major; + case RADEON_VID_DRM_MINOR: + return ws->drm_minor; + case RADEON_VID_DRM_PATCHLEVEL: + return ws->drm_patchlevel; + case RADEON_VID_DRM_2_6_0: + return ws->drm_major*100 + ws->drm_minor >= 206; + case RADEON_VID_DRM_2_8_0: + return ws->drm_major*100 + ws->drm_minor >= 208; + case RADEON_VID_CAN_HYPERZ: + return ws->hyperz; + case RADEON_VID_CAN_AACOMPRESS: + return ws->aacompress; + } + return 0; +} + +struct radeon_winsys *radeon_drm_winsys_create(int fd) +{ + struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys); + if (!ws) { + return NULL; + } + + ws->fd = fd; + do_ioctls(ws); + + if (!is_r3xx(ws->pci_id)) { + goto fail; + } + + /* Create managers. */ + ws->kman = radeon_bomgr_create(ws); + if (!ws->kman) + goto fail; + ws->cman = pb_cache_manager_create(ws->kman, 1000000); + if (!ws->cman) + goto fail; + + /* Set functions. */ + ws->base.destroy = radeon_winsys_destroy; + ws->base.get_value = radeon_get_value; + + radeon_bomgr_init_functions(ws); + radeon_drm_cs_init_functions(ws); + + return &ws->base; + +fail: + if (ws->cman) + ws->cman->destroy(ws->cman); + if (ws->kman) + ws->kman->destroy(ws->kman); + FREE(ws); + return NULL; +} diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h new file mode 100644 index 00000000000..e1b9493fc10 --- /dev/null +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2009 Corbin Simpson + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS + * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Corbin Simpson + */ +#ifndef RADEON_DRM_WINSYS_H +#define RADEON_DRM_WINSYS_H + +#include "radeon_winsys.h" + +struct radeon_drm_winsys { + struct radeon_winsys base; + + int fd; /* DRM file descriptor */ + int num_cs; /* The number of command streams created. */ + + struct pb_manager *kman; + struct pb_manager *cman; + + uint32_t pci_id; /* PCI ID */ + uint32_t gb_pipes; /* GB pipe count */ + uint32_t z_pipes; /* Z pipe count (rv530 only) */ + uint32_t gart_size; /* GART size. */ + uint32_t vram_size; /* VRAM size. */ + uint32_t num_cpus; /* Number of CPUs. */ + + unsigned drm_major; + unsigned drm_minor; + unsigned drm_patchlevel; + + /* Hyper-Z user */ + boolean hyperz; + /* AA compression (CMask) */ + boolean aacompress; +}; + +static INLINE struct radeon_drm_winsys * +radeon_drm_winsys(struct radeon_winsys *base) +{ + return (struct radeon_drm_winsys*)base; +} + +#endif diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 9ecbb074572..ca0e6624138 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -1,67 +1,319 @@ /* - * Copyright © 2009 Corbin Simpson - * All Rights Reserved. + * Copyright 2008 Corbin Simpson + * Copyright 2010 Marek Olšák * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS - * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - */ -/* - * Authors: - * Corbin Simpson - */ + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #ifndef RADEON_WINSYS_H #define RADEON_WINSYS_H -#include "r300_winsys.h" +/* The public winsys interface header for the radeon driver. */ -struct radeon_drm_winsys { - struct r300_winsys_screen base; +#include "pipebuffer/pb_bufmgr.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" - int fd; /* DRM file descriptor */ - int num_cs; /* The number of command streams created. */ +#define RADEON_MAX_CMDBUF_DWORDS (16 * 1024) +#define RADEON_FLUSH_ASYNC (1 << 0) - struct pb_manager *kman; - struct pb_manager *cman; +/* Tiling flags. */ +enum radeon_bo_layout { + RADEON_LAYOUT_LINEAR = 0, + RADEON_LAYOUT_TILED, + RADEON_LAYOUT_SQUARETILED, - uint32_t pci_id; /* PCI ID */ - uint32_t gb_pipes; /* GB pipe count */ - uint32_t z_pipes; /* Z pipe count (rv530 only) */ - uint32_t gart_size; /* GART size. */ - uint32_t vram_size; /* VRAM size. */ - uint32_t num_cpus; /* Number of CPUs. */ + RADEON_LAYOUT_UNKNOWN +}; + +enum radeon_bo_domain { /* bitfield */ + RADEON_DOMAIN_GTT = 2, + RADEON_DOMAIN_VRAM = 4 +}; - unsigned drm_major; - unsigned drm_minor; - unsigned drm_patchlevel; +struct winsys_handle; +struct radeon_winsys_cs_handle; /* for write_reloc etc. */ - /* Hyper-Z user */ - boolean hyperz; - /* AA compression (CMask) */ - boolean aacompress; +struct radeon_winsys_cs { + unsigned cdw; /* Number of used dwords. */ + uint32_t *buf; /* The command buffer. */ }; -static INLINE struct radeon_drm_winsys * -radeon_drm_winsys(struct r300_winsys_screen *base) -{ - return (struct radeon_drm_winsys*)base; -} +enum radeon_value_id { + RADEON_VID_PCI_ID, + RADEON_VID_R300_GB_PIPES, + RADEON_VID_R300_Z_PIPES, + RADEON_VID_GART_SIZE, + RADEON_VID_VRAM_SIZE, + RADEON_VID_DRM_MAJOR, + RADEON_VID_DRM_MINOR, + RADEON_VID_DRM_PATCHLEVEL, + + /* These should probably go away: */ + + /* R300 features: + * - Hyper-Z + * - GB_Z_PEQ_CONFIG on rv350->r4xx + * - R500 FG_ALPHA_VALUE + * + * R600 features: + * - TBD + */ + RADEON_VID_DRM_2_6_0, + + /* R300 features: + * - R500 US_FORMAT regs + * - R500 ARGB2101010 colorbuffer + * - CMask and AA regs + * - R16F/RG16F + * + * R600 features: + * - TBD + */ + RADEON_VID_DRM_2_8_0, + + RADEON_VID_CAN_HYPERZ, /* ZMask + HiZ */ + RADEON_VID_CAN_AACOMPRESS, /* CMask */ +}; + +struct radeon_winsys { + /** + * Destroy this winsys. + * + * \param ws The winsys this function is called from. + */ + void (*destroy)(struct radeon_winsys *ws); + + /** + * Query a system value from a winsys. + * + * \param ws The winsys this function is called from. + * \param vid One of the RADEON_VID_* enums. + */ + uint32_t (*get_value)(struct radeon_winsys *ws, + enum radeon_value_id vid); + + /************************************************************************** + * Buffer management. Buffer attributes are mostly fixed over its lifetime. + * + * Remember that gallium gets to choose the interface it needs, and the + * window systems must then implement that interface (rather than the + * other way around...). + *************************************************************************/ + + /** + * Create a buffer object. + * + * \param ws The winsys this function is called from. + * \param size The size to allocate. + * \param alignment An alignment of the buffer in memory. + * \param bind A bitmask of the PIPE_BIND_* flags. + * \param usage A bitmask of the PIPE_USAGE_* flags. + * \param domain A bitmask of the RADEON_DOMAIN_* flags. + * \return The created buffer object. + */ + struct pb_buffer *(*buffer_create)(struct radeon_winsys *ws, + unsigned size, + unsigned alignment, + unsigned bind, + unsigned usage, + enum radeon_bo_domain domain); + + struct radeon_winsys_cs_handle *(*buffer_get_cs_handle)( + struct pb_buffer *buf); + + /** + * Map the entire data store of a buffer object into the client's address + * space. + * + * \param buf A winsys buffer object to map. + * \param cs A command stream to flush if the buffer is referenced by it. + * \param usage A bitmask of the PIPE_TRANSFER_* flags. + * \return The pointer at the beginning of the buffer. + */ + void *(*buffer_map)(struct pb_buffer *buf, + struct radeon_winsys_cs *cs, + enum pipe_transfer_usage usage); + + /** + * Unmap a buffer object from the client's address space. + * + * \param buf A winsys buffer object to unmap. + */ + void (*buffer_unmap)(struct pb_buffer *buf); + + /** + * Return TRUE if a buffer object is being used by the GPU. + * + * \param buf A winsys buffer object. + */ + boolean (*buffer_is_busy)(struct pb_buffer *buf); + + /** + * Wait for a buffer object until it is not used by a GPU. This is + * equivalent to a fence placed after the last command using the buffer, + * and synchronizing to the fence. + * + * \param buf A winsys buffer object to wait for. + */ + void (*buffer_wait)(struct pb_buffer *buf); + + /** + * Return tiling flags describing a memory layout of a buffer object. + * + * \param buf A winsys buffer object to get the flags from. + * \param macrotile A pointer to the return value of the microtile flag. + * \param microtile A pointer to the return value of the macrotile flag. + * + * \note microtile and macrotile are not bitmasks! + */ + void (*buffer_get_tiling)(struct pb_buffer *buf, + enum radeon_bo_layout *microtile, + enum radeon_bo_layout *macrotile); + + /** + * Set tiling flags describing a memory layout of a buffer object. + * + * \param buf A winsys buffer object to set the flags for. + * \param cs A command stream to flush if the buffer is referenced by it. + * \param macrotile A macrotile flag. + * \param microtile A microtile flag. + * \param stride A stride of the buffer in bytes, for texturing. + * + * \note microtile and macrotile are not bitmasks! + */ + void (*buffer_set_tiling)(struct pb_buffer *buf, + struct radeon_winsys_cs *cs, + enum radeon_bo_layout microtile, + enum radeon_bo_layout macrotile, + unsigned stride); + + /** + * Get a winsys buffer from a winsys handle. The internal structure + * of the handle is platform-specific and only a winsys should access it. + * + * \param ws The winsys this function is called from. + * \param whandle A winsys handle pointer as was received from a state + * tracker. + * \param stride The returned buffer stride in bytes. + * \param size The returned buffer size. + */ + struct pb_buffer *(*buffer_from_handle)(struct radeon_winsys *ws, + struct winsys_handle *whandle, + unsigned *stride, + unsigned *size); + + /** + * Get a winsys handle from a winsys buffer. The internal structure + * of the handle is platform-specific and only a winsys should access it. + * + * \param buf A winsys buffer object to get the handle from. + * \param whandle A winsys handle pointer. + * \param stride A stride of the buffer in bytes, for texturing. + * \return TRUE on success. + */ + boolean (*buffer_get_handle)(struct pb_buffer *buf, + unsigned stride, + struct winsys_handle *whandle); + + /************************************************************************** + * Command submission. + * + * Each pipe context should create its own command stream and submit + * commands independently of other contexts. + *************************************************************************/ + + /** + * Create a command stream. + * + * \param ws The winsys this function is called from. + */ + struct radeon_winsys_cs *(*cs_create)(struct radeon_winsys *ws); + + /** + * Destroy a command stream. + * + * \param cs A command stream to destroy. + */ + void (*cs_destroy)(struct radeon_winsys_cs *cs); + + /** + * Add a new buffer relocation. Every relocation must first be added + * before it can be written. + * + * \param cs A command stream to add buffer for validation against. + * \param buf A winsys buffer to validate. + * \param rd A read domain containing a bitmask of the RADEON_DOMAIN_* flags. + * \param wd A write domain containing a bitmask of the RADEON_DOMAIN_* flags. + */ + void (*cs_add_reloc)(struct radeon_winsys_cs *cs, + struct radeon_winsys_cs_handle *buf, + enum radeon_bo_domain rd, + enum radeon_bo_domain wd); + + /** + * Return TRUE if there is enough memory in VRAM and GTT for the relocs + * added so far. + * + * \param cs A command stream to validate. + */ + boolean (*cs_validate)(struct radeon_winsys_cs *cs); + + /** + * Write a relocated dword to a command buffer. + * + * \param cs A command stream the relocation is written to. + * \param buf A winsys buffer to write the relocation for. + * \param rd A read domain containing a bitmask of the RADEON_DOMAIN_* flags. + * \param wd A write domain containing a bitmask of the RADEON_DOMAIN_* flags. + */ + void (*cs_write_reloc)(struct radeon_winsys_cs *cs, + struct radeon_winsys_cs_handle *buf); + + /** + * Flush a command stream. + * + * \param cs A command stream to flush. + * \param flags, RADEON_FLUSH_ASYNC or 0. + */ + void (*cs_flush)(struct radeon_winsys_cs *cs, unsigned flags); + + /** + * Set a flush callback which is called from winsys when flush is + * required. + * + * \param cs A command stream to set the callback for. + * \param flush A flush callback function associated with the command stream. + * \param user A user pointer that will be passed to the flush callback. + */ + void (*cs_set_flush)(struct radeon_winsys_cs *cs, + void (*flush)(void *ctx, unsigned flags), + void *user); + + /** + * Return TRUE if a buffer is referenced by a command stream. + * + * \param cs A command stream. + * \param buf A winsys buffer. + */ + boolean (*cs_is_buffer_referenced)(struct radeon_winsys_cs *cs, + struct radeon_winsys_cs_handle *buf); +}; #endif -- cgit v1.2.3