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:
parent
4d45b280bf
commit
184a690fca
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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)],
|
||||
]
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
)
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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 );
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_buffer_objects.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_buffer_objects.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_chipset.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_cmdbuf.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_common.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_common.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_common_context.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_common_context.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_debug.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_debug.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_dma.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_dma.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_fbo.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_fog.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_fog.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_mipmap_tree.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_mipmap_tree.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_pixel_read.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_queryobj.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_queryobj.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_screen.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_screen.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_span.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_span.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_tex_copy.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_texture.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_texture.h
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_tile.c
|
|
@ -1 +0,0 @@
|
|||
../radeon/radeon_tile.h
|
|
@ -1 +0,0 @@
|
|||
../../radeon/server/radeon_reg.h
|
Loading…
Reference in New Issue