mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
svga: Add svga driver
This commit is contained in:
parent
6b480dc21d
commit
3192633d4a
95 changed files with 27235 additions and 0 deletions
63
src/gallium/drivers/svga/Makefile
Normal file
63
src/gallium/drivers/svga/Makefile
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = svga
|
||||
|
||||
C_SOURCES = \
|
||||
svgadump/st_shader_dump.c \
|
||||
svgadump/st_shader_op.c \
|
||||
svgadump/svga_dump.c \
|
||||
svga_cmd.c \
|
||||
svga_context.c \
|
||||
svga_draw.c \
|
||||
svga_draw_arrays.c \
|
||||
svga_draw_elements.c \
|
||||
svga_pipe_blend.c \
|
||||
svga_pipe_blit.c \
|
||||
svga_pipe_clear.c \
|
||||
svga_pipe_constants.c \
|
||||
svga_pipe_depthstencil.c \
|
||||
svga_pipe_draw.c \
|
||||
svga_pipe_flush.c \
|
||||
svga_pipe_fs.c \
|
||||
svga_pipe_misc.c \
|
||||
svga_pipe_query.c \
|
||||
svga_pipe_rasterizer.c \
|
||||
svga_pipe_sampler.c \
|
||||
svga_pipe_vertex.c \
|
||||
svga_pipe_vs.c \
|
||||
svga_screen.c \
|
||||
svga_screen_buffer.c \
|
||||
svga_screen_texture.c \
|
||||
svga_screen_cache.c \
|
||||
svga_state.c \
|
||||
svga_state_need_swtnl.c \
|
||||
svga_state_constants.c \
|
||||
svga_state_framebuffer.c \
|
||||
svga_state_rss.c \
|
||||
svga_state_tss.c \
|
||||
svga_state_vdecl.c \
|
||||
svga_state_fs.c \
|
||||
svga_state_vs.c \
|
||||
svga_swtnl_backend.c \
|
||||
svga_swtnl_draw.c \
|
||||
svga_swtnl_state.c \
|
||||
svga_tgsi.c \
|
||||
svga_tgsi_decl_sm20.c \
|
||||
svga_tgsi_decl_sm30.c \
|
||||
svga_tgsi_insn.c
|
||||
|
||||
LIBRARY_INCLUDES = \
|
||||
-I$(TOP)/src/gallium/drivers/svga/include
|
||||
|
||||
LIBRARY_DEFINES = \
|
||||
-DHAVE_STDINT_H -DHAVE_SYS_TYPES_H
|
||||
|
||||
CC = gcc -fvisibility=hidden -msse -msse2
|
||||
|
||||
# Set the gnu99 standard to enable anonymous structs in vmware headers.
|
||||
#
|
||||
CFLAGS = -Wall -Werror -Wmissing-prototypes -std=gnu99 -ffast-math \
|
||||
$(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) $(ASM_FLAGS)
|
||||
|
||||
include ../../Makefile.template
|
||||
75
src/gallium/drivers/svga/SConscript
Normal file
75
src/gallium/drivers/svga/SConscript
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
Import('*')
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
if env['platform'] in ['linux']:
|
||||
env.Append(CCFLAGS = ['-fvisibility=hidden'])
|
||||
|
||||
if env['gcc']:
|
||||
env.Append(CPPDEFINES = [
|
||||
'HAVE_STDINT_H',
|
||||
'HAVE_SYS_TYPES_H',
|
||||
])
|
||||
if env['platform'] not in ['windows']:
|
||||
# The Windows headers cause many gcc warnings
|
||||
env.Append(CCFLAGS = ['-Werror'])
|
||||
|
||||
env.Prepend(CPPPATH = [
|
||||
'include',
|
||||
])
|
||||
|
||||
env.Append(CPPDEFINES = [
|
||||
])
|
||||
|
||||
sources = [
|
||||
'svga_cmd.c',
|
||||
'svga_context.c',
|
||||
'svga_draw.c',
|
||||
'svga_draw_arrays.c',
|
||||
'svga_draw_elements.c',
|
||||
'svga_pipe_blend.c',
|
||||
'svga_pipe_blit.c',
|
||||
'svga_pipe_clear.c',
|
||||
'svga_pipe_constants.c',
|
||||
'svga_pipe_depthstencil.c',
|
||||
'svga_pipe_draw.c',
|
||||
'svga_pipe_flush.c',
|
||||
'svga_pipe_fs.c',
|
||||
'svga_pipe_misc.c',
|
||||
'svga_pipe_query.c',
|
||||
'svga_pipe_rasterizer.c',
|
||||
'svga_pipe_sampler.c',
|
||||
'svga_pipe_vertex.c',
|
||||
'svga_pipe_vs.c',
|
||||
'svga_screen.c',
|
||||
'svga_screen_buffer.c',
|
||||
'svga_screen_cache.c',
|
||||
'svga_screen_texture.c',
|
||||
'svga_state.c',
|
||||
'svga_state_constants.c',
|
||||
'svga_state_framebuffer.c',
|
||||
'svga_state_need_swtnl.c',
|
||||
'svga_state_rss.c',
|
||||
'svga_state_tss.c',
|
||||
'svga_state_vdecl.c',
|
||||
'svga_state_fs.c',
|
||||
'svga_state_vs.c',
|
||||
'svga_swtnl_backend.c',
|
||||
'svga_swtnl_draw.c',
|
||||
'svga_swtnl_state.c',
|
||||
'svga_tgsi.c',
|
||||
'svga_tgsi_decl_sm20.c',
|
||||
'svga_tgsi_decl_sm30.c',
|
||||
'svga_tgsi_insn.c',
|
||||
|
||||
'svgadump/svga_dump.c',
|
||||
'svgadump/st_shader_dump.c',
|
||||
'svgadump/st_shader_op.c',
|
||||
]
|
||||
|
||||
svga = env.ConvenienceLibrary(
|
||||
target = 'svga',
|
||||
source = sources,
|
||||
)
|
||||
|
||||
Export('svga')
|
||||
3
src/gallium/drivers/svga/include/README
Normal file
3
src/gallium/drivers/svga/include/README
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
This directory contains the headers from the VMware SVGA Device Developer Kit:
|
||||
|
||||
https://vmware-svga.svn.sourceforge.net/svnroot/vmware-svga/trunk/lib/vmware/
|
||||
139
src/gallium/drivers/svga/include/svga3d_caps.h
Normal file
139
src/gallium/drivers/svga/include/svga3d_caps.h
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/**********************************************************
|
||||
* Copyright 2007-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/*
|
||||
* svga3d_caps.h --
|
||||
*
|
||||
* Definitions for SVGA3D hardware capabilities. Capabilities
|
||||
* are used to query for optional rendering features during
|
||||
* driver initialization. The capability data is stored as very
|
||||
* basic key/value dictionary within the "FIFO register" memory
|
||||
* area at the beginning of BAR2.
|
||||
*
|
||||
* Note that these definitions are only for 3D capabilities.
|
||||
* The SVGA device also has "device capabilities" and "FIFO
|
||||
* capabilities", which are non-3D-specific and are stored as
|
||||
* bitfields rather than key/value pairs.
|
||||
*/
|
||||
|
||||
#ifndef _SVGA3D_CAPS_H_
|
||||
#define _SVGA3D_CAPS_H_
|
||||
|
||||
#define SVGA_FIFO_3D_CAPS_SIZE (SVGA_FIFO_3D_CAPS_LAST - \
|
||||
SVGA_FIFO_3D_CAPS + 1)
|
||||
|
||||
|
||||
/*
|
||||
* SVGA3dCapsRecordType
|
||||
*
|
||||
* Record types that can be found in the caps block.
|
||||
* Related record types are grouped together numerically so that
|
||||
* SVGA3dCaps_FindRecord() can be applied on a range of record
|
||||
* types.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
SVGA3DCAPS_RECORD_UNKNOWN = 0,
|
||||
SVGA3DCAPS_RECORD_DEVCAPS_MIN = 0x100,
|
||||
SVGA3DCAPS_RECORD_DEVCAPS = 0x100,
|
||||
SVGA3DCAPS_RECORD_DEVCAPS_MAX = 0x1ff,
|
||||
} SVGA3dCapsRecordType;
|
||||
|
||||
|
||||
/*
|
||||
* SVGA3dCapsRecordHeader
|
||||
*
|
||||
* Header field leading each caps block record. Contains the offset (in
|
||||
* register words, NOT bytes) to the next caps block record (or the end
|
||||
* of caps block records which will be a zero word) and the record type
|
||||
* as defined above.
|
||||
*/
|
||||
|
||||
typedef
|
||||
struct SVGA3dCapsRecordHeader {
|
||||
uint32 length;
|
||||
SVGA3dCapsRecordType type;
|
||||
}
|
||||
SVGA3dCapsRecordHeader;
|
||||
|
||||
|
||||
/*
|
||||
* SVGA3dCapsRecord
|
||||
*
|
||||
* Caps block record; "data" is a placeholder for the actual data structure
|
||||
* contained within the record; for example a record containing a FOOBAR
|
||||
* structure would be of size "sizeof(SVGA3dCapsRecordHeader) +
|
||||
* sizeof(FOOBAR)".
|
||||
*/
|
||||
|
||||
typedef
|
||||
struct SVGA3dCapsRecord {
|
||||
SVGA3dCapsRecordHeader header;
|
||||
uint32 data[1];
|
||||
}
|
||||
SVGA3dCapsRecord;
|
||||
|
||||
|
||||
typedef uint32 SVGA3dCapPair[2];
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* SVGA3dCaps_FindRecord
|
||||
*
|
||||
* Finds the record with the highest-valued type within the given range
|
||||
* in the caps block.
|
||||
*
|
||||
* Result: pointer to found record, or NULL if not found.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static INLINE SVGA3dCapsRecord *
|
||||
SVGA3dCaps_FindRecord(const uint32 *capsBlock,
|
||||
SVGA3dCapsRecordType recordTypeMin,
|
||||
SVGA3dCapsRecordType recordTypeMax)
|
||||
{
|
||||
SVGA3dCapsRecord *record, *found = NULL;
|
||||
uint32 offset;
|
||||
|
||||
/*
|
||||
* Search linearly through the caps block records for the specified type.
|
||||
*/
|
||||
for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
|
||||
record = (SVGA3dCapsRecord *) (capsBlock + offset);
|
||||
if ((record->header.type >= recordTypeMin) &&
|
||||
(record->header.type <= recordTypeMax) &&
|
||||
(!found || (record->header.type > found->header.type))) {
|
||||
found = record;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
#endif // _SVGA3D_CAPS_H_
|
||||
1793
src/gallium/drivers/svga/include/svga3d_reg.h
Normal file
1793
src/gallium/drivers/svga/include/svga3d_reg.h
Normal file
File diff suppressed because it is too large
Load diff
519
src/gallium/drivers/svga/include/svga3d_shaderdefs.h
Normal file
519
src/gallium/drivers/svga/include/svga3d_shaderdefs.h
Normal file
|
|
@ -0,0 +1,519 @@
|
|||
/**********************************************************
|
||||
* Copyright 2007-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/*
|
||||
* svga3d_shaderdefs.h --
|
||||
*
|
||||
* SVGA3D byte code format and limit definitions.
|
||||
*
|
||||
* The format of the byte code directly corresponds to that defined
|
||||
* by Microsoft DirectX SDK 9.0c (file d3d9types.h). The format can
|
||||
* also be extended so that different shader formats can be supported
|
||||
* for example GLSL, ARB vp/fp, NV/ATI shader formats, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SVGA3D_SHADER_DEFS__
|
||||
#define __SVGA3D_SHADER_DEFS__
|
||||
|
||||
/* SVGA3D shader hardware limits. */
|
||||
|
||||
#define SVGA3D_INPUTREG_MAX 16
|
||||
#define SVGA3D_OUTPUTREG_MAX 12
|
||||
#define SVGA3D_VERTEX_SAMPLERREG_MAX 4
|
||||
#define SVGA3D_PIXEL_SAMPLERREG_MAX 16
|
||||
#define SVGA3D_SAMPLERREG_MAX (SVGA3D_PIXEL_SAMPLERREG_MAX+\
|
||||
SVGA3D_VERTEX_SAMPLERREG_MAX)
|
||||
#define SVGA3D_TEMPREG_MAX 32
|
||||
#define SVGA3D_CONSTREG_MAX 256
|
||||
#define SVGA3D_CONSTINTREG_MAX 16
|
||||
#define SVGA3D_CONSTBOOLREG_MAX 16
|
||||
#define SVGA3D_ADDRREG_MAX 1
|
||||
#define SVGA3D_PREDREG_MAX 1
|
||||
|
||||
/* SVGA3D byte code specific limits */
|
||||
|
||||
#define SVGA3D_MAX_SRC_REGS 4
|
||||
#define SVGA3D_MAX_NESTING_LEVEL 32
|
||||
|
||||
/* SVGA3D version information. */
|
||||
|
||||
#define SVGA3D_VS_TYPE 0xFFFE
|
||||
#define SVGA3D_PS_TYPE 0xFFFF
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32 minor : 8;
|
||||
uint32 major : 8;
|
||||
uint32 type : 16;
|
||||
};
|
||||
|
||||
uint32 value;
|
||||
};
|
||||
} SVGA3dShaderVersion;
|
||||
|
||||
#define SVGA3D_VS_10 ((SVGA3D_VS_TYPE << 16) | 1 << 8)
|
||||
#define SVGA3D_VS_11 (SVGA3D_VS_10 | 1)
|
||||
#define SVGA3D_VS_20 ((SVGA3D_VS_TYPE << 16) | 2 << 8)
|
||||
#define SVGA3D_VS_30 ((SVGA3D_VS_TYPE << 16) | 3 << 8)
|
||||
|
||||
#define SVGA3D_PS_10 ((SVGA3D_PS_TYPE << 16) | 1 << 8)
|
||||
#define SVGA3D_PS_11 (SVGA3D_PS_10 | 1)
|
||||
#define SVGA3D_PS_12 (SVGA3D_PS_10 | 2)
|
||||
#define SVGA3D_PS_13 (SVGA3D_PS_10 | 3)
|
||||
#define SVGA3D_PS_14 (SVGA3D_PS_10 | 4)
|
||||
#define SVGA3D_PS_20 ((SVGA3D_PS_TYPE << 16) | 2 << 8)
|
||||
#define SVGA3D_PS_30 ((SVGA3D_PS_TYPE << 16) | 3 << 8)
|
||||
|
||||
/* The *_ENABLED are for backwards compatibility with old drivers */
|
||||
typedef enum {
|
||||
SVGA3DPSVERSION_NONE = 0,
|
||||
SVGA3DPSVERSION_ENABLED = 1,
|
||||
SVGA3DPSVERSION_11 = 3,
|
||||
SVGA3DPSVERSION_12 = 5,
|
||||
SVGA3DPSVERSION_13 = 7,
|
||||
SVGA3DPSVERSION_14 = 9,
|
||||
SVGA3DPSVERSION_20 = 11,
|
||||
SVGA3DPSVERSION_30 = 13,
|
||||
SVGA3DPSVERSION_40 = 15,
|
||||
SVGA3DPSVERSION_MAX
|
||||
} SVGA3dPixelShaderVersion;
|
||||
|
||||
typedef enum {
|
||||
SVGA3DVSVERSION_NONE = 0,
|
||||
SVGA3DVSVERSION_ENABLED = 1,
|
||||
SVGA3DVSVERSION_11 = 3,
|
||||
SVGA3DVSVERSION_20 = 5,
|
||||
SVGA3DVSVERSION_30 = 7,
|
||||
SVGA3DVSVERSION_40 = 9,
|
||||
SVGA3DVSVERSION_MAX
|
||||
} SVGA3dVertexShaderVersion;
|
||||
|
||||
/* SVGA3D instruction op codes. */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DOP_NOP = 0,
|
||||
SVGA3DOP_MOV,
|
||||
SVGA3DOP_ADD,
|
||||
SVGA3DOP_SUB,
|
||||
SVGA3DOP_MAD,
|
||||
SVGA3DOP_MUL,
|
||||
SVGA3DOP_RCP,
|
||||
SVGA3DOP_RSQ,
|
||||
SVGA3DOP_DP3,
|
||||
SVGA3DOP_DP4,
|
||||
SVGA3DOP_MIN,
|
||||
SVGA3DOP_MAX,
|
||||
SVGA3DOP_SLT,
|
||||
SVGA3DOP_SGE,
|
||||
SVGA3DOP_EXP,
|
||||
SVGA3DOP_LOG,
|
||||
SVGA3DOP_LIT,
|
||||
SVGA3DOP_DST,
|
||||
SVGA3DOP_LRP,
|
||||
SVGA3DOP_FRC,
|
||||
SVGA3DOP_M4x4,
|
||||
SVGA3DOP_M4x3,
|
||||
SVGA3DOP_M3x4,
|
||||
SVGA3DOP_M3x3,
|
||||
SVGA3DOP_M3x2,
|
||||
SVGA3DOP_CALL,
|
||||
SVGA3DOP_CALLNZ,
|
||||
SVGA3DOP_LOOP,
|
||||
SVGA3DOP_RET,
|
||||
SVGA3DOP_ENDLOOP,
|
||||
SVGA3DOP_LABEL,
|
||||
SVGA3DOP_DCL,
|
||||
SVGA3DOP_POW,
|
||||
SVGA3DOP_CRS,
|
||||
SVGA3DOP_SGN,
|
||||
SVGA3DOP_ABS,
|
||||
SVGA3DOP_NRM,
|
||||
SVGA3DOP_SINCOS,
|
||||
SVGA3DOP_REP,
|
||||
SVGA3DOP_ENDREP,
|
||||
SVGA3DOP_IF,
|
||||
SVGA3DOP_IFC,
|
||||
SVGA3DOP_ELSE,
|
||||
SVGA3DOP_ENDIF,
|
||||
SVGA3DOP_BREAK,
|
||||
SVGA3DOP_BREAKC,
|
||||
SVGA3DOP_MOVA,
|
||||
SVGA3DOP_DEFB,
|
||||
SVGA3DOP_DEFI,
|
||||
SVGA3DOP_TEXCOORD = 64,
|
||||
SVGA3DOP_TEXKILL,
|
||||
SVGA3DOP_TEX,
|
||||
SVGA3DOP_TEXBEM,
|
||||
SVGA3DOP_TEXBEML,
|
||||
SVGA3DOP_TEXREG2AR,
|
||||
SVGA3DOP_TEXREG2GB = 70,
|
||||
SVGA3DOP_TEXM3x2PAD,
|
||||
SVGA3DOP_TEXM3x2TEX,
|
||||
SVGA3DOP_TEXM3x3PAD,
|
||||
SVGA3DOP_TEXM3x3TEX,
|
||||
SVGA3DOP_RESERVED0,
|
||||
SVGA3DOP_TEXM3x3SPEC,
|
||||
SVGA3DOP_TEXM3x3VSPEC,
|
||||
SVGA3DOP_EXPP,
|
||||
SVGA3DOP_LOGP,
|
||||
SVGA3DOP_CND = 80,
|
||||
SVGA3DOP_DEF,
|
||||
SVGA3DOP_TEXREG2RGB,
|
||||
SVGA3DOP_TEXDP3TEX,
|
||||
SVGA3DOP_TEXM3x2DEPTH,
|
||||
SVGA3DOP_TEXDP3,
|
||||
SVGA3DOP_TEXM3x3,
|
||||
SVGA3DOP_TEXDEPTH,
|
||||
SVGA3DOP_CMP,
|
||||
SVGA3DOP_BEM,
|
||||
SVGA3DOP_DP2ADD = 90,
|
||||
SVGA3DOP_DSX,
|
||||
SVGA3DOP_DSY,
|
||||
SVGA3DOP_TEXLDD,
|
||||
SVGA3DOP_SETP,
|
||||
SVGA3DOP_TEXLDL,
|
||||
SVGA3DOP_BREAKP = 96,
|
||||
SVGA3DOP_LAST_INST,
|
||||
SVGA3DOP_PHASE = 0xFFFD,
|
||||
SVGA3DOP_COMMENT = 0xFFFE,
|
||||
SVGA3DOP_END = 0xFFFF,
|
||||
} SVGA3dShaderOpCodeType;
|
||||
|
||||
/* SVGA3D operation control/comparison function types */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DOPCONT_NONE,
|
||||
SVGA3DOPCONT_PROJECT, /* Projective texturing */
|
||||
SVGA3DOPCONT_BIAS, /* Texturing with a LOD bias */
|
||||
} SVGA3dShaderOpCodeControlFnType;
|
||||
|
||||
typedef enum {
|
||||
SVGA3DOPCOMP_RESERVED0 = 0,
|
||||
SVGA3DOPCOMP_GT,
|
||||
SVGA3DOPCOMP_EQ,
|
||||
SVGA3DOPCOMP_GE,
|
||||
SVGA3DOPCOMP_LT,
|
||||
SVGA3DOPCOMPC_NE,
|
||||
SVGA3DOPCOMP_LE,
|
||||
SVGA3DOPCOMP_RESERVED1
|
||||
} SVGA3dShaderOpCodeCompFnType;
|
||||
|
||||
/* SVGA3D register types */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DREG_TEMP = 0, /* Temporary register file */
|
||||
SVGA3DREG_INPUT, /* Input register file */
|
||||
SVGA3DREG_CONST, /* Constant register file */
|
||||
SVGA3DREG_ADDR, /* Address register for VS */
|
||||
SVGA3DREG_TEXTURE = 3, /* Texture register file for PS */
|
||||
SVGA3DREG_RASTOUT, /* Rasterizer register file */
|
||||
SVGA3DREG_ATTROUT, /* Attribute output register file */
|
||||
SVGA3DREG_TEXCRDOUT, /* Texture coordinate output register file */
|
||||
SVGA3DREG_OUTPUT = 6, /* Output register file for VS 3.0+ */
|
||||
SVGA3DREG_CONSTINT, /* Constant integer vector register file */
|
||||
SVGA3DREG_COLOROUT, /* Color output register file */
|
||||
SVGA3DREG_DEPTHOUT, /* Depth output register file */
|
||||
SVGA3DREG_SAMPLER, /* Sampler state register file */
|
||||
SVGA3DREG_CONST2, /* Constant register file 2048 - 4095 */
|
||||
SVGA3DREG_CONST3, /* Constant register file 4096 - 6143 */
|
||||
SVGA3DREG_CONST4, /* Constant register file 6144 - 8191 */
|
||||
SVGA3DREG_CONSTBOOL, /* Constant boolean register file */
|
||||
SVGA3DREG_LOOP, /* Loop counter register file */
|
||||
SVGA3DREG_TEMPFLOAT16, /* 16-bit float temp register file */
|
||||
SVGA3DREG_MISCTYPE, /* Miscellaneous (single) registers */
|
||||
SVGA3DREG_LABEL, /* Label */
|
||||
SVGA3DREG_PREDICATE, /* Predicate register */
|
||||
} SVGA3dShaderRegType;
|
||||
|
||||
/* SVGA3D rasterizer output register types */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DRASTOUT_POSITION = 0,
|
||||
SVGA3DRASTOUT_FOG,
|
||||
SVGA3DRASTOUT_PSIZE
|
||||
} SVGA3dShaderRastOutRegType;
|
||||
|
||||
/* SVGA3D miscellaneous register types */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DMISCREG_POSITION = 0, /* Input position x,y,z,rhw (PS) */
|
||||
SVGA3DMISCREG_FACE /* Floating point primitive area (PS) */
|
||||
} SVGA3DShaderMiscRegType;
|
||||
|
||||
/* SVGA3D sampler types */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DSAMP_UNKNOWN = 0, /* Uninitialized value */
|
||||
SVGA3DSAMP_2D = 2, /* dcl_2d s# (for declaring a 2-D texture) */
|
||||
SVGA3DSAMP_CUBE, /* dcl_cube s# (for declaring a cube texture) */
|
||||
SVGA3DSAMP_VOLUME, /* dcl_volume s# (for declaring a volume texture) */
|
||||
} SVGA3dShaderSamplerType;
|
||||
|
||||
/* SVGA3D sampler format classes */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DSAMPFORMAT_ARGB, /* ARGB formats */
|
||||
SVGA3DSAMPFORMAT_V8U8, /* Sign and normalize (SNORM) V & U */
|
||||
SVGA3DSAMPFORMAT_Q8W8V8U8, /* SNORM all */
|
||||
SVGA3DSAMPFORMAT_CxV8U8, /* SNORM V & U, C=SQRT(1-U^2-V^2) */
|
||||
SVGA3DSAMPFORMAT_X8L8V8U8, /* SNORM V & U */
|
||||
SVGA3DSAMPFORMAT_A2W10V10U10, /* SNORM W, V & U */
|
||||
SVGA3DSAMPFORMAT_DXT_PMA, /* DXT pre-multiplied alpha */
|
||||
SVGA3DSAMPFORMAT_YUV, /* YUV video format */
|
||||
SVGA3DSAMPFORMAT_UYVY, /* UYVY video format */
|
||||
SVGA3DSAMPFORMAT_Rx, /* R16F/32F */
|
||||
SVGA3DSAMPFORMAT_RxGx, /* R16FG16F, R32FG32F */
|
||||
SVGA3DSAMPFORMAT_V16U16, /* SNORM all */
|
||||
} SVGA3DShaderSamplerFormatClass;
|
||||
|
||||
/* SVGA3D write mask */
|
||||
|
||||
#define SVGA3DWRITEMASK_0 1 /* Component 0 (X;Red) */
|
||||
#define SVGA3DWRITEMASK_1 2 /* Component 1 (Y;Green) */
|
||||
#define SVGA3DWRITEMASK_2 4 /* Component 2 (Z;Blue) */
|
||||
#define SVGA3DWRITEMASK_3 8 /* Component 3 (W;Alpha) */
|
||||
#define SVGA3DWRITEMASK_ALL 15 /* All components */
|
||||
|
||||
/* SVGA3D destination modifiers */
|
||||
|
||||
#define SVGA3DDSTMOD_NONE 0 /* nop */
|
||||
#define SVGA3DDSTMOD_SATURATE 1 /* clamp to [0, 1] */
|
||||
#define SVGA3DDSTMOD_PARTIALPRECISION 2 /* Partial precision hint */
|
||||
|
||||
/*
|
||||
* Relevant to multisampling only:
|
||||
* When the pixel center is not covered, sample
|
||||
* attribute or compute gradients/LOD
|
||||
* using multisample "centroid" location.
|
||||
* "Centroid" is some location within the covered
|
||||
* region of the pixel.
|
||||
*/
|
||||
|
||||
#define SVGA3DDSTMOD_MSAMPCENTROID 4
|
||||
|
||||
/* SVGA3D source swizzle */
|
||||
|
||||
#define SVGA3DSWIZZLE_REPLICATEX 0x00
|
||||
#define SVGA3DSWIZZLE_REPLICATEY 0x55
|
||||
#define SVGA3DSWIZZLE_REPLICATEZ 0xAA
|
||||
#define SVGA3DSWIZZLE_REPLICATEW 0xFF
|
||||
#define SVGA3DSWIZZLE_NONE 0xE4
|
||||
#define SVGA3DSWIZZLE_YZXW 0xC9
|
||||
#define SVGA3DSWIZZLE_ZXYW 0xD2
|
||||
#define SVGA3DSWIZZLE_WXYZ 0x1B
|
||||
|
||||
/* SVGA3D source modifiers */
|
||||
|
||||
typedef enum {
|
||||
SVGA3DSRCMOD_NONE = 0, /* nop */
|
||||
SVGA3DSRCMOD_NEG, /* negate */
|
||||
SVGA3DSRCMOD_BIAS, /* bias */
|
||||
SVGA3DSRCMOD_BIASNEG, /* bias and negate */
|
||||
SVGA3DSRCMOD_SIGN, /* sign */
|
||||
SVGA3DSRCMOD_SIGNNEG, /* sign and negate */
|
||||
SVGA3DSRCMOD_COMP, /* complement */
|
||||
SVGA3DSRCMOD_X2, /* x2 */
|
||||
SVGA3DSRCMOD_X2NEG, /* x2 and negate */
|
||||
SVGA3DSRCMOD_DZ, /* divide through by z component */
|
||||
SVGA3DSRCMOD_DW, /* divide through by w component */
|
||||
SVGA3DSRCMOD_ABS, /* abs() */
|
||||
SVGA3DSRCMOD_ABSNEG, /* -abs() */
|
||||
SVGA3DSRCMOD_NOT, /* ! (for predicate register) */
|
||||
} SVGA3dShaderSrcModType;
|
||||
|
||||
/* SVGA3D instruction token */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32 comment_op : 16;
|
||||
uint32 comment_size : 16;
|
||||
};
|
||||
|
||||
struct {
|
||||
uint32 op : 16;
|
||||
uint32 control : 3;
|
||||
uint32 reserved2 : 5;
|
||||
uint32 size : 4;
|
||||
uint32 predicated : 1;
|
||||
uint32 reserved1 : 1;
|
||||
uint32 coissue : 1;
|
||||
uint32 reserved0 : 1;
|
||||
};
|
||||
|
||||
uint32 value;
|
||||
};
|
||||
} SVGA3dShaderInstToken;
|
||||
|
||||
/* SVGA3D destination parameter token */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32 num : 11;
|
||||
uint32 type_upper : 2;
|
||||
uint32 relAddr : 1;
|
||||
uint32 reserved1 : 2;
|
||||
uint32 mask : 4;
|
||||
uint32 dstMod : 4;
|
||||
uint32 shfScale : 4;
|
||||
uint32 type_lower : 3;
|
||||
uint32 reserved0 : 1;
|
||||
};
|
||||
|
||||
uint32 value;
|
||||
};
|
||||
} SVGA3dShaderDestToken;
|
||||
|
||||
/* SVGA3D source parameter token */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32 num : 11;
|
||||
uint32 type_upper : 2;
|
||||
uint32 relAddr : 1;
|
||||
uint32 reserved1 : 2;
|
||||
uint32 swizzle : 8;
|
||||
uint32 srcMod : 4;
|
||||
uint32 type_lower : 3;
|
||||
uint32 reserved0 : 1;
|
||||
};
|
||||
|
||||
uint32 value;
|
||||
};
|
||||
} SVGA3dShaderSrcToken;
|
||||
|
||||
/* SVGA3DOP_DCL parameter tokens */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
uint32 usage : 5;
|
||||
uint32 reserved1 : 11;
|
||||
uint32 index : 4;
|
||||
uint32 reserved0 : 12;
|
||||
}; /* input / output declaration */
|
||||
|
||||
struct {
|
||||
uint32 reserved3 : 27;
|
||||
uint32 type : 4;
|
||||
uint32 reserved2 : 1;
|
||||
}; /* sampler declaration */
|
||||
};
|
||||
|
||||
SVGA3dShaderDestToken dst;
|
||||
};
|
||||
|
||||
uint32 values[2];
|
||||
};
|
||||
} SVGA3DOpDclArgs;
|
||||
|
||||
/* SVGA3DOP_DEF parameter tokens */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
SVGA3dShaderDestToken dst;
|
||||
|
||||
union {
|
||||
float constValues[4];
|
||||
int constIValues[4];
|
||||
Bool constBValue;
|
||||
};
|
||||
};
|
||||
|
||||
uint32 values[5];
|
||||
};
|
||||
} SVGA3DOpDefArgs;
|
||||
|
||||
/* SVGA3D shader token */
|
||||
|
||||
typedef union {
|
||||
uint32 value;
|
||||
SVGA3dShaderInstToken inst;
|
||||
SVGA3dShaderDestToken dest;
|
||||
SVGA3dShaderSrcToken src;
|
||||
} SVGA3dShaderToken;
|
||||
|
||||
/* SVGA3D shader program */
|
||||
|
||||
typedef struct {
|
||||
SVGA3dShaderVersion version;
|
||||
/* SVGA3dShaderToken stream */
|
||||
} SVGA3dShaderProgram;
|
||||
|
||||
/* SVGA3D version specific register assignments */
|
||||
|
||||
static const uint32 SVGA3D_INPUT_REG_POSITION_VS11 = 0;
|
||||
static const uint32 SVGA3D_INPUT_REG_PSIZE_VS11 = 1;
|
||||
static const uint32 SVGA3D_INPUT_REG_FOG_VS11 = 3;
|
||||
static const uint32 SVGA3D_INPUT_REG_FOG_MASK_VS11 = SVGA3DWRITEMASK_3;
|
||||
static const uint32 SVGA3D_INPUT_REG_COLOR_BASE_VS11 = 2;
|
||||
static const uint32 SVGA3D_INPUT_REG_TEXCOORD_BASE_VS11 = 4;
|
||||
|
||||
static const uint32 SVGA3D_INPUT_REG_COLOR_BASE_PS11 = 0;
|
||||
static const uint32 SVGA3D_INPUT_REG_TEXCOORD_BASE_PS11 = 2;
|
||||
static const uint32 SVGA3D_OUTPUT_REG_DEPTH_PS11 = 0;
|
||||
static const uint32 SVGA3D_OUTPUT_REG_COLOR_PS11 = 1;
|
||||
|
||||
static const uint32 SVGA3D_INPUT_REG_COLOR_BASE_PS20 = 0;
|
||||
static const uint32 SVGA3D_INPUT_REG_COLOR_NUM_PS20 = 2;
|
||||
static const uint32 SVGA3D_INPUT_REG_TEXCOORD_BASE_PS20 = 2;
|
||||
static const uint32 SVGA3D_INPUT_REG_TEXCOORD_NUM_PS20 = 8;
|
||||
static const uint32 SVGA3D_OUTPUT_REG_COLOR_BASE_PS20 = 1;
|
||||
static const uint32 SVGA3D_OUTPUT_REG_COLOR_NUM_PS20 = 4;
|
||||
static const uint32 SVGA3D_OUTPUT_REG_DEPTH_BASE_PS20 = 0;
|
||||
static const uint32 SVGA3D_OUTPUT_REG_DEPTH_NUM_PS20 = 1;
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* SVGA3dShaderGetRegType --
|
||||
*
|
||||
* As the register type is split into two non sequential fields,
|
||||
* this function provides an useful way of accessing the actual
|
||||
* register type without having to manually concatenate the
|
||||
* type_upper and type_lower fields.
|
||||
*
|
||||
* Results:
|
||||
* Returns the register type.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static INLINE SVGA3dShaderRegType
|
||||
SVGA3dShaderGetRegType(uint32 token)
|
||||
{
|
||||
SVGA3dShaderSrcToken src;
|
||||
src.value = token;
|
||||
return (SVGA3dShaderRegType)(src.type_upper << 3 | src.type_lower);
|
||||
}
|
||||
|
||||
#endif /* __SVGA3D_SHADER_DEFS__ */
|
||||
1346
src/gallium/drivers/svga/include/svga_reg.h
Normal file
1346
src/gallium/drivers/svga/include/svga_reg.h
Normal file
File diff suppressed because it is too large
Load diff
46
src/gallium/drivers/svga/include/svga_types.h
Normal file
46
src/gallium/drivers/svga/include/svga_types.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**********************************************************
|
||||
* Copyright 1998-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef _SVGA_TYPES_H_
|
||||
#define _SVGA_TYPES_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
typedef int64_t int64;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
typedef int32_t int32;
|
||||
typedef uint32_t uint32;
|
||||
|
||||
typedef int16_t int16;
|
||||
typedef uint16_t uint16;
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef uint8_t uint8;
|
||||
|
||||
typedef uint8_t Bool;
|
||||
|
||||
#endif /* _SVGA_TYPES_H_ */
|
||||
|
||||
1427
src/gallium/drivers/svga/svga_cmd.c
Normal file
1427
src/gallium/drivers/svga/svga_cmd.c
Normal file
File diff suppressed because it is too large
Load diff
235
src/gallium/drivers/svga/svga_cmd.h
Normal file
235
src/gallium/drivers/svga/svga_cmd.h
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/*
|
||||
* svga_cmd.h --
|
||||
*
|
||||
* Command construction utility for the SVGA3D protocol used by
|
||||
* the VMware SVGA device, based on the svgautil library.
|
||||
*/
|
||||
|
||||
#ifndef __SVGA3D_H__
|
||||
#define __SVGA3D_H__
|
||||
|
||||
|
||||
#include "svga_types.h"
|
||||
#include "svga_reg.h"
|
||||
#include "svga3d_reg.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
struct pipe_buffer;
|
||||
struct pipe_surface;
|
||||
struct svga_transfer;
|
||||
struct svga_winsys_context;
|
||||
struct svga_winsys_buffer;
|
||||
struct svga_winsys_surface;
|
||||
|
||||
|
||||
/*
|
||||
* SVGA Device Interoperability
|
||||
*/
|
||||
|
||||
void *
|
||||
SVGA3D_FIFOReserve(struct svga_winsys_context *swc, uint32 cmd, uint32 cmdSize, uint32 nr_relocs);
|
||||
|
||||
void
|
||||
SVGA_FIFOCommitAll(struct svga_winsys_context *swc);
|
||||
|
||||
|
||||
/*
|
||||
* Context Management
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DefineContext(struct svga_winsys_context *swc);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DestroyContext(struct svga_winsys_context *swc);
|
||||
|
||||
|
||||
/*
|
||||
* Surface Management
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_surface *sid,
|
||||
SVGA3dSurfaceFlags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
SVGA3dSurfaceFace **faces,
|
||||
SVGA3dSize **mipSizes,
|
||||
uint32 numMipSizes);
|
||||
enum pipe_error
|
||||
SVGA3D_DefineSurface2D(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_surface *sid,
|
||||
uint32 width,
|
||||
uint32 height,
|
||||
SVGA3dSurfaceFormat format);
|
||||
enum pipe_error
|
||||
SVGA3D_DestroySurface(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_surface *sid);
|
||||
|
||||
|
||||
/*
|
||||
* Surface Operations
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
|
||||
struct svga_transfer *st,
|
||||
SVGA3dTransferType transfer,
|
||||
const SVGA3dCopyBox *boxes,
|
||||
uint32 numBoxes);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BufferDMA(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_buffer *guest,
|
||||
struct svga_winsys_surface *host,
|
||||
SVGA3dTransferType transfer,
|
||||
uint32 size,
|
||||
uint32 offset,
|
||||
SVGA3dSurfaceDMAFlags flags);
|
||||
|
||||
/*
|
||||
* Drawing Operations
|
||||
*/
|
||||
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginClear(struct svga_winsys_context *swc,
|
||||
SVGA3dClearFlag flags,
|
||||
uint32 color, float depth, uint32 stencil,
|
||||
SVGA3dRect **rects, uint32 numRects);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_ClearRect(struct svga_winsys_context *swc,
|
||||
SVGA3dClearFlag flags, uint32 color, float depth,
|
||||
uint32 stencil, uint32 x, uint32 y, uint32 w, uint32 h);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
|
||||
SVGA3dVertexDecl **decls,
|
||||
uint32 numVertexDecls,
|
||||
SVGA3dPrimitiveRange **ranges,
|
||||
uint32 numRanges);
|
||||
|
||||
/*
|
||||
* Blits
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
|
||||
struct pipe_surface *src,
|
||||
struct pipe_surface *dest,
|
||||
SVGA3dCopyBox **boxes, uint32 numBoxes);
|
||||
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
|
||||
struct pipe_surface *src,
|
||||
struct pipe_surface *dest,
|
||||
SVGA3dBox *boxSrc, SVGA3dBox *boxDest,
|
||||
SVGA3dStretchBltMode mode);
|
||||
|
||||
/*
|
||||
* Shared FFP/Shader Render State
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
|
||||
SVGA3dRenderTargetType type,
|
||||
struct pipe_surface *surface);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetZRange(struct svga_winsys_context *swc,
|
||||
float zMin, float zMax);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetViewport(struct svga_winsys_context *swc,
|
||||
SVGA3dRect *rect);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
|
||||
SVGA3dRect *rect);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
|
||||
uint32 index, const float *plane);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
|
||||
SVGA3dTextureState **states,
|
||||
uint32 numStates);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
|
||||
SVGA3dRenderState **states,
|
||||
uint32 numStates);
|
||||
|
||||
|
||||
/*
|
||||
* Shaders
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DefineShader(struct svga_winsys_context *swc,
|
||||
uint32 shid, SVGA3dShaderType type,
|
||||
const uint32 *bytecode, uint32 bytecodeLen);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DestroyShader(struct svga_winsys_context *swc,
|
||||
uint32 shid, SVGA3dShaderType type);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
|
||||
uint32 reg, SVGA3dShaderType type,
|
||||
SVGA3dShaderConstType ctype, const void *value);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_SetShader(struct svga_winsys_context *swc,
|
||||
SVGA3dShaderType type, uint32 shid);
|
||||
|
||||
|
||||
/*
|
||||
* Queries
|
||||
*/
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BeginQuery(struct svga_winsys_context *swc,
|
||||
SVGA3dQueryType type);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_EndQuery(struct svga_winsys_context *swc,
|
||||
SVGA3dQueryType type,
|
||||
struct svga_winsys_buffer *buffer);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
|
||||
SVGA3dQueryType type,
|
||||
struct svga_winsys_buffer *buffer);
|
||||
|
||||
#endif /* __SVGA3D_H__ */
|
||||
269
src/gallium/drivers/svga/svga_context.c
Normal file
269
src/gallium/drivers/svga/svga_context.c
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_swtnl.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_debug.h"
|
||||
#include "svga_state.h"
|
||||
|
||||
|
||||
static void svga_destroy( struct pipe_context *pipe )
|
||||
{
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
unsigned shader;
|
||||
|
||||
svga_cleanup_framebuffer( svga );
|
||||
svga_cleanup_tss_binding( svga );
|
||||
|
||||
svga_hwtnl_destroy( svga->hwtnl );
|
||||
|
||||
svga_cleanup_vertex_state(svga);
|
||||
|
||||
svga->swc->destroy(svga->swc);
|
||||
|
||||
svga_destroy_swtnl( svga );
|
||||
|
||||
u_upload_destroy( svga->upload_vb );
|
||||
u_upload_destroy( svga->upload_ib );
|
||||
|
||||
for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader)
|
||||
pipe_buffer_reference( &svga->curr.cb[shader], NULL );
|
||||
|
||||
FREE( svga );
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
svga_is_texture_referenced( struct pipe_context *pipe,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level)
|
||||
{
|
||||
struct svga_texture *tex = svga_texture(texture);
|
||||
struct svga_screen *ss = svga_screen(pipe->screen);
|
||||
|
||||
/**
|
||||
* The screen does not cache texture writes.
|
||||
*/
|
||||
|
||||
if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
|
||||
return PIPE_UNREFERENCED;
|
||||
|
||||
/**
|
||||
* sws->surface_is_flushed() does not distinguish between read references
|
||||
* and write references. So assume a reference is both.
|
||||
*/
|
||||
|
||||
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
svga_is_buffer_referenced( struct pipe_context *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(pipe->screen);
|
||||
struct svga_buffer *sbuf = svga_buffer(buf);
|
||||
|
||||
/**
|
||||
* XXX: Check this.
|
||||
* The screen may cache buffer writes, but when we map, we map out
|
||||
* of those cached writes, so we don't need to set a
|
||||
* PIPE_REFERENCED_FOR_WRITE flag for cached buffers.
|
||||
*/
|
||||
|
||||
if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle))
|
||||
return PIPE_UNREFERENCED;
|
||||
|
||||
/**
|
||||
* sws->surface_is_flushed() does not distinguish between read references
|
||||
* and write references. So assume a reference is both,
|
||||
* however, we make an exception for index- and vertex buffers, to avoid
|
||||
* a flush in st_bufferobj_get_subdata, during display list replay.
|
||||
*/
|
||||
|
||||
if (sbuf->base.usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX))
|
||||
return PIPE_REFERENCED_FOR_READ;
|
||||
|
||||
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
|
||||
}
|
||||
|
||||
|
||||
struct pipe_context *svga_context_create( struct pipe_screen *screen )
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(screen);
|
||||
struct svga_context *svga = NULL;
|
||||
enum pipe_error ret;
|
||||
|
||||
svga = CALLOC_STRUCT(svga_context);
|
||||
if (svga == NULL)
|
||||
goto error1;
|
||||
|
||||
svga->pipe.winsys = screen->winsys;
|
||||
svga->pipe.screen = screen;
|
||||
svga->pipe.destroy = svga_destroy;
|
||||
svga->pipe.clear = svga_clear;
|
||||
|
||||
svga->pipe.is_texture_referenced = svga_is_texture_referenced;
|
||||
svga->pipe.is_buffer_referenced = svga_is_buffer_referenced;
|
||||
|
||||
svga->swc = svgascreen->sws->context_create(svgascreen->sws);
|
||||
if(!svga->swc)
|
||||
goto error2;
|
||||
|
||||
svga_init_blend_functions(svga);
|
||||
svga_init_blit_functions(svga);
|
||||
svga_init_depth_stencil_functions(svga);
|
||||
svga_init_draw_functions(svga);
|
||||
svga_init_flush_functions(svga);
|
||||
svga_init_misc_functions(svga);
|
||||
svga_init_rasterizer_functions(svga);
|
||||
svga_init_sampler_functions(svga);
|
||||
svga_init_fs_functions(svga);
|
||||
svga_init_vs_functions(svga);
|
||||
svga_init_vertex_functions(svga);
|
||||
svga_init_constbuffer_functions(svga);
|
||||
svga_init_query_functions(svga);
|
||||
|
||||
/* debug */
|
||||
svga->debug.no_swtnl = debug_get_bool_option("SVGA_NO_SWTNL", FALSE);
|
||||
svga->debug.force_swtnl = debug_get_bool_option("SVGA_FORCE_SWTNL", FALSE);
|
||||
svga->debug.use_min_mipmap = debug_get_bool_option("SVGA_USE_MIN_MIPMAP", FALSE);
|
||||
svga->debug.disable_shader = debug_get_num_option("SVGA_DISABLE_SHADER", ~0);
|
||||
|
||||
if (!svga_init_swtnl(svga))
|
||||
goto error3;
|
||||
|
||||
svga->upload_ib = u_upload_create( svga->pipe.screen,
|
||||
32 * 1024,
|
||||
16,
|
||||
PIPE_BUFFER_USAGE_INDEX );
|
||||
if (svga->upload_ib == NULL)
|
||||
goto error4;
|
||||
|
||||
svga->upload_vb = u_upload_create( svga->pipe.screen,
|
||||
128 * 1024,
|
||||
16,
|
||||
PIPE_BUFFER_USAGE_VERTEX );
|
||||
if (svga->upload_vb == NULL)
|
||||
goto error5;
|
||||
|
||||
svga->hwtnl = svga_hwtnl_create( svga,
|
||||
svga->upload_ib,
|
||||
svga->swc );
|
||||
if (svga->hwtnl == NULL)
|
||||
goto error6;
|
||||
|
||||
|
||||
ret = svga_emit_initial_state( svga );
|
||||
if (ret)
|
||||
goto error7;
|
||||
|
||||
/* Avoid shortcircuiting state with initial value of zero.
|
||||
*/
|
||||
memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
|
||||
memset(&svga->state.hw_clear.framebuffer, 0x0,
|
||||
sizeof(svga->state.hw_clear.framebuffer));
|
||||
|
||||
memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
|
||||
memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
|
||||
svga->state.hw_draw.num_views = 0;
|
||||
|
||||
svga->dirty = ~0;
|
||||
svga->state.white_fs_id = SVGA3D_INVALID_ID;
|
||||
|
||||
LIST_INITHEAD(&svga->dirty_buffers);
|
||||
|
||||
return &svga->pipe;
|
||||
|
||||
error7:
|
||||
svga_hwtnl_destroy( svga->hwtnl );
|
||||
error6:
|
||||
u_upload_destroy( svga->upload_vb );
|
||||
error5:
|
||||
u_upload_destroy( svga->upload_ib );
|
||||
error4:
|
||||
svga_destroy_swtnl(svga);
|
||||
error3:
|
||||
svga->swc->destroy(svga->swc);
|
||||
error2:
|
||||
FREE(svga);
|
||||
error1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void svga_context_flush( struct svga_context *svga,
|
||||
struct pipe_fence_handle **pfence )
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
|
||||
|
||||
/* Unmap upload manager buffers:
|
||||
*/
|
||||
u_upload_flush(svga->upload_vb);
|
||||
u_upload_flush(svga->upload_ib);
|
||||
|
||||
/* Flush screen, to ensure that texture dma uploads are processed
|
||||
* before submitting commands.
|
||||
*/
|
||||
svga_screen_flush(svgascreen, NULL);
|
||||
|
||||
svga_context_flush_buffers(svga);
|
||||
|
||||
/* Flush pending commands to hardware:
|
||||
*/
|
||||
svga->swc->flush(svga->swc, pfence);
|
||||
|
||||
if (SVGA_DEBUG & DEBUG_SYNC) {
|
||||
if (pfence && *pfence)
|
||||
svga->pipe.screen->fence_finish( svga->pipe.screen, *pfence, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void svga_hwtnl_flush_retry( struct svga_context *svga )
|
||||
{
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
|
||||
ret = svga_hwtnl_flush( svga->hwtnl );
|
||||
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
|
||||
svga_context_flush( svga, NULL );
|
||||
ret = svga_hwtnl_flush( svga->hwtnl );
|
||||
}
|
||||
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
443
src/gallium/drivers/svga/svga_context.h
Normal file
443
src/gallium/drivers/svga/svga_context.h
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_CONTEXT_H
|
||||
#define SVGA_CONTEXT_H
|
||||
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "util/u_double_list.h"
|
||||
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
|
||||
#define SVGA_TEX_UNITS 8
|
||||
|
||||
struct draw_vertex_shader;
|
||||
struct svga_shader_result;
|
||||
struct SVGACmdMemory;
|
||||
struct u_upload_mgr;
|
||||
|
||||
|
||||
struct svga_shader
|
||||
{
|
||||
const struct tgsi_token *tokens;
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
struct svga_shader_result *results;
|
||||
|
||||
unsigned id;
|
||||
|
||||
boolean use_sm30;
|
||||
};
|
||||
|
||||
struct svga_fragment_shader
|
||||
{
|
||||
struct svga_shader base;
|
||||
};
|
||||
|
||||
struct svga_vertex_shader
|
||||
{
|
||||
struct svga_shader base;
|
||||
|
||||
struct draw_vertex_shader *draw_shader;
|
||||
};
|
||||
|
||||
|
||||
struct svga_cache_context;
|
||||
struct svga_tracked_state;
|
||||
|
||||
struct svga_blend_state {
|
||||
|
||||
boolean need_white_fragments;
|
||||
|
||||
/* Should be per-render-target:
|
||||
*/
|
||||
struct {
|
||||
uint8_t writemask;
|
||||
|
||||
boolean blend_enable;
|
||||
uint8_t srcblend;
|
||||
uint8_t dstblend;
|
||||
uint8_t blendeq;
|
||||
|
||||
boolean separate_alpha_blend_enable;
|
||||
uint8_t srcblend_alpha;
|
||||
uint8_t dstblend_alpha;
|
||||
uint8_t blendeq_alpha;
|
||||
|
||||
} rt[1];
|
||||
};
|
||||
|
||||
struct svga_depth_stencil_state {
|
||||
unsigned zfunc:8;
|
||||
unsigned zenable:1;
|
||||
unsigned zwriteenable:1;
|
||||
|
||||
unsigned alphatestenable:1;
|
||||
unsigned alphafunc:8;
|
||||
|
||||
struct {
|
||||
unsigned enabled:1;
|
||||
unsigned func:8;
|
||||
unsigned fail:8;
|
||||
unsigned zfail:8;
|
||||
unsigned pass:8;
|
||||
} stencil[2];
|
||||
|
||||
/* SVGA3D has one ref/mask/writemask triple shared between front &
|
||||
* back face stencil. We really need two:
|
||||
*/
|
||||
unsigned stencil_ref:8;
|
||||
unsigned stencil_mask:8;
|
||||
unsigned stencil_writemask:8;
|
||||
|
||||
float alpharef;
|
||||
};
|
||||
|
||||
#define SVGA_UNFILLED_DISABLE 0
|
||||
#define SVGA_UNFILLED_LINE 1
|
||||
#define SVGA_UNFILLED_POINT 2
|
||||
|
||||
#define SVGA_PIPELINE_FLAG_POINTS (1<<PIPE_PRIM_POINTS)
|
||||
#define SVGA_PIPELINE_FLAG_LINES (1<<PIPE_PRIM_LINES)
|
||||
#define SVGA_PIPELINE_FLAG_TRIS (1<<PIPE_PRIM_TRIANGLES)
|
||||
|
||||
struct svga_rasterizer_state {
|
||||
struct pipe_rasterizer_state templ; /* needed for draw module */
|
||||
|
||||
unsigned shademode:8;
|
||||
unsigned cullmode:8;
|
||||
unsigned scissortestenable:1;
|
||||
unsigned multisampleantialias:1;
|
||||
unsigned antialiasedlineenable:1;
|
||||
unsigned lastpixel:1;
|
||||
|
||||
unsigned linepattern;
|
||||
|
||||
float slopescaledepthbias;
|
||||
float depthbias;
|
||||
float pointsize;
|
||||
float pointsize_min;
|
||||
float pointsize_max;
|
||||
|
||||
unsigned hw_unfilled:16; /* PIPE_POLYGON_MODE_x */
|
||||
unsigned need_pipeline:16; /* which prims do we need help for? */
|
||||
};
|
||||
|
||||
struct svga_sampler_state {
|
||||
unsigned mipfilter;
|
||||
unsigned magfilter;
|
||||
unsigned minfilter;
|
||||
unsigned aniso_level;
|
||||
float lod_bias;
|
||||
unsigned addressu;
|
||||
unsigned addressv;
|
||||
unsigned addressw;
|
||||
unsigned bordercolor;
|
||||
unsigned normalized_coords:1;
|
||||
unsigned compare_mode:1;
|
||||
unsigned compare_func:3;
|
||||
|
||||
unsigned min_lod;
|
||||
unsigned view_min_lod;
|
||||
unsigned view_max_lod;
|
||||
};
|
||||
|
||||
/* Use to calculate differences between state emitted to hardware and
|
||||
* current driver-calculated state.
|
||||
*/
|
||||
struct svga_state
|
||||
{
|
||||
const struct svga_blend_state *blend;
|
||||
const struct svga_depth_stencil_state *depth;
|
||||
const struct svga_rasterizer_state *rast;
|
||||
const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];
|
||||
|
||||
struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
|
||||
struct svga_fragment_shader *fs;
|
||||
struct svga_vertex_shader *vs;
|
||||
|
||||
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_buffer *cb[PIPE_SHADER_TYPES];
|
||||
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
float depthscale;
|
||||
|
||||
struct pipe_poly_stipple poly_stipple;
|
||||
struct pipe_scissor_state scissor;
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_clip_state clip;
|
||||
struct pipe_viewport_state viewport;
|
||||
|
||||
const unsigned *edgeflags;
|
||||
|
||||
unsigned num_samplers;
|
||||
unsigned num_textures;
|
||||
unsigned num_vertex_elements;
|
||||
unsigned num_vertex_buffers;
|
||||
unsigned reduced_prim;
|
||||
|
||||
struct {
|
||||
unsigned flag_1d;
|
||||
unsigned flag_srgb;
|
||||
} tex_flags;
|
||||
|
||||
boolean any_user_vertex_buffers;
|
||||
|
||||
unsigned zero_stride_vertex_elements;
|
||||
unsigned num_zero_stride_vertex_elements;
|
||||
/* ### maybe dynamically allocate this */
|
||||
float zero_stride_constants[PIPE_MAX_ATTRIBS*4];
|
||||
};
|
||||
|
||||
#define RS_MAX 97
|
||||
#define TS_MAX 30
|
||||
#define CB_MAX 256
|
||||
|
||||
struct svga_prescale {
|
||||
float translate[4];
|
||||
float scale[4];
|
||||
boolean enabled;
|
||||
};
|
||||
|
||||
|
||||
/* Updated by calling svga_update_state( SVGA_STATE_HW_VIEWPORT )
|
||||
*/
|
||||
struct svga_hw_clear_state
|
||||
{
|
||||
struct {
|
||||
unsigned x,y,w,h;
|
||||
} viewport;
|
||||
|
||||
struct {
|
||||
float zmin, zmax;
|
||||
} depthrange;
|
||||
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct svga_prescale prescale;
|
||||
};
|
||||
|
||||
struct svga_hw_view_state
|
||||
{
|
||||
struct pipe_texture *texture;
|
||||
struct svga_sampler_view *v;
|
||||
unsigned min_lod;
|
||||
unsigned max_lod;
|
||||
int dirty;
|
||||
};
|
||||
|
||||
/* Updated by calling svga_update_state( SVGA_STATE_HW_DRAW )
|
||||
*/
|
||||
struct svga_hw_draw_state
|
||||
{
|
||||
unsigned rs[RS_MAX];
|
||||
unsigned ts[16][TS_MAX];
|
||||
float cb[PIPE_SHADER_TYPES][CB_MAX][4];
|
||||
|
||||
unsigned shader_id[PIPE_SHADER_TYPES];
|
||||
|
||||
struct svga_shader_result *fs;
|
||||
struct svga_shader_result *vs;
|
||||
struct svga_hw_view_state views[PIPE_MAX_SAMPLERS];
|
||||
|
||||
unsigned num_views;
|
||||
};
|
||||
|
||||
|
||||
/* Updated by calling svga_update_state( SVGA_STATE_NEED_SWTNL )
|
||||
*/
|
||||
struct svga_sw_state
|
||||
{
|
||||
unsigned ve_format[PIPE_MAX_ATTRIBS]; /* NEW_VELEMENT */
|
||||
|
||||
/* which parts we need */
|
||||
boolean need_swvfetch;
|
||||
boolean need_pipeline;
|
||||
boolean need_swtnl;
|
||||
};
|
||||
|
||||
|
||||
/* Queue some state updates (like rss) and submit them to hardware in
|
||||
* a single packet.
|
||||
*/
|
||||
struct svga_hw_queue;
|
||||
|
||||
struct svga_query;
|
||||
|
||||
struct svga_context
|
||||
{
|
||||
struct pipe_context pipe;
|
||||
struct svga_winsys_context *swc;
|
||||
|
||||
struct {
|
||||
boolean no_swtnl;
|
||||
boolean force_swtnl;
|
||||
boolean use_min_mipmap;
|
||||
|
||||
/* incremented for each shader */
|
||||
unsigned shader_id;
|
||||
|
||||
unsigned disable_shader;
|
||||
} debug;
|
||||
|
||||
struct {
|
||||
struct draw_context *draw;
|
||||
struct vbuf_render *backend;
|
||||
unsigned hw_prim;
|
||||
boolean new_vbuf;
|
||||
boolean new_vdecl;
|
||||
} swtnl;
|
||||
|
||||
struct {
|
||||
unsigned dirty[4];
|
||||
|
||||
unsigned texture_timestamp;
|
||||
unsigned next_fs_id;
|
||||
unsigned next_vs_id;
|
||||
|
||||
/* Internally generated shaders:
|
||||
*/
|
||||
unsigned white_fs_id;
|
||||
|
||||
/*
|
||||
*/
|
||||
struct svga_sw_state sw;
|
||||
struct svga_hw_draw_state hw_draw;
|
||||
struct svga_hw_clear_state hw_clear;
|
||||
} state;
|
||||
|
||||
struct svga_state curr; /* state from the state tracker */
|
||||
unsigned dirty; /* statechanges since last update_state() */
|
||||
|
||||
struct u_upload_mgr *upload_ib;
|
||||
struct u_upload_mgr *upload_vb;
|
||||
struct svga_hwtnl *hwtnl;
|
||||
|
||||
/** The occlusion query currently in progress */
|
||||
struct svga_query *sq;
|
||||
|
||||
/** List of buffers with queued transfers */
|
||||
struct list_head dirty_buffers;
|
||||
};
|
||||
|
||||
/* A flag for each state_tracker state object:
|
||||
*/
|
||||
#define SVGA_NEW_BLEND 0x1
|
||||
#define SVGA_NEW_DEPTH_STENCIL 0x2
|
||||
#define SVGA_NEW_RAST 0x4
|
||||
#define SVGA_NEW_SAMPLER 0x8
|
||||
#define SVGA_NEW_TEXTURE 0x10
|
||||
#define SVGA_NEW_VBUFFER 0x20
|
||||
#define SVGA_NEW_VELEMENT 0x40
|
||||
#define SVGA_NEW_FS 0x80
|
||||
#define SVGA_NEW_VS 0x100
|
||||
#define SVGA_NEW_FS_CONST_BUFFER 0x200
|
||||
#define SVGA_NEW_VS_CONST_BUFFER 0x400
|
||||
#define SVGA_NEW_FRAME_BUFFER 0x800
|
||||
#define SVGA_NEW_STIPPLE 0x1000
|
||||
#define SVGA_NEW_SCISSOR 0x2000
|
||||
#define SVGA_NEW_BLEND_COLOR 0x5000
|
||||
#define SVGA_NEW_CLIP 0x8000
|
||||
#define SVGA_NEW_VIEWPORT 0x10000
|
||||
#define SVGA_NEW_PRESCALE 0x20000
|
||||
#define SVGA_NEW_REDUCED_PRIMITIVE 0x40000
|
||||
#define SVGA_NEW_TEXTURE_BINDING 0x80000
|
||||
#define SVGA_NEW_NEED_PIPELINE 0x100000
|
||||
#define SVGA_NEW_NEED_SWVFETCH 0x200000
|
||||
#define SVGA_NEW_NEED_SWTNL 0x400000
|
||||
#define SVGA_NEW_FS_RESULT 0x800000
|
||||
#define SVGA_NEW_VS_RESULT 0x1000000
|
||||
#define SVGA_NEW_EDGEFLAGS 0x2000000
|
||||
#define SVGA_NEW_ZERO_STRIDE 0x4000000
|
||||
#define SVGA_NEW_TEXTURE_FLAGS 0x8000000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* svga_clear.c:
|
||||
*/
|
||||
void svga_clear(struct pipe_context *pipe,
|
||||
unsigned buffers,
|
||||
const float *rgba,
|
||||
double depth,
|
||||
unsigned stencil);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* svga_screen_texture.c:
|
||||
*/
|
||||
void svga_mark_surfaces_dirty(struct svga_context *svga);
|
||||
|
||||
|
||||
|
||||
|
||||
void svga_init_state_functions( struct svga_context *svga );
|
||||
void svga_init_flush_functions( struct svga_context *svga );
|
||||
void svga_init_string_functions( struct svga_context *svga );
|
||||
void svga_init_blit_functions(struct svga_context *svga);
|
||||
|
||||
void svga_init_blend_functions( struct svga_context *svga );
|
||||
void svga_init_depth_stencil_functions( struct svga_context *svga );
|
||||
void svga_init_misc_functions( struct svga_context *svga );
|
||||
void svga_init_rasterizer_functions( struct svga_context *svga );
|
||||
void svga_init_sampler_functions( struct svga_context *svga );
|
||||
void svga_init_fs_functions( struct svga_context *svga );
|
||||
void svga_init_vs_functions( struct svga_context *svga );
|
||||
void svga_init_vertex_functions( struct svga_context *svga );
|
||||
void svga_init_constbuffer_functions( struct svga_context *svga );
|
||||
void svga_init_draw_functions( struct svga_context *svga );
|
||||
void svga_init_query_functions( struct svga_context *svga );
|
||||
|
||||
void svga_cleanup_vertex_state( struct svga_context *svga );
|
||||
void svga_cleanup_tss_binding( struct svga_context *svga );
|
||||
void svga_cleanup_framebuffer( struct svga_context *svga );
|
||||
|
||||
void svga_context_flush( struct svga_context *svga,
|
||||
struct pipe_fence_handle **pfence );
|
||||
|
||||
void svga_hwtnl_flush_retry( struct svga_context *svga );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Inline conversion functions. These are better-typed than the
|
||||
* macros used previously:
|
||||
*/
|
||||
static INLINE struct svga_context *
|
||||
svga_context( struct pipe_context *pipe )
|
||||
{
|
||||
return (struct svga_context *)pipe;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
74
src/gallium/drivers/svga/svga_debug.h
Normal file
74
src/gallium/drivers/svga/svga_debug.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_DEBUG_H
|
||||
#define SVGA_DEBUG_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
#define DEBUG_DMA 0x1
|
||||
#define DEBUG_TGSI 0x4
|
||||
#define DEBUG_PIPE 0x8
|
||||
#define DEBUG_STATE 0x10
|
||||
#define DEBUG_SCREEN 0x20
|
||||
#define DEBUG_TEX 0x40
|
||||
#define DEBUG_SWTNL 0x80
|
||||
#define DEBUG_CONSTS 0x100
|
||||
#define DEBUG_VIEWPORT 0x200
|
||||
#define DEBUG_VIEWS 0x400
|
||||
#define DEBUG_PERF 0x800 /* print something when we hit any slow path operation */
|
||||
#define DEBUG_FLUSH 0x1000 /* flush after every draw */
|
||||
#define DEBUG_SYNC 0x2000 /* sync after every flush */
|
||||
#define DEBUG_QUERY 0x4000
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int SVGA_DEBUG;
|
||||
#define DBSTR(x) x
|
||||
#else
|
||||
#define SVGA_DEBUG 0
|
||||
#define DBSTR(x) ""
|
||||
#endif
|
||||
|
||||
static INLINE void
|
||||
SVGA_DBG( unsigned flag, const char *fmt, ... )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (SVGA_DEBUG & flag)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, fmt );
|
||||
debug_vprintf( fmt, args );
|
||||
va_end( args );
|
||||
}
|
||||
#else
|
||||
(void)flag;
|
||||
(void)fmt;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
370
src/gallium/drivers/svga/svga_draw.c
Normal file
370
src/gallium/drivers/svga/svga_draw.c
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_draw.h"
|
||||
#include "svga_draw_private.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_cmd.h"
|
||||
|
||||
|
||||
struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
|
||||
struct u_upload_mgr *upload_ib,
|
||||
struct svga_winsys_context *swc )
|
||||
{
|
||||
struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
|
||||
if (hwtnl == NULL)
|
||||
goto fail;
|
||||
|
||||
hwtnl->svga = svga;
|
||||
hwtnl->upload_ib = upload_ib;
|
||||
|
||||
hwtnl->cmd.swc = swc;
|
||||
|
||||
return hwtnl;
|
||||
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < PIPE_PRIM_MAX; i++) {
|
||||
for (j = 0; j < IDX_CACHE_MAX; j++) {
|
||||
pipe_buffer_reference( &hwtnl->index_cache[i][j].buffer,
|
||||
NULL );
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.vdecl_count; i++)
|
||||
pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], NULL);
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.prim_count; i++)
|
||||
pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
|
||||
|
||||
|
||||
FREE(hwtnl);
|
||||
}
|
||||
|
||||
|
||||
void svga_hwtnl_set_flatshade( struct svga_hwtnl *hwtnl,
|
||||
boolean flatshade,
|
||||
boolean flatshade_first )
|
||||
{
|
||||
hwtnl->hw_pv = PV_FIRST;
|
||||
hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
|
||||
}
|
||||
|
||||
void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl,
|
||||
unsigned mode )
|
||||
{
|
||||
hwtnl->api_fillmode = mode;
|
||||
}
|
||||
|
||||
void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
|
||||
unsigned count )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
assert(hwtnl->cmd.prim_count == 0);
|
||||
|
||||
for (i = count; i < hwtnl->cmd.vdecl_count; i++) {
|
||||
pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i],
|
||||
NULL);
|
||||
}
|
||||
|
||||
hwtnl->cmd.vdecl_count = count;
|
||||
}
|
||||
|
||||
|
||||
void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
|
||||
unsigned i,
|
||||
const SVGA3dVertexDecl *decl,
|
||||
struct pipe_buffer *vb)
|
||||
{
|
||||
assert(hwtnl->cmd.prim_count == 0);
|
||||
|
||||
assert( i < hwtnl->cmd.vdecl_count );
|
||||
|
||||
hwtnl->cmd.vdecl[i] = *decl;
|
||||
|
||||
pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i],
|
||||
vb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
|
||||
{
|
||||
struct svga_winsys_context *swc = hwtnl->cmd.swc;
|
||||
struct svga_context *svga = hwtnl->svga;
|
||||
enum pipe_error ret;
|
||||
|
||||
if (hwtnl->cmd.prim_count) {
|
||||
struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
|
||||
struct svga_winsys_surface *ib_handle[QSZ];
|
||||
struct svga_winsys_surface *handle;
|
||||
SVGA3dVertexDecl *vdecl;
|
||||
SVGA3dPrimitiveRange *prim;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
|
||||
handle = svga_buffer_handle(svga, hwtnl->cmd.vdecl_vb[i]);
|
||||
if (handle == NULL)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
vb_handle[i] = handle;
|
||||
}
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.prim_count; i++) {
|
||||
if (hwtnl->cmd.prim_ib[i]) {
|
||||
handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
|
||||
if (handle == NULL)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
handle = NULL;
|
||||
|
||||
ib_handle[i] = handle;
|
||||
}
|
||||
|
||||
ret = SVGA3D_BeginDrawPrimitives(swc,
|
||||
&vdecl,
|
||||
hwtnl->cmd.vdecl_count,
|
||||
&prim,
|
||||
hwtnl->cmd.prim_count);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
|
||||
memcpy( vdecl,
|
||||
hwtnl->cmd.vdecl,
|
||||
hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
|
||||
/* Given rangeHint is considered to be relative to indexBias, and
|
||||
* indexBias varies per primitive, we cannot accurately supply an
|
||||
* rangeHint when emitting more than one primitive per draw command.
|
||||
*/
|
||||
if (hwtnl->cmd.prim_count == 1) {
|
||||
vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
|
||||
vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
|
||||
}
|
||||
else {
|
||||
vdecl[i].rangeHint.first = 0;
|
||||
vdecl[i].rangeHint.last = 0;
|
||||
}
|
||||
|
||||
swc->surface_relocation(swc,
|
||||
&vdecl[i].array.surfaceId,
|
||||
vb_handle[i],
|
||||
PIPE_BUFFER_USAGE_GPU_READ);
|
||||
}
|
||||
|
||||
memcpy( prim,
|
||||
hwtnl->cmd.prim,
|
||||
hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.prim_count; i++) {
|
||||
swc->surface_relocation(swc,
|
||||
&prim[i].indexArray.surfaceId,
|
||||
ib_handle[i],
|
||||
PIPE_BUFFER_USAGE_GPU_READ);
|
||||
pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
|
||||
}
|
||||
|
||||
SVGA_FIFOCommitAll( swc );
|
||||
hwtnl->cmd.prim_count = 0;
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Internal functions:
|
||||
*/
|
||||
|
||||
enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
|
||||
const SVGA3dPrimitiveRange *range,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
struct pipe_buffer *ib )
|
||||
{
|
||||
int ret = PIPE_OK;
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
|
||||
struct pipe_buffer *vb = hwtnl->cmd.vdecl_vb[i];
|
||||
unsigned size = vb ? vb->size : 0;
|
||||
unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
|
||||
unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
|
||||
unsigned index_bias = range->indexBias;
|
||||
unsigned width;
|
||||
|
||||
assert(vb);
|
||||
assert(size);
|
||||
assert(offset < size);
|
||||
assert(index_bias >= 0);
|
||||
assert(min_index <= max_index);
|
||||
assert(offset + index_bias*stride < size);
|
||||
assert(offset + (index_bias + min_index)*stride < size);
|
||||
|
||||
switch (hwtnl->cmd.vdecl[i].identity.type) {
|
||||
case SVGA3D_DECLTYPE_FLOAT1:
|
||||
width = 4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_FLOAT2:
|
||||
width = 4*2;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_FLOAT3:
|
||||
width = 4*3;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_FLOAT4:
|
||||
width = 4*4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_D3DCOLOR:
|
||||
width = 4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_UBYTE4:
|
||||
width = 1*4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_SHORT2:
|
||||
width = 2*2;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_SHORT4:
|
||||
width = 2*4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_UBYTE4N:
|
||||
width = 1*4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_SHORT2N:
|
||||
width = 2*2;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_SHORT4N:
|
||||
width = 2*4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_USHORT2N:
|
||||
width = 2*2;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_USHORT4N:
|
||||
width = 2*4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_UDEC3:
|
||||
width = 4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_DEC3N:
|
||||
width = 4;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_FLOAT16_2:
|
||||
width = 2*2;
|
||||
break;
|
||||
case SVGA3D_DECLTYPE_FLOAT16_4:
|
||||
width = 2*4;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
width = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(!stride || width <= stride);
|
||||
assert(offset + (index_bias + max_index)*stride + width <= size);
|
||||
}
|
||||
|
||||
assert(range->indexWidth == range->indexArray.stride);
|
||||
|
||||
if(ib) {
|
||||
unsigned size = ib->size;
|
||||
unsigned offset = range->indexArray.offset;
|
||||
unsigned stride = range->indexArray.stride;
|
||||
unsigned count;
|
||||
|
||||
assert(size);
|
||||
assert(offset < size);
|
||||
assert(stride);
|
||||
|
||||
switch (range->primType) {
|
||||
case SVGA3D_PRIMITIVE_POINTLIST:
|
||||
count = range->primitiveCount;
|
||||
break;
|
||||
case SVGA3D_PRIMITIVE_LINELIST:
|
||||
count = range->primitiveCount * 2;
|
||||
break;
|
||||
case SVGA3D_PRIMITIVE_LINESTRIP:
|
||||
count = range->primitiveCount + 1;
|
||||
break;
|
||||
case SVGA3D_PRIMITIVE_TRIANGLELIST:
|
||||
count = range->primitiveCount * 3;
|
||||
break;
|
||||
case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
|
||||
count = range->primitiveCount + 2;
|
||||
break;
|
||||
case SVGA3D_PRIMITIVE_TRIANGLEFAN:
|
||||
count = range->primitiveCount + 2;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(offset + count*stride <= size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hwtnl->cmd.prim_count+1 >= QSZ) {
|
||||
ret = svga_hwtnl_flush( hwtnl );
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* min/max indices are relative to bias */
|
||||
hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
|
||||
hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
|
||||
|
||||
hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
|
||||
|
||||
pipe_buffer_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
|
||||
hwtnl->cmd.prim_count++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
83
src/gallium/drivers/svga/svga_draw.h
Normal file
83
src/gallium/drivers/svga/svga_draw.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_DRAW_H
|
||||
#define SVGA_DRAW_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
struct svga_hwtnl;
|
||||
struct svga_winsys_context;
|
||||
struct svga_screen;
|
||||
struct svga_context;
|
||||
struct pipe_buffer;
|
||||
struct u_upload_mgr;
|
||||
|
||||
struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
|
||||
struct u_upload_mgr *upload_ib,
|
||||
struct svga_winsys_context *swc );
|
||||
|
||||
void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl );
|
||||
|
||||
void svga_hwtnl_set_flatshade( struct svga_hwtnl *hwtnl,
|
||||
boolean flatshade,
|
||||
boolean flatshade_first );
|
||||
|
||||
void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl,
|
||||
unsigned mode );
|
||||
|
||||
void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
|
||||
unsigned i,
|
||||
const SVGA3dVertexDecl *decl,
|
||||
struct pipe_buffer *vb);
|
||||
|
||||
void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
|
||||
unsigned count );
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count);
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned index_size,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
unsigned bias );
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_flush( struct svga_hwtnl *hwtnl );
|
||||
|
||||
|
||||
#endif /* SVGA_DRAW_H_ */
|
||||
297
src/gallium/drivers/svga/svga_draw_arrays.c
Normal file
297
src/gallium/drivers/svga/svga_draw_arrays.c
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "indices/u_indices.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_draw_private.h"
|
||||
#include "svga_context.h"
|
||||
|
||||
|
||||
#define DBG 0
|
||||
|
||||
|
||||
|
||||
|
||||
static enum pipe_error generate_indices( struct svga_hwtnl *hwtnl,
|
||||
unsigned nr,
|
||||
unsigned index_size,
|
||||
u_generate_func generate,
|
||||
struct pipe_buffer **out_buf )
|
||||
{
|
||||
struct pipe_screen *screen = hwtnl->svga->pipe.screen;
|
||||
unsigned size = index_size * nr;
|
||||
struct pipe_buffer *dst = NULL;
|
||||
void *dst_map = NULL;
|
||||
|
||||
dst = screen->buffer_create( screen, 32,
|
||||
PIPE_BUFFER_USAGE_INDEX |
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE |
|
||||
PIPE_BUFFER_USAGE_GPU_READ,
|
||||
size );
|
||||
if (dst == NULL)
|
||||
goto fail;
|
||||
|
||||
dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE );
|
||||
if (dst_map == NULL)
|
||||
goto fail;
|
||||
|
||||
generate( nr,
|
||||
dst_map );
|
||||
|
||||
pipe_buffer_unmap( screen, dst );
|
||||
|
||||
*out_buf = dst;
|
||||
return PIPE_OK;
|
||||
|
||||
fail:
|
||||
if (dst_map)
|
||||
screen->buffer_unmap( screen, dst );
|
||||
|
||||
if (dst)
|
||||
screen->buffer_destroy( dst );
|
||||
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static boolean compare( unsigned cached_nr,
|
||||
unsigned nr,
|
||||
unsigned type )
|
||||
{
|
||||
if (type == U_GENERATE_REUSABLE)
|
||||
return cached_nr >= nr;
|
||||
else
|
||||
return cached_nr == nr;
|
||||
}
|
||||
|
||||
static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
|
||||
unsigned prim,
|
||||
unsigned gen_type,
|
||||
unsigned gen_nr,
|
||||
unsigned gen_size,
|
||||
u_generate_func generate,
|
||||
struct pipe_buffer **out_buf )
|
||||
{
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IDX_CACHE_MAX; i++) {
|
||||
if (hwtnl->index_cache[prim][i].buffer != NULL &&
|
||||
hwtnl->index_cache[prim][i].generate == generate)
|
||||
{
|
||||
if (compare(hwtnl->index_cache[prim][i].gen_nr, gen_nr, gen_type))
|
||||
{
|
||||
pipe_buffer_reference( out_buf,
|
||||
hwtnl->index_cache[prim][i].buffer );
|
||||
|
||||
if (DBG)
|
||||
debug_printf("%s retrieve %d/%d\n", __FUNCTION__, i, gen_nr);
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
else if (gen_type == U_GENERATE_REUSABLE)
|
||||
{
|
||||
pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer,
|
||||
NULL );
|
||||
|
||||
if (DBG)
|
||||
debug_printf("%s discard %d/%d\n", __FUNCTION__,
|
||||
i, hwtnl->index_cache[prim][i].gen_nr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == IDX_CACHE_MAX)
|
||||
{
|
||||
unsigned smallest = 0;
|
||||
unsigned smallest_size = ~0;
|
||||
|
||||
for (i = 0; i < IDX_CACHE_MAX && smallest_size; i++) {
|
||||
if (hwtnl->index_cache[prim][i].buffer == NULL)
|
||||
{
|
||||
smallest = i;
|
||||
smallest_size = 0;
|
||||
}
|
||||
else if (hwtnl->index_cache[prim][i].gen_nr < smallest)
|
||||
{
|
||||
smallest = i;
|
||||
smallest_size = hwtnl->index_cache[prim][i].gen_nr;
|
||||
}
|
||||
}
|
||||
|
||||
assert (smallest != IDX_CACHE_MAX);
|
||||
|
||||
pipe_buffer_reference( &hwtnl->index_cache[prim][smallest].buffer,
|
||||
NULL );
|
||||
|
||||
if (DBG)
|
||||
debug_printf("%s discard smallest %d/%d\n", __FUNCTION__,
|
||||
smallest, smallest_size);
|
||||
|
||||
i = smallest;
|
||||
}
|
||||
|
||||
|
||||
ret = generate_indices( hwtnl,
|
||||
gen_nr,
|
||||
gen_size,
|
||||
generate,
|
||||
out_buf );
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
|
||||
hwtnl->index_cache[prim][i].generate = generate;
|
||||
hwtnl->index_cache[prim][i].gen_nr = gen_nr;
|
||||
pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer,
|
||||
*out_buf );
|
||||
|
||||
if (DBG)
|
||||
debug_printf("%s cache %d/%d\n", __FUNCTION__,
|
||||
i, hwtnl->index_cache[prim][i].gen_nr);
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
simple_draw_arrays( struct svga_hwtnl *hwtnl,
|
||||
unsigned prim, unsigned start, unsigned count )
|
||||
{
|
||||
SVGA3dPrimitiveRange range;
|
||||
unsigned hw_prim;
|
||||
unsigned hw_count;
|
||||
|
||||
hw_prim = svga_translate_prim(prim, count, &hw_count);
|
||||
if (hw_count == 0)
|
||||
return PIPE_ERROR_BAD_INPUT;
|
||||
|
||||
range.primType = hw_prim;
|
||||
range.primitiveCount = hw_count;
|
||||
range.indexArray.surfaceId = SVGA3D_INVALID_ID;
|
||||
range.indexArray.offset = 0;
|
||||
range.indexArray.stride = 0;
|
||||
range.indexWidth = 0;
|
||||
range.indexBias = start;
|
||||
|
||||
/* Min/max index should be calculated prior to applying bias, so we
|
||||
* end up with min_index = 0, max_index = count - 1 and everybody
|
||||
* looking at those numbers knows to adjust them by
|
||||
* range.indexBias.
|
||||
*/
|
||||
return svga_hwtnl_prim( hwtnl, &range, 0, count - 1, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count)
|
||||
{
|
||||
unsigned gen_prim, gen_size, gen_nr, gen_type;
|
||||
u_generate_func gen_func;
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
|
||||
if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL &&
|
||||
prim >= PIPE_PRIM_TRIANGLES)
|
||||
{
|
||||
gen_type = u_unfilled_generator( prim,
|
||||
start,
|
||||
count,
|
||||
hwtnl->api_fillmode,
|
||||
&gen_prim,
|
||||
&gen_size,
|
||||
&gen_nr,
|
||||
&gen_func );
|
||||
}
|
||||
else {
|
||||
gen_type = u_index_generator( svga_hw_prims,
|
||||
prim,
|
||||
start,
|
||||
count,
|
||||
hwtnl->api_pv,
|
||||
hwtnl->hw_pv,
|
||||
&gen_prim,
|
||||
&gen_size,
|
||||
&gen_nr,
|
||||
&gen_func );
|
||||
}
|
||||
|
||||
if (gen_type == U_GENERATE_LINEAR) {
|
||||
return simple_draw_arrays( hwtnl, gen_prim, start, count );
|
||||
}
|
||||
else {
|
||||
struct pipe_buffer *gen_buf = NULL;
|
||||
|
||||
/* Need to draw as indexed primitive.
|
||||
* Potentially need to run the gen func to build an index buffer.
|
||||
*/
|
||||
ret = retrieve_or_generate_indices( hwtnl,
|
||||
prim,
|
||||
gen_type,
|
||||
gen_nr,
|
||||
gen_size,
|
||||
gen_func,
|
||||
&gen_buf );
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
ret = svga_hwtnl_simple_draw_range_elements( hwtnl,
|
||||
gen_buf,
|
||||
gen_size,
|
||||
0,
|
||||
count - 1,
|
||||
gen_prim,
|
||||
0,
|
||||
gen_nr,
|
||||
start );
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (gen_buf)
|
||||
pipe_buffer_reference( &gen_buf, NULL );
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
255
src/gallium/drivers/svga/svga_draw_elements.c
Normal file
255
src/gallium/drivers/svga/svga_draw_elements.c
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "indices/u_indices.h"
|
||||
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_draw_private.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_context.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
translate_indices( struct svga_hwtnl *hwtnl,
|
||||
struct pipe_buffer *src,
|
||||
unsigned offset,
|
||||
unsigned nr,
|
||||
unsigned index_size,
|
||||
u_translate_func translate,
|
||||
struct pipe_buffer **out_buf )
|
||||
{
|
||||
struct pipe_screen *screen = hwtnl->svga->pipe.screen;
|
||||
unsigned size = index_size * nr;
|
||||
const void *src_map = NULL;
|
||||
struct pipe_buffer *dst = NULL;
|
||||
void *dst_map = NULL;
|
||||
|
||||
dst = screen->buffer_create( screen, 32,
|
||||
PIPE_BUFFER_USAGE_INDEX |
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE |
|
||||
PIPE_BUFFER_USAGE_GPU_READ,
|
||||
size );
|
||||
if (dst == NULL)
|
||||
goto fail;
|
||||
|
||||
src_map = pipe_buffer_map( screen, src, PIPE_BUFFER_USAGE_CPU_READ );
|
||||
if (src_map == NULL)
|
||||
goto fail;
|
||||
|
||||
dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE );
|
||||
if (dst_map == NULL)
|
||||
goto fail;
|
||||
|
||||
translate( (const char *)src_map + offset,
|
||||
nr,
|
||||
dst_map );
|
||||
|
||||
pipe_buffer_unmap( screen, src );
|
||||
pipe_buffer_unmap( screen, dst );
|
||||
|
||||
*out_buf = dst;
|
||||
return PIPE_OK;
|
||||
|
||||
fail:
|
||||
if (src_map)
|
||||
screen->buffer_unmap( screen, src );
|
||||
|
||||
if (dst_map)
|
||||
screen->buffer_unmap( screen, dst );
|
||||
|
||||
if (dst)
|
||||
screen->buffer_destroy( dst );
|
||||
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
|
||||
struct pipe_buffer *index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
unsigned bias )
|
||||
{
|
||||
struct pipe_buffer *upload_buffer = NULL;
|
||||
SVGA3dPrimitiveRange range;
|
||||
unsigned hw_prim;
|
||||
unsigned hw_count;
|
||||
unsigned index_offset = start * index_size;
|
||||
int ret = PIPE_OK;
|
||||
|
||||
hw_prim = svga_translate_prim(prim, count, &hw_count);
|
||||
if (hw_count == 0)
|
||||
goto done;
|
||||
|
||||
if (index_buffer &&
|
||||
svga_buffer_is_user_buffer(index_buffer))
|
||||
{
|
||||
assert( index_buffer->size >= index_offset + count * index_size );
|
||||
|
||||
ret = u_upload_buffer( hwtnl->upload_ib,
|
||||
index_offset,
|
||||
count * index_size,
|
||||
index_buffer,
|
||||
&index_offset,
|
||||
&upload_buffer );
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
/* Don't need to worry about refcounting index_buffer as this is
|
||||
* just a stack variable without a counted reference of its own.
|
||||
* The caller holds the reference.
|
||||
*/
|
||||
index_buffer = upload_buffer;
|
||||
}
|
||||
|
||||
range.primType = hw_prim;
|
||||
range.primitiveCount = hw_count;
|
||||
range.indexArray.offset = index_offset;
|
||||
range.indexArray.stride = index_size;
|
||||
range.indexWidth = index_size;
|
||||
range.indexBias = bias;
|
||||
|
||||
ret = svga_hwtnl_prim( hwtnl, &range, min_index, max_index, index_buffer );
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (upload_buffer)
|
||||
pipe_buffer_reference( &upload_buffer, NULL );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
|
||||
struct pipe_buffer *index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim, unsigned start, unsigned count,
|
||||
unsigned bias)
|
||||
{
|
||||
unsigned gen_prim, gen_size, gen_nr, gen_type;
|
||||
u_translate_func gen_func;
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
|
||||
if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL &&
|
||||
prim >= PIPE_PRIM_TRIANGLES)
|
||||
{
|
||||
gen_type = u_unfilled_translator( prim,
|
||||
index_size,
|
||||
count,
|
||||
hwtnl->api_fillmode,
|
||||
&gen_prim,
|
||||
&gen_size,
|
||||
&gen_nr,
|
||||
&gen_func );
|
||||
}
|
||||
else
|
||||
{
|
||||
gen_type = u_index_translator( svga_hw_prims,
|
||||
prim,
|
||||
index_size,
|
||||
count,
|
||||
hwtnl->api_pv,
|
||||
hwtnl->hw_pv,
|
||||
&gen_prim,
|
||||
&gen_size,
|
||||
&gen_nr,
|
||||
&gen_func );
|
||||
}
|
||||
|
||||
|
||||
if (gen_type == U_TRANSLATE_MEMCPY) {
|
||||
/* No need for translation, just pass through to hardware:
|
||||
*/
|
||||
return svga_hwtnl_simple_draw_range_elements( hwtnl, index_buffer,
|
||||
index_size,
|
||||
min_index,
|
||||
max_index,
|
||||
gen_prim, start, count, bias );
|
||||
}
|
||||
else {
|
||||
struct pipe_buffer *gen_buf = NULL;
|
||||
|
||||
/* Need to allocate a new index buffer and run the translate
|
||||
* func to populate it. Could potentially cache this translated
|
||||
* index buffer with the original to avoid future
|
||||
* re-translations. Not much point if we're just accelerating
|
||||
* GL though, as index buffers are typically used only once
|
||||
* there.
|
||||
*/
|
||||
ret = translate_indices( hwtnl,
|
||||
index_buffer,
|
||||
start * index_size,
|
||||
gen_nr,
|
||||
gen_size,
|
||||
gen_func,
|
||||
&gen_buf );
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
ret = svga_hwtnl_simple_draw_range_elements( hwtnl,
|
||||
gen_buf,
|
||||
gen_size,
|
||||
min_index,
|
||||
max_index,
|
||||
gen_prim,
|
||||
0,
|
||||
gen_nr,
|
||||
bias );
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (gen_buf)
|
||||
pipe_buffer_reference( &gen_buf, NULL );
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
158
src/gallium/drivers/svga/svga_draw_private.h
Normal file
158
src/gallium/drivers/svga/svga_draw_private.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_DRAW_H_
|
||||
#define SVGA_DRAW_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "indices/u_indices.h"
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga3d_shaderdefs.h"
|
||||
|
||||
struct svga_context;
|
||||
struct u_upload_mgr;
|
||||
|
||||
/* Should include polygon?
|
||||
*/
|
||||
static const unsigned svga_hw_prims =
|
||||
((1 << PIPE_PRIM_POINTS) |
|
||||
(1 << PIPE_PRIM_LINES) |
|
||||
(1 << PIPE_PRIM_LINE_STRIP) |
|
||||
(1 << PIPE_PRIM_TRIANGLES) |
|
||||
(1 << PIPE_PRIM_TRIANGLE_STRIP) |
|
||||
(1 << PIPE_PRIM_TRIANGLE_FAN));
|
||||
|
||||
|
||||
static INLINE unsigned svga_translate_prim(unsigned mode,
|
||||
unsigned count,
|
||||
unsigned *out_count)
|
||||
{
|
||||
switch (mode) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
*out_count = count;
|
||||
return SVGA3D_PRIMITIVE_POINTLIST;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
*out_count = count / 2;
|
||||
return SVGA3D_PRIMITIVE_LINELIST;
|
||||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
*out_count = count - 1;
|
||||
return SVGA3D_PRIMITIVE_LINESTRIP;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
*out_count = count / 3;
|
||||
return SVGA3D_PRIMITIVE_TRIANGLELIST;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
*out_count = count - 2;
|
||||
return SVGA3D_PRIMITIVE_TRIANGLESTRIP;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
*out_count = count - 2;
|
||||
return SVGA3D_PRIMITIVE_TRIANGLEFAN;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
*out_count = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct index_cache {
|
||||
u_generate_func generate;
|
||||
unsigned gen_nr;
|
||||
|
||||
/* If non-null, this buffer is filled by calling
|
||||
* generate(nr, map(buffer))
|
||||
*/
|
||||
struct pipe_buffer *buffer;
|
||||
};
|
||||
|
||||
#define QSZ 32
|
||||
|
||||
struct draw_cmd {
|
||||
struct svga_winsys_context *swc;
|
||||
|
||||
SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX];
|
||||
struct pipe_buffer *vdecl_vb[SVGA3D_INPUTREG_MAX];
|
||||
unsigned vdecl_count;
|
||||
|
||||
SVGA3dPrimitiveRange prim[QSZ];
|
||||
struct pipe_buffer *prim_ib[QSZ];
|
||||
unsigned prim_count;
|
||||
unsigned min_index[QSZ];
|
||||
unsigned max_index[QSZ];
|
||||
};
|
||||
|
||||
#define IDX_CACHE_MAX 8
|
||||
|
||||
struct svga_hwtnl {
|
||||
struct svga_context *svga;
|
||||
struct u_upload_mgr *upload_ib;
|
||||
|
||||
/* Flatshade information:
|
||||
*/
|
||||
unsigned api_pv;
|
||||
unsigned hw_pv;
|
||||
unsigned api_fillmode;
|
||||
|
||||
/* Cache the results of running a particular generate func on each
|
||||
* primitive type.
|
||||
*/
|
||||
struct index_cache index_cache[PIPE_PRIM_MAX][IDX_CACHE_MAX];
|
||||
|
||||
/* Try to build the maximal draw command packet before emitting:
|
||||
*/
|
||||
struct draw_cmd cmd;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Internal functions
|
||||
*/
|
||||
enum pipe_error
|
||||
svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
|
||||
const SVGA3dPrimitiveRange *range,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
struct pipe_buffer *ib );
|
||||
|
||||
enum pipe_error
|
||||
svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned index_size,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
unsigned bias );
|
||||
|
||||
|
||||
#endif
|
||||
42
src/gallium/drivers/svga/svga_hw_reg.h
Normal file
42
src/gallium/drivers/svga/svga_hw_reg.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_HW_REG_H
|
||||
#define SVGA_HW_REG_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
#if defined(PIPE_CC_GCC)
|
||||
#ifndef HAVE_STDINT_H
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "svga_types.h"
|
||||
|
||||
#include "svga3d_reg.h"
|
||||
|
||||
|
||||
#endif
|
||||
246
src/gallium/drivers/svga/svga_pipe_blend.c
Normal file
246
src/gallium/drivers/svga/svga_pipe_blend.c
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
static INLINE unsigned
|
||||
svga_translate_blend_factor(unsigned factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case PIPE_BLENDFACTOR_ZERO: return SVGA3D_BLENDOP_ZERO;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA: return SVGA3D_BLENDOP_SRCALPHA;
|
||||
case PIPE_BLENDFACTOR_ONE: return SVGA3D_BLENDOP_ONE;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR: return SVGA3D_BLENDOP_SRCCOLOR;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR: return SVGA3D_BLENDOP_INVSRCCOLOR;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR: return SVGA3D_BLENDOP_DESTCOLOR;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR: return SVGA3D_BLENDOP_INVDESTCOLOR;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return SVGA3D_BLENDOP_INVSRCALPHA;
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA: return SVGA3D_BLENDOP_DESTALPHA;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA: return SVGA3D_BLENDOP_INVDESTALPHA;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR: return SVGA3D_BLENDOP_BLENDFACTOR;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR;
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA: return SVGA3D_BLENDOP_BLENDFACTOR; /* ? */
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return SVGA3D_BLENDOP_INVBLENDFACTOR; /* ? */
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_BLENDOP_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
svga_translate_blend_func(unsigned mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case PIPE_BLEND_ADD: return SVGA3D_BLENDEQ_ADD;
|
||||
case PIPE_BLEND_SUBTRACT: return SVGA3D_BLENDEQ_SUBTRACT;
|
||||
case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT;
|
||||
case PIPE_BLEND_MIN: return SVGA3D_BLENDEQ_MINIMUM;
|
||||
case PIPE_BLEND_MAX: return SVGA3D_BLENDEQ_MAXIMUM;
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_BLENDEQ_ADD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
svga_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *templ)
|
||||
{
|
||||
struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
|
||||
unsigned i;
|
||||
|
||||
|
||||
/* Fill in the per-rendertarget blend state. We currently only
|
||||
* have one rendertarget.
|
||||
*/
|
||||
for (i = 0; i < 1; i++) {
|
||||
/* No way to set this in SVGA3D, and no way to correctly implement it on
|
||||
* top of D3D9 API. Instead we try to simulate with various blend modes.
|
||||
*/
|
||||
if (templ->logicop_enable) {
|
||||
switch (templ->logicop_func) {
|
||||
case PIPE_LOGICOP_XOR:
|
||||
blend->need_white_fragments = TRUE;
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_SUBTRACT;
|
||||
break;
|
||||
case PIPE_LOGICOP_CLEAR:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_COPY:
|
||||
blend->rt[i].blend_enable = FALSE;
|
||||
break;
|
||||
case PIPE_LOGICOP_COPY_INVERTED:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
|
||||
break;
|
||||
case PIPE_LOGICOP_NOOP:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
|
||||
break;
|
||||
case PIPE_LOGICOP_SET:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_INVERT:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
|
||||
break;
|
||||
case PIPE_LOGICOP_AND:
|
||||
/* Approximate with minimum - works for the 0 & anything case: */
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_AND_REVERSE:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_AND_INVERTED:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_OR:
|
||||
/* Approximate with maximum - works for the 1 | anything case: */
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_OR_REVERSE:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_OR_INVERTED:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_NAND:
|
||||
case PIPE_LOGICOP_NOR:
|
||||
case PIPE_LOGICOP_EQUIV:
|
||||
/* Fill these in with plausible values */
|
||||
blend->rt[i].blend_enable = FALSE;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
blend->rt[i].blend_enable = templ->blend_enable;
|
||||
|
||||
if (templ->blend_enable) {
|
||||
blend->rt[i].srcblend = svga_translate_blend_factor(templ->rgb_src_factor);
|
||||
blend->rt[i].dstblend = svga_translate_blend_factor(templ->rgb_dst_factor);
|
||||
blend->rt[i].blendeq = svga_translate_blend_func(templ->rgb_func);
|
||||
blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->alpha_src_factor);
|
||||
blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->alpha_dst_factor);
|
||||
blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->alpha_func);
|
||||
|
||||
if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
|
||||
blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
|
||||
blend->rt[i].blendeq_alpha != blend->rt[i].blendeq)
|
||||
{
|
||||
blend->rt[i].separate_alpha_blend_enable = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blend->rt[i].writemask = templ->colormask;
|
||||
}
|
||||
|
||||
return blend;
|
||||
}
|
||||
|
||||
static void svga_bind_blend_state(struct pipe_context *pipe,
|
||||
void *blend)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.blend = (struct svga_blend_state*)blend;
|
||||
svga->dirty |= SVGA_NEW_BLEND;
|
||||
}
|
||||
|
||||
|
||||
static void svga_delete_blend_state(struct pipe_context *pipe, void *blend)
|
||||
{
|
||||
FREE(blend);
|
||||
}
|
||||
|
||||
static void svga_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color )
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.blend_color = *blend_color;
|
||||
|
||||
svga->dirty |= SVGA_NEW_BLEND;
|
||||
}
|
||||
|
||||
|
||||
void svga_init_blend_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_blend_state = svga_create_blend_state;
|
||||
svga->pipe.bind_blend_state = svga_bind_blend_state;
|
||||
svga->pipe.delete_blend_state = svga_delete_blend_state;
|
||||
|
||||
svga->pipe.set_blend_color = svga_set_blend_color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
84
src/gallium/drivers/svga/svga_pipe_blit.c
Normal file
84
src/gallium/drivers/svga/svga_pipe_blit.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#define FILE_DEBUG_FLAG DEBUG_BLIT
|
||||
|
||||
|
||||
static void svga_surface_copy(struct pipe_context *pipe,
|
||||
struct pipe_surface *dest,
|
||||
unsigned destx, unsigned desty,
|
||||
struct pipe_surface *src,
|
||||
unsigned srcx, unsigned srcy,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
SVGA3dCopyBox *box;
|
||||
enum pipe_error ret;
|
||||
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
|
||||
ret = SVGA3D_BeginSurfaceCopy(svga->swc,
|
||||
src,
|
||||
dest,
|
||||
&box,
|
||||
1);
|
||||
if(ret != PIPE_OK) {
|
||||
|
||||
svga_context_flush(svga, NULL);
|
||||
|
||||
ret = SVGA3D_BeginSurfaceCopy(svga->swc,
|
||||
src,
|
||||
dest,
|
||||
&box,
|
||||
1);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
box->x = destx;
|
||||
box->y = desty;
|
||||
box->z = 0;
|
||||
box->w = width;
|
||||
box->h = height;
|
||||
box->d = 1;
|
||||
box->srcx = srcx;
|
||||
box->srcy = srcy;
|
||||
box->srcz = 0;
|
||||
|
||||
SVGA_FIFOCommitAll(svga->swc);
|
||||
|
||||
svga_surface(dest)->dirty = TRUE;
|
||||
svga_propagate_surface(pipe, dest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_init_blit_functions(struct svga_context *svga)
|
||||
{
|
||||
svga->pipe.surface_copy = svga_surface_copy;
|
||||
}
|
||||
119
src/gallium/drivers/svga/svga_pipe_clear.c
Normal file
119
src/gallium/drivers/svga/svga_pipe_clear.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_pack_color.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
try_clear(struct svga_context *svga,
|
||||
unsigned buffers,
|
||||
const float *rgba,
|
||||
double depth,
|
||||
unsigned stencil)
|
||||
{
|
||||
int ret = PIPE_OK;
|
||||
SVGA3dRect rect = { 0, 0, 0, 0 };
|
||||
boolean restore_viewport = FALSE;
|
||||
SVGA3dClearFlag flags = 0;
|
||||
struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
|
||||
unsigned color = 0;
|
||||
|
||||
ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((buffers & PIPE_CLEAR_COLOR) && fb->cbufs[0]) {
|
||||
flags |= SVGA3D_CLEAR_COLOR;
|
||||
util_pack_color(rgba, PIPE_FORMAT_A8R8G8B8_UNORM, &color);
|
||||
|
||||
rect.w = fb->cbufs[0]->width;
|
||||
rect.h = fb->cbufs[0]->height;
|
||||
}
|
||||
|
||||
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) {
|
||||
flags |= SVGA3D_CLEAR_DEPTH;
|
||||
|
||||
if (svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_Z24S8_UNORM)
|
||||
flags |= SVGA3D_CLEAR_STENCIL;
|
||||
|
||||
rect.w = MAX2(rect.w, fb->zsbuf->width);
|
||||
rect.h = MAX2(rect.h, fb->zsbuf->height);
|
||||
}
|
||||
|
||||
if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
|
||||
restore_viewport = TRUE;
|
||||
ret = SVGA3D_SetViewport(svga->swc, &rect);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = SVGA3D_ClearRect(svga->swc, flags, color, depth, stencil,
|
||||
rect.x, rect.y, rect.w, rect.h);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
if (restore_viewport) {
|
||||
memcpy(&rect, &svga->state.hw_clear.viewport, sizeof rect);
|
||||
ret = SVGA3D_SetViewport(svga->swc, &rect);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the given surface to the specified value.
|
||||
* No masking, no scissor (clear entire buffer).
|
||||
*/
|
||||
void
|
||||
svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
|
||||
double depth, unsigned stencil)
|
||||
{
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
int ret;
|
||||
|
||||
ret = try_clear( svga, buffers, rgba, depth, stencil );
|
||||
|
||||
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
|
||||
/* Flush command buffer and retry:
|
||||
*/
|
||||
svga_context_flush( svga, NULL );
|
||||
|
||||
ret = try_clear( svga, buffers, rgba, depth, stencil );
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark target surfaces as dirty
|
||||
* TODO Mark only cleared surfaces.
|
||||
*/
|
||||
svga_mark_surfaces_dirty(svga);
|
||||
|
||||
assert (ret == PIPE_OK);
|
||||
}
|
||||
74
src/gallium/drivers/svga/svga_pipe_constants.c
Normal file
74
src/gallium/drivers/svga/svga_pipe_constants.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga_cmd.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Constant buffers
|
||||
*/
|
||||
|
||||
struct svga_constbuf
|
||||
{
|
||||
unsigned type;
|
||||
float (*data)[4];
|
||||
unsigned count;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void svga_set_constant_buffer(struct pipe_context *pipe,
|
||||
uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index == 0);
|
||||
|
||||
pipe_buffer_reference( &svga->curr.cb[shader],
|
||||
buf->buffer );
|
||||
|
||||
if (shader == PIPE_SHADER_FRAGMENT)
|
||||
svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
|
||||
else
|
||||
svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void svga_init_constbuffer_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.set_constant_buffer = svga_set_constant_buffer;
|
||||
}
|
||||
|
||||
153
src/gallium/drivers/svga/svga_pipe_depthstencil.c
Normal file
153
src/gallium/drivers/svga/svga_pipe_depthstencil.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
static INLINE unsigned
|
||||
svga_translate_compare_func(unsigned func)
|
||||
{
|
||||
switch (func) {
|
||||
case PIPE_FUNC_NEVER: return SVGA3D_CMP_NEVER;
|
||||
case PIPE_FUNC_LESS: return SVGA3D_CMP_LESS;
|
||||
case PIPE_FUNC_LEQUAL: return SVGA3D_CMP_LESSEQUAL;
|
||||
case PIPE_FUNC_GREATER: return SVGA3D_CMP_GREATER;
|
||||
case PIPE_FUNC_GEQUAL: return SVGA3D_CMP_GREATEREQUAL;
|
||||
case PIPE_FUNC_NOTEQUAL: return SVGA3D_CMP_NOTEQUAL;
|
||||
case PIPE_FUNC_EQUAL: return SVGA3D_CMP_EQUAL;
|
||||
case PIPE_FUNC_ALWAYS: return SVGA3D_CMP_ALWAYS;
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_CMP_ALWAYS;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
svga_translate_stencil_op(unsigned op)
|
||||
{
|
||||
switch (op) {
|
||||
case PIPE_STENCIL_OP_KEEP: return SVGA3D_STENCILOP_KEEP;
|
||||
case PIPE_STENCIL_OP_ZERO: return SVGA3D_STENCILOP_ZERO;
|
||||
case PIPE_STENCIL_OP_REPLACE: return SVGA3D_STENCILOP_REPLACE;
|
||||
case PIPE_STENCIL_OP_INCR: return SVGA3D_STENCILOP_INCR;
|
||||
case PIPE_STENCIL_OP_DECR: return SVGA3D_STENCILOP_DECR;
|
||||
case PIPE_STENCIL_OP_INCR_WRAP: return SVGA3D_STENCILOP_INCRSAT; /* incorrect? */
|
||||
case PIPE_STENCIL_OP_DECR_WRAP: return SVGA3D_STENCILOP_DECRSAT; /* incorrect? */
|
||||
case PIPE_STENCIL_OP_INVERT: return SVGA3D_STENCILOP_INVERT;
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_STENCILOP_KEEP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
svga_create_depth_stencil_state(struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_alpha_state *templ)
|
||||
{
|
||||
struct svga_depth_stencil_state *ds = CALLOC_STRUCT( svga_depth_stencil_state );
|
||||
|
||||
/* Don't try to figure out CW/CCW correspondence with
|
||||
* stencil[0]/[1] at this point. Presumably this can change as
|
||||
* back/front face are modified.
|
||||
*/
|
||||
ds->stencil[0].enabled = templ->stencil[0].enabled;
|
||||
if (ds->stencil[0].enabled) {
|
||||
ds->stencil[0].func = svga_translate_compare_func(templ->stencil[0].func);
|
||||
ds->stencil[0].fail = svga_translate_stencil_op(templ->stencil[0].fail_op);
|
||||
ds->stencil[0].zfail = svga_translate_stencil_op(templ->stencil[0].zfail_op);
|
||||
ds->stencil[0].pass = svga_translate_stencil_op(templ->stencil[0].zpass_op);
|
||||
|
||||
/* SVGA3D has one ref/mask/writemask triple shared between front &
|
||||
* back face stencil. We really need two:
|
||||
*/
|
||||
ds->stencil_ref = templ->stencil[0].ref_value & 0xff;
|
||||
ds->stencil_mask = templ->stencil[0].valuemask & 0xff;
|
||||
ds->stencil_writemask = templ->stencil[0].writemask & 0xff;
|
||||
}
|
||||
|
||||
|
||||
ds->stencil[1].enabled = templ->stencil[1].enabled;
|
||||
if (templ->stencil[1].enabled) {
|
||||
ds->stencil[1].func = svga_translate_compare_func(templ->stencil[1].func);
|
||||
ds->stencil[1].fail = svga_translate_stencil_op(templ->stencil[1].fail_op);
|
||||
ds->stencil[1].zfail = svga_translate_stencil_op(templ->stencil[1].zfail_op);
|
||||
ds->stencil[1].pass = svga_translate_stencil_op(templ->stencil[1].zpass_op);
|
||||
|
||||
ds->stencil_ref = templ->stencil[1].ref_value & 0xff;
|
||||
ds->stencil_mask = templ->stencil[1].valuemask & 0xff;
|
||||
ds->stencil_writemask = templ->stencil[1].writemask & 0xff;
|
||||
}
|
||||
|
||||
|
||||
ds->zenable = templ->depth.enabled;
|
||||
if (ds->zenable) {
|
||||
ds->zfunc = svga_translate_compare_func(templ->depth.func);
|
||||
ds->zwriteenable = templ->depth.writemask;
|
||||
}
|
||||
|
||||
ds->alphatestenable = templ->alpha.enabled;
|
||||
if (ds->alphatestenable) {
|
||||
ds->alphafunc = svga_translate_compare_func(templ->alpha.func);
|
||||
ds->alpharef = templ->alpha.ref_value;
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
static void svga_bind_depth_stencil_state(struct pipe_context *pipe,
|
||||
void *depth_stencil)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.depth = (const struct svga_depth_stencil_state *)depth_stencil;
|
||||
svga->dirty |= SVGA_NEW_DEPTH_STENCIL;
|
||||
}
|
||||
|
||||
static void svga_delete_depth_stencil_state(struct pipe_context *pipe,
|
||||
void *depth_stencil)
|
||||
{
|
||||
FREE(depth_stencil);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void svga_init_depth_stencil_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_depth_stencil_alpha_state = svga_create_depth_stencil_state;
|
||||
svga->pipe.bind_depth_stencil_alpha_state = svga_bind_depth_stencil_state;
|
||||
svga->pipe.delete_depth_stencil_alpha_state = svga_delete_depth_stencil_state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
261
src/gallium/drivers/svga/svga_pipe_draw.c
Normal file
261
src/gallium/drivers/svga/svga_pipe_draw.c
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "util/u_time.h"
|
||||
#include "indices/u_indices.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_swtnl.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
retry_draw_range_elements( struct svga_context *svga,
|
||||
struct pipe_buffer *index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
boolean do_retry )
|
||||
{
|
||||
enum pipe_error ret = 0;
|
||||
|
||||
svga_hwtnl_set_unfilled( svga->hwtnl,
|
||||
svga->curr.rast->hw_unfilled );
|
||||
|
||||
svga_hwtnl_set_flatshade( svga->hwtnl,
|
||||
svga->curr.rast->templ.flatshade,
|
||||
svga->curr.rast->templ.flatshade_first );
|
||||
|
||||
|
||||
ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
|
||||
if (ret)
|
||||
goto retry;
|
||||
|
||||
ret = svga_hwtnl_draw_range_elements( svga->hwtnl,
|
||||
index_buffer, index_size,
|
||||
min_index, max_index,
|
||||
prim, start, count, 0 );
|
||||
if (ret)
|
||||
goto retry;
|
||||
|
||||
if (svga->curr.any_user_vertex_buffers) {
|
||||
ret = svga_hwtnl_flush( svga->hwtnl );
|
||||
if (ret)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
|
||||
retry:
|
||||
svga_context_flush( svga, NULL );
|
||||
|
||||
if (do_retry)
|
||||
{
|
||||
return retry_draw_range_elements( svga,
|
||||
index_buffer, index_size,
|
||||
min_index, max_index,
|
||||
prim, start, count,
|
||||
FALSE );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
retry_draw_arrays( struct svga_context *svga,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
boolean do_retry )
|
||||
{
|
||||
enum pipe_error ret;
|
||||
|
||||
svga_hwtnl_set_unfilled( svga->hwtnl,
|
||||
svga->curr.rast->hw_unfilled );
|
||||
|
||||
svga_hwtnl_set_flatshade( svga->hwtnl,
|
||||
svga->curr.rast->templ.flatshade,
|
||||
svga->curr.rast->templ.flatshade_first );
|
||||
|
||||
ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
|
||||
if (ret)
|
||||
goto retry;
|
||||
|
||||
ret = svga_hwtnl_draw_arrays( svga->hwtnl, prim,
|
||||
start, count );
|
||||
if (ret)
|
||||
goto retry;
|
||||
|
||||
if (svga->curr.any_user_vertex_buffers) {
|
||||
ret = svga_hwtnl_flush( svga->hwtnl );
|
||||
if (ret)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
retry:
|
||||
if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry)
|
||||
{
|
||||
svga_context_flush( svga, NULL );
|
||||
|
||||
return retry_draw_arrays( svga,
|
||||
prim,
|
||||
start,
|
||||
count,
|
||||
FALSE );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static boolean
|
||||
svga_draw_range_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer *index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
unsigned reduced_prim = u_reduced_prim(prim);
|
||||
enum pipe_error ret = 0;
|
||||
|
||||
if (!u_trim_pipe_prim( prim, &count ))
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* Mark currently bound target surfaces as dirty
|
||||
* doesn't really matter if it is done before drawing.
|
||||
*
|
||||
* TODO If we ever normaly return something other then
|
||||
* true we should not mark it as dirty then.
|
||||
*/
|
||||
svga_mark_surfaces_dirty(svga_context(pipe));
|
||||
|
||||
if (svga->curr.reduced_prim != reduced_prim) {
|
||||
svga->curr.reduced_prim = reduced_prim;
|
||||
svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
|
||||
}
|
||||
|
||||
svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL );
|
||||
|
||||
#ifdef DEBUG
|
||||
if (svga->curr.vs->base.id == svga->debug.disable_shader ||
|
||||
svga->curr.fs->base.id == svga->debug.disable_shader)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (svga->state.sw.need_swtnl)
|
||||
{
|
||||
ret = svga_swtnl_draw_range_elements( svga,
|
||||
index_buffer,
|
||||
index_size,
|
||||
min_index, max_index,
|
||||
prim,
|
||||
start, count );
|
||||
}
|
||||
else {
|
||||
if (index_buffer) {
|
||||
ret = retry_draw_range_elements( svga,
|
||||
index_buffer,
|
||||
index_size,
|
||||
min_index,
|
||||
max_index,
|
||||
prim,
|
||||
start,
|
||||
count,
|
||||
TRUE );
|
||||
}
|
||||
else {
|
||||
ret = retry_draw_arrays( svga,
|
||||
prim,
|
||||
start,
|
||||
count,
|
||||
TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
if (SVGA_DEBUG & DEBUG_FLUSH) {
|
||||
static unsigned id;
|
||||
debug_printf("%s %d\n", __FUNCTION__, id++);
|
||||
if (id > 1300)
|
||||
util_time_sleep( 2000 );
|
||||
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
svga_context_flush(svga, NULL);
|
||||
}
|
||||
|
||||
return ret == PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
svga_draw_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer *index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return svga_draw_range_elements( pipe, index_buffer,
|
||||
index_size,
|
||||
0, 0xffffffff,
|
||||
prim, start, count );
|
||||
}
|
||||
|
||||
static boolean
|
||||
svga_draw_arrays( struct pipe_context *pipe,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return svga_draw_range_elements(pipe, NULL, 0,
|
||||
start, start + count - 1,
|
||||
prim,
|
||||
start, count);
|
||||
}
|
||||
|
||||
|
||||
void svga_init_draw_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.draw_arrays = svga_draw_arrays;
|
||||
svga->pipe.draw_elements = svga_draw_elements;
|
||||
svga->pipe.draw_range_elements = svga_draw_range_elements;
|
||||
}
|
||||
68
src/gallium/drivers/svga/svga_pipe_flush.c
Normal file
68
src/gallium/drivers/svga/svga_pipe_flush.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static void svga_flush( struct pipe_context *pipe,
|
||||
unsigned flags,
|
||||
struct pipe_fence_handle **fence )
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
int i;
|
||||
|
||||
/* Emit buffered drawing commands.
|
||||
*/
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
|
||||
/* Emit back-copy from render target view to texture.
|
||||
*/
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
if (svga->curr.framebuffer.cbufs[i])
|
||||
svga_propagate_surface(pipe, svga->curr.framebuffer.cbufs[i]);
|
||||
}
|
||||
if (svga->curr.framebuffer.zsbuf)
|
||||
svga_propagate_surface(pipe, svga->curr.framebuffer.zsbuf);
|
||||
|
||||
/* Flush command queue.
|
||||
*/
|
||||
svga_context_flush(svga, fence);
|
||||
}
|
||||
|
||||
|
||||
void svga_init_flush_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.flush = svga_flush;
|
||||
}
|
||||
124
src/gallium/drivers/svga/svga_pipe_fs.c
Normal file
124
src/gallium/drivers/svga/svga_pipe_fs.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_text.h"
|
||||
|
||||
#include "svga_screen.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Fragment shaders
|
||||
*/
|
||||
|
||||
static void *
|
||||
svga_create_fs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_screen *svgascreen = svga_screen(pipe->screen);
|
||||
struct svga_fragment_shader *fs;
|
||||
|
||||
fs = CALLOC_STRUCT(svga_fragment_shader);
|
||||
if (!fs)
|
||||
return NULL;
|
||||
|
||||
fs->base.tokens = tgsi_dup_tokens(templ->tokens);
|
||||
|
||||
/* Collect basic info that we'll need later:
|
||||
*/
|
||||
tgsi_scan_shader(fs->base.tokens, &fs->base.info);
|
||||
|
||||
fs->base.id = svga->debug.shader_id++;
|
||||
fs->base.use_sm30 = svgascreen->use_ps30;
|
||||
|
||||
if (SVGA_DEBUG & DEBUG_TGSI || 0) {
|
||||
debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
|
||||
__FUNCTION__, fs->base.id,
|
||||
fs->base.info.num_inputs, fs->base.info.num_outputs);
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
static void
|
||||
svga_bind_fs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.fs = fs;
|
||||
svga->dirty |= SVGA_NEW_FS;
|
||||
}
|
||||
|
||||
static
|
||||
void svga_delete_fs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
|
||||
struct svga_shader_result *result, *tmp;
|
||||
enum pipe_error ret;
|
||||
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
|
||||
for (result = fs->base.results; result; result = tmp ) {
|
||||
tmp = result->next;
|
||||
|
||||
ret = SVGA3D_DestroyShader(svga->swc,
|
||||
result->id,
|
||||
SVGA3D_SHADERTYPE_PS );
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = SVGA3D_DestroyShader(svga->swc,
|
||||
result->id,
|
||||
SVGA3D_SHADERTYPE_PS );
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
svga_destroy_shader_result( result );
|
||||
}
|
||||
|
||||
FREE((void *)fs->base.tokens);
|
||||
FREE(fs);
|
||||
}
|
||||
|
||||
|
||||
void svga_init_fs_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_fs_state = svga_create_fs_state;
|
||||
svga->pipe.bind_fs_state = svga_bind_fs_state;
|
||||
svga->pipe.delete_fs_state = svga_delete_fs_state;
|
||||
}
|
||||
|
||||
187
src/gallium/drivers/svga/svga_pipe_misc.c
Normal file
187
src/gallium/drivers/svga/svga_pipe_misc.c
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_winsys.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static void svga_set_scissor_state( struct pipe_context *pipe,
|
||||
const struct pipe_scissor_state *scissor )
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
memcpy( &svga->curr.scissor, scissor, sizeof(*scissor) );
|
||||
svga->dirty |= SVGA_NEW_SCISSOR;
|
||||
}
|
||||
|
||||
|
||||
static void svga_set_polygon_stipple( struct pipe_context *pipe,
|
||||
const struct pipe_poly_stipple *stipple )
|
||||
{
|
||||
/* overridden by the draw module */
|
||||
}
|
||||
|
||||
|
||||
void svga_cleanup_framebuffer(struct svga_context *svga)
|
||||
{
|
||||
struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
|
||||
struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
pipe_surface_reference(&curr->cbufs[i], NULL);
|
||||
pipe_surface_reference(&hw->cbufs[i], NULL);
|
||||
}
|
||||
|
||||
pipe_surface_reference(&curr->zsbuf, NULL);
|
||||
pipe_surface_reference(&hw->zsbuf, NULL);
|
||||
}
|
||||
|
||||
|
||||
#define DEPTH_BIAS_SCALE_FACTOR_D16 ((float)(1<<15))
|
||||
#define DEPTH_BIAS_SCALE_FACTOR_D24S8 ((float)(1<<23))
|
||||
#define DEPTH_BIAS_SCALE_FACTOR_D32 ((float)(1<<31))
|
||||
|
||||
|
||||
static void svga_set_framebuffer_state(struct pipe_context *pipe,
|
||||
const struct pipe_framebuffer_state *fb)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct pipe_framebuffer_state *dst = &svga->curr.framebuffer;
|
||||
boolean propagate = FALSE;
|
||||
int i;
|
||||
|
||||
dst->width = fb->width;
|
||||
dst->height = fb->height;
|
||||
dst->nr_cbufs = fb->nr_cbufs;
|
||||
|
||||
/* check if we need to propaget any of the target surfaces */
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
if (dst->cbufs[i] && dst->cbufs[i] != fb->cbufs[i])
|
||||
if (svga_surface_needs_propagation(dst->cbufs[i]))
|
||||
propagate = TRUE;
|
||||
}
|
||||
|
||||
if (propagate) {
|
||||
/* make sure that drawing calls comes before propagation calls */
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
if (dst->cbufs[i] && dst->cbufs[i] != fb->cbufs[i])
|
||||
svga_propagate_surface(pipe, dst->cbufs[i]);
|
||||
}
|
||||
|
||||
/* XXX: Actually the virtual hardware may support rendertargets with
|
||||
* different size, depending on the host API and driver, but since we cannot
|
||||
* know that make no such assumption here. */
|
||||
for(i = 0; i < fb->nr_cbufs; ++i) {
|
||||
if (fb->zsbuf && fb->cbufs[i]) {
|
||||
assert(fb->zsbuf->width == fb->cbufs[i]->width);
|
||||
assert(fb->zsbuf->height == fb->cbufs[i]->height);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
pipe_surface_reference(&dst->cbufs[i], fb->cbufs[i]);
|
||||
pipe_surface_reference(&dst->zsbuf, fb->zsbuf);
|
||||
|
||||
|
||||
if (svga->curr.framebuffer.zsbuf)
|
||||
{
|
||||
switch (svga->curr.framebuffer.zsbuf->format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D16;
|
||||
break;
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D24S8;
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D32;
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_FLOAT:
|
||||
svga->curr.depthscale = 1.0f / ((float)(1<<23));
|
||||
break;
|
||||
default:
|
||||
svga->curr.depthscale = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
svga->curr.depthscale = 0.0f;
|
||||
}
|
||||
|
||||
svga->dirty |= SVGA_NEW_FRAME_BUFFER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void svga_set_clip_state( struct pipe_context *pipe,
|
||||
const struct pipe_clip_state *clip )
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.clip = *clip; /* struct copy */
|
||||
|
||||
svga->dirty |= SVGA_NEW_CLIP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called when driver state tracker notices changes to the viewport
|
||||
* matrix:
|
||||
*/
|
||||
static void svga_set_viewport_state( struct pipe_context *pipe,
|
||||
const struct pipe_viewport_state *viewport )
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.viewport = *viewport; /* struct copy */
|
||||
|
||||
svga->dirty |= SVGA_NEW_VIEWPORT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void svga_init_misc_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.set_scissor_state = svga_set_scissor_state;
|
||||
svga->pipe.set_polygon_stipple = svga_set_polygon_stipple;
|
||||
svga->pipe.set_framebuffer_state = svga_set_framebuffer_state;
|
||||
svga->pipe.set_clip_state = svga_set_clip_state;
|
||||
svga->pipe.set_viewport_state = svga_set_viewport_state;
|
||||
}
|
||||
|
||||
|
||||
267
src/gallium/drivers/svga/svga_pipe_query.c
Normal file
267
src/gallium/drivers/svga/svga_pipe_query.c
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
|
||||
/* Fixme: want a public base class for all pipe structs, even if there
|
||||
* isn't much in them.
|
||||
*/
|
||||
struct pipe_query {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
struct svga_query {
|
||||
struct pipe_query base;
|
||||
SVGA3dQueryType type;
|
||||
struct svga_winsys_buffer *hwbuf;
|
||||
volatile SVGA3dQueryResult *queryResult;
|
||||
struct pipe_fence_handle *fence;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Inline conversion functions. These are better-typed than the
|
||||
* macros used previously:
|
||||
*/
|
||||
static INLINE struct svga_query *
|
||||
svga_query( struct pipe_query *q )
|
||||
{
|
||||
return (struct svga_query *)q;
|
||||
}
|
||||
|
||||
static boolean svga_get_query_result(struct pipe_context *pipe,
|
||||
struct pipe_query *q,
|
||||
boolean wait,
|
||||
uint64_t *result);
|
||||
|
||||
static struct pipe_query *svga_create_query( struct pipe_context *pipe,
|
||||
unsigned query_type )
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(pipe->screen);
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_query *sq;
|
||||
|
||||
SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
|
||||
|
||||
sq = CALLOC_STRUCT(svga_query);
|
||||
if (!sq)
|
||||
goto no_sq;
|
||||
|
||||
sq->type = SVGA3D_QUERYTYPE_OCCLUSION;
|
||||
|
||||
sq->hwbuf = svga_winsys_buffer_create(svgascreen,
|
||||
1,
|
||||
SVGA_BUFFER_USAGE_PINNED,
|
||||
sizeof *sq->queryResult);
|
||||
if(!sq->hwbuf)
|
||||
goto no_hwbuf;
|
||||
|
||||
sq->queryResult = (SVGA3dQueryResult *)sws->buffer_map(sws,
|
||||
sq->hwbuf,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
if(!sq->queryResult)
|
||||
goto no_query_result;
|
||||
|
||||
sq->queryResult->totalSize = sizeof *sq->queryResult;
|
||||
sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
|
||||
|
||||
/*
|
||||
* We request the buffer to be pinned and assume it is always mapped.
|
||||
*
|
||||
* The reason is that we don't want to wait for fences when checking the
|
||||
* query status.
|
||||
*/
|
||||
sws->buffer_unmap(sws, sq->hwbuf);
|
||||
|
||||
return &sq->base;
|
||||
|
||||
no_query_result:
|
||||
sws->buffer_destroy(sws, sq->hwbuf);
|
||||
no_hwbuf:
|
||||
FREE(sq);
|
||||
no_sq:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void svga_destroy_query(struct pipe_context *pipe,
|
||||
struct pipe_query *q)
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(pipe->screen);
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_query *sq = svga_query( q );
|
||||
|
||||
SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
|
||||
sws->buffer_destroy(sws, sq->hwbuf);
|
||||
sws->fence_reference(sws, &sq->fence, NULL);
|
||||
FREE(sq);
|
||||
}
|
||||
|
||||
static void svga_begin_query(struct pipe_context *pipe,
|
||||
struct pipe_query *q)
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(pipe->screen);
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
struct svga_query *sq = svga_query( q );
|
||||
enum pipe_error ret;
|
||||
|
||||
SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
|
||||
|
||||
assert(!svga->sq);
|
||||
|
||||
/* Need to flush out buffered drawing commands so that they don't
|
||||
* get counted in the query results.
|
||||
*/
|
||||
svga_hwtnl_flush_retry(svga);
|
||||
|
||||
if(sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
|
||||
/* The application doesn't care for the pending query result. We cannot
|
||||
* let go the existing buffer and just get a new one because its storage
|
||||
* may be reused for other purposes and clobbered by the host when it
|
||||
* determines the query result. So the only option here is to wait for
|
||||
* the existing query's result -- not a big deal, given that no sane
|
||||
* application would do this.
|
||||
*/
|
||||
uint64_t result;
|
||||
|
||||
svga_get_query_result(pipe, q, TRUE, &result);
|
||||
|
||||
assert(sq->queryResult->state != SVGA3D_QUERYSTATE_PENDING);
|
||||
}
|
||||
|
||||
sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
|
||||
sws->fence_reference(sws, &sq->fence, NULL);
|
||||
|
||||
ret = SVGA3D_BeginQuery(svga->swc, sq->type);
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = SVGA3D_BeginQuery(svga->swc, sq->type);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
svga->sq = sq;
|
||||
}
|
||||
|
||||
static void svga_end_query(struct pipe_context *pipe,
|
||||
struct pipe_query *q)
|
||||
{
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
struct svga_query *sq = svga_query( q );
|
||||
enum pipe_error ret;
|
||||
|
||||
SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
|
||||
assert(svga->sq == sq);
|
||||
|
||||
svga_hwtnl_flush_retry(svga);
|
||||
|
||||
/* Set to PENDING before sending EndQuery. */
|
||||
sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;
|
||||
|
||||
ret = SVGA3D_EndQuery( svga->swc, sq->type, sq->hwbuf);
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = SVGA3D_EndQuery( svga->swc, sq->type, sq->hwbuf);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
/* TODO: Delay flushing. We don't really need to flush here, just ensure
|
||||
* that there is one flush before svga_get_query_result attempts to get the
|
||||
* result */
|
||||
svga_context_flush(svga, NULL);
|
||||
|
||||
svga->sq = NULL;
|
||||
}
|
||||
|
||||
static boolean svga_get_query_result(struct pipe_context *pipe,
|
||||
struct pipe_query *q,
|
||||
boolean wait,
|
||||
uint64_t *result)
|
||||
{
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
struct svga_screen *svgascreen = svga_screen( pipe->screen );
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_query *sq = svga_query( q );
|
||||
SVGA3dQueryState state;
|
||||
|
||||
SVGA_DBG(DEBUG_QUERY, "%s wait: %d\n", __FUNCTION__);
|
||||
|
||||
/* The query status won't be updated by the host unless
|
||||
* SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause a
|
||||
* synchronous wait on the host */
|
||||
if(!sq->fence) {
|
||||
enum pipe_error ret;
|
||||
|
||||
ret = SVGA3D_WaitForQuery( svga->swc, sq->type, sq->hwbuf);
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = SVGA3D_WaitForQuery( svga->swc, sq->type, sq->hwbuf);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
svga_context_flush(svga, &sq->fence);
|
||||
|
||||
assert(sq->fence);
|
||||
}
|
||||
|
||||
state = sq->queryResult->state;
|
||||
if(state == SVGA3D_QUERYSTATE_PENDING) {
|
||||
if(!wait)
|
||||
return FALSE;
|
||||
|
||||
sws->fence_finish(sws, sq->fence, 0);
|
||||
|
||||
state = sq->queryResult->state;
|
||||
}
|
||||
|
||||
assert(state == SVGA3D_QUERYSTATE_SUCCEEDED ||
|
||||
state == SVGA3D_QUERYSTATE_FAILED);
|
||||
|
||||
*result = (uint64_t)sq->queryResult->result32;
|
||||
|
||||
SVGA_DBG(DEBUG_QUERY, "%s result %d\n", __FUNCTION__, (unsigned)*result);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void svga_init_query_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_query = svga_create_query;
|
||||
svga->pipe.destroy_query = svga_destroy_query;
|
||||
svga->pipe.begin_query = svga_begin_query;
|
||||
svga->pipe.end_query = svga_end_query;
|
||||
svga->pipe.get_query_result = svga_get_query_result;
|
||||
}
|
||||
250
src/gallium/drivers/svga/svga_pipe_rasterizer.c
Normal file
250
src/gallium/drivers/svga/svga_pipe_rasterizer.c
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
/* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW.
|
||||
*/
|
||||
static SVGA3dFace svga_translate_cullmode( unsigned mode,
|
||||
unsigned front_winding )
|
||||
{
|
||||
switch (mode) {
|
||||
case PIPE_WINDING_NONE:
|
||||
return SVGA3D_FACE_NONE;
|
||||
case PIPE_WINDING_CCW:
|
||||
return SVGA3D_FACE_BACK;
|
||||
case PIPE_WINDING_CW:
|
||||
return SVGA3D_FACE_FRONT;
|
||||
case PIPE_WINDING_BOTH:
|
||||
return SVGA3D_FACE_FRONT_BACK;
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_FACE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static SVGA3dShadeMode svga_translate_flatshade( unsigned mode )
|
||||
{
|
||||
return mode ? SVGA3D_SHADEMODE_FLAT : SVGA3D_SHADEMODE_SMOOTH;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
svga_create_rasterizer_state(struct pipe_context *pipe,
|
||||
const struct pipe_rasterizer_state *templ)
|
||||
{
|
||||
struct svga_rasterizer_state *rast = CALLOC_STRUCT( svga_rasterizer_state );
|
||||
/* need this for draw module. */
|
||||
rast->templ = *templ;
|
||||
|
||||
/* light_twoside - XXX: need fragment shader varient */
|
||||
/* poly_smooth - XXX: no fallback available */
|
||||
/* poly_stipple_enable - draw module */
|
||||
/* point_sprite - ? */
|
||||
/* point_size_per_vertex - ? */
|
||||
/* sprite_coord_mode - ??? */
|
||||
/* bypass_vs_viewport_and_clip - handled by viewport setup */
|
||||
/* flatshade_first - handled by index translation */
|
||||
/* gl_rasterization_rules - XXX - viewport code */
|
||||
/* line_width - draw module */
|
||||
/* fill_cw, fill_ccw - draw module or index translation */
|
||||
|
||||
rast->shademode = svga_translate_flatshade( templ->flatshade );
|
||||
rast->cullmode = svga_translate_cullmode( templ->cull_mode,
|
||||
templ->front_winding );
|
||||
rast->scissortestenable = templ->scissor;
|
||||
rast->multisampleantialias = templ->multisample;
|
||||
rast->antialiasedlineenable = templ->line_smooth;
|
||||
rast->lastpixel = templ->line_last_pixel;
|
||||
rast->pointsize = templ->point_size;
|
||||
rast->pointsize_min = templ->point_size_min;
|
||||
rast->pointsize_max = templ->point_size_max;
|
||||
rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
|
||||
|
||||
/* Use swtnl + decomposition implement these:
|
||||
*/
|
||||
if (templ->poly_stipple_enable)
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
|
||||
|
||||
if (templ->line_width != 1.0 &&
|
||||
templ->line_width != 0.0)
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
|
||||
|
||||
if (templ->line_stipple_enable) {
|
||||
/* LinePattern not implemented on all backends.
|
||||
*/
|
||||
if (0) {
|
||||
SVGA3dLinePattern lp;
|
||||
lp.repeat = templ->line_stipple_factor + 1;
|
||||
lp.pattern = templ->line_stipple_pattern;
|
||||
rast->linepattern = lp.uintValue;
|
||||
}
|
||||
else {
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
|
||||
}
|
||||
}
|
||||
|
||||
if (templ->point_smooth)
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS;
|
||||
|
||||
{
|
||||
boolean offset_cw = templ->offset_cw;
|
||||
boolean offset_ccw = templ->offset_ccw;
|
||||
boolean offset = 0;
|
||||
int fill_cw = templ->fill_cw;
|
||||
int fill_ccw = templ->fill_ccw;
|
||||
int fill = PIPE_POLYGON_MODE_FILL;
|
||||
|
||||
switch (templ->cull_mode) {
|
||||
case PIPE_WINDING_BOTH:
|
||||
offset = 0;
|
||||
fill = PIPE_POLYGON_MODE_FILL;
|
||||
break;
|
||||
|
||||
case PIPE_WINDING_CW:
|
||||
offset = offset_ccw;
|
||||
fill = fill_ccw;
|
||||
break;
|
||||
|
||||
case PIPE_WINDING_CCW:
|
||||
offset = offset_cw;
|
||||
fill = fill_cw;
|
||||
break;
|
||||
|
||||
case PIPE_WINDING_NONE:
|
||||
if (fill_cw != fill_ccw || offset_cw != offset_ccw)
|
||||
{
|
||||
/* Always need the draw module to work out different
|
||||
* front/back fill modes:
|
||||
*/
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
|
||||
}
|
||||
else {
|
||||
offset = offset_ccw;
|
||||
fill = fill_ccw;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unfilled primitive modes aren't implemented on all virtual
|
||||
* hardware. We can do some unfilled processing with index
|
||||
* translation, but otherwise need the draw module:
|
||||
*/
|
||||
if (fill != PIPE_POLYGON_MODE_FILL &&
|
||||
(templ->flatshade ||
|
||||
templ->light_twoside ||
|
||||
offset ||
|
||||
templ->cull_mode != PIPE_WINDING_NONE))
|
||||
{
|
||||
fill = PIPE_POLYGON_MODE_FILL;
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
|
||||
}
|
||||
|
||||
/* If we are decomposing to lines, and lines need the pipeline,
|
||||
* then we also need the pipeline for tris.
|
||||
*/
|
||||
if (fill == PIPE_POLYGON_MODE_LINE &&
|
||||
(rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES))
|
||||
{
|
||||
fill = PIPE_POLYGON_MODE_FILL;
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
|
||||
}
|
||||
|
||||
/* Similarly for points:
|
||||
*/
|
||||
if (fill == PIPE_POLYGON_MODE_POINT &&
|
||||
(rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS))
|
||||
{
|
||||
fill = PIPE_POLYGON_MODE_FILL;
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
rast->slopescaledepthbias = templ->offset_scale;
|
||||
rast->depthbias = templ->offset_units;
|
||||
}
|
||||
|
||||
rast->hw_unfilled = fill;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (rast->need_pipeline & SVGA_PIPELINE_FLAG_TRIS) {
|
||||
/* Turn off stuff which will get done in the draw module:
|
||||
*/
|
||||
rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
|
||||
rast->slopescaledepthbias = 0;
|
||||
rast->depthbias = 0;
|
||||
}
|
||||
|
||||
return rast;
|
||||
}
|
||||
|
||||
static void svga_bind_rasterizer_state( struct pipe_context *pipe,
|
||||
void *state )
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state;
|
||||
|
||||
svga->curr.rast = raster;
|
||||
|
||||
draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL);
|
||||
|
||||
svga->dirty |= SVGA_NEW_RAST;
|
||||
}
|
||||
|
||||
static void svga_delete_rasterizer_state(struct pipe_context *pipe,
|
||||
void *raster)
|
||||
{
|
||||
FREE(raster);
|
||||
}
|
||||
|
||||
|
||||
void svga_init_rasterizer_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_rasterizer_state = svga_create_rasterizer_state;
|
||||
svga->pipe.bind_rasterizer_state = svga_bind_rasterizer_state;
|
||||
svga->pipe.delete_rasterizer_state = svga_delete_rasterizer_state;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Hardware state update
|
||||
*/
|
||||
|
||||
243
src/gallium/drivers/svga/svga_pipe_sampler.c
Normal file
243
src/gallium/drivers/svga/svga_pipe_sampler.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_pack_color.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_state.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
#include "svga_debug.h"
|
||||
|
||||
static INLINE unsigned
|
||||
translate_wrap_mode(unsigned wrap)
|
||||
{
|
||||
switch (wrap) {
|
||||
case PIPE_TEX_WRAP_REPEAT:
|
||||
return SVGA3D_TEX_ADDRESS_WRAP;
|
||||
|
||||
case PIPE_TEX_WRAP_CLAMP:
|
||||
return SVGA3D_TEX_ADDRESS_CLAMP;
|
||||
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
||||
/* Unfortunately SVGA3D_TEX_ADDRESS_EDGE not respected by
|
||||
* hardware.
|
||||
*/
|
||||
return SVGA3D_TEX_ADDRESS_CLAMP;
|
||||
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
||||
return SVGA3D_TEX_ADDRESS_BORDER;
|
||||
|
||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
||||
return SVGA3D_TEX_ADDRESS_MIRROR;
|
||||
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
||||
return SVGA3D_TEX_ADDRESS_MIRRORONCE;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_TEX_ADDRESS_WRAP;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE unsigned translate_img_filter( unsigned filter )
|
||||
{
|
||||
switch (filter) {
|
||||
case PIPE_TEX_FILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST;
|
||||
case PIPE_TEX_FILTER_LINEAR: return SVGA3D_TEX_FILTER_LINEAR;
|
||||
case PIPE_TEX_FILTER_ANISO: return SVGA3D_TEX_FILTER_ANISOTROPIC;
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_TEX_FILTER_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE unsigned translate_mip_filter( unsigned filter )
|
||||
{
|
||||
switch (filter) {
|
||||
case PIPE_TEX_MIPFILTER_NONE: return SVGA3D_TEX_FILTER_NONE;
|
||||
case PIPE_TEX_MIPFILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST;
|
||||
case PIPE_TEX_MIPFILTER_LINEAR: return SVGA3D_TEX_FILTER_LINEAR;
|
||||
default:
|
||||
assert(0);
|
||||
return SVGA3D_TEX_FILTER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
svga_create_sampler_state(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *sampler)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_sampler_state *cso = CALLOC_STRUCT( svga_sampler_state );
|
||||
|
||||
cso->mipfilter = translate_mip_filter(sampler->min_mip_filter);
|
||||
cso->magfilter = translate_img_filter( sampler->mag_img_filter );
|
||||
cso->minfilter = translate_img_filter( sampler->min_img_filter );
|
||||
cso->aniso_level = MAX2( (unsigned) sampler->max_anisotropy, 1 );
|
||||
cso->lod_bias = sampler->lod_bias;
|
||||
cso->addressu = translate_wrap_mode(sampler->wrap_s);
|
||||
cso->addressv = translate_wrap_mode(sampler->wrap_t);
|
||||
cso->addressw = translate_wrap_mode(sampler->wrap_r);
|
||||
cso->normalized_coords = sampler->normalized_coords;
|
||||
cso->compare_mode = sampler->compare_mode;
|
||||
cso->compare_func = sampler->compare_func;
|
||||
|
||||
{
|
||||
ubyte r = float_to_ubyte(sampler->border_color[0]);
|
||||
ubyte g = float_to_ubyte(sampler->border_color[1]);
|
||||
ubyte b = float_to_ubyte(sampler->border_color[2]);
|
||||
ubyte a = float_to_ubyte(sampler->border_color[3]);
|
||||
|
||||
util_pack_color_ub( r, g, b, a,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM,
|
||||
&cso->bordercolor );
|
||||
}
|
||||
|
||||
/* No SVGA3D support for:
|
||||
* - min/max LOD clamping
|
||||
*/
|
||||
cso->min_lod = 0;
|
||||
cso->view_min_lod = MAX2(sampler->min_lod, 0);
|
||||
cso->view_max_lod = MAX2(sampler->max_lod, 0);
|
||||
|
||||
/* Use min_mipmap */
|
||||
if (svga->debug.use_min_mipmap) {
|
||||
if (cso->view_min_lod == cso->view_max_lod) {
|
||||
cso->min_lod = cso->view_min_lod;
|
||||
cso->view_min_lod = 0;
|
||||
cso->view_max_lod = 1000; /* Just a high number */
|
||||
cso->mipfilter = SVGA3D_TEX_FILTER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWS, "min %u, view(min %u, max %u) lod, mipfilter %s\n",
|
||||
cso->min_lod, cso->view_min_lod, cso->view_max_lod,
|
||||
cso->mipfilter == SVGA3D_TEX_FILTER_NONE ? "SVGA3D_TEX_FILTER_NONE" : "SOMETHING");
|
||||
|
||||
return cso;
|
||||
}
|
||||
|
||||
static void svga_bind_sampler_states(struct pipe_context *pipe,
|
||||
unsigned num, void **sampler)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
unsigned i;
|
||||
|
||||
assert(num <= PIPE_MAX_SAMPLERS);
|
||||
|
||||
/* Check for no-op */
|
||||
if (num == svga->curr.num_samplers &&
|
||||
!memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) {
|
||||
debug_printf("sampler noop\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
svga->curr.sampler[i] = sampler[i];
|
||||
|
||||
for (i = num; i < svga->curr.num_samplers; i++)
|
||||
svga->curr.sampler[i] = NULL;
|
||||
|
||||
svga->curr.num_samplers = num;
|
||||
svga->dirty |= SVGA_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
static void svga_delete_sampler_state(struct pipe_context *pipe,
|
||||
void *sampler)
|
||||
{
|
||||
FREE(sampler);
|
||||
}
|
||||
|
||||
|
||||
static void svga_set_sampler_textures(struct pipe_context *pipe,
|
||||
unsigned num,
|
||||
struct pipe_texture **texture)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
unsigned flag_1d = 0;
|
||||
unsigned flag_srgb = 0;
|
||||
uint i;
|
||||
|
||||
assert(num <= PIPE_MAX_SAMPLERS);
|
||||
|
||||
/* Check for no-op */
|
||||
if (num == svga->curr.num_textures &&
|
||||
!memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) {
|
||||
if (0) debug_printf("texture noop\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
pipe_texture_reference(&svga->curr.texture[i],
|
||||
texture[i]);
|
||||
|
||||
if (!texture[i])
|
||||
continue;
|
||||
|
||||
if (texture[i]->format == PIPE_FORMAT_A8R8G8B8_SRGB)
|
||||
flag_srgb |= 1 << i;
|
||||
|
||||
if (texture[i]->target == PIPE_TEXTURE_1D)
|
||||
flag_1d |= 1 << i;
|
||||
}
|
||||
|
||||
for (i = num; i < svga->curr.num_textures; i++)
|
||||
pipe_texture_reference(&svga->curr.texture[i],
|
||||
NULL);
|
||||
|
||||
svga->curr.num_textures = num;
|
||||
svga->dirty |= SVGA_NEW_TEXTURE_BINDING;
|
||||
|
||||
if (flag_srgb != svga->curr.tex_flags.flag_srgb ||
|
||||
flag_1d != svga->curr.tex_flags.flag_1d)
|
||||
{
|
||||
svga->dirty |= SVGA_NEW_TEXTURE_FLAGS;
|
||||
svga->curr.tex_flags.flag_1d = flag_1d;
|
||||
svga->curr.tex_flags.flag_srgb = flag_srgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void svga_init_sampler_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_sampler_state = svga_create_sampler_state;
|
||||
svga->pipe.bind_sampler_states = svga_bind_sampler_states;
|
||||
svga->pipe.delete_sampler_state = svga_delete_sampler_state;
|
||||
svga->pipe.set_sampler_textures = svga_set_sampler_textures;
|
||||
}
|
||||
|
||||
|
||||
|
||||
115
src/gallium/drivers/svga/svga_pipe_vertex.c
Normal file
115
src/gallium/drivers/svga/svga_pipe_vertex.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_winsys.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
static void svga_set_vertex_buffers(struct pipe_context *pipe,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_buffer *buffers)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
unsigned i;
|
||||
boolean any_user_buffer = FALSE;
|
||||
|
||||
/* Check for no change */
|
||||
if (count == svga->curr.num_vertex_buffers &&
|
||||
memcmp(svga->curr.vb, buffers, count * sizeof buffers[0]) == 0)
|
||||
return;
|
||||
|
||||
/* Adjust refcounts */
|
||||
for (i = 0; i < count; i++) {
|
||||
pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
|
||||
if (svga_buffer(buffers[i].buffer)->user)
|
||||
any_user_buffer = TRUE;
|
||||
}
|
||||
|
||||
for ( ; i < svga->curr.num_vertex_buffers; i++)
|
||||
pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL);
|
||||
|
||||
/* Copy remaining data */
|
||||
memcpy(svga->curr.vb, buffers, count * sizeof buffers[0]);
|
||||
svga->curr.num_vertex_buffers = count;
|
||||
svga->curr.any_user_vertex_buffers = any_user_buffer;
|
||||
|
||||
svga->dirty |= SVGA_NEW_VBUFFER;
|
||||
}
|
||||
|
||||
static void svga_set_vertex_elements(struct pipe_context *pipe,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_element *elements)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
svga->curr.ve[i] = elements[i];
|
||||
|
||||
svga->curr.num_vertex_elements = count;
|
||||
svga->dirty |= SVGA_NEW_VELEMENT;
|
||||
}
|
||||
|
||||
|
||||
static void svga_set_edgeflags(struct pipe_context *pipe,
|
||||
const unsigned *bitfield)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
if (bitfield != NULL || svga->curr.edgeflags != NULL) {
|
||||
svga->curr.edgeflags = bitfield;
|
||||
svga->dirty |= SVGA_NEW_EDGEFLAGS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void svga_cleanup_vertex_state( struct svga_context *svga )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0 ; i < svga->curr.num_vertex_buffers; i++)
|
||||
pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL);
|
||||
}
|
||||
|
||||
|
||||
void svga_init_vertex_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
|
||||
svga->pipe.set_vertex_elements = svga_set_vertex_elements;
|
||||
svga->pipe.set_edgeflags = svga_set_edgeflags;
|
||||
}
|
||||
|
||||
|
||||
189
src/gallium/drivers/svga/svga_pipe_vs.c
Normal file
189
src/gallium/drivers/svga/svga_pipe_vs.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_text.h"
|
||||
|
||||
#include "svga_screen.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
|
||||
static const struct tgsi_token *substitute_vs(
|
||||
unsigned shader_id,
|
||||
const struct tgsi_token *old_tokens )
|
||||
{
|
||||
#if 0
|
||||
if (shader_id == 12) {
|
||||
static struct tgsi_token tokens[300];
|
||||
|
||||
const char *text =
|
||||
"VERT1.1\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL IN[2]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL TEMP[0..4]\n"
|
||||
"IMM FLT32 { 1.0000, 1.0000, 1.0000, 1.0000 }\n"
|
||||
"IMM FLT32 { 0.45, 1.0000, 1.0000, 1.0000 }\n"
|
||||
"IMM FLT32 { 1.297863, 0.039245, 0.035993, 0.035976}\n"
|
||||
"IMM FLT32 { -0.019398, 1.696131, -0.202151, -0.202050 }\n"
|
||||
"IMM FLT32 { 0.051711, -0.348713, -0.979204, -0.978714 }\n"
|
||||
"IMM FLT32 { 0.000000, 0.000003, 139.491577, 141.421356 }\n"
|
||||
"DCL CONST[0..7]\n"
|
||||
"DCL CONST[9..16]\n"
|
||||
" MOV TEMP[2], IMM[0]\n"
|
||||
|
||||
" MOV TEMP[2].xyz, IN[2]\n"
|
||||
" MOV TEMP[2].xyz, IN[0]\n"
|
||||
" MOV TEMP[2].xyz, IN[1]\n"
|
||||
|
||||
" MUL TEMP[1], IMM[3], TEMP[2].yyyy\n"
|
||||
" MAD TEMP[3], IMM[2], TEMP[2].xxxx, TEMP[1]\n"
|
||||
" MAD TEMP[1], IMM[4], TEMP[2].zzzz, TEMP[3]\n"
|
||||
" MAD TEMP[4], IMM[5], TEMP[2].wwww, TEMP[1]\n"
|
||||
|
||||
" MOV OUT[0], TEMP[4]\n"
|
||||
" END\n";
|
||||
|
||||
if (!tgsi_text_translate( text,
|
||||
tokens,
|
||||
Elements(tokens) ))
|
||||
{
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
#endif
|
||||
|
||||
return old_tokens;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Vertex shaders
|
||||
*/
|
||||
|
||||
static void *
|
||||
svga_create_vs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_screen *svgascreen = svga_screen(pipe->screen);
|
||||
struct svga_vertex_shader *vs = CALLOC_STRUCT(svga_vertex_shader);
|
||||
if (!vs)
|
||||
return NULL;
|
||||
|
||||
/* substitute a debug shader?
|
||||
*/
|
||||
vs->base.tokens = tgsi_dup_tokens(substitute_vs(svga->debug.shader_id,
|
||||
templ->tokens));
|
||||
|
||||
|
||||
/* Collect basic info that we'll need later:
|
||||
*/
|
||||
tgsi_scan_shader(vs->base.tokens, &vs->base.info);
|
||||
|
||||
{
|
||||
/* Need to do construct a new template in case we substitued a
|
||||
* debug shader.
|
||||
*/
|
||||
struct pipe_shader_state tmp2 = *templ;
|
||||
tmp2.tokens = vs->base.tokens;
|
||||
vs->draw_shader = draw_create_vertex_shader(svga->swtnl.draw, &tmp2);
|
||||
}
|
||||
|
||||
vs->base.id = svga->debug.shader_id++;
|
||||
vs->base.use_sm30 = svgascreen->use_vs30;
|
||||
|
||||
if (SVGA_DEBUG & DEBUG_TGSI || 0) {
|
||||
debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
|
||||
__FUNCTION__, vs->base.id,
|
||||
vs->base.info.num_inputs, vs->base.info.num_outputs);
|
||||
}
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
static void svga_bind_vs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
|
||||
svga->curr.vs = vs;
|
||||
svga->dirty |= SVGA_NEW_VS;
|
||||
}
|
||||
|
||||
|
||||
static void svga_delete_vs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
|
||||
struct svga_shader_result *result, *tmp;
|
||||
enum pipe_error ret;
|
||||
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
|
||||
draw_delete_vertex_shader(svga->swtnl.draw, vs->draw_shader);
|
||||
|
||||
for (result = vs->base.results; result; result = tmp ) {
|
||||
tmp = result->next;
|
||||
|
||||
ret = SVGA3D_DestroyShader(svga->swc,
|
||||
result->id,
|
||||
SVGA3D_SHADERTYPE_VS );
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = SVGA3D_DestroyShader(svga->swc,
|
||||
result->id,
|
||||
SVGA3D_SHADERTYPE_VS );
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
svga_destroy_shader_result( result );
|
||||
}
|
||||
|
||||
FREE((void *)vs->base.tokens);
|
||||
FREE(vs);
|
||||
}
|
||||
|
||||
|
||||
void svga_init_vs_functions( struct svga_context *svga )
|
||||
{
|
||||
svga->pipe.create_vs_state = svga_create_vs_state;
|
||||
svga->pipe.bind_vs_state = svga_bind_vs_state;
|
||||
svga->pipe.delete_vs_state = svga_delete_vs_state;
|
||||
}
|
||||
|
||||
435
src/gallium/drivers/svga/svga_screen.c
Normal file
435
src/gallium/drivers/svga/svga_screen.c
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_string.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga3d_shaderdefs.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
int SVGA_DEBUG = 0;
|
||||
|
||||
static const struct debug_named_value svga_debug_flags[] = {
|
||||
{ "dma", DEBUG_DMA },
|
||||
{ "tgsi", DEBUG_TGSI },
|
||||
{ "pipe", DEBUG_PIPE },
|
||||
{ "state", DEBUG_STATE },
|
||||
{ "screen", DEBUG_SCREEN },
|
||||
{ "tex", DEBUG_TEX },
|
||||
{ "swtnl", DEBUG_SWTNL },
|
||||
{ "const", DEBUG_CONSTS },
|
||||
{ "viewport", DEBUG_VIEWPORT },
|
||||
{ "views", DEBUG_VIEWS },
|
||||
{ "perf", DEBUG_PERF },
|
||||
{ "flush", DEBUG_FLUSH },
|
||||
{ "sync", DEBUG_SYNC },
|
||||
{NULL, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
svga_get_vendor( struct pipe_screen *pscreen )
|
||||
{
|
||||
return "VMware, Inc.";
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
svga_get_name( struct pipe_screen *pscreen )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
/* Only return internal details in the DEBUG version:
|
||||
*/
|
||||
return "SVGA3D; build: DEBUG; mutex: " PIPE_ATOMIC;
|
||||
#else
|
||||
return "SVGA3D; build: RELEASE; ";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static float
|
||||
svga_get_paramf(struct pipe_screen *screen, int param)
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(screen);
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
SVGA3dDevCapResult result;
|
||||
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
||||
/* fall-through */
|
||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
||||
return 7.0;
|
||||
|
||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
||||
/* fall-through */
|
||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
||||
/* Keep this to a reasonable size to avoid failures in
|
||||
* conform/pntaa.c:
|
||||
*/
|
||||
return 80.0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
||||
return 4.0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
||||
return 16.0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
||||
return 16;
|
||||
case PIPE_CAP_NPOT_TEXTURES:
|
||||
return 1;
|
||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
||||
return 1;
|
||||
case PIPE_CAP_GLSL:
|
||||
return svgascreen->use_ps30 && svgascreen->use_vs30;
|
||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||
return 1;
|
||||
case PIPE_CAP_POINT_SPRITE:
|
||||
return 1;
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
|
||||
return 1;
|
||||
if(!result.u)
|
||||
return 1;
|
||||
return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
return 1;
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
return 1;
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
return SVGA_MAX_TEXTURE_LEVELS;
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
return 8; /* max 128x128x128 */
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
return SVGA_MAX_TEXTURE_LEVELS;
|
||||
|
||||
case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
|
||||
return 1;
|
||||
|
||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is a fairly pointless interface
|
||||
*/
|
||||
static int
|
||||
svga_get_param(struct pipe_screen *screen, int param)
|
||||
{
|
||||
return (int) svga_get_paramf( screen, param );
|
||||
}
|
||||
|
||||
|
||||
static INLINE SVGA3dDevCapIndex
|
||||
svga_translate_format_cap(enum pipe_format format)
|
||||
{
|
||||
switch(format) {
|
||||
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8;
|
||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8;
|
||||
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5;
|
||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5;
|
||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4;
|
||||
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_Z_D16;
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8;
|
||||
|
||||
case PIPE_FORMAT_A8_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8;
|
||||
case PIPE_FORMAT_L8_UNORM:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8;
|
||||
|
||||
case PIPE_FORMAT_DXT1_RGB:
|
||||
case PIPE_FORMAT_DXT1_RGBA:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_DXT1;
|
||||
case PIPE_FORMAT_DXT3_RGBA:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_DXT3;
|
||||
case PIPE_FORMAT_DXT5_RGBA:
|
||||
return SVGA3D_DEVCAP_SURFACEFMT_DXT5;
|
||||
|
||||
default:
|
||||
return SVGA3D_DEVCAP_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
svga_is_format_supported( struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned tex_usage,
|
||||
unsigned geom_flags )
|
||||
{
|
||||
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
|
||||
SVGA3dDevCapIndex index;
|
||||
SVGA3dDevCapResult result;
|
||||
|
||||
assert(tex_usage);
|
||||
|
||||
/* Override host capabilities */
|
||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
|
||||
switch(format) {
|
||||
|
||||
/* Often unsupported/problematic. This means we end up with the same
|
||||
* visuals for all virtual hardware implementations.
|
||||
*/
|
||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
||||
return FALSE;
|
||||
|
||||
/* Simulate ability to render into compressed textures */
|
||||
case PIPE_FORMAT_DXT1_RGB:
|
||||
case PIPE_FORMAT_DXT1_RGBA:
|
||||
case PIPE_FORMAT_DXT3_RGBA:
|
||||
case PIPE_FORMAT_DXT5_RGBA:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to query the host */
|
||||
index = svga_translate_format_cap(format);
|
||||
if( index < SVGA3D_DEVCAP_MAX &&
|
||||
sws->get_cap(sws, index, &result) )
|
||||
{
|
||||
SVGA3dSurfaceFormatCaps mask;
|
||||
|
||||
mask.value = 0;
|
||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
|
||||
mask.offscreenRenderTarget = 1;
|
||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
|
||||
mask.zStencil = 1;
|
||||
if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
|
||||
mask.texture = 1;
|
||||
|
||||
if ((result.u & mask.value) == mask.value)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Use our translate functions directly rather than relying on a
|
||||
* duplicated list of supported formats which is prone to getting
|
||||
* out of sync:
|
||||
*/
|
||||
if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
|
||||
return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID;
|
||||
else
|
||||
return svga_translate_format(format) != SVGA3D_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
svga_fence_reference(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
|
||||
sws->fence_reference(sws, ptr, fence);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
svga_fence_signalled(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
|
||||
return sws->fence_signalled(sws, fence, flag);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
svga_fence_finish(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
|
||||
return sws->fence_finish(sws, fence, flag);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
svga_destroy_screen( struct pipe_screen *screen )
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(screen);
|
||||
|
||||
svga_screen_cache_cleanup(svgascreen);
|
||||
|
||||
pipe_mutex_destroy(svgascreen->swc_mutex);
|
||||
pipe_mutex_destroy(svgascreen->tex_mutex);
|
||||
|
||||
svgascreen->swc->destroy(svgascreen->swc);
|
||||
|
||||
svgascreen->sws->destroy(svgascreen->sws);
|
||||
|
||||
FREE(svgascreen);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new svga_screen object
|
||||
*/
|
||||
struct pipe_screen *
|
||||
svga_screen_create(struct svga_winsys_screen *sws)
|
||||
{
|
||||
struct svga_screen *svgascreen;
|
||||
struct pipe_screen *screen;
|
||||
SVGA3dDevCapResult result;
|
||||
|
||||
#ifdef DEBUG
|
||||
SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
|
||||
#endif
|
||||
|
||||
svgascreen = CALLOC_STRUCT(svga_screen);
|
||||
if (!svgascreen)
|
||||
goto error1;
|
||||
|
||||
svgascreen->debug.force_level_surface_view =
|
||||
debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
|
||||
svgascreen->debug.force_surface_view =
|
||||
debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
|
||||
svgascreen->debug.force_sampler_view =
|
||||
debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
|
||||
svgascreen->debug.no_surface_view =
|
||||
debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
|
||||
svgascreen->debug.no_sampler_view =
|
||||
debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);
|
||||
|
||||
screen = &svgascreen->screen;
|
||||
|
||||
screen->destroy = svga_destroy_screen;
|
||||
screen->get_name = svga_get_name;
|
||||
screen->get_vendor = svga_get_vendor;
|
||||
screen->get_param = svga_get_param;
|
||||
screen->get_paramf = svga_get_paramf;
|
||||
screen->is_format_supported = svga_is_format_supported;
|
||||
screen->fence_reference = svga_fence_reference;
|
||||
screen->fence_signalled = svga_fence_signalled;
|
||||
screen->fence_finish = svga_fence_finish;
|
||||
svgascreen->sws = sws;
|
||||
|
||||
svga_screen_init_texture_functions(screen);
|
||||
svga_screen_init_buffer_functions(screen);
|
||||
|
||||
svgascreen->use_ps30 =
|
||||
sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
|
||||
result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE;
|
||||
|
||||
svgascreen->use_vs30 =
|
||||
sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) &&
|
||||
result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE;
|
||||
|
||||
#if 1
|
||||
/* Shader model 2.0 is unsupported at the moment. */
|
||||
if(!svgascreen->use_ps30 || !svgascreen->use_vs30)
|
||||
goto error2;
|
||||
#else
|
||||
if(debug_get_bool_option("SVGA_NO_SM30", FALSE))
|
||||
svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE;
|
||||
#endif
|
||||
|
||||
svgascreen->swc = sws->context_create(sws);
|
||||
if(!svgascreen->swc)
|
||||
goto error2;
|
||||
|
||||
pipe_mutex_init(svgascreen->tex_mutex);
|
||||
pipe_mutex_init(svgascreen->swc_mutex);
|
||||
|
||||
LIST_INITHEAD(&svgascreen->cached_buffers);
|
||||
|
||||
svga_screen_cache_init(svgascreen);
|
||||
|
||||
return screen;
|
||||
error2:
|
||||
FREE(svgascreen);
|
||||
error1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void svga_screen_flush( struct svga_screen *svgascreen,
|
||||
struct pipe_fence_handle **pfence )
|
||||
{
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
|
||||
SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__);
|
||||
|
||||
pipe_mutex_lock(svgascreen->swc_mutex);
|
||||
svgascreen->swc->flush(svgascreen->swc, &fence);
|
||||
pipe_mutex_unlock(svgascreen->swc_mutex);
|
||||
|
||||
svga_screen_cache_flush(svgascreen, fence);
|
||||
|
||||
if(pfence)
|
||||
*pfence = fence;
|
||||
else
|
||||
svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
|
||||
}
|
||||
|
||||
struct svga_winsys_screen *
|
||||
svga_winsys_screen(struct pipe_screen *screen)
|
||||
{
|
||||
return svga_screen(screen)->sws;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct svga_screen *
|
||||
svga_screen(struct pipe_screen *screen)
|
||||
{
|
||||
assert(screen);
|
||||
assert(screen->destroy == svga_destroy_screen);
|
||||
return (struct svga_screen *)screen;
|
||||
}
|
||||
#endif
|
||||
95
src/gallium/drivers/svga/svga_screen.h
Normal file
95
src/gallium/drivers/svga/svga_screen.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_SCREEN_H
|
||||
#define SVGA_SCREEN_H
|
||||
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_thread.h"
|
||||
|
||||
#include "util/u_double_list.h"
|
||||
|
||||
#include "svga_screen_cache.h"
|
||||
|
||||
|
||||
struct svga_winsys_screen;
|
||||
struct svga_winsys_context;
|
||||
struct SVGACmdMemory;
|
||||
|
||||
#define SVGA_COMBINE_USERBUFFERS 1
|
||||
|
||||
/**
|
||||
* Subclass of pipe_screen
|
||||
*/
|
||||
struct svga_screen
|
||||
{
|
||||
struct pipe_screen screen;
|
||||
struct svga_winsys_screen *sws;
|
||||
|
||||
unsigned use_ps30;
|
||||
unsigned use_vs30;
|
||||
|
||||
struct {
|
||||
boolean force_level_surface_view;
|
||||
boolean force_surface_view;
|
||||
boolean no_surface_view;
|
||||
boolean force_sampler_view;
|
||||
boolean no_sampler_view;
|
||||
} debug;
|
||||
|
||||
/* The screen needs its own context */
|
||||
struct svga_winsys_context *swc;
|
||||
struct SVGACmdMemory *fifo;
|
||||
|
||||
unsigned texture_timestamp;
|
||||
pipe_mutex tex_mutex;
|
||||
pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */
|
||||
|
||||
/**
|
||||
* List of buffers with cached GMR. Ordered from the most recently used to
|
||||
* the least recently used
|
||||
*/
|
||||
struct list_head cached_buffers;
|
||||
|
||||
struct svga_host_surface_cache cache;
|
||||
};
|
||||
|
||||
#ifndef DEBUG
|
||||
/** cast wrapper */
|
||||
static INLINE struct svga_screen *
|
||||
svga_screen(struct pipe_screen *pscreen)
|
||||
{
|
||||
return (struct svga_screen *) pscreen;
|
||||
}
|
||||
#else
|
||||
struct svga_screen *
|
||||
svga_screen(struct pipe_screen *screen);
|
||||
#endif
|
||||
|
||||
void svga_screen_flush( struct svga_screen *svga_screen,
|
||||
struct pipe_fence_handle **pfence );
|
||||
|
||||
#endif /* SVGA_SCREEN_H */
|
||||
820
src/gallium/drivers/svga/svga_screen_buffer.c
Normal file
820
src/gallium/drivers/svga/svga_screen_buffer.c
Normal file
|
|
@ -0,0 +1,820 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_thread.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
|
||||
/**
|
||||
* Vertex and index buffers have to be treated slightly differently from
|
||||
* regular guest memory regions because the SVGA device sees them as
|
||||
* surfaces, and the state tracker can create/destroy without the pipe
|
||||
* driver, therefore we must do the uploads from the vws.
|
||||
*/
|
||||
static INLINE boolean
|
||||
svga_buffer_needs_hw_storage(unsigned usage)
|
||||
{
|
||||
return usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX);
|
||||
}
|
||||
|
||||
|
||||
static INLINE enum pipe_error
|
||||
svga_buffer_create_host_surface(struct svga_screen *ss,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
if(!sbuf->handle) {
|
||||
sbuf->key.flags = 0;
|
||||
|
||||
sbuf->key.format = SVGA3D_BUFFER;
|
||||
if(sbuf->base.usage & PIPE_BUFFER_USAGE_VERTEX)
|
||||
sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
|
||||
if(sbuf->base.usage & PIPE_BUFFER_USAGE_INDEX)
|
||||
sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
|
||||
|
||||
sbuf->key.size.width = sbuf->base.size;
|
||||
sbuf->key.size.height = 1;
|
||||
sbuf->key.size.depth = 1;
|
||||
|
||||
sbuf->key.numFaces = 1;
|
||||
sbuf->key.numMipLevels = 1;
|
||||
|
||||
sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
|
||||
if(!sbuf->handle)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
/* Always set the discard flag on the first time the buffer is written
|
||||
* as svga_screen_surface_create might have passed a recycled host
|
||||
* buffer.
|
||||
*/
|
||||
sbuf->hw.flags.discard = TRUE;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, " grab sid %p sz %d\n", sbuf->handle, sbuf->base.size);
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
svga_buffer_destroy_host_surface(struct svga_screen *ss,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
if(sbuf->handle) {
|
||||
SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->base.size);
|
||||
svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
{
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
|
||||
assert(!sbuf->map.count);
|
||||
assert(sbuf->hw.buf);
|
||||
if(sbuf->hw.buf) {
|
||||
sws->buffer_destroy(sws, sbuf->hw.buf);
|
||||
sbuf->hw.buf = NULL;
|
||||
assert(sbuf->head.prev && sbuf->head.next);
|
||||
LIST_DEL(&sbuf->head);
|
||||
#ifdef DEBUG
|
||||
sbuf->head.next = sbuf->head.prev = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE enum pipe_error
|
||||
svga_buffer_backup(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
{
|
||||
if (sbuf->hw.buf && sbuf->hw.num_ranges) {
|
||||
void *src;
|
||||
|
||||
if (!sbuf->swbuf)
|
||||
sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
|
||||
if (!sbuf->swbuf)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
src = ss->sws->buffer_map(ss->sws, sbuf->hw.buf,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
if (!src)
|
||||
return PIPE_ERROR;
|
||||
|
||||
memcpy(sbuf->swbuf, src, sbuf->base.size);
|
||||
ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to make GMR space available by freeing the hardware storage of
|
||||
* unmapped
|
||||
*/
|
||||
boolean
|
||||
svga_buffer_free_cached_hw_storage(struct svga_screen *ss)
|
||||
{
|
||||
struct list_head *curr;
|
||||
struct svga_buffer *sbuf;
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
|
||||
curr = ss->cached_buffers.prev;
|
||||
|
||||
/* free the least recently used buffer's hw storage which is not mapped */
|
||||
do {
|
||||
if(curr == &ss->cached_buffers)
|
||||
return FALSE;
|
||||
|
||||
sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
|
||||
|
||||
curr = curr->prev;
|
||||
if (sbuf->map.count == 0)
|
||||
ret = svga_buffer_backup(ss, sbuf);
|
||||
|
||||
} while(sbuf->map.count != 0 || ret != PIPE_OK);
|
||||
|
||||
svga_buffer_destroy_hw_storage(ss, sbuf);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct svga_winsys_buffer *
|
||||
svga_winsys_buffer_create( struct svga_screen *ss,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size )
|
||||
{
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
struct svga_winsys_buffer *buf;
|
||||
|
||||
/* Just try */
|
||||
buf = sws->buffer_create(sws, alignment, usage, size);
|
||||
if(!buf) {
|
||||
|
||||
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing screen to find %d bytes GMR\n",
|
||||
size);
|
||||
|
||||
/* Try flushing all pending DMAs */
|
||||
svga_screen_flush(ss, NULL);
|
||||
buf = sws->buffer_create(sws, alignment, usage, size);
|
||||
|
||||
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "evicting buffers to find %d bytes GMR\n",
|
||||
size);
|
||||
|
||||
/* Try evicing all buffer storage */
|
||||
while(!buf && svga_buffer_free_cached_hw_storage(ss))
|
||||
buf = sws->buffer_create(sws, alignment, usage, size);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate DMA'ble storage for the buffer.
|
||||
*
|
||||
* Called before mapping a buffer.
|
||||
*/
|
||||
static INLINE enum pipe_error
|
||||
svga_buffer_create_hw_storage(struct svga_screen *ss,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
if(!sbuf->hw.buf) {
|
||||
unsigned alignment = sbuf->base.alignment;
|
||||
unsigned usage = 0;
|
||||
unsigned size = sbuf->base.size;
|
||||
|
||||
sbuf->hw.buf = svga_winsys_buffer_create(ss, alignment, usage, size);
|
||||
if(!sbuf->hw.buf)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
assert(!sbuf->needs_flush);
|
||||
assert(!sbuf->head.prev && !sbuf->head.next);
|
||||
LIST_ADD(&sbuf->head, &ss->cached_buffers);
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank.
|
||||
*/
|
||||
static enum pipe_error
|
||||
svga_buffer_upload_command(struct svga_context *svga,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
struct svga_winsys_context *swc = svga->swc;
|
||||
struct svga_winsys_buffer *guest = sbuf->hw.buf;
|
||||
struct svga_winsys_surface *host = sbuf->handle;
|
||||
SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM;
|
||||
SVGA3dSurfaceDMAFlags flags = sbuf->hw.flags;
|
||||
SVGA3dCmdSurfaceDMA *cmd;
|
||||
uint32 numBoxes = sbuf->hw.num_ranges;
|
||||
SVGA3dCopyBox *boxes;
|
||||
SVGA3dCmdSurfaceDMASuffix *pSuffix;
|
||||
unsigned region_flags;
|
||||
unsigned surface_flags;
|
||||
struct pipe_buffer *dummy;
|
||||
|
||||
if(transfer == SVGA3D_WRITE_HOST_VRAM) {
|
||||
region_flags = PIPE_BUFFER_USAGE_GPU_READ;
|
||||
surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
|
||||
}
|
||||
else if(transfer == SVGA3D_READ_HOST_VRAM) {
|
||||
region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
|
||||
surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
return PIPE_ERROR_BAD_INPUT;
|
||||
}
|
||||
|
||||
assert(numBoxes);
|
||||
|
||||
cmd = SVGA3D_FIFOReserve(swc,
|
||||
SVGA_3D_CMD_SURFACE_DMA,
|
||||
sizeof *cmd + numBoxes * sizeof *boxes + sizeof *pSuffix,
|
||||
2);
|
||||
if(!cmd)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
|
||||
cmd->guest.pitch = 0;
|
||||
|
||||
swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
|
||||
cmd->host.face = 0;
|
||||
cmd->host.mipmap = 0;
|
||||
|
||||
cmd->transfer = transfer;
|
||||
|
||||
sbuf->hw.boxes = (SVGA3dCopyBox *)&cmd[1];
|
||||
sbuf->hw.svga = svga;
|
||||
|
||||
/* Increment reference count */
|
||||
dummy = NULL;
|
||||
pipe_buffer_reference(&dummy, &sbuf->base);
|
||||
|
||||
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes);
|
||||
pSuffix->suffixSize = sizeof *pSuffix;
|
||||
pSuffix->maximumOffset = sbuf->base.size;
|
||||
pSuffix->flags = flags;
|
||||
|
||||
swc->commit(swc);
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Patch up the upload DMA command reserved by svga_buffer_upload_command
|
||||
* with the final ranges.
|
||||
*/
|
||||
static void
|
||||
svga_buffer_upload_flush(struct svga_context *svga,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(svga->pipe.screen);
|
||||
SVGA3dCopyBox *boxes;
|
||||
unsigned i;
|
||||
|
||||
assert(sbuf->handle);
|
||||
assert(sbuf->hw.buf);
|
||||
assert(sbuf->hw.num_ranges);
|
||||
assert(sbuf->hw.svga == svga);
|
||||
assert(sbuf->hw.boxes);
|
||||
|
||||
/*
|
||||
* Patch the DMA command with the final copy box.
|
||||
*/
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
|
||||
|
||||
boxes = sbuf->hw.boxes;
|
||||
for(i = 0; i < sbuf->hw.num_ranges; ++i) {
|
||||
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
|
||||
sbuf->hw.ranges[i].start, sbuf->hw.ranges[i].end);
|
||||
|
||||
boxes[i].x = sbuf->hw.ranges[i].start;
|
||||
boxes[i].y = 0;
|
||||
boxes[i].z = 0;
|
||||
boxes[i].w = sbuf->hw.ranges[i].end - sbuf->hw.ranges[i].start;
|
||||
boxes[i].h = 1;
|
||||
boxes[i].d = 1;
|
||||
boxes[i].srcx = sbuf->hw.ranges[i].start;
|
||||
boxes[i].srcy = 0;
|
||||
boxes[i].srcz = 0;
|
||||
}
|
||||
|
||||
sbuf->hw.num_ranges = 0;
|
||||
memset(&sbuf->hw.flags, 0, sizeof sbuf->hw.flags);
|
||||
|
||||
assert(sbuf->head.prev && sbuf->head.next);
|
||||
LIST_DEL(&sbuf->head);
|
||||
sbuf->needs_flush = FALSE;
|
||||
/* XXX: do we care about cached_buffers any more ?*/
|
||||
LIST_ADD(&sbuf->head, &ss->cached_buffers);
|
||||
|
||||
sbuf->hw.svga = NULL;
|
||||
sbuf->hw.boxes = NULL;
|
||||
|
||||
/* Decrement reference count */
|
||||
pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Queue a DMA upload of a range of this buffer to the host.
|
||||
*
|
||||
* This function only notes the range down. It doesn't actually emit a DMA
|
||||
* upload command. That only happens when a context tries to refer to this
|
||||
* buffer, and the DMA upload command is added to that context's command buffer.
|
||||
*
|
||||
* We try to lump as many contiguous DMA transfers together as possible.
|
||||
*/
|
||||
static void
|
||||
svga_buffer_upload_queue(struct svga_buffer *sbuf,
|
||||
unsigned start,
|
||||
unsigned end)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
assert(sbuf->hw.buf);
|
||||
assert(end > start);
|
||||
|
||||
/*
|
||||
* Try to grow one of the ranges.
|
||||
*
|
||||
* Note that it is not this function task to care about overlapping ranges,
|
||||
* as the GMR was already given so it is too late to do anything. Situations
|
||||
* where overlapping ranges may pose a problem should be detected via
|
||||
* pipe_context::is_buffer_referenced and the context that refers to the
|
||||
* buffer should be flushed.
|
||||
*/
|
||||
|
||||
for(i = 0; i < sbuf->hw.num_ranges; ++i) {
|
||||
if(start <= sbuf->hw.ranges[i].end && sbuf->hw.ranges[i].start <= end) {
|
||||
sbuf->hw.ranges[i].start = MIN2(sbuf->hw.ranges[i].start, start);
|
||||
sbuf->hw.ranges[i].end = MAX2(sbuf->hw.ranges[i].end, end);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot add a new range to an existing DMA command, so patch-up the
|
||||
* pending DMA upload and start clean.
|
||||
*/
|
||||
|
||||
if(sbuf->needs_flush)
|
||||
svga_buffer_upload_flush(sbuf->hw.svga, sbuf);
|
||||
|
||||
assert(!sbuf->needs_flush);
|
||||
assert(!sbuf->hw.svga);
|
||||
assert(!sbuf->hw.boxes);
|
||||
|
||||
/*
|
||||
* Add a new range.
|
||||
*/
|
||||
|
||||
sbuf->hw.ranges[sbuf->hw.num_ranges].start = start;
|
||||
sbuf->hw.ranges[sbuf->hw.num_ranges].end = end;
|
||||
++sbuf->hw.num_ranges;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
svga_buffer_map_range( struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned offset, unsigned length,
|
||||
unsigned usage )
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(screen);
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
struct svga_buffer *sbuf = svga_buffer( buf );
|
||||
void *map;
|
||||
|
||||
if(sbuf->swbuf) {
|
||||
/* User/malloc buffer */
|
||||
map = sbuf->swbuf;
|
||||
}
|
||||
else {
|
||||
if(!sbuf->hw.buf) {
|
||||
struct svga_winsys_surface *handle = sbuf->handle;
|
||||
|
||||
if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK)
|
||||
return NULL;
|
||||
|
||||
/* Populate the hardware storage if the host surface pre-existed */
|
||||
if((usage & PIPE_BUFFER_USAGE_CPU_READ) && handle) {
|
||||
SVGA3dSurfaceDMAFlags flags;
|
||||
enum pipe_error ret;
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p, bytes %u - %u\n",
|
||||
sbuf->handle, 0, sbuf->base.size);
|
||||
|
||||
memset(&flags, 0, sizeof flags);
|
||||
|
||||
ret = SVGA3D_BufferDMA(ss->swc,
|
||||
sbuf->hw.buf,
|
||||
sbuf->handle,
|
||||
SVGA3D_READ_HOST_VRAM,
|
||||
sbuf->base.size,
|
||||
0,
|
||||
flags);
|
||||
if(ret != PIPE_OK) {
|
||||
ss->swc->flush(ss->swc, NULL);
|
||||
|
||||
ret = SVGA3D_BufferDMA(ss->swc,
|
||||
sbuf->hw.buf,
|
||||
sbuf->handle,
|
||||
SVGA3D_READ_HOST_VRAM,
|
||||
sbuf->base.size,
|
||||
0,
|
||||
flags);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
ss->swc->flush(ss->swc, &fence);
|
||||
sws->fence_finish(sws, fence, 0);
|
||||
sws->fence_reference(sws, &fence, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((usage & PIPE_BUFFER_USAGE_CPU_READ) && !sbuf->needs_flush) {
|
||||
/* We already had the hardware storage but we would have to issue
|
||||
* a download if we hadn't, so move the buffer to the begginning
|
||||
* of the LRU list.
|
||||
*/
|
||||
assert(sbuf->head.prev && sbuf->head.next);
|
||||
LIST_DEL(&sbuf->head);
|
||||
LIST_ADD(&sbuf->head, &ss->cached_buffers);
|
||||
}
|
||||
}
|
||||
|
||||
map = sws->buffer_map(sws, sbuf->hw.buf, usage);
|
||||
}
|
||||
|
||||
if(map) {
|
||||
pipe_mutex_lock(ss->swc_mutex);
|
||||
|
||||
++sbuf->map.count;
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
|
||||
assert(sbuf->map.count <= 1);
|
||||
sbuf->map.writing = TRUE;
|
||||
if (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT)
|
||||
sbuf->map.flush_explicit = TRUE;
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static void
|
||||
svga_buffer_flush_mapped_range( struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned offset, unsigned length)
|
||||
{
|
||||
struct svga_buffer *sbuf = svga_buffer( buf );
|
||||
struct svga_screen *ss = svga_screen(screen);
|
||||
|
||||
pipe_mutex_lock(ss->swc_mutex);
|
||||
assert(sbuf->map.writing);
|
||||
if(sbuf->map.writing) {
|
||||
assert(sbuf->map.flush_explicit);
|
||||
if(sbuf->hw.buf)
|
||||
svga_buffer_upload_queue(sbuf, offset, offset + length);
|
||||
}
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
svga_buffer_unmap( struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(screen);
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
struct svga_buffer *sbuf = svga_buffer( buf );
|
||||
|
||||
pipe_mutex_lock(ss->swc_mutex);
|
||||
|
||||
assert(sbuf->map.count);
|
||||
if(sbuf->map.count)
|
||||
--sbuf->map.count;
|
||||
|
||||
if(sbuf->hw.buf)
|
||||
sws->buffer_unmap(sws, sbuf->hw.buf);
|
||||
|
||||
if(sbuf->map.writing) {
|
||||
if(!sbuf->map.flush_explicit) {
|
||||
/* No mapped range was flushed -- flush the whole buffer */
|
||||
SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
|
||||
|
||||
if(sbuf->hw.buf)
|
||||
svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
|
||||
}
|
||||
|
||||
sbuf->map.writing = FALSE;
|
||||
sbuf->map.flush_explicit = FALSE;
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
svga_buffer_destroy( struct pipe_buffer *buf )
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(buf->screen);
|
||||
struct svga_buffer *sbuf = svga_buffer( buf );
|
||||
|
||||
assert(!p_atomic_read(&buf->reference.count));
|
||||
|
||||
assert(!sbuf->needs_flush);
|
||||
|
||||
if(sbuf->handle) {
|
||||
SVGA_DBG(DEBUG_DMA, "release sid %p sz %d\n", sbuf->handle, sbuf->base.size);
|
||||
svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
|
||||
}
|
||||
|
||||
if(sbuf->hw.buf)
|
||||
svga_buffer_destroy_hw_storage(ss, sbuf);
|
||||
|
||||
if(sbuf->swbuf && !sbuf->user)
|
||||
align_free(sbuf->swbuf);
|
||||
|
||||
FREE(sbuf);
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
svga_buffer_create(struct pipe_screen *screen,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(screen);
|
||||
struct svga_buffer *sbuf;
|
||||
|
||||
sbuf = CALLOC_STRUCT(svga_buffer);
|
||||
if(!sbuf)
|
||||
goto error1;
|
||||
|
||||
sbuf->magic = SVGA_BUFFER_MAGIC;
|
||||
|
||||
pipe_reference_init(&sbuf->base.reference, 1);
|
||||
sbuf->base.screen = screen;
|
||||
sbuf->base.alignment = alignment;
|
||||
sbuf->base.usage = usage;
|
||||
sbuf->base.size = size;
|
||||
|
||||
if(svga_buffer_needs_hw_storage(usage)) {
|
||||
if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK)
|
||||
goto error2;
|
||||
}
|
||||
else {
|
||||
if(alignment < sizeof(void*))
|
||||
alignment = sizeof(void*);
|
||||
|
||||
usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
|
||||
|
||||
sbuf->swbuf = align_malloc(size, alignment);
|
||||
if(!sbuf->swbuf)
|
||||
goto error2;
|
||||
}
|
||||
|
||||
return &sbuf->base;
|
||||
|
||||
error2:
|
||||
FREE(sbuf);
|
||||
error1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
svga_user_buffer_create(struct pipe_screen *screen,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct svga_buffer *sbuf;
|
||||
|
||||
sbuf = CALLOC_STRUCT(svga_buffer);
|
||||
if(!sbuf)
|
||||
goto no_sbuf;
|
||||
|
||||
sbuf->magic = SVGA_BUFFER_MAGIC;
|
||||
|
||||
sbuf->swbuf = ptr;
|
||||
sbuf->user = TRUE;
|
||||
|
||||
pipe_reference_init(&sbuf->base.reference, 1);
|
||||
sbuf->base.screen = screen;
|
||||
sbuf->base.alignment = 1;
|
||||
sbuf->base.usage = 0;
|
||||
sbuf->base.size = bytes;
|
||||
|
||||
return &sbuf->base;
|
||||
|
||||
no_sbuf:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_screen_init_buffer_functions(struct pipe_screen *screen)
|
||||
{
|
||||
screen->buffer_create = svga_buffer_create;
|
||||
screen->user_buffer_create = svga_user_buffer_create;
|
||||
screen->buffer_map_range = svga_buffer_map_range;
|
||||
screen->buffer_flush_mapped_range = svga_buffer_flush_mapped_range;
|
||||
screen->buffer_unmap = svga_buffer_unmap;
|
||||
screen->buffer_destroy = svga_buffer_destroy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the contents of the user buffer / malloc buffer to a hardware buffer.
|
||||
*/
|
||||
static INLINE enum pipe_error
|
||||
svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
{
|
||||
if(!sbuf->hw.buf) {
|
||||
enum pipe_error ret;
|
||||
void *map;
|
||||
|
||||
assert(sbuf->swbuf);
|
||||
if(!sbuf->swbuf)
|
||||
return PIPE_ERROR;
|
||||
|
||||
ret = svga_buffer_create_hw_storage(ss, sbuf);
|
||||
assert(ret == PIPE_OK);
|
||||
if(ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
pipe_mutex_lock(ss->swc_mutex);
|
||||
map = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
assert(map);
|
||||
if(!map) {
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(map, sbuf->swbuf, sbuf->base.size);
|
||||
ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
|
||||
|
||||
/* This user/malloc buffer is now indistinguishable from a gpu buffer */
|
||||
assert(!sbuf->map.count);
|
||||
if(!sbuf->map.count) {
|
||||
if(sbuf->user)
|
||||
sbuf->user = FALSE;
|
||||
else
|
||||
align_free(sbuf->swbuf);
|
||||
sbuf->swbuf = NULL;
|
||||
}
|
||||
|
||||
svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
struct svga_winsys_surface *
|
||||
svga_buffer_handle(struct svga_context *svga,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct pipe_screen *screen = svga->pipe.screen;
|
||||
struct svga_screen *ss = svga_screen(screen);
|
||||
struct svga_buffer *sbuf;
|
||||
enum pipe_error ret;
|
||||
|
||||
if(!buf)
|
||||
return NULL;
|
||||
|
||||
sbuf = svga_buffer(buf);
|
||||
|
||||
assert(!sbuf->map.count);
|
||||
|
||||
if(!sbuf->handle) {
|
||||
ret = svga_buffer_create_host_surface(ss, sbuf);
|
||||
if(ret != PIPE_OK)
|
||||
return NULL;
|
||||
|
||||
ret = svga_buffer_update_hw(ss, sbuf);
|
||||
if(ret != PIPE_OK)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!sbuf->needs_flush && sbuf->hw.num_ranges) {
|
||||
/* Queue the buffer for flushing */
|
||||
ret = svga_buffer_upload_command(svga, sbuf);
|
||||
if(ret != PIPE_OK)
|
||||
/* XXX: Should probably have a richer return value */
|
||||
return NULL;
|
||||
|
||||
assert(sbuf->hw.svga == svga);
|
||||
|
||||
sbuf->needs_flush = TRUE;
|
||||
assert(sbuf->head.prev && sbuf->head.next);
|
||||
LIST_DEL(&sbuf->head);
|
||||
LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
|
||||
}
|
||||
|
||||
return sbuf->handle;
|
||||
}
|
||||
|
||||
struct pipe_buffer *
|
||||
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
|
||||
enum SVGA3dSurfaceFormat format,
|
||||
struct svga_winsys_surface *srf)
|
||||
{
|
||||
struct pipe_buffer *buf;
|
||||
struct svga_buffer *sbuf;
|
||||
struct svga_winsys_screen *sws = svga_winsys_screen(screen);
|
||||
|
||||
buf = svga_buffer_create(screen, 0, SVGA_BUFFER_USAGE_WRAPPED, 0);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
sbuf = svga_buffer(buf);
|
||||
|
||||
/*
|
||||
* We are not the creator of this surface and therefore we must not
|
||||
* cache it for reuse. The caching code only caches SVGA3D_BUFFER surfaces
|
||||
* so make sure this isn't one of those.
|
||||
*/
|
||||
|
||||
assert(format != SVGA3D_BUFFER);
|
||||
sbuf->key.format = format;
|
||||
sws->surface_reference(sws, &sbuf->handle, srf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct svga_winsys_surface *
|
||||
svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer)
|
||||
{
|
||||
struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen);
|
||||
struct svga_winsys_surface *vsurf = NULL;
|
||||
|
||||
sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle);
|
||||
return vsurf;
|
||||
}
|
||||
|
||||
void
|
||||
svga_context_flush_buffers(struct svga_context *svga)
|
||||
{
|
||||
struct list_head *curr, *next;
|
||||
struct svga_buffer *sbuf;
|
||||
|
||||
curr = svga->dirty_buffers.next;
|
||||
next = curr->next;
|
||||
while(curr != &svga->dirty_buffers) {
|
||||
sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
|
||||
|
||||
assert(p_atomic_read(&sbuf->base.reference.count) != 0);
|
||||
assert(sbuf->needs_flush);
|
||||
|
||||
svga_buffer_upload_flush(svga, sbuf);
|
||||
|
||||
curr = next;
|
||||
next = curr->next;
|
||||
}
|
||||
}
|
||||
190
src/gallium/drivers/svga/svga_screen_buffer.h
Normal file
190
src/gallium/drivers/svga/svga_screen_buffer.h
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_BUFFER_H
|
||||
#define SVGA_BUFFER_H
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "util/u_double_list.h"
|
||||
|
||||
#include "svga_screen_cache.h"
|
||||
|
||||
|
||||
#define SVGA_BUFFER_MAGIC 0x344f9005
|
||||
|
||||
/**
|
||||
* Maximum number of discontiguous ranges
|
||||
*/
|
||||
#define SVGA_BUFFER_MAX_RANGES 32
|
||||
|
||||
|
||||
struct svga_screen;
|
||||
struct svga_context;
|
||||
struct svga_winsys_buffer;
|
||||
struct svga_winsys_surface;
|
||||
|
||||
|
||||
struct svga_buffer_range
|
||||
{
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Describe a
|
||||
*
|
||||
* This holds the information to emit a SVGA3dCmdSurfaceDMA.
|
||||
*/
|
||||
struct svga_buffer_upload
|
||||
{
|
||||
/**
|
||||
* Guest memory region.
|
||||
*/
|
||||
struct svga_winsys_buffer *buf;
|
||||
|
||||
struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
|
||||
unsigned num_ranges;
|
||||
|
||||
SVGA3dSurfaceDMAFlags flags;
|
||||
|
||||
/**
|
||||
* Pointer to the DMA copy box *inside* the command buffer.
|
||||
*/
|
||||
SVGA3dCopyBox *boxes;
|
||||
|
||||
/**
|
||||
* Context that has the pending DMA to this buffer.
|
||||
*/
|
||||
struct svga_context *svga;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* SVGA pipe buffer.
|
||||
*/
|
||||
struct svga_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
|
||||
/**
|
||||
* Marker to detect bad casts in runtime.
|
||||
*/
|
||||
uint32_t magic;
|
||||
|
||||
/**
|
||||
* Regular (non DMA'able) memory.
|
||||
*
|
||||
* Used for user buffers or for buffers which we know before hand that can
|
||||
* never be used by the virtual hardware directly, such as constant buffers.
|
||||
*/
|
||||
void *swbuf;
|
||||
|
||||
/**
|
||||
* Whether swbuf was created by the user or not.
|
||||
*/
|
||||
boolean user;
|
||||
|
||||
/**
|
||||
* DMA'ble memory.
|
||||
*
|
||||
* A piece of GMR memory. It is created when mapping the buffer, and will be
|
||||
* used to upload/download vertex data from the host.
|
||||
*/
|
||||
struct svga_buffer_upload hw;
|
||||
|
||||
/**
|
||||
* Creation key for the host surface handle.
|
||||
*
|
||||
* This structure describes all the host surface characteristics so that it
|
||||
* can be looked up in cache, since creating a host surface is often a slow
|
||||
* operation.
|
||||
*/
|
||||
struct svga_host_surface_cache_key key;
|
||||
|
||||
/**
|
||||
* Host surface handle.
|
||||
*
|
||||
* This is a platform independent abstraction for host SID. We create when
|
||||
* trying to bind
|
||||
*/
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
struct {
|
||||
unsigned count;
|
||||
boolean writing;
|
||||
boolean flush_explicit;
|
||||
} map;
|
||||
|
||||
boolean needs_flush;
|
||||
struct list_head head;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct svga_buffer *
|
||||
svga_buffer(struct pipe_buffer *buffer)
|
||||
{
|
||||
if (buffer) {
|
||||
assert(((struct svga_buffer *)buffer)->magic == SVGA_BUFFER_MAGIC);
|
||||
return (struct svga_buffer *)buffer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns TRUE for user buffers. We may
|
||||
* decide to use an alternate upload path for these buffers.
|
||||
*/
|
||||
static INLINE boolean
|
||||
svga_buffer_is_user_buffer( struct pipe_buffer *buffer )
|
||||
{
|
||||
return svga_buffer(buffer)->user;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_screen_init_buffer_functions(struct pipe_screen *screen);
|
||||
|
||||
struct svga_winsys_surface *
|
||||
svga_buffer_handle(struct svga_context *svga,
|
||||
struct pipe_buffer *buf);
|
||||
|
||||
void
|
||||
svga_context_flush_buffers(struct svga_context *svga);
|
||||
|
||||
boolean
|
||||
svga_buffer_free_cached_hw_storage(struct svga_screen *ss);
|
||||
|
||||
struct svga_winsys_buffer *
|
||||
svga_winsys_buffer_create(struct svga_screen *ss,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size);
|
||||
|
||||
#endif /* SVGA_BUFFER_H */
|
||||
307
src/gallium/drivers/svga/svga_screen_cache.c
Normal file
307
src/gallium/drivers/svga/svga_screen_cache.c
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_debug.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_cache.h"
|
||||
|
||||
|
||||
#define SVGA_SURFACE_CACHE_ENABLED 1
|
||||
|
||||
|
||||
/**
|
||||
* Compute the bucket for this key.
|
||||
*
|
||||
* We simply compute log2(width) for now, but
|
||||
*/
|
||||
static INLINE unsigned
|
||||
svga_screen_cache_bucket(const struct svga_host_surface_cache_key *key)
|
||||
{
|
||||
unsigned bucket = 0;
|
||||
unsigned size = key->size.width;
|
||||
|
||||
while ((size >>= 1))
|
||||
++bucket;
|
||||
|
||||
if(key->flags & SVGA3D_SURFACE_HINT_INDEXBUFFER)
|
||||
bucket += 32;
|
||||
|
||||
assert(bucket < SVGA_HOST_SURFACE_CACHE_BUCKETS);
|
||||
|
||||
return bucket;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct svga_winsys_surface *
|
||||
svga_screen_cache_lookup(struct svga_screen *svgascreen,
|
||||
const struct svga_host_surface_cache_key *key)
|
||||
{
|
||||
struct svga_host_surface_cache *cache = &svgascreen->cache;
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_host_surface_cache_entry *entry;
|
||||
struct svga_winsys_surface *handle = NULL;
|
||||
struct list_head *curr, *next;
|
||||
unsigned bucket;
|
||||
unsigned tries = 0;
|
||||
|
||||
bucket = svga_screen_cache_bucket(key);
|
||||
|
||||
pipe_mutex_lock(cache->mutex);
|
||||
|
||||
curr = cache->bucket[bucket].next;
|
||||
next = curr->next;
|
||||
while(curr != &cache->bucket[bucket]) {
|
||||
++tries;
|
||||
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, bucket_head);
|
||||
|
||||
assert(entry->handle);
|
||||
|
||||
if(memcmp(&entry->key, key, sizeof *key) == 0 &&
|
||||
sws->fence_signalled( sws, entry->fence, 0 ) == 0) {
|
||||
assert(sws->surface_is_flushed(sws, entry->handle));
|
||||
|
||||
handle = entry->handle; // Reference is transfered here.
|
||||
entry->handle = NULL;
|
||||
|
||||
LIST_DEL(&entry->bucket_head);
|
||||
|
||||
LIST_DEL(&entry->head);
|
||||
|
||||
LIST_ADD(&entry->head, &cache->empty);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
curr = next;
|
||||
next = curr->next;
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(cache->mutex);
|
||||
|
||||
#if 0
|
||||
_debug_printf("%s: cache %s after %u tries\n", __FUNCTION__, handle ? "hit" : "miss", tries);
|
||||
#else
|
||||
(void)tries;
|
||||
#endif
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Transfers a handle reference.
|
||||
*/
|
||||
|
||||
static INLINE void
|
||||
svga_screen_cache_add(struct svga_screen *svgascreen,
|
||||
const struct svga_host_surface_cache_key *key,
|
||||
struct svga_winsys_surface **p_handle)
|
||||
{
|
||||
struct svga_host_surface_cache *cache = &svgascreen->cache;
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_host_surface_cache_entry *entry = NULL;
|
||||
struct svga_winsys_surface *handle = *p_handle;
|
||||
|
||||
|
||||
assert(handle);
|
||||
if(!handle)
|
||||
return;
|
||||
|
||||
*p_handle = NULL;
|
||||
pipe_mutex_lock(cache->mutex);
|
||||
|
||||
if(!LIST_IS_EMPTY(&cache->empty)) {
|
||||
/* use the first empty entry */
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head);
|
||||
|
||||
LIST_DEL(&entry->head);
|
||||
}
|
||||
else if(!LIST_IS_EMPTY(&cache->unused)) {
|
||||
/* free the last used buffer and reuse its entry */
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->unused.prev, head);
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", entry->handle);
|
||||
sws->surface_reference(sws, &entry->handle, NULL);
|
||||
|
||||
LIST_DEL(&entry->bucket_head);
|
||||
|
||||
LIST_DEL(&entry->head);
|
||||
}
|
||||
|
||||
if(entry) {
|
||||
entry->handle = handle;
|
||||
memcpy(&entry->key, key, sizeof entry->key);
|
||||
|
||||
LIST_ADD(&entry->head, &cache->validated);
|
||||
}
|
||||
else {
|
||||
/* Couldn't cache the buffer -- this really shouldn't happen */
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", handle);
|
||||
sws->surface_reference(sws, &handle, NULL);
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(cache->mutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called during the screen flush to move all buffers not in a validate list
|
||||
* into the unused list.
|
||||
*/
|
||||
void
|
||||
svga_screen_cache_flush(struct svga_screen *svgascreen,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
struct svga_host_surface_cache *cache = &svgascreen->cache;
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_host_surface_cache_entry *entry;
|
||||
struct list_head *curr, *next;
|
||||
unsigned bucket;
|
||||
|
||||
pipe_mutex_lock(cache->mutex);
|
||||
|
||||
curr = cache->validated.next;
|
||||
next = curr->next;
|
||||
while(curr != &cache->validated) {
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, head);
|
||||
|
||||
assert(entry->handle);
|
||||
|
||||
if(sws->surface_is_flushed(sws, entry->handle)) {
|
||||
LIST_DEL(&entry->head);
|
||||
|
||||
svgascreen->sws->fence_reference(svgascreen->sws, &entry->fence, fence);
|
||||
|
||||
LIST_ADD(&entry->head, &cache->unused);
|
||||
|
||||
bucket = svga_screen_cache_bucket(&entry->key);
|
||||
LIST_ADD(&entry->bucket_head, &cache->bucket[bucket]);
|
||||
}
|
||||
|
||||
curr = next;
|
||||
next = curr->next;
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(cache->mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_screen_cache_cleanup(struct svga_screen *svgascreen)
|
||||
{
|
||||
struct svga_host_surface_cache *cache = &svgascreen->cache;
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
unsigned i;
|
||||
|
||||
for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) {
|
||||
if(cache->entries[i].handle) {
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", cache->entries[i].handle);
|
||||
sws->surface_reference(sws, &cache->entries[i].handle, NULL);
|
||||
}
|
||||
|
||||
if(cache->entries[i].fence)
|
||||
svgascreen->sws->fence_reference(svgascreen->sws, &cache->entries[i].fence, NULL);
|
||||
}
|
||||
|
||||
pipe_mutex_destroy(cache->mutex);
|
||||
}
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_screen_cache_init(struct svga_screen *svgascreen)
|
||||
{
|
||||
struct svga_host_surface_cache *cache = &svgascreen->cache;
|
||||
unsigned i;
|
||||
|
||||
pipe_mutex_init(cache->mutex);
|
||||
|
||||
for(i = 0; i < SVGA_HOST_SURFACE_CACHE_BUCKETS; ++i)
|
||||
LIST_INITHEAD(&cache->bucket[i]);
|
||||
|
||||
LIST_INITHEAD(&cache->unused);
|
||||
|
||||
LIST_INITHEAD(&cache->validated);
|
||||
|
||||
LIST_INITHEAD(&cache->empty);
|
||||
for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i)
|
||||
LIST_ADDTAIL(&cache->entries[i].head, &cache->empty);
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
struct svga_winsys_surface *
|
||||
svga_screen_surface_create(struct svga_screen *svgascreen,
|
||||
struct svga_host_surface_cache_key *key)
|
||||
{
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_winsys_surface *handle = NULL;
|
||||
|
||||
if (SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) {
|
||||
/* round the buffer size up to the nearest power of two to increase the
|
||||
* probability of cache hits */
|
||||
uint32_t size = 1;
|
||||
while(size < key->size.width)
|
||||
size <<= 1;
|
||||
key->size.width = size;
|
||||
|
||||
handle = svga_screen_cache_lookup(svgascreen, key);
|
||||
if (handle)
|
||||
SVGA_DBG(DEBUG_DMA, " reuse sid %p sz %d\n", handle, size);
|
||||
}
|
||||
|
||||
if (!handle) {
|
||||
handle = sws->surface_create(sws,
|
||||
key->flags,
|
||||
key->format,
|
||||
key->size,
|
||||
key->numFaces,
|
||||
key->numMipLevels);
|
||||
if (handle)
|
||||
SVGA_DBG(DEBUG_DMA, "create sid %p sz %d\n", handle, key->size);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_screen_surface_destroy(struct svga_screen *svgascreen,
|
||||
const struct svga_host_surface_cache_key *key,
|
||||
struct svga_winsys_surface **p_handle)
|
||||
{
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
|
||||
if(SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) {
|
||||
svga_screen_cache_add(svgascreen, key, p_handle);
|
||||
}
|
||||
else {
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", *p_handle);
|
||||
sws->surface_reference(sws, p_handle, NULL);
|
||||
}
|
||||
}
|
||||
135
src/gallium/drivers/svga/svga_screen_cache.h
Normal file
135
src/gallium/drivers/svga/svga_screen_cache.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_SCREEN_CACHE_H_
|
||||
#define SVGA_SCREEN_CACHE_H_
|
||||
|
||||
|
||||
#include "svga_types.h"
|
||||
#include "svga_reg.h"
|
||||
#include "svga3d_reg.h"
|
||||
|
||||
#include "pipe/p_thread.h"
|
||||
|
||||
#include "util/u_double_list.h"
|
||||
|
||||
|
||||
/* TODO: Reduce this once we don't allocate an index buffer per draw call */
|
||||
#define SVGA_HOST_SURFACE_CACHE_SIZE 1024
|
||||
|
||||
#define SVGA_HOST_SURFACE_CACHE_BUCKETS 64
|
||||
|
||||
|
||||
struct svga_winsys_surface;
|
||||
struct svga_screen;
|
||||
|
||||
/**
|
||||
* Same as svga_winsys_screen::surface_create.
|
||||
*/
|
||||
struct svga_host_surface_cache_key
|
||||
{
|
||||
SVGA3dSurfaceFlags flags;
|
||||
SVGA3dSurfaceFormat format;
|
||||
SVGA3dSize size;
|
||||
uint32_t numFaces;
|
||||
uint32_t numMipLevels;
|
||||
};
|
||||
|
||||
|
||||
struct svga_host_surface_cache_entry
|
||||
{
|
||||
/**
|
||||
* Head for the LRU list, svga_host_surface_cache::unused, and
|
||||
* svga_host_surface_cache::empty
|
||||
*/
|
||||
struct list_head head;
|
||||
|
||||
/** Head for the bucket lists. */
|
||||
struct list_head bucket_head;
|
||||
|
||||
struct svga_host_surface_cache_key key;
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
struct pipe_fence_handle *fence;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cache of the host surfaces.
|
||||
*
|
||||
* A cache entry can be in the following stages:
|
||||
* 1. empty
|
||||
* 2. holding a buffer in a validate list
|
||||
* 3. holding a flushed buffer (not in any validate list) with an active fence
|
||||
* 4. holding a flushed buffer with an expired fence
|
||||
*
|
||||
* An entry progresses from 1 -> 2 -> 3 -> 4. When we need an entry to put a
|
||||
* buffer into we preferencial take from 1, or from the least recentely used
|
||||
* buffer from 3/4.
|
||||
*/
|
||||
struct svga_host_surface_cache
|
||||
{
|
||||
pipe_mutex mutex;
|
||||
|
||||
/* Unused buffers are put in buckets to speed up lookups */
|
||||
struct list_head bucket[SVGA_HOST_SURFACE_CACHE_BUCKETS];
|
||||
|
||||
/* Entries with unused buffers, ordered from most to least recently used
|
||||
* (3 and 4) */
|
||||
struct list_head unused;
|
||||
|
||||
/* Entries with buffers still in validate lists (2) */
|
||||
struct list_head validated;
|
||||
|
||||
/** Empty entries (1) */
|
||||
struct list_head empty;
|
||||
|
||||
/** The actual storage for the entries */
|
||||
struct svga_host_surface_cache_entry entries[SVGA_HOST_SURFACE_CACHE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
svga_screen_cache_cleanup(struct svga_screen *svgascreen);
|
||||
|
||||
void
|
||||
svga_screen_cache_flush(struct svga_screen *svgascreen,
|
||||
struct pipe_fence_handle *fence);
|
||||
|
||||
enum pipe_error
|
||||
svga_screen_cache_init(struct svga_screen *svgascreen);
|
||||
|
||||
|
||||
struct svga_winsys_surface *
|
||||
svga_screen_surface_create(struct svga_screen *svgascreen,
|
||||
struct svga_host_surface_cache_key *key);
|
||||
|
||||
void
|
||||
svga_screen_surface_destroy(struct svga_screen *svgascreen,
|
||||
const struct svga_host_surface_cache_key *key,
|
||||
struct svga_winsys_surface **handle);
|
||||
|
||||
|
||||
#endif /* SVGA_SCREEN_CACHE_H_ */
|
||||
1065
src/gallium/drivers/svga/svga_screen_texture.c
Normal file
1065
src/gallium/drivers/svga/svga_screen_texture.c
Normal file
File diff suppressed because it is too large
Load diff
177
src/gallium/drivers/svga/svga_screen_texture.h
Normal file
177
src/gallium/drivers/svga/svga_screen_texture.h
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_TEXTURE_H
|
||||
#define SVGA_TEXTURE_H
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
struct svga_context;
|
||||
struct svga_winsys_surface;
|
||||
enum SVGA3dSurfaceFormat;
|
||||
|
||||
|
||||
#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */
|
||||
|
||||
|
||||
/**
|
||||
* A sampler's view into a texture
|
||||
*
|
||||
* We currently cache one sampler view on
|
||||
* the texture and in there by holding a reference
|
||||
* from the texture to the sampler view.
|
||||
*
|
||||
* Because of this we can not hold a refernce to the
|
||||
* texture from the sampler view. So the user
|
||||
* of the sampler views must make sure that the
|
||||
* texture has a reference take for as long as
|
||||
* the sampler view is refrenced.
|
||||
*
|
||||
* Just unreferencing the sampler_view before the
|
||||
* texture is enough.
|
||||
*/
|
||||
struct svga_sampler_view
|
||||
{
|
||||
struct pipe_reference reference;
|
||||
|
||||
struct svga_texture *texture;
|
||||
|
||||
int min_lod;
|
||||
int max_lod;
|
||||
|
||||
unsigned age;
|
||||
|
||||
struct svga_winsys_surface *handle;
|
||||
};
|
||||
|
||||
|
||||
struct svga_texture
|
||||
{
|
||||
struct pipe_texture base;
|
||||
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
struct svga_sampler_view *cached_view;
|
||||
|
||||
unsigned view_age[SVGA_MAX_TEXTURE_LEVELS];
|
||||
unsigned age;
|
||||
|
||||
boolean views_modified;
|
||||
};
|
||||
|
||||
|
||||
struct svga_surface
|
||||
{
|
||||
struct pipe_surface base;
|
||||
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
unsigned real_face;
|
||||
unsigned real_level;
|
||||
unsigned real_zslice;
|
||||
|
||||
boolean dirty;
|
||||
};
|
||||
|
||||
|
||||
struct svga_transfer
|
||||
{
|
||||
struct pipe_transfer base;
|
||||
|
||||
struct svga_winsys_buffer *hwbuf;
|
||||
|
||||
/* Height of the hardware buffer in pixel blocks */
|
||||
unsigned hw_nblocksy;
|
||||
|
||||
/* Temporary malloc buffer when we can't allocate a hardware buffer
|
||||
* big enough */
|
||||
void *swbuf;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct svga_texture *
|
||||
svga_texture(struct pipe_texture *texture)
|
||||
{
|
||||
return (struct svga_texture *)texture;
|
||||
}
|
||||
|
||||
static INLINE struct svga_surface *
|
||||
svga_surface(struct pipe_surface *surface)
|
||||
{
|
||||
assert(surface);
|
||||
return (struct svga_surface *)surface;
|
||||
}
|
||||
|
||||
static INLINE struct svga_transfer *
|
||||
svga_transfer(struct pipe_transfer *transfer)
|
||||
{
|
||||
assert(transfer);
|
||||
return (struct svga_transfer *)transfer;
|
||||
}
|
||||
|
||||
extern struct svga_sampler_view *
|
||||
svga_get_tex_sampler_view(struct pipe_context *pipe,
|
||||
struct pipe_texture *pt,
|
||||
unsigned min_lod, unsigned max_lod);
|
||||
|
||||
void
|
||||
svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v);
|
||||
|
||||
void
|
||||
svga_destroy_sampler_view_priv(struct svga_sampler_view *v);
|
||||
|
||||
static INLINE void
|
||||
svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_view *v)
|
||||
{
|
||||
struct svga_sampler_view *old = *ptr;
|
||||
|
||||
if (pipe_reference((struct pipe_reference **)ptr, &v->reference))
|
||||
svga_destroy_sampler_view_priv(old);
|
||||
}
|
||||
|
||||
extern void
|
||||
svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf);
|
||||
|
||||
extern boolean
|
||||
svga_surface_needs_propagation(struct pipe_surface *surf);
|
||||
|
||||
extern void
|
||||
svga_screen_init_texture_functions(struct pipe_screen *screen);
|
||||
|
||||
enum SVGA3dSurfaceFormat
|
||||
svga_translate_format(enum pipe_format format);
|
||||
|
||||
enum SVGA3dSurfaceFormat
|
||||
svga_translate_format_render(enum pipe_format format);
|
||||
|
||||
|
||||
#endif /* SVGA_TEXTURE_H */
|
||||
278
src/gallium/drivers/svga/svga_state.c
Normal file
278
src/gallium/drivers/svga/svga_state.c
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
/* This is just enough to decide whether we need to use the draw
|
||||
* module (swtnl) or not.
|
||||
*/
|
||||
static const struct svga_tracked_state *need_swtnl_state[] =
|
||||
{
|
||||
&svga_update_need_swvfetch,
|
||||
&svga_update_need_pipeline,
|
||||
&svga_update_need_swtnl,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* Atoms to update hardware state prior to emitting a clear or draw
|
||||
* packet.
|
||||
*/
|
||||
static const struct svga_tracked_state *hw_clear_state[] =
|
||||
{
|
||||
&svga_hw_scissor,
|
||||
&svga_hw_viewport,
|
||||
&svga_hw_framebuffer,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* Atoms to update hardware state prior to emitting a draw packet.
|
||||
*/
|
||||
static const struct svga_tracked_state *hw_draw_state[] =
|
||||
{
|
||||
&svga_hw_update_zero_stride,
|
||||
&svga_hw_fs,
|
||||
&svga_hw_vs,
|
||||
&svga_hw_rss,
|
||||
&svga_hw_tss,
|
||||
&svga_hw_tss_binding,
|
||||
&svga_hw_clip_planes,
|
||||
&svga_hw_vdecl,
|
||||
&svga_hw_fs_parameters,
|
||||
&svga_hw_vs_parameters,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static const struct svga_tracked_state *swtnl_draw_state[] =
|
||||
{
|
||||
&svga_update_swtnl_draw,
|
||||
&svga_update_swtnl_vdecl,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Flattens the graph of state dependencies. Could swap the positions
|
||||
* of hw_clear_state and need_swtnl_state without breaking anything.
|
||||
*/
|
||||
static const struct svga_tracked_state **state_levels[] =
|
||||
{
|
||||
need_swtnl_state,
|
||||
hw_clear_state,
|
||||
hw_draw_state,
|
||||
swtnl_draw_state
|
||||
};
|
||||
|
||||
|
||||
|
||||
static unsigned check_state( unsigned a,
|
||||
unsigned b )
|
||||
{
|
||||
return (a & b);
|
||||
}
|
||||
|
||||
static void accumulate_state( unsigned *a,
|
||||
unsigned b )
|
||||
{
|
||||
*a |= b;
|
||||
}
|
||||
|
||||
|
||||
static void xor_states( unsigned *result,
|
||||
unsigned a,
|
||||
unsigned b )
|
||||
{
|
||||
*result = a ^ b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int update_state( struct svga_context *svga,
|
||||
const struct svga_tracked_state *atoms[],
|
||||
unsigned *state )
|
||||
{
|
||||
boolean debug = TRUE;
|
||||
enum pipe_error ret = 0;
|
||||
unsigned i;
|
||||
|
||||
ret = svga_hwtnl_flush( svga->hwtnl );
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (debug) {
|
||||
/* Debug version which enforces various sanity checks on the
|
||||
* state flags which are generated and checked to help ensure
|
||||
* state atoms are ordered correctly in the list.
|
||||
*/
|
||||
unsigned examined, prev;
|
||||
|
||||
examined = 0;
|
||||
prev = *state;
|
||||
|
||||
for (i = 0; atoms[i] != NULL; i++) {
|
||||
unsigned generated;
|
||||
|
||||
assert(atoms[i]->dirty);
|
||||
assert(atoms[i]->update);
|
||||
|
||||
if (check_state(*state, atoms[i]->dirty)) {
|
||||
if (0)
|
||||
debug_printf("update: %s\n", atoms[i]->name);
|
||||
ret = atoms[i]->update( svga, *state );
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* generated = (prev ^ state)
|
||||
* if (examined & generated)
|
||||
* fail;
|
||||
*/
|
||||
xor_states(&generated, prev, *state);
|
||||
if (check_state(examined, generated)) {
|
||||
debug_printf("state atom %s generated state already examined\n",
|
||||
atoms[i]->name);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
prev = *state;
|
||||
accumulate_state(&examined, atoms[i]->dirty);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; atoms[i] != NULL; i++) {
|
||||
if (check_state(*state, atoms[i]->dirty)) {
|
||||
ret = atoms[i]->update( svga, *state );
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int svga_update_state( struct svga_context *svga,
|
||||
unsigned max_level )
|
||||
{
|
||||
struct svga_screen *screen = svga_screen(svga->pipe.screen);
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
/* Check for updates to bound textures. This can't be done in an
|
||||
* atom as there is no flag which could provoke this test, and we
|
||||
* cannot create one.
|
||||
*/
|
||||
if (svga->state.texture_timestamp != screen->texture_timestamp) {
|
||||
svga->state.texture_timestamp = screen->texture_timestamp;
|
||||
svga->dirty |= SVGA_NEW_TEXTURE;
|
||||
}
|
||||
|
||||
for (i = 0; i <= max_level; i++) {
|
||||
svga->dirty |= svga->state.dirty[i];
|
||||
|
||||
if (svga->dirty) {
|
||||
ret = update_state( svga,
|
||||
state_levels[i],
|
||||
&svga->dirty );
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
svga->state.dirty[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < SVGA_STATE_MAX; i++)
|
||||
svga->state.dirty[i] |= svga->dirty;
|
||||
|
||||
svga->dirty = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void svga_update_state_retry( struct svga_context *svga,
|
||||
unsigned max_level )
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = svga_update_state( svga, max_level );
|
||||
|
||||
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = svga_update_state( svga, max_level );
|
||||
}
|
||||
|
||||
assert( ret == 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define EMIT_RS(_rs, _count, _name, _value) \
|
||||
do { \
|
||||
_rs[_count].state = _name; \
|
||||
_rs[_count].uintValue = _value; \
|
||||
_count++; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Setup any hardware state which will be constant through the life of
|
||||
* a context.
|
||||
*/
|
||||
enum pipe_error svga_emit_initial_state( struct svga_context *svga )
|
||||
{
|
||||
SVGA3dRenderState *rs;
|
||||
unsigned count = 0;
|
||||
const unsigned COUNT = 2;
|
||||
enum pipe_error ret;
|
||||
|
||||
ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Always use D3D style coordinate space as this is the only one
|
||||
* which is implemented on all backends.
|
||||
*/
|
||||
EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE, SVGA3D_COORDINATE_LEFTHANDED );
|
||||
EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
|
||||
|
||||
assert( COUNT == count );
|
||||
SVGA_FIFOCommitAll( svga->swc );
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
95
src/gallium/drivers/svga/svga_state.h
Normal file
95
src/gallium/drivers/svga/svga_state.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_STATE_H
|
||||
#define SVGA_STATE_H
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
struct svga_context;
|
||||
|
||||
|
||||
void svga_init_state( struct svga_context *svga );
|
||||
void svga_destroy_state( struct svga_context *svga );
|
||||
|
||||
|
||||
struct svga_tracked_state {
|
||||
const char *name;
|
||||
unsigned dirty;
|
||||
int (*update)( struct svga_context *svga, unsigned dirty );
|
||||
};
|
||||
|
||||
/* NEED_SWTNL
|
||||
*/
|
||||
extern struct svga_tracked_state svga_update_need_swvfetch;
|
||||
extern struct svga_tracked_state svga_update_need_pipeline;
|
||||
extern struct svga_tracked_state svga_update_need_swtnl;
|
||||
|
||||
/* HW_CLEAR
|
||||
*/
|
||||
extern struct svga_tracked_state svga_hw_viewport;
|
||||
extern struct svga_tracked_state svga_hw_scissor;
|
||||
extern struct svga_tracked_state svga_hw_framebuffer;
|
||||
|
||||
/* HW_DRAW
|
||||
*/
|
||||
extern struct svga_tracked_state svga_hw_vs;
|
||||
extern struct svga_tracked_state svga_hw_fs;
|
||||
extern struct svga_tracked_state svga_hw_rss;
|
||||
extern struct svga_tracked_state svga_hw_tss;
|
||||
extern struct svga_tracked_state svga_hw_tss_binding;
|
||||
extern struct svga_tracked_state svga_hw_clip_planes;
|
||||
extern struct svga_tracked_state svga_hw_vdecl;
|
||||
extern struct svga_tracked_state svga_hw_fs_parameters;
|
||||
extern struct svga_tracked_state svga_hw_vs_parameters;
|
||||
extern struct svga_tracked_state svga_hw_update_zero_stride;
|
||||
|
||||
/* SWTNL_DRAW
|
||||
*/
|
||||
extern struct svga_tracked_state svga_update_swtnl_draw;
|
||||
extern struct svga_tracked_state svga_update_swtnl_vdecl;
|
||||
|
||||
/* Bring the hardware fully up-to-date so that we can emit draw
|
||||
* commands.
|
||||
*/
|
||||
#define SVGA_STATE_NEED_SWTNL 0
|
||||
#define SVGA_STATE_HW_CLEAR 1
|
||||
#define SVGA_STATE_HW_DRAW 2
|
||||
#define SVGA_STATE_SWTNL_DRAW 3
|
||||
#define SVGA_STATE_MAX 4
|
||||
|
||||
|
||||
enum pipe_error svga_update_state( struct svga_context *svga,
|
||||
unsigned level );
|
||||
|
||||
void svga_update_state_retry( struct svga_context *svga,
|
||||
unsigned level );
|
||||
|
||||
|
||||
enum pipe_error svga_emit_initial_state( struct svga_context *svga );
|
||||
|
||||
#endif
|
||||
239
src/gallium/drivers/svga/svga_state_constants.c
Normal file
239
src/gallium/drivers/svga/svga_state_constants.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Hardware update
|
||||
*/
|
||||
|
||||
/* Convert from PIPE_SHADER_* to SVGA3D_SHADERTYPE_*
|
||||
*/
|
||||
static int svga_shader_type( int unit )
|
||||
{
|
||||
return unit + 1;
|
||||
}
|
||||
|
||||
|
||||
static int emit_const( struct svga_context *svga,
|
||||
int unit,
|
||||
int i,
|
||||
const float *value )
|
||||
{
|
||||
int ret = PIPE_OK;
|
||||
|
||||
if (memcmp(svga->state.hw_draw.cb[unit][i], value, 4 * sizeof(float)) != 0) {
|
||||
if (SVGA_DEBUG & DEBUG_CONSTS)
|
||||
debug_printf("%s %s %d: %f %f %f %f\n",
|
||||
__FUNCTION__,
|
||||
unit == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
|
||||
i,
|
||||
value[0],
|
||||
value[1],
|
||||
value[2],
|
||||
value[3]);
|
||||
|
||||
ret = SVGA3D_SetShaderConst( svga->swc,
|
||||
i,
|
||||
svga_shader_type(unit),
|
||||
SVGA3D_CONST_TYPE_FLOAT,
|
||||
value );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy(svga->state.hw_draw.cb[unit][i], value, 4 * sizeof(float));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int emit_consts( struct svga_context *svga,
|
||||
int offset,
|
||||
int unit )
|
||||
{
|
||||
struct pipe_screen *screen = svga->pipe.screen;
|
||||
unsigned count;
|
||||
const float (*data)[4] = NULL;
|
||||
unsigned i;
|
||||
int ret = PIPE_OK;
|
||||
|
||||
if (svga->curr.cb[unit] == NULL)
|
||||
goto done;
|
||||
|
||||
count = svga->curr.cb[unit]->size / (4 * sizeof(float));
|
||||
|
||||
data = (const float (*)[4])pipe_buffer_map(screen,
|
||||
svga->curr.cb[unit],
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
if (data == NULL) {
|
||||
ret = PIPE_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = emit_const( svga, unit, offset + i, data[i] );
|
||||
if (ret)
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (data)
|
||||
pipe_buffer_unmap(screen, svga->curr.cb[unit]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int emit_fs_consts( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
const struct svga_shader_result *result = svga->state.hw_draw.fs;
|
||||
const struct svga_fs_compile_key *key = &result->key.fkey;
|
||||
int ret = 0;
|
||||
|
||||
ret = emit_consts( svga, 0, PIPE_SHADER_FRAGMENT );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* The internally generated fragment shader for xor blending
|
||||
* doesn't have a 'result' struct. It should be fixed to avoid
|
||||
* this special case, but work around it with a NULL check:
|
||||
*/
|
||||
if (result != NULL &&
|
||||
key->num_unnormalized_coords)
|
||||
{
|
||||
unsigned offset = result->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < key->num_textures; i++) {
|
||||
if (key->tex[i].unnormalized) {
|
||||
struct pipe_texture *tex = svga->curr.texture[i];
|
||||
float data[4];
|
||||
|
||||
data[0] = 1.0 / (float)tex->width[0];
|
||||
data[1] = 1.0 / (float)tex->height[0];
|
||||
data[2] = 1.0;
|
||||
data[3] = 1.0;
|
||||
|
||||
ret = emit_const( svga,
|
||||
PIPE_SHADER_FRAGMENT,
|
||||
key->tex[i].width_height_idx + offset,
|
||||
data );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
offset += key->num_unnormalized_coords;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_fs_parameters =
|
||||
{
|
||||
"hw fs params",
|
||||
(SVGA_NEW_FS_CONST_BUFFER |
|
||||
SVGA_NEW_FS_RESULT |
|
||||
SVGA_NEW_TEXTURE_BINDING),
|
||||
emit_fs_consts
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static int emit_vs_consts( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
const struct svga_shader_result *result = svga->state.hw_draw.vs;
|
||||
const struct svga_vs_compile_key *key = &result->key.vkey;
|
||||
int ret = 0;
|
||||
unsigned offset;
|
||||
|
||||
/* SVGA_NEW_VS_RESULT
|
||||
*/
|
||||
if (result == NULL)
|
||||
return 0;
|
||||
|
||||
/* SVGA_NEW_VS_CONST_BUFFER
|
||||
*/
|
||||
ret = emit_consts( svga, 0, PIPE_SHADER_VERTEX );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
offset = result->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
|
||||
/* SVGA_NEW_VS_RESULT
|
||||
*/
|
||||
if (key->need_prescale) {
|
||||
ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
|
||||
svga->state.hw_clear.prescale.scale );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
|
||||
svga->state.hw_clear.prescale.translate );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* SVGA_NEW_ZERO_STRIDE
|
||||
*/
|
||||
if (key->zero_stride_vertex_elements) {
|
||||
unsigned i, curr_zero_stride = 0;
|
||||
for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
|
||||
if (key->zero_stride_vertex_elements & (1 << i)) {
|
||||
ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
|
||||
svga->curr.zero_stride_constants +
|
||||
4 * curr_zero_stride );
|
||||
if (ret)
|
||||
return ret;
|
||||
++curr_zero_stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_vs_parameters =
|
||||
{
|
||||
"hw vs params",
|
||||
(SVGA_NEW_VS_CONST_BUFFER |
|
||||
SVGA_NEW_ZERO_STRIDE |
|
||||
SVGA_NEW_VS_RESULT),
|
||||
emit_vs_consts
|
||||
};
|
||||
|
||||
455
src/gallium/drivers/svga/svga_state_framebuffer.c
Normal file
455
src/gallium/drivers/svga/svga_state_framebuffer.c
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Hardware state update
|
||||
*/
|
||||
|
||||
|
||||
static int emit_framebuffer( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
const struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
|
||||
struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
|
||||
unsigned i;
|
||||
enum pipe_error ret;
|
||||
|
||||
/* XXX: Need shadow state in svga->hw to eliminate redundant
|
||||
* uploads, especially of NULL buffers.
|
||||
*/
|
||||
|
||||
for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
|
||||
if (curr->cbufs[i] != hw->cbufs[i]) {
|
||||
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (curr->zsbuf != hw->zsbuf) {
|
||||
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, curr->zsbuf);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
if (curr->zsbuf &&
|
||||
curr->zsbuf->format == PIPE_FORMAT_Z24S8_UNORM) {
|
||||
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, curr->zsbuf);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, NULL);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_framebuffer =
|
||||
{
|
||||
"hw framebuffer state",
|
||||
SVGA_NEW_FRAME_BUFFER,
|
||||
emit_framebuffer
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static int emit_viewport( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
const struct pipe_viewport_state *viewport = &svga->curr.viewport;
|
||||
struct svga_prescale prescale;
|
||||
SVGA3dRect rect;
|
||||
/* Not sure if this state is relevant with POSITIONT. Probably
|
||||
* not, but setting to 0,1 avoids some state pingponging.
|
||||
*/
|
||||
float range_min = 0.0;
|
||||
float range_max = 1.0;
|
||||
float flip = -1.0;
|
||||
boolean degenerate = FALSE;
|
||||
enum pipe_error ret;
|
||||
|
||||
float fb_width = svga->curr.framebuffer.width;
|
||||
float fb_height = svga->curr.framebuffer.height;
|
||||
|
||||
memset( &prescale, 0, sizeof(prescale) );
|
||||
|
||||
if (svga->curr.rast->templ.bypass_vs_clip_and_viewport) {
|
||||
|
||||
/* Avoid POSITIONT as it has a non trivial implementation outside the D3D
|
||||
* API. Always generate a vertex shader.
|
||||
*/
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = svga->curr.framebuffer.width;
|
||||
rect.h = svga->curr.framebuffer.height;
|
||||
|
||||
prescale.scale[0] = 2.0 / (float)rect.w;
|
||||
prescale.scale[1] = - 2.0 / (float)rect.h;
|
||||
prescale.scale[2] = 1.0;
|
||||
prescale.scale[3] = 1.0;
|
||||
prescale.translate[0] = -1.0f;
|
||||
prescale.translate[1] = 1.0f;
|
||||
prescale.translate[2] = 0;
|
||||
prescale.translate[3] = 0;
|
||||
prescale.enabled = TRUE;
|
||||
} else {
|
||||
|
||||
/* Examine gallium viewport transformation and produce a screen
|
||||
* rectangle and possibly vertex shader pre-transformation to
|
||||
* get the same results.
|
||||
*/
|
||||
float fx = viewport->scale[0] * -1.0 + viewport->translate[0];
|
||||
float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
|
||||
float fw = viewport->scale[0] * 2;
|
||||
float fh = flip * viewport->scale[1] * 2;
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWPORT,
|
||||
"\ninitial %f,%f %fx%f\n",
|
||||
fx,
|
||||
fy,
|
||||
fw,
|
||||
fh);
|
||||
|
||||
prescale.scale[0] = 1.0;
|
||||
prescale.scale[1] = 1.0;
|
||||
prescale.scale[2] = 1.0;
|
||||
prescale.scale[3] = 1.0;
|
||||
prescale.translate[0] = 0;
|
||||
prescale.translate[1] = 0;
|
||||
prescale.translate[2] = 0;
|
||||
prescale.translate[3] = 0;
|
||||
prescale.enabled = TRUE;
|
||||
|
||||
|
||||
|
||||
if (fw < 0) {
|
||||
prescale.scale[0] *= -1.0;
|
||||
prescale.translate[0] += -fw;
|
||||
fw = -fw;
|
||||
fx = viewport->scale[0] * 1.0 + viewport->translate[0];
|
||||
}
|
||||
|
||||
if (fh < 0) {
|
||||
prescale.scale[1] *= -1.0;
|
||||
prescale.translate[1] += -fh;
|
||||
fh = -fh;
|
||||
fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
|
||||
}
|
||||
|
||||
if (fx < 0) {
|
||||
prescale.translate[0] += fx;
|
||||
prescale.scale[0] *= fw / (fw + fx);
|
||||
fw += fx;
|
||||
fx = 0;
|
||||
}
|
||||
|
||||
if (fy < 0) {
|
||||
prescale.translate[1] += fy;
|
||||
prescale.scale[1] *= fh / (fh + fy);
|
||||
fh += fy;
|
||||
fy = 0;
|
||||
}
|
||||
|
||||
if (fx + fw > fb_width) {
|
||||
prescale.scale[0] *= fw / (fb_width - fx);
|
||||
prescale.translate[0] -= fx * (fw / (fb_width - fx));
|
||||
prescale.translate[0] += fx;
|
||||
fw = fb_width - fx;
|
||||
|
||||
}
|
||||
|
||||
if (fy + fh > fb_height) {
|
||||
prescale.scale[1] *= fh / (fb_height - fy);
|
||||
prescale.translate[1] -= fy * (fh / (fb_height - fy));
|
||||
prescale.translate[1] += fy;
|
||||
fh = fb_height - fy;
|
||||
}
|
||||
|
||||
if (fw < 0 || fh < 0) {
|
||||
fw = fh = fx = fy = 0;
|
||||
degenerate = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* D3D viewport is integer space. Convert fx,fy,etc. to
|
||||
* integers.
|
||||
*
|
||||
* TODO: adjust pretranslate correct for any subpixel error
|
||||
* introduced converting to integers.
|
||||
*/
|
||||
rect.x = fx;
|
||||
rect.y = fy;
|
||||
rect.w = fw;
|
||||
rect.h = fh;
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWPORT,
|
||||
"viewport error %f,%f %fx%f\n",
|
||||
fabs((float)rect.x - fx),
|
||||
fabs((float)rect.y - fy),
|
||||
fabs((float)rect.w - fw),
|
||||
fabs((float)rect.h - fh));
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWPORT,
|
||||
"viewport %d,%d %dx%d\n",
|
||||
rect.x,
|
||||
rect.y,
|
||||
rect.w,
|
||||
rect.h);
|
||||
|
||||
|
||||
/* Finally, to get GL rasterization rules, need to tweak the
|
||||
* screen-space coordinates slightly relative to D3D which is
|
||||
* what hardware implements natively.
|
||||
*/
|
||||
if (svga->curr.rast->templ.gl_rasterization_rules) {
|
||||
float adjust_x = 0.0;
|
||||
float adjust_y = 0.0;
|
||||
|
||||
switch (svga->curr.reduced_prim) {
|
||||
case PIPE_PRIM_LINES:
|
||||
adjust_x = -0.5;
|
||||
adjust_y = 0;
|
||||
break;
|
||||
case PIPE_PRIM_POINTS:
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
adjust_x = -0.375;
|
||||
adjust_y = -0.5;
|
||||
break;
|
||||
}
|
||||
|
||||
prescale.translate[0] += adjust_x;
|
||||
prescale.translate[1] += adjust_y;
|
||||
prescale.translate[2] = 0.5; /* D3D clip space */
|
||||
prescale.scale[2] = 0.5; /* D3D clip space */
|
||||
}
|
||||
|
||||
|
||||
range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
|
||||
range_max = viewport->scale[2] * 1.0 + viewport->translate[2];
|
||||
|
||||
/* D3D (and by implication SVGA) doesn't like dealing with zmax
|
||||
* less than zmin. Detect that case, flip the depth range and
|
||||
* invert our z-scale factor to achieve the same effect.
|
||||
*/
|
||||
if (range_min > range_max) {
|
||||
float range_tmp;
|
||||
range_tmp = range_min;
|
||||
range_min = range_max;
|
||||
range_max = range_tmp;
|
||||
prescale.scale[2] = -prescale.scale[2];
|
||||
}
|
||||
}
|
||||
|
||||
if (prescale.enabled) {
|
||||
float H[2];
|
||||
float J[2];
|
||||
int i;
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWPORT,
|
||||
"prescale %f,%f %fx%f\n",
|
||||
prescale.translate[0],
|
||||
prescale.translate[1],
|
||||
prescale.scale[0],
|
||||
prescale.scale[1]);
|
||||
|
||||
H[0] = (float)rect.w / 2.0;
|
||||
H[1] = -(float)rect.h / 2.0;
|
||||
J[0] = (float)rect.x + (float)rect.w / 2.0;
|
||||
J[1] = (float)rect.y + (float)rect.h / 2.0;
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWPORT,
|
||||
"H %f,%f\n"
|
||||
"J %fx%f\n",
|
||||
H[0],
|
||||
H[1],
|
||||
J[0],
|
||||
J[1]);
|
||||
|
||||
/* Adjust prescale to take into account the fact that it is
|
||||
* going to be applied prior to the perspective divide and
|
||||
* viewport transformation.
|
||||
*
|
||||
* Vwin = H(Vc/Vc.w) + J
|
||||
*
|
||||
* We want to tweak Vwin with scale and translation from above,
|
||||
* as in:
|
||||
*
|
||||
* Vwin' = S Vwin + T
|
||||
*
|
||||
* But we can only modify the values at Vc. Plugging all the
|
||||
* above together, and rearranging, eventually we get:
|
||||
*
|
||||
* Vwin' = H(Vc'/Vc'.w) + J
|
||||
* where:
|
||||
* Vc' = SVc + KVc.w
|
||||
* K = (T + (S-1)J) / H
|
||||
*
|
||||
* Overwrite prescale.translate with values for K:
|
||||
*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
prescale.translate[i] = ((prescale.translate[i] +
|
||||
(prescale.scale[i] - 1.0) * J[i]) / H[i]);
|
||||
}
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWPORT,
|
||||
"clipspace %f,%f %fx%f\n",
|
||||
prescale.translate[0],
|
||||
prescale.translate[1],
|
||||
prescale.scale[0],
|
||||
prescale.scale[1]);
|
||||
}
|
||||
|
||||
out:
|
||||
if (degenerate) {
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = 1;
|
||||
rect.h = 1;
|
||||
prescale.enabled = FALSE;
|
||||
}
|
||||
|
||||
if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
|
||||
ret = SVGA3D_SetViewport(svga->swc, &rect);
|
||||
if(ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
memcpy(&svga->state.hw_clear.viewport, &rect, sizeof(rect));
|
||||
assert(sizeof(rect) == sizeof(svga->state.hw_clear.viewport));
|
||||
}
|
||||
|
||||
if (svga->state.hw_clear.depthrange.zmin != range_min ||
|
||||
svga->state.hw_clear.depthrange.zmax != range_max)
|
||||
{
|
||||
ret = SVGA3D_SetZRange(svga->swc, range_min, range_max );
|
||||
if(ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
svga->state.hw_clear.depthrange.zmin = range_min;
|
||||
svga->state.hw_clear.depthrange.zmax = range_max;
|
||||
}
|
||||
|
||||
if (memcmp(&prescale, &svga->state.hw_clear.prescale, sizeof prescale) != 0) {
|
||||
svga->dirty |= SVGA_NEW_PRESCALE;
|
||||
svga->state.hw_clear.prescale = prescale;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_viewport =
|
||||
{
|
||||
"hw viewport state",
|
||||
( SVGA_NEW_FRAME_BUFFER |
|
||||
SVGA_NEW_VIEWPORT |
|
||||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_REDUCED_PRIMITIVE ),
|
||||
emit_viewport
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Scissor state
|
||||
*/
|
||||
static int emit_scissor_rect( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
const struct pipe_scissor_state *scissor = &svga->curr.scissor;
|
||||
SVGA3dRect rect;
|
||||
|
||||
rect.x = scissor->minx;
|
||||
rect.y = scissor->miny;
|
||||
rect.w = scissor->maxx - scissor->minx; /* + 1 ?? */
|
||||
rect.h = scissor->maxy - scissor->miny; /* + 1 ?? */
|
||||
|
||||
return SVGA3D_SetScissorRect(svga->swc, &rect);
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_scissor =
|
||||
{
|
||||
"hw scissor state",
|
||||
SVGA_NEW_SCISSOR,
|
||||
emit_scissor_rect
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Userclip state
|
||||
*/
|
||||
|
||||
static int emit_clip_planes( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
unsigned i;
|
||||
enum pipe_error ret;
|
||||
|
||||
/* TODO: just emit directly from svga_set_clip_state()?
|
||||
*/
|
||||
for (i = 0; i < svga->curr.clip.nr; i++) {
|
||||
ret = SVGA3D_SetClipPlane( svga->swc,
|
||||
i,
|
||||
svga->curr.clip.ucp[i] );
|
||||
if(ret != PIPE_OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_clip_planes =
|
||||
{
|
||||
"hw viewport state",
|
||||
SVGA_NEW_CLIP,
|
||||
emit_clip_planes
|
||||
};
|
||||
282
src/gallium/drivers/svga/svga_state_fs.c
Normal file
282
src/gallium/drivers/svga/svga_state_fs.c
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_tgsi.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
|
||||
static INLINE int compare_fs_keys( const struct svga_fs_compile_key *a,
|
||||
const struct svga_fs_compile_key *b )
|
||||
{
|
||||
unsigned keysize = svga_fs_key_size( a );
|
||||
return memcmp( a, b, keysize );
|
||||
}
|
||||
|
||||
|
||||
static struct svga_shader_result *search_fs_key( struct svga_fragment_shader *fs,
|
||||
const struct svga_fs_compile_key *key )
|
||||
{
|
||||
struct svga_shader_result *result = fs->base.results;
|
||||
|
||||
assert(key);
|
||||
|
||||
for ( ; result; result = result->next) {
|
||||
if (compare_fs_keys( key, &result->key.fkey ) == 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error compile_fs( struct svga_context *svga,
|
||||
struct svga_fragment_shader *fs,
|
||||
const struct svga_fs_compile_key *key,
|
||||
struct svga_shader_result **out_result )
|
||||
{
|
||||
struct svga_shader_result *result;
|
||||
enum pipe_error ret;
|
||||
|
||||
result = svga_translate_fragment_program( fs, key );
|
||||
if (result == NULL) {
|
||||
ret = PIPE_ERROR_OUT_OF_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
ret = SVGA3D_DefineShader(svga->swc,
|
||||
svga->state.next_fs_id,
|
||||
SVGA3D_SHADERTYPE_PS,
|
||||
result->tokens,
|
||||
result->nr_tokens * sizeof result->tokens[0]);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
*out_result = result;
|
||||
result->id = svga->state.next_fs_id++;
|
||||
result->next = fs->base.results;
|
||||
fs->base.results = result;
|
||||
return PIPE_OK;
|
||||
|
||||
fail:
|
||||
if (result)
|
||||
svga_destroy_shader_result( result );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The blend workaround for simulating logicop xor behaviour requires
|
||||
* that the incoming fragment color be white. This change achieves
|
||||
* that by hooking up a hard-wired fragment shader that just emits
|
||||
* color 1,1,1,1
|
||||
*
|
||||
* This is a slightly incomplete solution as it assumes that the
|
||||
* actual bound shader has no other effects beyond generating a
|
||||
* fragment color. In particular shaders containing TEXKIL and/or
|
||||
* depth-write will not have the correct behaviour, nor will those
|
||||
* expecting to use alphatest.
|
||||
*
|
||||
* These are avoidable issues, but they are not much worse than the
|
||||
* unavoidable ones associated with this technique, so it's not clear
|
||||
* how much effort should be expended trying to resolve them - the
|
||||
* ultimate result will still not be correct in most cases.
|
||||
*
|
||||
* Shader below was generated with:
|
||||
* SVGA_DEBUG=tgsi ./mesa/progs/fp/fp-tri white.txt
|
||||
*/
|
||||
static int emit_white_fs( struct svga_context *svga )
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ps_3_0
|
||||
* def c0, 1.000000, 0.000000, 0.000000, 1.000000
|
||||
* mov oC0, c0.x
|
||||
* end
|
||||
*/
|
||||
static const unsigned white_tokens[] = {
|
||||
0xffff0300,
|
||||
0x05000051,
|
||||
0xa00f0000,
|
||||
0x3f800000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x3f800000,
|
||||
0x02000001,
|
||||
0x800f0800,
|
||||
0xa0000000,
|
||||
0x0000ffff,
|
||||
};
|
||||
|
||||
ret = SVGA3D_DefineShader(svga->swc,
|
||||
svga->state.next_fs_id,
|
||||
SVGA3D_SHADERTYPE_PS,
|
||||
white_tokens,
|
||||
sizeof(white_tokens));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
svga->state.white_fs_id = svga->state.next_fs_id++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* SVGA_NEW_TEXTURE_BINDING
|
||||
* SVGA_NEW_RAST
|
||||
* SVGA_NEW_NEED_SWTNL
|
||||
* SVGA_NEW_SAMPLER
|
||||
*/
|
||||
static int make_fs_key( const struct svga_context *svga,
|
||||
struct svga_fs_compile_key *key )
|
||||
{
|
||||
int i;
|
||||
int idx = 0;
|
||||
|
||||
memset(key, 0, sizeof *key);
|
||||
|
||||
/* Only need fragment shader fixup for twoside lighting if doing
|
||||
* hwtnl. Otherwise the draw module does the whole job for us.
|
||||
*
|
||||
* SVGA_NEW_SWTNL
|
||||
*/
|
||||
if (!svga->state.sw.need_swtnl) {
|
||||
/* SVGA_NEW_RAST
|
||||
*/
|
||||
key->light_twoside = svga->curr.rast->templ.light_twoside;
|
||||
key->front_cw = (svga->curr.rast->templ.front_winding ==
|
||||
PIPE_WINDING_CW);
|
||||
}
|
||||
|
||||
|
||||
/* XXX: want to limit this to the textures that the shader actually
|
||||
* refers to.
|
||||
*
|
||||
* SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
|
||||
*/
|
||||
for (i = 0; i < svga->curr.num_textures; i++) {
|
||||
if (svga->curr.texture[i]) {
|
||||
assert(svga->curr.sampler[i]);
|
||||
key->tex[i].texture_target = svga->curr.texture[i]->target;
|
||||
if (!svga->curr.sampler[i]->normalized_coords) {
|
||||
key->tex[i].width_height_idx = idx++;
|
||||
key->tex[i].unnormalized = TRUE;
|
||||
++key->num_unnormalized_coords;
|
||||
}
|
||||
}
|
||||
}
|
||||
key->num_textures = svga->curr.num_textures;
|
||||
|
||||
idx = 0;
|
||||
for (i = 0; i < svga->curr.num_samplers; ++i) {
|
||||
if (svga->curr.sampler[i]) {
|
||||
key->tex[i].compare_mode = svga->curr.sampler[i]->compare_mode;
|
||||
key->tex[i].compare_func = svga->curr.sampler[i]->compare_func;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int emit_hw_fs( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
struct svga_shader_result *result = NULL;
|
||||
unsigned id = SVGA3D_INVALID_ID;
|
||||
int ret = 0;
|
||||
|
||||
/* SVGA_NEW_BLEND
|
||||
*/
|
||||
if (svga->curr.blend->need_white_fragments) {
|
||||
if (svga->state.white_fs_id == SVGA3D_INVALID_ID) {
|
||||
ret = emit_white_fs( svga );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
id = svga->state.white_fs_id;
|
||||
}
|
||||
else {
|
||||
struct svga_fragment_shader *fs = svga->curr.fs;
|
||||
struct svga_fs_compile_key key;
|
||||
|
||||
/* SVGA_NEW_TEXTURE_BINDING
|
||||
* SVGA_NEW_RAST
|
||||
* SVGA_NEW_NEED_SWTNL
|
||||
* SVGA_NEW_SAMPLER
|
||||
*/
|
||||
ret = make_fs_key( svga, &key );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
result = search_fs_key( fs, &key );
|
||||
if (!result) {
|
||||
ret = compile_fs( svga, fs, &key, &result );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert (result);
|
||||
id = result->id;
|
||||
}
|
||||
|
||||
assert(id != SVGA3D_INVALID_ID);
|
||||
|
||||
if (id != svga->state.hw_draw.shader_id[PIPE_SHADER_FRAGMENT]) {
|
||||
ret = SVGA3D_SetShader(svga->swc,
|
||||
SVGA3D_SHADERTYPE_PS,
|
||||
id );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
svga->dirty |= SVGA_NEW_FS_RESULT;
|
||||
svga->state.hw_draw.shader_id[PIPE_SHADER_FRAGMENT] = id;
|
||||
svga->state.hw_draw.fs = result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct svga_tracked_state svga_hw_fs =
|
||||
{
|
||||
"fragment shader (hwtnl)",
|
||||
(SVGA_NEW_FS |
|
||||
SVGA_NEW_TEXTURE_BINDING |
|
||||
SVGA_NEW_NEED_SWTNL |
|
||||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_SAMPLER |
|
||||
SVGA_NEW_BLEND),
|
||||
emit_hw_fs
|
||||
};
|
||||
|
||||
|
||||
|
||||
200
src/gallium/drivers/svga/svga_state_need_swtnl.c
Normal file
200
src/gallium/drivers/svga/svga_state_need_swtnl.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_debug.h"
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static INLINE SVGA3dDeclType
|
||||
svga_translate_vertex_format(enum pipe_format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R32_FLOAT: return SVGA3D_DECLTYPE_FLOAT1;
|
||||
case PIPE_FORMAT_R32G32_FLOAT: return SVGA3D_DECLTYPE_FLOAT2;
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT: return SVGA3D_DECLTYPE_FLOAT3;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT: return SVGA3D_DECLTYPE_FLOAT4;
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM: return SVGA3D_DECLTYPE_D3DCOLOR;
|
||||
case PIPE_FORMAT_R8G8B8A8_USCALED: return SVGA3D_DECLTYPE_UBYTE4;
|
||||
case PIPE_FORMAT_R16G16_SSCALED: return SVGA3D_DECLTYPE_SHORT2;
|
||||
case PIPE_FORMAT_R16G16B16A16_SSCALED: return SVGA3D_DECLTYPE_SHORT4;
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM: return SVGA3D_DECLTYPE_UBYTE4N;
|
||||
case PIPE_FORMAT_R16G16_SNORM: return SVGA3D_DECLTYPE_SHORT2N;
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM: return SVGA3D_DECLTYPE_SHORT4N;
|
||||
case PIPE_FORMAT_R16G16_UNORM: return SVGA3D_DECLTYPE_USHORT2N;
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM: return SVGA3D_DECLTYPE_USHORT4N;
|
||||
|
||||
/* These formats don't exist yet:
|
||||
*
|
||||
case PIPE_FORMAT_R10G10B10_USCALED: return SVGA3D_DECLTYPE_UDEC3;
|
||||
case PIPE_FORMAT_R10G10B10_SNORM: return SVGA3D_DECLTYPE_DEC3N;
|
||||
case PIPE_FORMAT_R16G16_FLOAT: return SVGA3D_DECLTYPE_FLOAT16_2;
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT: return SVGA3D_DECLTYPE_FLOAT16_4;
|
||||
*/
|
||||
|
||||
default:
|
||||
/* There are many formats without hardware support. This case
|
||||
* will be hit regularly, meaning we'll need swvfetch.
|
||||
*/
|
||||
return SVGA3D_DECLTYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int update_need_swvfetch( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
unsigned i;
|
||||
boolean need_swvfetch = FALSE;
|
||||
|
||||
for (i = 0; i < svga->curr.num_vertex_elements; i++) {
|
||||
svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.ve[i].src_format);
|
||||
if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) {
|
||||
need_swvfetch = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_swvfetch != svga->state.sw.need_swvfetch) {
|
||||
svga->state.sw.need_swvfetch = need_swvfetch;
|
||||
svga->dirty |= SVGA_NEW_NEED_SWVFETCH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct svga_tracked_state svga_update_need_swvfetch =
|
||||
{
|
||||
"update need_swvfetch",
|
||||
( SVGA_NEW_VELEMENT ),
|
||||
update_need_swvfetch
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static int update_need_pipeline( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
|
||||
boolean need_pipeline = FALSE;
|
||||
|
||||
/* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
|
||||
*/
|
||||
if (svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim)) {
|
||||
SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (%d) & prim (%x)\n",
|
||||
__FUNCTION__,
|
||||
svga->curr.rast->need_pipeline,
|
||||
(1 << svga->curr.reduced_prim) );
|
||||
need_pipeline = TRUE;
|
||||
}
|
||||
|
||||
/* SVGA_NEW_EDGEFLAGS
|
||||
*/
|
||||
if (svga->curr.rast->hw_unfilled != PIPE_POLYGON_MODE_FILL &&
|
||||
svga->curr.reduced_prim == PIPE_PRIM_TRIANGLES &&
|
||||
svga->curr.edgeflags != NULL) {
|
||||
SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__);
|
||||
need_pipeline = TRUE;
|
||||
}
|
||||
|
||||
/* SVGA_NEW_CLIP
|
||||
*/
|
||||
if (!svga->curr.rast->templ.bypass_vs_clip_and_viewport &&
|
||||
svga->curr.clip.nr) {
|
||||
SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__);
|
||||
need_pipeline = TRUE;
|
||||
}
|
||||
|
||||
if (need_pipeline != svga->state.sw.need_pipeline) {
|
||||
svga->state.sw.need_pipeline = need_pipeline;
|
||||
svga->dirty |= SVGA_NEW_NEED_PIPELINE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_update_need_pipeline =
|
||||
{
|
||||
"need pipeline",
|
||||
(SVGA_NEW_RAST |
|
||||
SVGA_NEW_CLIP |
|
||||
SVGA_NEW_REDUCED_PRIMITIVE),
|
||||
update_need_pipeline
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static int update_need_swtnl( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
boolean need_swtnl;
|
||||
|
||||
if (svga->debug.no_swtnl) {
|
||||
svga->state.sw.need_swvfetch = 0;
|
||||
svga->state.sw.need_pipeline = 0;
|
||||
}
|
||||
|
||||
need_swtnl = (svga->state.sw.need_swvfetch ||
|
||||
svga->state.sw.need_pipeline);
|
||||
|
||||
if (svga->debug.force_swtnl) {
|
||||
need_swtnl = 1;
|
||||
}
|
||||
|
||||
if (need_swtnl != svga->state.sw.need_swtnl) {
|
||||
SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF,
|
||||
"%s need_swvfetch: %s, need_pipeline %s\n",
|
||||
__FUNCTION__,
|
||||
svga->state.sw.need_swvfetch ? "true" : "false",
|
||||
svga->state.sw.need_pipeline ? "true" : "false");
|
||||
|
||||
svga->state.sw.need_swtnl = need_swtnl;
|
||||
svga->dirty |= SVGA_NEW_NEED_SWTNL;
|
||||
svga->swtnl.new_vdecl = TRUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_update_need_swtnl =
|
||||
{
|
||||
"need swtnl",
|
||||
(SVGA_NEW_NEED_PIPELINE |
|
||||
SVGA_NEW_NEED_SWVFETCH),
|
||||
update_need_swtnl
|
||||
};
|
||||
268
src/gallium/drivers/svga/svga_state_rss.c
Normal file
268
src/gallium/drivers/svga/svga_state_rss.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
|
||||
struct rs_queue {
|
||||
unsigned rs_count;
|
||||
SVGA3dRenderState rs[SVGA3D_RS_MAX];
|
||||
};
|
||||
|
||||
|
||||
#define EMIT_RS(svga, value, token, fail) \
|
||||
do { \
|
||||
if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) { \
|
||||
svga_queue_rs( &queue, SVGA3D_RS_##token, value ); \
|
||||
svga->state.hw_draw.rs[SVGA3D_RS_##token] = value; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_RS_FLOAT(svga, fvalue, token, fail) \
|
||||
do { \
|
||||
unsigned value = fui(fvalue); \
|
||||
if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) { \
|
||||
svga_queue_rs( &queue, SVGA3D_RS_##token, value ); \
|
||||
svga->state.hw_draw.rs[SVGA3D_RS_##token] = value; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
static INLINE void
|
||||
svga_queue_rs( struct rs_queue *q,
|
||||
unsigned rss,
|
||||
unsigned value )
|
||||
{
|
||||
q->rs[q->rs_count].state = rss;
|
||||
q->rs[q->rs_count].uintValue = value;
|
||||
q->rs_count++;
|
||||
}
|
||||
|
||||
|
||||
/* Compare old and new render states and emit differences between them
|
||||
* to hardware. Simplest implementation would be to emit the whole of
|
||||
* the "to" state.
|
||||
*/
|
||||
static int emit_rss( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
struct rs_queue queue;
|
||||
|
||||
queue.rs_count = 0;
|
||||
|
||||
if (dirty & SVGA_NEW_BLEND) {
|
||||
const struct svga_blend_state *curr = svga->curr.blend;
|
||||
|
||||
EMIT_RS( svga, curr->rt[0].writemask, COLORWRITEENABLE, fail );
|
||||
EMIT_RS( svga, curr->rt[0].blend_enable, BLENDENABLE, fail );
|
||||
|
||||
if (curr->rt[0].blend_enable) {
|
||||
EMIT_RS( svga, curr->rt[0].srcblend, SRCBLEND, fail );
|
||||
EMIT_RS( svga, curr->rt[0].dstblend, DSTBLEND, fail );
|
||||
EMIT_RS( svga, curr->rt[0].blendeq, BLENDEQUATION, fail );
|
||||
|
||||
EMIT_RS( svga, curr->rt[0].separate_alpha_blend_enable,
|
||||
SEPARATEALPHABLENDENABLE, fail );
|
||||
|
||||
if (curr->rt[0].separate_alpha_blend_enable) {
|
||||
EMIT_RS( svga, curr->rt[0].srcblend_alpha, SRCBLENDALPHA, fail );
|
||||
EMIT_RS( svga, curr->rt[0].dstblend_alpha, DSTBLENDALPHA, fail );
|
||||
EMIT_RS( svga, curr->rt[0].blendeq_alpha, BLENDEQUATIONALPHA, fail );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
|
||||
const struct svga_depth_stencil_state *curr = svga->curr.depth;
|
||||
const struct svga_rasterizer_state *rast = svga->curr.rast;
|
||||
|
||||
if (!curr->stencil[0].enabled)
|
||||
{
|
||||
/* Stencil disabled
|
||||
*/
|
||||
EMIT_RS( svga, FALSE, STENCILENABLE, fail );
|
||||
EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
|
||||
}
|
||||
else if (curr->stencil[0].enabled && !curr->stencil[1].enabled)
|
||||
{
|
||||
/* Regular stencil
|
||||
*/
|
||||
EMIT_RS( svga, TRUE, STENCILENABLE, fail );
|
||||
EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
|
||||
|
||||
EMIT_RS( svga, curr->stencil[0].func, STENCILFUNC, fail );
|
||||
EMIT_RS( svga, curr->stencil[0].fail, STENCILFAIL, fail );
|
||||
EMIT_RS( svga, curr->stencil[0].zfail, STENCILZFAIL, fail );
|
||||
EMIT_RS( svga, curr->stencil[0].pass, STENCILPASS, fail );
|
||||
|
||||
EMIT_RS( svga, curr->stencil_ref, STENCILREF, fail );
|
||||
EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
|
||||
EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
|
||||
}
|
||||
else
|
||||
{
|
||||
int cw, ccw;
|
||||
|
||||
/* Hardware frontwinding is always CW, so if ours is also CW,
|
||||
* then our definition of front face agrees with hardware.
|
||||
* Otherwise need to flip.
|
||||
*/
|
||||
if (rast->templ.front_winding == PIPE_WINDING_CW) {
|
||||
cw = 0;
|
||||
ccw = 1;
|
||||
}
|
||||
else {
|
||||
cw = 1;
|
||||
ccw = 0;
|
||||
}
|
||||
|
||||
/* Twoside stencil
|
||||
*/
|
||||
EMIT_RS( svga, TRUE, STENCILENABLE, fail );
|
||||
EMIT_RS( svga, TRUE, STENCILENABLE2SIDED, fail );
|
||||
|
||||
EMIT_RS( svga, curr->stencil[cw].func, STENCILFUNC, fail );
|
||||
EMIT_RS( svga, curr->stencil[cw].fail, STENCILFAIL, fail );
|
||||
EMIT_RS( svga, curr->stencil[cw].zfail, STENCILZFAIL, fail );
|
||||
EMIT_RS( svga, curr->stencil[cw].pass, STENCILPASS, fail );
|
||||
|
||||
EMIT_RS( svga, curr->stencil[ccw].func, CCWSTENCILFUNC, fail );
|
||||
EMIT_RS( svga, curr->stencil[ccw].fail, CCWSTENCILFAIL, fail );
|
||||
EMIT_RS( svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL, fail );
|
||||
EMIT_RS( svga, curr->stencil[ccw].pass, CCWSTENCILPASS, fail );
|
||||
|
||||
EMIT_RS( svga, curr->stencil_ref, STENCILREF, fail );
|
||||
EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
|
||||
EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
|
||||
}
|
||||
|
||||
EMIT_RS( svga, curr->zenable, ZENABLE, fail );
|
||||
if (curr->zenable) {
|
||||
EMIT_RS( svga, curr->zfunc, ZFUNC, fail );
|
||||
EMIT_RS( svga, curr->zwriteenable, ZWRITEENABLE, fail );
|
||||
}
|
||||
|
||||
EMIT_RS( svga, curr->alphatestenable, ALPHATESTENABLE, fail );
|
||||
if (curr->alphatestenable) {
|
||||
EMIT_RS( svga, curr->alphafunc, ALPHAFUNC, fail );
|
||||
EMIT_RS_FLOAT( svga, curr->alpharef, ALPHAREF, fail );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dirty & SVGA_NEW_RAST)
|
||||
{
|
||||
const struct svga_rasterizer_state *curr = svga->curr.rast;
|
||||
|
||||
/* Shademode: still need to rearrange index list to move
|
||||
* flat-shading PV first vertex.
|
||||
*/
|
||||
EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
|
||||
EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
|
||||
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
|
||||
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
|
||||
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
|
||||
EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
|
||||
EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
|
||||
EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail );
|
||||
EMIT_RS_FLOAT( svga, curr->pointsize_max, POINTSIZEMAX, fail );
|
||||
}
|
||||
|
||||
if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))
|
||||
{
|
||||
const struct svga_rasterizer_state *curr = svga->curr.rast;
|
||||
float slope = 0.0;
|
||||
float bias = 0.0;
|
||||
|
||||
/* Need to modify depth bias according to bound depthbuffer
|
||||
* format. Don't do hardware depthbias while the software
|
||||
* pipeline is active.
|
||||
*/
|
||||
if (!svga->state.sw.need_pipeline &&
|
||||
svga->curr.framebuffer.zsbuf)
|
||||
{
|
||||
slope = curr->slopescaledepthbias;
|
||||
bias = svga->curr.depthscale * curr->depthbias;
|
||||
}
|
||||
|
||||
EMIT_RS_FLOAT( svga, slope, SLOPESCALEDEPTHBIAS, fail );
|
||||
EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail );
|
||||
}
|
||||
|
||||
|
||||
if (queue.rs_count) {
|
||||
SVGA3dRenderState *rs;
|
||||
|
||||
if (SVGA3D_BeginSetRenderState( svga->swc,
|
||||
&rs,
|
||||
queue.rs_count ) != PIPE_OK)
|
||||
goto fail;
|
||||
|
||||
memcpy( rs,
|
||||
queue.rs,
|
||||
queue.rs_count * sizeof queue.rs[0]);
|
||||
|
||||
SVGA_FIFOCommitAll( svga->swc );
|
||||
}
|
||||
|
||||
/* Also blend color:
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
/* XXX: need to poison cached hardware state on failure to ensure
|
||||
* dirty state gets re-emitted. Fix this by re-instating partial
|
||||
* FIFOCommit command and only updating cached hw state once the
|
||||
* initial allocation has succeeded.
|
||||
*/
|
||||
memset(svga->state.hw_draw.rs, 0xcd, sizeof(svga->state.hw_draw.rs));
|
||||
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_rss =
|
||||
{
|
||||
"hw rss state",
|
||||
|
||||
(SVGA_NEW_BLEND |
|
||||
SVGA_NEW_DEPTH_STENCIL |
|
||||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_FRAME_BUFFER |
|
||||
SVGA_NEW_NEED_PIPELINE),
|
||||
|
||||
emit_rss
|
||||
};
|
||||
279
src/gallium/drivers/svga/svga_state_tss.c
Normal file
279
src/gallium/drivers/svga/svga_state_tss.c
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "svga_screen_texture.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
void svga_cleanup_tss_binding(struct svga_context *svga)
|
||||
{
|
||||
int i;
|
||||
unsigned count = MAX2( svga->curr.num_textures,
|
||||
svga->state.hw_draw.num_views );
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
|
||||
|
||||
svga_sampler_view_reference(&view->v, NULL);
|
||||
pipe_texture_reference( &svga->curr.texture[i], NULL );
|
||||
pipe_texture_reference( &view->texture, NULL );
|
||||
|
||||
view->dirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
update_tss_binding(struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
unsigned i;
|
||||
unsigned count = MAX2( svga->curr.num_textures,
|
||||
svga->state.hw_draw.num_views );
|
||||
unsigned min_lod;
|
||||
unsigned max_lod;
|
||||
|
||||
|
||||
struct {
|
||||
struct {
|
||||
unsigned unit;
|
||||
struct svga_hw_view_state *view;
|
||||
} bind[PIPE_MAX_SAMPLERS];
|
||||
|
||||
unsigned bind_count;
|
||||
} queue;
|
||||
|
||||
queue.bind_count = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const struct svga_sampler_state *s = svga->curr.sampler[i];
|
||||
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
|
||||
|
||||
/* get min max lod */
|
||||
if (svga->curr.texture[i]) {
|
||||
min_lod = MAX2(s->view_min_lod, 0);
|
||||
max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
|
||||
} else {
|
||||
min_lod = 0;
|
||||
max_lod = 0;
|
||||
}
|
||||
|
||||
if (view->texture != svga->curr.texture[i] ||
|
||||
view->min_lod != min_lod ||
|
||||
view->max_lod != max_lod) {
|
||||
|
||||
svga_sampler_view_reference(&view->v, NULL);
|
||||
pipe_texture_reference( &view->texture, svga->curr.texture[i] );
|
||||
|
||||
view->dirty = TRUE;
|
||||
view->min_lod = min_lod;
|
||||
view->max_lod = max_lod;
|
||||
|
||||
if (svga->curr.texture[i])
|
||||
view->v = svga_get_tex_sampler_view(&svga->pipe,
|
||||
svga->curr.texture[i],
|
||||
min_lod,
|
||||
max_lod);
|
||||
}
|
||||
|
||||
if (view->dirty) {
|
||||
queue.bind[queue.bind_count].unit = i;
|
||||
queue.bind[queue.bind_count].view = view;
|
||||
queue.bind_count++;
|
||||
}
|
||||
else if (view->v) {
|
||||
svga_validate_sampler_view(svga, view->v);
|
||||
}
|
||||
}
|
||||
|
||||
svga->state.hw_draw.num_views = svga->curr.num_textures;
|
||||
|
||||
if (queue.bind_count) {
|
||||
SVGA3dTextureState *ts;
|
||||
|
||||
if (SVGA3D_BeginSetTextureState( svga->swc,
|
||||
&ts,
|
||||
queue.bind_count ) != PIPE_OK)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < queue.bind_count; i++) {
|
||||
ts[i].stage = queue.bind[i].unit;
|
||||
ts[i].name = SVGA3D_TS_BIND_TEXTURE;
|
||||
|
||||
if (queue.bind[i].view->v) {
|
||||
svga->swc->surface_relocation(svga->swc,
|
||||
&ts[i].value,
|
||||
queue.bind[i].view->v->handle,
|
||||
PIPE_BUFFER_USAGE_GPU_READ);
|
||||
}
|
||||
else {
|
||||
ts[i].value = SVGA3D_INVALID_ID;
|
||||
}
|
||||
|
||||
queue.bind[i].view->dirty = FALSE;
|
||||
}
|
||||
|
||||
SVGA_FIFOCommitAll( svga->swc );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_tss_binding = {
|
||||
"texture binding emit",
|
||||
SVGA_NEW_TEXTURE_BINDING |
|
||||
SVGA_NEW_SAMPLER,
|
||||
update_tss_binding
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
struct ts_queue {
|
||||
unsigned ts_count;
|
||||
SVGA3dTextureState ts[PIPE_MAX_SAMPLERS*SVGA3D_TS_MAX];
|
||||
};
|
||||
|
||||
|
||||
#define EMIT_TS(svga, unit, val, token, fail) \
|
||||
do { \
|
||||
if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \
|
||||
svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val ); \
|
||||
svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_TS_FLOAT(svga, unit, fvalue, token, fail) \
|
||||
do { \
|
||||
unsigned val = fui(fvalue); \
|
||||
if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \
|
||||
svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val ); \
|
||||
svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
static INLINE void
|
||||
svga_queue_tss( struct ts_queue *q,
|
||||
unsigned unit,
|
||||
unsigned tss,
|
||||
unsigned value )
|
||||
{
|
||||
assert(q->ts_count < sizeof(q->ts)/sizeof(q->ts[0]));
|
||||
q->ts[q->ts_count].stage = unit;
|
||||
q->ts[q->ts_count].name = tss;
|
||||
q->ts[q->ts_count].value = value;
|
||||
q->ts_count++;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
update_tss(struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
unsigned i;
|
||||
struct ts_queue queue;
|
||||
|
||||
queue.ts_count = 0;
|
||||
for (i = 0; i < svga->curr.num_samplers; i++) {
|
||||
if (svga->curr.sampler[i]) {
|
||||
const struct svga_sampler_state *curr = svga->curr.sampler[i];
|
||||
|
||||
EMIT_TS(svga, i, curr->mipfilter, MIPFILTER, fail);
|
||||
EMIT_TS(svga, i, curr->min_lod, TEXTURE_MIPMAP_LEVEL, fail);
|
||||
EMIT_TS(svga, i, curr->magfilter, MAGFILTER, fail);
|
||||
EMIT_TS(svga, i, curr->minfilter, MINFILTER, fail);
|
||||
EMIT_TS(svga, i, curr->aniso_level, TEXTURE_ANISOTROPIC_LEVEL, fail);
|
||||
EMIT_TS_FLOAT(svga, i, curr->lod_bias, TEXTURE_LOD_BIAS, fail);
|
||||
EMIT_TS(svga, i, curr->addressu, ADDRESSU, fail);
|
||||
EMIT_TS(svga, i, curr->addressw, ADDRESSW, fail);
|
||||
EMIT_TS(svga, i, curr->bordercolor, BORDERCOLOR, fail);
|
||||
// TEXCOORDINDEX -- hopefully not needed
|
||||
|
||||
if (svga->curr.tex_flags.flag_1d & (1 << i)) {
|
||||
debug_printf("wrap 1d tex %d\n", i);
|
||||
EMIT_TS(svga, i, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV, fail);
|
||||
}
|
||||
else
|
||||
EMIT_TS(svga, i, curr->addressv, ADDRESSV, fail);
|
||||
|
||||
if (svga->curr.tex_flags.flag_srgb & (1 << i))
|
||||
EMIT_TS_FLOAT(svga, i, 2.2f, GAMMA, fail);
|
||||
else
|
||||
EMIT_TS_FLOAT(svga, i, 1.0f, GAMMA, fail);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (queue.ts_count) {
|
||||
SVGA3dTextureState *ts;
|
||||
|
||||
if (SVGA3D_BeginSetTextureState( svga->swc,
|
||||
&ts,
|
||||
queue.ts_count ) != PIPE_OK)
|
||||
goto fail;
|
||||
|
||||
memcpy( ts,
|
||||
queue.ts,
|
||||
queue.ts_count * sizeof queue.ts[0]);
|
||||
|
||||
SVGA_FIFOCommitAll( svga->swc );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
/* XXX: need to poison cached hardware state on failure to ensure
|
||||
* dirty state gets re-emitted. Fix this by re-instating partial
|
||||
* FIFOCommit command and only updating cached hw state once the
|
||||
* initial allocation has succeeded.
|
||||
*/
|
||||
memset(svga->state.hw_draw.ts, 0xcd, sizeof(svga->state.hw_draw.ts));
|
||||
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_tss = {
|
||||
"texture state emit",
|
||||
(SVGA_NEW_SAMPLER |
|
||||
SVGA_NEW_TEXTURE_FLAGS),
|
||||
update_tss
|
||||
};
|
||||
|
||||
182
src/gallium/drivers/svga/svga_state_vdecl.c
Normal file
182
src/gallium/drivers/svga/svga_state_vdecl.c
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga_screen.h"
|
||||
#include "svga_screen_buffer.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
||||
static int
|
||||
upload_user_buffers( struct svga_context *svga )
|
||||
{
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
int i;
|
||||
int nr;
|
||||
|
||||
if (0)
|
||||
debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers);
|
||||
|
||||
nr = svga->curr.num_vertex_buffers;
|
||||
|
||||
for (i = 0; i < nr; i++)
|
||||
{
|
||||
if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
|
||||
{
|
||||
struct pipe_buffer *upload_buffer = NULL;
|
||||
unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
|
||||
unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
|
||||
unsigned upload_offset;
|
||||
|
||||
ret = u_upload_buffer( svga->upload_vb,
|
||||
offset,
|
||||
size,
|
||||
svga->curr.vb[i].buffer,
|
||||
&upload_offset,
|
||||
&upload_buffer );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (0)
|
||||
debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
|
||||
__FUNCTION__,
|
||||
i,
|
||||
svga->curr.vb[i].buffer,
|
||||
upload_buffer, upload_offset, size);
|
||||
|
||||
/* Make sure we release the old buffer and end up with the
|
||||
* correct refcount on the uploaded buffer.
|
||||
*/
|
||||
pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
|
||||
svga->curr.vb[i].buffer = upload_buffer;
|
||||
svga->curr.vb[i].buffer_offset = upload_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (0)
|
||||
debug_printf("%s: DONE\n", __FUNCTION__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
static int emit_hw_vs_vdecl( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
const struct pipe_vertex_element *ve = svga->curr.ve;
|
||||
SVGA3dVertexDecl decl;
|
||||
unsigned i;
|
||||
|
||||
assert(svga->curr.num_vertex_elements >=
|
||||
svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
|
||||
|
||||
svga_hwtnl_reset_vdecl( svga->hwtnl,
|
||||
svga->curr.num_vertex_elements );
|
||||
|
||||
for (i = 0; i < svga->curr.num_vertex_elements; i++) {
|
||||
const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
|
||||
unsigned usage, index;
|
||||
|
||||
|
||||
svga_generate_vdecl_semantics( i, &usage, &index );
|
||||
|
||||
/* SVGA_NEW_VELEMENT
|
||||
*/
|
||||
decl.identity.type = svga->state.sw.ve_format[i];
|
||||
decl.identity.method = SVGA3D_DECLMETHOD_DEFAULT;
|
||||
decl.identity.usage = usage;
|
||||
decl.identity.usageIndex = index;
|
||||
decl.array.stride = vb->stride;
|
||||
decl.array.offset = (vb->buffer_offset +
|
||||
ve[i].src_offset);
|
||||
|
||||
svga_hwtnl_vdecl( svga->hwtnl,
|
||||
i,
|
||||
&decl,
|
||||
vb->buffer );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int emit_hw_vdecl( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* SVGA_NEW_NEED_SWTNL
|
||||
*/
|
||||
if (svga->state.sw.need_swtnl)
|
||||
return 0; /* Do not emit during swtnl */
|
||||
|
||||
/* If we get to here, we know that we're going to draw. Upload
|
||||
* userbuffers now and try to combine multiple userbuffers from
|
||||
* multiple draw calls into a single host buffer for performance.
|
||||
*/
|
||||
if (svga->curr.any_user_vertex_buffers &&
|
||||
SVGA_COMBINE_USERBUFFERS)
|
||||
{
|
||||
ret = upload_user_buffers( svga );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
svga->curr.any_user_vertex_buffers = FALSE;
|
||||
}
|
||||
|
||||
return emit_hw_vs_vdecl( svga, dirty );
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_hw_vdecl =
|
||||
{
|
||||
"hw vertex decl state (hwtnl version)",
|
||||
( SVGA_NEW_NEED_SWTNL |
|
||||
SVGA_NEW_VELEMENT |
|
||||
SVGA_NEW_VBUFFER |
|
||||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_FS |
|
||||
SVGA_NEW_VS ),
|
||||
emit_hw_vdecl
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
239
src/gallium/drivers/svga/svga_state_vs.c
Normal file
239
src/gallium/drivers/svga/svga_state_vs.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "translate/translate.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_cmd.h"
|
||||
#include "svga_tgsi.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
static INLINE int compare_vs_keys( const struct svga_vs_compile_key *a,
|
||||
const struct svga_vs_compile_key *b )
|
||||
{
|
||||
unsigned keysize = svga_vs_key_size( a );
|
||||
return memcmp( a, b, keysize );
|
||||
}
|
||||
|
||||
|
||||
static struct svga_shader_result *search_vs_key( struct svga_vertex_shader *vs,
|
||||
const struct svga_vs_compile_key *key )
|
||||
{
|
||||
struct svga_shader_result *result = vs->base.results;
|
||||
|
||||
assert(key);
|
||||
|
||||
for ( ; result; result = result->next) {
|
||||
if (compare_vs_keys( key, &result->key.vkey ) == 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error compile_vs( struct svga_context *svga,
|
||||
struct svga_vertex_shader *vs,
|
||||
const struct svga_vs_compile_key *key,
|
||||
struct svga_shader_result **out_result )
|
||||
{
|
||||
struct svga_shader_result *result;
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
|
||||
result = svga_translate_vertex_program( vs, key );
|
||||
if (result == NULL) {
|
||||
ret = PIPE_ERROR_OUT_OF_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = SVGA3D_DefineShader(svga->swc,
|
||||
svga->state.next_vs_id,
|
||||
SVGA3D_SHADERTYPE_VS,
|
||||
result->tokens,
|
||||
result->nr_tokens * sizeof result->tokens[0]);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
*out_result = result;
|
||||
result->id = svga->state.next_vs_id++;
|
||||
result->next = vs->base.results;
|
||||
vs->base.results = result;
|
||||
return PIPE_OK;
|
||||
|
||||
fail:
|
||||
if (result)
|
||||
svga_destroy_shader_result( result );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* SVGA_NEW_PRESCALE, SVGA_NEW_RAST, SVGA_NEW_ZERO_STRIDE
|
||||
*/
|
||||
static int make_vs_key( struct svga_context *svga,
|
||||
struct svga_vs_compile_key *key )
|
||||
{
|
||||
memset(key, 0, sizeof *key);
|
||||
key->need_prescale = svga->state.hw_clear.prescale.enabled;
|
||||
key->allow_psiz = svga->curr.rast->templ.point_size_per_vertex;
|
||||
key->zero_stride_vertex_elements =
|
||||
svga->curr.zero_stride_vertex_elements;
|
||||
key->num_zero_stride_vertex_elements =
|
||||
svga->curr.num_zero_stride_vertex_elements;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int emit_hw_vs( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
struct svga_shader_result *result = NULL;
|
||||
unsigned id = SVGA3D_INVALID_ID;
|
||||
int ret = 0;
|
||||
|
||||
/* SVGA_NEW_NEED_SWTNL */
|
||||
if (!svga->state.sw.need_swtnl) {
|
||||
struct svga_vertex_shader *vs = svga->curr.vs;
|
||||
struct svga_vs_compile_key key;
|
||||
|
||||
ret = make_vs_key( svga, &key );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
result = search_vs_key( vs, &key );
|
||||
if (!result) {
|
||||
ret = compile_vs( svga, vs, &key, &result );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert (result);
|
||||
id = result->id;
|
||||
}
|
||||
|
||||
if (id != svga->state.hw_draw.shader_id[PIPE_SHADER_VERTEX]) {
|
||||
ret = SVGA3D_SetShader(svga->swc,
|
||||
SVGA3D_SHADERTYPE_VS,
|
||||
id );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
svga->dirty |= SVGA_NEW_VS_RESULT;
|
||||
svga->state.hw_draw.shader_id[PIPE_SHADER_VERTEX] = id;
|
||||
svga->state.hw_draw.vs = result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct svga_tracked_state svga_hw_vs =
|
||||
{
|
||||
"vertex shader (hwtnl)",
|
||||
(SVGA_NEW_VS |
|
||||
SVGA_NEW_PRESCALE |
|
||||
SVGA_NEW_NEED_SWTNL |
|
||||
SVGA_NEW_ZERO_STRIDE),
|
||||
emit_hw_vs
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
static int update_zero_stride( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
svga->curr.zero_stride_vertex_elements = 0;
|
||||
svga->curr.num_zero_stride_vertex_elements = 0;
|
||||
|
||||
for (i = 0; i < svga->curr.num_vertex_elements; i++) {
|
||||
const struct pipe_vertex_element *vel = &svga->curr.ve[i];
|
||||
const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
|
||||
vel->vertex_buffer_index];
|
||||
if (vbuffer->stride == 0) {
|
||||
unsigned const_idx =
|
||||
svga->curr.num_zero_stride_vertex_elements;
|
||||
struct translate *translate;
|
||||
struct translate_key key;
|
||||
void *mapped_buffer;
|
||||
|
||||
svga->curr.zero_stride_vertex_elements |= (1 << i);
|
||||
++svga->curr.num_zero_stride_vertex_elements;
|
||||
|
||||
key.output_stride = 4 * sizeof(float);
|
||||
key.nr_elements = 1;
|
||||
key.element[0].input_format = vel->src_format;
|
||||
key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
key.element[0].input_buffer = vel->vertex_buffer_index;
|
||||
key.element[0].input_offset = vel->src_offset;
|
||||
key.element[0].output_offset = const_idx * 4 * sizeof(float);
|
||||
|
||||
translate_key_sanitize(&key);
|
||||
/* translate_generic_create is technically private but
|
||||
* we don't want to code-generate, just want generic
|
||||
* translation */
|
||||
translate = translate_generic_create(&key);
|
||||
|
||||
assert(vel->src_offset == 0);
|
||||
|
||||
mapped_buffer = pipe_buffer_map_range(svga->pipe.screen,
|
||||
vbuffer->buffer,
|
||||
vel->src_offset,
|
||||
pf_get_size(vel->src_format),
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
translate->set_buffer(translate, vel->vertex_buffer_index,
|
||||
mapped_buffer,
|
||||
vbuffer->stride);
|
||||
translate->run(translate, 0, 1,
|
||||
svga->curr.zero_stride_constants);
|
||||
|
||||
pipe_buffer_unmap(svga->pipe.screen,
|
||||
vbuffer->buffer);
|
||||
translate->release(translate);
|
||||
}
|
||||
}
|
||||
|
||||
if (svga->curr.num_zero_stride_vertex_elements)
|
||||
svga->dirty |= SVGA_NEW_ZERO_STRIDE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct svga_tracked_state svga_hw_update_zero_stride =
|
||||
{
|
||||
"update zero_stride",
|
||||
( SVGA_NEW_VELEMENT |
|
||||
SVGA_NEW_VBUFFER ),
|
||||
update_zero_stride
|
||||
};
|
||||
52
src/gallium/drivers/svga/svga_swtnl.h
Normal file
52
src/gallium/drivers/svga/svga_swtnl.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_SWTNL_H
|
||||
#define SVGA_SWTNL_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct svga_context;
|
||||
struct pipe_context;
|
||||
struct pipe_buffer;
|
||||
struct vbuf_render;
|
||||
|
||||
|
||||
boolean svga_init_swtnl( struct svga_context *svga );
|
||||
void svga_destroy_swtnl( struct svga_context *svga );
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_swtnl_draw_range_elements(struct svga_context *svga,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count);
|
||||
|
||||
|
||||
#endif
|
||||
349
src/gallium/drivers/svga/svga_swtnl_backend.c
Normal file
349
src/gallium/drivers/svga/svga_swtnl_backend.c
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "draw/draw_vbuf.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_vertex.h"
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_simple_shaders.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_swtnl.h"
|
||||
|
||||
#include "svga_types.h"
|
||||
#include "svga_reg.h"
|
||||
#include "svga3d_reg.h"
|
||||
#include "svga_draw.h"
|
||||
#include "svga_swtnl_private.h"
|
||||
|
||||
|
||||
static const struct vertex_info *
|
||||
svga_vbuf_render_get_vertex_info( struct vbuf_render *render )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
|
||||
svga_swtnl_update_vdecl(svga);
|
||||
|
||||
return &svga_render->vertex_info;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
svga_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
||||
ushort vertex_size,
|
||||
ushort nr_vertices )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
struct pipe_screen *screen = svga->pipe.screen;
|
||||
size_t size = (size_t)nr_vertices * (size_t)vertex_size;
|
||||
boolean new_vbuf = FALSE;
|
||||
boolean new_ibuf = FALSE;
|
||||
|
||||
if (svga_render->vertex_size != vertex_size)
|
||||
svga->swtnl.new_vdecl = TRUE;
|
||||
svga_render->vertex_size = (size_t)vertex_size;
|
||||
|
||||
if (svga->swtnl.new_vbuf)
|
||||
new_ibuf = new_vbuf = TRUE;
|
||||
svga->swtnl.new_vbuf = FALSE;
|
||||
|
||||
if (svga_render->vbuf_size < svga_render->vbuf_offset + svga_render->vbuf_used + size)
|
||||
new_vbuf = TRUE;
|
||||
|
||||
if (new_vbuf)
|
||||
pipe_buffer_reference(&svga_render->vbuf, NULL);
|
||||
if (new_ibuf)
|
||||
pipe_buffer_reference(&svga_render->ibuf, NULL);
|
||||
|
||||
if (!svga_render->vbuf) {
|
||||
svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size);
|
||||
svga_render->vbuf = pipe_buffer_create(screen,
|
||||
0,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
svga_render->vbuf_size);
|
||||
if(!svga_render->vbuf) {
|
||||
svga_context_flush(svga, NULL);
|
||||
svga_render->vbuf = pipe_buffer_create(screen,
|
||||
0,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
svga_render->vbuf_size);
|
||||
assert(svga_render->vbuf);
|
||||
}
|
||||
|
||||
svga->swtnl.new_vdecl = TRUE;
|
||||
svga_render->vbuf_offset = 0;
|
||||
} else {
|
||||
svga_render->vbuf_offset += svga_render->vbuf_used;
|
||||
}
|
||||
|
||||
svga_render->vbuf_used = 0;
|
||||
|
||||
if (svga->swtnl.new_vdecl)
|
||||
svga_render->vdecl_offset = svga_render->vbuf_offset;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void *
|
||||
svga_vbuf_render_map_vertices( struct vbuf_render *render )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
struct pipe_screen *screen = svga->pipe.screen;
|
||||
|
||||
char *ptr = (char*)pipe_buffer_map(screen,
|
||||
svga_render->vbuf,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE |
|
||||
PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
|
||||
return ptr + svga_render->vbuf_offset;
|
||||
}
|
||||
|
||||
static void
|
||||
svga_vbuf_render_unmap_vertices( struct vbuf_render *render,
|
||||
ushort min_index,
|
||||
ushort max_index )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
struct pipe_screen *screen = svga->pipe.screen;
|
||||
unsigned offset, length;
|
||||
size_t used = svga_render->vertex_size * ((size_t)max_index + 1);
|
||||
|
||||
offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index;
|
||||
length = svga_render->vertex_size * (max_index + 1 - min_index);
|
||||
pipe_buffer_flush_mapped_range(screen, svga_render->vbuf, offset, length);
|
||||
pipe_buffer_unmap(screen, svga_render->vbuf);
|
||||
svga_render->min_index = min_index;
|
||||
svga_render->max_index = max_index;
|
||||
svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used);
|
||||
}
|
||||
|
||||
static boolean
|
||||
svga_vbuf_render_set_primitive( struct vbuf_render *render,
|
||||
unsigned prim )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
svga_render->prim = prim;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
svga_vbuf_sumbit_state( struct svga_vbuf_render *svga_render )
|
||||
{
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
|
||||
enum pipe_error ret;
|
||||
int i;
|
||||
|
||||
/* if the vdecl or vbuf hasn't changed do nothing */
|
||||
if (!svga->swtnl.new_vdecl)
|
||||
return;
|
||||
|
||||
memcpy(vdecl, svga_render->vdecl, sizeof(vdecl));
|
||||
|
||||
/* flush the hw state */
|
||||
ret = svga_hwtnl_flush(svga->hwtnl);
|
||||
if (ret) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = svga_hwtnl_flush(svga->hwtnl);
|
||||
/* if we hit this path we might become synced with hw */
|
||||
svga->swtnl.new_vbuf = TRUE;
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
svga_hwtnl_reset_vdecl(svga->hwtnl, svga_render->vdecl_count);
|
||||
|
||||
for (i = 0; i < svga_render->vdecl_count; i++) {
|
||||
vdecl[i].array.offset += svga_render->vdecl_offset;
|
||||
|
||||
svga_hwtnl_vdecl( svga->hwtnl,
|
||||
i,
|
||||
&vdecl[i],
|
||||
svga_render->vbuf );
|
||||
}
|
||||
|
||||
/* We have already taken care of flatshading, so let the hwtnl
|
||||
* module use whatever is most convenient:
|
||||
*/
|
||||
if (svga->state.sw.need_pipeline) {
|
||||
svga_hwtnl_set_flatshade(svga->hwtnl, FALSE, FALSE);
|
||||
svga_hwtnl_set_unfilled(svga->hwtnl, PIPE_POLYGON_MODE_FILL);
|
||||
}
|
||||
else {
|
||||
svga_hwtnl_set_flatshade( svga->hwtnl,
|
||||
svga->curr.rast->templ.flatshade,
|
||||
svga->curr.rast->templ.flatshade_first );
|
||||
|
||||
svga_hwtnl_set_unfilled( svga->hwtnl,
|
||||
svga->curr.rast->hw_unfilled );
|
||||
}
|
||||
|
||||
svga->swtnl.new_vdecl = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
svga_vbuf_render_draw_arrays( struct vbuf_render *render,
|
||||
unsigned start,
|
||||
uint nr )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size;
|
||||
enum pipe_error ret = 0;
|
||||
|
||||
svga_vbuf_sumbit_state(svga_render);
|
||||
|
||||
/* Need to call update_state() again as the draw module may have
|
||||
* altered some of our state behind our backs. Testcase:
|
||||
* redbook/polys.c
|
||||
*/
|
||||
svga_update_state_retry( svga, SVGA_STATE_HW_DRAW );
|
||||
|
||||
ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr);
|
||||
if (ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr);
|
||||
svga->swtnl.new_vbuf = TRUE;
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
svga_vbuf_render_draw( struct vbuf_render *render,
|
||||
const ushort *indices,
|
||||
uint nr_indices)
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
struct svga_context *svga = svga_render->svga;
|
||||
struct pipe_screen *screen = svga->pipe.screen;
|
||||
unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size;
|
||||
boolean ret;
|
||||
size_t size = 2 * nr_indices;
|
||||
|
||||
assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0);
|
||||
|
||||
if (svga_render->ibuf_size < svga_render->ibuf_offset + size)
|
||||
pipe_buffer_reference(&svga_render->ibuf, NULL);
|
||||
|
||||
if (!svga_render->ibuf) {
|
||||
svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size);
|
||||
svga_render->ibuf = pipe_buffer_create(screen,
|
||||
0,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
svga_render->ibuf_size);
|
||||
svga_render->ibuf_offset = 0;
|
||||
}
|
||||
|
||||
pipe_buffer_write(screen, svga_render->ibuf,
|
||||
svga_render->ibuf_offset, 2 * nr_indices, indices);
|
||||
|
||||
|
||||
/* off to hardware */
|
||||
svga_vbuf_sumbit_state(svga_render);
|
||||
|
||||
/* Need to call update_state() again as the draw module may have
|
||||
* altered some of our state behind our backs. Testcase:
|
||||
* redbook/polys.c
|
||||
*/
|
||||
svga_update_state_retry( svga, SVGA_STATE_HW_DRAW );
|
||||
|
||||
ret = svga_hwtnl_draw_range_elements(svga->hwtnl,
|
||||
svga_render->ibuf,
|
||||
2,
|
||||
svga_render->min_index,
|
||||
svga_render->max_index,
|
||||
svga_render->prim,
|
||||
svga_render->ibuf_offset / 2, nr_indices, bias);
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = svga_hwtnl_draw_range_elements(svga->hwtnl,
|
||||
svga_render->ibuf,
|
||||
2,
|
||||
svga_render->min_index,
|
||||
svga_render->max_index,
|
||||
svga_render->prim,
|
||||
svga_render->ibuf_offset / 2, nr_indices, bias);
|
||||
svga->swtnl.new_vbuf = TRUE;
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
svga_render->ibuf_offset += size;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
svga_vbuf_render_release_vertices( struct vbuf_render *render )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
svga_vbuf_render_destroy( struct vbuf_render *render )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
|
||||
|
||||
pipe_buffer_reference(&svga_render->vbuf, NULL);
|
||||
pipe_buffer_reference(&svga_render->ibuf, NULL);
|
||||
FREE(svga_render);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new primitive render.
|
||||
*/
|
||||
struct vbuf_render *
|
||||
svga_vbuf_render_create( struct svga_context *svga )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = CALLOC_STRUCT(svga_vbuf_render);
|
||||
|
||||
svga_render->svga = svga;
|
||||
svga_render->ibuf_size = 0;
|
||||
svga_render->vbuf_size = 0;
|
||||
svga_render->ibuf_alloc_size = 4*1024;
|
||||
svga_render->vbuf_alloc_size = 64*1024;
|
||||
svga_render->base.max_vertex_buffer_bytes = 64*1024/10;
|
||||
svga_render->base.max_indices = 65536;
|
||||
svga_render->base.get_vertex_info = svga_vbuf_render_get_vertex_info;
|
||||
svga_render->base.allocate_vertices = svga_vbuf_render_allocate_vertices;
|
||||
svga_render->base.map_vertices = svga_vbuf_render_map_vertices;
|
||||
svga_render->base.unmap_vertices = svga_vbuf_render_unmap_vertices;
|
||||
svga_render->base.set_primitive = svga_vbuf_render_set_primitive;
|
||||
svga_render->base.draw = svga_vbuf_render_draw;
|
||||
svga_render->base.draw_arrays = svga_vbuf_render_draw_arrays;
|
||||
svga_render->base.release_vertices = svga_vbuf_render_release_vertices;
|
||||
svga_render->base.destroy = svga_vbuf_render_destroy;
|
||||
|
||||
return &svga_render->base;
|
||||
}
|
||||
170
src/gallium/drivers/svga/svga_swtnl_draw.c
Normal file
170
src/gallium/drivers/svga/svga_swtnl_draw.c
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_vbuf.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_swtnl.h"
|
||||
#include "svga_state.h"
|
||||
#include "svga_swtnl_private.h"
|
||||
|
||||
|
||||
|
||||
enum pipe_error
|
||||
svga_swtnl_draw_range_elements(struct svga_context *svga,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
struct draw_context *draw = svga->swtnl.draw;
|
||||
unsigned i;
|
||||
const void *map;
|
||||
enum pipe_error ret;
|
||||
|
||||
assert(!svga->dirty);
|
||||
assert(svga->state.sw.need_swtnl);
|
||||
assert(draw);
|
||||
|
||||
ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
|
||||
if (ret) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
|
||||
svga->swtnl.new_vbuf = TRUE;
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map vertex buffers
|
||||
*/
|
||||
for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
|
||||
map = pipe_buffer_map(svga->pipe.screen,
|
||||
svga->curr.vb[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
|
||||
draw_set_mapped_vertex_buffer(draw, i, map);
|
||||
}
|
||||
|
||||
/* Map index buffer, if present */
|
||||
if (indexBuffer) {
|
||||
map = pipe_buffer_map(svga->pipe.screen, indexBuffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
|
||||
draw_set_mapped_element_buffer_range(draw,
|
||||
indexSize,
|
||||
min_index,
|
||||
max_index,
|
||||
map);
|
||||
}
|
||||
|
||||
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
|
||||
map = pipe_buffer_map(svga->pipe.screen,
|
||||
svga->curr.cb[PIPE_SHADER_VERTEX],
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
assert(map);
|
||||
draw_set_mapped_constant_buffer(
|
||||
draw,
|
||||
map,
|
||||
svga->curr.cb[PIPE_SHADER_VERTEX]->size);
|
||||
}
|
||||
|
||||
draw_arrays(svga->swtnl.draw, prim, start, count);
|
||||
|
||||
draw_flush(svga->swtnl.draw);
|
||||
|
||||
/* Ensure the draw module didn't touch this */
|
||||
assert(i == svga->curr.num_vertex_buffers);
|
||||
|
||||
/*
|
||||
* unmap vertex/index buffers
|
||||
*/
|
||||
for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
|
||||
pipe_buffer_unmap(svga->pipe.screen, svga->curr.vb[i].buffer);
|
||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
||||
}
|
||||
|
||||
if (indexBuffer) {
|
||||
pipe_buffer_unmap(svga->pipe.screen, indexBuffer);
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
}
|
||||
|
||||
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
|
||||
pipe_buffer_unmap(svga->pipe.screen,
|
||||
svga->curr.cb[PIPE_SHADER_VERTEX]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
boolean svga_init_swtnl( struct svga_context *svga )
|
||||
{
|
||||
svga->swtnl.backend = svga_vbuf_render_create(svga);
|
||||
if(!svga->swtnl.backend)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Create drawing context and plug our rendering stage into it.
|
||||
*/
|
||||
svga->swtnl.draw = draw_create();
|
||||
if (svga->swtnl.draw == NULL)
|
||||
goto fail;
|
||||
|
||||
|
||||
draw_set_rasterize_stage(svga->swtnl.draw,
|
||||
draw_vbuf_stage( svga->swtnl.draw, svga->swtnl.backend ));
|
||||
|
||||
draw_set_render(svga->swtnl.draw, svga->swtnl.backend);
|
||||
|
||||
draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe);
|
||||
draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
|
||||
draw_install_pstipple_stage(svga->swtnl.draw, &svga->pipe);
|
||||
|
||||
draw_set_driver_clipping(svga->swtnl.draw, debug_get_bool_option("SVGA_SWTNL_FSE", FALSE));
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (svga->swtnl.backend)
|
||||
svga->swtnl.backend->destroy( svga->swtnl.backend );
|
||||
|
||||
if (svga->swtnl.draw)
|
||||
draw_destroy( svga->swtnl.draw );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void svga_destroy_swtnl( struct svga_context *svga )
|
||||
{
|
||||
draw_destroy( svga->swtnl.draw );
|
||||
}
|
||||
93
src/gallium/drivers/svga/svga_swtnl_private.h
Normal file
93
src/gallium/drivers/svga/svga_swtnl_private.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_SWTNL_PRIVATE_H
|
||||
#define SVGA_SWTNL_PRIVATE_H
|
||||
|
||||
#include "svga_swtnl.h"
|
||||
#include "draw/draw_vertex.h"
|
||||
|
||||
#include "svga_types.h"
|
||||
#include "svga3d_reg.h"
|
||||
|
||||
/**
|
||||
* Primitive renderer for svga.
|
||||
*/
|
||||
struct svga_vbuf_render {
|
||||
struct vbuf_render base;
|
||||
|
||||
struct svga_context *svga;
|
||||
struct vertex_info vertex_info;
|
||||
|
||||
unsigned vertex_size;
|
||||
|
||||
unsigned prim;
|
||||
|
||||
struct pipe_buffer *vbuf;
|
||||
struct pipe_buffer *ibuf;
|
||||
|
||||
/* current size of buffer */
|
||||
size_t vbuf_size;
|
||||
size_t ibuf_size;
|
||||
|
||||
/* size of that the buffer should be */
|
||||
size_t vbuf_alloc_size;
|
||||
size_t ibuf_alloc_size;
|
||||
|
||||
/* current write place */
|
||||
size_t vbuf_offset;
|
||||
size_t ibuf_offset;
|
||||
|
||||
/* currently used */
|
||||
size_t vbuf_used;
|
||||
|
||||
SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
|
||||
unsigned vdecl_offset;
|
||||
unsigned vdecl_count;
|
||||
|
||||
ushort min_index;
|
||||
ushort max_index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Basically a cast wrapper.
|
||||
*/
|
||||
static INLINE struct svga_vbuf_render *
|
||||
svga_vbuf_render( struct vbuf_render *render )
|
||||
{
|
||||
assert(render);
|
||||
return (struct svga_vbuf_render *)render;
|
||||
}
|
||||
|
||||
|
||||
struct vbuf_render *
|
||||
svga_vbuf_render_create( struct svga_context *svga );
|
||||
|
||||
|
||||
int
|
||||
svga_swtnl_update_vdecl( struct svga_context *svga );
|
||||
|
||||
|
||||
#endif
|
||||
242
src/gallium/drivers/svga/svga_swtnl_state.c
Normal file
242
src/gallium/drivers/svga/svga_swtnl_state.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_vbuf.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_swtnl.h"
|
||||
#include "svga_state.h"
|
||||
|
||||
#include "svga_swtnl_private.h"
|
||||
|
||||
|
||||
#define SVGA_POINT_ADJ_X -0.375
|
||||
#define SVGA_POINT_ADJ_Y -0.5
|
||||
|
||||
#define SVGA_LINE_ADJ_X -0.5
|
||||
#define SVGA_LINE_ADJ_Y -0.5
|
||||
|
||||
#define SVGA_TRIANGLE_ADJ_X -0.375
|
||||
#define SVGA_TRIANGLE_ADJ_Y -0.5
|
||||
|
||||
|
||||
static void set_draw_viewport( struct svga_context *svga )
|
||||
{
|
||||
struct pipe_viewport_state vp = svga->curr.viewport;
|
||||
float adjx = 0;
|
||||
float adjy = 0;
|
||||
|
||||
switch (svga->curr.reduced_prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
adjx = SVGA_POINT_ADJ_X;
|
||||
adjy = SVGA_POINT_ADJ_Y;
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
/* XXX: This is to compensate for the fact that wide lines are
|
||||
* going to be drawn with triangles, but we're not catching all
|
||||
* cases where that will happen.
|
||||
*/
|
||||
if (svga->curr.rast->templ.line_width > 1.0)
|
||||
{
|
||||
adjx = SVGA_LINE_ADJ_X + 0.175;
|
||||
adjy = SVGA_LINE_ADJ_Y - 0.175;
|
||||
}
|
||||
else {
|
||||
adjx = SVGA_LINE_ADJ_X;
|
||||
adjy = SVGA_LINE_ADJ_Y;
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
adjx += SVGA_TRIANGLE_ADJ_X;
|
||||
adjy += SVGA_TRIANGLE_ADJ_Y;
|
||||
break;
|
||||
}
|
||||
|
||||
vp.translate[0] += adjx;
|
||||
vp.translate[1] += adjy;
|
||||
|
||||
draw_set_viewport_state(svga->swtnl.draw, &vp);
|
||||
}
|
||||
|
||||
static int update_swtnl_draw( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
draw_flush( svga->swtnl.draw );
|
||||
|
||||
if (dirty & SVGA_NEW_VS)
|
||||
draw_bind_vertex_shader(svga->swtnl.draw,
|
||||
svga->curr.vs->draw_shader);
|
||||
|
||||
if (dirty & SVGA_NEW_VBUFFER)
|
||||
draw_set_vertex_buffers(svga->swtnl.draw,
|
||||
svga->curr.num_vertex_buffers,
|
||||
svga->curr.vb);
|
||||
|
||||
if (dirty & SVGA_NEW_VELEMENT)
|
||||
draw_set_vertex_elements(svga->swtnl.draw,
|
||||
svga->curr.num_vertex_elements,
|
||||
svga->curr.ve );
|
||||
|
||||
if (dirty & SVGA_NEW_CLIP)
|
||||
draw_set_clip_state(svga->swtnl.draw,
|
||||
&svga->curr.clip);
|
||||
|
||||
if (dirty & (SVGA_NEW_VIEWPORT |
|
||||
SVGA_NEW_REDUCED_PRIMITIVE |
|
||||
SVGA_NEW_RAST))
|
||||
set_draw_viewport( svga );
|
||||
|
||||
if (dirty & SVGA_NEW_RAST)
|
||||
draw_set_rasterizer_state(svga->swtnl.draw,
|
||||
&svga->curr.rast->templ);
|
||||
|
||||
if (dirty & SVGA_NEW_FRAME_BUFFER)
|
||||
draw_set_mrd(svga->swtnl.draw,
|
||||
svga->curr.depthscale);
|
||||
|
||||
if (dirty & SVGA_NEW_EDGEFLAGS)
|
||||
draw_set_edgeflags( svga->swtnl.draw,
|
||||
svga->curr.edgeflags );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_update_swtnl_draw =
|
||||
{
|
||||
"update draw module state",
|
||||
(SVGA_NEW_VS |
|
||||
SVGA_NEW_VBUFFER |
|
||||
SVGA_NEW_VELEMENT |
|
||||
SVGA_NEW_CLIP |
|
||||
SVGA_NEW_VIEWPORT |
|
||||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_FRAME_BUFFER |
|
||||
SVGA_NEW_REDUCED_PRIMITIVE |
|
||||
SVGA_NEW_EDGEFLAGS),
|
||||
update_swtnl_draw
|
||||
};
|
||||
|
||||
|
||||
int svga_swtnl_update_vdecl( struct svga_context *svga )
|
||||
{
|
||||
struct svga_vbuf_render *svga_render = svga_vbuf_render(svga->swtnl.backend);
|
||||
struct draw_context *draw = svga->swtnl.draw;
|
||||
struct vertex_info *vinfo = &svga_render->vertex_info;
|
||||
SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
|
||||
const enum interp_mode colorInterp =
|
||||
svga->curr.rast->templ.flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
|
||||
const struct svga_fragment_shader *fs = svga->curr.fs;
|
||||
int offset = 0;
|
||||
int nr_decls = 0;
|
||||
int src, i;
|
||||
|
||||
memset(vinfo, 0, sizeof(*vinfo));
|
||||
memset(vdecl, 0, sizeof(vdecl));
|
||||
|
||||
/* always add position */
|
||||
src = draw_find_vs_output(draw, TGSI_SEMANTIC_POSITION, 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
|
||||
vinfo->attrib[0].emit = EMIT_4F;
|
||||
vdecl[0].array.offset = offset;
|
||||
vdecl[0].identity.type = SVGA3D_DECLTYPE_FLOAT4;
|
||||
vdecl[0].identity.usage = SVGA3D_DECLUSAGE_POSITIONT;
|
||||
vdecl[0].identity.usageIndex = 0;
|
||||
offset += 16;
|
||||
nr_decls++;
|
||||
|
||||
for (i = 0; i < fs->base.info.num_inputs; i++) {
|
||||
unsigned name = fs->base.info.input_semantic_name[i];
|
||||
unsigned index = fs->base.info.input_semantic_index[i];
|
||||
src = draw_find_vs_output(draw, name, index);
|
||||
vdecl[nr_decls].array.offset = offset;
|
||||
vdecl[nr_decls].identity.usageIndex = fs->base.info.input_semantic_index[i];
|
||||
|
||||
switch (name) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
||||
vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_COLOR;
|
||||
vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4;
|
||||
offset += 16;
|
||||
nr_decls++;
|
||||
break;
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4;
|
||||
vdecl[nr_decls].identity.usageIndex += 1;
|
||||
offset += 16;
|
||||
nr_decls++;
|
||||
break;
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
|
||||
vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT1;
|
||||
assert(vdecl[nr_decls].identity.usageIndex == 0);
|
||||
offset += 4;
|
||||
nr_decls++;
|
||||
break;
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
/* generated internally, not a vertex shader output */
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
draw_compute_vertex_size(vinfo);
|
||||
|
||||
svga_render->vdecl_count = nr_decls;
|
||||
for (i = 0; i < svga_render->vdecl_count; i++)
|
||||
vdecl[i].array.stride = offset;
|
||||
|
||||
if (memcmp(svga_render->vdecl, vdecl, sizeof(vdecl)) == 0)
|
||||
return 0;
|
||||
|
||||
memcpy(svga_render->vdecl, vdecl, sizeof(vdecl));
|
||||
svga->swtnl.new_vdecl = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int update_swtnl_vdecl( struct svga_context *svga,
|
||||
unsigned dirty )
|
||||
{
|
||||
return svga_swtnl_update_vdecl( svga );
|
||||
}
|
||||
|
||||
|
||||
struct svga_tracked_state svga_update_swtnl_vdecl =
|
||||
{
|
||||
"update draw module vdecl",
|
||||
(SVGA_NEW_VS |
|
||||
SVGA_NEW_FS),
|
||||
update_swtnl_vdecl
|
||||
};
|
||||
266
src/gallium/drivers/svga/svga_tgsi.c
Normal file
266
src/gallium/drivers/svga/svga_tgsi.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_dump.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svgadump/st_shader_dump.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga_tgsi_emit.h"
|
||||
#include "svga_debug.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga3d_shaderdefs.h"
|
||||
|
||||
|
||||
/* Sinkhole used only in error conditions.
|
||||
*/
|
||||
static char err_buf[128];
|
||||
|
||||
#if 0
|
||||
static void svga_destroy_shader_emitter( struct svga_shader_emitter *emit )
|
||||
{
|
||||
if (emit->buf != err_buf)
|
||||
FREE(emit->buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static boolean svga_shader_expand( struct svga_shader_emitter *emit )
|
||||
{
|
||||
char *new_buf;
|
||||
unsigned newsize = emit->size * 2;
|
||||
|
||||
if(emit->buf != err_buf)
|
||||
new_buf = REALLOC(emit->buf, emit->size, newsize);
|
||||
else
|
||||
new_buf = NULL;
|
||||
|
||||
if (new_buf == NULL) {
|
||||
emit->ptr = err_buf;
|
||||
emit->buf = err_buf;
|
||||
emit->size = sizeof(err_buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
emit->size = newsize;
|
||||
emit->ptr = new_buf + (emit->ptr - emit->buf);
|
||||
emit->buf = new_buf;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE boolean reserve( struct svga_shader_emitter *emit,
|
||||
unsigned nr_dwords )
|
||||
{
|
||||
if (emit->ptr - emit->buf + nr_dwords * sizeof(unsigned) >= emit->size) {
|
||||
if (!svga_shader_expand( emit ))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean svga_shader_emit_dword( struct svga_shader_emitter *emit,
|
||||
unsigned dword )
|
||||
{
|
||||
if (!reserve(emit, 1))
|
||||
return FALSE;
|
||||
|
||||
*(unsigned *)emit->ptr = dword;
|
||||
emit->ptr += sizeof dword;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit,
|
||||
const unsigned *dwords,
|
||||
unsigned nr )
|
||||
{
|
||||
if (!reserve(emit, nr))
|
||||
return FALSE;
|
||||
|
||||
memcpy( emit->ptr, dwords, nr * sizeof *dwords );
|
||||
emit->ptr += nr * sizeof *dwords;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit,
|
||||
unsigned opcode )
|
||||
{
|
||||
SVGA3dShaderInstToken *here;
|
||||
|
||||
if (!reserve(emit, 1))
|
||||
return FALSE;
|
||||
|
||||
here = (SVGA3dShaderInstToken *)emit->ptr;
|
||||
here->value = opcode;
|
||||
|
||||
if (emit->insn_offset) {
|
||||
SVGA3dShaderInstToken *prev = (SVGA3dShaderInstToken *)(emit->buf +
|
||||
emit->insn_offset);
|
||||
prev->size = (here - prev) - 1;
|
||||
}
|
||||
|
||||
emit->insn_offset = emit->ptr - emit->buf;
|
||||
emit->ptr += sizeof(unsigned);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define SVGA3D_PS_2X (SVGA3D_PS_20 | 1)
|
||||
#define SVGA3D_VS_2X (SVGA3D_VS_20 | 1)
|
||||
|
||||
static boolean svga_shader_emit_header( struct svga_shader_emitter *emit )
|
||||
{
|
||||
SVGA3dShaderVersion header;
|
||||
|
||||
memset( &header, 0, sizeof header );
|
||||
|
||||
switch (emit->unit) {
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
header.value = emit->use_sm30 ? SVGA3D_PS_30 : SVGA3D_PS_2X;
|
||||
break;
|
||||
case PIPE_SHADER_VERTEX:
|
||||
header.value = emit->use_sm30 ? SVGA3D_VS_30 : SVGA3D_VS_2X;
|
||||
break;
|
||||
}
|
||||
|
||||
return svga_shader_emit_dword( emit, header.value );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parse TGSI shader and translate to SVGA/DX9 serialized
|
||||
* representation.
|
||||
*
|
||||
* In this function SVGA shader is emitted to an in-memory buffer that
|
||||
* can be dynamically grown. Once we've finished and know how large
|
||||
* it is, it will be copied to a hardware buffer for upload.
|
||||
*/
|
||||
static struct svga_shader_result *
|
||||
svga_tgsi_translate( const struct svga_shader *shader,
|
||||
union svga_compile_key key,
|
||||
unsigned unit )
|
||||
{
|
||||
struct svga_shader_result *result = NULL;
|
||||
struct svga_shader_emitter emit;
|
||||
int ret = 0;
|
||||
|
||||
memset(&emit, 0, sizeof(emit));
|
||||
|
||||
emit.use_sm30 = shader->use_sm30;
|
||||
emit.size = 1024;
|
||||
emit.buf = MALLOC(emit.size);
|
||||
if (emit.buf == NULL) {
|
||||
ret = PIPE_ERROR_OUT_OF_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
emit.ptr = emit.buf;
|
||||
emit.unit = unit;
|
||||
emit.key = key;
|
||||
|
||||
tgsi_scan_shader( shader->tokens, &emit.info);
|
||||
|
||||
emit.imm_start = emit.info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
|
||||
if (unit == PIPE_SHADER_FRAGMENT)
|
||||
emit.imm_start += key.fkey.num_unnormalized_coords;
|
||||
|
||||
if (unit == PIPE_SHADER_VERTEX) {
|
||||
emit.imm_start += key.vkey.need_prescale ? 2 : 0;
|
||||
emit.imm_start += key.vkey.num_zero_stride_vertex_elements;
|
||||
}
|
||||
|
||||
emit.nr_hw_const = (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1);
|
||||
|
||||
emit.nr_hw_temp = emit.info.file_max[TGSI_FILE_TEMPORARY] + 1;
|
||||
emit.in_main_func = TRUE;
|
||||
|
||||
if (!svga_shader_emit_header( &emit ))
|
||||
goto fail;
|
||||
|
||||
if (!svga_shader_emit_instructions( &emit, shader->tokens ))
|
||||
goto fail;
|
||||
|
||||
result = CALLOC_STRUCT(svga_shader_result);
|
||||
if (result == NULL)
|
||||
goto fail;
|
||||
|
||||
result->shader = shader;
|
||||
result->tokens = (const unsigned *)emit.buf;
|
||||
result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned);
|
||||
memcpy(&result->key, &key, sizeof key);
|
||||
|
||||
return result;
|
||||
|
||||
fail:
|
||||
FREE(result);
|
||||
FREE(emit.buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct svga_shader_result *
|
||||
svga_translate_fragment_program( const struct svga_fragment_shader *fs,
|
||||
const struct svga_fs_compile_key *fkey )
|
||||
{
|
||||
union svga_compile_key key;
|
||||
memcpy(&key.fkey, fkey, sizeof *fkey);
|
||||
|
||||
return svga_tgsi_translate( &fs->base,
|
||||
key,
|
||||
PIPE_SHADER_FRAGMENT );
|
||||
}
|
||||
|
||||
struct svga_shader_result *
|
||||
svga_translate_vertex_program( const struct svga_vertex_shader *vs,
|
||||
const struct svga_vs_compile_key *vkey )
|
||||
{
|
||||
union svga_compile_key key;
|
||||
memcpy(&key.vkey, vkey, sizeof *vkey);
|
||||
|
||||
return svga_tgsi_translate( &vs->base,
|
||||
key,
|
||||
PIPE_SHADER_VERTEX );
|
||||
}
|
||||
|
||||
|
||||
void svga_destroy_shader_result( struct svga_shader_result *result )
|
||||
{
|
||||
FREE((unsigned *)result->tokens);
|
||||
FREE(result);
|
||||
}
|
||||
|
||||
139
src/gallium/drivers/svga/svga_tgsi.h
Normal file
139
src/gallium/drivers/svga/svga_tgsi.h
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_TGSI_H
|
||||
#define SVGA_TGSI_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
struct svga_fragment_shader;
|
||||
struct svga_vertex_shader;
|
||||
struct svga_shader;
|
||||
struct tgsi_shader_info;
|
||||
struct tgsi_token;
|
||||
|
||||
|
||||
struct svga_vs_compile_key
|
||||
{
|
||||
ubyte need_prescale:1;
|
||||
ubyte allow_psiz:1;
|
||||
unsigned zero_stride_vertex_elements;
|
||||
ubyte num_zero_stride_vertex_elements:6;
|
||||
};
|
||||
|
||||
struct svga_fs_compile_key
|
||||
{
|
||||
boolean light_twoside:1;
|
||||
boolean front_cw:1;
|
||||
ubyte num_textures;
|
||||
ubyte num_unnormalized_coords;
|
||||
struct {
|
||||
ubyte compare_mode : 1;
|
||||
ubyte compare_func : 3;
|
||||
ubyte unnormalized : 1;
|
||||
|
||||
ubyte width_height_idx : 7;
|
||||
|
||||
ubyte texture_target;
|
||||
} tex[PIPE_MAX_SAMPLERS];
|
||||
};
|
||||
|
||||
union svga_compile_key {
|
||||
struct svga_vs_compile_key vkey;
|
||||
struct svga_fs_compile_key fkey;
|
||||
};
|
||||
|
||||
struct svga_shader_result
|
||||
{
|
||||
const struct svga_shader *shader;
|
||||
|
||||
/* Parameters used to generate this compilation result:
|
||||
*/
|
||||
union svga_compile_key key;
|
||||
|
||||
/* Compiled shader tokens:
|
||||
*/
|
||||
const unsigned *tokens;
|
||||
unsigned nr_tokens;
|
||||
|
||||
/* SVGA Shader ID:
|
||||
*/
|
||||
unsigned id;
|
||||
|
||||
/* Next compilation result:
|
||||
*/
|
||||
struct svga_shader_result *next;
|
||||
};
|
||||
|
||||
|
||||
/* TGSI doesn't provide use with VS input semantics (they're actually
|
||||
* pretty meaningless), so we just generate some plausible ones here.
|
||||
* This is called both from within the TGSI translator and when
|
||||
* building vdecls to ensure they match up.
|
||||
*
|
||||
* The real use of this information is matching vertex elements to
|
||||
* fragment shader inputs in the case where vertex shader is disabled.
|
||||
*/
|
||||
static INLINE void svga_generate_vdecl_semantics( unsigned idx,
|
||||
unsigned *usage,
|
||||
unsigned *usage_index )
|
||||
{
|
||||
if (idx == 0) {
|
||||
*usage = SVGA3D_DECLUSAGE_POSITION;
|
||||
*usage_index = 0;
|
||||
}
|
||||
else {
|
||||
*usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
*usage_index = idx - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static INLINE unsigned svga_vs_key_size( const struct svga_vs_compile_key *key )
|
||||
{
|
||||
return sizeof *key;
|
||||
}
|
||||
|
||||
static INLINE unsigned svga_fs_key_size( const struct svga_fs_compile_key *key )
|
||||
{
|
||||
return (const char *)&key->tex[key->num_textures].texture_target -
|
||||
(const char *)key;
|
||||
}
|
||||
|
||||
struct svga_shader_result *
|
||||
svga_translate_fragment_program( const struct svga_fragment_shader *fs,
|
||||
const struct svga_fs_compile_key *fkey );
|
||||
|
||||
struct svga_shader_result *
|
||||
svga_translate_vertex_program( const struct svga_vertex_shader *fs,
|
||||
const struct svga_vs_compile_key *vkey );
|
||||
|
||||
|
||||
void svga_destroy_shader_result( struct svga_shader_result *result );
|
||||
|
||||
#endif
|
||||
280
src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
Normal file
280
src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_tgsi_emit.h"
|
||||
#include "svga_context.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static boolean ps20_input( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
struct src_register reg;
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
switch (semantic.SemanticName) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
/* Special case:
|
||||
*/
|
||||
reg = src_register( SVGA3DREG_MISCTYPE,
|
||||
SVGA3DMISCREG_POSITION );
|
||||
break;
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
reg = src_register( SVGA3DREG_INPUT,
|
||||
semantic.SemanticIndex );
|
||||
break;
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
assert(semantic.SemanticIndex == 0);
|
||||
reg = src_register( SVGA3DREG_TEXTURE, 0 );
|
||||
break;
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
reg = src_register( SVGA3DREG_TEXTURE,
|
||||
semantic.SemanticIndex + 1 );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
emit->input_map[idx] = reg;
|
||||
|
||||
dcl.dst = dst( reg );
|
||||
|
||||
dcl.usage = 0;
|
||||
dcl.index = 0;
|
||||
|
||||
dcl.values[0] |= 1<<31;
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
|
||||
|
||||
static boolean ps20_output( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3dShaderDestToken reg;
|
||||
|
||||
switch (semantic.SemanticName) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
if (semantic.SemanticIndex < PIPE_MAX_COLOR_BUFS) {
|
||||
unsigned cbuf = semantic.SemanticIndex;
|
||||
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_col[cbuf] = emit->output_map[idx];
|
||||
emit->true_col[cbuf] = dst_register( SVGA3DREG_COLOROUT,
|
||||
semantic.SemanticIndex );
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
reg = dst_register( SVGA3DREG_COLOROUT, 0 );
|
||||
}
|
||||
break;
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_pos = emit->output_map[idx];
|
||||
emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT,
|
||||
semantic.SemanticIndex );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
reg = dst_register( SVGA3DREG_COLOROUT, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static boolean vs20_input( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
|
||||
dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
|
||||
|
||||
assert(dcl.dst.reserved0);
|
||||
|
||||
/* Mesa doesn't provide use with VS input semantics (they're
|
||||
* actually pretty meaningless), so we just generate some plausible
|
||||
* ones here. This has to match what we declare in the vdecl code
|
||||
* in svga_pipe_vertex.c.
|
||||
*/
|
||||
if (idx == 0) {
|
||||
dcl.usage = SVGA3D_DECLUSAGE_POSITION;
|
||||
dcl.index = 0;
|
||||
}
|
||||
else {
|
||||
dcl.usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
dcl.index = idx - 1;
|
||||
}
|
||||
|
||||
dcl.values[0] |= 1<<31;
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
|
||||
|
||||
static boolean vs20_output( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
/* Don't emit dcl instruction for vs20 inputs
|
||||
*/
|
||||
|
||||
/* Just build the register map table:
|
||||
*/
|
||||
switch (semantic.SemanticName) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
assert(semantic.SemanticIndex == 0);
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_pos = emit->output_map[idx];
|
||||
emit->true_pos = dst_register( SVGA3DREG_RASTOUT,
|
||||
SVGA3DRASTOUT_POSITION);
|
||||
break;
|
||||
case TGSI_SEMANTIC_PSIZE:
|
||||
assert(semantic.SemanticIndex == 0);
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_psiz = emit->output_map[idx];
|
||||
emit->true_psiz = dst_register( SVGA3DREG_RASTOUT,
|
||||
SVGA3DRASTOUT_PSIZE );
|
||||
break;
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
assert(semantic.SemanticIndex == 0);
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT, 0 );
|
||||
break;
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
/* oD0 */
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_ATTROUT,
|
||||
semantic.SemanticIndex );
|
||||
break;
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT,
|
||||
semantic.SemanticIndex + 1 );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 0 );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean ps20_sampler( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
|
||||
dcl.type = svga_tgsi_sampler_type( emit, idx );
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
|
||||
|
||||
boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_declaration *decl )
|
||||
{
|
||||
unsigned first = decl->DeclarationRange.First;
|
||||
unsigned last = decl->DeclarationRange.Last;
|
||||
unsigned semantic = 0;
|
||||
unsigned semantic_idx = 0;
|
||||
unsigned idx;
|
||||
|
||||
if (decl->Declaration.Semantic) {
|
||||
semantic = decl->Semantic.SemanticName;
|
||||
semantic_idx = decl->Semantic.SemanticIndex;
|
||||
}
|
||||
|
||||
for( idx = first; idx <= last; idx++ ) {
|
||||
boolean ok;
|
||||
|
||||
switch (decl->Declaration.File) {
|
||||
case TGSI_FILE_SAMPLER:
|
||||
assert (emit->unit == PIPE_SHADER_FRAGMENT);
|
||||
ok = ps20_sampler( emit, decl->Semantic, idx );
|
||||
break;
|
||||
|
||||
case TGSI_FILE_INPUT:
|
||||
if (emit->unit == PIPE_SHADER_VERTEX)
|
||||
ok = vs20_input( emit, decl->Semantic, idx );
|
||||
else
|
||||
ok = ps20_input( emit, decl->Semantic, idx );
|
||||
break;
|
||||
|
||||
case TGSI_FILE_OUTPUT:
|
||||
if (emit->unit == PIPE_SHADER_VERTEX)
|
||||
ok = vs20_output( emit, decl->Semantic, idx );
|
||||
else
|
||||
ok = ps20_output( emit, decl->Semantic, idx );
|
||||
break;
|
||||
|
||||
default:
|
||||
/* don't need to declare other vars */
|
||||
ok = TRUE;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
385
src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
Normal file
385
src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "svga_tgsi_emit.h"
|
||||
#include "svga_context.h"
|
||||
|
||||
static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic,
|
||||
unsigned *usage,
|
||||
unsigned *idx )
|
||||
{
|
||||
switch (semantic.SemanticName) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
*idx = semantic.SemanticIndex;
|
||||
*usage = SVGA3D_DECLUSAGE_POSITION;
|
||||
break;
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
|
||||
*idx = semantic.SemanticIndex;
|
||||
*usage = SVGA3D_DECLUSAGE_COLOR;
|
||||
break;
|
||||
case TGSI_SEMANTIC_BCOLOR:
|
||||
*idx = semantic.SemanticIndex + 2; /* sharing with COLOR */
|
||||
*usage = SVGA3D_DECLUSAGE_COLOR;
|
||||
break;
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
*idx = 0;
|
||||
assert(semantic.SemanticIndex == 0);
|
||||
*usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
break;
|
||||
case TGSI_SEMANTIC_PSIZE:
|
||||
*idx = semantic.SemanticIndex;
|
||||
*usage = SVGA3D_DECLUSAGE_PSIZE;
|
||||
break;
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
*idx = semantic.SemanticIndex + 1; /* texcoord[0] is reserved for fog */
|
||||
*usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
break;
|
||||
case TGSI_SEMANTIC_NORMAL:
|
||||
*idx = semantic.SemanticIndex;
|
||||
*usage = SVGA3D_DECLUSAGE_NORMAL;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
*usage = SVGA3D_DECLUSAGE_TEXCOORD;
|
||||
*idx = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static boolean emit_decl( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderDestToken reg,
|
||||
unsigned usage,
|
||||
unsigned index )
|
||||
{
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
dcl.dst = reg;
|
||||
dcl.usage = usage;
|
||||
dcl.index = index;
|
||||
dcl.values[0] |= 1<<31;
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
|
||||
static boolean emit_vface_decl( struct svga_shader_emitter *emit )
|
||||
{
|
||||
if (!emit->emitted_vface) {
|
||||
SVGA3dShaderDestToken reg =
|
||||
dst_register( SVGA3DREG_MISCTYPE,
|
||||
SVGA3DMISCREG_FACE );
|
||||
|
||||
if (!emit_decl( emit, reg, 0, 0 ))
|
||||
return FALSE;
|
||||
|
||||
emit->emitted_vface = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean ps30_input( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
unsigned usage, index;
|
||||
SVGA3dShaderDestToken reg;
|
||||
|
||||
if (semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
|
||||
emit->input_map[idx] = src_register( SVGA3DREG_MISCTYPE,
|
||||
SVGA3DMISCREG_POSITION );
|
||||
|
||||
emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
|
||||
TGSI_SWIZZLE_Y,
|
||||
TGSI_SWIZZLE_Y,
|
||||
TGSI_SWIZZLE_Y );
|
||||
|
||||
reg = writemask( dst(emit->input_map[idx]),
|
||||
TGSI_WRITEMASK_XY );
|
||||
|
||||
return emit_decl( emit, reg, 0, 0 );
|
||||
}
|
||||
else if (emit->key.fkey.light_twoside &&
|
||||
(semantic.SemanticName == TGSI_SEMANTIC_COLOR)) {
|
||||
|
||||
if (!translate_vs_ps_semantic( semantic, &usage, &index ))
|
||||
return FALSE;
|
||||
|
||||
emit->internal_color_idx[emit->internal_color_count] = idx;
|
||||
emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count );
|
||||
emit->ps30_input_count++;
|
||||
emit->internal_color_count++;
|
||||
|
||||
reg = dst( emit->input_map[idx] );
|
||||
|
||||
if (!emit_decl( emit, reg, usage, index ))
|
||||
return FALSE;
|
||||
|
||||
semantic.SemanticName = TGSI_SEMANTIC_BCOLOR;
|
||||
if (!translate_vs_ps_semantic( semantic, &usage, &index ))
|
||||
return FALSE;
|
||||
|
||||
reg = dst_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
|
||||
|
||||
if (!emit_decl( emit, reg, usage, index ))
|
||||
return FALSE;
|
||||
|
||||
if (!emit_vface_decl( emit ))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (semantic.SemanticName == TGSI_SEMANTIC_FACE) {
|
||||
if (!emit_vface_decl( emit ))
|
||||
return FALSE;
|
||||
emit->emit_frontface = TRUE;
|
||||
emit->internal_frontface_idx = idx;
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
|
||||
if (!translate_vs_ps_semantic( semantic, &usage, &index ))
|
||||
return FALSE;
|
||||
|
||||
emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
|
||||
reg = dst( emit->input_map[idx] );
|
||||
|
||||
return emit_decl( emit, reg, usage, index );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* PS output registers are the same as 2.0
|
||||
*/
|
||||
static boolean ps30_output( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3dShaderDestToken reg;
|
||||
|
||||
switch (semantic.SemanticName) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
|
||||
semantic.SemanticIndex );
|
||||
break;
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_pos = emit->output_map[idx];
|
||||
emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT,
|
||||
semantic.SemanticIndex );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
reg = dst_register( SVGA3DREG_COLOROUT, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* We still make up the input semantics the same as in 2.0
|
||||
*/
|
||||
static boolean vs30_input( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
unsigned usage, index;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
if (emit->key.vkey.zero_stride_vertex_elements & (1 << idx)) {
|
||||
unsigned i;
|
||||
unsigned offset = 0;
|
||||
unsigned start_idx = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
/* adjust for prescale constants */
|
||||
start_idx += emit->key.vkey.need_prescale ? 2 : 0;
|
||||
/* compute the offset from the start of zero stride constants */
|
||||
for (i = 0; i < PIPE_MAX_ATTRIBS && i < idx; ++i) {
|
||||
if (emit->key.vkey.zero_stride_vertex_elements & (1<<i))
|
||||
++offset;
|
||||
}
|
||||
emit->input_map[idx] = src_register( SVGA3DREG_CONST,
|
||||
start_idx + offset );
|
||||
} else {
|
||||
emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
|
||||
dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
|
||||
|
||||
assert(dcl.dst.reserved0);
|
||||
|
||||
svga_generate_vdecl_semantics( idx, &usage, &index );
|
||||
|
||||
dcl.usage = usage;
|
||||
dcl.index = index;
|
||||
dcl.values[0] |= 1<<31;
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* VS3.0 outputs have proper declarations and semantic info for
|
||||
* matching against PS inputs.
|
||||
*/
|
||||
static boolean vs30_output( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
unsigned usage, index;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
if (!translate_vs_ps_semantic( semantic, &usage, &index ))
|
||||
return FALSE;
|
||||
|
||||
dcl.dst = dst_register( SVGA3DREG_OUTPUT, idx );
|
||||
dcl.usage = usage;
|
||||
dcl.index = index;
|
||||
dcl.values[0] |= 1<<31;
|
||||
|
||||
if (semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
|
||||
assert(idx == 0);
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_pos = emit->output_map[idx];
|
||||
emit->true_pos = dcl.dst;
|
||||
}
|
||||
else if (semantic.SemanticName == TGSI_SEMANTIC_PSIZE) {
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_psiz = emit->output_map[idx];
|
||||
|
||||
/* This has the effect of not declaring psiz (below) and not
|
||||
* emitting the final MOV to true_psiz in the postamble.
|
||||
*/
|
||||
if (!emit->key.vkey.allow_psiz)
|
||||
return TRUE;
|
||||
|
||||
emit->true_psiz = dcl.dst;
|
||||
}
|
||||
else {
|
||||
emit->output_map[idx] = dcl.dst;
|
||||
}
|
||||
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
|
||||
static boolean ps30_sampler( struct svga_shader_emitter *emit,
|
||||
struct tgsi_declaration_semantic semantic,
|
||||
unsigned idx )
|
||||
{
|
||||
SVGA3DOpDclArgs dcl;
|
||||
SVGA3dShaderInstToken opcode;
|
||||
|
||||
opcode = inst_token( SVGA3DOP_DCL );
|
||||
dcl.values[0] = 0;
|
||||
dcl.values[1] = 0;
|
||||
|
||||
dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
|
||||
dcl.type = svga_tgsi_sampler_type( emit, idx );
|
||||
dcl.values[0] |= 1<<31;
|
||||
|
||||
return (emit_instruction(emit, opcode) &&
|
||||
svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
|
||||
}
|
||||
|
||||
|
||||
boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_declaration *decl )
|
||||
{
|
||||
unsigned first = decl->DeclarationRange.First;
|
||||
unsigned last = decl->DeclarationRange.Last;
|
||||
unsigned semantic = 0;
|
||||
unsigned semantic_idx = 0;
|
||||
unsigned idx;
|
||||
|
||||
if (decl->Declaration.Semantic) {
|
||||
semantic = decl->Semantic.SemanticName;
|
||||
semantic_idx = decl->Semantic.SemanticIndex;
|
||||
}
|
||||
|
||||
for( idx = first; idx <= last; idx++ ) {
|
||||
boolean ok;
|
||||
|
||||
switch (decl->Declaration.File) {
|
||||
case TGSI_FILE_SAMPLER:
|
||||
assert (emit->unit == PIPE_SHADER_FRAGMENT);
|
||||
ok = ps30_sampler( emit, decl->Semantic, idx );
|
||||
break;
|
||||
|
||||
case TGSI_FILE_INPUT:
|
||||
if (emit->unit == PIPE_SHADER_VERTEX)
|
||||
ok = vs30_input( emit, decl->Semantic, idx );
|
||||
else
|
||||
ok = ps30_input( emit, decl->Semantic, idx );
|
||||
break;
|
||||
|
||||
case TGSI_FILE_OUTPUT:
|
||||
if (emit->unit == PIPE_SHADER_VERTEX)
|
||||
ok = vs30_output( emit, decl->Semantic, idx );
|
||||
else
|
||||
ok = ps30_output( emit, decl->Semantic, idx );
|
||||
break;
|
||||
|
||||
default:
|
||||
/* don't need to declare other vars */
|
||||
ok = TRUE;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
345
src/gallium/drivers/svga/svga_tgsi_emit.h
Normal file
345
src/gallium/drivers/svga/svga_tgsi_emit.h
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_TGSI_EMIT_H
|
||||
#define SVGA_TGSI_EMIT_H
|
||||
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
#include "svga_hw_reg.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga3d_shaderdefs.h"
|
||||
|
||||
struct src_register
|
||||
{
|
||||
SVGA3dShaderSrcToken base;
|
||||
SVGA3dShaderSrcToken indirect;
|
||||
};
|
||||
|
||||
|
||||
struct svga_arl_consts {
|
||||
int number;
|
||||
int idx;
|
||||
int swizzle;
|
||||
int arl_num;
|
||||
};
|
||||
|
||||
/* Internal functions:
|
||||
*/
|
||||
|
||||
struct svga_shader_emitter
|
||||
{
|
||||
boolean use_sm30;
|
||||
|
||||
unsigned size;
|
||||
char *buf;
|
||||
char *ptr;
|
||||
|
||||
union svga_compile_key key;
|
||||
struct tgsi_shader_info info;
|
||||
int unit;
|
||||
|
||||
int imm_start;
|
||||
|
||||
int nr_hw_const;
|
||||
int nr_hw_temp;
|
||||
|
||||
int insn_offset;
|
||||
|
||||
int internal_temp_count;
|
||||
int internal_imm_count;
|
||||
|
||||
int internal_color_idx[2]; /* diffuse, specular */
|
||||
int internal_color_count;
|
||||
|
||||
boolean emitted_vface;
|
||||
boolean emit_frontface;
|
||||
int internal_frontface_idx;
|
||||
|
||||
int ps30_input_count;
|
||||
|
||||
boolean in_main_func;
|
||||
|
||||
boolean created_zero_immediate;
|
||||
int zero_immediate_idx;
|
||||
|
||||
boolean created_loop_const;
|
||||
int loop_const_idx;
|
||||
|
||||
boolean created_sincos_consts;
|
||||
int sincos_consts_idx;
|
||||
|
||||
unsigned label[32];
|
||||
unsigned nr_labels;
|
||||
|
||||
struct src_register input_map[PIPE_MAX_ATTRIBS];
|
||||
SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
|
||||
|
||||
struct src_register imm_0055;
|
||||
SVGA3dShaderDestToken temp_pos;
|
||||
SVGA3dShaderDestToken true_pos;
|
||||
|
||||
SVGA3dShaderDestToken temp_col[PIPE_MAX_COLOR_BUFS];
|
||||
SVGA3dShaderDestToken true_col[PIPE_MAX_COLOR_BUFS];
|
||||
|
||||
SVGA3dShaderDestToken temp_psiz;
|
||||
SVGA3dShaderDestToken true_psiz;
|
||||
|
||||
struct svga_arl_consts arl_consts[12];
|
||||
int num_arl_consts;
|
||||
int current_arl;
|
||||
};
|
||||
|
||||
|
||||
boolean svga_shader_emit_dword( struct svga_shader_emitter *emit,
|
||||
unsigned dword );
|
||||
|
||||
boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit,
|
||||
const unsigned *dwords,
|
||||
unsigned nr );
|
||||
|
||||
boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit,
|
||||
unsigned opcode );
|
||||
|
||||
boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
|
||||
const struct tgsi_token *tokens );
|
||||
|
||||
boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_declaration *decl );
|
||||
|
||||
boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_declaration *decl );
|
||||
|
||||
|
||||
static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderDestToken dest )
|
||||
{
|
||||
assert(dest.reserved0);
|
||||
return svga_shader_emit_dword( emit, dest.value );
|
||||
}
|
||||
|
||||
static INLINE boolean emit_src( struct svga_shader_emitter *emit,
|
||||
const struct src_register src )
|
||||
{
|
||||
if (src.base.relAddr) {
|
||||
assert(src.base.reserved0);
|
||||
assert(src.indirect.reserved0);
|
||||
return (svga_shader_emit_dword( emit, src.base.value ) &&
|
||||
svga_shader_emit_dword( emit, src.indirect.value ));
|
||||
}
|
||||
else {
|
||||
assert(src.base.reserved0);
|
||||
return svga_shader_emit_dword( emit, src.base.value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE boolean emit_instruction( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderInstToken opcode )
|
||||
{
|
||||
return svga_shader_emit_opcode( emit, opcode.value );
|
||||
}
|
||||
|
||||
|
||||
static INLINE boolean emit_op1( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderInstToken inst,
|
||||
SVGA3dShaderDestToken dest,
|
||||
struct src_register src0 )
|
||||
{
|
||||
return (emit_instruction( emit, inst ) &&
|
||||
emit_dst( emit, dest ) &&
|
||||
emit_src( emit, src0 ));
|
||||
}
|
||||
|
||||
static INLINE boolean emit_op2( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderInstToken inst,
|
||||
SVGA3dShaderDestToken dest,
|
||||
struct src_register src0,
|
||||
struct src_register src1 )
|
||||
{
|
||||
return (emit_instruction( emit, inst ) &&
|
||||
emit_dst( emit, dest ) &&
|
||||
emit_src( emit, src0 ) &&
|
||||
emit_src( emit, src1 ));
|
||||
}
|
||||
|
||||
static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderInstToken inst,
|
||||
SVGA3dShaderDestToken dest,
|
||||
struct src_register src0,
|
||||
struct src_register src1,
|
||||
struct src_register src2 )
|
||||
{
|
||||
return (emit_instruction( emit, inst ) &&
|
||||
emit_dst( emit, dest ) &&
|
||||
emit_src( emit, src0 ) &&
|
||||
emit_src( emit, src1 ) &&
|
||||
emit_src( emit, src2 ));
|
||||
}
|
||||
|
||||
|
||||
#define TRANSLATE_SWIZZLE(x,y,z,w) ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
|
||||
#define SWIZZLE_XYZW \
|
||||
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
|
||||
#define SWIZZLE_XXXX \
|
||||
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X)
|
||||
#define SWIZZLE_YYYY \
|
||||
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y)
|
||||
#define SWIZZLE_ZZZZ \
|
||||
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z)
|
||||
#define SWIZZLE_WWWW \
|
||||
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W)
|
||||
|
||||
|
||||
|
||||
static INLINE SVGA3dShaderInstToken
|
||||
inst_token( unsigned opcode )
|
||||
{
|
||||
SVGA3dShaderInstToken inst;
|
||||
|
||||
inst.value = 0;
|
||||
inst.op = opcode;
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static INLINE SVGA3dShaderDestToken
|
||||
dst_register( unsigned file,
|
||||
int number )
|
||||
{
|
||||
SVGA3dShaderDestToken dest;
|
||||
|
||||
dest.value = 0;
|
||||
dest.num = number;
|
||||
dest.type_upper = file >> 3;
|
||||
dest.relAddr = 0;
|
||||
dest.reserved1 = 0;
|
||||
dest.mask = 0xf;
|
||||
dest.dstMod = 0;
|
||||
dest.shfScale = 0;
|
||||
dest.type_lower = file & 0x7;
|
||||
dest.reserved0 = 1; /* is_reg */
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static INLINE SVGA3dShaderDestToken
|
||||
writemask( SVGA3dShaderDestToken dest,
|
||||
unsigned mask )
|
||||
{
|
||||
dest.mask &= mask;
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static INLINE SVGA3dShaderSrcToken
|
||||
src_token( unsigned file, int number )
|
||||
{
|
||||
SVGA3dShaderSrcToken src;
|
||||
|
||||
src.value = 0;
|
||||
src.num = number;
|
||||
src.type_upper = file >> 3;
|
||||
src.relAddr = 0;
|
||||
src.reserved1 = 0;
|
||||
src.swizzle = SWIZZLE_XYZW;
|
||||
src.srcMod = 0;
|
||||
src.type_lower = file & 0x7;
|
||||
src.reserved0 = 1; /* is_reg */
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct src_register
|
||||
absolute( struct src_register src )
|
||||
{
|
||||
src.base.srcMod = SVGA3DSRCMOD_ABS;
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct src_register
|
||||
negate( struct src_register src )
|
||||
{
|
||||
switch (src.base.srcMod) {
|
||||
case SVGA3DSRCMOD_ABS:
|
||||
src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
|
||||
break;
|
||||
case SVGA3DSRCMOD_ABSNEG:
|
||||
src.base.srcMod = SVGA3DSRCMOD_ABS;
|
||||
break;
|
||||
case SVGA3DSRCMOD_NEG:
|
||||
src.base.srcMod = SVGA3DSRCMOD_NONE;
|
||||
break;
|
||||
case SVGA3DSRCMOD_NONE:
|
||||
src.base.srcMod = SVGA3DSRCMOD_NEG;
|
||||
break;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct src_register
|
||||
src_register( unsigned file, int number )
|
||||
{
|
||||
struct src_register src;
|
||||
|
||||
src.base = src_token( file, number );
|
||||
src.indirect.value = 0;
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
static INLINE SVGA3dShaderDestToken dst( struct src_register src )
|
||||
{
|
||||
return dst_register( SVGA3dShaderGetRegType( src.base.value ),
|
||||
src.base.num );
|
||||
}
|
||||
|
||||
static INLINE struct src_register src( SVGA3dShaderDestToken dst )
|
||||
{
|
||||
return src_register( SVGA3dShaderGetRegType( dst.value ),
|
||||
dst.num );
|
||||
}
|
||||
|
||||
static INLINE ubyte svga_tgsi_sampler_type( struct svga_shader_emitter *emit,
|
||||
int idx )
|
||||
{
|
||||
switch (emit->key.fkey.tex[idx].texture_target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
return SVGA3DSAMP_2D;
|
||||
case PIPE_TEXTURE_2D:
|
||||
return SVGA3DSAMP_2D;
|
||||
case PIPE_TEXTURE_3D:
|
||||
return SVGA3DSAMP_VOLUME;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
return SVGA3DSAMP_CUBE;
|
||||
}
|
||||
|
||||
return SVGA3DSAMP_UNKNOWN;
|
||||
}
|
||||
|
||||
#endif
|
||||
2716
src/gallium/drivers/svga/svga_tgsi_insn.c
Normal file
2716
src/gallium/drivers/svga/svga_tgsi_insn.c
Normal file
File diff suppressed because it is too large
Load diff
299
src/gallium/drivers/svga/svga_winsys.h
Normal file
299
src/gallium/drivers/svga/svga_winsys.h
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* VMware SVGA specific winsys interface.
|
||||
*
|
||||
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||
*
|
||||
* Documentation taken from the VMware SVGA DDK.
|
||||
*/
|
||||
|
||||
#ifndef SVGA_WINSYS_H_
|
||||
#define SVGA_WINSYS_H_
|
||||
|
||||
|
||||
#include "svga_types.h"
|
||||
#include "svga_reg.h"
|
||||
#include "svga3d_reg.h"
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
struct svga_winsys_screen;
|
||||
struct svga_winsys_buffer;
|
||||
struct pipe_screen;
|
||||
struct pipe_context;
|
||||
struct pipe_fence_handle;
|
||||
struct pipe_texture;
|
||||
struct svga_region;
|
||||
|
||||
|
||||
#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0)
|
||||
#define SVGA_BUFFER_USAGE_WRAPPED (PIPE_BUFFER_USAGE_CUSTOM << 1)
|
||||
|
||||
|
||||
/** Opaque surface handle */
|
||||
struct svga_winsys_surface;
|
||||
|
||||
/** Opaque buffer handle */
|
||||
struct svga_winsys_handle;
|
||||
|
||||
|
||||
/**
|
||||
* SVGA per-context winsys interface.
|
||||
*/
|
||||
struct svga_winsys_context
|
||||
{
|
||||
void
|
||||
(*destroy)(struct svga_winsys_context *swc);
|
||||
|
||||
void *
|
||||
(*reserve)(struct svga_winsys_context *swc,
|
||||
uint32_t nr_bytes, uint32_t nr_relocs );
|
||||
|
||||
/**
|
||||
* Emit a relocation for a host surface.
|
||||
*
|
||||
* @param flags PIPE_BUFFER_USAGE_GPU_READ/WRITE
|
||||
*
|
||||
* NOTE: Order of this call does matter. It should be the same order
|
||||
* as relocations appear in the command buffer.
|
||||
*/
|
||||
void
|
||||
(*surface_relocation)(struct svga_winsys_context *swc,
|
||||
uint32 *sid,
|
||||
struct svga_winsys_surface *surface,
|
||||
unsigned flags);
|
||||
|
||||
/**
|
||||
* Emit a relocation for a guest memory region.
|
||||
*
|
||||
* @param flags PIPE_BUFFER_USAGE_GPU_READ/WRITE
|
||||
*
|
||||
* NOTE: Order of this call does matter. It should be the same order
|
||||
* as relocations appear in the command buffer.
|
||||
*/
|
||||
void
|
||||
(*region_relocation)(struct svga_winsys_context *swc,
|
||||
struct SVGAGuestPtr *ptr,
|
||||
struct svga_winsys_buffer *buffer,
|
||||
uint32 offset,
|
||||
unsigned flags);
|
||||
|
||||
void
|
||||
(*commit)(struct svga_winsys_context *swc);
|
||||
|
||||
enum pipe_error
|
||||
(*flush)(struct svga_winsys_context *swc,
|
||||
struct pipe_fence_handle **pfence);
|
||||
|
||||
/**
|
||||
* Context ID used to fill in the commands
|
||||
*
|
||||
* Context IDs are arbitrary small non-negative integers,
|
||||
* global to the entire SVGA device.
|
||||
*/
|
||||
uint32 cid;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* SVGA per-screen winsys interface.
|
||||
*/
|
||||
struct svga_winsys_screen
|
||||
{
|
||||
void
|
||||
(*destroy)(struct svga_winsys_screen *sws);
|
||||
|
||||
boolean
|
||||
(*get_cap)(struct svga_winsys_screen *sws,
|
||||
SVGA3dDevCapIndex index,
|
||||
SVGA3dDevCapResult *result);
|
||||
|
||||
/**
|
||||
* Create a new context.
|
||||
*
|
||||
* Context objects encapsulate all render state, and shader
|
||||
* objects are per-context.
|
||||
*
|
||||
* Surfaces are not per-context. The same surface can be shared
|
||||
* between multiple contexts, and surface operations can occur
|
||||
* without a context.
|
||||
*/
|
||||
struct svga_winsys_context *
|
||||
(*context_create)(struct svga_winsys_screen *sws);
|
||||
|
||||
|
||||
/**
|
||||
* This creates a "surface" object in the SVGA3D device,
|
||||
* and returns the surface ID (sid). Surfaces are generic
|
||||
* containers for host VRAM objects like textures, vertex
|
||||
* buffers, and depth/stencil buffers.
|
||||
*
|
||||
* Surfaces are hierarchial:
|
||||
*
|
||||
* - Surface may have multiple faces (for cube maps)
|
||||
*
|
||||
* - Each face has a list of mipmap levels
|
||||
*
|
||||
* - Each mipmap image may have multiple volume
|
||||
* slices, if the image is three dimensional.
|
||||
*
|
||||
* - Each slice is a 2D array of 'blocks'
|
||||
*
|
||||
* - Each block may be one or more pixels.
|
||||
* (Usually 1, more for DXT or YUV formats.)
|
||||
*
|
||||
* Surfaces are generic host VRAM objects. The SVGA3D device
|
||||
* may optimize surfaces according to the format they were
|
||||
* created with, but this format does not limit the ways in
|
||||
* which the surface may be used. For example, a depth surface
|
||||
* can be used as a texture, or a floating point image may
|
||||
* be used as a vertex buffer. Some surface usages may be
|
||||
* lower performance, due to software emulation, but any
|
||||
* usage should work with any surface.
|
||||
*/
|
||||
struct svga_winsys_surface *
|
||||
(*surface_create)(struct svga_winsys_screen *sws,
|
||||
SVGA3dSurfaceFlags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
SVGA3dSize size,
|
||||
uint32 numFaces,
|
||||
uint32 numMipLevels);
|
||||
|
||||
/**
|
||||
* Whether this surface is sitting in a validate list
|
||||
*/
|
||||
boolean
|
||||
(*surface_is_flushed)(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_surface *surface);
|
||||
|
||||
/**
|
||||
* Reference a SVGA3D surface object. This allows sharing of a
|
||||
* surface between different objects.
|
||||
*/
|
||||
void
|
||||
(*surface_reference)(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_surface **pdst,
|
||||
struct svga_winsys_surface *src);
|
||||
|
||||
/**
|
||||
* Buffer management. Buffer attributes are mostly fixed over its lifetime.
|
||||
*
|
||||
* Remember that gallium gets to choose the interface it needs, and the
|
||||
* window systems must then implement that interface (rather than the
|
||||
* other way around...).
|
||||
*
|
||||
* usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
|
||||
* usage argument is only an optimization hint, not a guarantee, therefore
|
||||
* proper behavior must be observed in all circumstances.
|
||||
*
|
||||
* alignment indicates the client's alignment requirements, eg for
|
||||
* SSE instructions.
|
||||
*/
|
||||
struct svga_winsys_buffer *
|
||||
(*buffer_create)( struct svga_winsys_screen *sws,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size );
|
||||
|
||||
/**
|
||||
* Map the entire data store of a buffer object into the client's address.
|
||||
* flags is a bitmask of:
|
||||
* - PIPE_BUFFER_USAGE_CPU_READ/WRITE
|
||||
* - PIPE_BUFFER_USAGE_DONTBLOCK
|
||||
* - PIPE_BUFFER_USAGE_UNSYNCHRONIZED
|
||||
*/
|
||||
void *
|
||||
(*buffer_map)( struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_buffer *buf,
|
||||
unsigned usage );
|
||||
|
||||
void
|
||||
(*buffer_unmap)( struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_buffer *buf );
|
||||
|
||||
void
|
||||
(*buffer_destroy)( struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_buffer *buf );
|
||||
|
||||
|
||||
/**
|
||||
* Reference a fence object.
|
||||
*/
|
||||
void
|
||||
(*fence_reference)( struct svga_winsys_screen *sws,
|
||||
struct pipe_fence_handle **pdst,
|
||||
struct pipe_fence_handle *src );
|
||||
|
||||
/**
|
||||
* Checks whether the fence has been signalled.
|
||||
* \param flags driver-specific meaning
|
||||
* \return zero on success.
|
||||
*/
|
||||
int (*fence_signalled)( struct svga_winsys_screen *sws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag );
|
||||
|
||||
/**
|
||||
* Wait for the fence to finish.
|
||||
* \param flags driver-specific meaning
|
||||
* \return zero on success.
|
||||
*/
|
||||
int (*fence_finish)( struct svga_winsys_screen *sws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag );
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct pipe_context *
|
||||
svga_context_create(struct pipe_screen *screen);
|
||||
|
||||
struct pipe_screen *
|
||||
svga_screen_create(struct svga_winsys_screen *sws);
|
||||
|
||||
struct svga_winsys_screen *
|
||||
svga_winsys_screen(struct pipe_screen *screen);
|
||||
|
||||
struct pipe_buffer *
|
||||
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
|
||||
enum SVGA3dSurfaceFormat format,
|
||||
struct svga_winsys_surface *srf);
|
||||
|
||||
struct svga_winsys_surface *
|
||||
svga_screen_texture_get_winsys_surface(struct pipe_texture *texture);
|
||||
struct svga_winsys_surface *
|
||||
svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
|
||||
|
||||
boolean
|
||||
svga_screen_buffer_from_texture(struct pipe_texture *texture,
|
||||
struct pipe_buffer **buffer,
|
||||
unsigned *stride);
|
||||
|
||||
#endif /* SVGA_WINSYS_H_ */
|
||||
214
src/gallium/drivers/svga/svgadump/st_shader.h
Normal file
214
src/gallium/drivers/svga/svgadump/st_shader.h
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/**********************************************************
|
||||
* Copyright 2007-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* SVGA Shader Token Definitions
|
||||
*
|
||||
* @author Michal Krol <michal@vmware.com>
|
||||
*/
|
||||
|
||||
#ifndef ST_SHADER_SVGA_H
|
||||
#define ST_SHADER_SVGA_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct sh_op
|
||||
{
|
||||
unsigned opcode:16;
|
||||
unsigned control:8;
|
||||
unsigned length:4;
|
||||
unsigned predicated:1;
|
||||
unsigned unused:1;
|
||||
unsigned coissue:1;
|
||||
unsigned is_reg:1;
|
||||
};
|
||||
|
||||
struct sh_reg
|
||||
{
|
||||
unsigned number:11;
|
||||
unsigned type_hi:2;
|
||||
unsigned relative:1;
|
||||
unsigned unused:14;
|
||||
unsigned type_lo:3;
|
||||
unsigned is_reg:1;
|
||||
};
|
||||
|
||||
static INLINE unsigned
|
||||
sh_reg_type( struct sh_reg reg )
|
||||
{
|
||||
return reg.type_lo | (reg.type_hi << 3);
|
||||
}
|
||||
|
||||
struct sh_cdata
|
||||
{
|
||||
float xyzw[4];
|
||||
};
|
||||
|
||||
struct sh_def
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_reg reg;
|
||||
struct sh_cdata cdata;
|
||||
};
|
||||
|
||||
struct sh_defb
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_reg reg;
|
||||
uint data;
|
||||
};
|
||||
|
||||
struct sh_idata
|
||||
{
|
||||
int xyzw[4];
|
||||
};
|
||||
|
||||
struct sh_defi
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_reg reg;
|
||||
struct sh_idata idata;
|
||||
};
|
||||
|
||||
#define PS_TEXTURETYPE_UNKNOWN SVGA3DSAMP_UNKNOWN
|
||||
#define PS_TEXTURETYPE_2D SVGA3DSAMP_2D
|
||||
#define PS_TEXTURETYPE_CUBE SVGA3DSAMP_CUBE
|
||||
#define PS_TEXTURETYPE_VOLUME SVGA3DSAMP_VOLUME
|
||||
|
||||
struct ps_sampleinfo
|
||||
{
|
||||
unsigned unused:27;
|
||||
unsigned texture_type:4;
|
||||
unsigned is_reg:1;
|
||||
};
|
||||
|
||||
struct vs_semantic
|
||||
{
|
||||
unsigned usage:5;
|
||||
unsigned unused1:11;
|
||||
unsigned usage_index:4;
|
||||
unsigned unused2:12;
|
||||
};
|
||||
|
||||
struct sh_dstreg
|
||||
{
|
||||
unsigned number:11;
|
||||
unsigned type_hi:2;
|
||||
unsigned relative:1;
|
||||
unsigned unused:2;
|
||||
unsigned write_mask:4;
|
||||
unsigned modifier:4;
|
||||
unsigned shift_scale:4;
|
||||
unsigned type_lo:3;
|
||||
unsigned is_reg:1;
|
||||
};
|
||||
|
||||
static INLINE unsigned
|
||||
sh_dstreg_type( struct sh_dstreg reg )
|
||||
{
|
||||
return reg.type_lo | (reg.type_hi << 3);
|
||||
}
|
||||
|
||||
struct sh_dcl
|
||||
{
|
||||
struct sh_op op;
|
||||
union {
|
||||
struct {
|
||||
struct ps_sampleinfo sampleinfo;
|
||||
} ps;
|
||||
struct {
|
||||
struct vs_semantic semantic;
|
||||
} vs;
|
||||
} u;
|
||||
struct sh_dstreg reg;
|
||||
};
|
||||
|
||||
|
||||
struct sh_srcreg
|
||||
{
|
||||
unsigned number:11;
|
||||
unsigned type_hi:2;
|
||||
unsigned relative:1;
|
||||
unsigned unused:2;
|
||||
unsigned swizzle_x:2;
|
||||
unsigned swizzle_y:2;
|
||||
unsigned swizzle_z:2;
|
||||
unsigned swizzle_w:2;
|
||||
unsigned modifier:4;
|
||||
unsigned type_lo:3;
|
||||
unsigned is_reg:1;
|
||||
};
|
||||
|
||||
static INLINE unsigned
|
||||
sh_srcreg_type( struct sh_srcreg reg )
|
||||
{
|
||||
return reg.type_lo | (reg.type_hi << 3);
|
||||
}
|
||||
|
||||
struct sh_dstop
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_dstreg dst;
|
||||
};
|
||||
|
||||
struct sh_srcop
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_srcreg src;
|
||||
};
|
||||
|
||||
struct sh_src2op
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_srcreg src0;
|
||||
struct sh_srcreg src1;
|
||||
};
|
||||
|
||||
struct sh_unaryop
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_dstreg dst;
|
||||
struct sh_srcreg src;
|
||||
};
|
||||
|
||||
struct sh_binaryop
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_dstreg dst;
|
||||
struct sh_srcreg src0;
|
||||
struct sh_srcreg src1;
|
||||
};
|
||||
|
||||
struct sh_trinaryop
|
||||
{
|
||||
struct sh_op op;
|
||||
struct sh_dstreg dst;
|
||||
struct sh_srcreg src0;
|
||||
struct sh_srcreg src1;
|
||||
struct sh_srcreg src2;
|
||||
};
|
||||
|
||||
#endif /* ST_SHADER_SVGA_H */
|
||||
649
src/gallium/drivers/svga/svgadump/st_shader_dump.c
Normal file
649
src/gallium/drivers/svga/svgadump/st_shader_dump.c
Normal file
|
|
@ -0,0 +1,649 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* SVGA Shader Dump Facilities
|
||||
*
|
||||
* @author Michal Krol <michal@vmware.com>
|
||||
*/
|
||||
|
||||
#include "st_shader.h"
|
||||
#include "st_shader_dump.h"
|
||||
#include "st_shader_op.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
#include "../svga_hw_reg.h"
|
||||
#include "svga3d_shaderdefs.h"
|
||||
|
||||
struct dump_info
|
||||
{
|
||||
SVGA3dShaderVersion version;
|
||||
boolean is_ps;
|
||||
};
|
||||
|
||||
static void dump_op( struct sh_op op, const char *mnemonic )
|
||||
{
|
||||
assert( op.predicated == 0 );
|
||||
assert( op.is_reg == 0 );
|
||||
|
||||
if (op.coissue)
|
||||
debug_printf( "+" );
|
||||
debug_printf( "%s", mnemonic );
|
||||
switch (op.control) {
|
||||
case 0:
|
||||
break;
|
||||
case SVGA3DOPCONT_PROJECT:
|
||||
debug_printf( "p" );
|
||||
break;
|
||||
case SVGA3DOPCONT_BIAS:
|
||||
debug_printf( "b" );
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_comp_op( struct sh_op op, const char *mnemonic )
|
||||
{
|
||||
assert( op.is_reg == 0 );
|
||||
|
||||
if (op.coissue)
|
||||
debug_printf( "+" );
|
||||
debug_printf( "%s", mnemonic );
|
||||
switch (op.control) {
|
||||
case SVGA3DOPCOMP_RESERVED0:
|
||||
break;
|
||||
case SVGA3DOPCOMP_GT:
|
||||
debug_printf("_gt");
|
||||
break;
|
||||
case SVGA3DOPCOMP_EQ:
|
||||
debug_printf("_eq");
|
||||
break;
|
||||
case SVGA3DOPCOMP_GE:
|
||||
debug_printf("_ge");
|
||||
break;
|
||||
case SVGA3DOPCOMP_LT:
|
||||
debug_printf("_lt");
|
||||
break;
|
||||
case SVGA3DOPCOMPC_NE:
|
||||
debug_printf("_ne");
|
||||
break;
|
||||
case SVGA3DOPCOMP_LE:
|
||||
debug_printf("_le");
|
||||
break;
|
||||
case SVGA3DOPCOMP_RESERVED1:
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct dump_info *di )
|
||||
{
|
||||
assert( sh_reg_type( reg ) == SVGA3DREG_CONST || reg.relative == 0 );
|
||||
assert( reg.is_reg == 1 );
|
||||
|
||||
switch (sh_reg_type( reg )) {
|
||||
case SVGA3DREG_TEMP:
|
||||
debug_printf( "r%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_INPUT:
|
||||
debug_printf( "v%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_CONST:
|
||||
if (reg.relative) {
|
||||
if (sh_srcreg_type( *indreg ) == SVGA3DREG_LOOP)
|
||||
debug_printf( "c[aL+%u]", reg.number );
|
||||
else
|
||||
debug_printf( "c[a%u.x+%u]", indreg->number, reg.number );
|
||||
}
|
||||
else
|
||||
debug_printf( "c%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_ADDR: /* VS */
|
||||
/* SVGA3DREG_TEXTURE */ /* PS */
|
||||
if (di->is_ps)
|
||||
debug_printf( "t%u", reg.number );
|
||||
else
|
||||
debug_printf( "a%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_RASTOUT:
|
||||
switch (reg.number) {
|
||||
case 0 /*POSITION*/:
|
||||
debug_printf( "oPos" );
|
||||
break;
|
||||
case 1 /*FOG*/:
|
||||
debug_printf( "oFog" );
|
||||
break;
|
||||
case 2 /*POINT_SIZE*/:
|
||||
debug_printf( "oPts" );
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
debug_printf( "???" );
|
||||
}
|
||||
break;
|
||||
|
||||
case SVGA3DREG_ATTROUT:
|
||||
assert( reg.number < 2 );
|
||||
debug_printf( "oD%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_TEXCRDOUT:
|
||||
/* SVGA3DREG_OUTPUT */
|
||||
debug_printf( "oT%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_COLOROUT:
|
||||
debug_printf( "oC%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_DEPTHOUT:
|
||||
debug_printf( "oD%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_SAMPLER:
|
||||
debug_printf( "s%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_CONSTBOOL:
|
||||
assert( !reg.relative );
|
||||
debug_printf( "b%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_CONSTINT:
|
||||
assert( !reg.relative );
|
||||
debug_printf( "i%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_LOOP:
|
||||
assert( reg.number == 0 );
|
||||
debug_printf( "aL" );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_MISCTYPE:
|
||||
switch (reg.number) {
|
||||
case SVGA3DMISCREG_POSITION:
|
||||
debug_printf( "vPos" );
|
||||
break;
|
||||
case SVGA3DMISCREG_FACE:
|
||||
debug_printf( "vFace" );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SVGA3DREG_LABEL:
|
||||
debug_printf( "l%u", reg.number );
|
||||
break;
|
||||
|
||||
case SVGA3DREG_PREDICATE:
|
||||
debug_printf( "p%u", reg.number );
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
debug_printf( "???" );
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_cdata( struct sh_cdata cdata )
|
||||
{
|
||||
debug_printf( "%f, %f, %f, %f", cdata.xyzw[0], cdata.xyzw[1], cdata.xyzw[2], cdata.xyzw[3] );
|
||||
}
|
||||
|
||||
static void dump_idata( struct sh_idata idata )
|
||||
{
|
||||
debug_printf( "%d, %d, %d, %d", idata.xyzw[0], idata.xyzw[1], idata.xyzw[2], idata.xyzw[3] );
|
||||
}
|
||||
|
||||
static void dump_bdata( boolean bdata )
|
||||
{
|
||||
debug_printf( bdata ? "TRUE" : "FALSE" );
|
||||
}
|
||||
|
||||
static void dump_sampleinfo( struct ps_sampleinfo sampleinfo )
|
||||
{
|
||||
switch (sampleinfo.texture_type) {
|
||||
case SVGA3DSAMP_2D:
|
||||
debug_printf( "_2d" );
|
||||
break;
|
||||
case SVGA3DSAMP_CUBE:
|
||||
debug_printf( "_cube" );
|
||||
break;
|
||||
case SVGA3DSAMP_VOLUME:
|
||||
debug_printf( "_volume" );
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_usageinfo( struct vs_semantic semantic )
|
||||
{
|
||||
switch (semantic.usage) {
|
||||
case SVGA3D_DECLUSAGE_POSITION:
|
||||
debug_printf("_position" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_BLENDWEIGHT:
|
||||
debug_printf("_blendweight" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_BLENDINDICES:
|
||||
debug_printf("_blendindices" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_NORMAL:
|
||||
debug_printf("_normal" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_PSIZE:
|
||||
debug_printf("_psize" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_TEXCOORD:
|
||||
debug_printf("_texcoord");
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_TANGENT:
|
||||
debug_printf("_tangent" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_BINORMAL:
|
||||
debug_printf("_binormal" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_TESSFACTOR:
|
||||
debug_printf("_tessfactor" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_POSITIONT:
|
||||
debug_printf("_positiont" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_COLOR:
|
||||
debug_printf("_color" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_FOG:
|
||||
debug_printf("_fog" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_DEPTH:
|
||||
debug_printf("_depth" );
|
||||
break;
|
||||
case SVGA3D_DECLUSAGE_SAMPLE:
|
||||
debug_printf("_sample");
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if (semantic.usage_index != 0) {
|
||||
debug_printf("%d", semantic.usage_index );
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di )
|
||||
{
|
||||
union {
|
||||
struct sh_reg reg;
|
||||
struct sh_dstreg dstreg;
|
||||
} u;
|
||||
|
||||
assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
|
||||
|
||||
if (dstreg.modifier & SVGA3DDSTMOD_SATURATE)
|
||||
debug_printf( "_sat" );
|
||||
if (dstreg.modifier & SVGA3DDSTMOD_PARTIALPRECISION)
|
||||
debug_printf( "_pp" );
|
||||
switch (dstreg.shift_scale) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
debug_printf( "_x2" );
|
||||
break;
|
||||
case 2:
|
||||
debug_printf( "_x4" );
|
||||
break;
|
||||
case 3:
|
||||
debug_printf( "_x8" );
|
||||
break;
|
||||
case 13:
|
||||
debug_printf( "_d8" );
|
||||
break;
|
||||
case 14:
|
||||
debug_printf( "_d4" );
|
||||
break;
|
||||
case 15:
|
||||
debug_printf( "_d2" );
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
debug_printf( " " );
|
||||
|
||||
u.dstreg = dstreg;
|
||||
dump_reg( u.reg, NULL, di );
|
||||
if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
|
||||
debug_printf( "." );
|
||||
if (dstreg.write_mask & SVGA3DWRITEMASK_0)
|
||||
debug_printf( "x" );
|
||||
if (dstreg.write_mask & SVGA3DWRITEMASK_1)
|
||||
debug_printf( "y" );
|
||||
if (dstreg.write_mask & SVGA3DWRITEMASK_2)
|
||||
debug_printf( "z" );
|
||||
if (dstreg.write_mask & SVGA3DWRITEMASK_3)
|
||||
debug_printf( "w" );
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di )
|
||||
{
|
||||
union {
|
||||
struct sh_reg reg;
|
||||
struct sh_srcreg srcreg;
|
||||
} u;
|
||||
|
||||
switch (srcreg.modifier) {
|
||||
case SVGA3DSRCMOD_NEG:
|
||||
case SVGA3DSRCMOD_BIASNEG:
|
||||
case SVGA3DSRCMOD_SIGNNEG:
|
||||
case SVGA3DSRCMOD_X2NEG:
|
||||
debug_printf( "-" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_ABS:
|
||||
debug_printf( "|" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_ABSNEG:
|
||||
debug_printf( "-|" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_COMP:
|
||||
debug_printf( "1-" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_NOT:
|
||||
debug_printf( "!" );
|
||||
}
|
||||
|
||||
u.srcreg = srcreg;
|
||||
dump_reg( u.reg, indreg, di );
|
||||
switch (srcreg.modifier) {
|
||||
case SVGA3DSRCMOD_NONE:
|
||||
case SVGA3DSRCMOD_NEG:
|
||||
case SVGA3DSRCMOD_COMP:
|
||||
case SVGA3DSRCMOD_NOT:
|
||||
break;
|
||||
case SVGA3DSRCMOD_ABS:
|
||||
case SVGA3DSRCMOD_ABSNEG:
|
||||
debug_printf( "|" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_BIAS:
|
||||
case SVGA3DSRCMOD_BIASNEG:
|
||||
debug_printf( "_bias" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_SIGN:
|
||||
case SVGA3DSRCMOD_SIGNNEG:
|
||||
debug_printf( "_bx2" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_X2:
|
||||
case SVGA3DSRCMOD_X2NEG:
|
||||
debug_printf( "_x2" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_DZ:
|
||||
debug_printf( "_dz" );
|
||||
break;
|
||||
case SVGA3DSRCMOD_DW:
|
||||
debug_printf( "_dw" );
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
if (srcreg.swizzle_x != 0 || srcreg.swizzle_y != 1 || srcreg.swizzle_z != 2 || srcreg.swizzle_w != 3) {
|
||||
debug_printf( "." );
|
||||
if (srcreg.swizzle_x == srcreg.swizzle_y && srcreg.swizzle_y == srcreg.swizzle_z && srcreg.swizzle_z == srcreg.swizzle_w) {
|
||||
debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
|
||||
}
|
||||
else {
|
||||
debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
|
||||
debug_printf( "%c", "xyzw"[srcreg.swizzle_y] );
|
||||
debug_printf( "%c", "xyzw"[srcreg.swizzle_z] );
|
||||
debug_printf( "%c", "xyzw"[srcreg.swizzle_w] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sh_svga_dump(
|
||||
const unsigned *assem,
|
||||
unsigned dwords,
|
||||
unsigned do_binary )
|
||||
{
|
||||
const unsigned *start = assem;
|
||||
boolean finished = FALSE;
|
||||
struct dump_info di;
|
||||
unsigned i;
|
||||
|
||||
if (do_binary) {
|
||||
for (i = 0; i < dwords; i++)
|
||||
debug_printf(" 0x%08x,\n", assem[i]);
|
||||
|
||||
debug_printf("\n\n");
|
||||
}
|
||||
|
||||
di.version.value = *assem++;
|
||||
di.is_ps = (di.version.type == SVGA3D_PS_TYPE);
|
||||
|
||||
debug_printf(
|
||||
"%s_%u_%u\n",
|
||||
di.is_ps ? "ps" : "vs",
|
||||
di.version.major,
|
||||
di.version.minor );
|
||||
|
||||
while (!finished) {
|
||||
struct sh_op op = *(struct sh_op *) assem;
|
||||
|
||||
if (assem - start >= dwords) {
|
||||
debug_printf("... ran off end of buffer\n");
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (op.opcode) {
|
||||
case SVGA3DOP_DCL:
|
||||
{
|
||||
struct sh_dcl dcl = *(struct sh_dcl *) assem;
|
||||
|
||||
debug_printf( "dcl" );
|
||||
if (sh_dstreg_type( dcl.reg ) == SVGA3DREG_SAMPLER)
|
||||
dump_sampleinfo( dcl.u.ps.sampleinfo );
|
||||
else if (di.is_ps) {
|
||||
if (di.version.major == 3 &&
|
||||
sh_dstreg_type( dcl.reg ) != SVGA3DREG_MISCTYPE)
|
||||
dump_usageinfo( dcl.u.vs.semantic );
|
||||
}
|
||||
else
|
||||
dump_usageinfo( dcl.u.vs.semantic );
|
||||
dump_dstreg( dcl.reg, &di );
|
||||
debug_printf( "\n" );
|
||||
assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
|
||||
}
|
||||
break;
|
||||
|
||||
case SVGA3DOP_DEFB:
|
||||
{
|
||||
struct sh_defb defb = *(struct sh_defb *) assem;
|
||||
|
||||
debug_printf( "defb " );
|
||||
dump_reg( defb.reg, NULL, &di );
|
||||
debug_printf( ", " );
|
||||
dump_bdata( defb.data );
|
||||
debug_printf( "\n" );
|
||||
assem += sizeof( struct sh_defb ) / sizeof( unsigned );
|
||||
}
|
||||
break;
|
||||
|
||||
case SVGA3DOP_DEFI:
|
||||
{
|
||||
struct sh_defi defi = *(struct sh_defi *) assem;
|
||||
|
||||
debug_printf( "defi " );
|
||||
dump_reg( defi.reg, NULL, &di );
|
||||
debug_printf( ", " );
|
||||
dump_idata( defi.idata );
|
||||
debug_printf( "\n" );
|
||||
assem += sizeof( struct sh_defi ) / sizeof( unsigned );
|
||||
}
|
||||
break;
|
||||
|
||||
case SVGA3DOP_TEXCOORD:
|
||||
assert( di.is_ps );
|
||||
dump_op( op, "texcoord" );
|
||||
if (0) {
|
||||
struct sh_dstop dstop = *(struct sh_dstop *) assem;
|
||||
dump_dstreg( dstop.dst, &di );
|
||||
assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
|
||||
}
|
||||
else {
|
||||
struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
|
||||
dump_dstreg( unaryop.dst, &di );
|
||||
debug_printf( ", " );
|
||||
dump_srcreg( unaryop.src, NULL, &di );
|
||||
assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
|
||||
}
|
||||
debug_printf( "\n" );
|
||||
break;
|
||||
|
||||
case SVGA3DOP_TEX:
|
||||
assert( di.is_ps );
|
||||
if (0) {
|
||||
dump_op( op, "tex" );
|
||||
if (0) {
|
||||
struct sh_dstop dstop = *(struct sh_dstop *) assem;
|
||||
|
||||
dump_dstreg( dstop.dst, &di );
|
||||
assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
|
||||
}
|
||||
else {
|
||||
struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
|
||||
|
||||
dump_dstreg( unaryop.dst, &di );
|
||||
debug_printf( ", " );
|
||||
dump_srcreg( unaryop.src, NULL, &di );
|
||||
assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct sh_binaryop binaryop = *(struct sh_binaryop *) assem;
|
||||
|
||||
dump_op( op, "texld" );
|
||||
dump_dstreg( binaryop.dst, &di );
|
||||
debug_printf( ", " );
|
||||
dump_srcreg( binaryop.src0, NULL, &di );
|
||||
debug_printf( ", " );
|
||||
dump_srcreg( binaryop.src1, NULL, &di );
|
||||
assem += sizeof( struct sh_binaryop ) / sizeof( unsigned );
|
||||
}
|
||||
debug_printf( "\n" );
|
||||
break;
|
||||
|
||||
case SVGA3DOP_DEF:
|
||||
{
|
||||
struct sh_def def = *(struct sh_def *) assem;
|
||||
|
||||
debug_printf( "def " );
|
||||
dump_reg( def.reg, NULL, &di );
|
||||
debug_printf( ", " );
|
||||
dump_cdata( def.cdata );
|
||||
debug_printf( "\n" );
|
||||
assem += sizeof( struct sh_def ) / sizeof( unsigned );
|
||||
}
|
||||
break;
|
||||
|
||||
case SVGA3DOP_PHASE:
|
||||
debug_printf( "phase\n" );
|
||||
assem += sizeof( struct sh_op ) / sizeof( unsigned );
|
||||
break;
|
||||
|
||||
case SVGA3DOP_COMMENT:
|
||||
assert( 0 );
|
||||
break;
|
||||
|
||||
case SVGA3DOP_RET:
|
||||
debug_printf( "ret\n" );
|
||||
assem += sizeof( struct sh_op ) / sizeof( unsigned );
|
||||
break;
|
||||
|
||||
case SVGA3DOP_END:
|
||||
debug_printf( "end\n" );
|
||||
finished = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const struct sh_opcode_info *info = sh_svga_opcode_info( op.opcode );
|
||||
uint i;
|
||||
uint num_src = info->num_src + op.predicated;
|
||||
boolean not_first_arg = FALSE;
|
||||
|
||||
assert( info->num_dst <= 1 );
|
||||
|
||||
if (op.opcode == SVGA3DOP_SINCOS && di.version.major < 3)
|
||||
num_src += 2;
|
||||
|
||||
dump_comp_op( op, info->mnemonic );
|
||||
assem += sizeof( struct sh_op ) / sizeof( unsigned );
|
||||
|
||||
if (info->num_dst > 0) {
|
||||
struct sh_dstreg dstreg = *(struct sh_dstreg *) assem;
|
||||
|
||||
dump_dstreg( dstreg, &di );
|
||||
assem += sizeof( struct sh_dstreg ) / sizeof( unsigned );
|
||||
not_first_arg = TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_src; i++) {
|
||||
struct sh_srcreg srcreg;
|
||||
struct sh_srcreg indreg;
|
||||
|
||||
srcreg = *(struct sh_srcreg *) assem;
|
||||
assem += sizeof( struct sh_srcreg ) / sizeof( unsigned );
|
||||
if (srcreg.relative && !di.is_ps && di.version.major >= 2) {
|
||||
indreg = *(struct sh_srcreg *) assem;
|
||||
assem += sizeof( struct sh_srcreg ) / sizeof( unsigned );
|
||||
}
|
||||
|
||||
if (not_first_arg)
|
||||
debug_printf( ", " );
|
||||
else
|
||||
debug_printf( " " );
|
||||
dump_srcreg( srcreg, &indreg, &di );
|
||||
not_first_arg = TRUE;
|
||||
}
|
||||
|
||||
debug_printf( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/gallium/drivers/svga/svgadump/st_shader_dump.h
Normal file
42
src/gallium/drivers/svga/svgadump/st_shader_dump.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* SVGA Shader Dump Facilities
|
||||
*
|
||||
* @author Michal Krol <michal@vmware.com>
|
||||
*/
|
||||
|
||||
#ifndef ST_SHADER_SVGA_DUMP_H
|
||||
#define ST_SHADER_SVGA_DUMP_H
|
||||
|
||||
void
|
||||
sh_svga_dump(
|
||||
const unsigned *assem,
|
||||
unsigned dwords,
|
||||
unsigned do_binary );
|
||||
|
||||
#endif /* ST_SHADER_SVGA_DUMP_H */
|
||||
168
src/gallium/drivers/svga/svgadump/st_shader_op.c
Normal file
168
src/gallium/drivers/svga/svgadump/st_shader_op.c
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* SVGA Shader Token Opcode Info
|
||||
*
|
||||
* @author Michal Krol <michal@vmware.com>
|
||||
*/
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "st_shader_op.h"
|
||||
|
||||
#include "../svga_hw_reg.h"
|
||||
#include "svga3d_shaderdefs.h"
|
||||
|
||||
#define SVGA3DOP_INVALID SVGA3DOP_END
|
||||
#define TGSI_OPCODE_INVALID TGSI_OPCODE_LAST
|
||||
|
||||
static struct sh_opcode_info opcode_info[] =
|
||||
{
|
||||
{ "nop", 0, 0, SVGA3DOP_NOP },
|
||||
{ "mov", 1, 1, SVGA3DOP_MOV, },
|
||||
{ "add", 1, 2, SVGA3DOP_ADD, },
|
||||
{ "sub", 1, 2, SVGA3DOP_SUB, },
|
||||
{ "mad", 1, 3, SVGA3DOP_MAD, },
|
||||
{ "mul", 1, 2, SVGA3DOP_MUL, },
|
||||
{ "rcp", 1, 1, SVGA3DOP_RCP, },
|
||||
{ "rsq", 1, 1, SVGA3DOP_RSQ, },
|
||||
{ "dp3", 1, 2, SVGA3DOP_DP3, },
|
||||
{ "dp4", 1, 2, SVGA3DOP_DP4, },
|
||||
{ "min", 1, 2, SVGA3DOP_MIN, },
|
||||
{ "max", 1, 2, SVGA3DOP_MAX, },
|
||||
{ "slt", 1, 2, SVGA3DOP_SLT, },
|
||||
{ "sge", 1, 2, SVGA3DOP_SGE, },
|
||||
{ "exp", 1, 1, SVGA3DOP_EXP, },
|
||||
{ "log", 1, 1, SVGA3DOP_LOG, },
|
||||
{ "lit", 1, 1, SVGA3DOP_LIT, },
|
||||
{ "dst", 1, 2, SVGA3DOP_DST, },
|
||||
{ "lrp", 1, 3, SVGA3DOP_LRP, },
|
||||
{ "frc", 1, 1, SVGA3DOP_FRC, },
|
||||
{ "m4x4", 1, 2, SVGA3DOP_M4x4, },
|
||||
{ "m4x3", 1, 2, SVGA3DOP_M4x3, },
|
||||
{ "m3x4", 1, 2, SVGA3DOP_M3x4, },
|
||||
{ "m3x3", 1, 2, SVGA3DOP_M3x3, },
|
||||
{ "m3x2", 1, 2, SVGA3DOP_M3x2, },
|
||||
{ "call", 0, 1, SVGA3DOP_CALL, },
|
||||
{ "callnz", 0, 2, SVGA3DOP_CALLNZ, },
|
||||
{ "loop", 0, 2, SVGA3DOP_LOOP, },
|
||||
{ "ret", 0, 0, SVGA3DOP_RET, },
|
||||
{ "endloop", 0, 0, SVGA3DOP_ENDLOOP, },
|
||||
{ "label", 0, 1, SVGA3DOP_LABEL, },
|
||||
{ "dcl", 0, 0, SVGA3DOP_DCL, },
|
||||
{ "pow", 1, 2, SVGA3DOP_POW, },
|
||||
{ "crs", 1, 2, SVGA3DOP_CRS, },
|
||||
{ "sgn", 1, 3, SVGA3DOP_SGN, },
|
||||
{ "abs", 1, 1, SVGA3DOP_ABS, },
|
||||
{ "nrm", 1, 1, SVGA3DOP_NRM, }, /* 3-componenet normalization */
|
||||
{ "sincos", 1, 1, SVGA3DOP_SINCOS, },
|
||||
{ "rep", 0, 1, SVGA3DOP_REP, },
|
||||
{ "endrep", 0, 0, SVGA3DOP_ENDREP, },
|
||||
{ "if", 0, 1, SVGA3DOP_IF, },
|
||||
{ "ifc", 0, 2, SVGA3DOP_IFC, },
|
||||
{ "else", 0, 0, SVGA3DOP_ELSE, },
|
||||
{ "endif", 0, 0, SVGA3DOP_ENDIF, },
|
||||
{ "break", 0, 0, SVGA3DOP_BREAK, },
|
||||
{ "breakc", 0, 0, SVGA3DOP_BREAKC, },
|
||||
{ "mova", 1, 1, SVGA3DOP_MOVA, },
|
||||
{ "defb", 0, 0, SVGA3DOP_DEFB, },
|
||||
{ "defi", 0, 0, SVGA3DOP_DEFI, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "???", 0, 0, SVGA3DOP_INVALID, },
|
||||
{ "texcoord", 0, 0, SVGA3DOP_TEXCOORD, },
|
||||
{ "texkill", 1, 0, SVGA3DOP_TEXKILL, },
|
||||
{ "tex", 0, 0, SVGA3DOP_TEX, },
|
||||
{ "texbem", 1, 1, SVGA3DOP_TEXBEM, },
|
||||
{ "texbeml", 1, 1, SVGA3DOP_TEXBEML, },
|
||||
{ "texreg2ar", 1, 1, SVGA3DOP_TEXREG2AR, },
|
||||
{ "texreg2gb", 1, 1, SVGA3DOP_TEXREG2GB, },
|
||||
{ "texm3x2pad", 1, 1, SVGA3DOP_TEXM3x2PAD, },
|
||||
{ "texm3x2tex", 1, 1, SVGA3DOP_TEXM3x2TEX, },
|
||||
{ "texm3x3pad", 1, 1, SVGA3DOP_TEXM3x3PAD, },
|
||||
{ "texm3x3tex", 1, 1, SVGA3DOP_TEXM3x3TEX, },
|
||||
{ "reserved0", 0, 0, SVGA3DOP_RESERVED0, },
|
||||
{ "texm3x3spec", 1, 2, SVGA3DOP_TEXM3x3SPEC, },
|
||||
{ "texm3x3vspec", 1, 1, SVGA3DOP_TEXM3x3VSPEC,},
|
||||
{ "expp", 1, 1, SVGA3DOP_EXPP, },
|
||||
{ "logp", 1, 1, SVGA3DOP_LOGP, },
|
||||
{ "cnd", 1, 3, SVGA3DOP_CND, },
|
||||
{ "def", 0, 0, SVGA3DOP_DEF, },
|
||||
{ "texreg2rgb", 1, 1, SVGA3DOP_TEXREG2RGB, },
|
||||
{ "texdp3tex", 1, 1, SVGA3DOP_TEXDP3TEX, },
|
||||
{ "texm3x2depth", 1, 1, SVGA3DOP_TEXM3x2DEPTH,},
|
||||
{ "texdp3", 1, 1, SVGA3DOP_TEXDP3, },
|
||||
{ "texm3x3", 1, 1, SVGA3DOP_TEXM3x3, },
|
||||
{ "texdepth", 1, 0, SVGA3DOP_TEXDEPTH, },
|
||||
{ "cmp", 1, 3, SVGA3DOP_CMP, },
|
||||
{ "bem", 1, 2, SVGA3DOP_BEM, },
|
||||
{ "dp2add", 1, 3, SVGA3DOP_DP2ADD, },
|
||||
{ "dsx", 1, 1, SVGA3DOP_INVALID, },
|
||||
{ "dsy", 1, 1, SVGA3DOP_INVALID, },
|
||||
{ "texldd", 1, 1, SVGA3DOP_INVALID, },
|
||||
{ "setp", 1, 2, SVGA3DOP_SETP, },
|
||||
{ "texldl", 1, 1, SVGA3DOP_INVALID, },
|
||||
{ "breakp", 1, 1, SVGA3DOP_INVALID, },
|
||||
};
|
||||
|
||||
const struct sh_opcode_info *sh_svga_opcode_info( uint op )
|
||||
{
|
||||
struct sh_opcode_info *info;
|
||||
|
||||
if (op >= sizeof( opcode_info ) / sizeof( opcode_info[0] )) {
|
||||
/* The opcode is either PHASE, COMMENT, END or out of range.
|
||||
*/
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info = &opcode_info[op];
|
||||
|
||||
if (info->svga_opcode == SVGA3DOP_INVALID) {
|
||||
/* No valid information. Please provide number of dst/src registers.
|
||||
*/
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Sanity check.
|
||||
*/
|
||||
assert( op == info->svga_opcode );
|
||||
|
||||
return info;
|
||||
}
|
||||
46
src/gallium/drivers/svga/svgadump/st_shader_op.h
Normal file
46
src/gallium/drivers/svga/svgadump/st_shader_op.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* SVGA Shader Token Opcode Info
|
||||
*
|
||||
* @author Michal Krol <michal@vmware.com>
|
||||
*/
|
||||
|
||||
#ifndef ST_SHADER_SVGA_OP_H
|
||||
#define ST_SHADER_SVGA_OP_H
|
||||
|
||||
struct sh_opcode_info
|
||||
{
|
||||
const char *mnemonic;
|
||||
unsigned num_dst:8;
|
||||
unsigned num_src:8;
|
||||
unsigned svga_opcode:16;
|
||||
};
|
||||
|
||||
const struct sh_opcode_info *sh_svga_opcode_info( unsigned op );
|
||||
|
||||
#endif /* ST_SHADER_SVGA_OP_H */
|
||||
1736
src/gallium/drivers/svga/svgadump/svga_dump.c
Normal file
1736
src/gallium/drivers/svga/svgadump/svga_dump.c
Normal file
File diff suppressed because it is too large
Load diff
34
src/gallium/drivers/svga/svgadump/svga_dump.h
Normal file
34
src/gallium/drivers/svga/svgadump/svga_dump.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifndef SVGA_DUMP_H_
|
||||
#define SVGA_DUMP_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
void
|
||||
svga_dump_commands(const void *commands, uint32_t size);
|
||||
|
||||
#endif /* SVGA_DUMP_H_ */
|
||||
329
src/gallium/drivers/svga/svgadump/svga_dump.py
Executable file
329
src/gallium/drivers/svga/svgadump/svga_dump.py
Executable file
|
|
@ -0,0 +1,329 @@
|
|||
#!/usr/bin/env python
|
||||
'''
|
||||
Generates dumper for the SVGA 3D command stream using pygccxml.
|
||||
|
||||
Jose Fonseca <jfonseca@vmware.com>
|
||||
'''
|
||||
|
||||
copyright = '''
|
||||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pygccxml import parser
|
||||
from pygccxml import declarations
|
||||
|
||||
from pygccxml.declarations import algorithm
|
||||
from pygccxml.declarations import decl_visitor
|
||||
from pygccxml.declarations import type_traits
|
||||
from pygccxml.declarations import type_visitor
|
||||
|
||||
|
||||
enums = True
|
||||
|
||||
|
||||
class decl_dumper_t(decl_visitor.decl_visitor_t):
|
||||
|
||||
def __init__(self, instance = '', decl = None):
|
||||
decl_visitor.decl_visitor_t.__init__(self)
|
||||
self._instance = instance
|
||||
self.decl = decl
|
||||
|
||||
def clone(self):
|
||||
return decl_dumper_t(self._instance, self.decl)
|
||||
|
||||
def visit_class(self):
|
||||
class_ = self.decl
|
||||
assert self.decl.class_type in ('struct', 'union')
|
||||
|
||||
for variable in class_.variables():
|
||||
if variable.name != '':
|
||||
#print 'variable = %r' % variable.name
|
||||
dump_type(self._instance + '.' + variable.name, variable.type)
|
||||
|
||||
def visit_enumeration(self):
|
||||
if enums:
|
||||
print ' switch(%s) {' % ("(*cmd)" + self._instance,)
|
||||
for name, value in self.decl.values:
|
||||
print ' case %s:' % (name,)
|
||||
print ' debug_printf("\\t\\t%s = %s\\n");' % (self._instance, name)
|
||||
print ' break;'
|
||||
print ' default:'
|
||||
print ' debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
|
||||
print ' break;'
|
||||
print ' }'
|
||||
else:
|
||||
print ' debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
|
||||
|
||||
|
||||
def dump_decl(instance, decl):
|
||||
dumper = decl_dumper_t(instance, decl)
|
||||
algorithm.apply_visitor(dumper, decl)
|
||||
|
||||
|
||||
class type_dumper_t(type_visitor.type_visitor_t):
|
||||
|
||||
def __init__(self, instance, type_):
|
||||
type_visitor.type_visitor_t.__init__(self)
|
||||
self.instance = instance
|
||||
self.type = type_
|
||||
|
||||
def clone(self):
|
||||
return type_dumper_t(self.instance, self.type)
|
||||
|
||||
def visit_char(self):
|
||||
self.print_instance('%i')
|
||||
|
||||
def visit_unsigned_char(self):
|
||||
self.print_instance('%u')
|
||||
|
||||
def visit_signed_char(self):
|
||||
self.print_instance('%i')
|
||||
|
||||
def visit_wchar(self):
|
||||
self.print_instance('%i')
|
||||
|
||||
def visit_short_int(self):
|
||||
self.print_instance('%i')
|
||||
|
||||
def visit_short_unsigned_int(self):
|
||||
self.print_instance('%u')
|
||||
|
||||
def visit_bool(self):
|
||||
self.print_instance('%i')
|
||||
|
||||
def visit_int(self):
|
||||
self.print_instance('%i')
|
||||
|
||||
def visit_unsigned_int(self):
|
||||
self.print_instance('%u')
|
||||
|
||||
def visit_long_int(self):
|
||||
self.print_instance('%li')
|
||||
|
||||
def visit_long_unsigned_int(self):
|
||||
self.print_instance('%lu')
|
||||
|
||||
def visit_long_long_int(self):
|
||||
self.print_instance('%lli')
|
||||
|
||||
def visit_long_long_unsigned_int(self):
|
||||
self.print_instance('%llu')
|
||||
|
||||
def visit_float(self):
|
||||
self.print_instance('%f')
|
||||
|
||||
def visit_double(self):
|
||||
self.print_instance('%f')
|
||||
|
||||
def visit_array(self):
|
||||
for i in range(type_traits.array_size(self.type)):
|
||||
dump_type(self.instance + '[%i]' % i, type_traits.base_type(self.type))
|
||||
|
||||
def visit_pointer(self):
|
||||
self.print_instance('%p')
|
||||
|
||||
def visit_declarated(self):
|
||||
#print 'decl = %r' % self.type.decl_string
|
||||
decl = type_traits.remove_declarated(self.type)
|
||||
dump_decl(self.instance, decl)
|
||||
|
||||
def print_instance(self, format):
|
||||
print ' debug_printf("\\t\\t%s = %s\\n", %s);' % (self.instance, format, "(*cmd)" + self.instance)
|
||||
|
||||
|
||||
def dump_type(instance, type_):
|
||||
type_ = type_traits.remove_alias(type_)
|
||||
visitor = type_dumper_t(instance, type_)
|
||||
algorithm.apply_visitor(visitor, type_)
|
||||
|
||||
|
||||
def dump_struct(decls, class_):
|
||||
print 'static void'
|
||||
print 'dump_%s(const %s *cmd)' % (class_.name, class_.name)
|
||||
print '{'
|
||||
dump_decl('', class_)
|
||||
print '}'
|
||||
print ''
|
||||
|
||||
|
||||
cmds = [
|
||||
('SVGA_3D_CMD_SURFACE_DEFINE', 'SVGA3dCmdDefineSurface', (), 'SVGA3dSize'),
|
||||
('SVGA_3D_CMD_SURFACE_DESTROY', 'SVGA3dCmdDestroySurface', (), None),
|
||||
('SVGA_3D_CMD_SURFACE_COPY', 'SVGA3dCmdSurfaceCopy', (), 'SVGA3dCopyBox'),
|
||||
('SVGA_3D_CMD_SURFACE_STRETCHBLT', 'SVGA3dCmdSurfaceStretchBlt', (), None),
|
||||
('SVGA_3D_CMD_SURFACE_DMA', 'SVGA3dCmdSurfaceDMA', (), 'SVGA3dCopyBox'),
|
||||
('SVGA_3D_CMD_CONTEXT_DEFINE', 'SVGA3dCmdDefineContext', (), None),
|
||||
('SVGA_3D_CMD_CONTEXT_DESTROY', 'SVGA3dCmdDestroyContext', (), None),
|
||||
('SVGA_3D_CMD_SETTRANSFORM', 'SVGA3dCmdSetTransform', (), None),
|
||||
('SVGA_3D_CMD_SETZRANGE', 'SVGA3dCmdSetZRange', (), None),
|
||||
('SVGA_3D_CMD_SETRENDERSTATE', 'SVGA3dCmdSetRenderState', (), 'SVGA3dRenderState'),
|
||||
('SVGA_3D_CMD_SETRENDERTARGET', 'SVGA3dCmdSetRenderTarget', (), None),
|
||||
('SVGA_3D_CMD_SETTEXTURESTATE', 'SVGA3dCmdSetTextureState', (), 'SVGA3dTextureState'),
|
||||
('SVGA_3D_CMD_SETMATERIAL', 'SVGA3dCmdSetMaterial', (), None),
|
||||
('SVGA_3D_CMD_SETLIGHTDATA', 'SVGA3dCmdSetLightData', (), None),
|
||||
('SVGA_3D_CMD_SETLIGHTENABLED', 'SVGA3dCmdSetLightEnabled', (), None),
|
||||
('SVGA_3D_CMD_SETVIEWPORT', 'SVGA3dCmdSetViewport', (), None),
|
||||
('SVGA_3D_CMD_SETCLIPPLANE', 'SVGA3dCmdSetClipPlane', (), None),
|
||||
('SVGA_3D_CMD_CLEAR', 'SVGA3dCmdClear', (), 'SVGA3dRect'),
|
||||
('SVGA_3D_CMD_PRESENT', 'SVGA3dCmdPresent', (), 'SVGA3dCopyRect'),
|
||||
('SVGA_3D_CMD_SHADER_DEFINE', 'SVGA3dCmdDefineShader', (), None),
|
||||
('SVGA_3D_CMD_SHADER_DESTROY', 'SVGA3dCmdDestroyShader', (), None),
|
||||
('SVGA_3D_CMD_SET_SHADER', 'SVGA3dCmdSetShader', (), None),
|
||||
('SVGA_3D_CMD_SET_SHADER_CONST', 'SVGA3dCmdSetShaderConst', (), None),
|
||||
('SVGA_3D_CMD_DRAW_PRIMITIVES', 'SVGA3dCmdDrawPrimitives', (('SVGA3dVertexDecl', 'numVertexDecls'), ('SVGA3dPrimitiveRange', 'numRanges')), 'SVGA3dVertexDivisor'),
|
||||
('SVGA_3D_CMD_SETSCISSORRECT', 'SVGA3dCmdSetScissorRect', (), None),
|
||||
('SVGA_3D_CMD_BEGIN_QUERY', 'SVGA3dCmdBeginQuery', (), None),
|
||||
('SVGA_3D_CMD_END_QUERY', 'SVGA3dCmdEndQuery', (), None),
|
||||
('SVGA_3D_CMD_WAIT_FOR_QUERY', 'SVGA3dCmdWaitForQuery', (), None),
|
||||
#('SVGA_3D_CMD_PRESENT_READBACK', None, (), None),
|
||||
]
|
||||
|
||||
def dump_cmds():
|
||||
print r'''
|
||||
void
|
||||
svga_dump_commands(const void *commands, uint32_t size)
|
||||
{
|
||||
const uint8_t *next = commands;
|
||||
const uint8_t *last = next + size;
|
||||
|
||||
assert(size % sizeof(uint32_t) == 0);
|
||||
|
||||
while(next < last) {
|
||||
const uint32_t cmd_id = *(const uint32_t *)next;
|
||||
|
||||
if(SVGA_3D_CMD_BASE <= cmd_id && cmd_id < SVGA_3D_CMD_MAX) {
|
||||
const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
|
||||
const uint8_t *body = (const uint8_t *)&header[1];
|
||||
|
||||
next = (const uint8_t *)body + header->size;
|
||||
if(next > last)
|
||||
break;
|
||||
'''
|
||||
|
||||
print ' switch(cmd_id) {'
|
||||
indexes = 'ijklmn'
|
||||
for id, header, body, footer in cmds:
|
||||
print ' case %s:' % id
|
||||
print ' debug_printf("\\t%s\\n");' % id
|
||||
print ' {'
|
||||
print ' const %s *cmd = (const %s *)body;' % (header, header)
|
||||
if len(body):
|
||||
print ' unsigned ' + ', '.join(indexes[:len(body)]) + ';'
|
||||
print ' dump_%s(cmd);' % header
|
||||
print ' body = (const uint8_t *)&cmd[1];'
|
||||
for i in range(len(body)):
|
||||
struct, count = body[i]
|
||||
idx = indexes[i]
|
||||
print ' for(%s = 0; %s < cmd->%s; ++%s) {' % (idx, idx, count, idx)
|
||||
print ' dump_%s((const %s *)body);' % (struct, struct)
|
||||
print ' body += sizeof(%s);' % struct
|
||||
print ' }'
|
||||
if footer is not None:
|
||||
print ' while(body + sizeof(%s) <= next) {' % footer
|
||||
print ' dump_%s((const %s *)body);' % (footer, footer)
|
||||
print ' body += sizeof(%s);' % footer
|
||||
print ' }'
|
||||
if id == 'SVGA_3D_CMD_SHADER_DEFINE':
|
||||
print ' sh_svga_dump((const uint32_t *)body, (unsigned)(next - body)/sizeof(uint32_t));'
|
||||
print ' body = next;'
|
||||
print ' }'
|
||||
print ' break;'
|
||||
print ' default:'
|
||||
print ' debug_printf("\\t0x%08x\\n", cmd_id);'
|
||||
print ' break;'
|
||||
print ' }'
|
||||
|
||||
print r'''
|
||||
while(body + sizeof(uint32_t) <= next) {
|
||||
debug_printf("\t\t0x%08x\n", *(const uint32_t *)body);
|
||||
body += sizeof(uint32_t);
|
||||
}
|
||||
while(body + sizeof(uint32_t) <= next)
|
||||
debug_printf("\t\t0x%02x\n", *body++);
|
||||
}
|
||||
else if(cmd_id == SVGA_CMD_FENCE) {
|
||||
debug_printf("\tSVGA_CMD_FENCE\n");
|
||||
debug_printf("\t\t0x%08x\n", ((const uint32_t *)next)[1]);
|
||||
next += 2*sizeof(uint32_t);
|
||||
}
|
||||
else {
|
||||
debug_printf("\t0x%08x\n", cmd_id);
|
||||
next += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
def main():
|
||||
print copyright.strip()
|
||||
print
|
||||
print '/**'
|
||||
print ' * @file'
|
||||
print ' * Dump SVGA commands.'
|
||||
print ' *'
|
||||
print ' * Generated automatically from svga3d_reg.h by svga_dump.py.'
|
||||
print ' */'
|
||||
print
|
||||
print '#include "svga_types.h"'
|
||||
print '#include "shader_dump/st_shader_dump.h"'
|
||||
print '#include "svga3d_reg.h"'
|
||||
print
|
||||
print '#include "pipe/p_debug.h"'
|
||||
print '#include "svga_dump.h"'
|
||||
print
|
||||
|
||||
config = parser.config_t(
|
||||
include_paths = ['include'],
|
||||
compiler = 'gcc',
|
||||
)
|
||||
|
||||
headers = [
|
||||
'include/svga_types.h',
|
||||
'include/svga3d_reg.h',
|
||||
]
|
||||
|
||||
decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE)
|
||||
global_ns = declarations.get_global_namespace(decls)
|
||||
|
||||
names = set()
|
||||
for id, header, body, footer in cmds:
|
||||
names.add(header)
|
||||
for struct, count in body:
|
||||
names.add(struct)
|
||||
if footer is not None:
|
||||
names.add(footer)
|
||||
|
||||
for class_ in global_ns.classes(lambda decl: decl.name in names):
|
||||
dump_struct(decls, class_)
|
||||
|
||||
dump_cmds()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
12
src/gallium/winsys/drm/vmware/Makefile
Normal file
12
src/gallium/winsys/drm/vmware/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# src/gallium/winsys/drm/vmware/Makefile
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
|
||||
|
||||
default install clean:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
if [ -d $$dir ] ; then \
|
||||
(cd $$dir && $(MAKE) $@) || exit 1; \
|
||||
fi \
|
||||
done
|
||||
11
src/gallium/winsys/drm/vmware/SConscript
Normal file
11
src/gallium/winsys/drm/vmware/SConscript
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
Import('*')
|
||||
|
||||
SConscript(['core/SConscript',])
|
||||
|
||||
if 'mesa' in env['statetrackers']:
|
||||
|
||||
SConscript(['dri/SConscript'])
|
||||
|
||||
if 'xorg' in env['statetrackers']:
|
||||
|
||||
SConscript(['xorg/SConscript'])
|
||||
47
src/gallium/winsys/drm/vmware/core/Makefile
Normal file
47
src/gallium/winsys/drm/vmware/core/Makefile
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = svgadrm
|
||||
|
||||
C_SOURCES = \
|
||||
vmw_buffer.c \
|
||||
vmw_context.c \
|
||||
vmw_fence.c \
|
||||
vmw_screen.c \
|
||||
vmw_screen_dri.c \
|
||||
vmw_screen_ioctl.c \
|
||||
vmw_screen_pools.c \
|
||||
vmw_screen_svga.c \
|
||||
vmw_surface.c
|
||||
|
||||
LIBRARY_INCLUDES = \
|
||||
-I$(TOP)/src/gallium/drivers/svga \
|
||||
-I$(TOP)/src/gallium/drivers/svga/include \
|
||||
-I$(GALLIUM)/src/mesa/drivers/dri/common \
|
||||
-I$(GALLIUM)/include \
|
||||
-I$(GALLIUM)/include/GL/internal \
|
||||
-I$(GALLIUM)/src/mesa \
|
||||
-I$(GALLIUM)/src/mesa/main \
|
||||
-I$(GALLIUM)/src/mesa/glapi \
|
||||
-I$(GALLIUM)/src/egl/main \
|
||||
-I$(GALLIUM)/src/egl/drivers/dri \
|
||||
$(shell pkg-config libdrm --cflags-only-I)
|
||||
|
||||
LIBRARY_DEFINES = \
|
||||
-DHAVE_STDINT_H -D_FILE_OFFSET_BITS=64 \
|
||||
$(shell pkg-config libdrm --cflags-only-other)
|
||||
|
||||
CC = gcc -fvisibility=hidden -msse -msse2
|
||||
|
||||
# Set the gnu99 standard to enable anonymous structs in vmware headers.
|
||||
#
|
||||
CFLAGS = -Wall -Werror -Wmissing-prototypes -std=gnu99 -ffast-math \
|
||||
$(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) $(ASM_FLAGS)
|
||||
|
||||
include ../../../../Makefile.template
|
||||
|
||||
|
||||
symlinks:
|
||||
|
||||
|
||||
include depend
|
||||
39
src/gallium/winsys/drm/vmware/core/SConscript
Normal file
39
src/gallium/winsys/drm/vmware/core/SConscript
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
Import('*')
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
if env['gcc']:
|
||||
env.Append(CCFLAGS = ['-fvisibility=hidden', '-Werror'])
|
||||
env.Append(CPPDEFINES = [
|
||||
'HAVE_STDINT_H',
|
||||
'HAVE_SYS_TYPES_H',
|
||||
'-D_FILE_OFFSET_BITS=64',
|
||||
])
|
||||
|
||||
env.Prepend(CPPPATH = [
|
||||
'include',
|
||||
'#/src/gallium/drivers/svga',
|
||||
'#/src/gallium/drivers/svga/include',
|
||||
])
|
||||
|
||||
env.Append(CPPDEFINES = [
|
||||
])
|
||||
|
||||
sources = [
|
||||
'vmw_buffer.c',
|
||||
'vmw_context.c',
|
||||
'vmw_fence.c',
|
||||
'vmw_screen.c',
|
||||
'vmw_screen_dri.c',
|
||||
'vmw_screen_ioctl.c',
|
||||
'vmw_screen_pools.c',
|
||||
'vmw_screen_svga.c',
|
||||
'vmw_surface.c',
|
||||
]
|
||||
|
||||
svgadrm = env.ConvenienceLibrary(
|
||||
target = 'svgadrm',
|
||||
source = sources,
|
||||
)
|
||||
|
||||
Export('svgadrm')
|
||||
274
src/gallium/winsys/drm/vmware/core/vmw_buffer.c
Normal file
274
src/gallium/winsys/drm/vmware/core/vmw_buffer.c
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* SVGA buffer manager for Guest Memory Regions (GMRs).
|
||||
*
|
||||
* GMRs are used for pixel and vertex data upload/download to/from the virtual
|
||||
* SVGA hardware. There is a limited number of GMRs available, and
|
||||
* creating/destroying them is also a slow operation so we must suballocate
|
||||
* them.
|
||||
*
|
||||
* This file implements a pipebuffer library's buffer manager, so that we can
|
||||
* use pipepbuffer's suballocation, fencing, and debugging facilities with GMRs.
|
||||
*
|
||||
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
|
||||
#include "svga_winsys.h"
|
||||
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_buffer.h"
|
||||
|
||||
|
||||
struct vmw_gmr_bufmgr;
|
||||
|
||||
|
||||
struct vmw_gmr_buffer
|
||||
{
|
||||
struct pb_buffer base;
|
||||
|
||||
struct vmw_gmr_bufmgr *mgr;
|
||||
|
||||
struct vmw_region *region;
|
||||
void *map;
|
||||
|
||||
#ifdef DEBUG
|
||||
struct pipe_fence_handle *last_fence;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
extern const struct pb_vtbl vmw_gmr_buffer_vtbl;
|
||||
|
||||
|
||||
static INLINE struct vmw_gmr_buffer *
|
||||
vmw_gmr_buffer(struct pb_buffer *buf)
|
||||
{
|
||||
assert(buf);
|
||||
assert(buf->vtbl == &vmw_gmr_buffer_vtbl);
|
||||
return (struct vmw_gmr_buffer *)buf;
|
||||
}
|
||||
|
||||
|
||||
struct vmw_gmr_bufmgr
|
||||
{
|
||||
struct pb_manager base;
|
||||
|
||||
struct vmw_winsys_screen *vws;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct vmw_gmr_bufmgr *
|
||||
vmw_gmr_bufmgr(struct pb_manager *mgr)
|
||||
{
|
||||
assert(mgr);
|
||||
return (struct vmw_gmr_bufmgr *)mgr;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
|
||||
{
|
||||
struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
|
||||
|
||||
#ifdef DEBUG
|
||||
if(buf->last_fence) {
|
||||
struct svga_winsys_screen *sws = &buf->mgr->vws->base;
|
||||
assert(sws->fence_signalled(sws, buf->last_fence, 0) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
vmw_ioctl_region_unmap(buf->region);
|
||||
|
||||
vmw_ioctl_region_destroy(buf->region);
|
||||
|
||||
FREE(buf);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vmw_gmr_buffer_map(struct pb_buffer *_buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
|
||||
return buf->map;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
|
||||
{
|
||||
/* Do nothing */
|
||||
(void)_buf;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_gmr_buffer_get_base_buffer(struct pb_buffer *buf,
|
||||
struct pb_buffer **base_buf,
|
||||
unsigned *offset)
|
||||
{
|
||||
*base_buf = buf;
|
||||
*offset = 0;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
vmw_gmr_buffer_validate( struct pb_buffer *_buf,
|
||||
struct pb_validate *vl,
|
||||
unsigned flags )
|
||||
{
|
||||
/* Always pinned */
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_gmr_buffer_fence( struct pb_buffer *_buf,
|
||||
struct pipe_fence_handle *fence )
|
||||
{
|
||||
/* We don't need to do anything, as the pipebuffer library
|
||||
* will take care of delaying the destruction of fenced buffers */
|
||||
#ifdef DEBUG
|
||||
struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
|
||||
if(fence)
|
||||
buf->last_fence = fence;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
const struct pb_vtbl vmw_gmr_buffer_vtbl = {
|
||||
vmw_gmr_buffer_destroy,
|
||||
vmw_gmr_buffer_map,
|
||||
vmw_gmr_buffer_unmap,
|
||||
vmw_gmr_buffer_validate,
|
||||
vmw_gmr_buffer_fence,
|
||||
vmw_gmr_buffer_get_base_buffer
|
||||
};
|
||||
|
||||
|
||||
static struct pb_buffer *
|
||||
vmw_gmr_bufmgr_create_buffer(struct pb_manager *_mgr,
|
||||
pb_size size,
|
||||
const struct pb_desc *desc)
|
||||
{
|
||||
struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
|
||||
struct vmw_winsys_screen *vws = mgr->vws;
|
||||
struct vmw_gmr_buffer *buf;
|
||||
|
||||
buf = CALLOC_STRUCT(vmw_gmr_buffer);
|
||||
if(!buf)
|
||||
goto error1;
|
||||
|
||||
pipe_reference_init(&buf->base.base.reference, 1);
|
||||
buf->base.base.alignment = desc->alignment;
|
||||
buf->base.base.usage = desc->usage;
|
||||
buf->base.base.size = size;
|
||||
buf->base.vtbl = &vmw_gmr_buffer_vtbl;
|
||||
buf->mgr = mgr;
|
||||
|
||||
buf->region = vmw_ioctl_region_create(vws, size);
|
||||
if(!buf->region)
|
||||
goto error2;
|
||||
|
||||
buf->map = vmw_ioctl_region_map(buf->region);
|
||||
if(!buf->map)
|
||||
goto error3;
|
||||
|
||||
return &buf->base;
|
||||
|
||||
error3:
|
||||
vmw_ioctl_region_destroy(buf->region);
|
||||
error2:
|
||||
FREE(buf);
|
||||
error1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_gmr_bufmgr_flush(struct pb_manager *mgr)
|
||||
{
|
||||
/* No-op */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_gmr_bufmgr_destroy(struct pb_manager *_mgr)
|
||||
{
|
||||
struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
|
||||
FREE(mgr);
|
||||
}
|
||||
|
||||
|
||||
struct pb_manager *
|
||||
vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
struct vmw_gmr_bufmgr *mgr;
|
||||
|
||||
mgr = CALLOC_STRUCT(vmw_gmr_bufmgr);
|
||||
if(!mgr)
|
||||
return NULL;
|
||||
|
||||
mgr->base.destroy = vmw_gmr_bufmgr_destroy;
|
||||
mgr->base.create_buffer = vmw_gmr_bufmgr_create_buffer;
|
||||
mgr->base.flush = vmw_gmr_bufmgr_flush;
|
||||
|
||||
mgr->vws = vws;
|
||||
|
||||
return &mgr->base;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
|
||||
struct SVGAGuestPtr *ptr)
|
||||
{
|
||||
struct pb_buffer *base_buf;
|
||||
unsigned offset = 0;
|
||||
struct vmw_gmr_buffer *gmr_buf;
|
||||
|
||||
pb_get_base_buffer( buf, &base_buf, &offset );
|
||||
|
||||
gmr_buf = vmw_gmr_buffer(base_buf);
|
||||
if(!gmr_buf)
|
||||
return FALSE;
|
||||
|
||||
*ptr = vmw_ioctl_region_ptr(gmr_buf->region);
|
||||
|
||||
ptr->offset += offset;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
65
src/gallium/winsys/drm/vmware/core/vmw_buffer.h
Normal file
65
src/gallium/winsys/drm/vmware/core/vmw_buffer.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#ifndef VMW_BUFFER_H_
|
||||
#define VMW_BUFFER_H_
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct SVGAGuestPtr;
|
||||
struct pb_buffer;
|
||||
struct pb_manager;
|
||||
struct svga_winsys_buffer;
|
||||
struct svga_winsys_surface;
|
||||
struct vmw_winsys_screen;
|
||||
|
||||
|
||||
static INLINE struct pb_buffer *
|
||||
vmw_pb_buffer(struct svga_winsys_buffer *buffer)
|
||||
{
|
||||
assert(buffer);
|
||||
return (struct pb_buffer *)buffer;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct svga_winsys_buffer *
|
||||
vmw_svga_winsys_buffer(struct pb_buffer *buffer)
|
||||
{
|
||||
assert(buffer);
|
||||
return (struct svga_winsys_buffer *)buffer;
|
||||
}
|
||||
|
||||
|
||||
struct pb_manager *
|
||||
vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws);
|
||||
|
||||
boolean
|
||||
vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
|
||||
struct SVGAGuestPtr *ptr);
|
||||
|
||||
|
||||
#endif /* VMW_BUFFER_H_ */
|
||||
297
src/gallium/winsys/drm/vmware/core/vmw_context.c
Normal file
297
src/gallium/winsys/drm/vmware/core/vmw_context.c
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_debug_stack.h"
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_validate.h"
|
||||
|
||||
#include "svga_winsys.h"
|
||||
#include "vmw_context.h"
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_buffer.h"
|
||||
#include "vmw_surface.h"
|
||||
#include "vmw_fence.h"
|
||||
|
||||
#define VMW_COMMAND_SIZE (64*1024)
|
||||
#define VMW_SURFACE_RELOCS (1024)
|
||||
|
||||
#define VMW_MUST_FLUSH_STACK 8
|
||||
|
||||
struct vmw_svga_winsys_context
|
||||
{
|
||||
struct svga_winsys_context base;
|
||||
|
||||
struct vmw_winsys_screen *vws;
|
||||
|
||||
#ifdef DEBUG
|
||||
boolean must_flush;
|
||||
struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK];
|
||||
#endif
|
||||
|
||||
struct {
|
||||
uint8_t buffer[VMW_COMMAND_SIZE];
|
||||
uint32_t size;
|
||||
uint32_t used;
|
||||
uint32_t reserved;
|
||||
} command;
|
||||
|
||||
struct {
|
||||
struct vmw_svga_winsys_surface *handles[VMW_SURFACE_RELOCS];
|
||||
uint32_t size;
|
||||
uint32_t used;
|
||||
uint32_t staged;
|
||||
uint32_t reserved;
|
||||
} surface;
|
||||
|
||||
struct pb_validate *validate;
|
||||
|
||||
uint32_t last_fence;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct vmw_svga_winsys_context *
|
||||
vmw_svga_winsys_context(struct svga_winsys_context *swc)
|
||||
{
|
||||
assert(swc);
|
||||
return (struct vmw_svga_winsys_context *)swc;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
vmw_swc_flush(struct svga_winsys_context *swc,
|
||||
struct pipe_fence_handle **pfence)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
unsigned i;
|
||||
enum pipe_error ret;
|
||||
|
||||
ret = pb_validate_validate(vswc->validate);
|
||||
assert(ret == PIPE_OK);
|
||||
if(ret == PIPE_OK) {
|
||||
|
||||
if (vswc->command.used)
|
||||
vmw_ioctl_command(vswc->vws,
|
||||
vswc->command.buffer,
|
||||
vswc->command.used,
|
||||
&vswc->last_fence);
|
||||
|
||||
fence = vmw_pipe_fence(vswc->last_fence);
|
||||
|
||||
pb_validate_fence(vswc->validate, fence);
|
||||
}
|
||||
|
||||
vswc->command.used = 0;
|
||||
vswc->command.reserved = 0;
|
||||
|
||||
for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) {
|
||||
struct vmw_svga_winsys_surface *vsurf =
|
||||
vswc->surface.handles[i];
|
||||
p_atomic_dec(&vsurf->validated);
|
||||
vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
|
||||
}
|
||||
|
||||
vswc->surface.used = 0;
|
||||
vswc->surface.reserved = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
vswc->must_flush = FALSE;
|
||||
#endif
|
||||
|
||||
if(pfence)
|
||||
*pfence = fence;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vmw_swc_reserve(struct svga_winsys_context *swc,
|
||||
uint32_t nr_bytes, uint32_t nr_relocs )
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Check if somebody forgot to check the previous failure */
|
||||
if(vswc->must_flush) {
|
||||
debug_printf("Forgot to flush:\n");
|
||||
debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK);
|
||||
assert(!vswc->must_flush);
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(nr_bytes <= vswc->command.size);
|
||||
if(nr_bytes > vswc->command.size)
|
||||
return NULL;
|
||||
|
||||
if(vswc->command.used + nr_bytes > vswc->command.size ||
|
||||
vswc->surface.used + nr_relocs > vswc->surface.size) {
|
||||
#ifdef DEBUG
|
||||
vswc->must_flush = TRUE;
|
||||
debug_backtrace_capture(vswc->must_flush_stack, 1,
|
||||
VMW_MUST_FLUSH_STACK);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(vswc->command.used + nr_bytes <= vswc->command.size);
|
||||
assert(vswc->surface.used + nr_relocs <= vswc->surface.size);
|
||||
|
||||
vswc->command.reserved = nr_bytes;
|
||||
vswc->surface.reserved = nr_relocs;
|
||||
vswc->surface.staged = 0;
|
||||
|
||||
return vswc->command.buffer + vswc->command.used;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_swc_surface_relocation(struct svga_winsys_context *swc,
|
||||
uint32 *where,
|
||||
struct svga_winsys_surface *surface,
|
||||
unsigned flags)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
struct vmw_svga_winsys_surface *vsurf;
|
||||
|
||||
if(!surface) {
|
||||
*where = SVGA3D_INVALID_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(vswc->surface.staged < vswc->surface.reserved);
|
||||
|
||||
vsurf = vmw_svga_winsys_surface(surface);
|
||||
|
||||
*where = vsurf->sid;
|
||||
|
||||
vmw_svga_winsys_surface_reference(&vswc->surface.handles[vswc->surface.used + vswc->surface.staged], vsurf);
|
||||
p_atomic_inc(&vsurf->validated);
|
||||
++vswc->surface.staged;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_swc_region_relocation(struct svga_winsys_context *swc,
|
||||
struct SVGAGuestPtr *where,
|
||||
struct svga_winsys_buffer *buffer,
|
||||
uint32 offset,
|
||||
unsigned flags)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
struct SVGAGuestPtr ptr;
|
||||
struct pb_buffer *buf = vmw_pb_buffer(buffer);
|
||||
enum pipe_error ret;
|
||||
|
||||
if(!vmw_gmr_bufmgr_region_ptr(buf, &ptr))
|
||||
assert(0);
|
||||
|
||||
ptr.offset += offset;
|
||||
|
||||
*where = ptr;
|
||||
|
||||
ret = pb_validate_add_buffer(vswc->validate, buf, flags);
|
||||
/* TODO: Update pipebuffer to reserve buffers and not fail here */
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_swc_commit(struct svga_winsys_context *swc)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
|
||||
assert(vswc->command.reserved);
|
||||
assert(vswc->command.used + vswc->command.reserved <= vswc->command.size);
|
||||
vswc->command.used += vswc->command.reserved;
|
||||
vswc->command.reserved = 0;
|
||||
|
||||
assert(vswc->surface.staged <= vswc->surface.reserved);
|
||||
assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size);
|
||||
vswc->surface.used += vswc->surface.staged;
|
||||
vswc->surface.staged = 0;
|
||||
vswc->surface.reserved = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_swc_destroy(struct svga_winsys_context *swc)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
unsigned i;
|
||||
for(i = 0; i < vswc->surface.used; ++i) {
|
||||
p_atomic_dec(&vswc->surface.handles[i]->validated);
|
||||
vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
|
||||
}
|
||||
pb_validate_destroy(vswc->validate);
|
||||
vmw_ioctl_context_destroy(vswc->vws, swc->cid);
|
||||
FREE(vswc);
|
||||
}
|
||||
|
||||
|
||||
struct svga_winsys_context *
|
||||
vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
struct vmw_svga_winsys_context *vswc;
|
||||
|
||||
vswc = CALLOC_STRUCT(vmw_svga_winsys_context);
|
||||
if(!vswc)
|
||||
return NULL;
|
||||
|
||||
vswc->base.destroy = vmw_swc_destroy;
|
||||
vswc->base.reserve = vmw_swc_reserve;
|
||||
vswc->base.surface_relocation = vmw_swc_surface_relocation;
|
||||
vswc->base.region_relocation = vmw_swc_region_relocation;
|
||||
vswc->base.commit = vmw_swc_commit;
|
||||
vswc->base.flush = vmw_swc_flush;
|
||||
|
||||
vswc->base.cid = vmw_ioctl_context_create(vws);
|
||||
|
||||
vswc->vws = vws;
|
||||
|
||||
vswc->command.size = VMW_COMMAND_SIZE;
|
||||
vswc->surface.size = VMW_SURFACE_RELOCS;
|
||||
|
||||
vswc->validate = pb_validate_create();
|
||||
if(!vswc->validate) {
|
||||
FREE(vswc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &vswc->base;
|
||||
}
|
||||
|
||||
|
||||
struct pipe_context *
|
||||
vmw_svga_context_create(struct pipe_screen *screen)
|
||||
{
|
||||
return svga_context_create(screen);
|
||||
}
|
||||
59
src/gallium/winsys/drm/vmware/core/vmw_context.h
Normal file
59
src/gallium/winsys/drm/vmware/core/vmw_context.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VMW_CONTEXT_H_
|
||||
#define VMW_CONTEXT_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct svga_winsys_screen;
|
||||
struct svga_winsys_context;
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
|
||||
#define VMW_DEBUG 0
|
||||
|
||||
#if VMW_DEBUG
|
||||
#define vmw_printf debug_printf
|
||||
#define VMW_FUNC debug_printf("%s\n", __FUNCTION__)
|
||||
#else
|
||||
#define VMW_FUNC
|
||||
#define vmw_printf(...)
|
||||
#endif
|
||||
|
||||
|
||||
struct svga_winsys_context *
|
||||
vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
|
||||
|
||||
struct pipe_context *
|
||||
vmw_svga_context_create(struct pipe_screen *screen);
|
||||
|
||||
|
||||
#endif /* VMW_CONTEXT_H_ */
|
||||
108
src/gallium/winsys/drm/vmware/core/vmw_fence.c
Normal file
108
src/gallium/winsys/drm/vmware/core/vmw_fence.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "pipebuffer/pb_buffer_fenced.h"
|
||||
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_fence.h"
|
||||
|
||||
|
||||
|
||||
struct vmw_fence_ops
|
||||
{
|
||||
struct pb_fence_ops base;
|
||||
|
||||
struct vmw_winsys_screen *vws;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct vmw_fence_ops *
|
||||
vmw_fence_ops(struct pb_fence_ops *ops)
|
||||
{
|
||||
assert(ops);
|
||||
return (struct vmw_fence_ops *)ops;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_fence_ops_fence_reference(struct pb_fence_ops *ops,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
*ptr = fence;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vmw_fence_ops_fence_signalled(struct pb_fence_ops *ops,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vmw_fence_ops_fence_finish(struct pb_fence_ops *ops,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_fence_ops_destroy(struct pb_fence_ops *ops)
|
||||
{
|
||||
FREE(ops);
|
||||
}
|
||||
|
||||
|
||||
struct pb_fence_ops *
|
||||
vmw_fence_ops_create(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
struct vmw_fence_ops *ops;
|
||||
|
||||
ops = CALLOC_STRUCT(vmw_fence_ops);
|
||||
if(!ops)
|
||||
return NULL;
|
||||
|
||||
ops->base.destroy = &vmw_fence_ops_destroy;
|
||||
ops->base.fence_reference = &vmw_fence_ops_fence_reference;
|
||||
ops->base.fence_signalled = &vmw_fence_ops_fence_signalled;
|
||||
ops->base.fence_finish = &vmw_fence_ops_fence_finish;
|
||||
|
||||
ops->vws = vws;
|
||||
|
||||
return &ops->base;
|
||||
}
|
||||
|
||||
|
||||
59
src/gallium/winsys/drm/vmware/core/vmw_fence.h
Normal file
59
src/gallium/winsys/drm/vmware/core/vmw_fence.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#ifndef VMW_FENCE_H_
|
||||
#define VMW_FENCE_H_
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
|
||||
struct pipe_fence_handle;
|
||||
struct pb_fence_ops;
|
||||
struct vmw_winsys_screen;
|
||||
|
||||
|
||||
/** Cast from a pipe_fence_handle pointer into a SVGA fence */
|
||||
static INLINE uint32_t
|
||||
vmw_fence( struct pipe_fence_handle *fence )
|
||||
{
|
||||
return (uint32_t)(uintptr_t)fence;
|
||||
}
|
||||
|
||||
|
||||
/** Cast from a SVGA fence number to pipe_fence_handle pointer */
|
||||
static INLINE struct pipe_fence_handle *
|
||||
vmw_pipe_fence( uint32_t fence )
|
||||
{
|
||||
return (struct pipe_fence_handle *)(uintptr_t)fence;
|
||||
}
|
||||
|
||||
|
||||
struct pb_fence_ops *
|
||||
vmw_fence_ops_create(struct vmw_winsys_screen *vws);
|
||||
|
||||
|
||||
#endif /* VMW_FENCE_H_ */
|
||||
74
src/gallium/winsys/drm/vmware/core/vmw_screen.c
Normal file
74
src/gallium/winsys/drm/vmware/core/vmw_screen.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "vmw_screen.h"
|
||||
|
||||
#include "vmw_context.h"
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
|
||||
/* Called from vmw_drm_create_screen(), creates and initializes the
|
||||
* vmw_winsys_screen structure, which is the main entity in this
|
||||
* module.
|
||||
*/
|
||||
struct vmw_winsys_screen *
|
||||
vmw_winsys_create( int fd )
|
||||
{
|
||||
struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
|
||||
if (!vws)
|
||||
goto out_no_vws;
|
||||
|
||||
vws->ioctl.drm_fd = fd;
|
||||
|
||||
if (!vmw_ioctl_init(vws))
|
||||
goto out_no_ioctl;
|
||||
|
||||
if(!vmw_pools_init(vws))
|
||||
goto out_no_pools;
|
||||
|
||||
if (!vmw_winsys_screen_init_svga(vws))
|
||||
goto out_no_svga;
|
||||
|
||||
return vws;
|
||||
out_no_svga:
|
||||
vmw_pools_cleanup(vws);
|
||||
out_no_pools:
|
||||
vmw_ioctl_cleanup(vws);
|
||||
out_no_ioctl:
|
||||
FREE(vws);
|
||||
out_no_vws:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_winsys_destroy(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
vmw_pools_cleanup(vws);
|
||||
vmw_ioctl_cleanup(vws);
|
||||
FREE(vws);
|
||||
}
|
||||
134
src/gallium/winsys/drm/vmware/core/vmw_screen.h
Normal file
134
src/gallium/winsys/drm/vmware/core/vmw_screen.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Common definitions for the VMware SVGA winsys.
|
||||
*
|
||||
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VMW_SCREEN_H_
|
||||
#define VMW_SCREEN_H_
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "svga_winsys.h"
|
||||
|
||||
struct pb_manager;
|
||||
struct vmw_region;
|
||||
|
||||
|
||||
struct vmw_winsys_screen
|
||||
{
|
||||
struct svga_winsys_screen base;
|
||||
|
||||
struct {
|
||||
volatile uint32_t *fifo_map;
|
||||
uint64_t last_fence;
|
||||
int drm_fd;
|
||||
} ioctl;
|
||||
|
||||
struct {
|
||||
struct pb_manager *gmr;
|
||||
struct pb_manager *gmr_mm;
|
||||
struct pb_manager *gmr_fenced;
|
||||
} pools;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct vmw_winsys_screen *
|
||||
vmw_winsys_screen(struct svga_winsys_screen *base)
|
||||
{
|
||||
return (struct vmw_winsys_screen *)base;
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32
|
||||
vmw_ioctl_context_create(struct vmw_winsys_screen *vws);
|
||||
|
||||
void
|
||||
vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws,
|
||||
uint32 cid);
|
||||
|
||||
uint32
|
||||
vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
|
||||
SVGA3dSurfaceFlags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
SVGA3dSize size,
|
||||
uint32 numFaces,
|
||||
uint32 numMipLevels);
|
||||
|
||||
void
|
||||
vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
|
||||
uint32 sid);
|
||||
|
||||
void
|
||||
vmw_ioctl_command(struct vmw_winsys_screen *vws,
|
||||
void *commands,
|
||||
uint32_t size,
|
||||
uint32_t *fence);
|
||||
|
||||
struct vmw_region *
|
||||
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
|
||||
|
||||
void
|
||||
vmw_ioctl_region_destroy(struct vmw_region *region);
|
||||
|
||||
struct SVGAGuestPtr
|
||||
vmw_ioctl_region_ptr(struct vmw_region *region);
|
||||
|
||||
void *
|
||||
vmw_ioctl_region_map(struct vmw_region *region);
|
||||
void
|
||||
vmw_ioctl_region_unmap(struct vmw_region *region);
|
||||
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence);
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence);
|
||||
|
||||
|
||||
/* Initialize parts of vmw_winsys_screen at startup:
|
||||
*/
|
||||
boolean vmw_ioctl_init(struct vmw_winsys_screen *vws);
|
||||
boolean vmw_pools_init(struct vmw_winsys_screen *vws);
|
||||
boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
|
||||
|
||||
void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
|
||||
void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
|
||||
|
||||
struct vmw_winsys_screen *vmw_winsys_create(int fd);
|
||||
void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
|
||||
|
||||
|
||||
#endif /* VMW_SCREEN_H_ */
|
||||
371
src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
Normal file
371
src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "vmw_screen.h"
|
||||
|
||||
#include "trace/tr_drm.h"
|
||||
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_surface.h"
|
||||
#include "vmw_fence.h"
|
||||
#include "vmw_context.h"
|
||||
|
||||
#include <state_tracker/dri1_api.h>
|
||||
#include <state_tracker/drm_api.h>
|
||||
#include <vmwgfx_drm.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static struct dri1_api dri1_api_hooks;
|
||||
static struct dri1_api_version ddx_required = { 0, 1, 0 };
|
||||
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
|
||||
static struct dri1_api_version dri_required = { 4, 0, 0 };
|
||||
static struct dri1_api_version dri_compat = { 4, 0, 0 };
|
||||
static struct dri1_api_version drm_required = { 0, 1, 0 };
|
||||
static struct dri1_api_version drm_compat = { 0, 0, 0 };
|
||||
|
||||
static boolean
|
||||
vmw_dri1_check_version(const struct dri1_api_version *cur,
|
||||
const struct dri1_api_version *required,
|
||||
const struct dri1_api_version *compat,
|
||||
const char component[])
|
||||
{
|
||||
if (cur->major > required->major && cur->major <= compat->major)
|
||||
return TRUE;
|
||||
if (cur->major == required->major && cur->minor >= required->minor)
|
||||
return TRUE;
|
||||
|
||||
fprintf(stderr, "%s version failure.\n", component);
|
||||
fprintf(stderr, "%s version is %d.%d.%d and this driver can only work\n"
|
||||
"with versions %d.%d.x through %d.x.x.\n",
|
||||
component,
|
||||
cur->major,
|
||||
cur->minor,
|
||||
cur->patch_level, required->major, required->minor, compat->major);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This is actually the entrypoint to the entire driver, called by the
|
||||
* libGL (or EGL, or ...) code via the drm_api_hooks table at the
|
||||
* bottom of the file.
|
||||
*/
|
||||
static struct pipe_screen *
|
||||
vmw_drm_create_screen(struct drm_api *drm_api,
|
||||
int fd,
|
||||
struct drm_create_screen_arg *arg)
|
||||
{
|
||||
struct vmw_winsys_screen *vws;
|
||||
struct pipe_screen *screen;
|
||||
struct dri1_create_screen_arg *dri1;
|
||||
|
||||
if (arg != NULL) {
|
||||
switch (arg->mode) {
|
||||
case DRM_CREATE_NORMAL:
|
||||
break;
|
||||
case DRM_CREATE_DRI1:
|
||||
dri1 = (struct dri1_create_screen_arg *)arg;
|
||||
if (!vmw_dri1_check_version(&dri1->ddx_version, &ddx_required,
|
||||
&ddx_compat, "ddx - driver api"))
|
||||
return NULL;
|
||||
if (!vmw_dri1_check_version(&dri1->dri_version, &dri_required,
|
||||
&dri_compat, "dri info"))
|
||||
return NULL;
|
||||
if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
|
||||
&drm_compat, "vmwgfx drm driver"))
|
||||
return NULL;
|
||||
dri1->api = &dri1_api_hooks;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
vws = vmw_winsys_create( fd );
|
||||
if (!vws)
|
||||
goto out_no_vws;
|
||||
|
||||
screen = svga_screen_create( &vws->base );
|
||||
if (!screen)
|
||||
goto out_no_screen;
|
||||
|
||||
return screen;
|
||||
|
||||
/* Failure cases:
|
||||
*/
|
||||
out_no_screen:
|
||||
vmw_winsys_destroy( vws );
|
||||
|
||||
out_no_vws:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
vmw_dri1_intersect_src_bbox(struct drm_clip_rect *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const struct drm_clip_rect *src,
|
||||
const struct drm_clip_rect *bbox)
|
||||
{
|
||||
int xy1;
|
||||
int xy2;
|
||||
|
||||
xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
|
||||
(int)bbox->x1 + dst_x;
|
||||
xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
|
||||
(int)bbox->x2 + dst_x;
|
||||
if (xy1 >= xy2 || xy1 < 0)
|
||||
return FALSE;
|
||||
|
||||
dst->x1 = xy1;
|
||||
dst->x2 = xy2;
|
||||
|
||||
xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
|
||||
(int)bbox->y1 + dst_y;
|
||||
xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
|
||||
(int)bbox->y2 + dst_y;
|
||||
if (xy1 >= xy2 || xy1 < 0)
|
||||
return FALSE;
|
||||
|
||||
dst->y1 = xy1;
|
||||
dst->y2 = xy2;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* No fancy get-surface-from-sarea stuff here.
|
||||
* Just use the present blit.
|
||||
*/
|
||||
|
||||
static void
|
||||
vmw_dri1_present_locked(struct pipe_context *locked_pipe,
|
||||
struct pipe_surface *surf,
|
||||
const struct drm_clip_rect *rect,
|
||||
unsigned int num_clip,
|
||||
int x_draw, int y_draw,
|
||||
const struct drm_clip_rect *bbox,
|
||||
struct pipe_fence_handle **p_fence)
|
||||
{
|
||||
struct svga_winsys_surface *srf =
|
||||
svga_screen_texture_get_winsys_surface(surf->texture);
|
||||
struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
|
||||
struct vmw_winsys_screen *vws =
|
||||
vmw_winsys_screen(svga_winsys_screen(locked_pipe->screen));
|
||||
struct drm_clip_rect clip;
|
||||
int i;
|
||||
struct
|
||||
{
|
||||
SVGA3dCmdHeader header;
|
||||
SVGA3dCmdPresent body;
|
||||
SVGA3dCopyRect rect;
|
||||
} cmd;
|
||||
boolean visible = FALSE;
|
||||
uint32_t fence_seq = 0;
|
||||
|
||||
VMW_FUNC;
|
||||
cmd.header.id = SVGA_3D_CMD_PRESENT;
|
||||
cmd.header.size = sizeof cmd.body + sizeof cmd.rect;
|
||||
cmd.body.sid = vsrf->sid;
|
||||
|
||||
for (i = 0; i < num_clip; ++i) {
|
||||
if (!vmw_dri1_intersect_src_bbox(&clip, x_draw, y_draw, rect++, bbox))
|
||||
continue;
|
||||
|
||||
cmd.rect.x = clip.x1;
|
||||
cmd.rect.y = clip.y1;
|
||||
cmd.rect.w = clip.x2 - clip.x1;
|
||||
cmd.rect.h = clip.y2 - clip.y1;
|
||||
cmd.rect.srcx = (int)clip.x1 - x_draw;
|
||||
cmd.rect.srcy = (int)clip.y1 - y_draw;
|
||||
|
||||
vmw_printf("%s: Clip %d x %d y %d w %d h %d srcx %d srcy %d\n",
|
||||
__FUNCTION__,
|
||||
i,
|
||||
cmd.rect.x,
|
||||
cmd.rect.y,
|
||||
cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy);
|
||||
|
||||
vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size,
|
||||
&fence_seq);
|
||||
visible = TRUE;
|
||||
}
|
||||
|
||||
*p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL;
|
||||
vmw_svga_winsys_surface_reference(&vsrf, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: We'd probably want to cache these buffers in the
|
||||
* screen, based on handle.
|
||||
*/
|
||||
|
||||
static struct pipe_buffer *
|
||||
vmw_drm_buffer_from_handle(struct drm_api *drm_api,
|
||||
struct pipe_screen *screen,
|
||||
const char *name,
|
||||
unsigned handle)
|
||||
{
|
||||
struct vmw_svga_winsys_surface *vsrf;
|
||||
struct svga_winsys_surface *ssrf;
|
||||
struct vmw_winsys_screen *vws =
|
||||
vmw_winsys_screen(svga_winsys_screen(screen));
|
||||
struct pipe_buffer *buf;
|
||||
union drm_vmw_surface_reference_arg arg;
|
||||
struct drm_vmw_surface_arg *req = &arg.req;
|
||||
struct drm_vmw_surface_create_req *rep = &arg.rep;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* The vmware device specific handle is the hardware SID.
|
||||
* FIXME: We probably want to move this to the ioctl implementations.
|
||||
*/
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
req->sid = handle;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
|
||||
&arg, sizeof(arg));
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
|
||||
"Error %d (%s).\n",
|
||||
handle, ret, strerror(-ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rep->mip_levels[0] != 1) {
|
||||
fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
|
||||
" SID %d, levels %d\n",
|
||||
handle, rep->mip_levels[0]);
|
||||
goto out_mip;
|
||||
}
|
||||
|
||||
for (i=1; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
|
||||
if (rep->mip_levels[i] != 0) {
|
||||
fprintf(stderr, "Incorrect number of faces levels on shared surface."
|
||||
" SID %d, face %d present.\n",
|
||||
handle, i);
|
||||
goto out_mip;
|
||||
}
|
||||
}
|
||||
|
||||
vsrf = CALLOC_STRUCT(vmw_svga_winsys_surface);
|
||||
if (!vsrf)
|
||||
goto out_mip;
|
||||
|
||||
pipe_reference_init(&vsrf->refcnt, 1);
|
||||
p_atomic_set(&vsrf->validated, 0);
|
||||
vsrf->sid = handle;
|
||||
ssrf = svga_winsys_surface(vsrf);
|
||||
buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf);
|
||||
if (!buf)
|
||||
vmw_svga_winsys_surface_reference(&vsrf, NULL);
|
||||
|
||||
return buf;
|
||||
out_mip:
|
||||
vmw_ioctl_surface_destroy(vws, handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_texture *
|
||||
vmw_drm_texture_from_handle(struct drm_api *drm_api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *templat,
|
||||
const char *name,
|
||||
unsigned stride,
|
||||
unsigned handle)
|
||||
{
|
||||
struct pipe_buffer *buffer;
|
||||
buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle);
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
return screen->texture_blanket(screen, templat, &stride, buffer);
|
||||
}
|
||||
|
||||
static boolean
|
||||
vmw_drm_handle_from_buffer(struct drm_api *drm_api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_buffer *buffer,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct svga_winsys_surface *surface =
|
||||
svga_screen_buffer_get_winsys_surface(buffer);
|
||||
struct vmw_svga_winsys_surface *vsrf;
|
||||
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
|
||||
vsrf = vmw_svga_winsys_surface(surface);
|
||||
*handle = vsrf->sid;
|
||||
vmw_svga_winsys_surface_reference(&vsrf, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
vmw_drm_handle_from_texture(struct drm_api *drm_api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *stride,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct pipe_buffer *buffer;
|
||||
|
||||
if (!svga_screen_buffer_from_texture(texture, &buffer, stride))
|
||||
return FALSE;
|
||||
|
||||
return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle);
|
||||
}
|
||||
|
||||
static struct pipe_context*
|
||||
vmw_drm_create_context(struct drm_api *drm_api,
|
||||
struct pipe_screen *screen)
|
||||
{
|
||||
return vmw_svga_context_create(screen);
|
||||
}
|
||||
|
||||
static struct dri1_api dri1_api_hooks = {
|
||||
.front_srf_locked = NULL,
|
||||
.present_locked = vmw_dri1_present_locked
|
||||
};
|
||||
|
||||
static struct drm_api vmw_drm_api_hooks = {
|
||||
.create_screen = vmw_drm_create_screen,
|
||||
.create_context = vmw_drm_create_context,
|
||||
.texture_from_shared_handle = vmw_drm_texture_from_handle,
|
||||
.shared_handle_from_texture = vmw_drm_handle_from_texture,
|
||||
.local_handle_from_texture = vmw_drm_handle_from_texture,
|
||||
};
|
||||
|
||||
struct drm_api* drm_api_create()
|
||||
{
|
||||
return trace_drm_create(&vmw_drm_api_hooks);
|
||||
}
|
||||
503
src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
Normal file
503
src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Wrappers for DRM ioctl functionlaity used by the rest of the vmw
|
||||
* drm winsys.
|
||||
*
|
||||
* Based on svgaicd_escape.c
|
||||
*/
|
||||
|
||||
|
||||
#include "svga_cmd.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
#include "svgadump/svga_dump.h"
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_context.h"
|
||||
#include "xf86drm.h"
|
||||
#include "vmwgfx_drm.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct vmw_region
|
||||
{
|
||||
SVGAGuestPtr ptr;
|
||||
uint32_t handle;
|
||||
uint64_t map_handle;
|
||||
void *data;
|
||||
uint32_t map_count;
|
||||
int drm_fd;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
static void
|
||||
vmw_check_last_cmd(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
static uint32_t buffer[16384];
|
||||
struct drm_vmw_fifo_debug_arg arg;
|
||||
int ret;
|
||||
|
||||
return;
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.debug_buffer = (unsigned long)buffer;
|
||||
arg.debug_buffer_size = 65536;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FIFO_DEBUG,
|
||||
&arg, sizeof(arg));
|
||||
|
||||
if (ret) {
|
||||
debug_printf("%s Ioctl error: \"%s\".\n", __FUNCTION__, strerror(-ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg.did_not_fit) {
|
||||
debug_printf("%s Command did not fit completely.\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
svga_dump_commands(buffer, arg.used_size);
|
||||
}
|
||||
|
||||
static void
|
||||
vmw_ioctl_fifo_unmap(struct vmw_winsys_screen *vws, void *mapping)
|
||||
{
|
||||
VMW_FUNC;
|
||||
(void)munmap(mapping, getpagesize());
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vmw_ioctl_fifo_map(struct vmw_winsys_screen *vws,
|
||||
uint32_t fifo_offset )
|
||||
{
|
||||
void *map;
|
||||
|
||||
VMW_FUNC;
|
||||
|
||||
map = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED,
|
||||
vws->ioctl.drm_fd, fifo_offset);
|
||||
|
||||
if (map == MAP_FAILED) {
|
||||
debug_printf("Map failed %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vmw_printf("Fifo (min) is 0x%08x\n", ((uint32_t *) map)[SVGA_FIFO_MIN]);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
uint32
|
||||
vmw_ioctl_context_create(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
struct drm_vmw_context_arg c_arg;
|
||||
int ret;
|
||||
|
||||
VMW_FUNC;
|
||||
|
||||
ret = drmCommandRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_CONTEXT,
|
||||
&c_arg, sizeof(c_arg));
|
||||
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
vmw_check_last_cmd(vws);
|
||||
vmw_printf("Context id is %d\n", c_arg.cid);
|
||||
|
||||
return c_arg.cid;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
|
||||
{
|
||||
struct drm_vmw_context_arg c_arg;
|
||||
|
||||
VMW_FUNC;
|
||||
|
||||
memset(&c_arg, 0, sizeof(c_arg));
|
||||
c_arg.cid = cid;
|
||||
|
||||
(void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_CONTEXT,
|
||||
&c_arg, sizeof(c_arg));
|
||||
|
||||
vmw_check_last_cmd(vws);
|
||||
}
|
||||
|
||||
uint32
|
||||
vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
|
||||
SVGA3dSurfaceFlags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
SVGA3dSize size,
|
||||
uint32_t numFaces, uint32_t numMipLevels)
|
||||
{
|
||||
union drm_vmw_surface_create_arg s_arg;
|
||||
struct drm_vmw_surface_create_req *req = &s_arg.req;
|
||||
struct drm_vmw_surface_arg *rep = &s_arg.rep;
|
||||
struct drm_vmw_size sizes[DRM_VMW_MAX_SURFACE_FACES*
|
||||
DRM_VMW_MAX_MIP_LEVELS];
|
||||
struct drm_vmw_size *cur_size;
|
||||
uint32_t iFace;
|
||||
uint32_t iMipLevel;
|
||||
int ret;
|
||||
|
||||
vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
|
||||
|
||||
memset(&s_arg, 0, sizeof(s_arg));
|
||||
req->flags = (uint32_t) flags;
|
||||
req->format = (uint32_t) format;
|
||||
req->shareable = 1;
|
||||
|
||||
assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
|
||||
DRM_VMW_MAX_MIP_LEVELS);
|
||||
cur_size = sizes;
|
||||
for (iFace = 0; iFace < numFaces; ++iFace) {
|
||||
SVGA3dSize mipSize = size;
|
||||
|
||||
req->mip_levels[iFace] = numMipLevels;
|
||||
for (iMipLevel = 0; iMipLevel < numMipLevels; ++iMipLevel) {
|
||||
cur_size->width = mipSize.width;
|
||||
cur_size->height = mipSize.height;
|
||||
cur_size->depth = mipSize.depth;
|
||||
mipSize.width = MAX2(mipSize.width >> 1, 1);
|
||||
mipSize.height = MAX2(mipSize.height >> 1, 1);
|
||||
mipSize.depth = MAX2(mipSize.depth >> 1, 1);
|
||||
cur_size++;
|
||||
}
|
||||
}
|
||||
for (iFace = numFaces; iFace < SVGA3D_MAX_SURFACE_FACES; ++iFace) {
|
||||
req->mip_levels[iFace] = 0;
|
||||
}
|
||||
|
||||
req->size_addr = (unsigned long)&sizes;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SURFACE,
|
||||
&s_arg, sizeof(s_arg));
|
||||
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
vmw_printf("Surface id is %d\n", rep->sid);
|
||||
vmw_check_last_cmd(vws);
|
||||
|
||||
return rep->sid;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
|
||||
{
|
||||
struct drm_vmw_surface_arg s_arg;
|
||||
|
||||
VMW_FUNC;
|
||||
|
||||
memset(&s_arg, 0, sizeof(s_arg));
|
||||
s_arg.sid = sid;
|
||||
|
||||
(void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SURFACE,
|
||||
&s_arg, sizeof(s_arg));
|
||||
vmw_check_last_cmd(vws);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
|
||||
uint32_t * pfence)
|
||||
{
|
||||
struct drm_vmw_execbuf_arg arg;
|
||||
struct drm_vmw_fence_rep rep;
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
static boolean firsttime = TRUE;
|
||||
static boolean debug = FALSE;
|
||||
static boolean skip = FALSE;
|
||||
if (firsttime) {
|
||||
debug = debug_get_bool_option("SVGA_DUMP_CMD", FALSE);
|
||||
skip = debug_get_bool_option("SVGA_SKIP_CMD", FALSE);
|
||||
}
|
||||
if (debug) {
|
||||
VMW_FUNC;
|
||||
svga_dump_commands(commands, size);
|
||||
}
|
||||
firsttime = FALSE;
|
||||
if (skip) {
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
memset(&rep, 0, sizeof(rep));
|
||||
|
||||
rep.error = -EFAULT;
|
||||
arg.fence_rep = (unsigned long)&rep;
|
||||
arg.commands = (unsigned long)commands;
|
||||
arg.command_size = size;
|
||||
|
||||
do {
|
||||
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
|
||||
} while(ret == -ERESTART);
|
||||
if (ret) {
|
||||
debug_printf("%s error %s.\n", __FUNCTION__, strerror(-ret));
|
||||
}
|
||||
if (rep.error) {
|
||||
|
||||
/*
|
||||
* Kernel has synced and put the last fence sequence in the FIFO
|
||||
* register.
|
||||
*/
|
||||
|
||||
if (rep.error == -EFAULT)
|
||||
rep.fence_seq = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
|
||||
|
||||
debug_printf("%s Fence error %s.\n", __FUNCTION__,
|
||||
strerror(-rep.error));
|
||||
}
|
||||
|
||||
vws->ioctl.last_fence = rep.fence_seq;
|
||||
|
||||
if (pfence)
|
||||
*pfence = rep.fence_seq;
|
||||
vmw_check_last_cmd(vws);
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct vmw_region *
|
||||
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
|
||||
{
|
||||
struct vmw_region *region;
|
||||
union drm_vmw_alloc_dmabuf_arg arg;
|
||||
struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
|
||||
struct drm_vmw_dmabuf_rep *rep = &arg.rep;
|
||||
int ret;
|
||||
|
||||
vmw_printf("%s: size = %u\n", __FUNCTION__, size);
|
||||
|
||||
region = CALLOC_STRUCT(vmw_region);
|
||||
if (!region)
|
||||
goto out_err1;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
req->size = size;
|
||||
do {
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_ALLOC_DMABUF, &arg,
|
||||
sizeof(arg));
|
||||
} while (ret == -ERESTART);
|
||||
|
||||
if (ret) {
|
||||
debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret));
|
||||
goto out_err1;
|
||||
}
|
||||
|
||||
region->ptr.gmrId = rep->cur_gmr_id;
|
||||
region->ptr.offset = rep->cur_gmr_offset;
|
||||
region->data = NULL;
|
||||
region->handle = rep->handle;
|
||||
region->map_handle = rep->map_handle;
|
||||
region->map_count = 0;
|
||||
region->size = size;
|
||||
region->drm_fd = vws->ioctl.drm_fd;
|
||||
|
||||
vmw_printf(" gmrId = %u, offset = %u\n",
|
||||
region->ptr.gmrId, region->ptr.offset);
|
||||
|
||||
return region;
|
||||
|
||||
out_err1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_region_destroy(struct vmw_region *region)
|
||||
{
|
||||
struct drm_vmw_unref_dmabuf_arg arg;
|
||||
|
||||
vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
|
||||
region->ptr.gmrId, region->ptr.offset);
|
||||
|
||||
if (region->data) {
|
||||
munmap(region->data, region->size);
|
||||
region->data = NULL;
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.handle = region->handle;
|
||||
drmCommandWrite(region->drm_fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg));
|
||||
|
||||
FREE(region);
|
||||
}
|
||||
|
||||
SVGAGuestPtr
|
||||
vmw_ioctl_region_ptr(struct vmw_region *region)
|
||||
{
|
||||
return region->ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
vmw_ioctl_region_map(struct vmw_region *region)
|
||||
{
|
||||
void *map;
|
||||
|
||||
vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
|
||||
region->ptr.gmrId, region->ptr.offset);
|
||||
|
||||
if (region->data == NULL) {
|
||||
map = mmap(NULL, region->size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
region->drm_fd, region->map_handle);
|
||||
if (map == MAP_FAILED) {
|
||||
debug_printf("%s: Map failed.\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
region->data = map;
|
||||
}
|
||||
|
||||
++region->map_count;
|
||||
|
||||
return region->data;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_region_unmap(struct vmw_region *region)
|
||||
{
|
||||
vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
|
||||
region->ptr.gmrId, region->ptr.offset);
|
||||
--region->map_count;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence)
|
||||
{
|
||||
uint32_t expected;
|
||||
uint32_t current;
|
||||
|
||||
assert(fence);
|
||||
if(!fence)
|
||||
return 0;
|
||||
|
||||
expected = fence;
|
||||
current = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
|
||||
|
||||
if ((int32)(current - expected) >= 0)
|
||||
return 0; /* fence passed */
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_ioctl_sync(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence)
|
||||
{
|
||||
uint32_t cur_fence;
|
||||
struct drm_vmw_fence_wait_arg arg;
|
||||
int ret;
|
||||
|
||||
vmw_printf("%s: fence = %lu\n", __FUNCTION__,
|
||||
(unsigned long)fence);
|
||||
|
||||
cur_fence = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
|
||||
vmw_printf("%s: Fence id read is 0x%08x\n", __FUNCTION__,
|
||||
(unsigned int)cur_fence);
|
||||
|
||||
if ((cur_fence - fence) < (1 << 24))
|
||||
return;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.sequence = fence;
|
||||
|
||||
do {
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT, &arg,
|
||||
sizeof(arg));
|
||||
} while (ret == -ERESTART);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence)
|
||||
{
|
||||
assert(fence);
|
||||
|
||||
if(fence) {
|
||||
if(vmw_ioctl_fence_signalled(vws, fence) != 0) {
|
||||
vmw_ioctl_sync(vws, fence);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
struct drm_vmw_getparam_arg gp_arg;
|
||||
int ret;
|
||||
|
||||
VMW_FUNC;
|
||||
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_FIFO_OFFSET;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
&gp_arg, sizeof(gp_arg));
|
||||
|
||||
if (ret) {
|
||||
debug_printf("GET_PARAM on %d returned %d: %s\n",
|
||||
vws->ioctl.drm_fd, ret, strerror(-ret));
|
||||
goto out_err1;
|
||||
}
|
||||
|
||||
vmw_printf("Offset to map is 0x%08llx\n",
|
||||
(unsigned long long)gp_arg.value);
|
||||
|
||||
vws->ioctl.fifo_map = vmw_ioctl_fifo_map(vws, gp_arg.value);
|
||||
if (vws->ioctl.fifo_map == NULL)
|
||||
goto out_err1;
|
||||
|
||||
vmw_printf("%s OK\n", __FUNCTION__);
|
||||
return TRUE;
|
||||
|
||||
out_err1:
|
||||
debug_printf("%s Failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
vmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
VMW_FUNC;
|
||||
|
||||
vmw_ioctl_fifo_unmap(vws, (void *)vws->ioctl.fifo_map);
|
||||
}
|
||||
79
src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
Normal file
79
src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "vmw_screen.h"
|
||||
|
||||
#include "vmw_buffer.h"
|
||||
#include "vmw_fence.h"
|
||||
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
|
||||
void
|
||||
vmw_pools_cleanup(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
if(vws->pools.gmr_fenced)
|
||||
vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced);
|
||||
|
||||
/* gmr_mm pool is already destroyed above */
|
||||
|
||||
if(vws->pools.gmr)
|
||||
vws->pools.gmr->destroy(vws->pools.gmr);
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
vmw_pools_init(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
vws->pools.gmr = vmw_gmr_bufmgr_create(vws);
|
||||
if(!vws->pools.gmr)
|
||||
goto error;
|
||||
|
||||
vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
|
||||
16*1024*1024,
|
||||
12 /* 4096 alignment */);
|
||||
if(!vws->pools.gmr_mm)
|
||||
goto error;
|
||||
|
||||
vws->pools.gmr_fenced = fenced_bufmgr_create(
|
||||
vws->pools.gmr_mm,
|
||||
vmw_fence_ops_create(vws));
|
||||
|
||||
#ifdef DEBUG
|
||||
vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
|
||||
4096,
|
||||
4096);
|
||||
#endif
|
||||
if(!vws->pools.gmr_fenced)
|
||||
goto error;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
vmw_pools_cleanup(vws);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
295
src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
Normal file
295
src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the SVGA interface into this winsys, defined
|
||||
* in drivers/svga/svga_winsys.h.
|
||||
*
|
||||
* @author Keith Whitwell
|
||||
* @author Jose Fonseca
|
||||
*/
|
||||
|
||||
|
||||
#include "svga_cmd.h"
|
||||
#include "svga3d_caps.h"
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
#include "svga_winsys.h"
|
||||
#include "vmw_context.h"
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_surface.h"
|
||||
#include "vmw_buffer.h"
|
||||
#include "vmw_fence.h"
|
||||
|
||||
|
||||
static struct svga_winsys_buffer *
|
||||
vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
struct pb_desc desc;
|
||||
struct pb_manager *provider;
|
||||
struct pb_buffer *buffer;
|
||||
|
||||
memset(&desc, 0, sizeof desc);
|
||||
desc.alignment = alignment;
|
||||
desc.usage = usage;
|
||||
|
||||
provider = vws->pools.gmr_fenced;
|
||||
|
||||
assert(provider);
|
||||
buffer = provider->create_buffer(provider, size, &desc);
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
return vmw_svga_winsys_buffer(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
(void)sws;
|
||||
return pb_map(vmw_pb_buffer(buf), flags);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_svga_winsys_buffer_unmap(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_buffer *buf)
|
||||
{
|
||||
(void)sws;
|
||||
pb_unmap(vmw_pb_buffer(buf));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_svga_winsys_buffer_destroy(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_buffer *buf)
|
||||
{
|
||||
struct pb_buffer *pbuf = vmw_pb_buffer(buf);
|
||||
(void)sws;
|
||||
pb_reference(&pbuf, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_svga_winsys_fence_reference(struct svga_winsys_screen *sws,
|
||||
struct pipe_fence_handle **pdst,
|
||||
struct pipe_fence_handle *src)
|
||||
{
|
||||
(void)sws;
|
||||
*pdst = src;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vmw_svga_winsys_fence_signalled(struct svga_winsys_screen *sws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct svga_winsys_surface *
|
||||
vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
|
||||
SVGA3dSurfaceFlags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
SVGA3dSize size,
|
||||
uint32 numFaces,
|
||||
uint32 numMipLevels)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
struct vmw_svga_winsys_surface *surface;
|
||||
|
||||
surface = CALLOC_STRUCT(vmw_svga_winsys_surface);
|
||||
if(!surface)
|
||||
goto no_surface;
|
||||
|
||||
pipe_reference_init(&surface->refcnt, 1);
|
||||
p_atomic_set(&surface->validated, 0);
|
||||
surface->screen = vws;
|
||||
surface->sid = vmw_ioctl_surface_create(vws,
|
||||
flags, format, size,
|
||||
numFaces, numMipLevels);
|
||||
if(surface->sid == SVGA3D_INVALID_ID)
|
||||
goto no_sid;
|
||||
|
||||
return svga_winsys_surface(surface);
|
||||
|
||||
no_sid:
|
||||
FREE(surface);
|
||||
no_surface:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_surface *surface)
|
||||
{
|
||||
struct vmw_svga_winsys_surface *vsurf = vmw_svga_winsys_surface(surface);
|
||||
return (p_atomic_read(&vsurf->validated) == 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_svga_winsys_surface_ref(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_surface **pDst,
|
||||
struct svga_winsys_surface *src)
|
||||
{
|
||||
struct vmw_svga_winsys_surface *d_vsurf = vmw_svga_winsys_surface(*pDst);
|
||||
struct vmw_svga_winsys_surface *s_vsurf = vmw_svga_winsys_surface(src);
|
||||
|
||||
vmw_svga_winsys_surface_reference(&d_vsurf, s_vsurf);
|
||||
*pDst = svga_winsys_surface(d_vsurf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_svga_winsys_destroy(struct svga_winsys_screen *sws)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
|
||||
vmw_winsys_destroy(vws);
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
vmw_svga_winsys_get_cap(struct svga_winsys_screen *sws,
|
||||
SVGA3dDevCapIndex index,
|
||||
SVGA3dDevCapResult *result)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
const uint32 *capsBlock;
|
||||
const SVGA3dCapsRecord *capsRecord = NULL;
|
||||
uint32 offset;
|
||||
const SVGA3dCapPair *capArray;
|
||||
int numCaps, first, last;
|
||||
|
||||
if(!vws->ioctl.fifo_map)
|
||||
return FALSE;
|
||||
|
||||
if(vws->ioctl.fifo_map[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS6_B1)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Search linearly through the caps block records for the specified type.
|
||||
*/
|
||||
capsBlock = (const uint32 *)&vws->ioctl.fifo_map[SVGA_FIFO_3D_CAPS];
|
||||
for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
|
||||
const SVGA3dCapsRecord *record;
|
||||
assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
|
||||
record = (const SVGA3dCapsRecord *) (capsBlock + offset);
|
||||
if ((record->header.type >= SVGA3DCAPS_RECORD_DEVCAPS_MIN) &&
|
||||
(record->header.type <= SVGA3DCAPS_RECORD_DEVCAPS_MAX) &&
|
||||
(!capsRecord || (record->header.type > capsRecord->header.type))) {
|
||||
capsRecord = record;
|
||||
}
|
||||
}
|
||||
|
||||
if(!capsRecord)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Calculate the number of caps from the size of the record.
|
||||
*/
|
||||
capArray = (const SVGA3dCapPair *) capsRecord->data;
|
||||
numCaps = (int) ((capsRecord->header.length * sizeof(uint32) -
|
||||
sizeof capsRecord->header) / (2 * sizeof(uint32)));
|
||||
|
||||
/*
|
||||
* Binary-search for the cap with the specified index.
|
||||
*/
|
||||
for (first = 0, last = numCaps - 1; first <= last; ) {
|
||||
int mid = (first + last) / 2;
|
||||
|
||||
if ((SVGA3dDevCapIndex) capArray[mid][0] == index) {
|
||||
/*
|
||||
* Found it.
|
||||
*/
|
||||
result->u = capArray[mid][1];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Divide and conquer.
|
||||
*/
|
||||
if ((SVGA3dDevCapIndex) capArray[mid][0] > index) {
|
||||
last = mid - 1;
|
||||
} else {
|
||||
first = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
vws->base.destroy = vmw_svga_winsys_destroy;
|
||||
vws->base.get_cap = vmw_svga_winsys_get_cap;
|
||||
vws->base.context_create = vmw_svga_winsys_context_create;
|
||||
vws->base.surface_create = vmw_svga_winsys_surface_create;
|
||||
vws->base.surface_is_flushed = vmw_svga_winsys_surface_is_flushed;
|
||||
vws->base.surface_reference = vmw_svga_winsys_surface_ref;
|
||||
vws->base.buffer_create = vmw_svga_winsys_buffer_create;
|
||||
vws->base.buffer_map = vmw_svga_winsys_buffer_map;
|
||||
vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap;
|
||||
vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy;
|
||||
vws->base.fence_reference = vmw_svga_winsys_fence_reference;
|
||||
vws->base.fence_signalled = vmw_svga_winsys_fence_signalled;
|
||||
vws->base.fence_finish = vmw_svga_winsys_fence_finish;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
59
src/gallium/winsys/drm/vmware/core/vmw_surface.c
Normal file
59
src/gallium/winsys/drm/vmware/core/vmw_surface.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
|
||||
#include "svga_cmd.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "vmw_surface.h"
|
||||
#include "vmw_screen.h"
|
||||
|
||||
void
|
||||
vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
|
||||
struct vmw_svga_winsys_surface *src)
|
||||
{
|
||||
struct pipe_reference *src_ref;
|
||||
struct pipe_reference *dst_ref;
|
||||
struct vmw_svga_winsys_surface *dst = *pdst;
|
||||
|
||||
if(*pdst == src || pdst == NULL)
|
||||
return;
|
||||
|
||||
src_ref = src ? &src->refcnt : NULL;
|
||||
dst_ref = dst ? &dst->refcnt : NULL;
|
||||
|
||||
if (pipe_reference(&dst_ref, src_ref)) {
|
||||
vmw_ioctl_surface_destroy(dst->screen, dst->sid);
|
||||
#ifdef DEBUG
|
||||
/* to detect dangling pointers */
|
||||
assert(p_atomic_read(&dst->validated) == 0);
|
||||
dst->sid = SVGA3D_INVALID_ID;
|
||||
#endif
|
||||
FREE(dst);
|
||||
}
|
||||
|
||||
*pdst = src;
|
||||
}
|
||||
79
src/gallium/winsys/drm/vmware/core/vmw_surface.h
Normal file
79
src/gallium/winsys/drm/vmware/core/vmw_surface.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Surfaces for VMware SVGA winsys.
|
||||
*
|
||||
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VMW_SURFACE_H_
|
||||
#define VMW_SURFACE_H_
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_atomic.h"
|
||||
#include "pipe/p_refcnt.h"
|
||||
|
||||
#define VMW_MAX_PRESENTS 3
|
||||
|
||||
|
||||
|
||||
struct vmw_svga_winsys_surface
|
||||
{
|
||||
struct pipe_atomic validated;
|
||||
struct pipe_reference refcnt;
|
||||
|
||||
struct vmw_winsys_screen *screen;
|
||||
uint32_t sid;
|
||||
|
||||
/* FIXME: make this thread safe */
|
||||
unsigned next_present_no;
|
||||
uint32_t present_fences[VMW_MAX_PRESENTS];
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct svga_winsys_surface *
|
||||
svga_winsys_surface(struct vmw_svga_winsys_surface *surf)
|
||||
{
|
||||
assert(!surf || surf->sid != SVGA3D_INVALID_ID);
|
||||
return (struct svga_winsys_surface *)surf;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct vmw_svga_winsys_surface *
|
||||
vmw_svga_winsys_surface(struct svga_winsys_surface *surf)
|
||||
{
|
||||
return (struct vmw_svga_winsys_surface *)surf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
|
||||
struct vmw_svga_winsys_surface *src);
|
||||
|
||||
#endif /* VMW_SURFACE_H_ */
|
||||
18
src/gallium/winsys/drm/vmware/dri/Makefile
Normal file
18
src/gallium/winsys/drm/vmware/dri/Makefile
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = vmwgfx_dri.so
|
||||
|
||||
PIPE_DRIVERS = \
|
||||
$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
|
||||
$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
|
||||
$(TOP)/src/gallium/drivers/trace/libtrace.a \
|
||||
$(TOP)/src/gallium/drivers/svga/libsvga.a
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_GALLIUM_SOURCES)
|
||||
|
||||
include ../../Makefile.template
|
||||
|
||||
symlinks:
|
||||
63
src/gallium/winsys/drm/vmware/dri/SConscript
Normal file
63
src/gallium/winsys/drm/vmware/dri/SConscript
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import os
|
||||
import os.path
|
||||
|
||||
Import('*')
|
||||
|
||||
if env['platform'] == 'linux':
|
||||
|
||||
if env['dri']:
|
||||
env = env.Clone()
|
||||
|
||||
sources = [
|
||||
'#/src/mesa/drivers/dri/common/utils.c',
|
||||
'#/src/mesa/drivers/dri/common/vblank.c',
|
||||
'#/src/mesa/drivers/dri/common/dri_util.c',
|
||||
'#/src/mesa/drivers/dri/common/xmlconfig.c',
|
||||
]
|
||||
|
||||
|
||||
env.ParseConfig('pkg-config --cflags --libs libdrm')
|
||||
|
||||
env.Prepend(CPPPATH = [
|
||||
'#/src/mesa/state_tracker',
|
||||
'#/src/mesa/drivers/dri/common',
|
||||
'#/src/mesa/main',
|
||||
'#/src/mesa/glapi',
|
||||
'#/src/mesa',
|
||||
'#/include',
|
||||
'#/src/gallium/drivers/svga',
|
||||
'#/src/gallium/drivers/svga/include',
|
||||
])
|
||||
|
||||
env.Append(CPPDEFINES = [
|
||||
'HAVE_STDINT_H',
|
||||
'HAVE_SYS_TYPES_H',
|
||||
])
|
||||
|
||||
env.Append(CFLAGS = [
|
||||
'-Werror',
|
||||
'-std=gnu99',
|
||||
'-D_FILE_OFFSET_BITS=64',
|
||||
])
|
||||
|
||||
env.Prepend(LIBPATH = [
|
||||
])
|
||||
|
||||
env.Prepend(LIBS = [
|
||||
trace,
|
||||
st_dri,
|
||||
svgadrm,
|
||||
svga,
|
||||
mesa,
|
||||
auxiliaries,
|
||||
])
|
||||
|
||||
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
|
||||
env.LoadableModule(
|
||||
target ='vmwgfx_dri.so',
|
||||
source = sources,
|
||||
LIBS = env['LIBS'],
|
||||
SHLIBPREFIX = '',
|
||||
)
|
||||
|
||||
|
||||
18
src/gallium/winsys/drm/vmware/egl/Makefile
Normal file
18
src/gallium/winsys/drm/vmware/egl/Makefile
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
TOP = ../../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = EGL_svga.so
|
||||
|
||||
PIPE_DRIVERS = \
|
||||
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
|
||||
$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
|
||||
$(TOP)/src/gallium/drivers/trace/libtrace.a \
|
||||
$(TOP)/src/gallium/drivers/svga/libsvga.a
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_GALLIUM_SOURCES)
|
||||
|
||||
include ../../Makefile.template
|
||||
|
||||
symlinks:
|
||||
54
src/gallium/winsys/drm/vmware/xorg/Makefile
Normal file
54
src/gallium/winsys/drm/vmware/xorg/Makefile
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
TARGET = vmwgfx_drv.so
|
||||
CFILES = $(wildcard ./*.c)
|
||||
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
|
||||
TOP = ../../../../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
INCLUDES = \
|
||||
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
|
||||
-I../gem \
|
||||
-I$(TOP)/src/gallium/include \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
-I$(TOP)/src/gallium/auxiliary \
|
||||
-I$(TOP)/src/gallium
|
||||
|
||||
LIBS = \
|
||||
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
|
||||
$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
|
||||
$(TOP)/src/gallium/drivers/trace/libtrace.a \
|
||||
$(TOP)/src/gallium/drivers/svga/libsvga.a \
|
||||
$(GALLIUM_AUXILIARIES)
|
||||
|
||||
DRIVER_DEFINES = \
|
||||
-DHAVE_CONFIG_H
|
||||
|
||||
|
||||
#############################################
|
||||
|
||||
|
||||
|
||||
all default: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
|
||||
$(TOP)/bin/mklib -noprefix -o $@ \
|
||||
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJECTS) $(TARGET)
|
||||
|
||||
install:
|
||||
$(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
|
||||
$(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
|
||||
|
||||
|
||||
##############################################
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
|
||||
|
||||
|
||||
##############################################
|
||||
|
||||
.PHONY = all clean install
|
||||
55
src/gallium/winsys/drm/vmware/xorg/SConscript
Normal file
55
src/gallium/winsys/drm/vmware/xorg/SConscript
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import os.path
|
||||
|
||||
Import('*')
|
||||
|
||||
if env['platform'] == 'linux':
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server')
|
||||
|
||||
env.Prepend(CPPPATH = [
|
||||
'#/include',
|
||||
'#/src/gallium',
|
||||
'#/src/mesa',
|
||||
'#/src/gallium/drivers/svga',
|
||||
'#/src/gallium/drivers/svga/include',
|
||||
])
|
||||
|
||||
env.Append(CPPDEFINES = [
|
||||
])
|
||||
|
||||
if env['gcc']:
|
||||
env.Append(CPPDEFINES = [
|
||||
'HAVE_STDINT_H',
|
||||
'HAVE_SYS_TYPES_H',
|
||||
])
|
||||
env.Append(CFLAGS = ['-Werror'])
|
||||
|
||||
env.Append(CFLAGS = [
|
||||
'-std=gnu99',
|
||||
'-D_FILE_OFFSET_BITS=64',
|
||||
])
|
||||
|
||||
env.Prepend(LIBPATH = [
|
||||
])
|
||||
|
||||
env.Prepend(LIBS = [
|
||||
trace,
|
||||
st_xorg,
|
||||
svgadrm,
|
||||
svga,
|
||||
auxiliaries,
|
||||
])
|
||||
|
||||
sources = [
|
||||
'vmw_xorg.c',
|
||||
]
|
||||
|
||||
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
|
||||
env.LoadableModule(
|
||||
target ='vmwgfx_drv.so',
|
||||
source = sources,
|
||||
LIBS = env['LIBS'],
|
||||
SHLIBPREFIX = '',
|
||||
)
|
||||
150
src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
Normal file
150
src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. 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 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.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Glue file for Xorg State Tracker.
|
||||
*
|
||||
* @author Alan Hourihane <alanh@tungstengraphics.com>
|
||||
* @author Jakob Bornecrantz <wallbraker@gmail.com>
|
||||
*/
|
||||
|
||||
#include "state_trackers/xorg/xorg_winsys.h"
|
||||
|
||||
static void vmw_xorg_identify(int flags);
|
||||
static Bool vmw_xorg_pci_probe(DriverPtr driver,
|
||||
int entity_num,
|
||||
struct pci_device *device,
|
||||
intptr_t match_data);
|
||||
|
||||
static const struct pci_id_match vmw_xorg_device_match[] = {
|
||||
{0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static SymTabRec vmw_xorg_chipsets[] = {
|
||||
{PCI_MATCH_ANY, "VMware SVGA Device"},
|
||||
{-1, NULL}
|
||||
};
|
||||
|
||||
static PciChipsets vmw_xorg_pci_devices[] = {
|
||||
{PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
|
||||
{-1, -1, NULL}
|
||||
};
|
||||
|
||||
static XF86ModuleVersionInfo vmw_xorg_version = {
|
||||
"vmwgfx",
|
||||
MODULEVENDORSTRING,
|
||||
MODINFOSTRING1,
|
||||
MODINFOSTRING2,
|
||||
XORG_VERSION_CURRENT,
|
||||
0, 1, 0, /* major, minor, patch */
|
||||
ABI_CLASS_VIDEODRV,
|
||||
ABI_VIDEODRV_VERSION,
|
||||
MOD_CLASS_VIDEODRV,
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Xorg driver exported structures
|
||||
*/
|
||||
|
||||
_X_EXPORT DriverRec vmwgfx = {
|
||||
1,
|
||||
"vmwgfx",
|
||||
vmw_xorg_identify,
|
||||
NULL,
|
||||
xorg_tracker_available_options,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
vmw_xorg_device_match,
|
||||
vmw_xorg_pci_probe
|
||||
};
|
||||
|
||||
static MODULESETUPPROTO(vmw_xorg_setup);
|
||||
|
||||
_X_EXPORT XF86ModuleData vmwgfxModuleData = {
|
||||
&vmw_xorg_version,
|
||||
vmw_xorg_setup,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Xorg driver functions
|
||||
*/
|
||||
|
||||
static pointer
|
||||
vmw_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
|
||||
{
|
||||
static Bool setupDone = 0;
|
||||
|
||||
/* This module should be loaded only once, but check to be sure.
|
||||
*/
|
||||
if (!setupDone) {
|
||||
setupDone = 1;
|
||||
xf86AddDriver(&vmwgfx, module, HaveDriverFuncs);
|
||||
|
||||
/*
|
||||
* The return value must be non-NULL on success even though there
|
||||
* is no TearDownProc.
|
||||
*/
|
||||
return (pointer) 1;
|
||||
} else {
|
||||
if (errmaj)
|
||||
*errmaj = LDR_ONCEONLY;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vmw_xorg_identify(int flags)
|
||||
{
|
||||
xf86PrintChipsets("vmwgfx", "Driver for VMware SVGA device",
|
||||
vmw_xorg_chipsets);
|
||||
}
|
||||
|
||||
static Bool
|
||||
vmw_xorg_pci_probe(DriverPtr driver,
|
||||
int entity_num, struct pci_device *device, intptr_t match_data)
|
||||
{
|
||||
ScrnInfoPtr scrn = NULL;
|
||||
EntityInfoPtr entity;
|
||||
|
||||
scrn = xf86ConfigPciEntity(scrn, 0, entity_num, vmw_xorg_pci_devices,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
if (scrn != NULL) {
|
||||
scrn->driverVersion = 1;
|
||||
scrn->driverName = "vmwgfx";
|
||||
scrn->name = "vmwgfx";
|
||||
scrn->Probe = NULL;
|
||||
|
||||
entity = xf86GetEntityInfo(entity_num);
|
||||
|
||||
/* Use all the functions from the xorg tracker */
|
||||
xorg_tracker_set_functions(scrn);
|
||||
}
|
||||
return scrn != NULL;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue