Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv30/nv30_clear.c
4574 views
/*1* Copyright 2012 Red Hat Inc.2*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 shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*21* Authors: Ben Skeggs22*23*/2425#include "pipe/p_defines.h"26#include "util/u_pack_color.h"2728#include "nouveau_gldefs.h"29#include "nv_object.xml.h"30#include "nv30/nv30-40_3d.xml.h"31#include "nv30/nv30_context.h"32#include "nv30/nv30_format.h"3334static inline uint32_t35pack_rgba(enum pipe_format format, const float *rgba)36{37union util_color uc;38util_pack_color(rgba, format, &uc);39return uc.ui[0];40}4142static inline uint32_t43pack_zeta(enum pipe_format format, double depth, unsigned stencil)44{45uint32_t zuint = (uint32_t)(depth * 4294967295.0);46if (format != PIPE_FORMAT_Z16_UNORM)47return (zuint & 0xffffff00) | (stencil & 0xff);48return zuint >> 16;49}5051static void52nv30_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scissor_state *scissor_state,53const union pipe_color_union *color, double depth, unsigned stencil)54{55struct nv30_context *nv30 = nv30_context(pipe);56struct nouveau_pushbuf *push = nv30->base.pushbuf;57struct pipe_framebuffer_state *fb = &nv30->framebuffer;58uint32_t colr = 0, zeta = 0, mode = 0;5960if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, true))61return;6263if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {64colr = pack_rgba(fb->cbufs[0]->format, color->f);65mode |= NV30_3D_CLEAR_BUFFERS_COLOR_R |66NV30_3D_CLEAR_BUFFERS_COLOR_G |67NV30_3D_CLEAR_BUFFERS_COLOR_B |68NV30_3D_CLEAR_BUFFERS_COLOR_A;69}7071if (fb->zsbuf) {72zeta = pack_zeta(fb->zsbuf->format, depth, stencil);73if (buffers & PIPE_CLEAR_DEPTH)74mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;75if (buffers & PIPE_CLEAR_STENCIL) {76mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;77BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 2);78PUSH_DATA (push, 0);79PUSH_DATA (push, 0x000000ff);80nv30->dirty |= NV30_NEW_ZSA;81}82}8384/*XXX: wtf? fixes clears sometimes not clearing on nv3x... */85if (nv30->screen->eng3d->oclass < NV40_3D_CLASS) {86BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);87PUSH_DATA (push, zeta);88PUSH_DATA (push, colr);89PUSH_DATA (push, mode);90}9192BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);93PUSH_DATA (push, zeta);94PUSH_DATA (push, colr);95PUSH_DATA (push, mode);9697nv30_state_release(nv30);98}99100static void101nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,102const union pipe_color_union *color,103unsigned x, unsigned y, unsigned w, unsigned h,104bool render_condition_enabled)105{106struct nv30_context *nv30 = nv30_context(pipe);107struct nv30_surface *sf = nv30_surface(ps);108struct nv30_miptree *mt = nv30_miptree(ps->texture);109struct nouveau_pushbuf *push = nv30->base.pushbuf;110struct nouveau_object *eng3d = nv30->screen->eng3d;111struct nouveau_pushbuf_refn refn;112uint32_t rt_format;113114rt_format = nv30_format(pipe->screen, ps->format)->hw;115if (util_format_get_blocksize(ps->format) == 4)116rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;117else118rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;119120if (nv30_miptree(ps->texture)->swizzled) {121rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;122rt_format |= util_logbase2(sf->width) << 16;123rt_format |= util_logbase2(sf->height) << 24;124} else {125rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;126}127128refn.bo = mt->base.bo;129refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;130if (nouveau_pushbuf_space(push, 32, 1, 0) ||131nouveau_pushbuf_refn (push, &refn, 1))132return;133134BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);135PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);136BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);137PUSH_DATA (push, sf->width << 16);138PUSH_DATA (push, sf->height << 16);139PUSH_DATA (push, rt_format);140BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);141if (eng3d->oclass < NV40_3D_CLASS)142PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);143else144PUSH_DATA (push, sf->pitch);145PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);146BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);147PUSH_DATA (push, (w << 16) | x);148PUSH_DATA (push, (h << 16) | y);149150BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);151PUSH_DATA (push, pack_rgba(ps->format, color->f));152PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |153NV30_3D_CLEAR_BUFFERS_COLOR_G |154NV30_3D_CLEAR_BUFFERS_COLOR_B |155NV30_3D_CLEAR_BUFFERS_COLOR_A);156157nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;158}159160static void161nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,162unsigned buffers, double depth, unsigned stencil,163unsigned x, unsigned y, unsigned w, unsigned h,164bool render_condition_enabled)165{166struct nv30_context *nv30 = nv30_context(pipe);167struct nv30_surface *sf = nv30_surface(ps);168struct nv30_miptree *mt = nv30_miptree(ps->texture);169struct nouveau_pushbuf *push = nv30->base.pushbuf;170struct nouveau_object *eng3d = nv30->screen->eng3d;171struct nouveau_pushbuf_refn refn;172uint32_t rt_format, mode = 0;173174rt_format = nv30_format(pipe->screen, ps->format)->hw;175if (util_format_get_blocksize(ps->format) == 4)176rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;177else178rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;179180if (nv30_miptree(ps->texture)->swizzled) {181rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;182rt_format |= util_logbase2(sf->width) << 16;183rt_format |= util_logbase2(sf->height) << 24;184} else {185rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;186}187188if (buffers & PIPE_CLEAR_DEPTH)189mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;190if (buffers & PIPE_CLEAR_STENCIL)191mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;192193refn.bo = mt->base.bo;194refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;195if (nouveau_pushbuf_space(push, 32, 1, 0) ||196nouveau_pushbuf_refn (push, &refn, 1))197return;198199BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);200PUSH_DATA (push, 0);201BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);202PUSH_DATA (push, sf->width << 16);203PUSH_DATA (push, sf->height << 16);204PUSH_DATA (push, rt_format);205if (eng3d->oclass < NV40_3D_CLASS) {206BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 1);207PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);208} else {209BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);210PUSH_DATA (push, sf->pitch);211}212BEGIN_NV04(push, NV30_3D(ZETA_OFFSET), 1);213PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);214BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);215PUSH_DATA (push, (w << 16) | x);216PUSH_DATA (push, (h << 16) | y);217218BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 1);219PUSH_DATA (push, pack_zeta(ps->format, depth, stencil));220BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);221PUSH_DATA (push, mode);222223nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;224}225226void227nv30_clear_init(struct pipe_context *pipe)228{229pipe->clear = nv30_clear;230pipe->clear_render_target = nv30_clear_render_target;231pipe->clear_depth_stencil = nv30_clear_depth_stencil;232}233234235