diff --git a/src/engine/platform/win_gamma.c b/src/engine/platform/win_gamma.c index 2a6b117..c047eb5 100644 --- a/src/engine/platform/win_gamma.c +++ b/src/engine/platform/win_gamma.c @@ -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); + } /* diff --git a/src/engine/platform/win_glimp.c b/src/engine/platform/win_glimp.c index fc20d56..496069f 100644 --- a/src/engine/platform/win_glimp.c +++ b/src/engine/platform/win_glimp.c @@ -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(); } diff --git a/src/engine/platform/win_qgl.c b/src/engine/platform/win_qgl.c index 19783d6..22e13af 100644 --- a/src/engine/platform/win_qgl.c +++ b/src/engine/platform/win_qgl.c @@ -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; diff --git a/src/engine/renderer/tr_backend.c b/src/engine/renderer/tr_backend.c index 27966b7..b97a198 100644 --- a/src/engine/renderer/tr_backend.c +++ b/src/engine/renderer/tr_backend.c @@ -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 - 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); + 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,8 +727,10 @@ 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 - const Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index]; - vk_upload_image_data(image.handle, cols, rows, false, data); + if (vk_active) { + const Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index]; + vk_upload_image_data(image.handle, cols, rows, false, data); + } } } } @@ -900,7 +870,7 @@ const void *RB_DrawBuffer( const void *data ) { qglDrawBuffer( cmd->buffer ); // VULKAN - vk_begin_frame(); + vk_begin_frame(); return (const void *)(cmd + 1); } diff --git a/src/engine/renderer/tr_image.c b/src/engine/renderer/tr_image.c index 123f63e..c73a153 100644 --- a/src/engine/renderer/tr_image.c +++ b/src/engine/renderer/tr_image.c @@ -118,8 +118,7 @@ GL_TextureMode =============== */ void GL_TextureMode( const char *string ) { - int i; - image_t *glt; + int i; 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 - Vk_Image& image = vk_resources.images[i]; - vk_update_descriptor_set(image.descriptor_set, image.view, true, glt->wrapClampMode == GL_REPEAT); } } + + // 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 - image = vk_create_image(*pUploadWidth, *pUploadHeight, miplevel + 1, repeat_texture); - vk_upload_image_data(image.handle, *pUploadWidth, *pUploadHeight, mipmap == qtrue, mipmap_buffer); - + 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 ); diff --git a/src/engine/renderer/tr_init.c b/src/engine/renderer/tr_init.c index f4efcbc..6896523 100644 --- a/src/engine/renderer/tr_init.c +++ b/src/engine/renderer/tr_init.c @@ -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(); } diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 16e9590..ade6863 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -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; // diff --git a/src/engine/renderer/tr_shade.c b/src/engine/renderer/tr_shade.c index 4ee2579..49531ef 100644 --- a/src/engine/renderer/tr_shade.c +++ b/src/engine/renderer/tr_shade.c @@ -362,10 +362,12 @@ static void ProjectDlightTexture( void ) { backEnd.pc.c_dlightIndexes += numIndexes; // VULKAN - 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; + 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); + vk_resources.dirty_attachments = true; + } } } @@ -406,11 +408,13 @@ static void RB_FogPass( void ) { R_DrawElements( tess.numIndexes, tess.indexes ); // VULKAN - 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; + 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); + 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,15 +767,17 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) } // VULKAN - VkPipeline pipeline = pStage->vk_pipeline; - if (backEnd.viewParms.isMirror) - pipeline = pStage->vk_mirror_pipeline; - else if (backEnd.viewParms.isPortal) - pipeline = pStage->vk_portal_pipeline; + if (vk_active) { + VkPipeline pipeline = pStage->vk_pipeline; + if (backEnd.viewParms.isMirror) + pipeline = pStage->vk_mirror_pipeline; + else if (backEnd.viewParms.isPortal) + pipeline = pStage->vk_portal_pipeline; - 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_bind_stage_specific_resources(pipeline, multitexture, input->shader->isSky == qtrue); + vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0); + 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 ) ) diff --git a/src/engine/renderer/tr_shader.c b/src/engine/renderer/tr_shader.c index e235199..f680a60 100644 --- a/src/engine/renderer/tr_shader.c +++ b/src/engine/renderer/tr_shader.c @@ -2160,35 +2160,37 @@ static shader_t *FinishShader( void ) { shader.sort = SS_FOG; } - // VULKAN - Vk_Pipeline_Def def; - def.face_culling = shader.cullType; - def.polygon_offset = (shader.polygonOffset == qtrue); + // 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); - for (int i = 0; i < stage; i++) { - shaderStage_t *pStage = &stages[i]; - def.state_bits = pStage->stateBits; + for (int i = 0; i < stage; i++) { + shaderStage_t *pStage = &stages[i]; + def.state_bits = pStage->stateBits; - if (pStage->bundle[1].image[0] == nullptr) - def.shader_type = Vk_Shader_Type::single_texture; - else if (shader.multitextureEnv == GL_MODULATE) - def.shader_type = Vk_Shader_Type::multi_texture_mul; - 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); + if (pStage->bundle[1].image[0] == nullptr) + def.shader_type = Vk_Shader_Type::single_texture; + else if (shader.multitextureEnv == GL_MODULATE) + def.shader_type = Vk_Shader_Type::multi_texture_mul; + else if (shader.multitextureEnv == GL_ADD) + def.shader_type = Vk_Shader_Type::multi_texture_add; + else + ri.Error(ERR_FATAL, "Vulkan: could not create pipelines for q3 shader '%s'\n", shader.name); - def.clipping_plane = false; - def.mirror = false; - pStage->vk_pipeline = vk_find_pipeline(def); + def.clipping_plane = false; + def.mirror = false; + pStage->vk_pipeline = vk_find_pipeline(def); - def.clipping_plane = true; - def.mirror = false; - pStage->vk_portal_pipeline = vk_find_pipeline(def); + def.clipping_plane = true; + def.mirror = false; + pStage->vk_portal_pipeline = vk_find_pipeline(def); - def.clipping_plane = true; - def.mirror = true; - pStage->vk_mirror_pipeline = vk_find_pipeline(def); + def.clipping_plane = true; + def.mirror = true; + pStage->vk_mirror_pipeline = vk_find_pipeline(def); + } } return GeneratePermanentShader(); diff --git a/src/engine/renderer/tr_sky.c b/src/engine/renderer/tr_sky.c index 60536fc..94da1d0 100644 --- a/src/engine/renderer/tr_sky.c +++ b/src/engine/renderer/tr_sky.c @@ -450,52 +450,56 @@ static void DrawSkyBox( shader_t *shader ) sky_mins_subd, sky_maxs_subd ); - // VULKAN - glState.vk_current_images[0] = shader->sky.outerbox[sky_texorder[i]]; - tess.numVertexes = 0; - tess.numIndexes = 0; + // 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; - for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t < sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ ) - { - for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s < sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ ) + tess.numVertexes = 0; + tess.numIndexes = 0; + + for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t < sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ ) { - int ndx = tess.numVertexes; + for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s < sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ ) + { + int ndx = tess.numVertexes; - tess.indexes[ tess.numIndexes ] = ndx; - tess.indexes[ tess.numIndexes + 1 ] = ndx + 1; - tess.indexes[ tess.numIndexes + 2 ] = ndx + 2; + tess.indexes[ tess.numIndexes ] = ndx; + tess.indexes[ tess.numIndexes + 1 ] = ndx + 1; + tess.indexes[ tess.numIndexes + 2 ] = ndx + 2; - tess.indexes[ tess.numIndexes + 3 ] = ndx + 2; - tess.indexes[ tess.numIndexes + 4 ] = ndx + 1; - tess.indexes[ tess.numIndexes + 5 ] = ndx + 3; - tess.numIndexes += 6; + tess.indexes[ tess.numIndexes + 3 ] = ndx + 2; + tess.indexes[ tess.numIndexes + 4 ] = ndx + 1; + tess.indexes[ tess.numIndexes + 5 ] = ndx + 3; + tess.numIndexes += 6; - VectorCopy(s_skyPoints[t][s], tess.xyz[ndx]); - tess.svars.texcoords[0][ndx][0] = s_skyTexCoords[t][s][0]; - tess.svars.texcoords[0][ndx][1] = s_skyTexCoords[t][s][1]; + VectorCopy(s_skyPoints[t][s], tess.xyz[ndx]); + tess.svars.texcoords[0][ndx][0] = s_skyTexCoords[t][s][0]; + tess.svars.texcoords[0][ndx][1] = s_skyTexCoords[t][s][1]; - VectorCopy(s_skyPoints[t + 1][s], tess.xyz[ndx + 1]); - tess.svars.texcoords[0][ndx + 1][0] = s_skyTexCoords[t + 1][s][0]; - tess.svars.texcoords[0][ndx + 1][1] = s_skyTexCoords[t + 1][s][1]; + VectorCopy(s_skyPoints[t + 1][s], tess.xyz[ndx + 1]); + tess.svars.texcoords[0][ndx + 1][0] = s_skyTexCoords[t + 1][s][0]; + tess.svars.texcoords[0][ndx + 1][1] = s_skyTexCoords[t + 1][s][1]; - VectorCopy(s_skyPoints[t][s + 1], tess.xyz[ndx + 2]); - tess.svars.texcoords[0][ndx + 2][0] = s_skyTexCoords[t][s + 1][0]; - tess.svars.texcoords[0][ndx + 2][1] = s_skyTexCoords[t][s + 1][1]; + VectorCopy(s_skyPoints[t][s + 1], tess.xyz[ndx + 2]); + tess.svars.texcoords[0][ndx + 2][0] = s_skyTexCoords[t][s + 1][0]; + tess.svars.texcoords[0][ndx + 2][1] = s_skyTexCoords[t][s + 1][1]; - VectorCopy(s_skyPoints[t + 1][s + 1], tess.xyz[ndx + 3]); - tess.svars.texcoords[0][ndx + 3][0] = s_skyTexCoords[t + 1][s + 1][0]; - tess.svars.texcoords[0][ndx + 3][1] = s_skyTexCoords[t + 1][s + 1][1]; + VectorCopy(s_skyPoints[t + 1][s + 1], tess.xyz[ndx + 3]); + tess.svars.texcoords[0][ndx + 3][0] = s_skyTexCoords[t + 1][s + 1][0]; + tess.svars.texcoords[0][ndx + 3][1] = s_skyTexCoords[t + 1][s + 1][1]; - tess.numVertexes += 4; + tess.numVertexes += 4; + } } - } - Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 ); - 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.xyz_elements += tess.numVertexes; + Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 ); + 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); + vk_resources.dirty_attachments = true; + vk.xyz_elements += tess.numVertexes; + } } } diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index a6c84eb..92297b2 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -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, diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index daf216b..ee97e97 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -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; };