Path: blob/21.2-virgl/src/gallium/drivers/svga/svga_pipe_misc.c
4570 views
/**********************************************************1* Copyright 2008-2009 VMware, Inc. All rights reserved.2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation5* files (the "Software"), to deal in the Software without6* restriction, including without limitation the rights to use, copy,7* modify, merge, publish, distribute, sublicense, and/or sell copies8* of the Software, and to permit persons to whom the Software is9* furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23**********************************************************/2425#include "util/u_framebuffer.h"26#include "util/u_inlines.h"27#include "util/u_pstipple.h"2829#include "svga_cmd.h"30#include "svga_context.h"31#include "svga_screen.h"32#include "svga_surface.h"33#include "svga_resource_texture.h"343536static void37svga_set_scissor_states(struct pipe_context *pipe,38unsigned start_slot,39unsigned num_scissors,40const struct pipe_scissor_state *scissors)41{42ASSERTED struct svga_screen *svgascreen = svga_screen(pipe->screen);43struct svga_context *svga = svga_context(pipe);44unsigned i, num_sc;4546assert(start_slot + num_scissors <= svgascreen->max_viewports);4748for (i = 0, num_sc = start_slot; i < num_scissors; i++) {49svga->curr.scissor[num_sc++] = scissors[i]; /* struct copy */50}5152svga->dirty |= SVGA_NEW_SCISSOR;53}545556static void57svga_set_polygon_stipple(struct pipe_context *pipe,58const struct pipe_poly_stipple *stipple)59{60struct svga_context *svga = svga_context(pipe);6162/* release old texture */63pipe_resource_reference(&svga->polygon_stipple.texture, NULL);6465/* release old sampler view */66if (svga->polygon_stipple.sampler_view) {67pipe->sampler_view_destroy(pipe,68&svga->polygon_stipple.sampler_view->base);69}7071/* create new stipple texture */72svga->polygon_stipple.texture =73util_pstipple_create_stipple_texture(pipe, stipple->stipple);7475/* create new sampler view */76svga->polygon_stipple.sampler_view =77(struct svga_pipe_sampler_view *)78util_pstipple_create_sampler_view(pipe,79svga->polygon_stipple.texture);8081/* allocate sampler state, if first time */82if (!svga->polygon_stipple.sampler) {83svga->polygon_stipple.sampler = util_pstipple_create_sampler(pipe);84}8586svga->dirty |= SVGA_NEW_STIPPLE;87}888990void91svga_cleanup_framebuffer(struct svga_context *svga)92{93struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);94struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;95struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;96unsigned i;9798for (i = 0; i < svgascreen->max_color_buffers; i++) {99pipe_surface_reference(&curr->cbufs[i], NULL);100pipe_surface_reference(&hw->cbufs[i], NULL);101}102103pipe_surface_reference(&curr->zsbuf, NULL);104pipe_surface_reference(&hw->zsbuf, NULL);105}106107108#define DEPTH_BIAS_SCALE_FACTOR_D16 ((float)(1<<15))109#define DEPTH_BIAS_SCALE_FACTOR_D24S8 ((float)(1<<23))110#define DEPTH_BIAS_SCALE_FACTOR_D32 ((float)(1<<31))111112113static void114svga_set_framebuffer_state(struct pipe_context *pipe,115const struct pipe_framebuffer_state *fb)116{117struct svga_context *svga = svga_context(pipe);118struct pipe_framebuffer_state *dst = &svga->curr.framebuffer;119unsigned i;120121/* make sure any pending drawing calls are flushed before changing122* the framebuffer state123*/124svga_hwtnl_flush_retry(svga);125126dst->width = fb->width;127dst->height = fb->height;128dst->nr_cbufs = fb->nr_cbufs;129130/* Check that all surfaces are the same size.131* Actually, the virtual hardware may support rendertargets with132* different size, depending on the host API and driver,133*/134{135int width = 0, height = 0;136if (fb->zsbuf) {137width = fb->zsbuf->width;138height = fb->zsbuf->height;139}140for (i = 0; i < fb->nr_cbufs; ++i) {141if (fb->cbufs[i]) {142if (width && height) {143if (fb->cbufs[i]->width != width ||144fb->cbufs[i]->height != height) {145debug_warning("Mixed-size color and depth/stencil surfaces "146"may not work properly");147}148}149else {150width = fb->cbufs[i]->width;151height = fb->cbufs[i]->height;152}153}154}155}156157util_copy_framebuffer_state(dst, fb);158159if (svga->curr.framebuffer.zsbuf) {160switch (svga->curr.framebuffer.zsbuf->format) {161case PIPE_FORMAT_Z16_UNORM:162svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D16;163break;164case PIPE_FORMAT_Z24_UNORM_S8_UINT:165case PIPE_FORMAT_Z24X8_UNORM:166case PIPE_FORMAT_S8_UINT_Z24_UNORM:167case PIPE_FORMAT_X8Z24_UNORM:168svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D24S8;169break;170case PIPE_FORMAT_Z32_UNORM:171svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D32;172break;173case PIPE_FORMAT_Z32_FLOAT:174svga->curr.depthscale = 1.0f / ((float)(1<<23));175break;176default:177svga->curr.depthscale = 0.0f;178break;179}180}181else {182svga->curr.depthscale = 0.0f;183}184185svga->dirty |= SVGA_NEW_FRAME_BUFFER;186}187188189static void190svga_set_clip_state(struct pipe_context *pipe,191const struct pipe_clip_state *clip)192{193struct svga_context *svga = svga_context(pipe);194195svga->curr.clip = *clip; /* struct copy */196197svga->dirty |= SVGA_NEW_CLIP;198}199200201static void202svga_set_viewport_states(struct pipe_context *pipe,203unsigned start_slot,204unsigned num_viewports,205const struct pipe_viewport_state *viewports)206{207struct svga_context *svga = svga_context(pipe);208ASSERTED struct svga_screen *svgascreen = svga_screen(pipe->screen);209unsigned i, num_vp;210211assert(start_slot + num_viewports <= svgascreen->max_viewports);212213for (i = 0, num_vp = start_slot; i < num_viewports; i++) {214svga->curr.viewport[num_vp++] = viewports[i]; /* struct copy */215}216217svga->dirty |= SVGA_NEW_VIEWPORT;218}219220221/**222* Called by state tracker to specify a callback function the driver223* can use to report info back to the gallium frontend.224*/225static void226svga_set_debug_callback(struct pipe_context *pipe,227const struct pipe_debug_callback *cb)228{229struct svga_context *svga = svga_context(pipe);230231if (cb) {232svga->debug.callback = *cb;233svga->swc->debug_callback = &svga->debug.callback;234} else {235memset(&svga->debug.callback, 0, sizeof(svga->debug.callback));236svga->swc->debug_callback = NULL;237}238}239240241void242svga_init_misc_functions(struct svga_context *svga)243{244svga->pipe.set_scissor_states = svga_set_scissor_states;245svga->pipe.set_polygon_stipple = svga_set_polygon_stipple;246svga->pipe.set_framebuffer_state = svga_set_framebuffer_state;247svga->pipe.set_clip_state = svga_set_clip_state;248svga->pipe.set_viewport_states = svga_set_viewport_states;249svga->pipe.set_debug_callback = svga_set_debug_callback;250}251252253