Path: blob/21.2-virgl/src/gallium/drivers/tegra/tegra_context.c
4570 views
/*1* Copyright © 2014-2018 NVIDIA Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <inttypes.h>24#include <stdlib.h>2526#include "util/u_debug.h"27#include "util/u_draw.h"28#include "util/u_inlines.h"29#include "util/u_upload_mgr.h"3031#include "tegra_context.h"32#include "tegra_resource.h"33#include "tegra_screen.h"3435static void36tegra_destroy(struct pipe_context *pcontext)37{38struct tegra_context *context = to_tegra_context(pcontext);3940if (context->base.stream_uploader)41u_upload_destroy(context->base.stream_uploader);4243context->gpu->destroy(context->gpu);44free(context);45}4647static void48tegra_draw_vbo(struct pipe_context *pcontext,49const struct pipe_draw_info *pinfo,50unsigned drawid_offset,51const struct pipe_draw_indirect_info *pindirect,52const struct pipe_draw_start_count_bias *draws,53unsigned num_draws)54{55if (num_draws > 1) {56util_draw_multi(pcontext, pinfo, drawid_offset, pindirect, draws, num_draws);57return;58}5960if (!pindirect && (!draws[0].count || !pinfo->instance_count))61return;6263struct tegra_context *context = to_tegra_context(pcontext);64struct pipe_draw_indirect_info indirect;65struct pipe_draw_info info;6667if (pinfo && ((pindirect && pindirect->buffer) || pinfo->index_size)) {68memcpy(&info, pinfo, sizeof(info));6970if (pindirect && pindirect->buffer) {71memcpy(&indirect, pindirect, sizeof(indirect));72indirect.buffer = tegra_resource_unwrap(pindirect->buffer);73indirect.indirect_draw_count = tegra_resource_unwrap(pindirect->indirect_draw_count);74pindirect = &indirect;75}7677if (pinfo->index_size && !pinfo->has_user_indices)78info.index.resource = tegra_resource_unwrap(info.index.resource);7980pinfo = &info;81}8283context->gpu->draw_vbo(context->gpu, pinfo, drawid_offset, pindirect, draws, num_draws);84}8586static void87tegra_render_condition(struct pipe_context *pcontext,88struct pipe_query *query,89bool condition,90unsigned int mode)91{92struct tegra_context *context = to_tegra_context(pcontext);9394context->gpu->render_condition(context->gpu, query, condition, mode);95}9697static struct pipe_query *98tegra_create_query(struct pipe_context *pcontext, unsigned int query_type,99unsigned int index)100{101struct tegra_context *context = to_tegra_context(pcontext);102103return context->gpu->create_query(context->gpu, query_type, index);104}105106static struct pipe_query *107tegra_create_batch_query(struct pipe_context *pcontext,108unsigned int num_queries,109unsigned int *queries)110{111struct tegra_context *context = to_tegra_context(pcontext);112113return context->gpu->create_batch_query(context->gpu, num_queries,114queries);115}116117static void118tegra_destroy_query(struct pipe_context *pcontext, struct pipe_query *query)119{120struct tegra_context *context = to_tegra_context(pcontext);121122context->gpu->destroy_query(context->gpu, query);123}124125static bool126tegra_begin_query(struct pipe_context *pcontext, struct pipe_query *query)127{128struct tegra_context *context = to_tegra_context(pcontext);129130return context->gpu->begin_query(context->gpu, query);131}132133static bool134tegra_end_query(struct pipe_context *pcontext, struct pipe_query *query)135{136struct tegra_context *context = to_tegra_context(pcontext);137138return context->gpu->end_query(context->gpu, query);139}140141static bool142tegra_get_query_result(struct pipe_context *pcontext,143struct pipe_query *query,144bool wait,145union pipe_query_result *result)146{147struct tegra_context *context = to_tegra_context(pcontext);148149return context->gpu->get_query_result(context->gpu, query, wait,150result);151}152153static void154tegra_get_query_result_resource(struct pipe_context *pcontext,155struct pipe_query *query,156bool wait,157enum pipe_query_value_type result_type,158int index,159struct pipe_resource *resource,160unsigned int offset)161{162struct tegra_context *context = to_tegra_context(pcontext);163164context->gpu->get_query_result_resource(context->gpu, query, wait,165result_type, index, resource,166offset);167}168169static void170tegra_set_active_query_state(struct pipe_context *pcontext, bool enable)171{172struct tegra_context *context = to_tegra_context(pcontext);173174context->gpu->set_active_query_state(context->gpu, enable);175}176177static void *178tegra_create_blend_state(struct pipe_context *pcontext,179const struct pipe_blend_state *cso)180{181struct tegra_context *context = to_tegra_context(pcontext);182183return context->gpu->create_blend_state(context->gpu, cso);184}185186static void187tegra_bind_blend_state(struct pipe_context *pcontext, void *so)188{189struct tegra_context *context = to_tegra_context(pcontext);190191context->gpu->bind_blend_state(context->gpu, so);192}193194static void195tegra_delete_blend_state(struct pipe_context *pcontext, void *so)196{197struct tegra_context *context = to_tegra_context(pcontext);198199context->gpu->delete_blend_state(context->gpu, so);200}201202static void *203tegra_create_sampler_state(struct pipe_context *pcontext,204const struct pipe_sampler_state *cso)205{206struct tegra_context *context = to_tegra_context(pcontext);207208return context->gpu->create_sampler_state(context->gpu, cso);209}210211static void212tegra_bind_sampler_states(struct pipe_context *pcontext, unsigned shader,213unsigned start_slot, unsigned num_samplers,214void **samplers)215{216struct tegra_context *context = to_tegra_context(pcontext);217218context->gpu->bind_sampler_states(context->gpu, shader, start_slot,219num_samplers, samplers);220}221222static void223tegra_delete_sampler_state(struct pipe_context *pcontext, void *so)224{225struct tegra_context *context = to_tegra_context(pcontext);226227context->gpu->delete_sampler_state(context->gpu, so);228}229230static void *231tegra_create_rasterizer_state(struct pipe_context *pcontext,232const struct pipe_rasterizer_state *cso)233{234struct tegra_context *context = to_tegra_context(pcontext);235236return context->gpu->create_rasterizer_state(context->gpu, cso);237}238239static void240tegra_bind_rasterizer_state(struct pipe_context *pcontext, void *so)241{242struct tegra_context *context = to_tegra_context(pcontext);243244context->gpu->bind_rasterizer_state(context->gpu, so);245}246247static void248tegra_delete_rasterizer_state(struct pipe_context *pcontext, void *so)249{250struct tegra_context *context = to_tegra_context(pcontext);251252context->gpu->delete_rasterizer_state(context->gpu, so);253}254255static void *256tegra_create_depth_stencil_alpha_state(struct pipe_context *pcontext,257const struct pipe_depth_stencil_alpha_state *cso)258{259struct tegra_context *context = to_tegra_context(pcontext);260261return context->gpu->create_depth_stencil_alpha_state(context->gpu, cso);262}263264static void265tegra_bind_depth_stencil_alpha_state(struct pipe_context *pcontext, void *so)266{267struct tegra_context *context = to_tegra_context(pcontext);268269context->gpu->bind_depth_stencil_alpha_state(context->gpu, so);270}271272static void273tegra_delete_depth_stencil_alpha_state(struct pipe_context *pcontext, void *so)274{275struct tegra_context *context = to_tegra_context(pcontext);276277context->gpu->delete_depth_stencil_alpha_state(context->gpu, so);278}279280static void *281tegra_create_fs_state(struct pipe_context *pcontext,282const struct pipe_shader_state *cso)283{284struct tegra_context *context = to_tegra_context(pcontext);285286return context->gpu->create_fs_state(context->gpu, cso);287}288289static void290tegra_bind_fs_state(struct pipe_context *pcontext, void *so)291{292struct tegra_context *context = to_tegra_context(pcontext);293294context->gpu->bind_fs_state(context->gpu, so);295}296297static void298tegra_delete_fs_state(struct pipe_context *pcontext, void *so)299{300struct tegra_context *context = to_tegra_context(pcontext);301302context->gpu->delete_fs_state(context->gpu, so);303}304305static void *306tegra_create_vs_state(struct pipe_context *pcontext,307const struct pipe_shader_state *cso)308{309struct tegra_context *context = to_tegra_context(pcontext);310311return context->gpu->create_vs_state(context->gpu, cso);312}313314static void315tegra_bind_vs_state(struct pipe_context *pcontext, void *so)316{317struct tegra_context *context = to_tegra_context(pcontext);318319context->gpu->bind_vs_state(context->gpu, so);320}321322static void323tegra_delete_vs_state(struct pipe_context *pcontext, void *so)324{325struct tegra_context *context = to_tegra_context(pcontext);326327context->gpu->delete_vs_state(context->gpu, so);328}329330static void *331tegra_create_gs_state(struct pipe_context *pcontext,332const struct pipe_shader_state *cso)333{334struct tegra_context *context = to_tegra_context(pcontext);335336return context->gpu->create_gs_state(context->gpu, cso);337}338339static void340tegra_bind_gs_state(struct pipe_context *pcontext, void *so)341{342struct tegra_context *context = to_tegra_context(pcontext);343344context->gpu->bind_gs_state(context->gpu, so);345}346347static void348tegra_delete_gs_state(struct pipe_context *pcontext, void *so)349{350struct tegra_context *context = to_tegra_context(pcontext);351352context->gpu->delete_gs_state(context->gpu, so);353}354355static void *356tegra_create_tcs_state(struct pipe_context *pcontext,357const struct pipe_shader_state *cso)358{359struct tegra_context *context = to_tegra_context(pcontext);360361return context->gpu->create_tcs_state(context->gpu, cso);362}363364static void365tegra_bind_tcs_state(struct pipe_context *pcontext, void *so)366{367struct tegra_context *context = to_tegra_context(pcontext);368369context->gpu->bind_tcs_state(context->gpu, so);370}371372static void373tegra_delete_tcs_state(struct pipe_context *pcontext, void *so)374{375struct tegra_context *context = to_tegra_context(pcontext);376377context->gpu->delete_tcs_state(context->gpu, so);378}379380static void *381tegra_create_tes_state(struct pipe_context *pcontext,382const struct pipe_shader_state *cso)383{384struct tegra_context *context = to_tegra_context(pcontext);385386return context->gpu->create_tes_state(context->gpu, cso);387}388389static void390tegra_bind_tes_state(struct pipe_context *pcontext, void *so)391{392struct tegra_context *context = to_tegra_context(pcontext);393394context->gpu->bind_tes_state(context->gpu, so);395}396397static void398tegra_delete_tes_state(struct pipe_context *pcontext, void *so)399{400struct tegra_context *context = to_tegra_context(pcontext);401402context->gpu->delete_tes_state(context->gpu, so);403}404405static void *406tegra_create_vertex_elements_state(struct pipe_context *pcontext,407unsigned num_elements,408const struct pipe_vertex_element *elements)409{410struct tegra_context *context = to_tegra_context(pcontext);411412return context->gpu->create_vertex_elements_state(context->gpu,413num_elements,414elements);415}416417static void418tegra_bind_vertex_elements_state(struct pipe_context *pcontext, void *so)419{420struct tegra_context *context = to_tegra_context(pcontext);421422context->gpu->bind_vertex_elements_state(context->gpu, so);423}424425static void426tegra_delete_vertex_elements_state(struct pipe_context *pcontext, void *so)427{428struct tegra_context *context = to_tegra_context(pcontext);429430context->gpu->delete_vertex_elements_state(context->gpu, so);431}432433static void434tegra_set_blend_color(struct pipe_context *pcontext,435const struct pipe_blend_color *color)436{437struct tegra_context *context = to_tegra_context(pcontext);438439context->gpu->set_blend_color(context->gpu, color);440}441442static void443tegra_set_stencil_ref(struct pipe_context *pcontext,444const struct pipe_stencil_ref ref)445{446struct tegra_context *context = to_tegra_context(pcontext);447448context->gpu->set_stencil_ref(context->gpu, ref);449}450451static void452tegra_set_sample_mask(struct pipe_context *pcontext, unsigned int mask)453{454struct tegra_context *context = to_tegra_context(pcontext);455456context->gpu->set_sample_mask(context->gpu, mask);457}458459static void460tegra_set_min_samples(struct pipe_context *pcontext, unsigned int samples)461{462struct tegra_context *context = to_tegra_context(pcontext);463464context->gpu->set_min_samples(context->gpu, samples);465}466467static void468tegra_set_clip_state(struct pipe_context *pcontext,469const struct pipe_clip_state *state)470{471struct tegra_context *context = to_tegra_context(pcontext);472473context->gpu->set_clip_state(context->gpu, state);474}475476static void477tegra_set_constant_buffer(struct pipe_context *pcontext, unsigned int shader,478unsigned int index, bool take_ownership,479const struct pipe_constant_buffer *buf)480{481struct tegra_context *context = to_tegra_context(pcontext);482struct pipe_constant_buffer buffer;483484if (buf && buf->buffer) {485memcpy(&buffer, buf, sizeof(buffer));486buffer.buffer = tegra_resource_unwrap(buffer.buffer);487buf = &buffer;488}489490context->gpu->set_constant_buffer(context->gpu, shader, index, take_ownership, buf);491}492493static void494tegra_set_framebuffer_state(struct pipe_context *pcontext,495const struct pipe_framebuffer_state *fb)496{497struct tegra_context *context = to_tegra_context(pcontext);498struct pipe_framebuffer_state state;499unsigned i;500501if (fb) {502memcpy(&state, fb, sizeof(state));503504for (i = 0; i < fb->nr_cbufs; i++)505state.cbufs[i] = tegra_surface_unwrap(fb->cbufs[i]);506507while (i < PIPE_MAX_COLOR_BUFS)508state.cbufs[i++] = NULL;509510state.zsbuf = tegra_surface_unwrap(fb->zsbuf);511512fb = &state;513}514515context->gpu->set_framebuffer_state(context->gpu, fb);516}517518static void519tegra_set_polygon_stipple(struct pipe_context *pcontext,520const struct pipe_poly_stipple *stipple)521{522struct tegra_context *context = to_tegra_context(pcontext);523524context->gpu->set_polygon_stipple(context->gpu, stipple);525}526527static void528tegra_set_scissor_states(struct pipe_context *pcontext, unsigned start_slot,529unsigned num_scissors,530const struct pipe_scissor_state *scissors)531{532struct tegra_context *context = to_tegra_context(pcontext);533534context->gpu->set_scissor_states(context->gpu, start_slot, num_scissors,535scissors);536}537538static void539tegra_set_window_rectangles(struct pipe_context *pcontext, bool include,540unsigned int num_rectangles,541const struct pipe_scissor_state *rectangles)542{543struct tegra_context *context = to_tegra_context(pcontext);544545context->gpu->set_window_rectangles(context->gpu, include, num_rectangles,546rectangles);547}548549static void550tegra_set_viewport_states(struct pipe_context *pcontext, unsigned start_slot,551unsigned num_viewports,552const struct pipe_viewport_state *viewports)553{554struct tegra_context *context = to_tegra_context(pcontext);555556context->gpu->set_viewport_states(context->gpu, start_slot, num_viewports,557viewports);558}559560static void561tegra_set_sampler_views(struct pipe_context *pcontext, unsigned shader,562unsigned start_slot, unsigned num_views,563unsigned unbind_num_trailing_slots,564struct pipe_sampler_view **pviews)565{566struct pipe_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS];567struct tegra_context *context = to_tegra_context(pcontext);568unsigned i;569570for (i = 0; i < num_views; i++)571views[i] = tegra_sampler_view_unwrap(pviews[i]);572573context->gpu->set_sampler_views(context->gpu, shader, start_slot,574num_views, unbind_num_trailing_slots,575views);576}577578static void579tegra_set_tess_state(struct pipe_context *pcontext,580const float default_outer_level[4],581const float default_inner_level[2])582{583struct tegra_context *context = to_tegra_context(pcontext);584585context->gpu->set_tess_state(context->gpu, default_outer_level,586default_inner_level);587}588589static void590tegra_set_debug_callback(struct pipe_context *pcontext,591const struct pipe_debug_callback *callback)592{593struct tegra_context *context = to_tegra_context(pcontext);594595context->gpu->set_debug_callback(context->gpu, callback);596}597598static void599tegra_set_shader_buffers(struct pipe_context *pcontext, unsigned int shader,600unsigned start, unsigned count,601const struct pipe_shader_buffer *buffers,602unsigned writable_bitmask)603{604struct tegra_context *context = to_tegra_context(pcontext);605606context->gpu->set_shader_buffers(context->gpu, shader, start, count,607buffers, writable_bitmask);608}609610static void611tegra_set_shader_images(struct pipe_context *pcontext, unsigned int shader,612unsigned start, unsigned count,613unsigned unbind_num_trailing_slots,614const struct pipe_image_view *images)615{616struct tegra_context *context = to_tegra_context(pcontext);617618context->gpu->set_shader_images(context->gpu, shader, start, count,619unbind_num_trailing_slots, images);620}621622static void623tegra_set_vertex_buffers(struct pipe_context *pcontext, unsigned start_slot,624unsigned num_buffers, unsigned unbind_num_trailing_slots,625bool take_ownership,626const struct pipe_vertex_buffer *buffers)627{628struct tegra_context *context = to_tegra_context(pcontext);629struct pipe_vertex_buffer buf[PIPE_MAX_SHADER_INPUTS];630unsigned i;631632if (num_buffers && buffers) {633memcpy(buf, buffers, num_buffers * sizeof(struct pipe_vertex_buffer));634635for (i = 0; i < num_buffers; i++) {636if (!buf[i].is_user_buffer)637buf[i].buffer.resource = tegra_resource_unwrap(buf[i].buffer.resource);638}639640buffers = buf;641}642643context->gpu->set_vertex_buffers(context->gpu, start_slot, num_buffers,644unbind_num_trailing_slots,645take_ownership, buffers);646}647648static struct pipe_stream_output_target *649tegra_create_stream_output_target(struct pipe_context *pcontext,650struct pipe_resource *presource,651unsigned buffer_offset,652unsigned buffer_size)653{654struct tegra_resource *resource = to_tegra_resource(presource);655struct tegra_context *context = to_tegra_context(pcontext);656657return context->gpu->create_stream_output_target(context->gpu,658resource->gpu,659buffer_offset,660buffer_size);661}662663static void664tegra_stream_output_target_destroy(struct pipe_context *pcontext,665struct pipe_stream_output_target *target)666{667struct tegra_context *context = to_tegra_context(pcontext);668669context->gpu->stream_output_target_destroy(context->gpu, target);670}671672static void673tegra_set_stream_output_targets(struct pipe_context *pcontext,674unsigned num_targets,675struct pipe_stream_output_target **targets,676const unsigned *offsets)677{678struct tegra_context *context = to_tegra_context(pcontext);679680context->gpu->set_stream_output_targets(context->gpu, num_targets,681targets, offsets);682}683684static void685tegra_resource_copy_region(struct pipe_context *pcontext,686struct pipe_resource *pdst,687unsigned int dst_level,688unsigned int dstx,689unsigned int dsty,690unsigned int dstz,691struct pipe_resource *psrc,692unsigned int src_level,693const struct pipe_box *src_box)694{695struct tegra_context *context = to_tegra_context(pcontext);696struct tegra_resource *dst = to_tegra_resource(pdst);697struct tegra_resource *src = to_tegra_resource(psrc);698699context->gpu->resource_copy_region(context->gpu, dst->gpu, dst_level, dstx,700dsty, dstz, src->gpu, src_level,701src_box);702}703704static void705tegra_blit(struct pipe_context *pcontext, const struct pipe_blit_info *pinfo)706{707struct tegra_context *context = to_tegra_context(pcontext);708struct pipe_blit_info info;709710if (pinfo) {711memcpy(&info, pinfo, sizeof(info));712info.dst.resource = tegra_resource_unwrap(info.dst.resource);713info.src.resource = tegra_resource_unwrap(info.src.resource);714pinfo = &info;715}716717context->gpu->blit(context->gpu, pinfo);718}719720static void721tegra_clear(struct pipe_context *pcontext, unsigned buffers, const struct pipe_scissor_state *scissor_state,722const union pipe_color_union *color, double depth,723unsigned stencil)724{725struct tegra_context *context = to_tegra_context(pcontext);726727context->gpu->clear(context->gpu, buffers, NULL, color, depth, stencil);728}729730static void731tegra_clear_render_target(struct pipe_context *pcontext,732struct pipe_surface *pdst,733const union pipe_color_union *color,734unsigned int dstx,735unsigned int dsty,736unsigned int width,737unsigned int height,738bool render_condition)739{740struct tegra_context *context = to_tegra_context(pcontext);741struct tegra_surface *dst = to_tegra_surface(pdst);742743context->gpu->clear_render_target(context->gpu, dst->gpu, color, dstx,744dsty, width, height, render_condition);745}746747static void748tegra_clear_depth_stencil(struct pipe_context *pcontext,749struct pipe_surface *pdst,750unsigned int flags,751double depth,752unsigned int stencil,753unsigned int dstx,754unsigned int dsty,755unsigned int width,756unsigned int height,757bool render_condition)758{759struct tegra_context *context = to_tegra_context(pcontext);760struct tegra_surface *dst = to_tegra_surface(pdst);761762context->gpu->clear_depth_stencil(context->gpu, dst->gpu, flags, depth,763stencil, dstx, dsty, width, height,764render_condition);765}766767static void768tegra_clear_texture(struct pipe_context *pcontext,769struct pipe_resource *presource,770unsigned int level,771const struct pipe_box *box,772const void *data)773{774struct tegra_resource *resource = to_tegra_resource(presource);775struct tegra_context *context = to_tegra_context(pcontext);776777context->gpu->clear_texture(context->gpu, resource->gpu, level, box, data);778}779780static void781tegra_clear_buffer(struct pipe_context *pcontext,782struct pipe_resource *presource,783unsigned int offset,784unsigned int size,785const void *value,786int value_size)787{788struct tegra_resource *resource = to_tegra_resource(presource);789struct tegra_context *context = to_tegra_context(pcontext);790791context->gpu->clear_buffer(context->gpu, resource->gpu, offset, size,792value, value_size);793}794795static void796tegra_flush(struct pipe_context *pcontext, struct pipe_fence_handle **fence,797unsigned flags)798{799struct tegra_context *context = to_tegra_context(pcontext);800801context->gpu->flush(context->gpu, fence, flags);802}803804static void805tegra_create_fence_fd(struct pipe_context *pcontext,806struct pipe_fence_handle **fence,807int fd, enum pipe_fd_type type)808{809struct tegra_context *context = to_tegra_context(pcontext);810811assert(type == PIPE_FD_TYPE_NATIVE_SYNC);812context->gpu->create_fence_fd(context->gpu, fence, fd, type);813}814815static void816tegra_fence_server_sync(struct pipe_context *pcontext,817struct pipe_fence_handle *fence)818{819struct tegra_context *context = to_tegra_context(pcontext);820821context->gpu->fence_server_sync(context->gpu, fence);822}823824static struct pipe_sampler_view *825tegra_create_sampler_view(struct pipe_context *pcontext,826struct pipe_resource *presource,827const struct pipe_sampler_view *template)828{829struct tegra_resource *resource = to_tegra_resource(presource);830struct tegra_context *context = to_tegra_context(pcontext);831struct tegra_sampler_view *view;832833view = calloc(1, sizeof(*view));834if (!view)835return NULL;836837view->gpu = context->gpu->create_sampler_view(context->gpu, resource->gpu,838template);839memcpy(&view->base, view->gpu, sizeof(*view->gpu));840/* overwrite to prevent reference from being released */841view->base.texture = NULL;842843pipe_reference_init(&view->base.reference, 1);844pipe_resource_reference(&view->base.texture, presource);845view->base.context = pcontext;846847return &view->base;848}849850static void851tegra_sampler_view_destroy(struct pipe_context *pcontext,852struct pipe_sampler_view *pview)853{854struct tegra_sampler_view *view = to_tegra_sampler_view(pview);855856pipe_resource_reference(&view->base.texture, NULL);857pipe_sampler_view_reference(&view->gpu, NULL);858free(view);859}860861static struct pipe_surface *862tegra_create_surface(struct pipe_context *pcontext,863struct pipe_resource *presource,864const struct pipe_surface *template)865{866struct tegra_resource *resource = to_tegra_resource(presource);867struct tegra_context *context = to_tegra_context(pcontext);868struct tegra_surface *surface;869870surface = calloc(1, sizeof(*surface));871if (!surface)872return NULL;873874surface->gpu = context->gpu->create_surface(context->gpu, resource->gpu,875template);876if (!surface->gpu) {877free(surface);878return NULL;879}880881memcpy(&surface->base, surface->gpu, sizeof(*surface->gpu));882/* overwrite to prevent reference from being released */883surface->base.texture = NULL;884885pipe_reference_init(&surface->base.reference, 1);886pipe_resource_reference(&surface->base.texture, presource);887surface->base.context = &context->base;888889return &surface->base;890}891892static void893tegra_surface_destroy(struct pipe_context *pcontext,894struct pipe_surface *psurface)895{896struct tegra_surface *surface = to_tegra_surface(psurface);897898pipe_resource_reference(&surface->base.texture, NULL);899pipe_surface_reference(&surface->gpu, NULL);900free(surface);901}902903static void *904tegra_transfer_map(struct pipe_context *pcontext,905struct pipe_resource *presource,906unsigned level, unsigned usage,907const struct pipe_box *box,908struct pipe_transfer **ptransfer)909{910struct tegra_resource *resource = to_tegra_resource(presource);911struct tegra_context *context = to_tegra_context(pcontext);912struct tegra_transfer *transfer;913914transfer = calloc(1, sizeof(*transfer));915if (!transfer)916return NULL;917918if (presource->target == PIPE_BUFFER) {919transfer->map = context->gpu->buffer_map(context->gpu, resource->gpu,920level, usage, box,921&transfer->gpu);922} else {923transfer->map = context->gpu->texture_map(context->gpu, resource->gpu,924level, usage, box,925&transfer->gpu);926}927memcpy(&transfer->base, transfer->gpu, sizeof(*transfer->gpu));928transfer->base.resource = NULL;929pipe_resource_reference(&transfer->base.resource, presource);930931*ptransfer = &transfer->base;932933return transfer->map;934}935936static void937tegra_transfer_flush_region(struct pipe_context *pcontext,938struct pipe_transfer *ptransfer,939const struct pipe_box *box)940{941struct tegra_transfer *transfer = to_tegra_transfer(ptransfer);942struct tegra_context *context = to_tegra_context(pcontext);943944context->gpu->transfer_flush_region(context->gpu, transfer->gpu, box);945}946947static void948tegra_transfer_unmap(struct pipe_context *pcontext,949struct pipe_transfer *ptransfer)950{951struct tegra_transfer *transfer = to_tegra_transfer(ptransfer);952struct tegra_context *context = to_tegra_context(pcontext);953954if (ptransfer->resource->target == PIPE_BUFFER)955context->gpu->buffer_unmap(context->gpu, transfer->gpu);956else957context->gpu->texture_unmap(context->gpu, transfer->gpu);958pipe_resource_reference(&transfer->base.resource, NULL);959free(transfer);960}961962static void963tegra_buffer_subdata(struct pipe_context *pcontext,964struct pipe_resource *presource,965unsigned usage, unsigned offset,966unsigned size, const void *data)967{968struct tegra_resource *resource = to_tegra_resource(presource);969struct tegra_context *context = to_tegra_context(pcontext);970971context->gpu->buffer_subdata(context->gpu, resource->gpu, usage, offset,972size, data);973}974975static void976tegra_texture_subdata(struct pipe_context *pcontext,977struct pipe_resource *presource,978unsigned level,979unsigned usage,980const struct pipe_box *box,981const void *data,982unsigned stride,983unsigned layer_stride)984{985struct tegra_resource *resource = to_tegra_resource(presource);986struct tegra_context *context = to_tegra_context(pcontext);987988context->gpu->texture_subdata(context->gpu, resource->gpu, level, usage,989box, data, stride, layer_stride);990}991992static void993tegra_texture_barrier(struct pipe_context *pcontext, unsigned int flags)994{995struct tegra_context *context = to_tegra_context(pcontext);996997context->gpu->texture_barrier(context->gpu, flags);998}9991000static void1001tegra_memory_barrier(struct pipe_context *pcontext, unsigned int flags)1002{1003struct tegra_context *context = to_tegra_context(pcontext);10041005if (!(flags & ~PIPE_BARRIER_UPDATE))1006return;10071008context->gpu->memory_barrier(context->gpu, flags);1009}10101011static struct pipe_video_codec *1012tegra_create_video_codec(struct pipe_context *pcontext,1013const struct pipe_video_codec *template)1014{1015struct tegra_context *context = to_tegra_context(pcontext);10161017return context->gpu->create_video_codec(context->gpu, template);1018}10191020static struct pipe_video_buffer *1021tegra_create_video_buffer(struct pipe_context *pcontext,1022const struct pipe_video_buffer *template)1023{1024struct tegra_context *context = to_tegra_context(pcontext);10251026return context->gpu->create_video_buffer(context->gpu, template);1027}10281029static void *1030tegra_create_compute_state(struct pipe_context *pcontext,1031const struct pipe_compute_state *template)1032{1033struct tegra_context *context = to_tegra_context(pcontext);10341035return context->gpu->create_compute_state(context->gpu, template);1036}10371038static void1039tegra_bind_compute_state(struct pipe_context *pcontext, void *so)1040{1041struct tegra_context *context = to_tegra_context(pcontext);10421043context->gpu->bind_compute_state(context->gpu, so);1044}10451046static void1047tegra_delete_compute_state(struct pipe_context *pcontext, void *so)1048{1049struct tegra_context *context = to_tegra_context(pcontext);10501051context->gpu->delete_compute_state(context->gpu, so);1052}10531054static void1055tegra_set_compute_resources(struct pipe_context *pcontext,1056unsigned int start, unsigned int count,1057struct pipe_surface **resources)1058{1059struct tegra_context *context = to_tegra_context(pcontext);10601061/* XXX unwrap resources */10621063context->gpu->set_compute_resources(context->gpu, start, count, resources);1064}10651066static void1067tegra_set_global_binding(struct pipe_context *pcontext, unsigned int first,1068unsigned int count, struct pipe_resource **resources,1069uint32_t **handles)1070{1071struct tegra_context *context = to_tegra_context(pcontext);10721073/* XXX unwrap resources */10741075context->gpu->set_global_binding(context->gpu, first, count, resources,1076handles);1077}10781079static void1080tegra_launch_grid(struct pipe_context *pcontext,1081const struct pipe_grid_info *info)1082{1083struct tegra_context *context = to_tegra_context(pcontext);10841085/* XXX unwrap info->indirect? */10861087context->gpu->launch_grid(context->gpu, info);1088}10891090static void1091tegra_get_sample_position(struct pipe_context *pcontext, unsigned int count,1092unsigned int index, float *value)1093{1094struct tegra_context *context = to_tegra_context(pcontext);10951096context->gpu->get_sample_position(context->gpu, count, index, value);1097}10981099static uint64_t1100tegra_get_timestamp(struct pipe_context *pcontext)1101{1102struct tegra_context *context = to_tegra_context(pcontext);11031104return context->gpu->get_timestamp(context->gpu);1105}11061107static void1108tegra_flush_resource(struct pipe_context *pcontext,1109struct pipe_resource *presource)1110{1111struct tegra_resource *resource = to_tegra_resource(presource);1112struct tegra_context *context = to_tegra_context(pcontext);11131114context->gpu->flush_resource(context->gpu, resource->gpu);1115}11161117static void1118tegra_invalidate_resource(struct pipe_context *pcontext,1119struct pipe_resource *presource)1120{1121struct tegra_resource *resource = to_tegra_resource(presource);1122struct tegra_context *context = to_tegra_context(pcontext);11231124context->gpu->invalidate_resource(context->gpu, resource->gpu);1125}11261127static enum pipe_reset_status1128tegra_get_device_reset_status(struct pipe_context *pcontext)1129{1130struct tegra_context *context = to_tegra_context(pcontext);11311132return context->gpu->get_device_reset_status(context->gpu);1133}11341135static void1136tegra_set_device_reset_callback(struct pipe_context *pcontext,1137const struct pipe_device_reset_callback *cb)1138{1139struct tegra_context *context = to_tegra_context(pcontext);11401141context->gpu->set_device_reset_callback(context->gpu, cb);1142}11431144static void1145tegra_dump_debug_state(struct pipe_context *pcontext, FILE *stream,1146unsigned int flags)1147{1148struct tegra_context *context = to_tegra_context(pcontext);11491150context->gpu->dump_debug_state(context->gpu, stream, flags);1151}11521153static void1154tegra_emit_string_marker(struct pipe_context *pcontext, const char *string,1155int length)1156{1157struct tegra_context *context = to_tegra_context(pcontext);11581159context->gpu->emit_string_marker(context->gpu, string, length);1160}11611162static bool1163tegra_generate_mipmap(struct pipe_context *pcontext,1164struct pipe_resource *presource,1165enum pipe_format format,1166unsigned int base_level,1167unsigned int last_level,1168unsigned int first_layer,1169unsigned int last_layer)1170{1171struct tegra_resource *resource = to_tegra_resource(presource);1172struct tegra_context *context = to_tegra_context(pcontext);11731174return context->gpu->generate_mipmap(context->gpu, resource->gpu, format,1175base_level, last_level, first_layer,1176last_layer);1177}11781179static uint64_t1180tegra_create_texture_handle(struct pipe_context *pcontext,1181struct pipe_sampler_view *view,1182const struct pipe_sampler_state *state)1183{1184struct tegra_context *context = to_tegra_context(pcontext);11851186return context->gpu->create_texture_handle(context->gpu, view, state);1187}11881189static void tegra_delete_texture_handle(struct pipe_context *pcontext,1190uint64_t handle)1191{1192struct tegra_context *context = to_tegra_context(pcontext);11931194context->gpu->delete_texture_handle(context->gpu, handle);1195}11961197static void tegra_make_texture_handle_resident(struct pipe_context *pcontext,1198uint64_t handle, bool resident)1199{1200struct tegra_context *context = to_tegra_context(pcontext);12011202context->gpu->make_texture_handle_resident(context->gpu, handle, resident);1203}12041205static uint64_t tegra_create_image_handle(struct pipe_context *pcontext,1206const struct pipe_image_view *image)1207{1208struct tegra_context *context = to_tegra_context(pcontext);12091210return context->gpu->create_image_handle(context->gpu, image);1211}12121213static void tegra_delete_image_handle(struct pipe_context *pcontext,1214uint64_t handle)1215{1216struct tegra_context *context = to_tegra_context(pcontext);12171218context->gpu->delete_image_handle(context->gpu, handle);1219}12201221static void tegra_make_image_handle_resident(struct pipe_context *pcontext,1222uint64_t handle, unsigned access,1223bool resident)1224{1225struct tegra_context *context = to_tegra_context(pcontext);12261227context->gpu->make_image_handle_resident(context->gpu, handle, access,1228resident);1229}12301231struct pipe_context *1232tegra_screen_context_create(struct pipe_screen *pscreen, void *priv,1233unsigned int flags)1234{1235struct tegra_screen *screen = to_tegra_screen(pscreen);1236struct tegra_context *context;12371238context = calloc(1, sizeof(*context));1239if (!context)1240return NULL;12411242context->gpu = screen->gpu->context_create(screen->gpu, priv, flags);1243if (!context->gpu) {1244debug_error("failed to create GPU context\n");1245goto free;1246}12471248context->base.screen = &screen->base;1249context->base.priv = priv;12501251/*1252* Create custom stream and const uploaders. Note that technically nouveau1253* already creates uploaders that could be reused, but that would make the1254* resource unwrapping rather complicate. The reason for that is that both1255* uploaders create resources based on the context that they were created1256* from, which means that nouveau's uploader will use the nouveau context1257* which means that those resources must not be unwrapped. So before each1258* resource is unwrapped, the code would need to check that it does not1259* correspond to the uploaders' buffers.1260*1261* However, duplicating the uploaders here sounds worse than it is. The1262* default implementation that nouveau uses allocates buffers lazily, and1263* since it is never used, no buffers will every be allocated and the only1264* memory wasted is that occupied by the nouveau uploader itself.1265*/1266context->base.stream_uploader = u_upload_create_default(&context->base);1267if (!context->base.stream_uploader)1268goto destroy;12691270context->base.const_uploader = context->base.stream_uploader;12711272context->base.destroy = tegra_destroy;12731274context->base.draw_vbo = tegra_draw_vbo;12751276context->base.render_condition = tegra_render_condition;12771278context->base.create_query = tegra_create_query;1279context->base.create_batch_query = tegra_create_batch_query;1280context->base.destroy_query = tegra_destroy_query;1281context->base.begin_query = tegra_begin_query;1282context->base.end_query = tegra_end_query;1283context->base.get_query_result = tegra_get_query_result;1284context->base.get_query_result_resource = tegra_get_query_result_resource;1285context->base.set_active_query_state = tegra_set_active_query_state;12861287context->base.create_blend_state = tegra_create_blend_state;1288context->base.bind_blend_state = tegra_bind_blend_state;1289context->base.delete_blend_state = tegra_delete_blend_state;12901291context->base.create_sampler_state = tegra_create_sampler_state;1292context->base.bind_sampler_states = tegra_bind_sampler_states;1293context->base.delete_sampler_state = tegra_delete_sampler_state;12941295context->base.create_rasterizer_state = tegra_create_rasterizer_state;1296context->base.bind_rasterizer_state = tegra_bind_rasterizer_state;1297context->base.delete_rasterizer_state = tegra_delete_rasterizer_state;12981299context->base.create_depth_stencil_alpha_state = tegra_create_depth_stencil_alpha_state;1300context->base.bind_depth_stencil_alpha_state = tegra_bind_depth_stencil_alpha_state;1301context->base.delete_depth_stencil_alpha_state = tegra_delete_depth_stencil_alpha_state;13021303context->base.create_fs_state = tegra_create_fs_state;1304context->base.bind_fs_state = tegra_bind_fs_state;1305context->base.delete_fs_state = tegra_delete_fs_state;13061307context->base.create_vs_state = tegra_create_vs_state;1308context->base.bind_vs_state = tegra_bind_vs_state;1309context->base.delete_vs_state = tegra_delete_vs_state;13101311context->base.create_gs_state = tegra_create_gs_state;1312context->base.bind_gs_state = tegra_bind_gs_state;1313context->base.delete_gs_state = tegra_delete_gs_state;13141315context->base.create_tcs_state = tegra_create_tcs_state;1316context->base.bind_tcs_state = tegra_bind_tcs_state;1317context->base.delete_tcs_state = tegra_delete_tcs_state;13181319context->base.create_tes_state = tegra_create_tes_state;1320context->base.bind_tes_state = tegra_bind_tes_state;1321context->base.delete_tes_state = tegra_delete_tes_state;13221323context->base.create_vertex_elements_state = tegra_create_vertex_elements_state;1324context->base.bind_vertex_elements_state = tegra_bind_vertex_elements_state;1325context->base.delete_vertex_elements_state = tegra_delete_vertex_elements_state;13261327context->base.set_blend_color = tegra_set_blend_color;1328context->base.set_stencil_ref = tegra_set_stencil_ref;1329context->base.set_sample_mask = tegra_set_sample_mask;1330context->base.set_min_samples = tegra_set_min_samples;1331context->base.set_clip_state = tegra_set_clip_state;13321333context->base.set_constant_buffer = tegra_set_constant_buffer;1334context->base.set_framebuffer_state = tegra_set_framebuffer_state;1335context->base.set_polygon_stipple = tegra_set_polygon_stipple;1336context->base.set_scissor_states = tegra_set_scissor_states;1337context->base.set_window_rectangles = tegra_set_window_rectangles;1338context->base.set_viewport_states = tegra_set_viewport_states;1339context->base.set_sampler_views = tegra_set_sampler_views;1340context->base.set_tess_state = tegra_set_tess_state;13411342context->base.set_debug_callback = tegra_set_debug_callback;13431344context->base.set_shader_buffers = tegra_set_shader_buffers;1345context->base.set_shader_images = tegra_set_shader_images;1346context->base.set_vertex_buffers = tegra_set_vertex_buffers;13471348context->base.create_stream_output_target = tegra_create_stream_output_target;1349context->base.stream_output_target_destroy = tegra_stream_output_target_destroy;1350context->base.set_stream_output_targets = tegra_set_stream_output_targets;13511352context->base.resource_copy_region = tegra_resource_copy_region;1353context->base.blit = tegra_blit;1354context->base.clear = tegra_clear;1355context->base.clear_render_target = tegra_clear_render_target;1356context->base.clear_depth_stencil = tegra_clear_depth_stencil;1357context->base.clear_texture = tegra_clear_texture;1358context->base.clear_buffer = tegra_clear_buffer;1359context->base.flush = tegra_flush;13601361context->base.create_fence_fd = tegra_create_fence_fd;1362context->base.fence_server_sync = tegra_fence_server_sync;13631364context->base.create_sampler_view = tegra_create_sampler_view;1365context->base.sampler_view_destroy = tegra_sampler_view_destroy;13661367context->base.create_surface = tegra_create_surface;1368context->base.surface_destroy = tegra_surface_destroy;13691370context->base.buffer_map = tegra_transfer_map;1371context->base.texture_map = tegra_transfer_map;1372context->base.transfer_flush_region = tegra_transfer_flush_region;1373context->base.buffer_unmap = tegra_transfer_unmap;1374context->base.texture_unmap = tegra_transfer_unmap;1375context->base.buffer_subdata = tegra_buffer_subdata;1376context->base.texture_subdata = tegra_texture_subdata;13771378context->base.texture_barrier = tegra_texture_barrier;1379context->base.memory_barrier = tegra_memory_barrier;13801381context->base.create_video_codec = tegra_create_video_codec;1382context->base.create_video_buffer = tegra_create_video_buffer;13831384context->base.create_compute_state = tegra_create_compute_state;1385context->base.bind_compute_state = tegra_bind_compute_state;1386context->base.delete_compute_state = tegra_delete_compute_state;1387context->base.set_compute_resources = tegra_set_compute_resources;1388context->base.set_global_binding = tegra_set_global_binding;1389context->base.launch_grid = tegra_launch_grid;1390context->base.get_sample_position = tegra_get_sample_position;1391context->base.get_timestamp = tegra_get_timestamp;13921393context->base.flush_resource = tegra_flush_resource;1394context->base.invalidate_resource = tegra_invalidate_resource;13951396context->base.get_device_reset_status = tegra_get_device_reset_status;1397context->base.set_device_reset_callback = tegra_set_device_reset_callback;1398context->base.dump_debug_state = tegra_dump_debug_state;1399context->base.emit_string_marker = tegra_emit_string_marker;14001401context->base.generate_mipmap = tegra_generate_mipmap;14021403context->base.create_texture_handle = tegra_create_texture_handle;1404context->base.delete_texture_handle = tegra_delete_texture_handle;1405context->base.make_texture_handle_resident = tegra_make_texture_handle_resident;1406context->base.create_image_handle = tegra_create_image_handle;1407context->base.delete_image_handle = tegra_delete_image_handle;1408context->base.make_image_handle_resident = tegra_make_image_handle_resident;14091410return &context->base;14111412destroy:1413context->gpu->destroy(context->gpu);1414free:1415free(context);1416return NULL;1417}141814191420