/* * Copyright 2008 Corbin Simpson * * 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 above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * 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. */ #include "radeon_drm_buffer.h" #include "util/u_memory.h" #include "pipebuffer/pb_bufmgr.h" #include "state_tracker/drm_driver.h" static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage, enum r300_buffer_domain domain) { unsigned res = 0; if (bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT)) res |= PB_USAGE_GPU_WRITE; if (bind & PIPE_BIND_SAMPLER_VIEW) res |= PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE; if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) res |= PB_USAGE_GPU_READ; if (bind & PIPE_BIND_TRANSFER_WRITE) res |= PB_USAGE_CPU_WRITE; if (bind & PIPE_BIND_TRANSFER_READ) res |= PB_USAGE_CPU_READ; /* Is usage of any use for us? Probably not. */ /* Now add driver-specific usage flags. */ if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) res |= RADEON_PB_USAGE_VERTEX; if (domain & R300_DOMAIN_GTT) res |= RADEON_PB_USAGE_DOMAIN_GTT; if (domain & R300_DOMAIN_VRAM) res |= RADEON_PB_USAGE_DOMAIN_VRAM; return res; } static struct r300_winsys_buffer * radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, unsigned size, unsigned alignment, unsigned bind, unsigned usage, enum r300_buffer_domain domain) { struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); struct pb_desc desc; struct pb_manager *provider; struct pb_buffer *buffer; memset(&desc, 0, sizeof(desc)); desc.alignment = alignment; desc.usage = get_pb_usage_from_create_flags(bind, usage, domain); /* Assign a buffer manager. */ if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) provider = ws->cman; else provider = ws->kman; buffer = provider->create_buffer(provider, size, &desc); if (!buffer) return NULL; return (struct r300_winsys_buffer*)buffer; } static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, struct r300_winsys_buffer **pdst, struct r300_winsys_buffer *src) { struct pb_buffer *_src = radeon_pb_buffer(src); struct pb_buffer *_dst = radeon_pb_buffer(*pdst); pb_reference(&_dst, _src); *pdst = (struct r300_winsys_buffer*)_dst; } static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws, struct winsys_handle *whandle, unsigned *stride, unsigned *size) { struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); struct pb_buffer *_buf; _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle); if (stride) *stride = whandle->stride; if (size) *size = _buf->base.size; return (struct r300_winsys_buffer*)_buf; } static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws, struct r300_winsys_buffer *buffer, unsigned stride, struct winsys_handle *whandle) { struct pb_buffer *_buf = radeon_pb_buffer(buffer); whandle->stride = stride; return radeon_drm_bufmgr_get_handle(_buf, whandle); } 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_1_0: return ws->drm_major*100 + ws->drm_minor >= 201; case R300_VID_DRM_2_3_0: return ws->drm_major*100 + ws->drm_minor >= 203; 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; } void radeon_winsys_init_functions(struct radeon_drm_winsys *ws) { ws->base.get_value = radeon_get_value; ws->base.buffer_create = radeon_r300_winsys_buffer_create; ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle; ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle; }