ref_vk: add initial vulkan render stub

It does not work at all, but serves as an exercise to help me figure out
how to make renderers for HL/xash3d.
This commit is contained in:
Ivan Avdeev 2021-01-02 17:52:53 -08:00
parent 3af742f103
commit 5c99bb0979
7 changed files with 579 additions and 15 deletions

View File

@ -20,9 +20,7 @@ typedef struct
qboolean initialized; // OpenGL subsystem started
qboolean extended; // extended context allows to GL_Debug
qboolean software;
int context_type; // REF_SOFTWARE / REF_GL / REF_VULKAN
} glwstate_t;
extern glwstate_t glw_state;

View File

@ -272,13 +272,12 @@ qboolean R_Init_Video( const int type )
VID_StartupGamma();
glw_state.context_type = type;
switch( type )
{
case REF_SOFTWARE:
glw_state.software = true;
break;
case REF_GL:
glw_state.software = false;
Sys_LoadLibrary( &egl_info );
if( !glw_state.safe && Sys_GetParmFromCmdLine( "-safegl", safe ) )
@ -290,7 +289,7 @@ qboolean R_Init_Video( const int type )
break;
}
if( glw_state.software )
if( glw_state.context_type = REF_SOFTWARE )
{
uint arg;
// Con_Reportf( S_ERROR "Native software mode isn't supported on Android yet! :(\n" );
@ -461,7 +460,7 @@ qboolean VID_SetMode( void )
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
if( glw_state.software )
if( glw_state.context_type = REF_SOFTWARE )
return true;
if( (*jni.env)->CallStaticBooleanMethod( jni.env, jni.actcls, jni.createGLContext, attribs, contextAttribs ) )

View File

@ -516,7 +516,7 @@ void VID_SaveWindowSize( int width, int height )
uint rotate = vid_rotate->value;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( !glw_state.software )
if( glw_state.context_type != REF_SOFTWARE )
SDL_GL_GetDrawableSize( host.hWnd, &render_w, &render_h );
else
SDL_RenderSetLogicalSize( sw.renderer, width, height );
@ -622,7 +622,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
{
static string wndname;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
Uint32 wndFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_MOUSE_FOCUS;
Uint32 wndFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_MOUSE_FOCUS;
rgbdata_t *icon = NULL;
qboolean iconLoaded = false;
char iconpath[MAX_STRING];
@ -630,8 +630,15 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
if( vid_highdpi->value ) wndFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
Q_strncpy( wndname, GI->title, sizeof( wndname ));
if( glw_state.software )
wndFlags &= ~SDL_WINDOW_OPENGL;
switch (glw_state.context_type)
{
case REF_GL:
wndFlags |= SDL_WINDOW_OPENGL;
break;
case REF_VULKAN:
wndFlags |= SDL_WINDOW_VULKAN;
break;
}
if( !fullscreen )
{
@ -737,7 +744,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
SDL_ShowWindow( host.hWnd );
if( glw_state.software )
if( glw_state.context_type == REF_SOFTWARE )
{
int sdl_renderer = -2;
char cmd[64];
@ -758,7 +765,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
}
}
}
else
else if( glw_state.context_type == REF_GL )
{
if( !glw_state.initialized )
{
@ -781,7 +788,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
flags |= SDL_FULLSCREEN|SDL_HWSURFACE;
}
if( glw_state.software )
if( glw_state.context_type == REF_SOFTWARE )
{
// flags |= SDL_ASYNCBLIT;
}
@ -986,10 +993,10 @@ qboolean R_Init_Video( const int type )
WIN_SetDPIAwareness();
#endif
glw_state.context_type = type;
switch( type )
{
case REF_SOFTWARE:
glw_state.software = true;
break;
case REF_GL:
if( !glw_state.safe && Sys_GetParmFromCmdLine( "-safegl", safe ) )
@ -1004,6 +1011,8 @@ qboolean R_Init_Video( const int type )
return false;
}
break;
case REF_VULKAN:
break;
default:
Host_Error( "Can't initialize unknown context type %d!\n", type );
break;

View File

@ -155,6 +155,7 @@ enum ref_graphic_apis_e
REF_SOFTWARE, // hypothetical: just make a surface to draw on, in software
REF_GL, // create GL context
REF_D3D, // Direct3D
REF_VULKAN, // Vulkan
};
typedef enum

512
ref_vk/vk_rmain.c Normal file
View File

@ -0,0 +1,512 @@
#include "xash3d_types.h"
#include "cvardef.h"
#include "const.h" // required for ref_api.h
#include "ref_api.h"
#include "crtlib.h"
#include <memory.h>
#include <stdio.h>
ref_api_t gEngine = {0};
ref_globals_t *gpGlobals = NULL;
qboolean R_VkInit( void )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
// TODO VkInstance create ...
if( !gEngine.R_Init_Video( REF_VULKAN )) // request Vulkan surface
{
// ...
return false;
}
return true;
}
void R_VkShutdown( void )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
// TODO destroy everything
}
const char *R_GetConfigName( void )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return "vk";
}
qboolean R_SetDisplayTransform( ref_screen_rotation_t rotate, int x, int y, float scale_x, float scale_y )
{
fprintf(stderr, "VK FIXME: %s(%d, %d, %d, %f, %f)\n", __FUNCTION__, rotate, x, y, scale_x, scale_y);
return true;
}
// only called for GL contexts
void GL_SetupAttributes( int safegl ) {}
void GL_ClearExtensions( void ) {}
void R_BeginFrame( qboolean clearScene ) {}
void R_RenderScene( void ) {}
void R_EndFrame( void ) {}
void R_PushScene( void ) {}
void R_PopScene( void ) {}
void GL_BackendStartFrame( void ) {}
void GL_BackendEndFrame( void ) {}
void R_ClearScreen( void ) {}
void R_AllowFog( qboolean allow ) {}
void GL_SetRenderMode( int renderMode ) {}
qboolean R_AddEntity( struct cl_entity_s *clent, int type )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return false;
}
void CL_AddCustomBeam( cl_entity_t *pEnvBeam ) {}
void R_ProcessEntData( qboolean allocate ) {}
// debug
void R_ShowTextures( void ) {}
// texture management
const byte *R_GetTextureOriginalBuffer( unsigned int idx )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return NULL;
}
int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
}
void R_SetupSky( const char *skyname )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
}
void R_Set2DMode( qboolean enable ) {}
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) {}
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) {}
void R_DrawTileClear( int texnum, int x, int y, int w, int h ) {}
void CL_FillRGBA( float x, float y, float w, float h, int r, int g, int b, int a ) {}
void CL_FillRGBABlend( float x, float y, float w, float h, int r, int g, int b, int a ) {}
// screenshot, cubemapshot
qboolean VID_ScreenShot( const char *filename, int shot_type )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return false;
}
qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return false;
}
// light
colorVec R_LightPoint( const float *p )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return (colorVec){0};
}
// decals
// Shoots a decal onto the surface of the BSP. position is the center of the decal in world coords
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale ) {}
void R_DecalRemoveAll( int texture ) {}
int R_CreateDecalList( struct decallist_s *pList )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
void R_ClearAllDecals( void ) {}
// studio interface
float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 1.f;
}
void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ) {}
void CL_InitStudioAPI( void ) {}
// bmodel
void R_InitSkyClouds( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette ) {}
void GL_SubdivideSurface( msurface_t *fa ) {}
void CL_RunLightStyles( void ) {}
// sprites
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite ) {}
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
// model management
// flags ignored for everything except spritemodels
void Mod_LoadMapSprite( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded ) {}
qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buffer )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return false;
}
void Mod_StudioLoadTextures( model_t *mod, void *data ) {}
// efx implementation
void CL_DrawParticles( double frametime, particle_t *particles, float partsize ) {}
void CL_DrawTracers( double frametime, particle_t *tracers ) {}
void CL_DrawBeams( int fTrans , BEAM *beams ) {}
qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return false;
}
// Xash3D Render Interface
// Get renderer info (doesn't changes engine state at all)
int RefGetParm( int parm, int arg )
{
fprintf(stderr, "VK FIXME: %s(%d, %d)\n", __FUNCTION__, parm, arg);
return 0;
}
void GetDetailScaleForTexture( int texture, float *xScale, float *yScale ) {}
void GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *alpha ) {}
float GetFrameTime( void )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 1.f;
}
// Set renderer info (tell engine about changes)
void R_SetCurrentEntity( struct cl_entity_s *ent ) {}
void R_SetCurrentModel( struct model_s *mod ) {}
// Texture tools
int GL_FindTexture( const char *name )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
const char* GL_TextureName( unsigned int texnum )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return "UNKNOWN";
}
const byte* GL_TextureData( unsigned int texnum )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return NULL;
}
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
int GL_LoadTextureArray( const char **names, int flags )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
void GL_FreeTexture( unsigned int texnum ) {}
// Decals manipulating (draw & remove)
void DrawSingleDecal( struct decal_s *pDecal, struct msurface_s *fa ) {}
float *R_DecalSetupVerts( struct decal_s *pDecal, struct msurface_s *surf, int texture, int *outCount )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return NULL;
}
void R_EntityRemoveDecals( struct model_s *mod ) {}
// AVI
void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ) {}
// glState related calls (must use this instead of normal gl-calls to prevent de-synchornize local states between engine and the client)
void GL_Bind( int tmu, unsigned int texnum ) {}
void GL_SelectTexture( int tmu ) {}
void GL_LoadTextureMatrix( const float *glmatrix ) {}
void GL_TexMatrixIdentity( void ) {}
void GL_CleanUpTextureUnits( int last ) {}
void GL_TexGen( unsigned int coord, unsigned int mode ) {}
void GL_TextureTarget( unsigned int target ) {}
void GL_TexCoordArrayMode( unsigned int texmode ) {}
void GL_UpdateTexSize( int texnum, int width, int height, int depth ) {}
// Misc renderer functions
void GL_DrawParticles( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime ) {}
colorVec R_LightVec( const float *start, const float *end, float *lightspot, float *lightvec )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return (colorVec){0};
}
struct mstudiotex_s *R_StudioGetTexture( struct cl_entity_s *e )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return NULL;
}
// passed through R_RenderFrame (0 - use engine renderer, 1 - use custom client renderer)
void GL_RenderFrame( const struct ref_viewpass_s *rvp ) {}
// setup map bounds for ortho-projection when we in dev_overview mode
void GL_OrthoBounds( const float *mins, const float *maxs ) {}
// grab r_speeds message
qboolean R_SpeedsMessage( char *out, size_t size )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return false;
}
// get visdata for current frame from custom renderer
byte* Mod_GetCurrentVis( void )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return NULL;
}
// tell the renderer what new map is started
void R_NewMap( void ) {}
// clear the render entities before each frame
void R_ClearScene( void ) {}
// GL_GetProcAddress for client renderer
void* R_GetProcAddress( const char *name )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return NULL;
}
// TriAPI Interface
// NOTE: implementation isn't required to be compatible
void TriRenderMode( int mode ) {}
void TriBegin( int primitiveCode ) {}
void TriEnd( void ) {}
void TriColor4f( float r, float g, float b, float a ) {}
void TriColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) {}
void TriTexCoord2f( float u, float v ) {}
void TriVertex3fv( const float *worldPnt ) {}
void TriVertex3f( float x, float y, float z ) {}
int TriWorldToScreen( const float *world, float *screen )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn ) {}
void R_ScreenToWorld( const float *screen, float *world ) {}
void TriGetMatrix( const int pname, float *matrix ) {}
void TriFogParams( float flDensity, int iFogSkybox ) {}
void TriCullFace( TRICULLSTYLE mode ) {}
// vgui drawing implementation
void VGUI_DrawInit( void ) {}
void VGUI_DrawShutdown( void ) {}
void VGUI_SetupDrawingText( int *pColor ) {}
void VGUI_SetupDrawingRect( int *pColor ) {}
void VGUI_SetupDrawingImage( int *pColor ) {}
void VGUI_BindTexture( int id ) {}
void VGUI_EnableTexture( qboolean enable ) {}
void VGUI_CreateTexture( int id, int width, int height ) {}
void VGUI_UploadTexture( int id, const char *buffer, int width, int height ) {}
void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ) {}
void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ) {}
void VGUI_GetTextureSizes( int *width, int *height ) {}
int VGUI_GenerateTexture( void )
{
fprintf(stderr, "VK FIXME: %s\n", __FUNCTION__);
return 0;
}
ref_interface_t gReffuncs =
{
.R_Init = R_VkInit,
.R_Shutdown = R_VkShutdown,
R_GetConfigName,
R_SetDisplayTransform,
GL_SetupAttributes,
.GL_InitExtensions = NULL, // Unused in Vulkan renderer
GL_ClearExtensions,
R_BeginFrame,
R_RenderScene,
R_EndFrame,
R_PushScene,
R_PopScene,
GL_BackendStartFrame,
GL_BackendEndFrame,
R_ClearScreen,
R_AllowFog,
GL_SetRenderMode,
R_AddEntity,
CL_AddCustomBeam,
R_ProcessEntData,
R_ShowTextures,
R_GetTextureOriginalBuffer,
GL_LoadTextureFromBuffer,
GL_ProcessTexture,
R_SetupSky,
R_Set2DMode,
R_DrawStretchRaw,
R_DrawStretchPic,
R_DrawTileClear,
CL_FillRGBA,
CL_FillRGBABlend,
VID_ScreenShot,
VID_CubemapShot,
R_LightPoint,
R_DecalShoot,
R_DecalRemoveAll,
R_CreateDecalList,
R_ClearAllDecals,
R_StudioEstimateFrame,
R_StudioLerpMovement,
CL_InitStudioAPI,
R_InitSkyClouds,
GL_SubdivideSurface,
CL_RunLightStyles,
R_GetSpriteParms,
R_GetSpriteTexture,
Mod_LoadMapSprite,
Mod_ProcessRenderData,
Mod_StudioLoadTextures,
CL_DrawParticles,
CL_DrawTracers,
CL_DrawBeams,
R_BeamCull,
RefGetParm,
GetDetailScaleForTexture,
GetExtraParmsForTexture,
GetFrameTime,
R_SetCurrentEntity,
R_SetCurrentModel,
GL_FindTexture,
GL_TextureName,
GL_TextureData,
GL_LoadTexture,
GL_CreateTexture,
GL_LoadTextureArray,
GL_CreateTextureArray,
GL_FreeTexture,
DrawSingleDecal,
R_DecalSetupVerts,
R_EntityRemoveDecals,
AVI_UploadRawFrame,
GL_Bind,
GL_SelectTexture,
GL_LoadTextureMatrix,
GL_TexMatrixIdentity,
GL_CleanUpTextureUnits,
GL_TexGen,
GL_TextureTarget,
GL_TexCoordArrayMode,
GL_UpdateTexSize,
NULL, // Reserved0
NULL, // Reserved1
GL_DrawParticles,
R_LightVec,
R_StudioGetTexture,
GL_RenderFrame,
GL_OrthoBounds,
R_SpeedsMessage,
Mod_GetCurrentVis,
R_NewMap,
R_ClearScene,
R_GetProcAddress,
TriRenderMode,
TriBegin,
TriEnd,
TriColor4f,
TriColor4ub,
TriTexCoord2f,
TriVertex3fv,
TriVertex3f,
TriWorldToScreen,
TriFog,
R_ScreenToWorld,
TriGetMatrix,
TriFogParams,
TriCullFace,
VGUI_DrawInit,
VGUI_DrawShutdown,
VGUI_SetupDrawingText,
VGUI_SetupDrawingRect,
VGUI_SetupDrawingImage,
VGUI_BindTexture,
VGUI_EnableTexture,
VGUI_CreateTexture,
VGUI_UploadTexture,
VGUI_UploadTextureBlock,
VGUI_DrawQuad,
VGUI_GetTextureSizes,
VGUI_GenerateTexture,
};
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
memcpy( funcs, &gReffuncs, sizeof( ref_interface_t ));
memcpy( &gEngine, engfuncs, sizeof( ref_api_t ));
gpGlobals = globals;
return REF_API_VERSION;
}
void EXPORT GetRefHumanReadableName( char *out, size_t size )
{
Q_strncpy( out, "Vulkan", size );
}

44
ref_vk/wscript Normal file
View File

@ -0,0 +1,44 @@
#! /usr/bin/env python
# encoding: utf-8
# mittorn, 2018
from waflib import Logs
import os
top = '.'
def options(opt):
grp = opt.add_option_group('ref_vk options')
def configure(conf):
# check for dedicated server build
if conf.options.DEDICATED:
return
conf.define('REF_DLL', 1)
def build(bld):
libs = [ 'public', 'M' ]
source = bld.path.ant_glob(['*.c'])
includes = ['.',
'../engine',
'../engine/common',
'../engine/server',
'../engine/client',
'../public',
'../common',
'../pm_shared' ]
bld.shlib(
source = source,
target = 'ref_vk',
features = 'c',
includes = includes,
use = libs, #+ (['GL'] if bld.env.GL_STATIC else []),
defines = [], # ['XASH_GL_STATIC'] if bld.env.GL_STATIC else [],
install_path = bld.env.LIBDIR,
subsystem = bld.env.MSVC_SUBSYSTEM
)

View File

@ -50,6 +50,7 @@ SUBDIRS = [
Subproject('game_launch', singlebin=True),
Subproject('ref_gl',),
Subproject('ref_soft'),
Subproject('ref_vk',),
Subproject('mainui'),
Subproject('vgui_support'),
Subproject('stub/server', dedicated=False),