101e04c3fSmrg/* 201e04c3fSmrg * Copyright 2014, 2015 Red Hat. 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * on the rights to use, copy, modify, merge, publish, distribute, sub 801e04c3fSmrg * license, and/or sell copies of the Software, and to permit persons to whom 901e04c3fSmrg * the Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 1901e04c3fSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2001e04c3fSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2101e04c3fSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#ifndef VIRGL_RESOURCE_H 2501e04c3fSmrg#define VIRGL_RESOURCE_H 2601e04c3fSmrg 2701e04c3fSmrg#include "util/u_resource.h" 2801e04c3fSmrg#include "util/u_range.h" 2901e04c3fSmrg#include "util/list.h" 3001e04c3fSmrg#include "util/u_transfer.h" 3101e04c3fSmrg 327ec681f3Smrg#include "virtio-gpu/virgl_hw.h" 339f464c52Smaya#include "virgl_screen.h" 3401e04c3fSmrg#define VR_MAX_TEXTURE_2D_LEVELS 15 3501e04c3fSmrg 367ec681f3Smrg#define VIRGL_BLOB_MEM_GUEST 1 377ec681f3Smrg#define VIRGL_BLOB_MEM_HOST3D 2 387ec681f3Smrg#define VIRGL_BLOB_MEM_HOST3D_GUEST 3 397ec681f3Smrg 4001e04c3fSmrgstruct winsys_handle; 4101e04c3fSmrgstruct virgl_screen; 4201e04c3fSmrgstruct virgl_context; 4301e04c3fSmrg 449f464c52Smayastruct virgl_resource_metadata 459f464c52Smaya{ 469f464c52Smaya unsigned long level_offset[VR_MAX_TEXTURE_2D_LEVELS]; 479f464c52Smaya unsigned stride[VR_MAX_TEXTURE_2D_LEVELS]; 489f464c52Smaya unsigned layer_stride[VR_MAX_TEXTURE_2D_LEVELS]; 497ec681f3Smrg uint32_t plane, plane_offset, total_size; 507ec681f3Smrg uint64_t modifier; 519f464c52Smaya}; 529f464c52Smaya 5301e04c3fSmrgstruct virgl_resource { 547ec681f3Smrg struct pipe_resource b; 559f464c52Smaya uint16_t clean_mask; 5601e04c3fSmrg struct virgl_hw_res *hw_res; 579f464c52Smaya struct virgl_resource_metadata metadata; 587ec681f3Smrg 597ec681f3Smrg /* For PIPE_BUFFER only. Data outside of this range are uninitialized. */ 607ec681f3Smrg struct util_range valid_buffer_range; 617ec681f3Smrg 627ec681f3Smrg /* This mask indicates where the resource has been bound to, excluding 637ec681f3Smrg * pipe_surface binds. 647ec681f3Smrg * 657ec681f3Smrg * This is more accurate than pipe_resource::bind. Besides, 667ec681f3Smrg * pipe_resource::bind can be 0 with direct state access, and is not 677ec681f3Smrg * usable. 687ec681f3Smrg */ 697ec681f3Smrg unsigned bind_history; 707ec681f3Smrg uint32_t blob_mem; 7101e04c3fSmrg}; 7201e04c3fSmrg 7301e04c3fSmrgstruct virgl_transfer { 7401e04c3fSmrg struct pipe_transfer base; 759f464c52Smaya uint32_t offset, l_stride; 769f464c52Smaya struct util_range range; 779f464c52Smaya struct list_head queue_link; 789f464c52Smaya struct pipe_transfer *resolve_transfer; 797ec681f3Smrg 807ec681f3Smrg struct virgl_hw_res *hw_res; 819f464c52Smaya void *hw_res_map; 827ec681f3Smrg /* If not NULL, denotes that this is a copy transfer, i.e., 837ec681f3Smrg * that the transfer source data should be taken from this 847ec681f3Smrg * resource instead of the original transfer resource. 857ec681f3Smrg */ 867ec681f3Smrg struct virgl_hw_res *copy_src_hw_res; 877ec681f3Smrg /* The offset in the copy source resource to copy data from. */ 887ec681f3Smrg uint32_t copy_src_offset; 8901e04c3fSmrg}; 9001e04c3fSmrg 9101e04c3fSmrgvoid virgl_resource_destroy(struct pipe_screen *screen, 9201e04c3fSmrg struct pipe_resource *resource); 9301e04c3fSmrg 9401e04c3fSmrgvoid virgl_init_screen_resource_functions(struct pipe_screen *screen); 9501e04c3fSmrg 9601e04c3fSmrgvoid virgl_init_context_resource_functions(struct pipe_context *ctx); 9701e04c3fSmrg 989f464c52Smayavoid virgl_texture_init(struct virgl_resource *res); 9901e04c3fSmrg 10001e04c3fSmrgstatic inline struct virgl_resource *virgl_resource(struct pipe_resource *r) 10101e04c3fSmrg{ 10201e04c3fSmrg return (struct virgl_resource *)r; 10301e04c3fSmrg} 10401e04c3fSmrg 10501e04c3fSmrgstatic inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans) 10601e04c3fSmrg{ 10701e04c3fSmrg return (struct virgl_transfer *)trans; 10801e04c3fSmrg} 10901e04c3fSmrg 1107ec681f3Smrgvoid virgl_buffer_transfer_flush_region(struct pipe_context *ctx, 1117ec681f3Smrg struct pipe_transfer *transfer, 1127ec681f3Smrg const struct pipe_box *box); 1137ec681f3Smrg 1147ec681f3Smrgvoid virgl_buffer_transfer_unmap(struct pipe_context *ctx, 1157ec681f3Smrg struct pipe_transfer *transfer); 1167ec681f3Smrg 1179f464c52Smayavoid virgl_buffer_init(struct virgl_resource *res); 11801e04c3fSmrg 1197ec681f3Smrgstatic inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs, 1207ec681f3Smrg unsigned pbind) 12101e04c3fSmrg{ 12201e04c3fSmrg unsigned outbind = 0; 12301e04c3fSmrg if (pbind & PIPE_BIND_DEPTH_STENCIL) 12401e04c3fSmrg outbind |= VIRGL_BIND_DEPTH_STENCIL; 12501e04c3fSmrg if (pbind & PIPE_BIND_RENDER_TARGET) 12601e04c3fSmrg outbind |= VIRGL_BIND_RENDER_TARGET; 12701e04c3fSmrg if (pbind & PIPE_BIND_SAMPLER_VIEW) 12801e04c3fSmrg outbind |= VIRGL_BIND_SAMPLER_VIEW; 12901e04c3fSmrg if (pbind & PIPE_BIND_VERTEX_BUFFER) 13001e04c3fSmrg outbind |= VIRGL_BIND_VERTEX_BUFFER; 13101e04c3fSmrg if (pbind & PIPE_BIND_INDEX_BUFFER) 13201e04c3fSmrg outbind |= VIRGL_BIND_INDEX_BUFFER; 13301e04c3fSmrg if (pbind & PIPE_BIND_CONSTANT_BUFFER) 13401e04c3fSmrg outbind |= VIRGL_BIND_CONSTANT_BUFFER; 13501e04c3fSmrg if (pbind & PIPE_BIND_DISPLAY_TARGET) 13601e04c3fSmrg outbind |= VIRGL_BIND_DISPLAY_TARGET; 13701e04c3fSmrg if (pbind & PIPE_BIND_STREAM_OUTPUT) 13801e04c3fSmrg outbind |= VIRGL_BIND_STREAM_OUTPUT; 13901e04c3fSmrg if (pbind & PIPE_BIND_CURSOR) 14001e04c3fSmrg outbind |= VIRGL_BIND_CURSOR; 14101e04c3fSmrg if (pbind & PIPE_BIND_CUSTOM) 14201e04c3fSmrg outbind |= VIRGL_BIND_CUSTOM; 14301e04c3fSmrg if (pbind & PIPE_BIND_SCANOUT) 14401e04c3fSmrg outbind |= VIRGL_BIND_SCANOUT; 1457ec681f3Smrg if (pbind & PIPE_BIND_SHARED) 1467ec681f3Smrg outbind |= VIRGL_BIND_SHARED; 14701e04c3fSmrg if (pbind & PIPE_BIND_SHADER_BUFFER) 14801e04c3fSmrg outbind |= VIRGL_BIND_SHADER_BUFFER; 1499f464c52Smaya if (pbind & PIPE_BIND_QUERY_BUFFER) 1509f464c52Smaya outbind |= VIRGL_BIND_QUERY_BUFFER; 1519f464c52Smaya if (pbind & PIPE_BIND_COMMAND_ARGS_BUFFER) 1529f464c52Smaya if (vs->caps.caps.v2.capability_bits & VIRGL_CAP_BIND_COMMAND_ARGS) 1539f464c52Smaya outbind |= VIRGL_BIND_COMMAND_ARGS; 1547ec681f3Smrg 1557ec681f3Smrg /* Staging resources should only be created directly through the winsys, 1567ec681f3Smrg * not using pipe_resources. 1577ec681f3Smrg */ 1587ec681f3Smrg assert(!(outbind & VIRGL_BIND_STAGING)); 1597ec681f3Smrg 16001e04c3fSmrg return outbind; 16101e04c3fSmrg} 16201e04c3fSmrg 1637ec681f3Smrgstatic inline unsigned pipe_to_virgl_flags(const struct virgl_screen *vs, 1647ec681f3Smrg unsigned pflags) 1657ec681f3Smrg{ 1667ec681f3Smrg unsigned out_flags = 0; 1677ec681f3Smrg if (pflags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) 1687ec681f3Smrg out_flags |= VIRGL_RESOURCE_FLAG_MAP_PERSISTENT; 1697ec681f3Smrg 1707ec681f3Smrg if (pflags & PIPE_RESOURCE_FLAG_MAP_COHERENT) 1717ec681f3Smrg out_flags |= VIRGL_RESOURCE_FLAG_MAP_COHERENT; 1729f464c52Smaya 1737ec681f3Smrg return out_flags; 1747ec681f3Smrg} 1757ec681f3Smrg 1767ec681f3Smrgvoid * 1777ec681f3Smrgvirgl_resource_transfer_map(struct pipe_context *ctx, 1787ec681f3Smrg struct pipe_resource *resource, 1797ec681f3Smrg unsigned level, 1807ec681f3Smrg unsigned usage, 1817ec681f3Smrg const struct pipe_box *box, 1827ec681f3Smrg struct pipe_transfer **transfer); 1839f464c52Smaya 1849f464c52Smayastruct virgl_transfer * 1857ec681f3Smrgvirgl_resource_create_transfer(struct virgl_context *vctx, 1869f464c52Smaya struct pipe_resource *pres, 1879f464c52Smaya const struct virgl_resource_metadata *metadata, 1889f464c52Smaya unsigned level, unsigned usage, 1899f464c52Smaya const struct pipe_box *box); 1909f464c52Smaya 1917ec681f3Smrgvoid virgl_resource_destroy_transfer(struct virgl_context *vctx, 1929f464c52Smaya struct virgl_transfer *trans); 1939f464c52Smaya 1949f464c52Smayavoid virgl_resource_destroy(struct pipe_screen *screen, 1959f464c52Smaya struct pipe_resource *resource); 1969f464c52Smaya 1977ec681f3Smrgbool virgl_resource_get_handle(struct pipe_screen *screen, 1987ec681f3Smrg struct pipe_context *context, 1997ec681f3Smrg struct pipe_resource *resource, 2007ec681f3Smrg struct winsys_handle *whandle, 2017ec681f3Smrg unsigned usage); 2029f464c52Smaya 2039f464c52Smayavoid virgl_resource_dirty(struct virgl_resource *res, uint32_t level); 2049f464c52Smaya 2057ec681f3Smrgvoid *virgl_texture_transfer_map(struct pipe_context *ctx, 2067ec681f3Smrg struct pipe_resource *resource, 2077ec681f3Smrg unsigned level, 2087ec681f3Smrg unsigned usage, 2097ec681f3Smrg const struct pipe_box *box, 2107ec681f3Smrg struct pipe_transfer **transfer); 2117ec681f3Smrg 2127ec681f3Smrgvoid virgl_texture_transfer_unmap(struct pipe_context *ctx, 2137ec681f3Smrg struct pipe_transfer *transfer); 2147ec681f3Smrg 21501e04c3fSmrg#endif 216