Functionality to make proper behavior of r_renderAPI: disables current API, enables selected API.

This commit is contained in:
Artem Kharytoniuk 2017-05-03 19:08:54 +03:00
parent 2f75ace0c9
commit 8ad279e5b9
12 changed files with 372 additions and 261 deletions

View File

@ -91,7 +91,7 @@ void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned
int i, j;
int ret;
if ( !glConfig.deviceSupportsGamma || r_ignorehwgamma->integer || !glw_state.hDC ) {
if ( !glConfig.deviceSupportsGamma || r_ignorehwgamma->integer ) {
return;
}
@ -123,10 +123,18 @@ void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned
}
}
ret = SetDeviceGammaRamp( glw_state.hDC, table );
HDC gamma_hdc = glw_state.hDC;
if (gamma_hdc == NULL)
gamma_hdc = GetDC(NULL);
ret = SetDeviceGammaRamp( gamma_hdc, table );
if ( !ret ) {
Com_Printf( "SetDeviceGammaRamp failed.\n" );
}
if (glw_state.hDC == NULL)
ReleaseDC(NULL, gamma_hdc);
}
/*

View File

@ -574,6 +574,16 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) {
}*/
}
} else { // vulkan
if (r_renderAPICompareWindow->integer) {
HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight);
if (!GLW_InitDriver(hwnd2)) {
DestroyWindow(hwnd2);
ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window");
} else {
g_wv.hWnd_opengl = hwnd2;
}
}
vk_create_instance(hwnd);
/*if (!vk_initialize(hwnd)) {
ShowWindow(hwnd, SW_HIDE);
@ -583,17 +593,6 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) {
g_wv.hWnd = hwnd;
g_wv.hWnd_vulkan = hwnd;
if (r_renderAPICompareWindow->integer) {
HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight);
if (!GLW_InitDriver(hwnd2)) {
ShowWindow(hwnd2, SW_HIDE);
DestroyWindow(hwnd2);
ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window");
} else {
g_wv.hWnd_opengl = hwnd2;
}
}
}
SetForegroundWindow(g_wv.hWnd);
@ -606,6 +605,12 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) {
*/
static void GLW_InitExtensions( void )
{
if (!gl_active) {
qglActiveTextureARB = [] (GLenum) {};
qglClientActiveTextureARB = [](GLenum) {};
return;
}
ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
// GL_S3_s3tc
@ -745,7 +750,6 @@ void GLimp_EndFrame (void)
*/
void GLimp_Init( void )
{
cvar_t *lastValidRenderer = ri.Cvar_Get( "r_lastValidRenderer", "(uninitialized)", CVAR_ARCHIVE );
cvar_t *cv;
ri.Printf( PRINT_ALL, "Initializing OpenGL subsystem\n" );
@ -775,19 +779,6 @@ void GLimp_Init( void )
Q_strncpyz(glConfig.version_string, (const char*)qglGetString(GL_VERSION), sizeof(glConfig.version_string));
Q_strncpyz(glConfig.extensions_string, (const char*)qglGetString(GL_EXTENSIONS), sizeof(glConfig.extensions_string));
//
// NOTE: if changing cvars, do it within this block. This allows them
// to be overridden when testing driver fixes, etc. but only sets
// them to their default state when the hardware is first installed/run.
//
if ( Q_stricmp( lastValidRenderer->string, glConfig.renderer_string ) )
{
ri.Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST" );
ri.Cvar_Set("r_picmip", "1");
}
ri.Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string );
GLW_InitExtensions();
WG_CheckHardwareGamma();
}

View File

@ -147,6 +147,80 @@ static void ( APIENTRY * dllVertex3fv )(const GLfloat *v);
static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height);
//
// Placeholder functions to replace OpenGL calls when Vulkan renderer is active.
//
static HGLRC nowglCreateContext(HDC) { return NULL;}
static BOOL nowglDeleteContext(HGLRC) { return FALSE; }
static PROC nowglGetProcAddress(LPCSTR) { return NULL; }
static BOOL nowglMakeCurrent(HDC, HGLRC) { return FALSE; }
static int nowglSwapIntervalEXT( int interval ) { return -1; }
static void noglActiveTextureARB ( GLenum texture ) {}
static void noglClientActiveTextureARB ( GLenum texture ) {}
static void noglLockArraysEXT (GLint, GLint) {}
static void noglUnlockArraysEXT (void) {}
static void noglAlphaFunc(GLenum func, GLclampf ref) {}
static void noglBegin(GLenum mode) {}
static void noglBindTexture(GLenum target, GLuint texture) {}
static void noglBlendFunc(GLenum sfactor, GLenum dfactor) {}
static void noglClear(GLbitfield mask) {}
static void noglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {}
static void noglClipPlane(GLenum plane, const GLdouble *equation) {}
static void noglColor3f(GLfloat red, GLfloat green, GLfloat blue) {}
static void noglColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {}
static void noglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {}
static void noglCullFace(GLenum mode) {}
static void noglDeleteTextures(GLsizei n, const GLuint *textures) {}
static void noglDepthFunc(GLenum func) {}
static void noglDepthMask(GLboolean flag) {}
static void noglDepthRange(GLclampd zNear, GLclampd zFar) {}
static void noglDisable(GLenum cap) {}
static void noglDisableClientState(GLenum array) {}
static void noglDrawBuffer(GLenum mode) {}
static void noglDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {}
static void noglEnable(GLenum cap) {}
static void noglEnableClientState(GLenum array) {}
static void noglEnd(void) {}
static void noglFinish(void) {}
static GLenum noglGetError(void) { return GL_NO_ERROR; }
static void noglGetIntegerv(GLenum pname, GLint *params) {
if (pname == GL_MAX_TEXTURE_SIZE) {
*params = 2048;
}
}
static const GLubyte* noglGetString(GLenum name) { static char* s = ""; return (GLubyte*)s;}
static void noglLineWidth(GLfloat width) {}
static void noglLoadIdentity(void) {}
static void noglLoadMatrixf(const GLfloat *m) {}
static void noglMatrixMode(GLenum mode) {}
static void noglOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {}
static void noglPolygonMode(GLenum face, GLenum mode) {}
static void noglPolygonOffset(GLfloat factor, GLfloat units) {}
static void noglPopMatrix(void) {}
static void noglPushMatrix(void) {}
static void noglReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {}
static void noglScissor(GLint x, GLint y, GLsizei width, GLsizei height) {}
static void noglStencilFunc(GLenum func, GLint ref, GLuint mask) {}
static void noglStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {}
static void noglTexCoord2f(GLfloat s, GLfloat t) {}
static void noglTexCoord2fv(const GLfloat *v) {}
static void noglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {}
static void noglTexEnvf(GLenum target, GLenum pname, GLfloat param) {}
static void noglTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {}
static void noglTexParameterf(GLenum target, GLenum pname, GLfloat param) {}
static void noglTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) {}
static void noglTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {}
static void noglVertex2f(GLfloat x, GLfloat y) {}
static void noglVertex3f(GLfloat x, GLfloat y, GLfloat z) {}
static void noglVertex3fv(const GLfloat *v) {}
static void noglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {}
static void noglViewport(GLint x, GLint y, GLsizei width, GLsizei height) {}
static const char * BooleanToString( GLboolean b )
{
if ( b == GL_FALSE )
@ -659,10 +733,8 @@ void QGL_Shutdown( void )
qwglMakeCurrent = NULL;
}
#define GR_NUM_BOARDS 0x0f
# pragma warning (disable : 4113 4133 4047 )
# define GPA( a ) GetProcAddress( glw_state.hinstOpenGL, a )
# define GPA( a ) (gl_active ? (void*)GetProcAddress(glw_state.hinstOpenGL, #a) : (void*)(&no ## a))
/*
** QGL_Init
@ -687,63 +759,63 @@ qboolean QGL_Init( const char *dllname )
}
ri.Printf( PRINT_ALL, "succeeded\n" );
qglAlphaFunc = dllAlphaFunc = (decltype(dllAlphaFunc))GPA("glAlphaFunc");
qglBegin = dllBegin = (decltype(dllBegin))GPA("glBegin");
qglBindTexture = dllBindTexture = (decltype(dllBindTexture))GPA("glBindTexture");
qglBlendFunc = dllBlendFunc = (decltype(dllBlendFunc))GPA("glBlendFunc");
qglClear = dllClear = (decltype(dllClear))GPA("glClear");
qglClearColor = dllClearColor = (decltype(dllClearColor))GPA("glClearColor");
qglClipPlane = dllClipPlane = (decltype(dllClipPlane))GPA("glClipPlane");
qglColor3f = dllColor3f = (decltype(dllColor3f))GPA("glColor3f");
qglColorMask = dllColorMask = (decltype(dllColorMask))GPA("glColorMask");
qglColorPointer = dllColorPointer = (decltype(dllColorPointer))GPA("glColorPointer");
qglCullFace = dllCullFace = (decltype(dllCullFace))GPA("glCullFace");
qglDeleteTextures = dllDeleteTextures = (decltype(dllDeleteTextures))GPA("glDeleteTextures");
qglDepthFunc = dllDepthFunc = (decltype(dllDepthFunc))GPA("glDepthFunc");
qglDepthMask = dllDepthMask = (decltype(dllDepthMask))GPA("glDepthMask");
qglDepthRange = dllDepthRange = (decltype(dllDepthRange))GPA("glDepthRange");
qglDisable = dllDisable = (decltype(dllDisable))GPA("glDisable");
qglDisableClientState = dllDisableClientState = (decltype(dllDisableClientState))GPA("glDisableClientState");
qglDrawBuffer = dllDrawBuffer = (decltype(dllDrawBuffer))GPA("glDrawBuffer");
qglDrawElements = dllDrawElements = (decltype(dllDrawElements))GPA("glDrawElements");
qglEnable = dllEnable = (decltype(dllEnable))GPA("glEnable");
qglEnableClientState = dllEnableClientState = (decltype(dllEnableClientState))GPA("glEnableClientState");
qglEnd = dllEnd = (decltype(dllEnd))GPA("glEnd");
qglFinish = dllFinish = (decltype(dllFinish))GPA("glFinish");
qglGetError = dllGetError = ( GLenum (__stdcall * )(void) ) GPA( "glGetError" );
qglGetIntegerv = dllGetIntegerv = (decltype(dllGetIntegerv))GPA("glGetIntegerv");
qglGetString = dllGetString = (decltype(dllGetString))GPA("glGetString");
qglLineWidth = dllLineWidth = (decltype(dllLineWidth))GPA("glLineWidth");
qglLoadIdentity = dllLoadIdentity = (decltype(dllLoadIdentity))GPA("glLoadIdentity");
qglLoadMatrixf = dllLoadMatrixf = (decltype(dllLoadMatrixf))GPA("glLoadMatrixf");
qglMatrixMode = dllMatrixMode = (decltype(dllMatrixMode))GPA("glMatrixMode");
qglOrtho = dllOrtho = (decltype(dllOrtho))GPA("glOrtho");
qglPolygonMode = dllPolygonMode = (decltype(dllPolygonMode))GPA("glPolygonMode");
qglPolygonOffset = dllPolygonOffset = (decltype(dllPolygonOffset))GPA("glPolygonOffset");
qglPopMatrix = dllPopMatrix = (decltype(dllPopMatrix))GPA("glPopMatrix");
qglPushMatrix = dllPushMatrix = (decltype(dllPushMatrix))GPA("glPushMatrix");
qglReadPixels = dllReadPixels = (decltype(dllReadPixels))GPA("glReadPixels");
qglScissor = dllScissor = (decltype(dllScissor))GPA("glScissor");
qglStencilFunc = dllStencilFunc = (decltype(dllStencilFunc))GPA("glStencilFunc");
qglStencilOp = dllStencilOp = (decltype(dllStencilOp))GPA("glStencilOp");
qglTexCoord2f = dllTexCoord2f = (decltype(dllTexCoord2f))GPA("glTexCoord2f");
qglTexCoord2fv = dllTexCoord2fv = (decltype(dllTexCoord2fv))GPA("glTexCoord2fv");
qglTexCoordPointer = dllTexCoordPointer = (decltype(dllTexCoordPointer))GPA("glTexCoordPointer");
qglTexEnvf = dllTexEnvf = (decltype(dllTexEnvf))GPA("glTexEnvf");
qglTexImage2D = dllTexImage2D = (decltype(dllTexImage2D))GPA("glTexImage2D");
qglTexParameterf = dllTexParameterf = (decltype(dllTexParameterf))GPA("glTexParameterf");
qglTexParameterfv = dllTexParameterfv = (decltype(dllTexParameterfv))GPA("glTexParameterfv");
qglTexSubImage2D = dllTexSubImage2D = (decltype(dllTexSubImage2D))GPA("glTexSubImage2D");
qglVertex2f = dllVertex2f = (decltype(dllVertex2f))GPA("glVertex2f");
qglVertex3f = dllVertex3f = (decltype(dllVertex3f))GPA("glVertex3f");
qglVertex3fv = dllVertex3fv = (decltype(dllVertex3fv))GPA("glVertex3fv");
qglVertexPointer = dllVertexPointer = (decltype(dllVertexPointer))GPA("glVertexPointer");
qglViewport = dllViewport = (decltype(dllViewport))GPA("glViewport");
qglAlphaFunc = dllAlphaFunc = (decltype(dllAlphaFunc))GPA(glAlphaFunc);
qglBegin = dllBegin = (decltype(dllBegin))GPA(glBegin);
qglBindTexture = dllBindTexture = (decltype(dllBindTexture))GPA(glBindTexture);
qglBlendFunc = dllBlendFunc = (decltype(dllBlendFunc))GPA(glBlendFunc);
qglClear = dllClear = (decltype(dllClear))GPA(glClear);
qglClearColor = dllClearColor = (decltype(dllClearColor))GPA(glClearColor);
qglClipPlane = dllClipPlane = (decltype(dllClipPlane))GPA(glClipPlane);
qglColor3f = dllColor3f = (decltype(dllColor3f))GPA(glColor3f);
qglColorMask = dllColorMask = (decltype(dllColorMask))GPA(glColorMask);
qglColorPointer = dllColorPointer = (decltype(dllColorPointer))GPA(glColorPointer);
qglCullFace = dllCullFace = (decltype(dllCullFace))GPA(glCullFace);
qglDeleteTextures = dllDeleteTextures = (decltype(dllDeleteTextures))GPA(glDeleteTextures);
qglDepthFunc = dllDepthFunc = (decltype(dllDepthFunc))GPA(glDepthFunc);
qglDepthMask = dllDepthMask = (decltype(dllDepthMask))GPA(glDepthMask);
qglDepthRange = dllDepthRange = (decltype(dllDepthRange))GPA(glDepthRange);
qglDisable = dllDisable = (decltype(dllDisable))GPA(glDisable);
qglDisableClientState = dllDisableClientState = (decltype(dllDisableClientState))GPA(glDisableClientState);
qglDrawBuffer = dllDrawBuffer = (decltype(dllDrawBuffer))GPA(glDrawBuffer);
qglDrawElements = dllDrawElements = (decltype(dllDrawElements))GPA(glDrawElements);
qglEnable = dllEnable = (decltype(dllEnable))GPA(glEnable);
qglEnableClientState = dllEnableClientState = (decltype(dllEnableClientState))GPA(glEnableClientState);
qglEnd = dllEnd = (decltype(dllEnd))GPA(glEnd);
qglFinish = dllFinish = (decltype(dllFinish))GPA(glFinish);
qglGetError = dllGetError = ( GLenum (__stdcall * )(void) ) GPA( glGetError );
qglGetIntegerv = dllGetIntegerv = (decltype(dllGetIntegerv))GPA(glGetIntegerv);
qglGetString = dllGetString = (decltype(dllGetString))GPA(glGetString);
qglLineWidth = dllLineWidth = (decltype(dllLineWidth))GPA(glLineWidth);
qglLoadIdentity = dllLoadIdentity = (decltype(dllLoadIdentity))GPA(glLoadIdentity);
qglLoadMatrixf = dllLoadMatrixf = (decltype(dllLoadMatrixf))GPA(glLoadMatrixf);
qglMatrixMode = dllMatrixMode = (decltype(dllMatrixMode))GPA(glMatrixMode);
qglOrtho = dllOrtho = (decltype(dllOrtho))GPA(glOrtho);
qglPolygonMode = dllPolygonMode = (decltype(dllPolygonMode))GPA(glPolygonMode);
qglPolygonOffset = dllPolygonOffset = (decltype(dllPolygonOffset))GPA(glPolygonOffset);
qglPopMatrix = dllPopMatrix = (decltype(dllPopMatrix))GPA(glPopMatrix);
qglPushMatrix = dllPushMatrix = (decltype(dllPushMatrix))GPA(glPushMatrix);
qglReadPixels = dllReadPixels = (decltype(dllReadPixels))GPA(glReadPixels);
qglScissor = dllScissor = (decltype(dllScissor))GPA(glScissor);
qglStencilFunc = dllStencilFunc = (decltype(dllStencilFunc))GPA(glStencilFunc);
qglStencilOp = dllStencilOp = (decltype(dllStencilOp))GPA(glStencilOp);
qglTexCoord2f = dllTexCoord2f = (decltype(dllTexCoord2f))GPA(glTexCoord2f);
qglTexCoord2fv = dllTexCoord2fv = (decltype(dllTexCoord2fv))GPA(glTexCoord2fv);
qglTexCoordPointer = dllTexCoordPointer = (decltype(dllTexCoordPointer))GPA(glTexCoordPointer);
qglTexEnvf = dllTexEnvf = (decltype(dllTexEnvf))GPA(glTexEnvf);
qglTexImage2D = dllTexImage2D = (decltype(dllTexImage2D))GPA(glTexImage2D);
qglTexParameterf = dllTexParameterf = (decltype(dllTexParameterf))GPA(glTexParameterf);
qglTexParameterfv = dllTexParameterfv = (decltype(dllTexParameterfv))GPA(glTexParameterfv);
qglTexSubImage2D = dllTexSubImage2D = (decltype(dllTexSubImage2D))GPA(glTexSubImage2D);
qglVertex2f = dllVertex2f = (decltype(dllVertex2f))GPA(glVertex2f);
qglVertex3f = dllVertex3f = (decltype(dllVertex3f))GPA(glVertex3f);
qglVertex3fv = dllVertex3fv = (decltype(dllVertex3fv))GPA(glVertex3fv);
qglVertexPointer = dllVertexPointer = (decltype(dllVertexPointer))GPA(glVertexPointer);
qglViewport = dllViewport = (decltype(dllViewport))GPA(glViewport);
qwglCreateContext = (decltype(qwglCreateContext))GPA("wglCreateContext");
qwglDeleteContext = (decltype(qwglDeleteContext))GPA("wglDeleteContext");
qwglGetProcAddress = (decltype(qwglGetProcAddress))GPA("wglGetProcAddress");
qwglMakeCurrent = (decltype(qwglMakeCurrent))GPA("wglMakeCurrent");
qwglCreateContext = (decltype(qwglCreateContext))GPA(wglCreateContext);
qwglDeleteContext = (decltype(qwglDeleteContext))GPA(wglDeleteContext);
qwglGetProcAddress = (decltype(qwglGetProcAddress))GPA(wglGetProcAddress);
qwglMakeCurrent = (decltype(qwglMakeCurrent))GPA(wglMakeCurrent);
qwglSwapIntervalEXT = 0;
qglActiveTextureARB = 0;

View File

@ -34,6 +34,12 @@ static float s_flipMatrix[16] = {
0, 0, 0, 1
};
#ifdef _DEBUG
float fast_sky_color[4] = { 0.8f, 0.7f, 0.4f, 1.0f };
#else
float fast_sky_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
#endif
/*
** GL_Bind
@ -58,7 +64,10 @@ void GL_Bind( image_t *image ) {
qglBindTexture (GL_TEXTURE_2D, texnum);
// VULKAN
glState.vk_current_images[glState.currenttmu] = final_image;
if (vk_active) {
VkDescriptorSet set = vk_resources.images[final_image->index].descriptor_set;
vk_resources.current_descriptor_sets[glState.currenttmu] = set;
}
}
}
@ -423,61 +432,17 @@ void RB_BeginDrawingView (void) {
clearBits |= GL_STENCIL_BUFFER_BIT;
}
#ifdef _DEBUG
float sky_color[4] = { 0.8f, 0.7f, 0.4f, 1.0f }; // FIXME: get color of sky
#else
float sky_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; // FIXME: get color of sky
#endif
bool fast_sky = r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL );
if ( fast_sky )
{
clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used
qglClearColor(sky_color[0], sky_color[1], sky_color[2], sky_color[3]);
qglClearColor(fast_sky_color[0], fast_sky_color[1], fast_sky_color[2], fast_sky_color[3]);
}
qglClear( clearBits );
// VULKAN
if (glState.vk_dirty_attachments || fast_sky) {
VkClearAttachment attachments[2];
uint32_t attachment_count = fast_sky ? 2 : 1;
attachments[0].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
attachments[0].clearValue.depthStencil.depth = 1.0f;
if (clear_stencil) {
attachments[0].aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
attachments[0].clearValue.depthStencil.stencil = 0;
}
if (fast_sky) {
attachments[1].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
attachments[1].colorAttachment = 0;
attachments[1].clearValue.color = { sky_color[0], sky_color[1], sky_color[2], sky_color[3] };
}
VkClearRect clear_rect[2];
clear_rect[0].rect = vk_get_scissor_rect();
clear_rect[0].baseArrayLayer = 0;
clear_rect[0].layerCount = 1;
int rect_count = 1;
// Split viewport rectangle into two non-overlapping rectangles.
// It's a HACK to prevent Vulkan validation layer's performance warning:
// "vkCmdClearAttachments() issued on command buffer object XXX prior to any Draw Cmds.
// It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw."
//
if (fast_sky) {
uint32_t h = clear_rect[0].rect.extent.height / 2;
clear_rect[0].rect.extent.height = h;
clear_rect[1] = clear_rect[0];
clear_rect[1].rect.offset.y = h;
rect_count = 2;
}
vkCmdClearAttachments(vk.command_buffer, attachment_count, attachments, rect_count, clear_rect);
}
vk_clear_attachments(clear_stencil, fast_sky);
if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) )
{
@ -746,12 +711,15 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
// VULKAN
if (vk_active) {
Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index];
vkDestroyImage(vk.device, image.handle, nullptr);
vkDestroyImageView(vk.device, image.view, nullptr);
vkFreeDescriptorSets(vk.device, vk.descriptor_pool, 1, &image.descriptor_set);
image = vk_create_image(cols, rows, 1, false);
vk_upload_image_data(image.handle, cols, rows, false, data);
vk_resources.current_descriptor_sets[glState.currenttmu] = image.descriptor_set;
}
} else {
if (dirty) {
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
@ -759,10 +727,12 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
// VULKAN
if (vk_active) {
const Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index];
vk_upload_image_data(image.handle, cols, rows, false, data);
}
}
}
}

View File

@ -119,7 +119,6 @@ GL_TextureMode
*/
void GL_TextureMode( const char *string ) {
int i;
image_t *glt;
for ( i=0 ; i< 6 ; i++ ) {
if ( !Q_stricmp( modes[i].name, string ) ) {
@ -135,22 +134,27 @@ void GL_TextureMode( const char *string ) {
gl_filter_min = modes[i].minimize;
gl_filter_max = modes[i].maximize;
// VULKAN
VK_CHECK(vkDeviceWaitIdle(vk.device));
// change all the existing mipmap texture objects
for ( i = 0 ; i < tr.numImages ; i++ ) {
glt = tr.images[ i ];
image_t* glt = tr.images[ i ];
if ( glt->mipmap ) {
GL_Bind (glt);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
}
// VULKAN
if (vk_active) {
VK_CHECK(vkDeviceWaitIdle(vk.device));
for ( i = 0 ; i < tr.numImages ; i++ ) {
image_t* glt = tr.images[i];
if (glt->mipmap) {
Vk_Image& image = vk_resources.images[i];
vk_update_descriptor_set(image.descriptor_set, image.view, true, glt->wrapClampMode == GL_REPEAT);
}
}
}
}
/*
@ -718,9 +722,10 @@ static void Upload32( unsigned *data,
done:
// VULKAN
if (vk_active) {
image = vk_create_image(*pUploadWidth, *pUploadHeight, miplevel + 1, repeat_texture);
vk_upload_image_data(image.handle, *pUploadWidth, *pUploadHeight, mipmap == qtrue, mipmap_buffer);
}
if (mipmap_buffer != nullptr)
ri.Hunk_FreeTempMemory(mipmap_buffer);
@ -1880,10 +1885,6 @@ void R_DeleteTextures( void ) {
Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
// VULKAN
vkDeviceWaitIdle(vk.device);
Com_Memset( glState.vk_current_images, 0, sizeof( glState.vk_current_images ) );
if ( qglBindTexture ) {
GL_SelectTexture( 1 );
qglBindTexture( GL_TEXTURE_2D, 0 );

View File

@ -29,6 +29,8 @@ glstate_t glState;
// VULKAN
Vk_Instance vk;
Vk_Resources vk_resources;
bool gl_active;
bool vk_active;
static void GfxInfo_f( void );
@ -989,6 +991,9 @@ void R_Init( void ) {
}
R_ToggleSmpFrame();
gl_active = (r_renderAPI->integer == 0 || r_renderAPICompareWindow->integer > 0);
vk_active = (r_renderAPI->integer > 0 || r_renderAPICompareWindow->integer > 0);
InitOpenGL();
R_InitImages();
@ -1027,23 +1032,23 @@ void RE_Shutdown( qboolean destroyWindow ) {
ri.Cmd_RemoveCommand( "modelist" );
ri.Cmd_RemoveCommand( "shaderstate" );
// VULKAN
if (vk_active) {
vk_destroy_resources();
if (destroyWindow)
vk_destroy_instance();
}
if ( tr.registered ) {
R_SyncRenderThread();
R_ShutdownCommandBuffers();
R_DeleteTextures();
// VULKAN
vk_destroy_resources();
}
R_DoneFreeType();
// shut down platform specific OpenGL stuff
if ( destroyWindow ) {
// VULKAN
vk_destroy_instance();
GLimp_Shutdown();
}

View File

@ -805,14 +805,6 @@ typedef struct {
int texEnv[2];
int faceCulling;
unsigned long glStateBits;
// VULKAN
// This flag is used to decide whether framebuffer's attachments should be cleared with vmCmdClearAttachment (vk_dirty_attachments == true),
// or they have just been cleared by render pass instance clear op (vk_dirty_attachments == false).
bool vk_dirty_attachments;
image_t* vk_current_images[2];
} glstate_t;
@ -950,6 +942,8 @@ extern glstate_t glState; // outside of TR since it shouldn't be cleared during
// VULKAN
extern Vk_Instance vk; // shouldn't be cleared during ref re-init
extern Vk_Resources vk_resources; // this data is cleared during ref re-init
extern bool gl_active;
extern bool vk_active;
//

View File

@ -362,10 +362,12 @@ static void ProjectDlightTexture( void ) {
backEnd.pc.c_dlightIndexes += numIndexes;
// VULKAN
if (vk_active) {
VkPipeline pipeline = vk.dlight_pipelines[dl->additive > 0 ? 1 : 0][tess.shader->cullType][tess.shader->polygonOffset];
vk_bind_stage_specific_resources(pipeline, false, false);
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
glState.vk_dirty_attachments = true;
vk_resources.dirty_attachments = true;
}
}
}
@ -406,11 +408,13 @@ static void RB_FogPass( void ) {
R_DrawElements( tess.numIndexes, tess.indexes );
// VULKAN
if (vk_active) {
assert(tess.shader->fogPass > 0);
VkPipeline pipeline = vk.fog_pipelines[tess.shader->fogPass - 1][tess.shader->cullType][tess.shader->polygonOffset];
vk_bind_stage_specific_resources(pipeline, false, false);
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
glState.vk_dirty_attachments = true;
vk_resources.dirty_attachments = true;
}
}
/*
@ -714,10 +718,6 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
static void RB_IterateStagesGeneric( shaderCommands_t *input )
{
// VULKAN
extern FILE* vk_log_file;
if (r_logFile->integer)
fprintf(vk_log_file, "vk_draw (passes %d, vert %d, inds %d)\n", input->numPasses, tess.numVertexes, tess.numIndexes);
vk_bind_resources_shared_between_stages();
for ( int stage = 0; stage < MAX_SHADER_STAGES; stage++ )
@ -767,6 +767,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
}
// VULKAN
if (vk_active) {
VkPipeline pipeline = pStage->vk_pipeline;
if (backEnd.viewParms.isMirror)
pipeline = pStage->vk_mirror_pipeline;
@ -775,7 +776,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
vk_bind_stage_specific_resources(pipeline, multitexture, input->shader->isSky == qtrue);
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
glState.vk_dirty_attachments = true;
vk_resources.dirty_attachments = true;
}
// allow skipping out to show just lightmaps during development
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )

View File

@ -2160,7 +2160,8 @@ static shader_t *FinishShader( void ) {
shader.sort = SS_FOG;
}
// VULKAN
// VULKAN: create pipelines for each shader stage
if (vk_active) {
Vk_Pipeline_Def def;
def.face_culling = shader.cullType;
def.polygon_offset = (shader.polygonOffset == qtrue);
@ -2176,7 +2177,7 @@ static shader_t *FinishShader( void ) {
else if (shader.multitextureEnv == GL_ADD)
def.shader_type = Vk_Shader_Type::multi_texture_add;
else
ri.Error(ERR_DROP, "ERROR: could not determine vulkan shader type for shader '%s'\n", shader.name);
ri.Error(ERR_FATAL, "Vulkan: could not create pipelines for q3 shader '%s'\n", shader.name);
def.clipping_plane = false;
def.mirror = false;
@ -2190,6 +2191,7 @@ static shader_t *FinishShader( void ) {
def.mirror = true;
pStage->vk_mirror_pipeline = vk_find_pipeline(def);
}
}
return GeneratePermanentShader();
}

View File

@ -450,8 +450,11 @@ static void DrawSkyBox( shader_t *shader )
sky_mins_subd,
sky_maxs_subd );
// VULKAN
glState.vk_current_images[0] = shader->sky.outerbox[sky_texorder[i]];
// VULKAN: draw skybox side
if (vk_active) {
VkDescriptorSet set = vk_resources.images[shader->sky.outerbox[sky_texorder[i]]->index].descriptor_set;
vk_resources.current_descriptor_sets[0] = set;
tess.numVertexes = 0;
tess.numIndexes = 0;
@ -494,9 +497,10 @@ static void DrawSkyBox( shader_t *shader )
vk_bind_resources_shared_between_stages();
vk_bind_stage_specific_resources(vk.skybox_pipeline, false, true);
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
glState.vk_dirty_attachments = true;
vk_resources.dirty_attachments = true;
vk.xyz_elements += tess.numVertexes;
}
}
}

View File

@ -7,6 +7,8 @@
FILE* vk_log_file;
extern float fast_sky_color[4];
const int VERTEX_CHUNK_SIZE = 512 * 1024;
const int XYZ_SIZE = 4 * VERTEX_CHUNK_SIZE;
@ -1617,6 +1619,51 @@ VkPipeline vk_find_pipeline(const Vk_Pipeline_Def& def) {
return pipeline;
}
void vk_clear_attachments(bool clear_stencil, bool fast_sky) {
if (!vk_active)
return;
if (!vk_resources.dirty_attachments && !fast_sky)
return;
VkClearAttachment attachments[2];
uint32_t attachment_count = fast_sky ? 2 : 1;
attachments[0].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
attachments[0].clearValue.depthStencil.depth = 1.0f;
if (clear_stencil) {
attachments[0].aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
attachments[0].clearValue.depthStencil.stencil = 0;
}
if (fast_sky) {
attachments[1].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
attachments[1].colorAttachment = 0;
attachments[1].clearValue.color = { fast_sky_color[0], fast_sky_color[1], fast_sky_color[2], fast_sky_color[3] };
}
VkClearRect clear_rect[2];
clear_rect[0].rect = vk_get_scissor_rect();
clear_rect[0].baseArrayLayer = 0;
clear_rect[0].layerCount = 1;
int rect_count = 1;
// Split viewport rectangle into two non-overlapping rectangles.
// It's a HACK to prevent Vulkan validation layer's performance warning:
// "vkCmdClearAttachments() issued on command buffer object XXX prior to any Draw Cmds.
// It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw."
//
if (fast_sky) {
uint32_t h = clear_rect[0].rect.extent.height / 2;
clear_rect[0].rect.extent.height = h;
clear_rect[1] = clear_rect[0];
clear_rect[1].rect.offset.y = h;
rect_count = 2;
}
vkCmdClearAttachments(vk.command_buffer, attachment_count, attachments, rect_count, clear_rect);
}
static VkRect2D get_viewport_rect() {
VkRect2D r;
if (backEnd.projection2D) {
@ -1708,6 +1755,8 @@ static void get_mvp_transform(float* mvp) {
}
void vk_bind_resources_shared_between_stages() {
if (!vk_active) return;
// xyz
{
if ((vk.xyz_elements + tess.numVertexes) * sizeof(vec4_t) > XYZ_SIZE)
@ -1821,12 +1870,7 @@ void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bo
// bind descriptor sets
uint32_t set_count = multitexture ? 2 : 1;
VkDescriptorSet sets[2];
sets[0] = vk_resources.images[glState.vk_current_images[0]->index].descriptor_set;
if (multitexture) {
sets[1] = vk_resources.images[glState.vk_current_images[1]->index].descriptor_set;
}
vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk.pipeline_layout, 0, set_count, sets, 0, nullptr);
vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk.pipeline_layout, 0, set_count, vk_resources.current_descriptor_sets, 0, nullptr);
// bind pipeline
vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
@ -1844,6 +1888,9 @@ void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bo
}
void vk_begin_frame() {
if (!vk_active)
return;
if (r_logFile->integer)
fprintf(vk_log_file, "vk_begin_frame\n");
@ -1876,15 +1923,17 @@ void vk_begin_frame() {
render_pass_begin_info.pClearValues = clear_values;
vkCmdBeginRenderPass(vk.command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
vk_resources.dirty_attachments = false;
vk.xyz_elements = 0;
vk.color_st_elements = 0;
vk.index_buffer_offset = 0;
glState.vk_dirty_attachments = false;
}
void vk_end_frame() {
if (!vk_active)
return;
if (r_logFile->integer)
fprintf(vk_log_file, "end_frame (vb_size %d, ib_size %d)\n",
vk.xyz_elements * 16 + vk.color_st_elements * 20,

View File

@ -71,6 +71,7 @@ VkPipeline vk_find_pipeline(const Vk_Pipeline_Def& def);
// Rendering setup.
//
VkRect2D vk_get_scissor_rect();
void vk_clear_attachments(bool clear_stencil, bool fast_sky);
void vk_bind_resources_shared_between_stages();
void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bool sky);
void vk_begin_frame();
@ -175,4 +176,16 @@ struct Vk_Resources {
VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE;
VkDeviceSize staging_buffer_size = 0;
byte* staging_buffer_ptr = nullptr; // pointer to mapped staging buffer
//
// State.
//
// Descriptor sets corresponding to bound texture images.
VkDescriptorSet current_descriptor_sets[2];
// This flag is used to decide whether framebuffer's attachments should be cleared
// with vmCmdClearAttachment (dirty_attachments == true), or they have just been
// cleared by render pass instance clear op (dirty_attachments == false).
bool dirty_attachments;
};