classic/r200: Delete driver

This will now only be available on the Amber branch

Reviewed-by: Emma Anholt <emma@anholt.net>
Acked-by: Jason Ekstrand <jason@jlekstrand.net>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10153>
This commit is contained in:
Dylan Baker 2021-04-09 09:49:49 -07:00 committed by Marge Bot
parent 4d45b280bf
commit 184a690fca
63 changed files with 6 additions and 15439 deletions

View File

@ -825,7 +825,7 @@ fedora-release:
-Wno-error=uninitialized
CPP_ARGS: >
-Wno-error=array-bounds
DRI_DRIVERS: "nouveau,i915,i965,r200"
DRI_DRIVERS: "nouveau,i915,i965"
DRI_LOADERS: >
-D glx=dri
-D gbm=enabled
@ -1118,7 +1118,7 @@ debian-i386:
CROSS: i386
VULKAN_DRIVERS: intel,amd,swrast,virtio-experimental
GALLIUM_DRIVERS: "iris,nouveau,r300,r600,radeonsi,swrast,virgl,zink,crocus"
DRI_DRIVERS: "i915,i965,r200,nouveau"
DRI_DRIVERS: "i915,i965,nouveau"
EXTRA_OPTION: >
-D vulkan-layers=device-select,overlay

View File

@ -1,24 +0,0 @@
CHIPSET(0x5148, R200_QH, R200)
CHIPSET(0x514C, R200_QL, R200)
CHIPSET(0x514D, R200_QM, R200)
CHIPSET(0x4242, R200_BB, R200)
CHIPSET(0x4966, RV250_If, RV250)
CHIPSET(0x4967, RV250_Ig, RV250)
CHIPSET(0x4C64, RV250_Ld, RV250)
CHIPSET(0x4C66, RV250_Lf, RV250)
CHIPSET(0x4C67, RV250_Lg, RV250)
CHIPSET(0x4C6E, RV280_4C6E, RV280)
CHIPSET(0x5960, RV280_5960, RV280)
CHIPSET(0x5961, RV280_5961, RV280)
CHIPSET(0x5962, RV280_5962, RV280)
CHIPSET(0x5964, RV280_5964, RV280)
CHIPSET(0x5965, RV280_5965, RV280)
CHIPSET(0x5C61, RV280_5C61, RV280)
CHIPSET(0x5C63, RV280_5C63, RV280)
CHIPSET(0x5834, RS300_5834, RS300)
CHIPSET(0x5835, RS300_5835, RS300)
CHIPSET(0x7834, RS350_7834, RS300)
CHIPSET(0x7835, RS350_7835, RS300)

View File

@ -178,11 +178,11 @@ if dri_drivers.contains('auto')
if system_has_kms_drm
# TODO: PPC, Sparc
if ['x86', 'x86_64'].contains(host_machine.cpu_family())
dri_drivers = ['i915', 'i965', 'r200', 'nouveau']
dri_drivers = ['i915', 'i965', 'nouveau']
elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
dri_drivers = []
elif ['mips', 'mips64', 'riscv32', 'riscv64'].contains(host_machine.cpu_family())
dri_drivers = ['r200', 'nouveau']
dri_drivers = ['nouveau']
else
error('Unknown architecture @0@. Please pass -Ddri-drivers to set driver options. Patches gladly accepted to fix this.'.format(
host_machine.cpu_family()))
@ -198,7 +198,6 @@ endif
with_dri_i915 = dri_drivers.contains('i915')
with_dri_i965 = dri_drivers.contains('i965')
with_dri_r200 = dri_drivers.contains('r200')
with_dri_nouveau = dri_drivers.contains('nouveau')
with_dri = dri_drivers.length() != 0
@ -1597,8 +1596,7 @@ _drm_ver = '2.4.109'
_libdrm_checks = [
['intel', with_dri_i915 or with_gallium_i915],
['amdgpu', (with_amd_vk and not with_platform_windows) or with_gallium_radeonsi],
['radeon', (with_gallium_radeonsi or with_dri_r200 or
with_gallium_r300 or with_gallium_r600)],
['radeon', (with_gallium_radeonsi or with_gallium_r300 or with_gallium_r600)],
['nouveau', (with_gallium_nouveau or with_dri_nouveau)],
]

View File

@ -55,7 +55,7 @@ option(
'dri-drivers',
type : 'array',
value : ['auto'],
choices : ['auto', 'i915', 'i965', 'r200', 'nouveau'],
choices : ['auto', 'i915', 'i965', 'nouveau'],
description : 'List of dri drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
)
option(

View File

@ -32,12 +32,6 @@ static const int crocus_chip_ids[] = {
#undef CHIPSET
};
static const int r200_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/r200_pci_ids.h"
#undef CHIPSET
};
static const int r300_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/r300_pci_ids.h"
@ -77,7 +71,6 @@ static const struct {
{ 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) },
{ 0x8086, "crocus", crocus_chip_ids, ARRAY_SIZE(crocus_chip_ids) },
{ 0x8086, "iris", NULL, -1, is_kernel_i915 },
{ 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids) },
{ 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) },
{ 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) },
{ 0x1002, "radeonsi", NULL, -1 },

View File

@ -33,11 +33,6 @@ if with_dri_i965
_dri_drivers += libi965
_dri_link += 'i965_dri.so'
endif
if with_dri_r200
subdir('r200')
_dri_drivers += libr200
_dri_link += 'r200_dri.so'
endif
if with_dri_nouveau
subdir('nouveau')
_dri_drivers += libnouveau_vieux

View File

@ -1,88 +0,0 @@
# Copyright © 2017 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
files_r200 = files(
'radeon_buffer_objects.c',
'radeon_buffer_objects.h',
'radeon_cmdbuf.h',
'radeon_common.c',
'radeon_common.h',
'radeon_common_context.c',
'radeon_common_context.h',
'radeon_debug.c',
'radeon_debug.h',
'radeon_dma.c',
'radeon_dma.h',
'radeon_fbo.c',
'radeon_fog.c',
'radeon_fog.h',
'radeon_mipmap_tree.c',
'radeon_mipmap_tree.h',
'radeon_pixel_read.c',
'radeon_queryobj.c',
'radeon_queryobj.h',
'radeon_span.c',
'radeon_span.h',
'radeon_tex_copy.c',
'radeon_texture.c',
'radeon_texture.h',
'radeon_tile.c',
'radeon_tile.h',
'r200_blit.c',
'r200_blit.h',
'r200_cmdbuf.c',
'r200_context.c',
'r200_context.h',
'r200_fragshader.c',
'r200_ioctl.c',
'r200_ioctl.h',
'r200_maos.c',
'r200_maos.h',
'r200_reg.h',
'r200_sanity.c',
'r200_sanity.h',
'r200_state.c',
'r200_state.h',
'r200_state_init.c',
'r200_swtcl.c',
'r200_swtcl.h',
'r200_tcl.c',
'r200_tcl.h',
'r200_tex.c',
'r200_tex.h',
'r200_texstate.c',
'r200_vertprog.c',
'r200_vertprog.h',
'radeon_chipset.h',
'radeon_screen.c',
'radeon_screen.h',
'server/radeon_reg.h',
)
libr200 = static_library(
'r200',
files_r200,
include_directories : [
inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_dri_common, inc_util, include_directories('server'),
],
c_args : ['-DRADEON_R200'],
gnu_symbol_visibility : 'hidden',
dependencies : [dep_libdrm, dep_libdrm_radeon, idep_mesautil],
)

View File

@ -1,576 +0,0 @@
/*
* Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "radeon_common.h"
#include "r200_context.h"
#include "r200_blit.h"
#include "r200_tex.h"
static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
int reg, int count)
{
if (count)
return CP_PACKET0(reg, count - 1);
return CP_PACKET2;
}
/* common formats supported as both textures and render targets */
unsigned r200_check_blit(mesa_format mesa_format, uint32_t dst_pitch)
{
/* XXX others? */
switch (mesa_format) {
#if UTIL_ARCH_LITTLE_ENDIAN
case MESA_FORMAT_B8G8R8A8_UNORM:
case MESA_FORMAT_B8G8R8X8_UNORM:
case MESA_FORMAT_B5G6R5_UNORM:
case MESA_FORMAT_B4G4R4A4_UNORM:
case MESA_FORMAT_B5G5R5A1_UNORM:
#else
case MESA_FORMAT_A8R8G8B8_UNORM:
case MESA_FORMAT_X8R8G8B8_UNORM:
case MESA_FORMAT_R5G6B5_UNORM:
case MESA_FORMAT_A4R4G4B4_UNORM:
case MESA_FORMAT_A1R5G5B5_UNORM:
#endif
case MESA_FORMAT_A_UNORM8:
case MESA_FORMAT_L_UNORM8:
case MESA_FORMAT_I_UNORM8:
/* swizzled - probably can't happen with the disabled Choose8888TexFormat code */
case MESA_FORMAT_A8B8G8R8_UNORM:
case MESA_FORMAT_R8G8B8A8_UNORM:
break;
default:
return 0;
}
/* Rendering to small buffer doesn't work.
* Looks like a hw limitation.
*/
if (dst_pitch < 32)
return 0;
/* ??? */
if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
return 0;
return 1;
}
static inline void emit_vtx_state(struct r200_context *r200)
{
BATCH_LOCALS(&r200->radeon);
BEGIN_BATCH(14);
if (r200->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, 0);
} else {
OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS);
}
OUT_BATCH_REGVAL(R200_SE_VAP_CNTL, (R200_VAP_FORCE_W_TO_ONE |
(9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT)));
OUT_BATCH_REGVAL(R200_SE_VTX_STATE_CNTL, 0);
OUT_BATCH_REGVAL(R200_SE_VTE_CNTL, 0);
OUT_BATCH_REGVAL(R200_SE_VTX_FMT_0, R200_VTX_XY);
OUT_BATCH_REGVAL(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT));
OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
RADEON_BFACE_SOLID |
RADEON_FFACE_SOLID |
RADEON_VTX_PIX_CENTER_OGL |
RADEON_ROUND_MODE_ROUND |
RADEON_ROUND_PREC_4TH_PIX));
END_BATCH();
}
static void inline emit_tx_setup(struct r200_context *r200,
mesa_format src_mesa_format,
mesa_format dst_mesa_format,
struct radeon_bo *bo,
intptr_t offset,
unsigned width,
unsigned height,
unsigned pitch)
{
uint32_t txformat = R200_TXFORMAT_NON_POWER2;
BATCH_LOCALS(&r200->radeon);
assert(width <= 2048);
assert(height <= 2048);
assert(offset % 32 == 0);
#if UTIL_ARCH_LITTLE_ENDIAN
txformat |= tx_table_le[src_mesa_format].format;
#else
txformat |= tx_table_be[src_mesa_format].format;
#endif
if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
offset |= R200_TXO_MACRO_TILE;
if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
offset |= R200_TXO_MICRO_TILE;
switch (dst_mesa_format) {
/* le */
case MESA_FORMAT_B8G8R8A8_UNORM:
case MESA_FORMAT_B8G8R8X8_UNORM:
case MESA_FORMAT_B5G6R5_UNORM:
case MESA_FORMAT_B4G4R4A4_UNORM:
case MESA_FORMAT_B5G5R5A1_UNORM:
/* be */
case MESA_FORMAT_A8R8G8B8_UNORM:
case MESA_FORMAT_X8R8G8B8_UNORM:
case MESA_FORMAT_R5G6B5_UNORM:
case MESA_FORMAT_A4R4G4B4_UNORM:
case MESA_FORMAT_A1R5G5B5_UNORM:
/* little and big */
case MESA_FORMAT_A_UNORM8:
case MESA_FORMAT_L_UNORM8:
case MESA_FORMAT_I_UNORM8:
default:
/* no swizzle required */
BEGIN_BATCH(10);
OUT_BATCH_REGVAL(RADEON_PP_CNTL, (RADEON_TEX_0_ENABLE |
RADEON_TEX_BLEND_0_ENABLE));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO |
R200_TXC_ARG_B_ZERO |
R200_TXC_ARG_C_R0_COLOR |
R200_TXC_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 |
R200_TXC_OUTPUT_REG_R0));
OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO |
R200_TXA_ARG_B_ZERO |
R200_TXA_ARG_C_R0_ALPHA |
R200_TXA_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, (R200_TXA_CLAMP_0_1 |
R200_TXA_OUTPUT_REG_R0));
END_BATCH();
break;
case MESA_FORMAT_A8B8G8R8_UNORM:
case MESA_FORMAT_R8G8B8A8_UNORM:
#if UTIL_ARCH_LITTLE_ENDIAN
if (dst_mesa_format == MESA_FORMAT_A8B8G8R8_UNORM) {
#else
if (dst_mesa_format == MESA_FORMAT_R8G8B8A8_UNORM) {
#endif
BEGIN_BATCH(10);
OUT_BATCH_REGVAL(RADEON_PP_CNTL, (RADEON_TEX_0_ENABLE |
RADEON_TEX_BLEND_0_ENABLE));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO |
R200_TXC_ARG_B_ZERO |
R200_TXC_ARG_C_R0_COLOR |
R200_TXC_OP_MADD));
/* XXX I don't think this can work. This is output rotation, and alpha contains
* red, not alpha (we'd write gbrr). */
OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 |
R200_TXC_OUTPUT_ROTATE_GBA |
R200_TXC_OUTPUT_REG_R0));
OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO |
R200_TXA_ARG_B_ZERO |
R200_TXA_ARG_C_R0_ALPHA |
R200_TXA_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, (R200_TXA_CLAMP_0_1 |
(R200_TXA_REPL_RED << R200_TXA_REPL_ARG_C_SHIFT) |
R200_TXA_OUTPUT_REG_R0));
END_BATCH();
}
else {
/* XXX pretty sure could do this with just 2 instead of 4 instructions.
* Like so:
* 1st: use RGA output rotation, rgb arg replicate b, a arg r, write mask rb.
* That's just one instruction in fact but I'm not entirely sure it works
* if some of those incoming r0 components are never written (due to mask)
* in the shader itself to r0.
* In any case this case (and the one above) may not be reachable with
* disabled Choose8888TexFormat code. */
BEGIN_BATCH(34);
OUT_BATCH_REGVAL(RADEON_PP_CNTL, (RADEON_TEX_0_ENABLE |
RADEON_TEX_BLEND_0_ENABLE |
RADEON_TEX_BLEND_1_ENABLE |
RADEON_TEX_BLEND_2_ENABLE |
RADEON_TEX_BLEND_3_ENABLE));
/* r1.r = r0.b */
OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO |
R200_TXC_ARG_B_ZERO |
R200_TXC_ARG_C_R0_COLOR |
R200_TXC_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 |
R200_TXC_OUTPUT_MASK_R |
(R200_TXC_REPL_BLUE << R200_TXC_REPL_ARG_C_SHIFT) |
R200_TXC_OUTPUT_REG_R1));
/* r1.a = r0.a */
OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO |
R200_TXA_ARG_B_ZERO |
R200_TXA_ARG_C_R0_ALPHA |
R200_TXA_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, (R200_TXA_CLAMP_0_1 |
R200_TXA_OUTPUT_REG_R1));
/* r1.g = r0.g */
OUT_BATCH_REGVAL(R200_PP_TXCBLEND_1, (R200_TXC_ARG_A_ZERO |
R200_TXC_ARG_B_ZERO |
R200_TXC_ARG_C_R0_COLOR |
R200_TXC_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_1, (R200_TXC_CLAMP_0_1 |
R200_TXC_OUTPUT_MASK_G |
(R200_TXC_REPL_GREEN << R200_TXC_REPL_ARG_C_SHIFT) |
R200_TXC_OUTPUT_REG_R1));
/* r1.a = r0.a */
OUT_BATCH_REGVAL(R200_PP_TXABLEND_1, (R200_TXA_ARG_A_ZERO |
R200_TXA_ARG_B_ZERO |
R200_TXA_ARG_C_R0_ALPHA |
R200_TXA_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXABLEND2_1, (R200_TXA_CLAMP_0_1 |
R200_TXA_OUTPUT_REG_R1));
/* r1.b = r0.r */
OUT_BATCH_REGVAL(R200_PP_TXCBLEND_2, (R200_TXC_ARG_A_ZERO |
R200_TXC_ARG_B_ZERO |
R200_TXC_ARG_C_R0_COLOR |
R200_TXC_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_2, (R200_TXC_CLAMP_0_1 |
R200_TXC_OUTPUT_MASK_B |
(R200_TXC_REPL_RED << R200_TXC_REPL_ARG_C_SHIFT) |
R200_TXC_OUTPUT_REG_R1));
/* r1.a = r0.a */
OUT_BATCH_REGVAL(R200_PP_TXABLEND_2, (R200_TXA_ARG_A_ZERO |
R200_TXA_ARG_B_ZERO |
R200_TXA_ARG_C_R0_ALPHA |
R200_TXA_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXABLEND2_2, (R200_TXA_CLAMP_0_1 |
R200_TXA_OUTPUT_REG_R1));
/* r0.rgb = r1.rgb */
OUT_BATCH_REGVAL(R200_PP_TXCBLEND_3, (R200_TXC_ARG_A_ZERO |
R200_TXC_ARG_B_ZERO |
R200_TXC_ARG_C_R1_COLOR |
R200_TXC_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_3, (R200_TXC_CLAMP_0_1 |
R200_TXC_OUTPUT_REG_R0));
/* r0.a = r1.a */
OUT_BATCH_REGVAL(R200_PP_TXABLEND_3, (R200_TXA_ARG_A_ZERO |
R200_TXA_ARG_B_ZERO |
R200_TXA_ARG_C_R1_ALPHA |
R200_TXA_OP_MADD));
OUT_BATCH_REGVAL(R200_PP_TXABLEND2_3, (R200_TXA_CLAMP_0_1 |
R200_TXA_OUTPUT_REG_R0));
END_BATCH();
}
break;
}
BEGIN_BATCH(18);
OUT_BATCH_REGVAL(R200_PP_CNTL_X, 0);
OUT_BATCH_REGVAL(R200_PP_TXMULTI_CTL_0, 0);
OUT_BATCH_REGVAL(R200_PP_TXFILTER_0, (R200_CLAMP_S_CLAMP_LAST |
R200_CLAMP_T_CLAMP_LAST |
R200_MAG_FILTER_NEAREST |
R200_MIN_FILTER_NEAREST));
OUT_BATCH_REGVAL(R200_PP_TXFORMAT_0, txformat);
OUT_BATCH_REGVAL(R200_PP_TXFORMAT_X_0, 0);
OUT_BATCH_REGVAL(R200_PP_TXSIZE_0, ((width - 1) |
((height - 1) << RADEON_TEX_VSIZE_SHIFT)));
OUT_BATCH_REGVAL(R200_PP_TXPITCH_0, pitch * _mesa_get_format_bytes(src_mesa_format) - 32);
OUT_BATCH_REGSEQ(R200_PP_TXOFFSET_0, 1);
OUT_BATCH_RELOC(bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
END_BATCH();
}
static inline void emit_cb_setup(struct r200_context *r200,
struct radeon_bo *bo,
intptr_t offset,
mesa_format mesa_format,
unsigned pitch,
unsigned width,
unsigned height)
{
uint32_t dst_pitch = pitch;
uint32_t dst_format = 0;
BATCH_LOCALS(&r200->radeon);
switch (mesa_format) {
/* The first of each pair is for little, the second for big endian */
case MESA_FORMAT_B8G8R8A8_UNORM:
case MESA_FORMAT_A8R8G8B8_UNORM:
case MESA_FORMAT_B8G8R8X8_UNORM:
case MESA_FORMAT_X8R8G8B8_UNORM:
/* These two are valid both for little and big endian (swizzled) */
case MESA_FORMAT_A8B8G8R8_UNORM:
case MESA_FORMAT_R8G8B8A8_UNORM:
dst_format = RADEON_COLOR_FORMAT_ARGB8888;
break;
case MESA_FORMAT_B5G6R5_UNORM:
case MESA_FORMAT_R5G6B5_UNORM:
dst_format = RADEON_COLOR_FORMAT_RGB565;
break;
case MESA_FORMAT_B4G4R4A4_UNORM:
case MESA_FORMAT_A4R4G4B4_UNORM:
dst_format = RADEON_COLOR_FORMAT_ARGB4444;
break;
case MESA_FORMAT_B5G5R5A1_UNORM:
case MESA_FORMAT_A1R5G5B5_UNORM:
dst_format = RADEON_COLOR_FORMAT_ARGB1555;
break;
case MESA_FORMAT_A_UNORM8:
case MESA_FORMAT_L_UNORM8:
case MESA_FORMAT_I_UNORM8:
dst_format = RADEON_COLOR_FORMAT_RGB8;
break;
default:
break;
}
if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
dst_pitch |= R200_COLOR_TILE_ENABLE;
if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
dst_pitch |= R200_COLOR_MICROTILE_ENABLE;
BEGIN_BATCH(22);
OUT_BATCH_REGVAL(R200_RE_AUX_SCISSOR_CNTL, 0);
OUT_BATCH_REGVAL(R200_RE_CNTL, 0);
OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0);
OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, (((width - 1) << RADEON_RE_WIDTH_SHIFT) |
((height - 1) << RADEON_RE_HEIGHT_SHIFT)));
OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff);
OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO);
OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format);
OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1);
OUT_BATCH_RELOC(bo, offset, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1);
OUT_BATCH_RELOC(bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
END_BATCH();
}
static GLboolean validate_buffers(struct r200_context *r200,
struct radeon_bo *src_bo,
struct radeon_bo *dst_bo)
{
int ret;
radeon_cs_space_reset_bos(r200->radeon.cmdbuf.cs);
ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs,
src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
if (ret)
return GL_FALSE;
ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs,
dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
if (ret)
return GL_FALSE;
return GL_TRUE;
}
/**
* Calculate texcoords for given image region.
* Output values are [minx, maxx, miny, maxy]
*/
static inline void calc_tex_coords(float img_width, float img_height,
float x, float y,
float reg_width, float reg_height,
unsigned flip_y, float *buf)
{
buf[0] = x / img_width;
buf[1] = buf[0] + reg_width / img_width;
buf[2] = y / img_height;
buf[3] = buf[2] + reg_height / img_height;
if (flip_y)
{
buf[2] = 1.0 - buf[2];
buf[3] = 1.0 - buf[3];
}
}
static inline void emit_draw_packet(struct r200_context *r200,
unsigned src_width, unsigned src_height,
unsigned src_x_offset, unsigned src_y_offset,
unsigned dst_x_offset, unsigned dst_y_offset,
unsigned reg_width, unsigned reg_height,
unsigned flip_y)
{
float texcoords[4];
float verts[12];
BATCH_LOCALS(&r200->radeon);
calc_tex_coords(src_width, src_height,
src_x_offset, src_y_offset,
reg_width, reg_height,
flip_y, texcoords);
verts[0] = dst_x_offset;
verts[1] = dst_y_offset + reg_height;
verts[2] = texcoords[0];
verts[3] = texcoords[3];
verts[4] = dst_x_offset + reg_width;
verts[5] = dst_y_offset + reg_height;
verts[6] = texcoords[1];
verts[7] = texcoords[3];
verts[8] = dst_x_offset + reg_width;
verts[9] = dst_y_offset;
verts[10] = texcoords[1];
verts[11] = texcoords[2];
BEGIN_BATCH(14);
OUT_BATCH(R200_CP_CMD_3D_DRAW_IMMD_2 | (12 << 16));
OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING |
RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST |
(3 << 16));
OUT_BATCH_TABLE(verts, 12);
END_BATCH();
}
/**
* Copy a region of [@a width x @a height] pixels from source buffer
* to destination buffer.
* @param[in] r200 r200 context
* @param[in] src_bo source radeon buffer object
* @param[in] src_offset offset of the source image in the @a src_bo
* @param[in] src_mesaformat source image format
* @param[in] src_pitch aligned source image width
* @param[in] src_width source image width
* @param[in] src_height source image height
* @param[in] src_x_offset x offset in the source image
* @param[in] src_y_offset y offset in the source image
* @param[in] dst_bo destination radeon buffer object
* @param[in] dst_offset offset of the destination image in the @a dst_bo
* @param[in] dst_mesaformat destination image format
* @param[in] dst_pitch aligned destination image width
* @param[in] dst_width destination image width
* @param[in] dst_height destination image height
* @param[in] dst_x_offset x offset in the destination image
* @param[in] dst_y_offset y offset in the destination image
* @param[in] width region width
* @param[in] height region height
* @param[in] flip_y set if y coords of the source image need to be flipped
*/
unsigned r200_blit(struct gl_context *ctx,
struct radeon_bo *src_bo,
intptr_t src_offset,
mesa_format src_mesaformat,
unsigned src_pitch,
unsigned src_width,
unsigned src_height,
unsigned src_x_offset,
unsigned src_y_offset,
struct radeon_bo *dst_bo,
intptr_t dst_offset,
mesa_format dst_mesaformat,
unsigned dst_pitch,
unsigned dst_width,
unsigned dst_height,
unsigned dst_x_offset,
unsigned dst_y_offset,
unsigned reg_width,
unsigned reg_height,
unsigned flip_y)
{
struct r200_context *r200 = R200_CONTEXT(ctx);
if (!r200_check_blit(dst_mesaformat, dst_pitch))
return GL_FALSE;
/* Make sure that colorbuffer has even width - hw limitation */
if (dst_pitch % 2 > 0)
++dst_pitch;
/* Need to clamp the region size to make sure
* we don't read outside of the source buffer
* or write outside of the destination buffer.
*/
if (reg_width + src_x_offset > src_width)
reg_width = src_width - src_x_offset;
if (reg_height + src_y_offset > src_height)
reg_height = src_height - src_y_offset;
if (reg_width + dst_x_offset > dst_width)
reg_width = dst_width - dst_x_offset;
if (reg_height + dst_y_offset > dst_height)
reg_height = dst_height - dst_y_offset;
if (src_bo == dst_bo) {
return GL_FALSE;
}
if (src_offset % 32 || dst_offset % 32) {
return GL_FALSE;
}
if (0) {
fprintf(stderr, "src: size [%d x %d], pitch %d, "
"offset [%d x %d], format %s, bo %p\n",
src_width, src_height, src_pitch,
src_x_offset, src_y_offset,
_mesa_get_format_name(src_mesaformat),
src_bo);
fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
dst_pitch, dst_x_offset, dst_y_offset,
_mesa_get_format_name(dst_mesaformat), dst_bo);
fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
}
/* Flush is needed to make sure that source buffer has correct data */
radeonFlush(&r200->radeon.glCtx, 0);
rcommonEnsureCmdBufSpace(&r200->radeon, 102, __func__);
if (!validate_buffers(r200, src_bo, dst_bo))
return GL_FALSE;
/* 14 */
emit_vtx_state(r200);
/* 52 */
emit_tx_setup(r200, src_mesaformat, dst_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
/* 22 */
emit_cb_setup(r200, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
/* 14 */
emit_draw_packet(r200, src_width, src_height,
src_x_offset, src_y_offset,
dst_x_offset, dst_y_offset,
reg_width, reg_height,
flip_y);
radeonFlush(ctx, 0);
/* We submitted those packets outside our state atom mechanism. Thus
* make sure the atoms are resubmitted the next time. */
r200->hw.cst.dirty = GL_TRUE;
r200->hw.ctx.dirty = GL_TRUE;
r200->hw.vap.dirty = GL_TRUE;
r200->hw.msk.dirty = GL_TRUE;
r200->hw.pix[0].dirty = GL_TRUE;
r200->hw.pix[1].dirty = GL_TRUE;
r200->hw.pix[2].dirty = GL_TRUE;
r200->hw.pix[3].dirty = GL_TRUE;
r200->hw.sci.dirty = GL_TRUE;
r200->hw.set.dirty = GL_TRUE;
r200->hw.tex[0].dirty = GL_TRUE;
r200->hw.vte.dirty = GL_TRUE;
r200->hw.vtx.dirty = GL_TRUE;
return GL_TRUE;
}

View File

@ -1,56 +0,0 @@
/*
* Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef R200_BLIT_H
#define R200_BLIT_H
void r200_blit_init(struct r200_context *r200);
unsigned r200_check_blit(mesa_format mesa_format, uint32_t dst_pitch);
unsigned r200_blit(struct gl_context *ctx,
struct radeon_bo *src_bo,
intptr_t src_offset,
mesa_format src_mesaformat,
unsigned src_pitch,
unsigned src_width,
unsigned src_height,
unsigned src_x_offset,
unsigned src_y_offset,
struct radeon_bo *dst_bo,
intptr_t dst_offset,
mesa_format dst_mesaformat,
unsigned dst_pitch,
unsigned dst_width,
unsigned dst_height,
unsigned dst_x_offset,
unsigned dst_y_offset,
unsigned width,
unsigned height,
unsigned flip_y);
#endif // R200_BLIT_H

View File

@ -1,300 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include "main/glheader.h"
#include "main/macros.h"
#include "main/context.h"
#include "util/simple_list.h"
#include "radeon_common.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "radeon_reg.h"
/* The state atoms will be emitted in the order they appear in the atom list,
* so this step is important.
*/
#define insert_at_tail_if(atom_list, atom) \
do { \
struct radeon_state_atom* current_atom = (atom); \
if (current_atom->check) \
insert_at_tail((atom_list), current_atom); \
} while(0)
void r200SetUpAtomList( r200ContextPtr rmesa )
{
int i, mtu;
mtu = rmesa->radeon.glCtx.Const.MaxTextureUnits;
make_empty_list(&rmesa->radeon.hw.atomlist);
rmesa->radeon.hw.atomlist.name = "atom-list";
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ctx );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.set );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lin );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msk );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpt );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vtx );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vap );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vte );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msc );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.cst );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.zbs );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcl );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msl );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcg );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.grd );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.fog );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tam );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tf );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.atf );
for (i = 0; i < mtu; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i] );
for (i = 0; i < mtu; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i] );
for (i = 0; i < 6; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.stp );
for (i = 0; i < 8; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] );
for (i = 0; i < 3 + mtu; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.eye );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.glt );
for (i = 0; i < 2; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.mtl[i] );
for (i = 0; i < 6; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.spr );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ptp );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.prf );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pvs );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[0] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[1] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[0] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[1] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.sci );
}
/* Fire a section of the retained (indexed_verts) buffer as a regular
* primtive.
*/
void r200EmitVbufPrim( r200ContextPtr rmesa,
GLuint primitive,
GLuint vertex_nr )
{
BATCH_LOCALS(&rmesa->radeon);
assert(!(primitive & R200_VF_PRIM_WALK_IND));
radeonEmitState(&rmesa->radeon);
radeon_print(RADEON_RENDER|RADEON_SWRENDER,RADEON_VERBOSE,
"%s cmd_used/4: %d prim %x nr %d\n", __func__,
rmesa->store.cmd_used/4, primitive, vertex_nr);
BEGIN_BATCH(3);
OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_VBUF_2, 0);
OUT_BATCH(primitive | R200_VF_PRIM_WALK_LIST | R200_VF_COLOR_ORDER_RGBA |
(vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT));
END_BATCH();
}
static void r200FireEB(r200ContextPtr rmesa, int vertex_count, int type)
{
BATCH_LOCALS(&rmesa->radeon);
if (vertex_count > 0) {
BEGIN_BATCH(8+2);
OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_INDX_2, 0);
OUT_BATCH(R200_VF_PRIM_WALK_IND |
R200_VF_COLOR_ORDER_RGBA |
((vertex_count + 0) << 16) |
type);
OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2);
OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810);
OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset);
OUT_BATCH((vertex_count + 1)/2);
radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
rmesa->radeon.tcl.elt_dma_bo,
RADEON_GEM_DOMAIN_GTT, 0, 0);
END_BATCH();
}
}
void r200FlushElts(struct gl_context *ctx)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
int nr, elt_used = rmesa->tcl.elt_used;
radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __func__, rmesa->tcl.hw_primitive, elt_used);
assert( rmesa->radeon.dma.flush == r200FlushElts );
rmesa->radeon.dma.flush = NULL;
nr = elt_used / 2;
radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);
r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive);
radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
rmesa->radeon.tcl.elt_dma_bo = NULL;
if (R200_ELT_BUF_SZ > elt_used)
radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);
}
GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
GLuint primitive,
GLuint min_nr )
{
GLushort *retval;
radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %d prim %x\n", __func__, min_nr, primitive);
assert((primitive & R200_VF_PRIM_WALK_IND));
radeonEmitState(&rmesa->radeon);
radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
&rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4);
rmesa->tcl.elt_used = min_nr * 2;
radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
assert(!rmesa->radeon.dma.flush);
rmesa->radeon.glCtx.Driver.NeedFlush |= FLUSH_STORED_VERTICES;
rmesa->radeon.dma.flush = r200FlushElts;
return retval;
}
void r200EmitMaxVtxIndex(r200ContextPtr rmesa, int count)
{
BATCH_LOCALS(&rmesa->radeon);
BEGIN_BATCH(2);
OUT_BATCH(CP_PACKET0(R200_SE_VF_MAX_VTX_INDX, 0));
OUT_BATCH(count);
END_BATCH();
}
void r200EmitVertexAOS( r200ContextPtr rmesa,
GLuint vertex_size,
struct radeon_bo *bo,
GLuint offset )
{
BATCH_LOCALS(&rmesa->radeon);
radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s: vertex_size 0x%x offset 0x%x \n",
__func__, vertex_size, offset);
BEGIN_BATCH(7);
OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, 2);
OUT_BATCH(1);
OUT_BATCH(vertex_size | (vertex_size << 8));
OUT_BATCH_RELOC(bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
END_BATCH();
}
void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset)
{
BATCH_LOCALS(&rmesa->radeon);
uint32_t voffset;
int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
int i;
radeon_print(RADEON_RENDER, RADEON_VERBOSE,
"%s: nr=%d, ofs=0x%08x\n",
__func__, nr, offset);
BEGIN_BATCH(sz+2+ (nr*2));
OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, sz - 1);
OUT_BATCH(nr);
{
for (i = 0; i + 1 < nr; i += 2) {
OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
(rmesa->radeon.tcl.aos[i].stride << 8) |
(rmesa->radeon.tcl.aos[i + 1].components << 16) |
(rmesa->radeon.tcl.aos[i + 1].stride << 24));
voffset = rmesa->radeon.tcl.aos[i + 0].offset +
offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
OUT_BATCH(voffset);
voffset = rmesa->radeon.tcl.aos[i + 1].offset +
offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
OUT_BATCH(voffset);
}
if (nr & 1) {
OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
(rmesa->radeon.tcl.aos[nr - 1].stride << 8));
voffset = rmesa->radeon.tcl.aos[nr - 1].offset +
offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
OUT_BATCH(voffset);
}
for (i = 0; i + 1 < nr; i += 2) {
voffset = rmesa->radeon.tcl.aos[i + 0].offset +
offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
rmesa->radeon.tcl.aos[i+0].bo,
RADEON_GEM_DOMAIN_GTT,
0, 0);
voffset = rmesa->radeon.tcl.aos[i + 1].offset +
offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
rmesa->radeon.tcl.aos[i+1].bo,
RADEON_GEM_DOMAIN_GTT,
0, 0);
}
if (nr & 1) {
voffset = rmesa->radeon.tcl.aos[nr - 1].offset +
offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
rmesa->radeon.tcl.aos[nr-1].bo,
RADEON_GEM_DOMAIN_GTT,
0, 0);
}
}
END_BATCH();
}

View File

@ -1,413 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include <stdbool.h>
#include "main/glheader.h"
#include "main/api_arrayelt.h"
#include "main/api_exec.h"
#include "main/context.h"
#include "main/extensions.h"
#include "main/version.h"
#include "main/vtxfmt.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "drivers/common/driverfuncs.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_state.h"
#include "r200_tex.h"
#include "r200_swtcl.h"
#include "r200_tcl.h"
#include "r200_vertprog.h"
#include "radeon_queryobj.h"
#include "r200_blit.h"
#include "radeon_fog.h"
#include "radeon_span.h"
#include "utils.h"
#include "util/driconf.h" /* for symbolic values of enum-type options */
#include "util/u_memory.h"
/* Return various strings for glGetString().
*/
static const GLubyte *r200GetString( struct gl_context *ctx, GLenum name )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
static char buffer[128];
unsigned offset;
GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type == RADEON_CARD_PCI)? 0 :
rmesa->radeon.radeonScreen->AGPMode;
switch ( name ) {
case GL_VENDOR:
return (GLubyte *)"Mesa Project";
case GL_RENDERER:
offset = driGetRendererString( buffer, "R200", agp_mode );
sprintf( & buffer[ offset ], " %sTCL",
!(rmesa->radeon.TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
? "" : "NO-" );
return (GLubyte *)buffer;
default:
return NULL;
}
}
extern const struct tnl_pipeline_stage _r200_render_stage;
extern const struct tnl_pipeline_stage _r200_tcl_stage;
static const struct tnl_pipeline_stage *r200_pipeline[] = {
/* Try and go straight to t&l
*/
&_r200_tcl_stage,
/* Catch any t&l fallbacks
*/
&_tnl_vertex_transform_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
&_tnl_point_attenuation_stage,
&_tnl_vertex_program_stage,
/* Try again to go to tcl?
* - no good for asymmetric-twoside (do with multipass)
* - no good for asymmetric-unfilled (do with multipass)
* - good for material
* - good for texgen
* - need to manipulate a bit of state
*
* - worth it/not worth it?
*/
/* Else do them here.
*/
/* &_r200_render_stage, */ /* FIXME: bugs with ut2003 */
&_tnl_render_stage, /* FALLBACK: */
NULL,
};
/* Initialize the driver's misc functions.
*/
static void r200InitDriverFuncs( struct dd_function_table *functions )
{
functions->GetString = r200GetString;
}
static void r200_emit_query_finish(radeonContextPtr radeon)
{
BATCH_LOCALS(radeon);
struct radeon_query_object *query = radeon->query.current;
BEGIN_BATCH(4);
OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
OUT_BATCH_RELOC(query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
END_BATCH();
query->curr_offset += sizeof(uint32_t);
assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
query->emitted_begin = GL_FALSE;
}
static void r200_init_vtbl(radeonContextPtr radeon)
{
radeon->vtbl.swtcl_flush = r200_swtcl_flush;
radeon->vtbl.fallback = r200Fallback;
radeon->vtbl.update_scissor = r200_vtbl_update_scissor;
radeon->vtbl.emit_query_finish = r200_emit_query_finish;
radeon->vtbl.check_blit = r200_check_blit;
radeon->vtbl.blit = r200_blit;
radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
radeon->vtbl.revalidate_all_buffers = r200ValidateBuffers;
}
/* Create the device specific rendering context.
*/
GLboolean r200CreateContext( gl_api api,
const struct gl_config *glVisual,
__DRIcontext *driContextPriv,
const struct __DriverContextConfig *ctx_config,
unsigned *error,
void *sharedContextPrivate)
{
__DRIscreen *sPriv = driContextPriv->driScreenPriv;
radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
struct dd_function_table functions;
r200ContextPtr rmesa;
struct gl_context *ctx;
int i;
int tcl_mode;
if (ctx_config->flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_NO_ERROR)) {
*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
return false;
}
if (ctx_config->attribute_mask) {
*error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
return false;
}
assert(driContextPriv);
assert(screen);
/* Allocate the R200 context */
rmesa = align_calloc(sizeof(*rmesa), 16);
if ( !rmesa ) {
*error = __DRI_CTX_ERROR_NO_MEMORY;
return GL_FALSE;
}
rmesa->radeon.radeonScreen = screen;
r200_init_vtbl(&rmesa->radeon);
/* init exp fog table data */
radeonInitStaticFogData();
/* Parse configuration files.
* Do this here so that initialMaxAnisotropy is set before we create
* the default textures.
*/
driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
screen->driScreen->myNum, "r200", NULL, NULL, NULL, 0, NULL, 0);
rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
"def_max_anisotropy");
if (driQueryOptionb( &rmesa->radeon.optionCache, "hyperz"))
rmesa->using_hyperz = GL_TRUE;
/* Init default driver functions then plug in our R200-specific functions
* (the texture functions are especially important)
*/
_mesa_init_driver_functions(&functions);
_tnl_init_driver_draw_function(&functions);
r200InitDriverFuncs(&functions);
r200InitIoctlFuncs(&functions);
r200InitStateFuncs(&rmesa->radeon, &functions);
r200InitTextureFuncs(&rmesa->radeon, &functions);
r200InitShaderFuncs(&functions);
radeonInitQueryObjFunctions(&functions);
if (!radeonInitContext(&rmesa->radeon, api, &functions,
glVisual, driContextPriv,
sharedContextPrivate)) {
align_free(rmesa);
*error = __DRI_CTX_ERROR_NO_MEMORY;
return GL_FALSE;
}
rmesa->radeon.swtcl.RenderIndex = ~0;
rmesa->radeon.hw.all_dirty = 1;
ctx = &rmesa->radeon.glCtx;
driContextSetFlags(ctx, ctx_config->flags);
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
_vbo_CreateContext( ctx, false );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
"texture_units");
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
ctx->Const.StripTextureBorder = GL_TRUE;
/* FIXME: When no memory manager is available we should set this
* to some reasonable value based on texture memory pool size */
ctx->Const.MaxTextureSize = 2048;
ctx->Const.Max3DTextureLevels = 9;
ctx->Const.MaxCubeTextureLevels = 12;
ctx->Const.MaxTextureRectSize = 2048;
ctx->Const.MaxRenderbufferSize = 2048;
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
/* No wide AA points.
*/
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
ctx->Const.MaxPointSizeAA = 1.0;
ctx->Const.PointSizeGranularity = 0.0625;
ctx->Const.MaxPointSize = 2047.0;
/* mesa initialization problem - _mesa_init_point was already called */
ctx->Point.MaxSize = ctx->Const.MaxPointSize;
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 10.0;
ctx->Const.MaxLineWidthAA = 10.0;
ctx->Const.LineWidthGranularity = 0.0625;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeInstructions = R200_VSF_MAX_INST;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAttribs = 12;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTemps = R200_VSF_MAX_TEMPS;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters = R200_VSF_MAX_PARAM;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAddressRegs = 1;
ctx->Const.MaxDrawBuffers = 1;
ctx->Const.MaxColorAttachments = 1;
ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = GL_TRUE;
/* Install the customized pipeline:
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, r200_pipeline );
/* Try and keep materials and vertices separate:
*/
/* _tnl_isolate_materials( ctx, GL_TRUE ); */
/* Configure swrast and TNL to match hardware characteristics:
*/
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );
_tnl_allow_pixel_fog( ctx, GL_FALSE );
_tnl_allow_vertex_fog( ctx, GL_TRUE );
for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
_math_matrix_ctr( &rmesa->TexGenMatrix[i] );
_math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
}
_math_matrix_ctr( &rmesa->tmpmat );
_math_matrix_set_identity( &rmesa->tmpmat );
ctx->Extensions.ARB_occlusion_query = true;
ctx->Extensions.ARB_point_sprite = true;
ctx->Extensions.ARB_texture_border_clamp = true;
ctx->Extensions.ARB_texture_cube_map = true;
ctx->Extensions.ARB_texture_env_combine = true;
ctx->Extensions.ARB_texture_env_dot3 = true;
ctx->Extensions.ARB_texture_env_crossbar = true;
ctx->Extensions.ARB_texture_filter_anisotropic = true;
ctx->Extensions.ARB_texture_mirror_clamp_to_edge = true;
ctx->Extensions.ARB_vertex_program = true;
ctx->Extensions.ATI_fragment_shader = (ctx->Const.MaxTextureUnits == 6);
ctx->Extensions.ATI_texture_env_combine3 = true;
ctx->Extensions.ATI_texture_mirror_once = true;
ctx->Extensions.EXT_blend_color = true;
ctx->Extensions.EXT_blend_equation_separate = true;
ctx->Extensions.EXT_blend_func_separate = true;
ctx->Extensions.EXT_blend_minmax = true;
ctx->Extensions.EXT_gpu_program_parameters = true;
ctx->Extensions.EXT_point_parameters = true;
ctx->Extensions.EXT_texture_env_dot3 = true;
ctx->Extensions.EXT_texture_filter_anisotropic = true;
ctx->Extensions.EXT_texture_mirror_clamp = true;
ctx->Extensions.NV_fog_distance = true;
ctx->Extensions.NV_texture_rectangle = true;
ctx->Extensions.OES_EGL_image = true;
if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
/* yuv textures don't work with some chips - R200 / rv280 okay so far
others get the bit ordering right but don't actually do YUV-RGB conversion */
ctx->Extensions.MESA_ycbcr_texture = true;
}
ctx->Extensions.EXT_texture_compression_s3tc = true;
ctx->Extensions.ANGLE_texture_compression_dxt = true;
#if 0
r200InitDriverFuncs( ctx );
r200InitIoctlFuncs( ctx );
r200InitStateFuncs( ctx );
r200InitTextureFuncs( ctx );
#endif
/* plug in a few more device driver functions */
/* XXX these should really go right after _mesa_init_driver_functions() */
radeon_fbo_init(&rmesa->radeon);
radeonInitSpanFuncs( ctx );
r200InitTnlFuncs( ctx );
r200InitState( rmesa );
r200InitSwtcl( ctx );
rmesa->prefer_gart_client_texturing =
(getenv("R200_GART_CLIENT_TEXTURES") != 0);
tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
if (getenv("R200_NO_RAST")) {
fprintf(stderr, "disabling 3D acceleration\n");
FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
}
else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
fprintf(stderr, "Disabling HW TCL support\n");
}
TCL_FALLBACK(&rmesa->radeon.glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
}
_mesa_override_extensions(ctx);
_mesa_compute_version(ctx);
/* Exec table initialization requires the version to be computed */
_mesa_initialize_dispatch_tables(ctx);
_mesa_initialize_vbo_vtxfmt(ctx);
*error = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
}
void r200DestroyContext( __DRIcontext *driContextPriv )
{
radeonDestroyContext(driContextPriv);
}

View File

@ -1,650 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_CONTEXT_H__
#define __R200_CONTEXT_H__
#include "tnl/t_vertex.h"
#include "drm-uapi/drm.h"
#include "radeon_drm.h"
#include "dri_util.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "r200_reg.h"
#include "r200_vertprog.h"
#ifndef R200_EMIT_VAP_PVS_CNTL
#error This driver requires a newer libdrm to compile
#endif
#include "radeon_screen.h"
#include "radeon_common.h"
struct r200_context;
typedef struct r200_context r200ContextRec;
typedef struct r200_context *r200ContextPtr;
struct r200_vertex_program {
struct gl_program mesa_program; /* Must be first */
int translated;
/* need excess instr: 1 for late loop checking, 2 for
additional instr due to instr/attr, 3 for fog */
VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6];
int pos_end;
int inputs[VERT_ATTRIB_MAX];
GLubyte inputmap_rev[16];
int native;
int fogpidx;
int fogmode;
};
#define R200_TEX_ALL 0x3f
struct r200_texture_env_state {
radeonTexObjPtr texobj;
GLuint outputreg;
GLuint unitneeded;
};
#define R200_MAX_TEXTURE_UNITS 6
struct r200_texture_state {
struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS];
};
/* Trying to keep these relatively short as the variables are becoming
* extravagently long. Drop the driver name prefix off the front of
* everything - I think we know which driver we're in by now, and keep the
* prefix to 3 letters unless absolutely impossible.
*/
#define CTX_CMD_0 0
#define CTX_PP_MISC 1
#define CTX_PP_FOG_COLOR 2
#define CTX_RE_SOLID_COLOR 3
#define CTX_RB3D_BLENDCNTL 4
#define CTX_RB3D_DEPTHOFFSET 5
#define CTX_RB3D_DEPTHPITCH 6
#define CTX_RB3D_ZSTENCILCNTL 7
#define CTX_CMD_1 8
#define CTX_PP_CNTL 9
#define CTX_RB3D_CNTL 10
#define CTX_RB3D_COLOROFFSET 11
#define CTX_CMD_2 12 /* why */
#define CTX_RB3D_COLORPITCH 13 /* why */
#define CTX_CMD_3 14
#define CTX_RB3D_BLENDCOLOR 15
#define CTX_RB3D_ABLENDCNTL 16
#define CTX_RB3D_CBLENDCNTL 17
#define CTX_STATE_SIZE_NEWDRM 18
#define SET_CMD_0 0
#define SET_SE_CNTL 1
#define SET_RE_CNTL 2 /* replace se_coord_fmt */
#define SET_STATE_SIZE 3
#define VTE_CMD_0 0
#define VTE_SE_VTE_CNTL 1
#define VTE_STATE_SIZE 2
#define LIN_CMD_0 0
#define LIN_RE_LINE_PATTERN 1
#define LIN_RE_LINE_STATE 2
#define LIN_CMD_1 3
#define LIN_SE_LINE_WIDTH 4
#define LIN_STATE_SIZE 5
#define MSK_CMD_0 0
#define MSK_RB3D_STENCILREFMASK 1
#define MSK_RB3D_ROPCNTL 2
#define MSK_RB3D_PLANEMASK 3
#define MSK_STATE_SIZE 4
#define VPT_CMD_0 0
#define VPT_SE_VPORT_XSCALE 1
#define VPT_SE_VPORT_XOFFSET 2
#define VPT_SE_VPORT_YSCALE 3
#define VPT_SE_VPORT_YOFFSET 4
#define VPT_SE_VPORT_ZSCALE 5
#define VPT_SE_VPORT_ZOFFSET 6
#define VPT_STATE_SIZE 7
#define ZBS_CMD_0 0
#define ZBS_SE_ZBIAS_FACTOR 1
#define ZBS_SE_ZBIAS_CONSTANT 2
#define ZBS_STATE_SIZE 3
#define MSC_CMD_0 0
#define MSC_RE_MISC 1
#define MSC_STATE_SIZE 2
#define TAM_CMD_0 0
#define TAM_DEBUG3 1
#define TAM_STATE_SIZE 2
#define TEX_CMD_0 0
#define TEX_PP_TXFILTER 1 /*2c00*/
#define TEX_PP_TXFORMAT 2 /*2c04*/
#define TEX_PP_TXFORMAT_X 3 /*2c08*/
#define TEX_PP_TXSIZE 4 /*2c0c*/
#define TEX_PP_TXPITCH 5 /*2c10*/
#define TEX_PP_BORDER_COLOR 6 /*2c14*/
#define TEX_PP_CUBIC_FACES 7
#define TEX_PP_TXMULTI_CTL 8
#define TEX_CMD_1_NEWDRM 9
#define TEX_PP_TXOFFSET_NEWDRM 10
#define TEX_STATE_SIZE_NEWDRM 11
#define CUBE_CMD_0 0 /* 1 register follows */ /* this command unnecessary */
#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */ /* with new enough drm */
#define CUBE_CMD_1 2 /* 5 registers follow */
#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */
#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */
#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */
#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */
#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */
#define CUBE_STATE_SIZE 8
#define PIX_CMD_0 0
#define PIX_PP_TXCBLEND 1
#define PIX_PP_TXCBLEND2 2
#define PIX_PP_TXABLEND 3
#define PIX_PP_TXABLEND2 4
#define PIX_STATE_SIZE 5
#define TF_CMD_0 0
#define TF_TFACTOR_0 1
#define TF_TFACTOR_1 2
#define TF_TFACTOR_2 3
#define TF_TFACTOR_3 4
#define TF_TFACTOR_4 5
#define TF_TFACTOR_5 6
#define TF_STATE_SIZE 7
#define ATF_CMD_0 0
#define ATF_TFACTOR_0 1
#define ATF_TFACTOR_1 2
#define ATF_TFACTOR_2 3
#define ATF_TFACTOR_3 4
#define ATF_TFACTOR_4 5
#define ATF_TFACTOR_5 6
#define ATF_TFACTOR_6 7
#define ATF_TFACTOR_7 8
#define ATF_STATE_SIZE 9
/* ATI_FRAGMENT_SHADER */
#define AFS_CMD_0 0
#define AFS_IC0 1 /* 2f00 */
#define AFS_IC1 2 /* 2f04 */
#define AFS_IA0 3 /* 2f08 */
#define AFS_IA1 4 /* 2f0c */
#define AFS_STATE_SIZE 33
#define PVS_CMD_0 0
#define PVS_CNTL_1 1
#define PVS_CNTL_2 2
#define PVS_STATE_SIZE 3
/* those are quite big... */
#define VPI_CMD_0 0
#define VPI_OPDST_0 1
#define VPI_SRC0_0 2
#define VPI_SRC1_0 3
#define VPI_SRC2_0 4
#define VPI_OPDST_63 253
#define VPI_SRC0_63 254
#define VPI_SRC1_63 255
#define VPI_SRC2_63 256
#define VPI_STATE_SIZE 257
#define VPP_CMD_0 0
#define VPP_PARAM0_0 1
#define VPP_PARAM1_0 2
#define VPP_PARAM2_0 3
#define VPP_PARAM3_0 4
#define VPP_PARAM0_95 381
#define VPP_PARAM1_95 382
#define VPP_PARAM2_95 383
#define VPP_PARAM3_95 384
#define VPP_STATE_SIZE 385
#define TCL_CMD_0 0
#define TCL_LIGHT_MODEL_CTL_0 1
#define TCL_LIGHT_MODEL_CTL_1 2
#define TCL_PER_LIGHT_CTL_0 3
#define TCL_PER_LIGHT_CTL_1 4
#define TCL_PER_LIGHT_CTL_2 5
#define TCL_PER_LIGHT_CTL_3 6
#define TCL_CMD_1 7
#define TCL_UCP_VERT_BLEND_CTL 8
#define TCL_STATE_SIZE 9
#define MSL_CMD_0 0
#define MSL_MATRIX_SELECT_0 1
#define MSL_MATRIX_SELECT_1 2
#define MSL_MATRIX_SELECT_2 3
#define MSL_MATRIX_SELECT_3 4
#define MSL_MATRIX_SELECT_4 5
#define MSL_STATE_SIZE 6
#define TCG_CMD_0 0
#define TCG_TEX_PROC_CTL_2 1
#define TCG_TEX_PROC_CTL_3 2
#define TCG_TEX_PROC_CTL_0 3
#define TCG_TEX_PROC_CTL_1 4
#define TCG_TEX_CYL_WRAP_CTL 5
#define TCG_STATE_SIZE 6
#define MTL_CMD_0 0
#define MTL_EMMISSIVE_RED 1
#define MTL_EMMISSIVE_GREEN 2
#define MTL_EMMISSIVE_BLUE 3
#define MTL_EMMISSIVE_ALPHA 4
#define MTL_AMBIENT_RED 5
#define MTL_AMBIENT_GREEN 6
#define MTL_AMBIENT_BLUE 7
#define MTL_AMBIENT_ALPHA 8
#define MTL_DIFFUSE_RED 9
#define MTL_DIFFUSE_GREEN 10
#define MTL_DIFFUSE_BLUE 11
#define MTL_DIFFUSE_ALPHA 12
#define MTL_SPECULAR_RED 13
#define MTL_SPECULAR_GREEN 14
#define MTL_SPECULAR_BLUE 15
#define MTL_SPECULAR_ALPHA 16
#define MTL_CMD_1 17
#define MTL_SHININESS 18
#define MTL_STATE_SIZE 19
#define VAP_CMD_0 0
#define VAP_SE_VAP_CNTL 1
#define VAP_STATE_SIZE 2
/* Replaces a lot of packet info from radeon
*/
#define VTX_CMD_0 0
#define VTX_VTXFMT_0 1
#define VTX_VTXFMT_1 2
#define VTX_TCL_OUTPUT_VTXFMT_0 3
#define VTX_TCL_OUTPUT_VTXFMT_1 4
#define VTX_CMD_1 5
#define VTX_TCL_OUTPUT_COMPSEL 6
#define VTX_CMD_2 7
#define VTX_STATE_CNTL 8
#define VTX_STATE_SIZE 9
/* SPR - point sprite state
*/
#define SPR_CMD_0 0
#define SPR_POINT_SPRITE_CNTL 1
#define SPR_STATE_SIZE 2
#define PTP_CMD_0 0
#define PTP_VPORT_SCALE_0 1
#define PTP_VPORT_SCALE_1 2
#define PTP_VPORT_SCALE_PTSIZE 3
#define PTP_VPORT_SCALE_3 4
#define PTP_CMD_1 5
#define PTP_ATT_CONST_QUAD 6
#define PTP_ATT_CONST_LIN 7
#define PTP_ATT_CONST_CON 8
#define PTP_ATT_CONST_3 9
#define PTP_EYE_X 10
#define PTP_EYE_Y 11
#define PTP_EYE_Z 12
#define PTP_EYE_3 13
#define PTP_CLAMP_MIN 14
#define PTP_CLAMP_MAX 15
#define PTP_CLAMP_2 16
#define PTP_CLAMP_3 17
#define PTP_STATE_SIZE 18
#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
R200_VTX_COLOR_MASK)
/**
* Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine
* how many components are in texture coordinate \c n.
*/
#define VTX_TEXn_COUNT(v,n) (((v) >> (3 * n)) & 0x07)
#define MAT_CMD_0 0
#define MAT_ELT_0 1
#define MAT_STATE_SIZE 17
#define GRD_CMD_0 0
#define GRD_VERT_GUARD_CLIP_ADJ 1
#define GRD_VERT_GUARD_DISCARD_ADJ 2
#define GRD_HORZ_GUARD_CLIP_ADJ 3
#define GRD_HORZ_GUARD_DISCARD_ADJ 4
#define GRD_STATE_SIZE 5
/* position changes frequently when lighting in modelpos - separate
* out to new state item?
*/
#define LIT_CMD_0 0
#define LIT_AMBIENT_RED 1
#define LIT_AMBIENT_GREEN 2
#define LIT_AMBIENT_BLUE 3
#define LIT_AMBIENT_ALPHA 4
#define LIT_DIFFUSE_RED 5
#define LIT_DIFFUSE_GREEN 6
#define LIT_DIFFUSE_BLUE 7
#define LIT_DIFFUSE_ALPHA 8
#define LIT_SPECULAR_RED 9
#define LIT_SPECULAR_GREEN 10
#define LIT_SPECULAR_BLUE 11
#define LIT_SPECULAR_ALPHA 12
#define LIT_POSITION_X 13
#define LIT_POSITION_Y 14
#define LIT_POSITION_Z 15
#define LIT_POSITION_W 16
#define LIT_DIRECTION_X 17
#define LIT_DIRECTION_Y 18
#define LIT_DIRECTION_Z 19
#define LIT_DIRECTION_W 20
#define LIT_ATTEN_QUADRATIC 21
#define LIT_ATTEN_LINEAR 22
#define LIT_ATTEN_CONST 23
#define LIT_ATTEN_XXX 24
#define LIT_CMD_1 25
#define LIT_SPOT_DCD 26
#define LIT_SPOT_DCM 27
#define LIT_SPOT_EXPONENT 28
#define LIT_SPOT_CUTOFF 29
#define LIT_SPECULAR_THRESH 30
#define LIT_RANGE_CUTOFF 31 /* ? */
#define LIT_ATTEN_CONST_INV 32
#define LIT_STATE_SIZE 33
/* Fog
*/
#define FOG_CMD_0 0
#define FOG_R 1
#define FOG_C 2
#define FOG_D 3
#define FOG_PAD 4
#define FOG_STATE_SIZE 5
/* UCP
*/
#define UCP_CMD_0 0
#define UCP_X 1
#define UCP_Y 2
#define UCP_Z 3
#define UCP_W 4
#define UCP_STATE_SIZE 5
/* GLT - Global ambient
*/
#define GLT_CMD_0 0
#define GLT_RED 1
#define GLT_GREEN 2
#define GLT_BLUE 3
#define GLT_ALPHA 4
#define GLT_STATE_SIZE 5
/* EYE
*/
#define EYE_CMD_0 0
#define EYE_X 1
#define EYE_Y 2
#define EYE_Z 3
#define EYE_RESCALE_FACTOR 4
#define EYE_STATE_SIZE 5
/* CST - constant state
*/
#define CST_CMD_0 0
#define CST_PP_CNTL_X 1
#define CST_CMD_1 2
#define CST_RB3D_DEPTHXY_OFFSET 3
#define CST_CMD_2 4
#define CST_RE_AUX_SCISSOR_CNTL 5
#define CST_CMD_4 6
#define CST_SE_VAP_CNTL_STATUS 7
#define CST_CMD_5 8
#define CST_RE_POINTSIZE 9
#define CST_CMD_6 10
#define CST_SE_TCL_INPUT_VTX_0 11
#define CST_SE_TCL_INPUT_VTX_1 12
#define CST_SE_TCL_INPUT_VTX_2 13
#define CST_SE_TCL_INPUT_VTX_3 14
#define CST_STATE_SIZE 15
#define PRF_CMD_0 0
#define PRF_PP_TRI_PERF 1
#define PRF_PP_PERF_CNTL 2
#define PRF_STATE_SIZE 3
#define SCI_CMD_1 0
#define SCI_XY_1 1
#define SCI_CMD_2 2
#define SCI_XY_2 3
#define SCI_STATE_SIZE 4
#define R200_QUERYOBJ_CMD_0 0
#define R200_QUERYOBJ_DATA_0 1
#define R200_QUERYOBJ_CMDSIZE 2
#define STP_CMD_0 0
#define STP_DATA_0 1
#define STP_CMD_1 2
#define STP_STATE_SIZE 35
struct r200_hw_state {
/* Hardware state, stored as cmdbuf commands:
* -- Need to doublebuffer for
* - reviving state after loss of context
* - eliding noop statechange loops? (except line stipple count)
*/
struct radeon_state_atom ctx;
struct radeon_state_atom set;
struct radeon_state_atom sci;
struct radeon_state_atom vte;
struct radeon_state_atom lin;
struct radeon_state_atom msk;
struct radeon_state_atom vpt;
struct radeon_state_atom vap;
struct radeon_state_atom vtx;
struct radeon_state_atom tcl;
struct radeon_state_atom msl;
struct radeon_state_atom tcg;
struct radeon_state_atom msc;
struct radeon_state_atom cst;
struct radeon_state_atom tam;
struct radeon_state_atom tf;
struct radeon_state_atom tex[6];
struct radeon_state_atom cube[6];
struct radeon_state_atom zbs;
struct radeon_state_atom mtl[2];
struct radeon_state_atom mat[9];
struct radeon_state_atom lit[8]; /* includes vec, scl commands */
struct radeon_state_atom ucp[6];
struct radeon_state_atom pix[6]; /* pixshader stages */
struct radeon_state_atom eye; /* eye pos */
struct radeon_state_atom grd; /* guard band clipping */
struct radeon_state_atom fog;
struct radeon_state_atom glt;
struct radeon_state_atom prf;
struct radeon_state_atom afs[2];
struct radeon_state_atom pvs;
struct radeon_state_atom vpi[2];
struct radeon_state_atom vpp[2];
struct radeon_state_atom atf;
struct radeon_state_atom spr;
struct radeon_state_atom ptp;
struct radeon_state_atom stp;
};
struct r200_state {
/* Derived state for internal purposes:
*/
struct r200_texture_state texture;
GLuint envneeded;
};
#define R200_CMD_BUF_SZ (16*1024)
#define R200_ELT_BUF_SZ (16*1024)
/* r200_tcl.c
*/
struct r200_tcl_info {
GLuint hw_primitive;
int elt_used;
};
/* r200_swtcl.c
*/
struct r200_swtcl_info {
radeon_point_func draw_point;
radeon_line_func draw_line;
radeon_tri_func draw_tri;
/**
* Offset of the 4UB color data within a hardware (swtcl) vertex.
*/
GLuint coloroffset;
/**
* Offset of the 3UB specular color data within a hardware (swtcl) vertex.
*/
GLuint specoffset;
/**
* Should Mesa project vertex data or will the hardware do it?
*/
GLboolean needproj;
};
/* A maximum total of 29 elements per vertex: 3 floats for position, 3
* floats for normal, 4 floats for color, 4 bytes for secondary color,
* 3 floats for each texture unit (18 floats total).
*
* we maybe need add. 4 to prevent segfault if someone specifies
* GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: )
*
* The position data is never actually stored here, so 3 elements could be
* trimmed out of the buffer.
*/
#define R200_MAX_VERTEX_SIZE ((3*6)+11)
struct r200_context {
struct radeon_context radeon;
/* Driver and hardware state management
*/
struct r200_hw_state hw;
struct r200_state state;
struct r200_vertex_program *curr_vp_hw;
/* Vertex buffers
*/
struct radeon_ioctl ioctl;
struct radeon_store store;
/* Clientdata textures;
*/
GLuint prefer_gart_client_texturing;
/* TCL stuff
*/
GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS];
GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS];
GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS];
GLuint TexMatEnabled;
GLuint TexMatCompSel;
GLuint TexGenEnabled;
GLuint TexGenCompSel;
GLmatrix tmpmat;
/* r200_tcl.c
*/
struct r200_tcl_info tcl;
/* r200_swtcl.c
*/
struct r200_swtcl_info swtcl;
GLboolean using_hyperz;
struct ati_fragment_shader *afs_loaded;
};
static inline r200ContextPtr
R200_CONTEXT(struct gl_context *ctx)
{
return (r200ContextPtr) ctx;
}
extern void r200DestroyContext( __DRIcontext *driContextPriv );
extern GLboolean r200CreateContext( gl_api api,
const struct gl_config *glVisual,
__DRIcontext *driContextPriv,
const struct __DriverContextConfig *
ctx_config,
unsigned *error,
void *sharedContextPrivate);
extern GLboolean r200MakeCurrent( __DRIcontext *driContextPriv,
__DRIdrawable *driDrawPriv,
__DRIdrawable *driReadPriv );
extern GLboolean r200UnbindContext( __DRIcontext *driContextPriv );
extern void r200_init_texcopy_functions(struct dd_function_table *table);
/* ================================================================
* Debugging:
*/
#define R200_DEBUG RADEON_DEBUG
#endif /* __R200_CONTEXT_H__ */

View File

@ -1,550 +0,0 @@
/**************************************************************************
*
* Copyright 2004 David Airlie
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL DAVID AIRLIE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "main/glheader.h"
#include "main/atifragshader.h"
#include "main/macros.h"
#include "main/enums.h"
#include "tnl/t_context.h"
#include "program/program.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_tex.h"
#define SET_INST(inst, type) afs_cmd[((inst<<2) + (type<<1) + 1)]
#define SET_INST_2(inst, type) afs_cmd[((inst<<2) + (type<<1) + 2)]
static void r200SetFragShaderArg( GLuint *afs_cmd, GLuint opnum, GLuint optype,
const struct atifragshader_src_register srcReg,
GLuint argPos, GLuint *tfactor )
{
const GLuint index = srcReg.Index;
const GLuint srcmod = srcReg.argMod;
const GLuint srcrep = srcReg.argRep;
GLuint reg0 = 0;
GLuint reg2 = 0;
GLuint useOddSrc = 0;
switch(srcrep) {
case GL_RED:
reg2 |= R200_TXC_REPL_RED << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
if (optype)
useOddSrc = 1;
break;
case GL_GREEN:
reg2 |= R200_TXC_REPL_GREEN << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
if (optype)
useOddSrc = 1;
break;
case GL_BLUE:
if (!optype)
reg2 |= R200_TXC_REPL_BLUE << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
else
useOddSrc = 1;
break;
case GL_ALPHA:
if (!optype)
useOddSrc = 1;
break;
}
if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)
reg0 |= (((index - GL_REG_0_ATI)*2) + 10 + useOddSrc) << (5*argPos);
else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
if ((*tfactor == 0) || (index == *tfactor)) {
reg0 |= (R200_TXC_ARG_A_TFACTOR_COLOR + useOddSrc) << (5*argPos);
reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR_SEL_SHIFT;
*tfactor = index;
}
else {
reg0 |= (R200_TXC_ARG_A_TFACTOR1_COLOR + useOddSrc) << (5*argPos);
reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR1_SEL_SHIFT;
}
}
else if (index == GL_PRIMARY_COLOR_EXT) {
reg0 |= (R200_TXC_ARG_A_DIFFUSE_COLOR + useOddSrc) << (5*argPos);
}
else if (index == GL_SECONDARY_INTERPOLATOR_ATI) {
reg0 |= (R200_TXC_ARG_A_SPECULAR_COLOR + useOddSrc) << (5*argPos);
}
/* GL_ZERO is a noop, for GL_ONE we set the complement */
else if (index == GL_ONE) {
reg0 |= R200_TXC_COMP_ARG_A << (4*argPos);
}
if (srcmod & GL_COMP_BIT_ATI)
reg0 ^= R200_TXC_COMP_ARG_A << (4*argPos);
if (srcmod & GL_BIAS_BIT_ATI)
reg0 |= R200_TXC_BIAS_ARG_A << (4*argPos);
if (srcmod & GL_2X_BIT_ATI)
reg0 |= R200_TXC_SCALE_ARG_A << (4*argPos);
if (srcmod & GL_NEGATE_BIT_ATI)
reg0 ^= R200_TXC_NEG_ARG_A << (4*argPos);
SET_INST(opnum, optype) |= reg0;
SET_INST_2(opnum, optype) |= reg2;
}
static GLuint dstmask_table[9] =
{
/* first slot never used, GL_NONE translated to RGB by mesa and you can't get a 0 dstmask. */
R200_TXC_OUTPUT_MASK_RGB,
R200_TXC_OUTPUT_MASK_R,
R200_TXC_OUTPUT_MASK_G,
R200_TXC_OUTPUT_MASK_RG,
R200_TXC_OUTPUT_MASK_B,
R200_TXC_OUTPUT_MASK_RB,
R200_TXC_OUTPUT_MASK_GB,
R200_TXC_OUTPUT_MASK_RGB,
R200_TXC_OUTPUT_MASK_RGB, /* alpha ops */
};
static void r200UpdateFSArith( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint *afs_cmd;
const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
GLuint pass;
R200_STATECHANGE( rmesa, afs[0] );
R200_STATECHANGE( rmesa, afs[1] );
if (shader->NumPasses < 2) {
afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
}
else {
afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd;
}
for (pass = 0; pass < shader->NumPasses; pass++) {
GLuint opnum = 0;
GLuint pc;
for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
GLuint optype;
struct atifs_instruction *inst = &shader->Instructions[pass][pc];
SET_INST(opnum, 0) = 0;
SET_INST_2(opnum, 0) = 0;
SET_INST(opnum, 1) = 0;
SET_INST_2(opnum, 1) = 0;
for (optype = 0; optype < 2; optype++) {
GLuint tfactor = 0;
if (inst->Opcode[optype]) {
switch (inst->Opcode[optype]) {
/* these are all MADD in disguise
MADD is A * B + C
so for GL_ADD use arg B/C and make A complement 0
for GL_SUB use arg B/C, negate C and make A complement 0
for GL_MOV use arg C
for GL_MUL use arg A
for GL_MAD all good */
case GL_SUB_ATI:
/* negate C */
SET_INST(opnum, optype) |= R200_TXC_NEG_ARG_C;
FALLTHROUGH;
case GL_ADD_ATI:
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][0], 1, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][1], 2, &tfactor);
/* A = complement 0 */
SET_INST(opnum, optype) |= R200_TXC_COMP_ARG_A;
SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
break;
case GL_MOV_ATI:
/* put arg0 in C */
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][0], 2, &tfactor);
SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
break;
case GL_MAD_ATI:
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][2], 2, &tfactor);
FALLTHROUGH;
case GL_MUL_ATI:
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][1], 1, &tfactor);
SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
break;
case GL_LERP_ATI:
/* arg order is not native chip order, swap A and C */
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][0], 2, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][1], 1, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][2], 0, &tfactor);
SET_INST(opnum, optype) |= R200_TXC_OP_LERP;
break;
case GL_CND_ATI:
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][1], 1, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][2], 2, &tfactor);
SET_INST(opnum, optype) |= R200_TXC_OP_CONDITIONAL;
break;
case GL_CND0_ATI:
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][1], 1, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, optype,
inst->SrcReg[optype][2], 2, &tfactor);
SET_INST(opnum, optype) |= R200_TXC_OP_CND0;
break;
/* cannot specify dot ops as alpha ops directly */
case GL_DOT2_ADD_ATI:
if (optype)
SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
else {
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][1], 1, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][2], 2, &tfactor);
SET_INST(opnum, 0) |= R200_TXC_OP_DOT2_ADD;
}
break;
case GL_DOT3_ATI:
if (optype)
SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
else {
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][1], 1, &tfactor);
SET_INST(opnum, 0) |= R200_TXC_OP_DOT3;
}
break;
case GL_DOT4_ATI:
/* experimental verification: for dot4 setup of alpha args is needed
(dstmod is ignored, though, so dot2/dot3 should be safe)
the hardware apparently does R1*R2 + G1*G2 + B1*B2 + A3*A4
but the API doesn't allow it */
if (optype)
SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
else {
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, 0,
inst->SrcReg[0][1], 1, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, 1,
inst->SrcReg[0][0], 0, &tfactor);
r200SetFragShaderArg(afs_cmd, opnum, 1,
inst->SrcReg[0][1], 1, &tfactor);
SET_INST(opnum, optype) |= R200_TXC_OP_DOT4;
}
break;
}
}
/* destination */
if (inst->DstReg[optype].Index) {
GLuint dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI;
GLuint dstmask = inst->DstReg[optype].dstMask;
GLuint sat = inst->DstReg[optype].dstMod & GL_SATURATE_BIT_ATI;
GLuint dstmod = inst->DstReg[optype].dstMod;
dstmod &= ~GL_SATURATE_BIT_ATI;
SET_INST_2(opnum, optype) |= (dstreg + 1) << R200_TXC_OUTPUT_REG_SHIFT;
SET_INST_2(opnum, optype) |= dstmask_table[dstmask];
/* fglrx does clamp the last instructions to 0_1 it seems */
/* this won't necessarily catch the last instruction
which writes to reg0 */
if (sat || (pc == (shader->numArithInstr[pass] - 1) &&
((pass == 1) || (shader->NumPasses == 1))))
SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_0_1;
else
/*should we clamp or not? spec is vague, I would suppose yes but fglrx doesn't */
SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_8_8;
/* SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_WRAP;*/
switch(dstmod) {
case GL_2X_BIT_ATI:
SET_INST_2(opnum, optype) |= R200_TXC_SCALE_2X;
break;
case GL_4X_BIT_ATI:
SET_INST_2(opnum, optype) |= R200_TXC_SCALE_4X;
break;
case GL_8X_BIT_ATI:
SET_INST_2(opnum, optype) |= R200_TXC_SCALE_8X;
break;
case GL_HALF_BIT_ATI:
SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV2;
break;
case GL_QUARTER_BIT_ATI:
SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV4;
break;
case GL_EIGHTH_BIT_ATI:
SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV8;
break;
default:
break;
}
}
}
/* fprintf(stderr, "pass %d nr %d inst 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
pass, opnum, SET_INST(opnum, 0), SET_INST_2(opnum, 0),
SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/
opnum++;
}
afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
}
rmesa->afs_loaded = ctx->ATIFragmentShader.Current;
}
static void r200UpdateFSRouting( struct gl_context *ctx ) {
r200ContextPtr rmesa = R200_CONTEXT(ctx);
const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
GLuint reg;
R200_STATECHANGE( rmesa, ctx );
R200_STATECHANGE( rmesa, cst );
for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
if (shader->swizzlerq & (1 << (2 * reg)))
/* r coord */
set_re_cntl_d3d( ctx, reg, 1);
/* q coord */
else set_re_cntl_d3d( ctx, reg, 0);
}
rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_MULTI_PASS_ENABLE |
R200_TEX_BLEND_ENABLE_MASK |
R200_TEX_ENABLE_MASK);
rmesa->hw.cst.cmd[CST_PP_CNTL_X] &= ~(R200_PPX_PFS_INST_ENABLE_MASK |
R200_PPX_TEX_ENABLE_MASK |
R200_PPX_OUTPUT_REG_MASK);
/* first pass registers use slots 8 - 15
but single pass shaders use slots 0 - 7 */
if (shader->NumPasses < 2) {
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[0] == 8 ?
0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
(0xff >> (8 - shader->numArithInstr[0])) << R200_TEX_BLEND_0_ENABLE_SHIFT;
} else {
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_MULTI_PASS_ENABLE;
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[1] == 8 ?
0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
(0xff >> (8 - shader->numArithInstr[1])) << R200_TEX_BLEND_0_ENABLE_SHIFT;
rmesa->hw.cst.cmd[CST_PP_CNTL_X] |=
(0xff >> (8 - shader->numArithInstr[0])) << R200_PPX_FPS_INST0_ENABLE_SHIFT;
}
if (shader->NumPasses < 2) {
for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
R200_STATECHANGE( rmesa, tex[reg] );
rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0;
if (shader->SetupInst[0][reg].Opcode) {
GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
& ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;
txformat |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
<< R200_TXFORMAT_ST_ROUTE_SHIFT;
/* fix up texcoords for proj/non-proj 2d (3d and cube are not defined when
using projection so don't have to worry there).
When passing coords, need R200_TEXCOORD_VOLUME, otherwise loose a coord */
/* FIXME: someone might rely on default tex coords r/q, which we unfortunately
don't provide (we have the same problem without shaders) */
if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_x |= R200_TEXCOORD_VOLUME;
}
else {
txformat_x |= R200_TEXCOORD_PROJ;
}
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
else if (texObj && texObj->Target == GL_TEXTURE_3D) {
txformat_x |= R200_TEXCOORD_VOLUME;
}
else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
txformat_x |= R200_TEXCOORD_CUBIC_ENV;
}
else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_x |= R200_TEXCOORD_NONPROJ;
}
else {
txformat_x |= R200_TEXCOORD_PROJ;
}
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
/* enabling texturing when unit isn't correctly configured may not be safe */
if (texObj)
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
}
} else {
/* setup 1st pass */
for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
R200_STATECHANGE( rmesa, tex[reg] );
GLuint txformat_multi = 0;
if (shader->SetupInst[0][reg].Opcode) {
txformat_multi |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
<< R200_PASS1_ST_ROUTE_SHIFT;
if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
txformat_multi |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
}
else {
txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
}
rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
}
else if (texObj && texObj->Target == GL_TEXTURE_3D) {
txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
}
else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV;
}
else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_multi |= R200_PASS1_TEXCOORD_NONPROJ;
}
else {
txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
}
if (texObj)
rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
}
rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
}
/* setup 2nd pass */
for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
if (shader->SetupInst[1][reg].Opcode) {
GLuint coord = shader->SetupInst[1][reg].src;
GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
& ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;
R200_STATECHANGE( rmesa, tex[reg] );
if (shader->SetupInst[1][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
txformat_x |= R200_TEXCOORD_VOLUME;
if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_x |= R200_TEXCOORD_VOLUME;
}
else {
txformat_x |= R200_TEXCOORD_PROJ;
}
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
else if (texObj && texObj->Target == GL_TEXTURE_3D) {
txformat_x |= R200_TEXCOORD_VOLUME;
}
else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
txformat_x |= R200_TEXCOORD_CUBIC_ENV;
}
else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_x |= R200_TEXCOORD_NONPROJ;
}
else {
txformat_x |= R200_TEXCOORD_PROJ;
}
if (coord >= GL_REG_0_ATI) {
GLuint txformat_multi = rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL];
txformat_multi |= (coord - GL_REG_0_ATI + 2) << R200_PASS2_COORDS_REG_SHIFT;
rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 1 <<
(R200_PPX_OUTPUT_REG_0_SHIFT + coord - GL_REG_0_ATI);
} else {
txformat |= (coord - GL_TEXTURE0_ARB) << R200_TXFORMAT_ST_ROUTE_SHIFT;
}
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
if (texObj)
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
}
}
}
static void r200UpdateFSConstants( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
GLuint i;
/* update constants */
R200_STATECHANGE(rmesa, atf);
for (i = 0; i < 8; i++)
{
GLubyte con_byte[4];
if ((shader->LocalConstDef >> i) & 1) {
CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->Constants[i][0]);
CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->Constants[i][1]);
CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->Constants[i][2]);
CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->Constants[i][3]);
}
else {
CLAMPED_FLOAT_TO_UBYTE(con_byte[0], ctx->ATIFragmentShader.GlobalConstants[i][0]);
CLAMPED_FLOAT_TO_UBYTE(con_byte[1], ctx->ATIFragmentShader.GlobalConstants[i][1]);
CLAMPED_FLOAT_TO_UBYTE(con_byte[2], ctx->ATIFragmentShader.GlobalConstants[i][2]);
CLAMPED_FLOAT_TO_UBYTE(con_byte[3], ctx->ATIFragmentShader.GlobalConstants[i][3]);
}
rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = radeonPackColor (
4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] );
}
}
/* update routing, constants and arithmetic
* constants need to be updated always (globals can change, no separate notification)
* routing needs to be updated always too (non-shader code will overwrite state, plus
* some of the routing depends on what sort of texture is bound)
* for both of them, we need to update anyway because of disabling/enabling ati_fs which
* we'd need to track otherwise
* arithmetic is only updated if current shader changes (and probably the data should be
* stored in some DriverData object attached to the mesa atifs object, i.e. binding a
* shader wouldn't force us to "recompile" the shader).
*/
void r200UpdateFragmentShader( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
r200UpdateFSConstants( ctx );
r200UpdateFSRouting( ctx );
if (rmesa->afs_loaded != ctx->ATIFragmentShader.Current)
r200UpdateFSArith( ctx );
}

View File

@ -1,88 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include <sched.h>
#include <errno.h>
#include "main/glheader.h"
#include "main/macros.h"
#include "main/context.h"
#include "swrast/swrast.h"
#include "radeon_common.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "radeon_reg.h"
#define R200_TIMEOUT 512
#define R200_IDLE_RETRY 16
/* ================================================================
* Buffer clear
*/
static void r200Clear( struct gl_context *ctx, GLbitfield mask )
{
GLuint hwmask, swmask;
GLuint hwbits = BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL |
BUFFER_BIT_COLOR0;
radeonFlush( ctx, 0 );
hwmask = mask & hwbits;
swmask = mask & ~hwbits;
if ( swmask ) {
if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n", __func__, swmask);
_swrast_Clear( ctx, swmask );
}
if ( !hwmask )
return;
radeonUserClear(ctx, hwmask);
}
void r200InitIoctlFuncs( struct dd_function_table *functions )
{
functions->Clear = r200Clear;
functions->Finish = radeonFinish;
functions->Flush = radeonFlush;
}

View File

@ -1,155 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_IOCTL_H__
#define __R200_IOCTL_H__
#include "radeon_bo_gem.h"
#include "radeon_cs_gem.h"
#include "xf86drm.h"
#include "drm-uapi/drm.h"
#include "radeon_drm.h"
extern void r200EmitMaxVtxIndex(r200ContextPtr rmesa, int count);
extern void r200EmitVertexAOS( r200ContextPtr rmesa,
GLuint vertex_size,
struct radeon_bo *bo,
GLuint offset );
extern void r200EmitVbufPrim( r200ContextPtr rmesa,
GLuint primitive,
GLuint vertex_nr );
extern void r200FlushElts(struct gl_context *ctx);
extern GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
GLuint primitive,
GLuint min_nr );
extern void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset);
extern void r200InitIoctlFuncs( struct dd_function_table *functions );
void r200SetUpAtomList( r200ContextPtr rmesa );
/* ================================================================
* Helper macros:
*/
/* Close off the last primitive, if it exists.
*/
#define R200_NEWPRIM( rmesa ) \
do { \
if ( rmesa->radeon.dma.flush ) \
rmesa->radeon.dma.flush( &rmesa->radeon.glCtx ); \
} while (0)
/* Can accommodate several state changes and primitive changes without
* actually firing the buffer.
*/
#define R200_STATECHANGE( rmesa, ATOM ) \
do { \
R200_NEWPRIM( rmesa ); \
rmesa->hw.ATOM.dirty = GL_TRUE; \
rmesa->radeon.hw.is_dirty = GL_TRUE; \
} while (0)
#define R200_SET_STATE( rmesa, ATOM, index, newvalue ) \
do { \
uint32_t __index = (index); \
uint32_t __dword = (newvalue); \
if (__dword != (rmesa)->hw.ATOM.cmd[__index]) { \
R200_STATECHANGE( (rmesa), ATOM ); \
(rmesa)->hw.ATOM.cmd[__index] = __dword; \
} \
} while(0)
#define R200_DB_STATE( ATOM ) \
memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
rmesa->hw.ATOM.cmd_size * 4)
static inline int R200_DB_STATECHANGE(
r200ContextPtr rmesa,
struct radeon_state_atom *atom )
{
if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) {
GLuint *tmp;
R200_NEWPRIM( rmesa );
atom->dirty = GL_TRUE;
rmesa->radeon.hw.is_dirty = GL_TRUE;
tmp = atom->cmd;
atom->cmd = atom->lastcmd;
atom->lastcmd = tmp;
return 1;
}
else
return 0;
}
/* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ
* are available, you will also be adding an rmesa->state.max_state_size because
* r200EmitState is called from within r200EmitVbufPrim and r200FlushElts.
*/
#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2) + nr*2))
#define VERT_AOS_BUFSZ (5)
#define ELTS_BUFSZ(nr) (12 + nr * 2)
#define VBUF_BUFSZ (3)
#define SCISSOR_BUFSZ (8)
#define INDEX_BUFSZ (8+2)
static inline uint32_t cmdpacket3(int cmd_type)
{
drm_radeon_cmd_header_t cmd;
cmd.i = 0;
cmd.header.cmd_type = cmd_type;
return (uint32_t)cmd.i;
}
#define OUT_BATCH_PACKET3(packet, num_extra) do { \
OUT_BATCH(CP_PACKET2); \
OUT_BATCH(CP_PACKET3((packet), (num_extra))); \
} while(0)
#define OUT_BATCH_PACKET3_CLIP(packet, num_extra) do { \
OUT_BATCH(CP_PACKET2); \
OUT_BATCH(CP_PACKET3((packet), (num_extra))); \
} while(0)
#endif /* __R200_IOCTL_H__ */

View File

@ -1,15 +0,0 @@
/* Currently, can only use arrays, verts are not implemented, though
* verts are suspected to be faster.
* To get an idea how the verts path works, look at the radeon implementation.
*/
#include <string.h>
#include "r200_context.h"
#define R200_MAOS_VERTS 0
#if (R200_MAOS_VERTS)
#include "r200_maos_verts.c"
#else
#include "r200_maos_arrays.c"
#endif

View File

@ -1,42 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_MAOS_H__
#define __R200_MAOS_H__
#include "r200_context.h"
extern void r200EmitArrays( struct gl_context *ctx, GLubyte *vimap_rev );
#endif

View File

@ -1,196 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/macros.h"
#include "main/state.h"
#include "swrast_setup/swrast_setup.h"
#include "math/m_translate.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_state.h"
#include "r200_swtcl.h"
#include "r200_maos.h"
#include "r200_tcl.h"
#if defined(USE_X86_ASM)
#define COPY_DWORDS( dst, src, nr ) \
do { \
int __tmp; \
__asm__ __volatile__( "rep ; movsl" \
: "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
: "0" (nr), \
"D" ((long)dst), \
"S" ((long)src) ); \
} while (0)
#else
#define COPY_DWORDS( dst, src, nr ) \
do { \
int j; \
for ( j = 0 ; j < nr ; j++ ) \
dst[j] = ((int *)src)[j]; \
dst += nr; \
} while (0)
#endif
/* Emit any changed arrays to new GART memory, re-emit a packet to
* update the arrays.
*/
void r200EmitArrays( struct gl_context *ctx, GLubyte *vimap_rev )
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
GLuint nr = 0;
GLuint vfmt0 = 0, vfmt1 = 0;
GLuint count = VB->Count;
GLuint i, emitsize;
// fprintf(stderr,"emit arrays\n");
for ( i = 0; i < 15; i++ ) {
GLubyte attrib = vimap_rev[i];
if (attrib != 255) {
switch (i) {
case 0:
emitsize = (VB->AttribPtr[attrib]->size);
switch (emitsize) {
case 4:
vfmt0 |= R200_VTX_W0;
FALLTHROUGH;
case 3:
vfmt0 |= R200_VTX_Z0;
break;
case 2:
break;
default: assert(0);
}
break;
case 1:
unreachable("r200: vertex weight attrib unsupported");
break;
case 2:
assert(attrib == VERT_ATTRIB_NORMAL);
emitsize = 3;
vfmt0 |= R200_VTX_N0;
break;
case 3:
/* special handling to fix up fog. Will get us into trouble with vbos...*/
assert(attrib == VERT_ATTRIB_FOG);
if (!rmesa->radeon.tcl.aos[i].bo) {
if (_mesa_arb_vertex_program_enabled(ctx))
rcommon_emit_vector( ctx,
&(rmesa->radeon.tcl.aos[nr]),
(char *)VB->AttribPtr[attrib]->data,
1,
VB->AttribPtr[attrib]->stride,
count);
else
rcommon_emit_vecfog( ctx,
&(rmesa->radeon.tcl.aos[nr]),
(char *)VB->AttribPtr[attrib]->data,
VB->AttribPtr[attrib]->stride,
count);
}
vfmt0 |= R200_VTX_DISCRETE_FOG;
goto after_emit;
break;
case 4:
case 5:
case 6:
case 7:
if (VB->AttribPtr[attrib]->size == 4 &&
(VB->AttribPtr[attrib]->stride != 0 ||
VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
else emitsize = 3;
if (emitsize == 4)
vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
else {
vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
}
break;
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
emitsize = VB->AttribPtr[attrib]->size;
vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
break;
case 14:
emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
switch (emitsize) {
case 2:
vfmt0 |= R200_VTX_XY1;
FALLTHROUGH;
case 3:
vfmt0 |= R200_VTX_Z1;
FALLTHROUGH;
case 4:
vfmt0 |= R200_VTX_W1;
}
break;
default:
assert(0);
emitsize = 0;
}
if (!rmesa->radeon.tcl.aos[nr].bo) {
rcommon_emit_vector( ctx,
&(rmesa->radeon.tcl.aos[nr]),
(char *)VB->AttribPtr[attrib]->data,
emitsize,
VB->AttribPtr[attrib]->stride,
count );
}
after_emit:
assert(nr < 12);
nr++;
}
}
if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
R200_STATECHANGE( rmesa, vtx );
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
}
rmesa->radeon.tcl.aos_count = nr;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
#ifndef R200_SANITY_H
#define R200_SANITY_H
extern int r200SanityCmdBuffer( r200ContextPtr rmesa,
int nbox,
drm_clip_rect_t *boxes );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_STATE_H__
#define __R200_STATE_H__
#include "r200_context.h"
extern void r200InitState( r200ContextPtr rmesa );
extern void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions );
extern void r200InitTnlFuncs( struct gl_context *ctx );
extern void r200UpdateMaterial( struct gl_context *ctx );
extern void r200UpdateWindow( struct gl_context *ctx );
extern void r200UpdateDrawBuffer(struct gl_context *ctx);
extern GLboolean r200ValidateBuffers(struct gl_context *ctx);
extern GLboolean r200ValidateState( struct gl_context *ctx );
extern void r200_vtbl_update_scissor( struct gl_context *ctx );
extern void r200Fallback( struct gl_context *ctx, GLuint bit, GLboolean mode );
#define FALLBACK( rmesa, bit, mode ) do { \
if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \
__func__, bit, mode ); \
r200Fallback( &rmesa->radeon.glCtx, bit, mode ); \
} while (0)
extern void r200LightingSpaceChange( struct gl_context *ctx );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,955 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/enums.h"
#include "main/image.h"
#include "main/macros.h"
#include "main/state.h"
#include "swrast/s_context.h"
#include "swrast/s_fog.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_state.h"
#include "r200_swtcl.h"
#include "r200_tcl.h"
/***********************************************************************
* Initialization
***********************************************************************/
#define EMIT_ATTR( ATTR, STYLE, F0 ) \
do { \
rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
rmesa->radeon.swtcl.vertex_attr_count++; \
fmt_0 |= F0; \
} while (0)
#define EMIT_PAD( N ) \
do { \
rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \
rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \
rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \
rmesa->radeon.swtcl.vertex_attr_count++; \
} while (0)
static void r200SetVertexFormat( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLbitfield64 index_bitset = tnl->render_inputs_bitset;
int fmt_0 = 0;
int fmt_1 = 0;
int offset = 0;
/* Important:
*/
if ( VB->NdcPtr != NULL ) {
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
}
else {
VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
}
assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
rmesa->radeon.swtcl.vertex_attr_count = 0;
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
* build up a hardware vertex.
*/
if ( !rmesa->swtcl.needproj ||
(index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) ) {
/* need w coord for projected textures */
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F, R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0 );
offset = 4;
}
else {
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F, R200_VTX_XY | R200_VTX_Z0 );
offset = 3;
}
if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE)) {
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, R200_VTX_POINT_SIZE );
offset += 1;
}
rmesa->swtcl.coloroffset = offset;
#if MESA_LITTLE_ENDIAN
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) );
#else
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR, (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) );
#endif
offset += 1;
rmesa->swtcl.specoffset = 0;
if (index_bitset &
(BITFIELD64_BIT(_TNL_ATTRIB_COLOR1) | BITFIELD64_BIT(_TNL_ATTRIB_FOG))) {
#if MESA_LITTLE_ENDIAN
if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
rmesa->swtcl.specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
else {
EMIT_PAD( 3 );
}
if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
else {
EMIT_PAD( 1 );
}
#else
if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
else {
EMIT_PAD( 1 );
}
if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
rmesa->swtcl.specoffset = offset;
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
}
else {
EMIT_PAD( 3 );
}
#endif
}
if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
int i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) {
GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
fmt_1 |= sz << (3 * i);
EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1, 0 );
}
}
}
if ( (rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
!= R200_FOG_USE_SPEC_ALPHA ) {
R200_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_SPEC_ALPHA;
}
if (rmesa->radeon.tnl_index_bitset != index_bitset ||
(rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) ||
(rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
R200_NEWPRIM(rmesa);
R200_STATECHANGE( rmesa, vtx );
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0;
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = fmt_1;
rmesa->radeon.swtcl.vertex_size =
_tnl_install_attrs( ctx,
rmesa->radeon.swtcl.vertex_attrs,
rmesa->radeon.swtcl.vertex_attr_count,
NULL, 0 );
rmesa->radeon.swtcl.vertex_size /= 4;
rmesa->radeon.tnl_index_bitset = index_bitset;
}
}
static void r200_predict_emit_size( r200ContextPtr rmesa )
{
if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s\n", __func__);
const int vertex_array_size = 7;
const int prim_size = 3;
if (!rmesa->radeon.swtcl.emit_prediction) {
const int state_size = radeonCountStateEmitSize(&rmesa->radeon);
if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
state_size +
vertex_array_size + prim_size,
__func__))
rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
else
rmesa->radeon.swtcl.emit_prediction = state_size;
rmesa->radeon.swtcl.emit_prediction += vertex_array_size + prim_size
+ rmesa->radeon.cmdbuf.cs->cdw;
}
}
static void r200RenderStart( struct gl_context *ctx )
{
r200SetVertexFormat( ctx );
if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s\n", __func__);
}
/**
* Set vertex state for SW TCL. The primary purpose of this function is to
* determine in advance whether or not the hardware can / should do the
* projection divide or Mesa should do it.
*/
void r200ChooseVertexState( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint vte;
GLuint vap;
GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
ctx->Polygon.BackMode != GL_FILL);
GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
/* We must ensure that we don't do _tnl_need_projected_coords while in a
* rasterization fallback. As this function will be called again when we
* leave a rasterization fallback, we can just skip it for now.
*/
if (rmesa->radeon.Fallback != 0)
return;
vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
/* HW perspective divide is a win, but tiny vertex formats are a
* bigger one.
*/
if ((0 == (tnl->render_inputs_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)))
|| twosided
|| unfilled) {
rmesa->swtcl.needproj = GL_TRUE;
vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT;
vte &= ~R200_VTX_W0_FMT;
if (tnl->render_inputs_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
vap &= ~R200_VAP_FORCE_W_TO_ONE;
}
else {
vap |= R200_VAP_FORCE_W_TO_ONE;
}
}
else {
rmesa->swtcl.needproj = GL_FALSE;
vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
vte |= R200_VTX_W0_FMT;
vap &= ~R200_VAP_FORCE_W_TO_ONE;
}
_tnl_need_projected_coords( ctx, rmesa->swtcl.needproj );
if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
R200_STATECHANGE( rmesa, vte );
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
}
if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
R200_STATECHANGE( rmesa, vap );
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
}
}
void r200_swtcl_flush(struct gl_context *ctx, uint32_t current_offset)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s\n", __func__);
radeonEmitState(&rmesa->radeon);
r200EmitVertexAOS( rmesa,
rmesa->radeon.swtcl.vertex_size,
rmesa->radeon.swtcl.bo,
current_offset);
r200EmitVbufPrim( rmesa,
rmesa->radeon.swtcl.hw_primitive,
rmesa->radeon.swtcl.numverts);
if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
WARN_ONCE("Rendering was %d commands larger than predicted size."
" We might overflow command buffer.\n",
rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
rmesa->radeon.swtcl.emit_prediction = 0;
}
/**************************************************************************/
static inline GLuint reduced_hw_prim( struct gl_context *ctx, GLuint prim)
{
switch (prim) {
case GL_POINTS:
return ((!ctx->Point.SmoothFlag) ?
R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS);
case GL_LINES:
FALLTHROUGH;
case GL_LINE_LOOP:
FALLTHROUGH;
case GL_LINE_STRIP:
return R200_VF_PRIM_LINES;
default:
/* all others reduced to triangles */
return R200_VF_PRIM_TRIANGLES;
}
}
static void r200RasterPrimitive( struct gl_context *ctx, GLuint hwprim );
static void r200RenderPrimitive( struct gl_context *ctx, GLenum prim );
static void r200ResetLineStipple( struct gl_context *ctx );
/***********************************************************************
* Emit primitives as inline vertices *
***********************************************************************/
#define HAVE_POINTS 1
#define HAVE_LINES 1
#define HAVE_LINE_STRIPS 1
#define HAVE_TRIANGLES 1
#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_FANS 1
#define HAVE_QUADS 0
#define HAVE_QUAD_STRIPS 0
#define HAVE_POLYGONS 1
#define HAVE_ELTS 0
static void* r200_alloc_verts( r200ContextPtr rmesa, GLuint n, GLuint size)
{
void *rv;
do {
r200_predict_emit_size( rmesa );
rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
} while(!rv);
return rv;
}
#undef LOCAL_VARS
#undef ALLOC_VERTS
#define CTX_ARG r200ContextPtr rmesa
#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
#define ALLOC_VERTS( n, size ) r200_alloc_verts(rmesa, n, size)
#define LOCAL_VARS \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
const char *r200verts = (char *)rmesa->radeon.swtcl.verts;
#define VERT(x) (radeonVertex *)(r200verts + ((x) * vertsize * sizeof(int)))
#define VERTEX radeonVertex
#define DO_DEBUG_VERTS (1 && (R200_DEBUG & RADEON_VERTS))
#undef TAG
#define TAG(x) r200_##x
#include "tnl_dd/t_dd_triemit.h"
/***********************************************************************
* Macros for t_dd_tritmp.h to draw basic primitives *
***********************************************************************/
#define QUAD( a, b, c, d ) r200_quad( rmesa, a, b, c, d )
#define TRI( a, b, c ) r200_triangle( rmesa, a, b, c )
#define LINE( a, b ) r200_line( rmesa, a, b )
#define POINT( a ) r200_point( rmesa, a )
/***********************************************************************
* Build render functions from dd templates *
***********************************************************************/
#define R200_TWOSIDE_BIT 0x01
#define R200_UNFILLED_BIT 0x02
#define R200_MAX_TRIFUNC 0x04
static struct {
tnl_points_func points;
tnl_line_func line;
tnl_triangle_func triangle;
tnl_quad_func quad;
} rast_tab[R200_MAX_TRIFUNC];
#define DO_FALLBACK 0
#define DO_UNFILLED ((IND & R200_UNFILLED_BIT) != 0)
#define DO_TWOSIDE ((IND & R200_TWOSIDE_BIT) != 0)
#define DO_FLAT 0
#define DO_OFFSET 0
#define DO_TRI 1
#define DO_QUAD 1
#define DO_LINE 1
#define DO_POINTS 1
#define DO_FULL_QUAD 1
#define HAVE_SPEC 1
#define HAVE_BACK_COLORS 0
#define HAVE_HW_FLATSHADE 1
#define TAB rast_tab
#define DEPTH_SCALE 1.0
#define UNFILLED_TRI unfilled_tri
#define UNFILLED_QUAD unfilled_quad
#define VERT_X(_v) _v->v.x
#define VERT_Y(_v) _v->v.y
#define VERT_Z(_v) _v->v.z
#define AREA_IS_CCW( a ) (a < 0)
#define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
#define VERT_SET_RGBA( v, c ) \
do { \
radeon_color_t *color = (radeon_color_t *)&((v)->ui[coloroffset]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
} while (0)
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
#define VERT_SET_SPEC( v, c ) \
do { \
if (specoffset) { \
radeon_color_t *spec = (radeon_color_t *)&((v)->ui[specoffset]); \
UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \
UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \
UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \
} \
} while (0)
#define VERT_COPY_SPEC( v0, v1 ) \
do { \
if (specoffset) { \
radeon_color_t *spec0 = (radeon_color_t *)&((v0)->ui[specoffset]); \
radeon_color_t *spec1 = (radeon_color_t *)&((v1)->ui[specoffset]); \
spec0->red = spec1->red; \
spec0->green = spec1->green; \
spec0->blue = spec1->blue; \
} \
} while (0)
/* These don't need LE32_TO_CPU() as they used to save and restore
* colors which are already in the correct format.
*/
#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
#undef LOCAL_VARS
#undef TAG
#undef INIT
#define LOCAL_VARS(n) \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
GLuint color[n] = {0}, spec[n] = {0}; \
GLuint coloroffset = rmesa->swtcl.coloroffset; \
GLuint specoffset = rmesa->swtcl.specoffset; \
(void) color; (void) spec; (void) coloroffset; (void) specoffset;
/***********************************************************************
* Helpers for rendering unfilled primitives *
***********************************************************************/
#define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim(ctx, x) )
#define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
#undef TAG
#define TAG(x) x
#include "tnl_dd/t_dd_unfilled.h"
#undef IND
/***********************************************************************
* Generate GL render functions *
***********************************************************************/
#define IND (0)
#define TAG(x) x
#include "tnl_dd/t_dd_tritmp.h"
#define IND (R200_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "tnl_dd/t_dd_tritmp.h"
#define IND (R200_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (R200_TWOSIDE_BIT|R200_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "tnl_dd/t_dd_tritmp.h"
static void init_rast_tab( void )
{
init();
init_twoside();
init_unfilled();
init_twoside_unfilled();
}
/**********************************************************************/
/* Render unclipped begin/end objects */
/**********************************************************************/
#define RENDER_POINTS( start, count ) \
for ( ; start < count ; start++) \
r200_point( rmesa, VERT(start) )
#define RENDER_LINE( v0, v1 ) \
r200_line( rmesa, VERT(v0), VERT(v1) )
#define RENDER_TRI( v0, v1, v2 ) \
r200_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
#define RENDER_QUAD( v0, v1, v2, v3 ) \
r200_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
#define INIT(x) do { \
r200RenderPrimitive( ctx, x ); \
} while (0)
#undef LOCAL_VARS
#define LOCAL_VARS \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
const char *r200verts = (char *)rmesa->radeon.swtcl.verts; \
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
const GLboolean stipple = ctx->Line.StippleFlag; \
(void) elt; (void) stipple;
#define RESET_STIPPLE if ( stipple ) r200ResetLineStipple( ctx );
#define RESET_OCCLUSION
#define PRESERVE_VB_DEFS
#define ELT(x) (x)
#define TAG(x) r200_##x##_verts
#include "tnl/t_vb_rendertmp.h"
#undef ELT
#undef TAG
#define TAG(x) r200_##x##_elts
#define ELT(x) elt[x]
#include "tnl/t_vb_rendertmp.h"
/**********************************************************************/
/* Choose render functions */
/**********************************************************************/
void r200ChooseRenderState( struct gl_context *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint index = 0;
GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
ctx->Polygon.BackMode != GL_FILL);
GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
if (!rmesa->radeon.TclFallback || rmesa->radeon.Fallback)
return;
if (twosided)
index |= R200_TWOSIDE_BIT;
if (unfilled)
index |= R200_UNFILLED_BIT;
if (index != rmesa->radeon.swtcl.RenderIndex) {
tnl->Driver.Render.Points = rast_tab[index].points;
tnl->Driver.Render.Line = rast_tab[index].line;
tnl->Driver.Render.ClippedLine = rast_tab[index].line;
tnl->Driver.Render.Triangle = rast_tab[index].triangle;
tnl->Driver.Render.Quad = rast_tab[index].quad;
if (index == 0) {
tnl->Driver.Render.PrimTabVerts = r200_render_tab_verts;
tnl->Driver.Render.PrimTabElts = r200_render_tab_elts;
tnl->Driver.Render.ClippedPolygon = r200_fast_clipped_poly;
} else {
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
}
rmesa->radeon.swtcl.RenderIndex = index;
}
}
/**********************************************************************/
/* High level hooks for t_vb_render.c */
/**********************************************************************/
static void r200RasterPrimitive( struct gl_context *ctx, GLuint hwprim )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
radeon_prepare_render(&rmesa->radeon);
if (rmesa->radeon.NewGLState)
r200ValidateState( ctx );
if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
/* need to disable perspective-correct texturing for point sprites */
if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) {
if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
R200_STATECHANGE( rmesa, set );
rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
}
}
else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
R200_STATECHANGE( rmesa, set );
rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
}
R200_NEWPRIM( rmesa );
rmesa->radeon.swtcl.hw_primitive = hwprim;
}
}
static void r200RenderPrimitive( struct gl_context *ctx, GLenum prim )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
ctx->Polygon.BackMode != GL_FILL);
rmesa->radeon.swtcl.render_primitive = prim;
if (prim < GL_TRIANGLES || !unfilled)
r200RasterPrimitive( ctx, reduced_hw_prim(ctx, prim) );
}
static void r200RenderFinish( struct gl_context *ctx )
{
}
static void r200ResetLineStipple( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
R200_STATECHANGE( rmesa, lin );
}
/**********************************************************************/
/* Transition to/from hardware rasterization. */
/**********************************************************************/
static const char * const fallbackStrings[] = {
"Texture mode",
"glDrawBuffer(GL_FRONT_AND_BACK)",
"glEnable(GL_STENCIL) without hw stencil buffer",
"glRenderMode(selection or feedback)",
"R200_NO_RAST",
"Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"
};
static const char *getFallbackString(GLuint bit)
{
int i = 0;
while (bit > 1) {
i++;
bit >>= 1;
}
return fallbackStrings[i];
}
void r200Fallback( struct gl_context *ctx, GLuint bit, GLboolean mode )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = rmesa->radeon.Fallback;
if (mode) {
rmesa->radeon.Fallback |= bit;
if (oldfallback == 0) {
radeon_firevertices(&rmesa->radeon);
TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE );
_swsetup_Wakeup( ctx );
rmesa->radeon.swtcl.RenderIndex = ~0;
if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
}
}
else {
rmesa->radeon.Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
tnl->Driver.Render.Start = r200RenderStart;
tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
tnl->Driver.Render.Finish = r200RenderFinish;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_FALSE );
if (rmesa->radeon.TclFallback) {
/* These are already done if rmesa->radeon.TclFallback goes to
* zero above. But not if it doesn't (R200_NO_TCL for
* example?)
*/
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
rmesa->radeon.tnl_index_bitset = 0;
r200ChooseVertexState( ctx );
r200ChooseRenderState( ctx );
}
if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "R200 end rasterization fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
}
}
}
/**
* Cope with depth operations by drawing individual pixels as points.
*
* \todo
* The way the vertex state is set in this routine is hokey. It seems to
* work, but it's very hackish. This whole routine is pretty hackish. If
* the bitmap is small enough, it seems like it would be faster to copy it
* to AGP memory and use it as a non-power-of-two texture (i.e.,
* NV_texture_rectangle).
*/
void
r200PointsBitmap( struct gl_context *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
const GLfloat *rc = ctx->Current.RasterColor;
GLint row, col;
radeonVertex vert;
GLuint orig_vte;
GLuint h;
/* Turn off tcl.
*/
TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 1 );
/* Choose tiny vertex format
*/
{
const GLuint fmt_0 = R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0
| (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT);
const GLuint fmt_1 = 0;
GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
vte |= R200_VTX_W0_FMT;
vap &= ~R200_VAP_FORCE_W_TO_ONE;
rmesa->radeon.swtcl.vertex_size = 5;
if ( (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0)
|| (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
R200_NEWPRIM(rmesa);
R200_STATECHANGE( rmesa, vtx );
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0;
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = fmt_1;
}
if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
R200_STATECHANGE( rmesa, vte );
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
}
if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
R200_STATECHANGE( rmesa, vap );
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
}
}
/* Ready for point primitives:
*/
r200RenderPrimitive( ctx, GL_POINTS );
/* Turn off the hw viewport transformation:
*/
R200_STATECHANGE( rmesa, vte );
orig_vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VPORT_X_SCALE_ENA |
R200_VPORT_Y_SCALE_ENA |
R200_VPORT_Z_SCALE_ENA |
R200_VPORT_X_OFFSET_ENA |
R200_VPORT_Y_OFFSET_ENA |
R200_VPORT_Z_OFFSET_ENA);
/* Turn off other stuff: Stipple?, texture?, blending?, etc.
*/
/* Populate the vertex
*
* Incorporate FOG into RGBA
*/
if (ctx->Fog.Enabled) {
const GLfloat *fc = ctx->Fog.Color;
GLfloat color[4];
GLfloat f;
if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
f = _swrast_z_to_fogfactor(ctx, ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
else
f = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
color[0] = f * rc[0] + (1.F - f) * fc[0];
color[1] = f * rc[1] + (1.F - f) * fc[1];
color[2] = f * rc[2] + (1.F - f) * fc[2];
color[3] = rc[3];
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red, color[0]);
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, color[1]);
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue, color[2]);
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, color[3]);
}
else {
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red, rc[0]);
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, rc[1]);
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue, rc[2]);
UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, rc[3]);
}
vert.tv.z = ctx->Current.RasterPos[2];
/* Update window height
*/
h = radeon_get_drawable(&rmesa->radeon)->h;
/* Clipping handled by existing mechansims in r200_ioctl.c?
*/
for (row=0; row<height; row++) {
const GLubyte *src = (const GLubyte *)
_mesa_image_address2d(unpack, bitmap, width, height,
GL_COLOR_INDEX, GL_BITMAP, row, 0 );
if (unpack->LsbFirst) {
/* Lsb first */
GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
if (*src & mask) {
vert.tv.x = px+col;
vert.tv.y = h - (py+row) - 1;
r200_point( rmesa, &vert );
}
src += (mask >> 7);
mask = ((mask << 1) & 0xff) | (mask >> 7);
}
/* get ready for next row */
if (mask != 1)
src++;
}
else {
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
if (*src & mask) {
vert.tv.x = px+col;
vert.tv.y = h - (py+row) - 1;
r200_point( rmesa, &vert );
}
src += mask & 1;
mask = ((mask << 7) & 0xff) | (mask >> 1);
}
/* get ready for next row */
if (mask != 128)
src++;
}
}
/* Fire outstanding vertices, restore state
*/
R200_STATECHANGE( rmesa, vte );
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = orig_vte;
/* Unfallback
*/
TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 0 );
/* Need to restore vertexformat?
*/
if (rmesa->radeon.TclFallback)
r200ChooseVertexState( ctx );
}
/**********************************************************************/
/* Initialization. */
/**********************************************************************/
void r200InitSwtcl( struct gl_context *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
r200ContextPtr rmesa = R200_CONTEXT(ctx);
static int firsttime = 1;
if (firsttime) {
init_rast_tab();
firsttime = 0;
}
rmesa->radeon.swtcl.emit_prediction = 0;
tnl->Driver.Render.Start = r200RenderStart;
tnl->Driver.Render.Finish = r200RenderFinish;
tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
/* FIXME: what are these numbers? */
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
36 * sizeof(GLfloat) );
rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
rmesa->radeon.swtcl.RenderIndex = ~0;
rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES;
rmesa->radeon.swtcl.hw_primitive = 0;
}

View File

@ -1,69 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_SWTCL_H__
#define __R200_SWTCL_H__
#include "main/mtypes.h"
#include "swrast/swrast.h"
#include "r200_context.h"
extern void r200InitSwtcl( struct gl_context *ctx );
extern void r200ChooseRenderState( struct gl_context *ctx );
extern void r200ChooseVertexState( struct gl_context *ctx );
extern void r200CheckTexSizes( struct gl_context *ctx );
extern void r200BuildVertices( struct gl_context *ctx, GLuint start, GLuint count,
GLuint newinputs );
extern void r200PrintSetupFlags(char *msg, GLuint flags );
extern void r200_translate_vertex( struct gl_context *ctx,
const radeonVertex *src,
SWvertex *dst );
extern void r200_print_vertex( struct gl_context *ctx, const radeonVertex *v );
extern void r200_import_float_colors( struct gl_context *ctx );
extern void r200_import_float_spec_colors( struct gl_context *ctx );
extern void r200PointsBitmap( struct gl_context *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap );
void r200_swtcl_flush(struct gl_context *ctx, uint32_t current_offset);
#endif

View File

@ -1,638 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/enums.h"
#include "main/light.h"
#include "main/state.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "r200_context.h"
#include "r200_state.h"
#include "r200_ioctl.h"
#include "r200_tcl.h"
#include "r200_swtcl.h"
#include "r200_maos.h"
#include "radeon_common_context.h"
#define HAVE_POINTS 1
#define HAVE_LINES 1
#define HAVE_LINE_LOOP 0
#define HAVE_LINE_STRIPS 1
#define HAVE_TRIANGLES 1
#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_FANS 1
#define HAVE_QUADS 1
#define HAVE_QUAD_STRIPS 1
#define HAVE_POLYGONS 1
#define HAVE_ELTS 1
#define HW_POINTS ((!ctx->Point.SmoothFlag) ? \
R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS)
#define HW_LINES R200_VF_PRIM_LINES
#define HW_LINE_LOOP 0
#define HW_LINE_STRIP R200_VF_PRIM_LINE_STRIP
#define HW_TRIANGLES R200_VF_PRIM_TRIANGLES
#define HW_TRIANGLE_STRIP_0 R200_VF_PRIM_TRIANGLE_STRIP
#define HW_TRIANGLE_STRIP_1 0
#define HW_TRIANGLE_FAN R200_VF_PRIM_TRIANGLE_FAN
#define HW_QUADS R200_VF_PRIM_QUADS
#define HW_QUAD_STRIP R200_VF_PRIM_QUAD_STRIP
#define HW_POLYGON R200_VF_PRIM_POLYGON
static GLboolean discrete_prim[0x10] = {
0, /* 0 none */
1, /* 1 points */
1, /* 2 lines */
0, /* 3 line_strip */
1, /* 4 tri_list */
0, /* 5 tri_fan */
0, /* 6 tri_strip */
0, /* 7 tri_w_flags */
1, /* 8 rect list (unused) */
1, /* 9 3vert point */
1, /* a 3vert line */
0, /* b point sprite */
0, /* c line loop */
1, /* d quads */
0, /* e quad strip */
0, /* f polygon */
};
#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx)
#define ELT_TYPE GLushort
#define ELT_INIT(prim, hw_prim) \
r200TclPrimitive( ctx, prim, hw_prim | R200_VF_PRIM_WALK_IND )
#define GET_MESA_ELTS() TNL_CONTEXT(ctx)->vb.Elts
/* Don't really know how many elts will fit in what's left of cmdbuf,
* as there is state to emit, etc:
*/
/* Testing on isosurf shows a maximum around here. Don't know if it's
* the card or driver or kernel module that is causing the behaviour.
*/
#define GET_MAX_HW_ELTS() 300
#define RESET_STIPPLE() do { \
R200_STATECHANGE( rmesa, lin ); \
radeonEmitState(&rmesa->radeon); \
} while (0)
#define AUTO_STIPPLE( mode ) do { \
R200_STATECHANGE( rmesa, lin ); \
if (mode) \
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \
R200_LINE_PATTERN_AUTO_RESET; \
else \
rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \
~R200_LINE_PATTERN_AUTO_RESET; \
radeonEmitState(&rmesa->radeon); \
} while (0)
#define ALLOC_ELTS(nr) r200AllocElts( rmesa, nr )
static GLushort *r200AllocElts( r200ContextPtr rmesa, GLuint nr )
{
if (rmesa->radeon.dma.flush == r200FlushElts &&
rmesa->tcl.elt_used + nr*2 < R200_ELT_BUF_SZ) {
GLushort *dest = (GLushort *)(rmesa->radeon.tcl.elt_dma_bo->ptr +
rmesa->radeon.tcl.elt_dma_offset + rmesa->tcl.elt_used);
rmesa->tcl.elt_used += nr*2;
return dest;
}
else {
if (rmesa->radeon.dma.flush)
rmesa->radeon.dma.flush( &rmesa->radeon.glCtx );
r200EmitAOS( rmesa,
rmesa->radeon.tcl.aos_count, 0 );
r200EmitMaxVtxIndex(rmesa, rmesa->radeon.tcl.aos[0].count);
return r200AllocEltsOpenEnded( rmesa, rmesa->tcl.hw_primitive, nr );
}
}
#define CLOSE_ELTS() \
do { \
if (0) R200_NEWPRIM( rmesa ); \
} \
while (0)
/* TODO: Try to extend existing primitive if both are identical,
* discrete and there are no intervening state changes. (Somewhat
* duplicates changes to DrawArrays code)
*/
static void r200EmitPrim( struct gl_context *ctx,
GLenum prim,
GLuint hwprim,
GLuint start,
GLuint count)
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
r200TclPrimitive( ctx, prim, hwprim );
// fprintf(stderr,"Emit prim %d\n", rmesa->radeon.tcl.aos_count);
r200EmitAOS( rmesa,
rmesa->radeon.tcl.aos_count,
start );
/* Why couldn't this packet have taken an offset param?
*/
r200EmitVbufPrim( rmesa,
rmesa->tcl.hw_primitive,
count - start );
}
#define EMIT_PRIM(ctx, prim, hwprim, start, count) do { \
r200EmitPrim( ctx, prim, hwprim, start, count ); \
(void) rmesa; } while (0)
#define MAX_CONVERSION_SIZE 40
/* Try & join small primitives
*/
#if 0
#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) 0
#else
#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) \
((NR) < 20 || \
((NR) < 40 && \
rmesa->tcl.hw_primitive == (PRIM| \
R200_VF_TCL_OUTPUT_VTX_ENABLE| \
R200_VF_PRIM_WALK_IND)))
#endif
#ifdef MESA_BIG_ENDIAN
/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
#define EMIT_ELT(dest, offset, x) do { \
int off = offset + ( ( (uintptr_t)dest & 0x2 ) >> 1 ); \
GLushort *des = (GLushort *)( (uintptr_t)dest & ~0x2 ); \
(des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); \
(void)rmesa; } while (0)
#else
#define EMIT_ELT(dest, offset, x) do { \
(dest)[offset] = (GLushort) (x); \
(void)rmesa; } while (0)
#endif
#define EMIT_TWO_ELTS(dest, offset, x, y) *(GLuint *)((dest)+offset) = ((y)<<16)|(x);
#define TAG(x) tcl_##x
#include "tnl_dd/t_dd_dmatmp2.h"
/**********************************************************************/
/* External entrypoints */
/**********************************************************************/
void r200EmitPrimitive( struct gl_context *ctx,
GLuint first,
GLuint last,
GLuint flags )
{
tcl_render_tab_verts[flags&PRIM_MODE_MASK]( ctx, first, last, flags );
}
void r200EmitEltPrimitive( struct gl_context *ctx,
GLuint first,
GLuint last,
GLuint flags )
{
tcl_render_tab_elts[flags&PRIM_MODE_MASK]( ctx, first, last, flags );
}
void r200TclPrimitive( struct gl_context *ctx,
GLenum prim,
int hw_prim )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE;
radeon_prepare_render(&rmesa->radeon);
if (rmesa->radeon.NewGLState)
r200ValidateState( ctx );
if (newprim != rmesa->tcl.hw_primitive ||
!discrete_prim[hw_prim&0xf]) {
/* need to disable perspective-correct texturing for point sprites */
if ((prim & PRIM_MODE_MASK) == GL_POINTS && ctx->Point.PointSprite) {
if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
R200_STATECHANGE( rmesa, set );
rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
}
}
else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
R200_STATECHANGE( rmesa, set );
rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
}
R200_NEWPRIM( rmesa );
rmesa->tcl.hw_primitive = newprim;
}
}
/**
* Predict total emit size for next rendering operation so there is no flush in middle of rendering
* Prediction has to aim towards the best possible value that is worse than worst case scenario
*/
static GLuint r200EnsureEmitSize( struct gl_context * ctx , GLubyte* vimap_rev )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint space_required;
GLuint state_size;
GLuint nr_aos = 0;
int i;
/* predict number of aos to emit */
for (i = 0; i < 15; ++i)
{
if (vimap_rev[i] != 255)
{
++nr_aos;
}
}
{
/* count the prediction for state size */
space_required = 0;
state_size = radeonCountStateEmitSize( &rmesa->radeon );
/* vtx may be changed in r200EmitArrays so account for it if not dirty */
if (!rmesa->hw.vtx.dirty)
state_size += rmesa->hw.vtx.check(&rmesa->radeon.glCtx, &rmesa->hw.vtx);
/* predict size for elements */
for (i = 0; i < VB->PrimitiveCount; ++i)
{
if (!VB->Primitive[i].count)
continue;
/* If primitive.count is less than MAX_CONVERSION_SIZE
rendering code may decide convert to elts.
In that case we have to make pessimistic prediction.
and use larger of 2 paths. */
const GLuint elt_count =(VB->Primitive[i].count/GET_MAX_HW_ELTS() + 1);
const GLuint elts = ELTS_BUFSZ(nr_aos) * elt_count;
const GLuint index = INDEX_BUFSZ * elt_count;
const GLuint vbuf = VBUF_BUFSZ;
if ( (!VB->Elts && VB->Primitive[i].count >= MAX_CONVERSION_SIZE)
|| vbuf > index + elts)
space_required += vbuf;
else
space_required += index + elts;
space_required += AOS_BUFSZ(nr_aos);
}
}
radeon_print(RADEON_RENDER,RADEON_VERBOSE,
"%s space %u, aos %d\n",
__func__, space_required, AOS_BUFSZ(nr_aos) );
/* flush the buffer in case we need more than is left. */
if (rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required + state_size, __func__))
return space_required + radeonCountStateEmitSize( &rmesa->radeon );
else
return space_required + state_size;
}
/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/
/* TCL render.
*/
static GLboolean r200_run_tcl_render( struct gl_context *ctx,
struct tnl_pipeline_stage *stage )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
GLubyte *vimap_rev;
/* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3,
color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use
more than 12 of those at the same time. */
GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255};
/* TODO: separate this from the swtnl pipeline
*/
if (rmesa->radeon.TclFallback)
return GL_TRUE; /* fallback to software t&l */
radeon_print(RADEON_RENDER, RADEON_NORMAL, "%s\n", __func__);
if (VB->Count == 0)
return GL_FALSE;
/* Validate state:
*/
if (rmesa->radeon.NewGLState)
if (!r200ValidateState( ctx ))
return GL_TRUE; /* fallback to sw t&l */
if (!_mesa_arb_vertex_program_enabled(ctx)) {
/* NOTE: inputs != tnl->render_inputs - these are the untransformed
* inputs.
*/
map_rev_fixed[0] = VERT_ATTRIB_POS;
/* technically there is no reason we always need VA_COLOR0. In theory
could disable it depending on lighting, color materials, texturing... */
map_rev_fixed[4] = VERT_ATTRIB_COLOR0;
if (ctx->Light.Enabled) {
map_rev_fixed[2] = VERT_ATTRIB_NORMAL;
}
/* this also enables VA_COLOR1 when using separate specular
lighting model, which is unnecessary.
FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses
the secondary color (if lighting is disabled). The chip seems
misconfigured for that though elsewhere (tcl output, might lock up) */
if (_mesa_need_secondary_color(ctx)) {
map_rev_fixed[5] = VERT_ATTRIB_COLOR1;
}
if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
map_rev_fixed[3] = VERT_ATTRIB_FOG;
}
for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
if (ctx->Texture.Unit[i]._Current) {
if (rmesa->TexGenNeedNormals[i]) {
map_rev_fixed[2] = VERT_ATTRIB_NORMAL;
}
map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i;
}
}
vimap_rev = &map_rev_fixed[0];
}
else {
/* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment
part", since using some vertex interpolator later which is not in
out_vtxfmt0/1 will lock up. It seems to be ok to write in vertex
prog to a not enabled output however, so just don't mess with it.
We only need to change compsel. */
GLuint out_compsel = 0;
const GLbitfield64 vp_out =
rmesa->curr_vp_hw->mesa_program.info.outputs_written;
vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0];
assert(vp_out & BITFIELD64_BIT(VARYING_SLOT_POS));
out_compsel = R200_OUTPUT_XYZW;
if (vp_out & BITFIELD64_BIT(VARYING_SLOT_COL0)) {
out_compsel |= R200_OUTPUT_COLOR_0;
}
if (vp_out & BITFIELD64_BIT(VARYING_SLOT_COL1)) {
out_compsel |= R200_OUTPUT_COLOR_1;
}
if (vp_out & BITFIELD64_BIT(VARYING_SLOT_FOGC)) {
out_compsel |= R200_OUTPUT_DISCRETE_FOG;
}
if (vp_out & BITFIELD64_BIT(VARYING_SLOT_PSIZ)) {
out_compsel |= R200_OUTPUT_PT_SIZE;
}
for (i = VARYING_SLOT_TEX0; i < VARYING_SLOT_TEX6; i++) {
if (vp_out & BITFIELD64_BIT(i)) {
out_compsel |= R200_OUTPUT_TEX_0 << (i - VARYING_SLOT_TEX0);
}
}
if (rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] != out_compsel) {
R200_STATECHANGE( rmesa, vtx );
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = out_compsel;
}
}
/* Do the actual work:
*/
radeonReleaseArrays( ctx, ~0 /* stage->changed_inputs */ );
GLuint emit_end = r200EnsureEmitSize( ctx, vimap_rev )
+ rmesa->radeon.cmdbuf.cs->cdw;
r200EmitArrays( ctx, vimap_rev );
for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
if (!length)
continue;
if (VB->Elts)
r200EmitEltPrimitive( ctx, start, start+length, prim );
else
r200EmitPrimitive( ctx, start, start+length, prim );
}
if ( emit_end < rmesa->radeon.cmdbuf.cs->cdw )
WARN_ONCE("Rendering was %d commands larger than predicted size."
" We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end);
return GL_FALSE; /* finished the pipe */
}
/* Initial state for tcl stage.
*/
const struct tnl_pipeline_stage _r200_tcl_stage =
{
"r200 render",
NULL, /* private */
NULL,
NULL,
NULL,
r200_run_tcl_render /* run */
};
/**********************************************************************/
/* Validate state at pipeline start */
/**********************************************************************/
/*-----------------------------------------------------------------------
* Manage TCL fallbacks
*/
static void transition_to_swtnl( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
R200_NEWPRIM( rmesa );
r200ChooseVertexState( ctx );
r200ChooseRenderState( ctx );
_tnl_validate_shine_tables( ctx );
tnl->Driver.NotifyMaterialChange =
_tnl_validate_shine_tables;
radeonReleaseArrays( ctx, ~0 );
/* Still using the D3D based hardware-rasterizer from the radeon;
* need to put the card into D3D mode to make it work:
*/
R200_STATECHANGE( rmesa, vap );
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_TCL_ENABLE|R200_VAP_PROG_VTX_SHADER_ENABLE);
}
static void transition_to_hwtnl( struct gl_context *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
_tnl_need_projected_coords( ctx, GL_FALSE );
r200UpdateMaterial( ctx );
tnl->Driver.NotifyMaterialChange = r200UpdateMaterial;
if ( rmesa->radeon.dma.flush )
rmesa->radeon.dma.flush( &rmesa->radeon.glCtx );
rmesa->radeon.dma.flush = NULL;
R200_STATECHANGE( rmesa, vap );
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE;
if (_mesa_arb_vertex_program_enabled(ctx)) {
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE;
}
if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
== R200_FOG_USE_SPEC_ALPHA) &&
(ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) {
R200_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG;
}
R200_STATECHANGE( rmesa, vte );
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;
if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "R200 end tcl fallback\n");
}
static char *fallbackStrings[] = {
"Rasterization fallback",
"Unfilled triangles",
"Twosided lighting, differing materials",
"Materials in VB (maybe between begin/end)",
"Texgen unit 0",
"Texgen unit 1",
"Texgen unit 2",
"Texgen unit 3",
"Texgen unit 4",
"Texgen unit 5",
"User disable",
"Bitmap as points",
"Vertex program"
};
static char *getFallbackString(GLuint bit)
{
int i = 0;
while (bit > 1) {
i++;
bit >>= 1;
}
return fallbackStrings[i];
}
void r200TclFallback( struct gl_context *ctx, GLuint bit, GLboolean mode )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint oldfallback = rmesa->radeon.TclFallback;
if (mode) {
if (oldfallback == 0) {
/* We have to flush before transition */
if ( rmesa->radeon.dma.flush )
rmesa->radeon.dma.flush( &rmesa->radeon.glCtx );
if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "R200 begin tcl fallback %s\n",
getFallbackString( bit ));
rmesa->radeon.TclFallback |= bit;
transition_to_swtnl( ctx );
} else
rmesa->radeon.TclFallback |= bit;
} else {
if (oldfallback == bit) {
/* We have to flush before transition */
if ( rmesa->radeon.dma.flush )
rmesa->radeon.dma.flush( &rmesa->radeon.glCtx );
if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "R200 end tcl fallback %s\n",
getFallbackString( bit ));
rmesa->radeon.TclFallback &= ~bit;
transition_to_hwtnl( ctx );
} else
rmesa->radeon.TclFallback &= ~bit;
}
}

View File

@ -1,64 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_TCL_H__
#define __R200_TCL_H__
#include "r200_context.h"
extern void r200TclPrimitive( struct gl_context *ctx, GLenum prim, int hw_prim );
extern void r200EmitEltPrimitive( struct gl_context *ctx, GLuint first, GLuint last,
GLuint flags );
extern void r200EmitPrimitive( struct gl_context *ctx, GLuint first, GLuint last,
GLuint flags );
extern void r200TclFallback( struct gl_context *ctx, GLuint bit, GLboolean mode );
#define R200_TCL_FALLBACK_RASTER 0x1 /* rasterization */
#define R200_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */
#define R200_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */
#define R200_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */
#define R200_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */
#define R200_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */
#define R200_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */
#define R200_TCL_FALLBACK_TEXGEN_3 0x80 /* texgen, unit 3 */
#define R200_TCL_FALLBACK_TEXGEN_4 0x100 /* texgen, unit 4 */
#define R200_TCL_FALLBACK_TEXGEN_5 0x200 /* texgen, unit 5 */
#define R200_TCL_FALLBACK_TCL_DISABLE 0x400 /* user disable */
#define R200_TCL_FALLBACK_BITMAP 0x800 /* draw bitmap with points */
#define R200_TCL_FALLBACK_VERTEX_PROGRAM 0x1000/* vertex program active */
#define TCL_FALLBACK( ctx, bit, mode ) r200TclFallback( ctx, bit, mode )
#endif

View File

@ -1,519 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#include "main/glheader.h"
#include "main/context.h"
#include "main/enums.h"
#include "main/image.h"
#include "main/teximage.h"
#include "main/texobj.h"
#include "main/samplerobj.h"
#include "radeon_mipmap_tree.h"
#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_tex.h"
#include "util/u_memory.h"
#include "util/driconf.h"
/**
* Set the texture wrap modes.
*
* \param t Texture object whose wrap modes are to be set
* \param swrap Wrap mode for the \a s texture coordinate
* \param twrap Wrap mode for the \a t texture coordinate
*/
static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap )
{
GLboolean is_clamp = GL_FALSE;
GLboolean is_clamp_to_border = GL_FALSE;
struct gl_texture_object *tObj = &t->base;
radeon_print(RADEON_TEXTURE, RADEON_TRACE,
"%s(tex %p) sw %s, tw %s, rw %s\n",
__func__, t,
_mesa_enum_to_string(swrap),
_mesa_enum_to_string(twrap),
_mesa_enum_to_string(rwrap));
t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D);
switch ( swrap ) {
case GL_REPEAT:
t->pp_txfilter |= R200_CLAMP_S_WRAP;
break;
case GL_CLAMP:
t->pp_txfilter |= R200_CLAMP_S_CLAMP_GL;
is_clamp = GL_TRUE;
break;
case GL_CLAMP_TO_EDGE:
t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST;
break;
case GL_CLAMP_TO_BORDER:
t->pp_txfilter |= R200_CLAMP_S_CLAMP_GL;
is_clamp_to_border = GL_TRUE;
break;
case GL_MIRRORED_REPEAT:
t->pp_txfilter |= R200_CLAMP_S_MIRROR;
break;
case GL_MIRROR_CLAMP_EXT:
t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_GL;
is_clamp = GL_TRUE;
break;
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_LAST;
break;
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_GL;
is_clamp_to_border = GL_TRUE;
break;
default:
_mesa_problem(NULL, "bad S wrap mode in %s", __func__);
}
if (tObj->Target != GL_TEXTURE_1D) {
switch ( twrap ) {
case GL_REPEAT:
t->pp_txfilter |= R200_CLAMP_T_WRAP;
break;
case GL_CLAMP:
t->pp_txfilter |= R200_CLAMP_T_CLAMP_GL;
is_clamp = GL_TRUE;
break;
case GL_CLAMP_TO_EDGE:
t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST;
break;
case GL_CLAMP_TO_BORDER:
t->pp_txfilter |= R200_CLAMP_T_CLAMP_GL;
is_clamp_to_border = GL_TRUE;
break;
case GL_MIRRORED_REPEAT:
t->pp_txfilter |= R200_CLAMP_T_MIRROR;
break;
case GL_MIRROR_CLAMP_EXT:
t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_GL;
is_clamp = GL_TRUE;
break;
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_LAST;
break;
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_GL;
is_clamp_to_border = GL_TRUE;
break;
default:
_mesa_problem(NULL, "bad T wrap mode in %s", __func__);
}
}
t->pp_txformat_x &= ~R200_CLAMP_Q_MASK;
switch ( rwrap ) {
case GL_REPEAT:
t->pp_txformat_x |= R200_CLAMP_Q_WRAP;
break;
case GL_CLAMP:
t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_GL;
is_clamp = GL_TRUE;
break;
case GL_CLAMP_TO_EDGE:
t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_LAST;
break;
case GL_CLAMP_TO_BORDER:
t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_GL;
is_clamp_to_border = GL_TRUE;
break;
case GL_MIRRORED_REPEAT:
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR;
break;
case GL_MIRROR_CLAMP_EXT:
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_GL;
is_clamp = GL_TRUE;
break;
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_LAST;
break;
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_GL;
is_clamp_to_border = GL_TRUE;
break;
default:
_mesa_problem(NULL, "bad R wrap mode in %s", __func__);
}
if ( is_clamp_to_border ) {
t->pp_txfilter |= R200_BORDER_MODE_D3D;
}
t->border_fallback = (is_clamp && is_clamp_to_border);
}
static void r200SetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max )
{
t->pp_txfilter &= ~R200_MAX_ANISO_MASK;
radeon_print(RADEON_TEXTURE, RADEON_TRACE,
"%s(tex %p) max %f.\n",
__func__, t, max);
if ( max <= 1.0 ) {
t->pp_txfilter |= R200_MAX_ANISO_1_TO_1;
} else if ( max <= 2.0 ) {
t->pp_txfilter |= R200_MAX_ANISO_2_TO_1;
} else if ( max <= 4.0 ) {
t->pp_txfilter |= R200_MAX_ANISO_4_TO_1;
} else if ( max <= 8.0 ) {
t->pp_txfilter |= R200_MAX_ANISO_8_TO_1;
} else {
t->pp_txfilter |= R200_MAX_ANISO_16_TO_1;
}
}
/**
* Set the texture magnification and minification modes.
*
* \param t Texture whose filter modes are to be set
* \param minf Texture minification mode
* \param magf Texture magnification mode
*/
static void r200SetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf )
{
GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK);
/* Force revalidation to account for switches from/to mipmapping. */
t->validated = GL_FALSE;
t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK);
t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK;
radeon_print(RADEON_TEXTURE, RADEON_TRACE,
"%s(tex %p) minf %s, maxf %s, anisotropy %d.\n",
__func__, t,
_mesa_enum_to_string(minf),
_mesa_enum_to_string(magf),
anisotropy);
if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) {
switch ( minf ) {
case GL_NEAREST:
t->pp_txfilter |= R200_MIN_FILTER_NEAREST;
break;
case GL_LINEAR:
t->pp_txfilter |= R200_MIN_FILTER_LINEAR;
break;
case GL_NEAREST_MIPMAP_NEAREST:
t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_NEAREST;
break;
case GL_LINEAR_MIPMAP_NEAREST:
t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_LINEAR;
break;
case GL_LINEAR_MIPMAP_LINEAR:
t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_LINEAR;
break;
}
} else {
switch ( minf ) {
case GL_NEAREST:
t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST;
break;
case GL_LINEAR:
t->pp_txfilter |= R200_MIN_FILTER_ANISO_LINEAR;
break;
case GL_NEAREST_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_NEAREST:
t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
break;
}
}
/* Note we don't have 3D mipmaps so only use the mag filter setting
* to set the 3D texture filter mode.
*/
switch ( magf ) {
case GL_NEAREST:
t->pp_txfilter |= R200_MAG_FILTER_NEAREST;
t->pp_txformat_x |= R200_VOLUME_FILTER_NEAREST;
break;
case GL_LINEAR:
t->pp_txfilter |= R200_MAG_FILTER_LINEAR;
t->pp_txformat_x |= R200_VOLUME_FILTER_LINEAR;
break;
}
}
static void r200SetTexBorderColor( radeonTexObjPtr t, const GLfloat color[4] )
{
GLubyte c[4];
CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
}
static void r200TexEnv( struct gl_context *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint unit = ctx->Texture.CurrentUnit;
struct gl_fixedfunc_texture_unit *texUnit =
&ctx->Texture.FixedFuncUnit[unit];
radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_VERBOSE, "%s( %s )\n",
__func__, _mesa_enum_to_string( pname ) );
/* This is incorrect: Need to maintain this data for each of
* GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
* between them according to _Current->Target.
*/
switch ( pname ) {
case GL_TEXTURE_ENV_COLOR: {
GLubyte c[4];
GLuint envColor;
_mesa_unclamped_float_rgba_to_ubyte(c, texUnit->EnvColor);
envColor = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
if ( rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] != envColor ) {
R200_STATECHANGE( rmesa, tf );
rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] = envColor;
}
break;
}
case GL_TEXTURE_LOD_BIAS_EXT: {
GLfloat bias, min;
GLuint b;
const int fixed_one = R200_LOD_BIAS_FIXED_ONE;
/* The R200's LOD bias is a signed 2's complement value with a
* range of -16.0 <= bias < 16.0.
*
* NOTE: Add a small bias to the bias for conform mipsel.c test.
*/
bias = *param;
min = driQueryOptionb (&rmesa->radeon.optionCache, "no_neg_lod_bias") ?
0.0 : -16.0;
bias = CLAMP( bias, min, 16.0 );
b = ((int)(bias * fixed_one)
+ R200_LOD_BIAS_CORRECTION) & R200_LOD_BIAS_MASK;
if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) {
R200_STATECHANGE( rmesa, tex[unit] );
rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] &= ~R200_LOD_BIAS_MASK;
rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] |= b;
}
break;
}
case GL_COORD_REPLACE_ARB:
if (ctx->Point.PointSprite) {
R200_STATECHANGE( rmesa, spr );
if ((GLenum)param[0]) {
rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_GEN_TEX_0 << unit;
} else {
rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~(R200_PS_GEN_TEX_0 << unit);
}
}
break;
default:
return;
}
}
void r200TexUpdateParameters(struct gl_context *ctx, GLuint unit)
{
struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
radeonTexObj* t = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
r200SetTexMaxAnisotropy(t , samp->Attrib.MaxAnisotropy);
r200SetTexFilter(t, samp->Attrib.MinFilter, samp->Attrib.MagFilter);
r200SetTexWrap(t, samp->Attrib.WrapS, samp->Attrib.WrapT, samp->Attrib.WrapR);
r200SetTexBorderColor(t, samp->Attrib.state.border_color.f);
}
/**
* Changes variables and flags for a state update, which will happen at the
* next UpdateTextureState
*/
static void r200TexParameter(struct gl_context *ctx,
struct gl_texture_object *texObj,
GLenum pname)
{
radeonTexObj* t = radeon_tex_obj(texObj);
radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_VERBOSE,
"%s(%p, tex %p) pname %s\n",
__func__, ctx, texObj,
_mesa_enum_to_string( pname ) );
switch ( pname ) {
case GL_ALL_ATTRIB_BITS: /* meaning is all pnames, internal */
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
case GL_TEXTURE_BORDER_COLOR:
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MAX_LEVEL:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
t->validated = GL_FALSE;
break;
default:
return;
}
}
static void r200DeleteTexture(struct gl_context * ctx, struct gl_texture_object *texObj)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
radeonTexObj* t = radeon_tex_obj(texObj);
radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_NORMAL,
"%s( %p (target = %s) )\n", __func__,
(void *)texObj,
_mesa_enum_to_string(texObj->Target));
if (rmesa) {
int i;
radeon_firevertices(&rmesa->radeon);
for ( i = 0 ; i < rmesa->radeon.glCtx.Const.MaxTextureUnits ; i++ ) {
if ( t == rmesa->state.texture.unit[i].texobj ) {
rmesa->state.texture.unit[i].texobj = NULL;
rmesa->hw.tex[i].dirty = GL_FALSE;
rmesa->hw.cube[i].dirty = GL_FALSE;
}
}
}
radeon_miptree_unreference(&t->mt);
_mesa_delete_texture_object(ctx, texObj);
}
/* Need:
* - Same GEN_MODE for all active bits
* - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
* - STRQ presumably all supported (matrix means incoming R values
* can end up in STQ, this has implications for vertex support,
* presumably ok if maos is used, though?)
*
* Basically impossible to do this on the fly - just collect some
* basic info & do the checks from ValidateState().
*/
static void r200TexGen( struct gl_context *ctx,
GLenum coord,
GLenum pname,
const GLfloat *params )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint unit = ctx->Texture.CurrentUnit;
rmesa->recheck_texgen[unit] = GL_TRUE;
}
/**
* Allocate a new texture object.
* Called via ctx->Driver.NewTextureObject.
* Note: this function will be called during context creation to
* allocate the default texture objects.
* Fixup MaxAnisotropy according to user preference.
*/
static struct gl_texture_object *r200NewTextureObject(struct gl_context * ctx,
GLuint name,
GLenum target)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj);
radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
"%s(%p) target %s, new texture %p.\n",
__func__, ctx,
_mesa_enum_to_string(target), t);
_mesa_initialize_texture_object(ctx, &t->base, name, target);
t->base.Sampler.Attrib.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
/* Initialize hardware state */
r200SetTexWrap( t, t->base.Sampler.Attrib.WrapS, t->base.Sampler.Attrib.WrapT, t->base.Sampler.Attrib.WrapR );
r200SetTexMaxAnisotropy( t, t->base.Sampler.Attrib.MaxAnisotropy );
r200SetTexFilter(t, t->base.Sampler.Attrib.MinFilter, t->base.Sampler.Attrib.MagFilter);
r200SetTexBorderColor(t, t->base.Sampler.Attrib.state.border_color.f);
return &t->base;
}
static struct gl_sampler_object *
r200NewSamplerObject(struct gl_context *ctx, GLuint name)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
struct gl_sampler_object *samp = _mesa_new_sampler_object(ctx, name);
if (samp)
samp->Attrib.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
return samp;
}
void r200InitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions )
{
/* Note: we only plug in the functions we implement in the driver
* since _mesa_init_driver_functions() was already called.
*/
radeon_init_common_texture_funcs(radeon, functions);
functions->NewTextureObject = r200NewTextureObject;
// functions->BindTexture = r200BindTexture;
functions->DeleteTexture = r200DeleteTexture;
functions->TexEnv = r200TexEnv;
functions->TexParameter = r200TexParameter;
functions->TexGen = r200TexGen;
functions->NewSamplerObject = r200NewSamplerObject;
}

View File

@ -1,121 +0,0 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keithw@vmware.com>
*/
#ifndef __R200_TEX_H__
#define __R200_TEX_H__
extern void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv);
extern void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format,
__DRIdrawable *dPriv);
extern void r200UpdateTextureState( struct gl_context *ctx );
extern int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face );
extern void r200DestroyTexObj( r200ContextPtr rmesa, radeonTexObjPtr t );
extern void r200InitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions );
extern void r200UpdateFragmentShader( struct gl_context *ctx );
extern void r200TexUpdateParameters(struct gl_context *ctx, GLuint unit);
extern void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d );
struct tx_table {
GLuint format, filter;
};
/* Note the tables (have to) contain invalid entries (if they are only valid
* for either be/le) */
static const struct tx_table tx_table_be[] =
{
[ MESA_FORMAT_A8B8G8R8_UNORM ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_R8G8B8A8_UNORM ] = { R200_TXFORMAT_RGBA8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_B8G8R8A8_UNORM ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_B8G8R8X8_UNORM ] = { R200_TXFORMAT_ARGB8888, 0 },
[ MESA_FORMAT_A8R8G8B8_UNORM ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_X8R8G8B8_UNORM ] = { R200_TXFORMAT_ARGB8888, 0 },
[ MESA_FORMAT_BGR_UNORM8 ] = { 0xffffffff, 0 },
[ MESA_FORMAT_B5G6R5_UNORM ] = { R200_TXFORMAT_RGB565, 0 },
[ MESA_FORMAT_R5G6B5_UNORM ] = { R200_TXFORMAT_RGB565, 0 },
[ MESA_FORMAT_B4G4R4A4_UNORM ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_A4R4G4B4_UNORM ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_B5G5R5A1_UNORM ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_A1R5G5B5_UNORM ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_A_UNORM8 ] = { R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_L_UNORM8 ] = { R200_TXFORMAT_I8, 0 },
[ MESA_FORMAT_LA_UNORM8 ] = { R200_TXFORMAT_AI88 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_I_UNORM8 ] = { R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_YCBCR ] = { R200_TXFORMAT_YVYU422, R200_YUV_TO_RGB },
[ MESA_FORMAT_YCBCR_REV ] = { R200_TXFORMAT_VYUY422, R200_YUV_TO_RGB },
[ MESA_FORMAT_RGB_FXT1 ] = { 0xffffffff, 0 },
[ MESA_FORMAT_RGBA_FXT1 ] = { 0xffffffff, 0 },
[ MESA_FORMAT_RGB_DXT1 ] = { R200_TXFORMAT_DXT1, 0 },
[ MESA_FORMAT_RGBA_DXT1 ] = { R200_TXFORMAT_DXT1 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_RGBA_DXT3 ] = { R200_TXFORMAT_DXT23 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_RGBA_DXT5 ] = { R200_TXFORMAT_DXT45 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
};
static const struct tx_table tx_table_le[] =
{
[ MESA_FORMAT_A8B8G8R8_UNORM ] = { R200_TXFORMAT_RGBA8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_R8G8B8A8_UNORM ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_B8G8R8A8_UNORM ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_B8G8R8X8_UNORM ] = { R200_TXFORMAT_ARGB8888, 0 },
[ MESA_FORMAT_A8R8G8B8_UNORM ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_X8R8G8B8_UNORM ] = { R200_TXFORMAT_ARGB8888, 0 },
[ MESA_FORMAT_BGR_UNORM8 ] = { R200_TXFORMAT_ARGB8888, 0 },
[ MESA_FORMAT_B5G6R5_UNORM ] = { R200_TXFORMAT_RGB565, 0 },
[ MESA_FORMAT_R5G6B5_UNORM ] = { R200_TXFORMAT_RGB565, 0 },
[ MESA_FORMAT_B4G4R4A4_UNORM ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_A4R4G4B4_UNORM ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_B5G5R5A1_UNORM ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_A1R5G5B5_UNORM ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_A_UNORM8 ] = { R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_L_UNORM8 ] = { R200_TXFORMAT_I8, 0 },
[ MESA_FORMAT_LA_UNORM8 ] = { R200_TXFORMAT_AI88 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_I_UNORM8 ] = { R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_YCBCR ] = { R200_TXFORMAT_YVYU422, R200_YUV_TO_RGB },
[ MESA_FORMAT_YCBCR_REV ] = { R200_TXFORMAT_VYUY422, R200_YUV_TO_RGB },
[ MESA_FORMAT_RGB_FXT1 ] = { 0xffffffff, 0 },
[ MESA_FORMAT_RGBA_FXT1 ] = { 0xffffffff, 0 },
[ MESA_FORMAT_RGB_DXT1 ] = { R200_TXFORMAT_DXT1, 0 },
[ MESA_FORMAT_RGBA_DXT1 ] = { R200_TXFORMAT_DXT1 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_RGBA_DXT3 ] = { R200_TXFORMAT_DXT23 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
[ MESA_FORMAT_RGBA_DXT5 ] = { R200_TXFORMAT_DXT45 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
};
#endif /* __R200_TEX_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,163 +0,0 @@
#ifndef __VERTEX_SHADER_H__
#define __VERTEX_SHADER_H__
#include "r200_reg.h"
typedef struct {
uint32_t op;
uint32_t src0;
uint32_t src1;
uint32_t src2;
} VERTEX_SHADER_INSTRUCTION;
extern void r200InitShaderFuncs(struct dd_function_table *functions);
extern void r200SetupVertexProg( struct gl_context *ctx );
#define VSF_FLAG_X 1
#define VSF_FLAG_Y 2
#define VSF_FLAG_Z 4
#define VSF_FLAG_W 8
#define VSF_FLAG_XYZ (VSF_FLAG_X | VSF_FLAG_Y | VSF_FLAG_Z)
#define VSF_FLAG_ALL 0xf
#define VSF_FLAG_NONE 0
#define R200_VSF_MAX_INST 128
#define R200_VSF_MAX_PARAM 192
#define R200_VSF_MAX_TEMPS 12
#define R200_VPI_OUT_REG_INDEX_SHIFT 13
#define R200_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
#define R200_VPI_OUT_WRITE_X (1 << 20)
#define R200_VPI_OUT_WRITE_Y (1 << 21)
#define R200_VPI_OUT_WRITE_Z (1 << 22)
#define R200_VPI_OUT_WRITE_W (1 << 23)
#define R200_VPI_IN_REG_CLASS_TEMPORARY (0 << 0)
#define R200_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
#define R200_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
#define R200_VPI_IN_REG_CLASS_NONE (9 << 0)
#define R200_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
#define R200_VPI_IN_REG_INDEX_SHIFT 5
#define R200_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
/* The R200 can select components from the input register arbitrarily.
// Use the following constants, shifted by the component shift you
// want to select */
#define R200_VPI_IN_SELECT_X 0
#define R200_VPI_IN_SELECT_Y 1
#define R200_VPI_IN_SELECT_Z 2
#define R200_VPI_IN_SELECT_W 3
#define R200_VPI_IN_SELECT_ZERO 4
#define R200_VPI_IN_SELECT_ONE 5
#define R200_VPI_IN_SELECT_MASK 7
#define R200_VPI_IN_X_SHIFT 13
#define R200_VPI_IN_Y_SHIFT 16
#define R200_VPI_IN_Z_SHIFT 19
#define R200_VPI_IN_W_SHIFT 22
#define R200_VPI_IN_NEG_X (1 << 25)
#define R200_VPI_IN_NEG_Y (1 << 26)
#define R200_VPI_IN_NEG_Z (1 << 27)
#define R200_VPI_IN_NEG_W (1 << 28)
#define R200_VSF_OUT_CLASS_TMP (0 << 8)
#define R200_VSF_OUT_CLASS_ADDR (3 << 8)
#define R200_VSF_OUT_CLASS_RESULT_POS (4 << 8)
#define R200_VSF_OUT_CLASS_RESULT_COLOR (5 << 8)
#define R200_VSF_OUT_CLASS_RESULT_TEXC (6 << 8)
#define R200_VSF_OUT_CLASS_RESULT_FOGC (7 << 8)
#define R200_VSF_OUT_CLASS_RESULT_POINTSIZE (8 << 8)
#define R200_VSF_OUT_CLASS_MASK (31 << 8)
/* opcodes - they all are the same as on r300 it seems, however
LIT and POW require different setup */
#define R200_VPI_OUT_OP_DOT (1 << 0)
#define R200_VPI_OUT_OP_MUL (2 << 0)
#define R200_VPI_OUT_OP_ADD (3 << 0)
#define R200_VPI_OUT_OP_MAD (4 << 0)
#define R200_VPI_OUT_OP_DST (5 << 0)
#define R200_VPI_OUT_OP_FRC (6 << 0)
#define R200_VPI_OUT_OP_MAX (7 << 0)
#define R200_VPI_OUT_OP_MIN (8 << 0)
#define R200_VPI_OUT_OP_SGE (9 << 0)
#define R200_VPI_OUT_OP_SLT (10 << 0)
#define R200_VPI_OUT_OP_ARL (13 << 0)
#define R200_VPI_OUT_OP_EXP (65 << 0)
#define R200_VPI_OUT_OP_LOG (66 << 0)
/* base e exp. Useful for fog. */
#define R200_VPI_OUT_OP_EXP_E (67 << 0)
#define R200_VPI_OUT_OP_LIT (68 << 0)
#define R200_VPI_OUT_OP_POW (69 << 0)
#define R200_VPI_OUT_OP_RCP (70 << 0)
#define R200_VPI_OUT_OP_RSQ (72 << 0)
#define R200_VPI_OUT_OP_EX2 (75 << 0)
#define R200_VPI_OUT_OP_LG2 (76 << 0)
#define R200_VPI_OUT_OP_MAD_2 (128 << 0)
/* first CARD32 of an instruction */
/* possible operations:
DOT, MUL, ADD, MAD, FRC, MAX, MIN, SGE, SLT, EXP, LOG, LIT, POW, RCP, RSQ, EX2,
LG2, MAD_2, ARL */
#define MAKE_VSF_OP(op, out_reg, out_reg_fields) \
((op) | (out_reg) | ((out_reg_fields) << 20) )
#define VSF_IN_CLASS_TMP 0
#define VSF_IN_CLASS_ATTR 1
#define VSF_IN_CLASS_PARAM 2
#define VSF_IN_CLASS_NONE 9
#define VSF_IN_COMPONENT_X 0
#define VSF_IN_COMPONENT_Y 1
#define VSF_IN_COMPONENT_Z 2
#define VSF_IN_COMPONENT_W 3
#define VSF_IN_COMPONENT_ZERO 4
#define VSF_IN_COMPONENT_ONE 5
#define MAKE_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \
( ((in_reg_index)<<R200_VPI_IN_REG_INDEX_SHIFT) \
| ((comp_x)<<R200_VPI_IN_X_SHIFT) \
| ((comp_y)<<R200_VPI_IN_Y_SHIFT) \
| ((comp_z)<<R200_VPI_IN_Z_SHIFT) \
| ((comp_w)<<R200_VPI_IN_W_SHIFT) \
| ((negate)<<25) | ((class)))
#define EASY_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \
MAKE_VSF_SOURCE(in_reg_index, \
VSF_IN_COMPONENT_##comp_x, \
VSF_IN_COMPONENT_##comp_y, \
VSF_IN_COMPONENT_##comp_z, \
VSF_IN_COMPONENT_##comp_w, \
VSF_IN_CLASS_##class, VSF_FLAG_##negate)
/* special sources: */
/* (1.0,1.0,1.0,1.0) vector (ATTR, plain ) */
#define VSF_ATTR_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, ATTR, NONE)
#define VSF_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, NONE, NONE)
/* contents of unmodified register */
#define VSF_REG(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, ATTR, NONE)
/* contents of unmodified parameter */
#define VSF_PARAM(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, PARAM, NONE)
/* contents of unmodified temporary register */
#define VSF_TMP(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, TMP, NONE)
/* components of ATTR register */
#define VSF_ATTR_X(reg) EASY_VSF_SOURCE(reg, X, X, X, X, ATTR, NONE)
#define VSF_ATTR_Y(reg) EASY_VSF_SOURCE(reg, Y, Y, Y, Y, ATTR, NONE)
#define VSF_ATTR_Z(reg) EASY_VSF_SOURCE(reg, Z, Z, Z, Z, ATTR, NONE)
#define VSF_ATTR_W(reg) EASY_VSF_SOURCE(reg, W, W, W, W, ATTR, NONE)
#endif

View File

@ -1 +0,0 @@
../radeon/radeon_buffer_objects.c

View File

@ -1 +0,0 @@
../radeon/radeon_buffer_objects.h

View File

@ -1 +0,0 @@
../radeon/radeon_chipset.h

View File

@ -1 +0,0 @@
../radeon/radeon_cmdbuf.h

View File

@ -1 +0,0 @@
../radeon/radeon_common.c

View File

@ -1 +0,0 @@
../radeon/radeon_common.h

View File

@ -1 +0,0 @@
../radeon/radeon_common_context.c

View File

@ -1 +0,0 @@
../radeon/radeon_common_context.h

View File

@ -1 +0,0 @@
../radeon/radeon_debug.c

View File

@ -1 +0,0 @@
../radeon/radeon_debug.h

View File

@ -1 +0,0 @@
../radeon/radeon_dma.c

View File

@ -1 +0,0 @@
../radeon/radeon_dma.h

View File

@ -1 +0,0 @@
../radeon/radeon_fbo.c

View File

@ -1 +0,0 @@
../radeon/radeon_fog.c

View File

@ -1 +0,0 @@
../radeon/radeon_fog.h

View File

@ -1 +0,0 @@
../radeon/radeon_mipmap_tree.c

View File

@ -1 +0,0 @@
../radeon/radeon_mipmap_tree.h

View File

@ -1 +0,0 @@
../radeon/radeon_pixel_read.c

View File

@ -1 +0,0 @@
../radeon/radeon_queryobj.c

View File

@ -1 +0,0 @@
../radeon/radeon_queryobj.h

View File

@ -1 +0,0 @@
../radeon/radeon_screen.c

View File

@ -1 +0,0 @@
../radeon/radeon_screen.h

View File

@ -1 +0,0 @@
../radeon/radeon_span.c

View File

@ -1 +0,0 @@
../radeon/radeon_span.h

View File

@ -1 +0,0 @@
../radeon/radeon_tex_copy.c

View File

@ -1 +0,0 @@
../radeon/radeon_texture.c

View File

@ -1 +0,0 @@
../radeon/radeon_texture.h

View File

@ -1 +0,0 @@
../radeon/radeon_tile.c

View File

@ -1 +0,0 @@
../radeon/radeon_tile.h

View File

@ -1 +0,0 @@
../../radeon/server/radeon_reg.h