From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/nvidia/nvidia_state.c | 730 +++++++++++++++++++++++ 1 file changed, 730 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/nvidia/nvidia_state.c (limited to 'Source/DirectFB/gfxdrivers/nvidia/nvidia_state.c') diff --git a/Source/DirectFB/gfxdrivers/nvidia/nvidia_state.c b/Source/DirectFB/gfxdrivers/nvidia/nvidia_state.c new file mode 100755 index 0000000..70645f2 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/nvidia/nvidia_state.c @@ -0,0 +1,730 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "nvidia.h" +#include "nvidia_regs.h" +#include "nvidia_accel.h" +#include "nvidia_objects.h" +#include "nvidia_state.h" + + +#define NVIDIA_IS_SET( flag ) ((nvdev->set & SMF_##flag) == SMF_##flag) + +#define NVIDIA_SET( flag ) nvdev->set |= SMF_##flag + +#define NVIDIA_UNSET( flag ) nvdev->set &= ~SMF_##flag + + + +void nv_set_destination( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + CoreSurface *surface = state->destination; + volatile u8 *mmio = nvdrv->mmio_base; + u32 dst_offset; + u32 dst_pitch; + u32 src_pitch; + + if (NVIDIA_IS_SET( DESTINATION )) + return; + + dst_offset = (state->dst.offset + nvdev->fb_offset) & ~63; + dst_pitch = state->dst.pitch & ~31; + src_pitch = (nvdev->src_pitch & ~31) ? : 32; // align to 32, maybe system buffer pitch + + if (nvdev->dst_format != surface->config.format) { + u32 sformat2D = 0; + u32 sformat3D = 0; + u32 cformat = 0; + bool dst_422 = false; + + switch (surface->config.format) { + case DSPF_A8: + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_RGB332: + sformat2D = SURFACES2D_FORMAT_Y8; + cformat = RECT_COLOR_FORMAT_Y32; + break; + case DSPF_RGB555: + sformat2D = SURFACES2D_FORMAT_X1R5G5B5; + sformat3D = SURFACES3D_FORMAT_COLOR_X1R5G5B5; + cformat = RECT_COLOR_FORMAT_A1Y15; + break; + case DSPF_ARGB1555: + sformat2D = SURFACES2D_FORMAT_A1R5G5B5; + sformat3D = SURFACES3D_FORMAT_COLOR_A1R5G5B5; + cformat = RECT_COLOR_FORMAT_A1Y15; + break; + case DSPF_RGB16: + sformat2D = SURFACES2D_FORMAT_R5G6B5; + sformat3D = SURFACES3D_FORMAT_COLOR_R5G6B5; + cformat = RECT_COLOR_FORMAT_Y16; + break; + case DSPF_RGB32: + sformat2D = SURFACES2D_FORMAT_X8R8G8B8; + sformat3D = SURAFCES3D_FORMAT_COLOR_X8R8G8B8; + cformat = RECT_COLOR_FORMAT_Y32; + break; + case DSPF_ARGB: + sformat2D = SURFACES2D_FORMAT_A8R8G8B8; + sformat3D = SURFACES3D_FORMAT_COLOR_A8R8G8B8; + cformat = 0x0D; + break; + case DSPF_YUY2: + sformat2D = SURFACES2D_FORMAT_A8R8G8B8; + cformat = 0x12; + dst_422 = true; + break; + case DSPF_UYVY: + sformat2D = SURFACES2D_FORMAT_A8R8G8B8; + cformat = 0x13; + dst_422 = true; + break; + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + if (sformat2D == SURFACES2D_FORMAT_A8R8G8B8) { + /* need to set color format manually */ + nv_waitidle( nvdrv, nvdev ); + + nv_out32( mmio, PRAMIN + (ADDR_RECTANGLE << 4) + 4, cformat << 8 ); + nv_out32( mmio, PRAMIN + (ADDR_TRIANGLE << 4) + 4, cformat << 8 ); + nv_out32( mmio, PRAMIN + (ADDR_LINE << 4) + 4, cformat << 8 ); + + nv_assign_object( nvdrv, nvdev, + SUBC_RECTANGLE, OBJ_RECTANGLE, true ); + nv_assign_object( nvdrv, nvdev, + SUBC_TRIANGLE, OBJ_TRIANGLE, true ); + nv_assign_object( nvdrv, nvdev, + SUBC_LINE, OBJ_LINE, true ); + } else { + nv_begin( SUBC_RECTANGLE, RECT_COLOR_FORMAT, 1 ); + nv_outr( cformat ); + + nv_begin( SUBC_TRIANGLE, TRI_COLOR_FORMAT, 1 ); + nv_outr( cformat ); + + nv_begin( SUBC_LINE, LINE_COLOR_FORMAT, 1 ); + nv_outr( cformat ); + } + + nv_assign_object( nvdrv, nvdev, + SUBC_SURFACES2D, OBJ_SURFACES2D, false ); + + nv_begin( SUBC_SURFACES2D, SURFACES2D_FORMAT, 2 ); + nv_outr( sformat2D ); + nv_outr( (dst_pitch << 16) | (src_pitch & 0xFFFF) ); + nv_begin( SUBC_SURFACES2D, SURFACES2D_DST_OFFSET, 1 ); + nv_outr( dst_offset ); + + if (nvdev->enabled_3d && sformat3D) { + nv_assign_object( nvdrv, nvdev, + SUBC_SURFACES3D, OBJ_SURFACES3D, false ); + + nv_begin( SUBC_SURFACES3D, SURFACES3D_FORMAT, 1 ); + nv_outr( sformat3D | SURFACES3D_FORMAT_TYPE_PITCH ); + nv_begin( SUBC_SURFACES3D, SURFACES3D_PITCH, 2 ); + nv_outr( (64 << 16) | (dst_pitch & 0xFFFF) ); + nv_outr( dst_offset ); + } + + if (nvdev->dst_422 != dst_422) { + NVIDIA_UNSET( CLIP ); + NVIDIA_UNSET( BLITTING_FLAGS ); + nvdev->dst_422 = dst_422; + } + + NVIDIA_UNSET( COLOR ); + NVIDIA_UNSET( DST_BLEND ); + } + else if (nvdev->dst_offset != dst_offset || + nvdev->dst_pitch != dst_pitch) { + nv_assign_object( nvdrv, nvdev, + SUBC_SURFACES2D, OBJ_SURFACES2D, false ); + + nv_begin( SUBC_SURFACES2D, SURFACES2D_PITCH, 1 ); + nv_outr( (dst_pitch << 16) | (src_pitch & 0xFFFF) ); + nv_begin( SUBC_SURFACES2D, SURFACES2D_DST_OFFSET, 1 ); + nv_outr( dst_offset ); + + if (nvdev->enabled_3d) { + nv_assign_object( nvdrv, nvdev, + SUBC_SURFACES3D, OBJ_SURFACES3D, false ); + + nv_begin( SUBC_SURFACES3D, SURFACES3D_PITCH, 2 ); + nv_outr( (64 << 16) | (dst_pitch & 0xFFFF) ); + nv_outr( dst_offset ); + } + } + + nvdev->dst_format = surface->config.format; + nvdev->dst_offset = dst_offset; + nvdev->dst_pitch = dst_pitch; + + NVIDIA_SET( DESTINATION ); +} + +void nv_set_source( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + CoreSurface *surface = state->source; + + nvdev->src_lock = &state->src; + + if (NVIDIA_IS_SET( SOURCE )) { + if ((state->blittingflags & DSBLIT_DEINTERLACE) == + (nvdev->blittingflags & DSBLIT_DEINTERLACE)) + return; + } + + if (state->src.buffer->policy == CSP_SYSTEMONLY) { + if (!nvdev->src_system) { + nv_assign_object( nvdrv, nvdev, + SUBC_IMAGEBLT, OBJ_IMAGEBLT, false ); + nv_assign_object( nvdrv, nvdev, + SUBC_STRETCHEDIMAGE, OBJ_STRETCHEDIMAGE, false ); + + NVIDIA_UNSET( BLITTING_FLAGS ); + } + + nvdev->src_address = state->src.addr; + nvdev->src_pitch = state->src.pitch; + nvdev->src_system = true; + } + else { + u32 src_offset = (state->src.offset + nvdev->fb_offset) & ~63; + u32 src_pitch = state->src.pitch & ~31; + + if (nvdev->src_offset != src_offset || + nvdev->src_pitch != src_pitch) { + nv_assign_object( nvdrv, nvdev, + SUBC_SURFACES2D, OBJ_SURFACES2D, false ); + + nv_begin( SUBC_SURFACES2D, SURFACES2D_PITCH, 2 ); + nv_outr( (nvdev->dst_pitch << 16) | (src_pitch & 0xFFFF) ); + nv_outr( src_offset ); + } + + if (nvdev->src_system) { + nv_assign_object( nvdrv, nvdev, + SUBC_SCREENBLT, OBJ_SCREENBLT, false ); + nv_assign_object( nvdrv, nvdev, + SUBC_SCALEDIMAGE, OBJ_SCALEDIMAGE, false ); + + NVIDIA_UNSET( BLITTING_FLAGS ); + } + + nvdev->src_offset = src_offset; + nvdev->src_pitch = src_pitch; + nvdev->src_system = false; + } + + nvdev->src_width = surface->config.size.w; + nvdev->src_height = surface->config.size.h; + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + nvdev->src_height /= 2; + if (surface->config.caps & DSCAPS_SEPARATED) { + if (surface->field) { + nvdev->src_address += nvdev->src_height * nvdev->src_pitch; + nvdev->src_offset += nvdev->src_height * nvdev->src_pitch; + } + } else { + if (surface->field) { + nvdev->src_address += nvdev->src_pitch; + nvdev->src_offset += nvdev->src_pitch; + } + nvdev->src_pitch *= 2; + } + nvdev->src_interlaced = true; + } else + nvdev->src_interlaced = false; + + if (nvdev->enabled_3d) { + u32 size_u = direct_log2(surface->config.size.w) & 0xF; + u32 size_v = direct_log2(surface->config.size.h) & 0xF; + + nvdev->state3d[1].offset = nvdev->fb_offset + nvdev->buf_offset[1]; + nvdev->state3d[1].format &= 0xFF00FFFF; + nvdev->state3d[1].format |= (size_u << 16) | (size_v << 20); + } + + if (nvdev->src_format != surface->config.format) { + NVIDIA_UNSET( SRC_BLEND ); + NVIDIA_UNSET( BLITTING_FLAGS ); + nvdev->src_format = surface->config.format; + } + + NVIDIA_SET( SOURCE ); +} + +void nv_set_clip( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + DFBRectangle *cr = &nvdev->clip; + + if (NVIDIA_IS_SET( CLIP )) + return; + + cr->x = state->clip.x1; + cr->y = state->clip.y1; + cr->w = state->clip.x2 - state->clip.x1 + 1; + cr->h = state->clip.y2 - state->clip.y1 + 1; + + if (nvdev->dst_422) { + cr->x = cr->x / 2; + cr->w = (cr->w / 2) ? : 1; + } + + nv_begin( SUBC_CLIP, CLIP_TOP_LEFT, 2 ); + nv_outr( (cr->y << 16) | (cr->x & 0xFFFF) ); + nv_outr( (cr->h << 16) | (cr->w & 0xFFFF) ); + + NVIDIA_SET( CLIP ); +} + +void nv_set_drawing_color( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + DFBColor color = state->color; + int y, u, v; + + if (NVIDIA_IS_SET( DRAWING_COLOR ) && NVIDIA_IS_SET( DRAWING_FLAGS )) + return; + + switch (nvdev->dst_format) { + case DSPF_A8: + nvdev->color2d = color.a; + break; + case DSPF_LUT8: + nvdev->color2d = state->color_index; + break; + case DSPF_ALUT44: + nvdev->color2d = (state->color_index & 0x0F) | + (state->color.a & 0xF0); + break; + case DSPF_RGB332: + nvdev->color2d = PIXEL_RGB332( color.r, + color.g, + color.b ); + break; + case DSPF_RGB555: + case DSPF_ARGB1555: + nvdev->color2d = PIXEL_ARGB1555( color.a, + color.r, + color.g, + color.b ); + break; + case DSPF_RGB16: + nvdev->color2d = PIXEL_RGB16( color.r, + color.g, + color.b ); + break; + case DSPF_RGB32: + nvdev->color2d = PIXEL_RGB32( color.r, + color.g, + color.b ); + break; + case DSPF_ARGB: + nvdev->color2d = PIXEL_ARGB( color.a, + color.r, + color.g, + color.b ); + break; + + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + nvdev->color2d = PIXEL_YUY2( y, u, v ); + break; + + case DSPF_UYVY: + RGB_TO_YCBCR( color.r, color.g, color.b, y, u, v ); + nvdev->color2d = PIXEL_UYVY( y, u, v ); + break; + + default: + D_BUG( "unexpected pixelformat" ); + break; + } + + nvdev->color3d = PIXEL_ARGB(color.a, color.r, color.g, color.b); + + if (nvdev->dst_format == DSPF_ARGB1555) { + nv_assign_object( nvdrv, nvdev, + SUBC_SURFACES2D, OBJ_SURFACES2D, false ); + + nv_begin( SUBC_SURFACES2D, SURFACES2D_FORMAT, 1 ); + nv_outr( (nvdev->color2d & 0x8000) + ? SURFACES2D_FORMAT_A1R5G5B5 + : SURFACES2D_FORMAT_X1R5G5B5 ); + } + + if (state->drawingflags & DSDRAW_BLEND && !nvdev->enabled_3d) { + if (!nvdev->beta1_set || nvdev->beta1_val != (color.a << 23)) { + nv_assign_object( nvdrv, nvdev, SUBC_BETA1, OBJ_BETA1, false ); + + nv_begin( SUBC_BETA1, BETA1_FACTOR, 1 ); + nv_outr( color.a << 23 ); + + nvdev->beta1_val = color.a << 23; + nvdev->beta1_set = true; + } + } + + NVIDIA_SET ( DRAWING_COLOR ); + NVIDIA_UNSET( BLITTING_COLOR ); +} + +void nv_set_blitting_color( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + DFBColor color = state->color; + + if (NVIDIA_IS_SET( BLITTING_COLOR ) && NVIDIA_IS_SET( BLITTING_FLAGS )) + return; + + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR) || + (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL && state->src_blend == DSBF_ONE)) { + nvdev->color3d = (state->blittingflags & DSBLIT_BLEND_COLORALPHA) + ? (color.a << 24) : 0xFF000000; + + if (state->blittingflags & DSBLIT_COLORIZE && + state->blittingflags & (DSBLIT_SRC_PREMULTCOLOR | DSBLIT_BLEND_COLORALPHA)) { + nvdev->color3d |= PIXEL_RGB32( color.r * color.a / 0xFF, + color.g * color.a / 0xFF, + color.b * color.a / 0xFF ); + } + else if (state->blittingflags & DSBLIT_COLORIZE) { + nvdev->color3d |= PIXEL_RGB32( color.r, color.g, color.b ); + } + else if (state->blittingflags & (DSBLIT_SRC_PREMULTCOLOR | DSBLIT_BLEND_COLORALPHA)) { + nvdev->color3d |= PIXEL_RGB32( color.a, color.a, color.a ); + } + else { + nvdev->color3d |= 0x00FFFFFF; + } + + if (!nvdev->beta4_set || nvdev->beta4_val != nvdev->color3d) { + nv_assign_object( nvdrv, nvdev, + SUBC_BETA4, OBJ_BETA4, false ); + + nv_begin( SUBC_BETA4, BETA4_FACTOR, 1 ); + nv_outr( nvdev->color3d ); + + nvdev->beta4_val = nvdev->color3d; + nvdev->beta4_set = true; + } + } + else if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_BLEND_ALPHACHANNEL)) { + u32 beta1; + + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + nvdev->color3d = (color.a << 24) | 0x00FFFFFF; + beta1 = color.a << 23; + } else { + nvdev->color3d = 0xFFFFFFFF; + beta1 = 0x7F800000; + } + + if (!nvdev->beta1_set || nvdev->beta1_val != beta1) { + nv_assign_object( nvdrv, nvdev, + SUBC_BETA1, OBJ_BETA1, false ); + + nv_begin( SUBC_BETA1, BETA1_FACTOR, 1 ); + nv_outr( beta1 ); + + nvdev->beta1_val = beta1; + nvdev->beta1_set = true; + } + } + + NVIDIA_SET ( BLITTING_COLOR ); + NVIDIA_UNSET( DRAWING_COLOR ); +} + +void nv_set_blend_function( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + DFBSurfaceBlendFunction sblend, dblend; + + if (NVIDIA_IS_SET( SRC_BLEND ) && NVIDIA_IS_SET( DST_BLEND )) + return; + + sblend = state->src_blend; + dblend = state->dst_blend; + + if (!DFB_PIXELFORMAT_HAS_ALPHA(nvdev->dst_format)) { + if (sblend == DSBF_DESTALPHA) + sblend = DSBF_ONE; + else if (sblend == DSBF_INVDESTALPHA) + sblend = DSBF_ZERO; + + if (dblend == DSBF_DESTALPHA) + dblend = DSBF_ONE; + else if (dblend == DSBF_INVDESTALPHA) + dblend = DSBF_ZERO; + } + + nvdev->state3d[0].blend &= 0x00FFFFFF; + nvdev->state3d[0].blend |= (sblend << 24) | (dblend << 28); + nvdev->state3d[1].blend &= 0x00FFFFFF; + nvdev->state3d[1].blend |= (sblend << 24) | (dblend << 28); + + if (!NVIDIA_IS_SET( SRC_BLEND )) + NVIDIA_UNSET( BLITTING_FLAGS ); + NVIDIA_SET( SRC_BLEND ); + NVIDIA_SET( DST_BLEND ); +} + +void nv_set_drawingflags( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + if (NVIDIA_IS_SET( DRAWING_FLAGS )) + return; + + if (!nvdev->enabled_3d) { + u32 operation; + + if (state->drawingflags & DSDRAW_BLEND) + operation = OPERATION_BLEND; + else + operation = OPERATION_SRCCOPY; + + if (nvdev->drawing_operation != operation) { + nv_begin( SUBC_RECTANGLE, RECT_OPERATION, 1 ); + nv_outr( operation ); + + nv_begin( SUBC_TRIANGLE, TRI_OPERATION, 1 ); + nv_outr( operation ); + + nv_begin( SUBC_LINE, LINE_OPERATION, 1 ); + nv_outr( operation ); + + nvdev->drawing_operation = operation; + } + } + else { + if (state->drawingflags & DSDRAW_BLEND) + nvdev->state3d[0].blend |= TXTRI_BLEND_ALPHABLEND_ENABLE; + else + nvdev->state3d[0].blend &= ~TXTRI_BLEND_ALPHABLEND_ENABLE; + } + + nvdev->drawingflags = state->drawingflags; + + NVIDIA_SET( DRAWING_FLAGS ); +} + +void nv_set_blittingflags( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + CardState *state ) +{ + u32 operation; + bool src_alpha; + + if (NVIDIA_IS_SET( BLITTING_FLAGS )) + return; + + operation = (nvdev->arch > NV_ARCH_04) ? OPERATION_SRCCOPY : OPERATION_COPY; + src_alpha = true; + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_BLEND_ALPHACHANNEL)) { + if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR) || + (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL && state->src_blend == DSBF_ONE)) { + operation = OPERATION_BLEND_PREMULTIPLIED; + } + else { + operation = OPERATION_BLEND; + src_alpha = !!(state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL); + } + } + else if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)) { + operation = OPERATION_COLOR_MULTIPLY; + } + + if (nvdev->src_system) { + switch (nvdev->src_format) { + case DSPF_RGB555: + nvdev->system_format = IBLIT_COLOR_FORMAT_X1R5G5B5; + break; + case DSPF_ARGB1555: + nvdev->system_format = src_alpha + ? IBLIT_COLOR_FORMAT_A1R5G5B5 + : IBLIT_COLOR_FORMAT_X1R5G5B5; + break; + case DSPF_RGB16: + nvdev->system_format = IBLIT_COLOR_FORMAT_R5G6B5; + break; + case DSPF_RGB32: + nvdev->system_format = IBLIT_COLOR_FORMAT_X8R8G8B8; + break; + case DSPF_ARGB: + nvdev->system_format = src_alpha + ? IBLIT_COLOR_FORMAT_A8R8G8B8 + : IBLIT_COLOR_FORMAT_X8R8G8B8; + break; + default: + D_BUG( "unexpected pixelformat" ); + break; + } + + if (nvdev->system_operation != operation) { + nv_begin( SUBC_IMAGEBLT, IBLIT_OPERATION, 1 ); + nv_outr( operation ); + + nv_begin( SUBC_STRETCHEDIMAGE, ISTRETCH_OPERATION, 1 ); + nv_outr( operation ); + + nvdev->system_operation = operation; + } + } + else { + switch (nvdev->src_format) { + case DSPF_A8: + nvdev->scaler_format = SCALER_COLOR_FORMAT_AY8; + break; + case DSPF_LUT8: + case DSPF_ALUT44: + case DSPF_RGB332: + nvdev->scaler_format = SCALER_COLOR_FORMAT_Y8; + break; + case DSPF_RGB555: + nvdev->scaler_format = SCALER_COLOR_FORMAT_X1R5G5B5; + break; + case DSPF_ARGB1555: + nvdev->scaler_format = src_alpha + ? SCALER_COLOR_FORMAT_A1R5G5B5 + : SCALER_COLOR_FORMAT_X1R5G5B5; + break; + case DSPF_RGB16: + nvdev->scaler_format = SCALER_COLOR_FORMAT_R5G6B5; + break; + case DSPF_RGB32: + nvdev->scaler_format = SCALER_COLOR_FORMAT_X8R8G8B8; + break; + case DSPF_ARGB: + nvdev->scaler_format = src_alpha + ? SCALER_COLOR_FORMAT_A8R8G8B8 + : SCALER_COLOR_FORMAT_X8R8G8B8; + break; + case DSPF_YUY2: + nvdev->scaler_format = nvdev->dst_422 + ? SCALER_COLOR_FORMAT_A8R8G8B8 + : SCALER_COLOR_FORMAT_V8YB8U8YA8; + break; + case DSPF_UYVY: + nvdev->scaler_format = nvdev->dst_422 + ? SCALER_COLOR_FORMAT_A8R8G8B8 + : SCALER_COLOR_FORMAT_YB8V8YA8U8; + break; + default: + D_BUG( "unexpected pixelformat 0x%08x", nvdev->src_format ); + break; + } + + if (nvdev->scaler_operation != operation) { + nv_begin( SUBC_SCALEDIMAGE, SCALER_OPERATION, 1 ); + nv_outr( operation ); + + nvdev->scaler_operation = operation; + } + } + + if (nvdev->enabled_3d) { + nvdev->state3d[1].format &= 0xFFFFF0FF; + nvdev->state3d[1].blend &= 0xFF00FFF0; + + switch (nvdev->src_format) { + case DSPF_RGB555: + nvdev->state3d[1].format |= TXTRI_FORMAT_COLOR_X1R5G5B5; + break; + case DSPF_ARGB1555: + nvdev->state3d[1].format |= TXTRI_FORMAT_COLOR_A1R5G5B5; + break; + case DSPF_A8: + case DSPF_ARGB: + nvdev->state3d[1].format |= TXTRI_FORMAT_COLOR_A4R4G4B4; + break; + default: + nvdev->state3d[1].format |= TXTRI_FORMAT_COLOR_R5G6B5; + break; + } + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_COLORIZE | + DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_SRC_PREMULTCOLOR)) { + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) + nvdev->state3d[1].blend |= + TXTRI_BLEND_TEXTUREMAPBLEND_MODULATEALPHA; + else + nvdev->state3d[1].blend |= + TXTRI_BLEND_TEXTUREMAPBLEND_MODULATE; + + if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA | + DSBLIT_BLEND_ALPHACHANNEL)) + nvdev->state3d[1].blend |= TXTRI_BLEND_ALPHABLEND_ENABLE; + } else + nvdev->state3d[1].blend |= TXTRI_BLEND_TEXTUREMAPBLEND_COPY; + } + + nvdev->blittingflags = state->blittingflags; + + NVIDIA_SET( BLITTING_FLAGS ); +} + -- cgit