<commit_before>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_FAULTS_HH__
#define __ARCH_X86_FAULTS_HH__

#include "base/misc.hh"
#include "sim/faults.hh"

namespace X86ISA
{
    // Base class for all x86 "faults" where faults is in the m5 sense
    class X86FaultBase : public FaultBase
    {
      protected:
        const char * faultName;
        const char * mnem;
        uint64_t errorCode;

        X86FaultBase(const char * _faultName, const char * _mnem,
                uint64_t _errorCode = 0) :
            faultName(_faultName), mnem(_mnem), errorCode(_errorCode)
        {
        }

        const char * name() const
        {
            return faultName;
        }

        virtual bool isBenign()
        {
            return true;
        }

        virtual const char * mnemonic() const
        {
            return mnem;
        }
    };

    // Base class for x86 faults which behave as if the underlying instruction
    // didn't happen.
    class X86Fault : public X86FaultBase
    {
      protected:
        X86Fault(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}
    };

    // Base class for x86 traps which behave as if the underlying instruction
    // completed.
    class X86Trap : public X86FaultBase
    {
      protected:
        X86Trap(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}

#if FULL_SYSTEM
        void invoke(ThreadContext * tc);
#endif
    };

    // Base class for x86 aborts which seem to be catastrophic failures.
    class X86Abort : public X86FaultBase
    {
      protected:
        X86Abort(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}

#if FULL_SYSTEM
        void invoke(ThreadContext * tc);
#endif
    };

    // Base class for x86 interrupts.
    class X86Interrupt : public X86FaultBase
    {
      protected:
        X86Interrupt(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}

#if FULL_SYSTEM
        void invoke(ThreadContext * tc);
#endif
    };

    class UnimpInstFault : public FaultBase
    {
      public:
        const char * name() const
        {
            return "unimplemented_micro";
        }

        void invoke(ThreadContext * tc)
        {
            panic("Unimplemented instruction!");
        }
    };

    static inline Fault genMachineCheckFault()
    {
        panic("Machine check fault not implemented in x86!\n");
    }

    // Below is a summary of the interrupt/exception information in the
    // architecture manuals.

    // Class  |  Type    | vector |               Cause                 | mnem
    //------------------------------------------------------------------------
    //Contrib   Fault     0         Divide-by-Zero-Error                  #DE
    //Benign    Either    1         Debug                                 #DB
    //Benign    Interrupt 2         Non-Maskable-Interrupt                #NMI
    //Benign    Trap      3         Breakpoint                            #BP
    //Benign    Trap      4         Overflow                              #OF
    //Benign    Fault     5         Bound-Range                           #BR
    //Benign    Fault     6         Invalid-Opcode                        #UD
    //Benign    Fault     7         Device-Not-Available                  #NM
    //Benign    Abort     8         Double-Fault                          #DF
    //                    9         Coprocessor-Segment-Overrun
    //Contrib   Fault     10        Invalid-TSS                           #TS
    //Contrib   Fault     11        Segment-Not-Present                   #NP
    //Contrib   Fault     12        Stack                                 #SS
    //Contrib   Fault     13        General-Protection                    #GP
    //Either    Fault     14        Page-Fault                            #PF
    //                    15        Reserved
    //Benign    Fault     16        x87 Floating-Point Exception Pending  #MF
    //Benign    Fault     17        Alignment-Check                       #AC
    //Benign    Abort     18        Machine-Check                         #MC
    //Benign    Fault     19        SIMD Floating-Point                   #XF
    //                    20-29     Reserved
    //Contrib   ?         30        Security Exception                    #SX
    //                    31        Reserved
    //Benign    Interrupt 0-255     External Interrupts                   #INTR
    //Benign    Interrupt 0-255     Software Interrupts                   INTn

    class DivideByZero : public X86Fault
    {
      public:
        DivideByZero() :
            X86Fault("Divide-by-Zero-Error", "#DE")
        {}
    };

    class DebugException : public X86FaultBase
    {
      public:
        DebugException() :
            X86FaultBase("Debug", "#DB")
        {}
    };

    class NonMaskableInterrupt : public X86Interrupt
    {
      public:
        NonMaskableInterrupt() :
            X86Interrupt("Non-Maskable-Interrupt", "#NMI")
        {}
    };

    class Breakpoint : public X86Trap
    {
      public:
        Breakpoint() :
            X86Trap("Breakpoint", "#BP")
        {}
    };

    class OverflowTrap : public X86Trap
    {
      public:
        OverflowTrap() :
            X86Trap("Overflow", "#OF")
        {}
    };

    class BoundRange : public X86Fault
    {
      public:
        BoundRange() :
            X86Fault("Bound-Range", "#BR")
        {}
    };

    class InvalidOpcode : public X86Fault
    {
      public:
        InvalidOpcode() :
            X86Fault("Invalid-Opcode", "#UD")
        {}
    };

    class DeviceNotAvailable : public X86Fault
    {
      public:
        DeviceNotAvailable() :
            X86Fault("Device-Not-Available", "#NM")
        {}
    };

    class DoubleFault : public X86Abort
    {
      public:
        DoubleFault() :
            X86Abort("Double-Fault", "#DF")
        {}
    };

    class InvalidTSS : public X86Fault
    {
      public:
        InvalidTSS() :
            X86Fault("Invalid-TSS", "#TS")
        {}
    };

    class SegmentNotPresent : public X86Fault
    {
      public:
        SegmentNotPresent() :
            X86Fault("Segment-Not-Present", "#NP")
        {}
    };

    class StackFault : public X86Fault
    {
      public:
        StackFault() :
            X86Fault("Stack", "#SS")
        {}
    };

    class GeneralProtection : public X86Fault
    {
      public:
        GeneralProtection(uint64_t _errorCode) :
            X86Fault("General-Protection", "#GP", _errorCode)
        {}
    };

    class PageFault : public X86Fault
    {
      public:
        PageFault() :
            X86Fault("Page-Fault", "#PF")
        {}
    };

    class X87FpExceptionPending : public X86Fault
    {
      public:
        X87FpExceptionPending() :
            X86Fault("x87 Floating-Point Exception Pending", "#MF")
        {}
    };

    class AlignmentCheck : X86Fault
    {
      public:
        AlignmentCheck() :
            X86Fault("Alignment-Check", "#AC")
        {}
    };

    class MachineCheck : X86Abort
    {
      public:
        MachineCheck() :
            X86Abort("Machine-Check", "#MC")
        {}
    };

    class SIMDFloatingPointFault : X86Fault
    {
      public:
        SIMDFloatingPointFault() :
            X86Fault("SIMD Floating-Point", "#XF")
        {}
    };

    class SecurityException : X86FaultBase
    {
      public:
        SecurityException() :
            X86FaultBase("Security Exception", "#SX")
        {}
    };

    class ExternalInterrupt : X86Interrupt
    {
      public:
        ExternalInterrupt() :
            X86Interrupt("External Interrupt", "#INTR")
        {}
    };

    class SoftwareInterrupt : X86Interrupt
    {
      public:
        SoftwareInterrupt() :
            X86Interrupt("Software Interrupt", "INTn")
        {}
    };

    // These faults aren't part of the ISA definition. They trigger filling
    // the tlb on a miss and are to take the place of a hardware table walker.
    class FakeITLBFault : public X86Fault
    {
      protected:
        Addr vaddr;
      public:
        FakeITLBFault(Addr _vaddr) :
            X86Fault("fake instruction tlb fault", "itlb"),
            vaddr(_vaddr)
        {}

        void invoke(ThreadContext * tc);
    };

    class FakeDTLBFault : public X86Fault
    {
      protected:
        Addr vaddr;
      public:
        FakeDTLBFault(Addr _vaddr) :
            X86Fault("fake data tlb fault", "dtlb"),
            vaddr(_vaddr)
        {}

        void invoke(ThreadContext * tc);
    };
};

#endif // __ARCH_X86_FAULTS_HH__
<commit_msg>X86: Make the bases for x86 fault class public.<commit_after>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_FAULTS_HH__
#define __ARCH_X86_FAULTS_HH__

#include "base/misc.hh"
#include "sim/faults.hh"

namespace X86ISA
{
    // Base class for all x86 "faults" where faults is in the m5 sense
    class X86FaultBase : public FaultBase
    {
      protected:
        const char * faultName;
        const char * mnem;
        uint64_t errorCode;

        X86FaultBase(const char * _faultName, const char * _mnem,
                uint64_t _errorCode = 0) :
            faultName(_faultName), mnem(_mnem), errorCode(_errorCode)
        {
        }

        const char * name() const
        {
            return faultName;
        }

        virtual bool isBenign()
        {
            return true;
        }

        virtual const char * mnemonic() const
        {
            return mnem;
        }
    };

    // Base class for x86 faults which behave as if the underlying instruction
    // didn't happen.
    class X86Fault : public X86FaultBase
    {
      protected:
        X86Fault(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}
    };

    // Base class for x86 traps which behave as if the underlying instruction
    // completed.
    class X86Trap : public X86FaultBase
    {
      protected:
        X86Trap(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}

#if FULL_SYSTEM
        void invoke(ThreadContext * tc);
#endif
    };

    // Base class for x86 aborts which seem to be catastrophic failures.
    class X86Abort : public X86FaultBase
    {
      protected:
        X86Abort(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}

#if FULL_SYSTEM
        void invoke(ThreadContext * tc);
#endif
    };

    // Base class for x86 interrupts.
    class X86Interrupt : public X86FaultBase
    {
      protected:
        X86Interrupt(const char * name, const char * mnem,
                uint64_t _errorCode = 0) :
            X86FaultBase(name, mnem, _errorCode)
        {}

#if FULL_SYSTEM
        void invoke(ThreadContext * tc);
#endif
    };

    class UnimpInstFault : public FaultBase
    {
      public:
        const char * name() const
        {
            return "unimplemented_micro";
        }

        void invoke(ThreadContext * tc)
        {
            panic("Unimplemented instruction!");
        }
    };

    static inline Fault genMachineCheckFault()
    {
        panic("Machine check fault not implemented in x86!\n");
    }

    // Below is a summary of the interrupt/exception information in the
    // architecture manuals.

    // Class  |  Type    | vector |               Cause                 | mnem
    //------------------------------------------------------------------------
    //Contrib   Fault     0         Divide-by-Zero-Error                  #DE
    //Benign    Either    1         Debug                                 #DB
    //Benign    Interrupt 2         Non-Maskable-Interrupt                #NMI
    //Benign    Trap      3         Breakpoint                            #BP
    //Benign    Trap      4         Overflow                              #OF
    //Benign    Fault     5         Bound-Range                           #BR
    //Benign    Fault     6         Invalid-Opcode                        #UD
    //Benign    Fault     7         Device-Not-Available                  #NM
    //Benign    Abort     8         Double-Fault                          #DF
    //                    9         Coprocessor-Segment-Overrun
    //Contrib   Fault     10        Invalid-TSS                           #TS
    //Contrib   Fault     11        Segment-Not-Present                   #NP
    //Contrib   Fault     12        Stack                                 #SS
    //Contrib   Fault     13        General-Protection                    #GP
    //Either    Fault     14        Page-Fault                            #PF
    //                    15        Reserved
    //Benign    Fault     16        x87 Floating-Point Exception Pending  #MF
    //Benign    Fault     17        Alignment-Check                       #AC
    //Benign    Abort     18        Machine-Check                         #MC
    //Benign    Fault     19        SIMD Floating-Point                   #XF
    //                    20-29     Reserved
    //Contrib   ?         30        Security Exception                    #SX
    //                    31        Reserved
    //Benign    Interrupt 0-255     External Interrupts                   #INTR
    //Benign    Interrupt 0-255     Software Interrupts                   INTn

    class DivideByZero : public X86Fault
    {
      public:
        DivideByZero() :
            X86Fault("Divide-by-Zero-Error", "#DE")
        {}
    };

    class DebugException : public X86FaultBase
    {
      public:
        DebugException() :
            X86FaultBase("Debug", "#DB")
        {}
    };

    class NonMaskableInterrupt : public X86Interrupt
    {
      public:
        NonMaskableInterrupt() :
            X86Interrupt("Non-Maskable-Interrupt", "#NMI")
        {}
    };

    class Breakpoint : public X86Trap
    {
      public:
        Breakpoint() :
            X86Trap("Breakpoint", "#BP")
        {}
    };

    class OverflowTrap : public X86Trap
    {
      public:
        OverflowTrap() :
            X86Trap("Overflow", "#OF")
        {}
    };

    class BoundRange : public X86Fault
    {
      public:
        BoundRange() :
            X86Fault("Bound-Range", "#BR")
        {}
    };

    class InvalidOpcode : public X86Fault
    {
      public:
        InvalidOpcode() :
            X86Fault("Invalid-Opcode", "#UD")
        {}
    };

    class DeviceNotAvailable : public X86Fault
    {
      public:
        DeviceNotAvailable() :
            X86Fault("Device-Not-Available", "#NM")
        {}
    };

    class DoubleFault : public X86Abort
    {
      public:
        DoubleFault() :
            X86Abort("Double-Fault", "#DF")
        {}
    };

    class InvalidTSS : public X86Fault
    {
      public:
        InvalidTSS() :
            X86Fault("Invalid-TSS", "#TS")
        {}
    };

    class SegmentNotPresent : public X86Fault
    {
      public:
        SegmentNotPresent() :
            X86Fault("Segment-Not-Present", "#NP")
        {}
    };

    class StackFault : public X86Fault
    {
      public:
        StackFault() :
            X86Fault("Stack", "#SS")
        {}
    };

    class GeneralProtection : public X86Fault
    {
      public:
        GeneralProtection(uint64_t _errorCode) :
            X86Fault("General-Protection", "#GP", _errorCode)
        {}
    };

    class PageFault : public X86Fault
    {
      public:
        PageFault() :
            X86Fault("Page-Fault", "#PF")
        {}
    };

    class X87FpExceptionPending : public X86Fault
    {
      public:
        X87FpExceptionPending() :
            X86Fault("x87 Floating-Point Exception Pending", "#MF")
        {}
    };

    class AlignmentCheck : public X86Fault
    {
      public:
        AlignmentCheck() :
            X86Fault("Alignment-Check", "#AC")
        {}
    };

    class MachineCheck : public X86Abort
    {
      public:
        MachineCheck() :
            X86Abort("Machine-Check", "#MC")
        {}
    };

    class SIMDFloatingPointFault : public X86Fault
    {
      public:
        SIMDFloatingPointFault() :
            X86Fault("SIMD Floating-Point", "#XF")
        {}
    };

    class SecurityException : public X86FaultBase
    {
      public:
        SecurityException() :
            X86FaultBase("Security Exception", "#SX")
        {}
    };

    class ExternalInterrupt : public X86Interrupt
    {
      public:
        ExternalInterrupt() :
            X86Interrupt("External Interrupt", "#INTR")
        {}
    };

    class SoftwareInterrupt : public X86Interrupt
    {
      public:
        SoftwareInterrupt() :
            X86Interrupt("Software Interrupt", "INTn")
        {}
    };

    // These faults aren't part of the ISA definition. They trigger filling
    // the tlb on a miss and are to take the place of a hardware table walker.
    class FakeITLBFault : public X86Fault
    {
      protected:
        Addr vaddr;
      public:
        FakeITLBFault(Addr _vaddr) :
            X86Fault("fake instruction tlb fault", "itlb"),
            vaddr(_vaddr)
        {}

        void invoke(ThreadContext * tc);
    };

    class FakeDTLBFault : public X86Fault
    {
      protected:
        Addr vaddr;
      public:
        FakeDTLBFault(Addr _vaddr) :
            X86Fault("fake data tlb fault", "dtlb"),
            vaddr(_vaddr)
        {}

        void invoke(ThreadContext * tc);
    };
};

#endif // __ARCH_X86_FAULTS_HH__
<|endoftext|>


<commit_before>
#include <vector>
#include <unordered_map>
#include <iostream>
#include <string>
#include <memory>
#include <glew.h>
#include <SDL.h>
#include <SDL_rwops.h>
#include <SOIL.h>

#include "tuple.h"
#include "threedee.h"
#include "matrix44.h"
#include "hashstring.h"
#include "locator.h"
#include "servicecounter.h"
#include "service.h"
#include "servicecheckout.h"
#include "serviceregistry.h"
#include "image.h"
#include "texture.h"
#include "shader.h"
#include "program.h"
#include "buffer.h"
#include "renderstate.h"
#include <res_path.h>

using namespace venk;

const int screen_width  = 640;
const int screen_height = 480;

GLuint gVBO = 0;
GLuint gIBO = 0;

void render_texture(SDL_Texture *tex, SDL_Renderer* ren, int x, int y)
{
    SDL_Rect dst;
    dst.x = x;
    dst.y = y;
    SDL_QueryTexture(tex, nullptr, nullptr, &dst.w, &dst.h);
    SDL_RenderCopy(ren, tex, NULL, &dst);
}

using bufferPair_t = std::pair< std::shared_ptr<Buffer>, std::shared_ptr<Buffer> >;

bufferPair_t init_buffers()
{
	/*
	 * Data used to seed our vertex array and element array buffers:
	 */
	static const GLfloat testVertices[] = {
		-1.0f, -1.0f,
		1.0f, -1.0f,
		-1.0f, 1.0f,
		1.0f, 1.0f
	};

	static const GLushort testElements[] = { 0, 1, 2, 3 };

	ServiceCheckout<BufferManagerService> buffers;

	auto vb = buffers->make_buffer(GL_ARRAY_BUFFER,  (const void*) testVertices, GL_FLOAT, 4, 2, GL_STATIC_DRAW);
	auto ib = buffers->make_buffer(GL_ELEMENT_ARRAY_BUFFER, (const void*) testElements, GL_UNSIGNED_SHORT, 4, 1, GL_STATIC_DRAW);
	bufferPair_t result = make_pair(vb, ib);
	return result;
}

void render(SDL_Window* window, SDL_Renderer* renderer, Texture* texture, Program *simple, bufferPair_t buffers)
{
	(void) renderer;
	// Clear the color and depth buffers
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	simple->use();
	texture->select();
	simple->setUniformSampler("textureMap", 0, texture);
	auto vb = buffers.first;
	auto ib = buffers.second;
	vb->bindAttribute(simple, "vVertex");
	ib->bindIndices();
	ib->draw();
	ib->unbindIndices();
	vb->unbindAttribute(simple, "vVertex");
	texture->deselect();
	simple->unUse();
	SDL_GL_SwapWindow(window);
	SDL_Delay(5000);
}

int main(int argc, char **argv)
{

	(void) argc;
	(void) argv;
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
		std::cerr << "SDL_Init error: " << SDL_GetError() << std::endl;
		return 1;
    } else {

		SDL_SetHint( SDL_HINT_RENDER_DRIVER, "opengl" );
		SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
		SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
		SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

		std::cout << "Resource path is: " << getResourcePath() << std::endl;

		auto window_deleter = [] (SDL_Window *w) {
			if (w) SDL_DestroyWindow(w);
		};
		std::shared_ptr<SDL_Window> window(SDL_CreateWindow( "SDLSkeleton",
															 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
															 screen_width, screen_height,
															 SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
										   window_deleter );
		if (!window) {
			std::cerr << "Unable to create SDL_Window" << std::endl;
		} else {
			auto renderer_deleter = [](SDL_Renderer *r) {
				if (r) SDL_DestroyRenderer(r);
			};
			Uint32 n_drivers = SDL_GetNumRenderDrivers();
			std::cout << n_drivers << " render drivers available" << std::endl;
			for(Uint32 i = 0; i < n_drivers; i++) {
				SDL_RendererInfo info;
				SDL_GetRenderDriverInfo(i, &info);
				std::cout << i << " " << info.name << std::endl;
			}
			Uint32 flags = SDL_RENDERER_ACCELERATED  |  SDL_RENDERER_TARGETTEXTURE;
			std::shared_ptr<SDL_Renderer> renderer(SDL_CreateRenderer(window.get(), -1, flags),  renderer_deleter);
			if (renderer) {

				SDL_RendererInfo info;
				SDL_GetRendererInfo(renderer.get(), &info);
				std::cout << " Renderer chosen " << info.name << std::endl;

				SDL_GLContext glctx = SDL_GL_CreateContext(window.get());
				SDL_assert(glctx != nullptr);

				Uint32 err = glewInit();
				if (err != GLEW_OK) {
					std::cerr << "Glew init failed " << glewGetErrorString(GLEW_VERSION) << std::endl;
					SDL_Quit();
					exit(-1);
				}

				GLdouble maj = 0;
				glGetDoublev(GL_MAJOR_VERSION, &maj);
				GLdouble min = 0;
				glGetDoublev(GL_MINOR_VERSION, &min);

				std::cout << "OpenGL Version: " << maj << "." << min << std::endl;

				//Use Vsync
				if( SDL_GL_SetSwapInterval( 1 ) < 0 ) {
					std::cerr <<  "Warning: Unable to set VSync! SDL Error: " << SDL_GetError() << std::endl;
				}

				// Enable depth testing
				glEnable(GL_DEPTH_TEST);
				glDepthFunc(GL_LEQUAL);

				// Set the clear color for when we re-draw the scene
				glClearColor(0.1, 0.1, 0.6, 1.0);

				ServiceRegistry<ImageService>::initialise();
				ServiceCheckout<ImageService> images;
				std::shared_ptr<Image> img(images->loadImage("test.tga"));
				if (img) {
					ServiceRegistry<TextureService>::initialise();
					ServiceRegistry<ProgramService>::initialise();
					ServiceRegistry<BufferManagerService>::initialise();
					ServiceRegistry<RenderStateService>::initialise();
					{
						ServiceCheckout<TextureService> textures;
						textures->setRenderer(renderer);
						std::shared_ptr<Texture> tex(textures->makeTexture(img.get(), true));
						ServiceCheckout<ProgramService> programs;
						std::shared_ptr<Program> simple(programs->loadProgram("test"));
						SDL_assert(simple->isValid());
						// ortho view, 100 units deep
						Matrix44 projection;
						projection.ortho(0.0f, (float) screen_width, 0.0f, (float) screen_height, 0.0f,  100.0f);
						bufferPair_t buffers(init_buffers());

						ServiceCheckout<RenderStateService> renderState;
						// to do - clean this up with a template make_parameter fn
						RenderParameter projParam;
						projParam.type = eMAT4;
						for(Uint32 i = 0; i < 16; i++)
							projParam.value.mat4[i] = projection.elements[i];
						renderState->set("projection", projParam);
						if (tex) {
							render(window.get(), renderer.get(), tex.get(), simple.get(), buffers);
						} else {
							std::cerr << "Creating texture failed" << std::endl;
						}
					}
					ServiceRegistry<RenderStateService>::shutdown();
					ServiceRegistry<BufferManagerService>::shutdown();
					ServiceRegistry<ProgramService>::shutdown();
					ServiceRegistry<TextureService>::shutdown();
					SDL_GL_DeleteContext(glctx);
				} else {
					std::cerr << "Loading image failed" << std::endl;
				}
			} else {
				std::cerr << "Creating renderer failed" << std::endl;
			}
			ServiceRegistry<ImageService>::shutdown();
		}
    }
    SDL_Quit();
    return 0;
}
<commit_msg>Make program quittable<commit_after>
#include <vector>
#include <unordered_map>
#include <iostream>
#include <string>
#include <memory>
#include <glew.h>
#include <SDL.h>
#include <SDL_rwops.h>
#include <SOIL.h>

#include "tuple.h"
#include "threedee.h"
#include "matrix44.h"
#include "hashstring.h"
#include "locator.h"
#include "servicecounter.h"
#include "service.h"
#include "servicecheckout.h"
#include "serviceregistry.h"
#include "image.h"
#include "texture.h"
#include "shader.h"
#include "program.h"
#include "buffer.h"
#include "renderstate.h"
#include <res_path.h>

using namespace venk;

const int screen_width  = 640;
const int screen_height = 480;

GLuint gVBO = 0;
GLuint gIBO = 0;

void render_texture(SDL_Texture *tex, SDL_Renderer* ren, int x, int y)
{
    SDL_Rect dst;
    dst.x = x;
    dst.y = y;
    SDL_QueryTexture(tex, nullptr, nullptr, &dst.w, &dst.h);
    SDL_RenderCopy(ren, tex, NULL, &dst);
}

using bufferPair_t = std::pair< std::shared_ptr<Buffer>, std::shared_ptr<Buffer> >;

bufferPair_t init_buffers()
{
	/*
	 * Data used to seed our vertex array and element array buffers:
	 */
	static const GLfloat testVertices[] = {
		-1.0f, -1.0f,
		1.0f, -1.0f,
		-1.0f, 1.0f,
		1.0f, 1.0f
	};

	static const GLushort testElements[] = { 0, 1, 2, 3 };

	ServiceCheckout<BufferManagerService> buffers;

	auto vb = buffers->make_buffer(GL_ARRAY_BUFFER,  (const void*) testVertices, GL_FLOAT, 4, 2, GL_STATIC_DRAW);
	auto ib = buffers->make_buffer(GL_ELEMENT_ARRAY_BUFFER, (const void*) testElements, GL_UNSIGNED_SHORT, 4, 1, GL_STATIC_DRAW);
	bufferPair_t result = make_pair(vb, ib);
	return result;
}

void render(SDL_Window* window, SDL_Renderer* renderer, Texture* texture, Program *simple, bufferPair_t buffers)
{
	(void) renderer;
	// Clear the color and depth buffers
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	simple->use();
	texture->select();
	simple->setUniformSampler("textureMap", 0, texture);
	auto vb = buffers.first;
	auto ib = buffers.second;
	vb->bindAttribute(simple, "vVertex");
	ib->bindIndices();
	ib->draw();
	ib->unbindIndices();
	vb->unbindAttribute(simple, "vVertex");
	texture->deselect();
	simple->unUse();
	SDL_GL_SwapWindow(window);
}

int main(int argc, char **argv)
{

	(void) argc;
	(void) argv;
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
		std::cerr << "SDL_Init error: " << SDL_GetError() << std::endl;
		return 1;
    } else {

		SDL_SetHint( SDL_HINT_RENDER_DRIVER, "opengl" );
		SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
		SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
		SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

		std::cout << "Resource path is: " << getResourcePath() << std::endl;

		auto window_deleter = [] (SDL_Window *w) {
			if (w) SDL_DestroyWindow(w);
		};
		std::shared_ptr<SDL_Window> window(SDL_CreateWindow( "SDLSkeleton",
															 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
															 screen_width, screen_height,
															 SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
										   window_deleter );
		if (!window) {
			std::cerr << "Unable to create SDL_Window" << std::endl;
		} else {
			auto renderer_deleter = [](SDL_Renderer *r) {
				if (r) SDL_DestroyRenderer(r);
			};
			Uint32 n_drivers = SDL_GetNumRenderDrivers();
			std::cout << n_drivers << " render drivers available" << std::endl;
			for(Uint32 i = 0; i < n_drivers; i++) {
				SDL_RendererInfo info;
				SDL_GetRenderDriverInfo(i, &info);
				std::cout << i << " " << info.name << std::endl;
			}
			Uint32 flags = SDL_RENDERER_ACCELERATED  |  SDL_RENDERER_TARGETTEXTURE;
			std::shared_ptr<SDL_Renderer> renderer(SDL_CreateRenderer(window.get(), -1, flags),  renderer_deleter);
			if (renderer) {

				SDL_RendererInfo info;
				SDL_GetRendererInfo(renderer.get(), &info);
				std::cout << " Renderer chosen " << info.name << std::endl;

				SDL_GLContext glctx = SDL_GL_CreateContext(window.get());
				SDL_assert(glctx != nullptr);

				Uint32 err = glewInit();
				if (err != GLEW_OK) {
					std::cerr << "Glew init failed " << glewGetErrorString(GLEW_VERSION) << std::endl;
					SDL_Quit();
					exit(-1);
				}

				GLdouble maj = 0;
				glGetDoublev(GL_MAJOR_VERSION, &maj);
				GLdouble min = 0;
				glGetDoublev(GL_MINOR_VERSION, &min);

				std::cout << "OpenGL Version: " << maj << "." << min << std::endl;

				//Use Vsync
				if( SDL_GL_SetSwapInterval( 1 ) < 0 ) {
					std::cerr <<  "Warning: Unable to set VSync! SDL Error: " << SDL_GetError() << std::endl;
				}

				// Enable depth testing
				glEnable(GL_DEPTH_TEST);
				glDepthFunc(GL_LEQUAL);

				// Set the clear color for when we re-draw the scene
				glClearColor(0.1, 0.1, 0.6, 1.0);

				ServiceRegistry<ImageService>::initialise();
				ServiceCheckout<ImageService> images;
				std::shared_ptr<Image> img(images->loadImage("test.tga"));
				if (img) {
					ServiceRegistry<TextureService>::initialise();
					ServiceRegistry<ProgramService>::initialise();
					ServiceRegistry<BufferManagerService>::initialise();
					ServiceRegistry<RenderStateService>::initialise();
					{
						ServiceCheckout<TextureService> textures;
						textures->setRenderer(renderer);
						std::shared_ptr<Texture> tex(textures->makeTexture(img.get(), true));
						ServiceCheckout<ProgramService> programs;
						std::shared_ptr<Program> simple(programs->loadProgram("test"));
						SDL_assert(simple->isValid());
						// ortho view, 100 units deep
						Matrix44 projection;
						projection.ortho(0.0f, (float) screen_width, 0.0f, (float) screen_height, 0.0f,  100.0f);
						bufferPair_t buffers(init_buffers());

						ServiceCheckout<RenderStateService> renderState;
						// to do - clean this up with a template make_parameter fn
						RenderParameter projParam;
						projParam.type = eMAT4;
						for(Uint32 i = 0; i < 16; i++)
							projParam.value.mat4[i] = projection.elements[i];
						renderState->set("projection", projParam);
						if (tex) {
							bool quit = false;
							SDL_Event e;
							while (!quit) {
								//Handle events on queue
								while( SDL_PollEvent( &e ) != 0 ) {
									//User requests quit
									if( e.type == SDL_QUIT ) {
										quit = true;
									}
								}
								render(window.get(), renderer.get(), tex.get(), simple.get(), buffers);
							}
						} else {
							std::cerr << "Creating texture failed" << std::endl;
						}
					}
					ServiceRegistry<RenderStateService>::shutdown();
					ServiceRegistry<BufferManagerService>::shutdown();
					ServiceRegistry<ProgramService>::shutdown();
					ServiceRegistry<TextureService>::shutdown();
					SDL_GL_DeleteContext(glctx);
				} else {
					std::cerr << "Loading image failed" << std::endl;
				}
			} else {
				std::cerr << "Creating renderer failed" << std::endl;
			}
			ServiceRegistry<ImageService>::shutdown();
		}
    }
    SDL_Quit();
    return 0;
}
<|endoftext|>


<commit_before>#include <qore/common.h>
#include <qore/QoreValue.h>
#include <qore/DBI.h>
#include <qore/QoreEncoding.h>
#include <qore/QoreString.h>
#include <qore/SQLStatement.h>
#include <qore/QoreStringNode.h>
#include <qore/AbstractPrivateData.h>
#include <qore/QoreQueue.h>
#include <qore/Datasource.h>
#include <qore/QoreListNode.h>
#include <qore/QoreHashNode.h>
#include <qore/QoreValue.h>

#include "connection.h"
#include "emptystatement.h"
#include "command.h"
#include "dbmodulewrap.h"
#include "utils.h"

namespace ss {

inline bool expect_row(command::ResType rt) {
    switch (rt) {
        case command::RES_ROW:
        case command::RES_PARAM:
            return true;
        default:
            return false;
    }
}

class Statement : public EmptyStatement {
    QoreHashNode *_execRes;

    bool has_res() {
        return _execRes ? true : false;
    }

    void set_res(QoreHashNode *res, ExceptionSink* xsink) {
        if (_execRes) _execRes->deref(xsink);
        _execRes = res;
    }

    QoreHashNode * release_res() {
        QoreHashNode *rv = _execRes;
        _execRes = 0;
        return rv;
    }

    ~Statement() {}

    SafePtr<command> context;
    Placeholders placeholders;
public:
    typedef connection Connection;

    Statement() : _execRes(0) {}

    static void Delete(Statement *self, ExceptionSink* xsink) {
        if (!self) return;
        self->set_res(0, xsink);
        delete self;
    }

    int exec(connection *conn,
            const QoreString *query,
            const QoreListNode *args,
            bool raw,
            ExceptionSink* xsink)
    {
#ifdef _QORE_HAS_DBI_EXECRAW
        if (raw) {
            context.reset(conn->create_command(query, xsink));
        } else
#endif
        {
            context.reset(conn->create_command(query, args, xsink));
        }
        return 0;
    }

    bool next(SQLStatement* stmt, ExceptionSink* xsink) {
        command::ResType res = context->read_next_result(xsink);
        if (expect_row(res)) {
            if (!has_res()) {
                set_res(context->fetch_row(xsink), xsink);
            }
        }

        return has_res();
    }

    QoreHashNode * fetch_row(SQLStatement* stmt, ExceptionSink* xsink) {
        return  release_res();
    }

    int define(SQLStatement* stmt, ExceptionSink* xsink) {
        return 0;
    }

    QoreListNode* fetch_rows(SQLStatement* stmt, int rows,
            ExceptionSink* xsink)
    {
        int r = rows;
        ReferenceHolder<QoreListNode> reslist(xsink);
        reslist = new QoreListNode();

        // next was already called once
        do {
            // acording the doc rows <=0 means fetch all
            if (r > 0) {
                if (rows <= 0) break;
                rows--;
            }
            if (xsink->isException()) return 0;
            ReferenceHolder<QoreHashNode> h(xsink);
            h = fetch_row(stmt, xsink);
            if (!h) continue;
            reslist->insert(h.release());
        } while (next(stmt, xsink));
        return reslist.release();
    }

    QoreHashNode* get_output(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->read_cols(&placeholders, xsink);
    }

    int affected_rows(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->get_row_count();
    }

    QoreHashNode* fetch_columns(SQLStatement* stmt, int rows, ExceptionSink* xsink) {
        return context->read_cols(0,  xsink);
    }

    int bind_placeholders(SQLStatement* stmt,
            const QoreListNode& l,
            ExceptionSink* xsink)
    {
        placeholders.clear();
        ConstListIterator it(l);
        while (it.next()) {
            QoreValue v(it.getValue());
            QoreStringNode *s = v.get<QoreStringNode>();
            placeholders.push_back(s->getBuffer());
        }
        return 0;
    }

};

void init(qore_dbi_method_list &methods) {
    DBModuleWrap<Statement> module(methods);
    module.reg();
}

} // namespace ss
<commit_msg>sybase: SQLStatement::getAffectedRows fix<commit_after>#include <qore/common.h>
#include <qore/QoreValue.h>
#include <qore/DBI.h>
#include <qore/QoreEncoding.h>
#include <qore/QoreString.h>
#include <qore/SQLStatement.h>
#include <qore/QoreStringNode.h>
#include <qore/AbstractPrivateData.h>
#include <qore/QoreQueue.h>
#include <qore/Datasource.h>
#include <qore/QoreListNode.h>
#include <qore/QoreHashNode.h>
#include <qore/QoreValue.h>

#include "connection.h"
#include "emptystatement.h"
#include "command.h"
#include "dbmodulewrap.h"
#include "utils.h"

namespace ss {

inline bool expect_row(command::ResType rt) {
    switch (rt) {
        case command::RES_ROW:
        case command::RES_PARAM:
            return true;
        default:
            return false;
    }
}

class Statement : public EmptyStatement {
    QoreHashNode *_execRes;

    bool has_res() {
        return _execRes ? true : false;
    }

    void set_res(QoreHashNode *res, ExceptionSink* xsink) {
        if (_execRes) _execRes->deref(xsink);
        _execRes = res;
    }

    QoreHashNode * release_res() {
        QoreHashNode *rv = _execRes;
        _execRes = 0;
        return rv;
    }

    ~Statement() {}

    SafePtr<command> context;
    Placeholders placeholders;
public:
    typedef connection Connection;

    Statement() : _execRes(0) {}

    static void Delete(Statement *self, ExceptionSink* xsink) {
        if (!self) return;
        self->set_res(0, xsink);
        delete self;
    }

    int exec(connection *conn,
            const QoreString *query,
            const QoreListNode *args,
            bool raw,
            ExceptionSink* xsink)
    {
#ifdef _QORE_HAS_DBI_EXECRAW
        if (raw) {
            context.reset(conn->create_command(query, xsink));
        } else
#endif
        {
            context.reset(conn->create_command(query, args, xsink));
        }
        // not sure what to do with the returned value here
        context->read_next_result(xsink);
        return 0;
    }

    bool next(SQLStatement* stmt, ExceptionSink* xsink) {
        command::ResType res = context->read_next_result(xsink);
        if (expect_row(res)) {
            if (!has_res()) {
                set_res(context->fetch_row(xsink), xsink);
            }
        }

        return has_res();
    }

    QoreHashNode * fetch_row(SQLStatement* stmt, ExceptionSink* xsink) {
        return  release_res();
    }

    int define(SQLStatement* stmt, ExceptionSink* xsink) {
        return 0;
    }

    QoreListNode* fetch_rows(SQLStatement* stmt, int rows,
            ExceptionSink* xsink)
    {
        int r = rows;
        ReferenceHolder<QoreListNode> reslist(xsink);
        reslist = new QoreListNode();

        // next was already called once
        do {
            // acording the doc rows <=0 means fetch all
            if (r > 0) {
                if (rows <= 0) break;
                rows--;
            }
            if (xsink->isException()) return 0;
            ReferenceHolder<QoreHashNode> h(xsink);
            h = fetch_row(stmt, xsink);
            if (!h) continue;
            reslist->insert(h.release());
        } while (next(stmt, xsink));
        return reslist.release();
    }

    QoreHashNode* get_output(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->read_cols(&placeholders, xsink);
    }

    int affected_rows(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->get_row_count();
    }

    QoreHashNode* fetch_columns(SQLStatement* stmt, int rows, ExceptionSink* xsink) {
        return context->read_cols(0,  xsink);
    }

    int bind_placeholders(SQLStatement* stmt,
            const QoreListNode& l,
            ExceptionSink* xsink)
    {
        placeholders.clear();
        ConstListIterator it(l);
        while (it.next()) {
            QoreValue v(it.getValue());
            QoreStringNode *s = v.get<QoreStringNode>();
            placeholders.push_back(s->getBuffer());
        }
        return 0;
    }
};

void init(qore_dbi_method_list &methods) {
    DBModuleWrap<Statement> module(methods);
    module.reg();
}

} // namespace ss
<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019-2020 Baldur Karlsson
 *
 * 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 "vk_test.h"

RD_TEST(VK_Mesh_Zoo, VulkanGraphicsTest)
{
  static constexpr const char *Description = "Draws some primitives for testing the mesh view.";

  std::string common = R"EOSHADER(

#version 420 core

)EOSHADER";

  std::string vertex = R"EOSHADER(

layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;

layout(push_constant, std140) uniform pushbuf
{
  vec4 scale;
  vec4 offset;
};

layout(location = 0) out vec2 vertOutCol2;
layout(location = 1) out vec4 vertOutcol;

void main()
{
	vec4 pos = vec4(Position.xy * scale.xy + offset.xy, Position.z, 1.0f);
	vertOutcol = Color;

  if(gl_InstanceIndex > 0)
  {
    pos *= 0.3f;
    pos.xy += vec2(0.1f);
    vertOutcol.x = 1.0f;
  }

  vertOutCol2.xy = pos.xy;

	gl_Position = pos * vec4(1, -1, 1, 1);
#if defined(USE_POINTS)
  gl_PointSize = 1.0f;
#endif
}

)EOSHADER";

  std::string pixel = R"EOSHADER(

layout(location = 0) in vec2 vertInCol2;
layout(location = 1) in vec4 vertIncol;

layout(location = 0, index = 0) out vec4 Color;

void main()
{
	Color = vertIncol + 1.0e-20 * vertInCol2.xyxy;
}

)EOSHADER";

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    const DefaultA2V test[] = {
        // single color quad
        {Vec3f(50.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(50.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},

        {Vec3f(250.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(50.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},

        // points, to test vertex picking
        {Vec3f(50.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(50.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},

        {Vec3f(70.0f, 170.0f, 0.1f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(170.0f, 170.0f, 0.1f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(70.0f, 70.0f, 0.1f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
    };

    // create depth-stencil image
    AllocatedImage depthimg(this, vkh::ImageCreateInfo(mainWindow->scissor.extent.width,
                                                       mainWindow->scissor.extent.height, 0,
                                                       VK_FORMAT_D32_SFLOAT_S8_UINT,
                                                       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT),
                            VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));

    VkImageView dsvview = createImageView(vkh::ImageViewCreateInfo(
        depthimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT_S8_UINT, {},
        vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)));

    // create renderpass using the DS image
    vkh::RenderPassCreator renderPassCreateInfo;

    renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
        mainWindow->format, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
    renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
        VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
        VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_SAMPLE_COUNT_1_BIT,
        VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE));

    renderPassCreateInfo.addSubpass({VkAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL})}, 1,
                                    VK_IMAGE_LAYOUT_GENERAL);

    VkRenderPass renderPass = createRenderPass(renderPassCreateInfo);

    // create framebuffers using swapchain images and DS image
    std::vector<VkFramebuffer> fbs;
    fbs.resize(mainWindow->GetCount());

    for(size_t i = 0; i < mainWindow->GetCount(); i++)
      fbs[i] = createFramebuffer(vkh::FramebufferCreateInfo(
          renderPass, {mainWindow->GetView(i), dsvview}, mainWindow->scissor.extent));

    VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
        {},
        {
            vkh::PushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(Vec4f) * 2),
        }));

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = renderPass;

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
    pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
        vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
        vkh::vertexAttr(2, 0, DefaultA2V, uv),
    };

    pipeCreateInfo.stages = {
        CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
        CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
    };

    pipeCreateInfo.depthStencilState.depthTestEnable = VK_TRUE;
    pipeCreateInfo.depthStencilState.depthWriteEnable = VK_TRUE;
    pipeCreateInfo.depthStencilState.stencilTestEnable = VK_FALSE;
    pipeCreateInfo.depthStencilState.back = pipeCreateInfo.depthStencilState.front;

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    pipeCreateInfo.stages[0] = CompileShaderModule(common + "\n#define USE_POINTS\n" + vertex,
                                                   ShaderLang::glsl, ShaderStage::vert, "main"),
    pipeCreateInfo.inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;

    VkPipeline pointspipe = createGraphicsPipeline(pipeCreateInfo);

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {{0, 0, VK_VERTEX_INPUT_RATE_VERTEX}};

    VkPipeline stride0pipe = createGraphicsPipeline(pipeCreateInfo);

    AllocatedBuffer vb(this,
                       vkh::BufferCreateInfo(sizeof(test), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                                                               VK_BUFFER_USAGE_TRANSFER_DST_BIT),
                       VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    vb.upload(test);

    Vec4f cbufferdata[] = {
        Vec4f(2.0f / (float)screenWidth, 2.0f / (float)screenHeight, 1.0f, 1.0f),
        Vec4f(-1.0f, -1.0f, 0.0f, 0.0f),
    };

    AllocatedBuffer cb(
        this, vkh::BufferCreateInfo(sizeof(cbufferdata), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
                                                             VK_BUFFER_USAGE_TRANSFER_DST_BIT),
        VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    cb.upload(cbufferdata);

    while(Running())
    {
      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(renderPass, fbs[mainWindow->imgIndex], mainWindow->scissor,
                                        {{}, vkh::ClearValue(1.0f, 0)}),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(cbufferdata),
                         &cbufferdata);
      vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
      vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
      vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});

      vkCmdDraw(cmd, 3, 1, 10, 0);

      setMarker(cmd, "Quad");

      vkCmdDraw(cmd, 6, 2, 0, 0);

      setMarker(cmd, "Points");

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pointspipe);

      vkCmdDraw(cmd, 4, 1, 6, 0);

      setMarker(cmd, "Stride 0");

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, stride0pipe);

      vkCmdDraw(cmd, 1, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();
    }

    return 0;
  }
};

REGISTER_TEST();
<commit_msg>Test push constant range that applies to vertex and fragment stages<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019-2020 Baldur Karlsson
 *
 * 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 "vk_test.h"

RD_TEST(VK_Mesh_Zoo, VulkanGraphicsTest)
{
  static constexpr const char *Description = "Draws some primitives for testing the mesh view.";

  std::string common = R"EOSHADER(

#version 420 core

)EOSHADER";

  std::string vertex = R"EOSHADER(

layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;

layout(push_constant, std140) uniform pushbuf
{
  vec4 scale;
  vec4 offset;
};

layout(location = 0) out vec2 vertOutCol2;
layout(location = 1) out vec4 vertOutcol;

void main()
{
	vec4 pos = vec4(Position.xy * scale.xy + offset.xy, Position.z, 1.0f);
	vertOutcol = Color;

  if(gl_InstanceIndex > 0)
  {
    pos *= 0.3f;
    pos.xy += vec2(0.1f);
    vertOutcol.x = 1.0f;
  }

  vertOutCol2.xy = pos.xy;

	gl_Position = pos * vec4(1, -1, 1, 1);
#if defined(USE_POINTS)
  gl_PointSize = 1.0f;
#endif
}

)EOSHADER";

  std::string pixel = R"EOSHADER(

layout(location = 0) in vec2 vertInCol2;
layout(location = 1) in vec4 vertIncol;

layout(location = 0, index = 0) out vec4 Color;

void main()
{
	Color = vertIncol + 1.0e-20 * vertInCol2.xyxy;
}

)EOSHADER";

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    const DefaultA2V test[] = {
        // single color quad
        {Vec3f(50.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(50.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},

        {Vec3f(250.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(50.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},

        // points, to test vertex picking
        {Vec3f(50.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 250.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(250.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(50.0f, 50.0f, 0.2f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},

        {Vec3f(70.0f, 170.0f, 0.1f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(170.0f, 170.0f, 0.1f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(70.0f, 70.0f, 0.1f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
    };

    // create depth-stencil image
    AllocatedImage depthimg(this, vkh::ImageCreateInfo(mainWindow->scissor.extent.width,
                                                       mainWindow->scissor.extent.height, 0,
                                                       VK_FORMAT_D32_SFLOAT_S8_UINT,
                                                       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT),
                            VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));

    VkImageView dsvview = createImageView(vkh::ImageViewCreateInfo(
        depthimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT_S8_UINT, {},
        vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)));

    // create renderpass using the DS image
    vkh::RenderPassCreator renderPassCreateInfo;

    renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
        mainWindow->format, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
    renderPassCreateInfo.attachments.push_back(vkh::AttachmentDescription(
        VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
        VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_SAMPLE_COUNT_1_BIT,
        VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE));

    renderPassCreateInfo.addSubpass({VkAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL})}, 1,
                                    VK_IMAGE_LAYOUT_GENERAL);

    VkRenderPass renderPass = createRenderPass(renderPassCreateInfo);

    // create framebuffers using swapchain images and DS image
    std::vector<VkFramebuffer> fbs;
    fbs.resize(mainWindow->GetCount());

    for(size_t i = 0; i < mainWindow->GetCount(); i++)
      fbs[i] = createFramebuffer(vkh::FramebufferCreateInfo(
          renderPass, {mainWindow->GetView(i), dsvview}, mainWindow->scissor.extent));

    VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
        {},
        {
            vkh::PushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
                                   sizeof(Vec4f) * 2),
        }));

    VkPipelineLayout layout2 = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
        {},
        {
            vkh::PushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(Vec4f) * 2),
        }));

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = renderPass;

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
    pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
        vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
        vkh::vertexAttr(2, 0, DefaultA2V, uv),
    };

    pipeCreateInfo.stages = {
        CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
        CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
    };

    pipeCreateInfo.depthStencilState.depthTestEnable = VK_TRUE;
    pipeCreateInfo.depthStencilState.depthWriteEnable = VK_TRUE;
    pipeCreateInfo.depthStencilState.stencilTestEnable = VK_FALSE;
    pipeCreateInfo.depthStencilState.back = pipeCreateInfo.depthStencilState.front;

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    pipeCreateInfo.stages[0] = CompileShaderModule(common + "\n#define USE_POINTS\n" + vertex,
                                                   ShaderLang::glsl, ShaderStage::vert, "main"),
    pipeCreateInfo.inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;

    VkPipeline pointspipe = createGraphicsPipeline(pipeCreateInfo);

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {{0, 0, VK_VERTEX_INPUT_RATE_VERTEX}};

    pipeCreateInfo.layout = layout2;

    VkPipeline stride0pipe = createGraphicsPipeline(pipeCreateInfo);

    AllocatedBuffer vb(this,
                       vkh::BufferCreateInfo(sizeof(test), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                                                               VK_BUFFER_USAGE_TRANSFER_DST_BIT),
                       VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    vb.upload(test);

    Vec4f cbufferdata[] = {
        Vec4f(2.0f / (float)screenWidth, 2.0f / (float)screenHeight, 1.0f, 1.0f),
        Vec4f(-1.0f, -1.0f, 0.0f, 0.0f),
    };

    AllocatedBuffer cb(
        this, vkh::BufferCreateInfo(sizeof(cbufferdata), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
                                                             VK_BUFFER_USAGE_TRANSFER_DST_BIT),
        VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    cb.upload(cbufferdata);

    while(Running())
    {
      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(renderPass, fbs[mainWindow->imgIndex], mainWindow->scissor,
                                        {{}, vkh::ClearValue(1.0f, 0)}),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
                         sizeof(cbufferdata), &cbufferdata);
      vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
      vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
      vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});

      vkCmdDraw(cmd, 3, 1, 10, 0);

      setMarker(cmd, "Quad");

      vkCmdDraw(cmd, 6, 2, 0, 0);

      setMarker(cmd, "Points");

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pointspipe);

      vkCmdDraw(cmd, 4, 1, 6, 0);

      setMarker(cmd, "Stride 0");

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, stride0pipe);
      vkCmdPushConstants(cmd, layout2, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(cbufferdata),
                         &cbufferdata);

      vkCmdDraw(cmd, 1, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();
    }

    return 0;
  }
};

REGISTER_TEST();
<|endoftext|>


<commit_before>// -*- c++ -*- ///////////////////////////////////////////////////////////////
//
// This file is part of Miro (The Middleware for Robots)
// Copyright (C) 1999-2013
// Department of Neural Information Processing, University of Ulm
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

// This module
#include "ParameterXML.h"
// This application
#include "ConfigFile.h"
// The Qt library
#include <QMenu>
#include <QTreeWidget>
#include <QTreeWidgetItem>
// The C++ Standard Library
#include <cassert>

QString const ParameterXML::XML_TAG = "parameter";

ParameterXML::ParameterXML(QDomNode const& _node,
			   QTreeWidgetItem * _parentItem,
			   QTreeWidgetItem * _pre,
			   QObject * _parent,
			   const char * _name) :
  Super(_node, _parentItem, _pre, _parent, _name),
  config_(ConfigFile::instance())
{
  assert(!node().toElement().isNull());
}

ParameterXML::ParameterXML(QDomNode const& _node,
			   QTreeWidget * _view,
			   QTreeWidgetItem * _pre,
			   QObject * _parent,
			   const char * _name) :
  Super(_node, _view, _pre, _parent, _name),
  config_(ConfigFile::instance())
{
  assert(!node().toElement().isNull());
}

void
ParameterXML::init()
{
}

void
ParameterXML::contextMenu(QMenu& _menu)
{
  // Add 4 QActions to the context menu: "Set Parameters", "Up", "Down" and
  // "Delete"
  QAction * pAction = NULL;

  pAction = new QAction(tr("Set Parameters"), this);
  connect(pAction, SIGNAL(triggered()), this, SLOT(slotSetParameters()));
  _menu.addAction(pAction);

  _menu.addSeparator();

  pAction = new QAction(tr("Up"), this);
  connect(pAction, SIGNAL(triggered()), this, SLOT(up()));
  _menu.addAction(pAction);

  pAction = new QAction(tr("Down"), this);
  connect(pAction, SIGNAL(triggered()), this, SLOT(down()));
  _menu.addAction(pAction);

  _menu.addSeparator();

  pAction = new QAction(tr("Delete"), this);
  connect(pAction, SIGNAL(triggered()), this, SLOT(slotDelete()));
  _menu.addAction(pAction);
}

void
ParameterXML::slotSetParameters()
{
  setParameters();
}

void
ParameterXML::setParameters()
{
}
<commit_msg>Make the QMenu the parent of the QAction<commit_after>// -*- c++ -*- ///////////////////////////////////////////////////////////////
//
// This file is part of Miro (The Middleware for Robots)
// Copyright (C) 1999-2013
// Department of Neural Information Processing, University of Ulm
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

// This module
#include "ParameterXML.h"
// This application
#include "ConfigFile.h"
// The Qt library
#include <QMenu>
#include <QTreeWidget>
#include <QTreeWidgetItem>
// The C++ Standard Library
#include <cassert>

QString const ParameterXML::XML_TAG = "parameter";

ParameterXML::ParameterXML(QDomNode const& _node,
			   QTreeWidgetItem * _parentItem,
			   QTreeWidgetItem * _pre,
			   QObject * _parent,
			   const char * _name) :
  Super(_node, _parentItem, _pre, _parent, _name),
  config_(ConfigFile::instance())
{
  assert(!node().toElement().isNull());
}

ParameterXML::ParameterXML(QDomNode const& _node,
			   QTreeWidget * _view,
			   QTreeWidgetItem * _pre,
			   QObject * _parent,
			   const char * _name) :
  Super(_node, _view, _pre, _parent, _name),
  config_(ConfigFile::instance())
{
  assert(!node().toElement().isNull());
}

void
ParameterXML::init()
{
}

void
ParameterXML::contextMenu(QMenu& _menu)
{
  // Add 4 QActions to the context menu: "Set Parameters", "Up", "Down" and
  // "Delete"
  QAction * pAction = NULL;

  pAction = new QAction(tr("Set Parameters"), &_menu);
  connect(pAction, SIGNAL(triggered()), this, SLOT(slotSetParameters()));
  _menu.addAction(pAction);

  _menu.addSeparator();

  pAction = new QAction(tr("Up"), &_menu);
  connect(pAction, SIGNAL(triggered()), this, SLOT(up()));
  _menu.addAction(pAction);

  pAction = new QAction(tr("Down"), &_menu);
  connect(pAction, SIGNAL(triggered()), this, SLOT(down()));
  _menu.addAction(pAction);

  _menu.addSeparator();

  pAction = new QAction(tr("Delete"), &_menu);
  connect(pAction, SIGNAL(triggered()), this, SLOT(slotDelete()));
  _menu.addAction(pAction);
}

void
ParameterXML::slotSetParameters()
{
  setParameters();
}

void
ParameterXML::setParameters()
{
}
<|endoftext|>


<commit_before>#include "terminal.h"

#include "filefinder.h"
#include "options.h"

terminal::terminal(){
  // save and copy terminal settings
  tcgetattr( STDIN_FILENO, &oldt);
  newt = oldt;

  // set new terminal settings
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr( STDIN_FILENO, TCSANOW, &newt);

  //
  for(int i=0; i < options.number_of_result_lines; ++i){
    fprintf(stderr,"\n");
  }
  cursor_up(options.number_of_result_lines);
  save_cursor_pos();
  restore_cursor_pos();
}

terminal::~terminal(){
  // restore terminal settings
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}

void terminal::save_cursor_pos() const{
  fprintf(stderr,"\033[s");
}

void terminal::restore_cursor_pos() const{
  fprintf(stderr,"\033[u");
}

void terminal::erase_line() const{
  fprintf(stderr,"\033[K");
}

void terminal::cursor_left(int n) const{
  fprintf(stderr,"\033[%dD",n);
}

void terminal::cursor_right(int n) const{
  fprintf(stderr,"\033[%dC",n);
}

void terminal::cursor_up(int n) const{
  fprintf(stderr,"\033[%dA",n);
}

void terminal::cursor_down(int n) const{
  fprintf(stderr,"\033[%dB",n);
}

void terminal::print_search_line(std::string str, int pos) const{
  restore_cursor_pos();
  erase_line();
  fprintf(stderr,">%s", str.c_str());
  restore_cursor_pos();
  cursor_right(1+pos);
}

void terminal::print_result(const terminal& term,const std::vector<node>& result, std::size_t selected) const{
  term.restore_cursor_pos();
  for(int i=0; i < options.number_of_result_lines; ++i){
    fprintf(stderr,"\n");
    term.erase_line();
  }
  term.restore_cursor_pos();

  for(std::size_t i=1; i <= result.size(); ++i){
    fprintf(stderr,"\n");
    if(i-1==selected) fprintf(stderr,"\033[7m");
    fprintf(stderr,"%lu: %s%s",(unsigned long)i,result[i-1].location.c_str(), result[i-1].filename.c_str());
    if(i-1==selected) fprintf(stderr,"\033[0m");
  }
}
<commit_msg>Update terminal.cpp<commit_after>#include "terminal.h"

#include "filefinder.h"
#include "options.h"

terminal::terminal(){
  // save and copy terminal settings
  tcgetattr( STDIN_FILENO, &oldt);
  newt = oldt;

  // set new terminal settings
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr( STDIN_FILENO, TCSANOW, &newt);

  // print as many newlines as number_of_result_lines to
  // enable moving the cursor up and down.
  for(int i=0; i < options.number_of_result_lines; ++i){
    fprintf(stderr,"\n");
  }
  cursor_up(options.number_of_result_lines);
  save_cursor_pos();
  restore_cursor_pos();
}

terminal::~terminal(){
  // restore terminal settings
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}

void terminal::save_cursor_pos() const{
  fprintf(stderr,"\033[s");
}

void terminal::restore_cursor_pos() const{
  fprintf(stderr,"\033[u");
}

void terminal::erase_line() const{
  fprintf(stderr,"\033[K");
}

void terminal::cursor_left(int n) const{
  fprintf(stderr,"\033[%dD",n);
}

void terminal::cursor_right(int n) const{
  fprintf(stderr,"\033[%dC",n);
}

void terminal::cursor_up(int n) const{
  fprintf(stderr,"\033[%dA",n);
}

void terminal::cursor_down(int n) const{
  fprintf(stderr,"\033[%dB",n);
}

void terminal::print_search_line(std::string str, int pos) const{
  restore_cursor_pos();
  erase_line();
  fprintf(stderr,">%s", str.c_str());
  restore_cursor_pos();
  cursor_right(1+pos);
}

void terminal::print_result(const terminal& term,const std::vector<node>& result, std::size_t selected) const{
  term.restore_cursor_pos();
  for(int i=0; i < options.number_of_result_lines; ++i){
    fprintf(stderr,"\n");
    term.erase_line();
  }
  term.restore_cursor_pos();

  for(std::size_t i=1; i <= result.size(); ++i){
    fprintf(stderr,"\n");
    if(i-1==selected) fprintf(stderr,"\033[7m");
    fprintf(stderr,"%lu: %s%s",(unsigned long)i,result[i-1].location.c_str(), result[i-1].filename.c_str());
    if(i-1==selected) fprintf(stderr,"\033[0m");
  }
}
<|endoftext|>


<commit_before>#include <nanogui/opengl.h>
#include "textures.h"
#include "util.h"
#define KONSTRUCTS_PATH_SIZE 256

namespace konstructs {
    void shtxt_path(const char *name, const char *type, char *path, size_t max_len) {
        snprintf(path, max_len, "%s/%s", type, name);

        if (!file_exist(path)) {
            snprintf(path, max_len, "../%s/%s", type, name);
        }

        if (!file_exist(path)) {
            snprintf(path, max_len, "/usr/local/share/konstructs-client/%s/%s", type, name);
        }

        if (!file_exist(path)) {
            printf("Error, no %s for %s found.\n", type, name);
            exit(1);
        }
    }

    void texture_path(const char *name, char *path, size_t max_len) {
        shtxt_path(name, "textures", path, max_len);
    }

    void load_textures() {
        char txtpth[KONSTRUCTS_PATH_SIZE];

        GLuint sky;
        glGenTextures(1, &sky);
        glActiveTexture(GL_TEXTURE0 + SKY_TEXTURE);
        glBindTexture(GL_TEXTURE_2D, sky);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        texture_path("sky.png", txtpth, KONSTRUCTS_PATH_SIZE);
        load_png_texture(txtpth);

        GLuint font;
        glGenTextures(1, &font);
        glActiveTexture(GL_TEXTURE0 + FONT_TEXTURE);
        glBindTexture(GL_TEXTURE_2D, font);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        texture_path("font.png", txtpth, KONSTRUCTS_PATH_SIZE);
        load_png_texture(txtpth);

        GLuint inventory_texture;
        glGenTextures(1, &inventory_texture);
        glActiveTexture(GL_TEXTURE0 + INVENTORY_TEXTURE);
        glBindTexture(GL_TEXTURE_2D, inventory_texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        texture_path("inventory.png", txtpth, KONSTRUCTS_PATH_SIZE);
        load_png_texture(txtpth);
    }
};
<commit_msg>Use GL_LINEAR instead of GL_NEAREST for better txt.<commit_after>#include <nanogui/opengl.h>
#include "textures.h"
#include "util.h"
#define KONSTRUCTS_PATH_SIZE 256

namespace konstructs {
    void shtxt_path(const char *name, const char *type, char *path, size_t max_len) {
        snprintf(path, max_len, "%s/%s", type, name);

        if (!file_exist(path)) {
            snprintf(path, max_len, "../%s/%s", type, name);
        }

        if (!file_exist(path)) {
            snprintf(path, max_len, "/usr/local/share/konstructs-client/%s/%s", type, name);
        }

        if (!file_exist(path)) {
            printf("Error, no %s for %s found.\n", type, name);
            exit(1);
        }
    }

    void texture_path(const char *name, char *path, size_t max_len) {
        shtxt_path(name, "textures", path, max_len);
    }

    void load_textures() {
        char txtpth[KONSTRUCTS_PATH_SIZE];

        GLuint sky;
        glGenTextures(1, &sky);
        glActiveTexture(GL_TEXTURE0 + SKY_TEXTURE);
        glBindTexture(GL_TEXTURE_2D, sky);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        texture_path("sky.png", txtpth, KONSTRUCTS_PATH_SIZE);
        load_png_texture(txtpth);

        GLuint font;
        glGenTextures(1, &font);
        glActiveTexture(GL_TEXTURE0 + FONT_TEXTURE);
        glBindTexture(GL_TEXTURE_2D, font);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        texture_path("font.png", txtpth, KONSTRUCTS_PATH_SIZE);
        load_png_texture(txtpth);

        GLuint inventory_texture;
        glGenTextures(1, &inventory_texture);
        glActiveTexture(GL_TEXTURE0 + INVENTORY_TEXTURE);
        glBindTexture(GL_TEXTURE_2D, inventory_texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        texture_path("inventory.png", txtpth, KONSTRUCTS_PATH_SIZE);
        load_png_texture(txtpth);
    }
};
<|endoftext|>


<commit_before>// Copyright (c) 2014-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <timedata.h>

#include <netaddress.h>
#include <sync.h>
#include <ui_interface.h>
#include <util/system.h>
#include <util/translation.h>
#include <warnings.h>

static Mutex g_timeoffset_mutex;
static int64_t nTimeOffset GUARDED_BY(g_timeoffset_mutex) = 0;

/**
 * "Never go to sea with two chronometers; take one or three."
 * Our three time sources are:
 *  - System clock
 *  - Median of other nodes clocks
 *  - The user (asking the user to fix the system clock if the first two disagree)
 */
int64_t GetTimeOffset()
{
    LOCK(g_timeoffset_mutex);
    return nTimeOffset;
}

int64_t GetAdjustedTime()
{
    return GetTime() + GetTimeOffset();
}

static int64_t abs64(int64_t n)
{
    return (n >= 0 ? n : -n);
}

#define BITCOIN_TIMEDATA_MAX_SAMPLES 200

void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
    LOCK(g_timeoffset_mutex);
    // Ignore duplicates
    static std::set<CNetAddr> setKnown;
    if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
        return;
    if (!setKnown.insert(ip).second)
        return;

    // Add data
    static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
    vTimeOffsets.input(nOffsetSample);
    LogPrint(BCLog::NET,"added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);

    // There is a known issue here (see issue #4521):
    //
    // - The structure vTimeOffsets contains up to 200 elements, after which
    // any new element added to it will not increase its size, replacing the
    // oldest element.
    //
    // - The condition to update nTimeOffset includes checking whether the
    // number of elements in vTimeOffsets is odd, which will never happen after
    // there are 200 elements.
    //
    // But in this case the 'bug' is protective against some attacks, and may
    // actually explain why we've never seen attacks which manipulate the
    // clock offset.
    //
    // So we should hold off on fixing this and clean it up as part of
    // a timing cleanup that strengthens it in a number of other ways.
    //
    if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
    {
        int64_t nMedian = vTimeOffsets.median();
        std::vector<int64_t> vSorted = vTimeOffsets.sorted();
        // Only let other nodes change our time by so much
        if (abs64(nMedian) <= std::max<int64_t>(0, gArgs.GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT)))
        {
            nTimeOffset = nMedian;
        }
        else
        {
            nTimeOffset = 0;

            static bool fDone;
            if (!fDone)
            {
                // If nobody has a time different than ours but within 5 minutes of ours, give a warning
                bool fMatch = false;
                for (const int64_t nOffset : vSorted)
                    if (nOffset != 0 && abs64(nOffset) < 5 * 60)
                        fMatch = true;

                if (!fMatch)
                {
                    fDone = true;
                    bilingual_str strMessage = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly."), PACKAGE_NAME);
                    SetMiscWarning(strMessage.translated);
                    uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
                }
            }
        }

        if (LogAcceptCategory(BCLog::NET)) {
            for (const int64_t n : vSorted) {
                LogPrint(BCLog::NET, "%+d  ", n); /* Continued */
            }
            LogPrint(BCLog::NET, "|  "); /* Continued */

            LogPrint(BCLog::NET, "nTimeOffset = %+d  (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
        }
    }
}
<commit_msg>refactor: Fix formatting of timedata.cpp<commit_after>// Copyright (c) 2014-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <timedata.h>

#include <netaddress.h>
#include <sync.h>
#include <ui_interface.h>
#include <util/system.h>
#include <util/translation.h>
#include <warnings.h>

static Mutex g_timeoffset_mutex;
static int64_t nTimeOffset GUARDED_BY(g_timeoffset_mutex) = 0;

/**
 * "Never go to sea with two chronometers; take one or three."
 * Our three time sources are:
 *  - System clock
 *  - Median of other nodes clocks
 *  - The user (asking the user to fix the system clock if the first two disagree)
 */
int64_t GetTimeOffset()
{
    LOCK(g_timeoffset_mutex);
    return nTimeOffset;
}

int64_t GetAdjustedTime()
{
    return GetTime() + GetTimeOffset();
}

static int64_t abs64(int64_t n)
{
    return (n >= 0 ? n : -n);
}

#define BITCOIN_TIMEDATA_MAX_SAMPLES 200

void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
    LOCK(g_timeoffset_mutex);
    // Ignore duplicates
    static std::set<CNetAddr> setKnown;
    if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
        return;
    if (!setKnown.insert(ip).second)
        return;

    // Add data
    static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
    vTimeOffsets.input(nOffsetSample);
    LogPrint(BCLog::NET, "added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample / 60);

    // There is a known issue here (see issue #4521):
    //
    // - The structure vTimeOffsets contains up to 200 elements, after which
    // any new element added to it will not increase its size, replacing the
    // oldest element.
    //
    // - The condition to update nTimeOffset includes checking whether the
    // number of elements in vTimeOffsets is odd, which will never happen after
    // there are 200 elements.
    //
    // But in this case the 'bug' is protective against some attacks, and may
    // actually explain why we've never seen attacks which manipulate the
    // clock offset.
    //
    // So we should hold off on fixing this and clean it up as part of
    // a timing cleanup that strengthens it in a number of other ways.
    //
    if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) {
        int64_t nMedian = vTimeOffsets.median();
        std::vector<int64_t> vSorted = vTimeOffsets.sorted();
        // Only let other nodes change our time by so much
        if (abs64(nMedian) <= std::max<int64_t>(0, gArgs.GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT))) {
            nTimeOffset = nMedian;
        } else {
            nTimeOffset = 0;

            static bool fDone;
            if (!fDone) {
                // If nobody has a time different than ours but within 5 minutes of ours, give a warning
                bool fMatch = false;
                for (const int64_t nOffset : vSorted) {
                    if (nOffset != 0 && abs64(nOffset) < 5 * 60) fMatch = true;
                }

                if (!fMatch) {
                    fDone = true;
                    bilingual_str strMessage = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly."), PACKAGE_NAME);
                    SetMiscWarning(strMessage.translated);
                    uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
                }
            }
        }

        if (LogAcceptCategory(BCLog::NET)) {
            for (const int64_t n : vSorted) {
                LogPrint(BCLog::NET, "%+d  ", n); /* Continued */
            }
            LogPrint(BCLog::NET, "|  "); /* Continued */
            LogPrint(BCLog::NET, "nTimeOffset = %+d  (%+d minutes)\n", nTimeOffset, nTimeOffset / 60);
        }
    }
}
<|endoftext|>