From 175052507ccc8569802ae2ee0b0b094c03698ff7 Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Mon, 29 Aug 2016 14:56:03 -0500 Subject: [PATCH] swr: [rasterizer] add archrast instrumentation Statistics measurement system --- src/gallium/drivers/swr/Makefile.am | 40 ++++- src/gallium/drivers/swr/Makefile.sources | 5 + .../drivers/swr/rasterizer/archrast/archrast.cpp | 72 ++++++++ .../drivers/swr/rasterizer/archrast/archrast.h | 41 +++++ .../drivers/swr/rasterizer/archrast/eventmanager.h | 68 +++++++ .../drivers/swr/rasterizer/archrast/events.proto | 108 ++++++++++++ src/gallium/drivers/swr/rasterizer/core/api.cpp | 16 ++ src/gallium/drivers/swr/rasterizer/core/context.h | 17 ++ .../drivers/swr/rasterizer/scripts/gen_archrast.py | 195 +++++++++++++++++++++ .../scripts/templates/ar_event_cpp.template | 41 +++++ .../scripts/templates/ar_event_h.template | 89 ++++++++++ .../scripts/templates/ar_eventhandler_h.template | 46 +++++ 12 files changed, 735 insertions(+), 3 deletions(-) create mode 100644 src/gallium/drivers/swr/rasterizer/archrast/archrast.cpp create mode 100644 src/gallium/drivers/swr/rasterizer/archrast/archrast.h create mode 100644 src/gallium/drivers/swr/rasterizer/archrast/eventmanager.h create mode 100644 src/gallium/drivers/swr/rasterizer/archrast/events.proto create mode 100644 src/gallium/drivers/swr/rasterizer/scripts/gen_archrast.py create mode 100644 src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_cpp.template create mode 100644 src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_h.template create mode 100644 src/gallium/drivers/swr/rasterizer/scripts/templates/ar_eventhandler_h.template diff --git a/src/gallium/drivers/swr/Makefile.am b/src/gallium/drivers/swr/Makefile.am index 33664d6..154f0ca 100644 --- a/src/gallium/drivers/swr/Makefile.am +++ b/src/gallium/drivers/swr/Makefile.am @@ -35,13 +35,16 @@ COMMON_CXXFLAGS = \ $(SWR_CXX11_CXXFLAGS) \ -I$(builddir)/rasterizer/scripts \ -I$(builddir)/rasterizer/jitter \ + -I$(builddir)/rasterizer/archrast \ -I$(srcdir)/rasterizer \ -I$(srcdir)/rasterizer/core \ -I$(srcdir)/rasterizer/scripts \ - -I$(srcdir)/rasterizer/jitter + -I$(srcdir)/rasterizer/jitter \ + -I$(srcdir)/rasterizer/archrast COMMON_SOURCES = \ $(CXX_SOURCES) \ + $(ARCHRAST_CXX_SOURCES) \ $(COMMON_CXX_SOURCES) \ $(CORE_CXX_SOURCES) \ $(JITTER_CXX_SOURCES) \ @@ -54,7 +57,10 @@ BUILT_SOURCES = \ rasterizer/scripts/gen_knobs.h \ rasterizer/jitter/state_llvm.h \ rasterizer/jitter/builder_x86.h \ - rasterizer/jitter/builder_x86.cpp + rasterizer/jitter/builder_x86.cpp \ + rasterizer/archrast/gen_ar_event.h \ + rasterizer/archrast/gen_ar_event.cpp \ + rasterizer/archrast/gen_ar_eventhandler.h MKDIR_GEN = $(AM_V_at)$(MKDIR_P) $(@D) PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) @@ -107,6 +113,29 @@ rasterizer/jitter/builder_x86.cpp: rasterizer/jitter/scripts/gen_llvm_ir_macros. --output rasterizer/jitter/builder_x86.cpp \ --gen_x86_cpp +rasterizer/archrast/gen_ar_event.h: rasterizer/scripts/gen_archrast.py rasterizer/scripts/templates/ar_event_h.template rasterizer/archrast/events.proto + $(MKDIR_GEN) + $(PYTHON_GEN) \ + $(srcdir)/rasterizer/scripts/gen_archrast.py \ + --proto $(srcdir)/rasterizer/archrast/events.proto \ + --output rasterizer/archrast/gen_ar_event.h \ + --gen_event_h + +rasterizer/archrast/gen_ar_event.cpp: rasterizer/scripts/gen_archrast.py rasterizer/scripts/templates/ar_event_cpp.template rasterizer/archrast/events.proto + $(MKDIR_GEN) + $(PYTHON_GEN) \ + $(srcdir)/rasterizer/scripts/gen_archrast.py \ + --proto $(srcdir)/rasterizer/archrast/events.proto \ + --output rasterizer/archrast/gen_ar_event.cpp \ + --gen_event_cpp + +rasterizer/archrast/gen_ar_eventhandler.h: rasterizer/scripts/gen_archrast.py rasterizer/scripts/templates/ar_eventhandler_h.template rasterizer/archrast/events.proto + $(MKDIR_GEN) + $(PYTHON_GEN) \ + $(srcdir)/rasterizer/scripts/gen_archrast.py \ + --proto $(srcdir)/rasterizer/archrast/events.proto \ + --output rasterizer/archrast/gen_ar_eventhandler.h \ + --gen_eventhandler_h COMMON_LIBADD = \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ @@ -197,8 +226,10 @@ libswrAVX2_la_LDFLAGS = \ include $(top_srcdir)/install-gallium-links.mk EXTRA_DIST = \ + rasterizer/archrast/events.proto \ rasterizer/jitter/scripts/gen_llvm_ir_macros.py \ rasterizer/jitter/scripts/gen_llvm_types.py \ + rasterizer/scripts/gen_archrast.py \ rasterizer/scripts/gen_knobs.py \ rasterizer/scripts/knob_defs.py \ rasterizer/scripts/mako/ast.py \ @@ -218,4 +249,7 @@ EXTRA_DIST = \ rasterizer/scripts/mako/runtime.py \ rasterizer/scripts/mako/template.py \ rasterizer/scripts/mako/util.py \ - rasterizer/scripts/templates/knobs.template + rasterizer/scripts/templates/knobs.template \ + rasterizer/scripts/templates/ar_event_h.template \ + rasterizer/scripts/templates/ar_event_cpp.template \ + rasterizer/scripts/templates/ar_eventhandler_h.template diff --git a/src/gallium/drivers/swr/Makefile.sources b/src/gallium/drivers/swr/Makefile.sources index 99b3900..e0ea161 100644 --- a/src/gallium/drivers/swr/Makefile.sources +++ b/src/gallium/drivers/swr/Makefile.sources @@ -45,6 +45,11 @@ CXX_SOURCES := \ swr_query.h \ swr_query.cpp +ARCHRAST_CXX_SOURCES := \ + rasterizer/archrast/archrast.cpp \ + rasterizer/archrast/archrast.h \ + rasterizer/archrast/eventmanager.h + COMMON_CXX_SOURCES := \ rasterizer/common/formats.cpp \ rasterizer/common/formats.h \ diff --git a/src/gallium/drivers/swr/rasterizer/archrast/archrast.cpp b/src/gallium/drivers/swr/rasterizer/archrast/archrast.cpp new file mode 100644 index 0000000..48dec28 --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/archrast/archrast.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +* Copyright (C) 2016 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +* +* @file archrast.h +* +* @brief Definitions for archrast. +* +******************************************************************************/ +#include "common/os.h" +#include "archrast/archrast.h" +#include "archrast/eventmanager.h" + +namespace ArchRast +{ + static EventManager* FromHandle(HANDLE hThreadContext) + { + return reinterpret_cast(hThreadContext); + } + + // Construct an event manager and associate a handler with it. + HANDLE CreateThreadContext() + { + EventManager* pManager = new EventManager(); + EventHandler* pHandler = new EventHandler(); + + if (pManager && pHandler) + { + pManager->attach(pHandler); + + return pManager; + } + + SWR_ASSERT(0, "Failed to register thread."); + return nullptr; + } + + void DestroyThreadContext(HANDLE hThreadContext) + { + EventManager* pManager = FromHandle(hThreadContext); + SWR_ASSERT(pManager != nullptr); + + delete pManager; + } + + // Dispatch event for this thread. + void dispatch(HANDLE hThreadContext, Event& event) + { + EventManager* pManager = FromHandle(hThreadContext); + SWR_ASSERT(pManager != nullptr); + + pManager->dispatch(event); + } +} diff --git a/src/gallium/drivers/swr/rasterizer/archrast/archrast.h b/src/gallium/drivers/swr/rasterizer/archrast/archrast.h new file mode 100644 index 0000000..bdb3afb --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/archrast/archrast.h @@ -0,0 +1,41 @@ +/**************************************************************************** +* Copyright (C) 2016 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +* +* @file archrast.h +* +* @brief Definitions for archrast. +* +******************************************************************************/ +#pragma once + +#include "common/os.h" +#include "gen_ar_event.h" + +namespace ArchRast +{ + HANDLE CreateThreadContext(); + void DestroyThreadContext(HANDLE hThreadContext); + + // Dispatch event for this thread. + void dispatch(HANDLE hThreadContext, Event& event); +}; + diff --git a/src/gallium/drivers/swr/rasterizer/archrast/eventmanager.h b/src/gallium/drivers/swr/rasterizer/archrast/eventmanager.h new file mode 100644 index 0000000..d162ca8 --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/archrast/eventmanager.h @@ -0,0 +1,68 @@ +/**************************************************************************** +* Copyright (C) 2016 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +* +* @file archrast.h +* +* @brief Definitions for the event manager. +* +******************************************************************************/ +#pragma once + +#include "common/os.h" + +#include "gen_ar_event.h" +#include "gen_ar_eventhandler.h" + +#include + +namespace ArchRast +{ + ////////////////////////////////////////////////////////////////////////// + /// EventManager - interface to dispatch events to handlers. + /// Event handling occurs only on a single thread. + ////////////////////////////////////////////////////////////////////////// + class EventManager + { + public: + void attach(EventHandler* pHandler) + { + mHandlers.push_back(pHandler); + } + + void dispatch(Event& event) + { + ///@todo Add event filter check here. + + for (auto pHandler : mHandlers) + { + event.accept(pHandler); + } + } + private: + + // Handlers stay registered for life + void detach(EventHandler* pHandler) { SWR_ASSERT(0); } + + std::vector mHandlers; + }; +}; + diff --git a/src/gallium/drivers/swr/rasterizer/archrast/events.proto b/src/gallium/drivers/swr/rasterizer/archrast/events.proto new file mode 100644 index 0000000..4c2e7dc --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/archrast/events.proto @@ -0,0 +1,108 @@ +# Copyright (C) 2016 Intel Corporation. All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) 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. +# +# Provides definitions for events. + +enum GroupType +{ + APIClearRenderTarget, + APIDraw, + APIDrawWakeAllThreads, + APIDrawIndexed, + APIDispatch, + APIStoreTiles, + APIGetDrawContext, + APISync, + APIWaitForIdle, + FEProcessDraw, + FEProcessDrawIndexed, + FEFetchShader, + FEVertexShader, + FEHullShader, + FETessellation, + FEDomainShader, + FEGeometryShader, + FEStreamout, + FEPAAssemble, + FEBinPoints, + FEBinLines, + FEBinTriangles, + FETriangleSetup, + FEViewportCull, + FEGuardbandClip, + FEClipPoints, + FEClipLines, + FEClipTriangles, + FECullZeroAreaAndBackface, + FECullBetweenCenters, + FEProcessStoreTiles, + FEProcessInvalidateTiles, + WorkerWorkOnFifoBE, + WorkerFoundWork, + BELoadTiles, + BEDispatch, + BEClear, + BERasterizeLine, + BERasterizeTriangle, + BETriangleSetup, + BEStepSetup, + BECullZeroArea, + BEEmptyTriangle, + BETrivialAccept, + BETrivialReject, + BERasterizePartial, + BEPixelBackend, + BESetup, + BEBarycentric, + BEEarlyDepthTest, + BEPixelShader, + BESingleSampleBackend, + BEPixelRateBackend, + BESampleRateBackend, + BENullBackend, + BELateDepthTest, + BEOutputMerger, + BEStoreTiles, + BEEndTile, + WorkerWaitForThreadEvent, +}; + +event Start +{ + GroupType type; + uint32_t id; +}; + +event End +{ + GroupType type; + uint32_t count; +}; + +event DrawIndexedInstance +{ + PRIMITIVE_TOPOLOGY topology; + uint32_t numIndices; + int32_t indexOffset; + int32_t baseVertex; + uint32_t numInstances; + uint32_t startInstance; +}; diff --git a/src/gallium/drivers/swr/rasterizer/core/api.cpp b/src/gallium/drivers/swr/rasterizer/core/api.cpp index 089ef0f..6bdb8f4 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/api.cpp @@ -46,6 +46,8 @@ #include "common/simdintrin.h" #include "common/os.h" +#include "archrast/archrast.h" + static const SWR_RECT g_MaxScissorRect = { 0, 0, KNOB_MAX_SCISSOR_X, KNOB_MAX_SCISSOR_Y }; void SetupDefaultState(SWR_CONTEXT *pContext); @@ -107,6 +109,10 @@ HANDLE SwrCreateContext( pContext->ppScratch = new uint8_t*[pContext->NumWorkerThreads]; pContext->pStats = new SWR_STATS[pContext->NumWorkerThreads]; + // Setup ArchRast thread contexts which includes +1 for API thread. + pContext->pArContext = new HANDLE[pContext->NumWorkerThreads+1]; + pContext->pArContext[pContext->NumWorkerThreads] = ArchRast::CreateThreadContext(); + // Allocate scratch space for workers. ///@note We could lazily allocate this but its rather small amount of memory. for (uint32_t i = 0; i < pContext->NumWorkerThreads; ++i) @@ -121,6 +127,9 @@ HANDLE SwrCreateContext( #else pContext->ppScratch[i] = (uint8_t*)AlignedMalloc(32 * sizeof(KILOBYTE), KNOB_SIMD_WIDTH * 4); #endif + + // Initialize worker thread context for ArchRast. + pContext->pArContext[i] = ArchRast::CreateThreadContext(); } // State setup AFTER context is fully initialized @@ -176,9 +185,12 @@ void SwrDestroyContext(HANDLE hContext) #else AlignedFree(pContext->ppScratch[i]); #endif + + ArchRast::DestroyThreadContext(pContext->pArContext[i]); } delete [] pContext->ppScratch; + delete [] pContext->pArContext; delete [] pContext->pStats; delete(pContext->pHotTileMgr); @@ -1194,6 +1206,9 @@ void DrawIndexedInstance( DRAW_CONTEXT* pDC = GetDrawContext(pContext); API_STATE* pState = &pDC->pState->state; + AR_BEGIN(AR_API_CTX, APIDrawIndexed, pDC->drawId); + AR_EVENT(AR_API_CTX, DrawIndexedInstance(topology, numIndices, indexOffset, baseVertex, numInstances, startInstance)); + uint32_t maxIndicesPerDraw = MaxVertsPerDraw(pDC, numIndices, topology); uint32_t primsPerDraw = GetNumPrims(topology, maxIndicesPerDraw); uint32_t remainingIndices = numIndices; @@ -1265,6 +1280,7 @@ void DrawIndexedInstance( pDC = GetDrawContext(pContext); pDC->pState->state.rastState.cullMode = oldCullMode; + AR_END(AR_API_CTX, APIDrawIndexed, numIndices * numInstances); RDTSC_STOP(APIDrawIndexed, numIndices * numInstances, 0); } diff --git a/src/gallium/drivers/swr/rasterizer/core/context.h b/src/gallium/drivers/swr/rasterizer/core/context.h index f24b8f0..6d63e08 100644 --- a/src/gallium/drivers/swr/rasterizer/core/context.h +++ b/src/gallium/drivers/swr/rasterizer/core/context.h @@ -506,7 +506,24 @@ struct SWR_CONTEXT uint32_t lastFrameChecked; uint64_t lastDrawChecked; TileSet singleThreadLockedTiles; + + // ArchRast thread contexts. + HANDLE* pArContext; }; #define UPDATE_STAT(name, count) if (GetApiState(pDC).enableStats) { pDC->dynState.pStats[workerId].name += count; } #define UPDATE_STAT_FE(name, count) if (GetApiState(pDC).enableStats) { pDC->dynState.statsFE.name += count; } + +// ArchRast instrumentation framework +#ifdef KNOB_ENABLE_AR +#define AR_WORKER_CTX pDC->pContext->pArContext[workerId] +#define AR_API_CTX pDC->pContext->pArContext[pContext->NumWorkerThreads] + +#define AR_BEGIN(ctx, type, id) ArchRast::dispatch(ctx, ArchRast::Start(ArchRast::type, id)) +#define AR_END(ctx, type, count) ArchRast::dispatch(ctx, ArchRast::End(ArchRast::type, count)) +#define AR_EVENT(ctx, event) ArchRast::dispatch(ctx, ArchRast::event) +#else +#define AR_BEGIN(ctx, type, id) +#define AR_END(ctx, type, id) +#define AR_EVENT(ctx, event) +#endif \ No newline at end of file diff --git a/src/gallium/drivers/swr/rasterizer/scripts/gen_archrast.py b/src/gallium/drivers/swr/rasterizer/scripts/gen_archrast.py new file mode 100644 index 0000000..deb16be --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/scripts/gen_archrast.py @@ -0,0 +1,195 @@ +# Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) 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. + +# Python source +from __future__ import print_function +import os +import sys +import re +import argparse +from mako.template import Template +from mako.exceptions import RichTraceback + +def write_template_to_string(template_filename, **kwargs): + try: + template = Template(filename=template_filename) + # Split + Join fixes line-endings for whatever platform you are using + return '\n'.join(template.render(**kwargs).splitlines()) + except: + traceback = RichTraceback() + for (filename, lineno, function, line) in traceback.traceback: + print("File %s, line %s, in %s" % (filename, lineno, function)) + print(line, "\n") + print("%s: %s" % (str(traceback.error.__class__.__name__), traceback.error)) + +def write_template_to_file(template_filename, output_filename, **kwargs): + with open(output_filename, "w") as outfile: + print(write_template_to_string(template_filename, **kwargs), file=outfile) + +def parse_event_fields(lines, idx, event_dict): + field_names = [] + field_types = [] + end_of_event = False + + # record all fields in event definition. + # note: we don't check if there's a leading brace. + while not end_of_event and idx < len(lines): + line = lines[idx].rstrip() + idx += 1 + + field = re.match(r"(\s*)(\w+)(\s*)(\w+)", line) + + if field: + field_types.append(field.group(2)) + field_names.append(field.group(4)) + + end_of_event = re.match(r"(\s*)};", line) + + event_dict['field_types'] = field_types + event_dict['field_names'] = field_names + return idx + +def parse_enums(lines, idx, event_dict): + enum_names = [] + end_of_enum = False + + # record all enum values in enumeration + # note: we don't check if there's a leading brace. + while not end_of_enum and idx < len(lines): + line = lines[idx].rstrip() + idx += 1 + + preprocessor = re.search(r"#if|#endif", line) + + if not preprocessor: + enum = re.match(r"(\s*)(\w+)(\s*)", line) + + if enum: + enum_names.append(line) + + end_of_enum = re.match(r"(\s*)};", line) + + event_dict['names'] = enum_names + return idx + +def parse_protos(filename): + protos = {} + + with open(filename, 'r') as f: + lines=f.readlines() + + idx = 0 + + protos['events'] = {} # event dictionary containing events with their fields + protos['event_names'] = [] # needed to keep events in order parsed. dict is not ordered. + protos['enums'] = {} + protos['enum_names'] = [] + + raw_text = [] + while idx < len(lines): + line = lines[idx].rstrip() + idx += 1 + + # search for event definitions. + match = re.match(r"(\s*)event(\s*)(\w+)", line) + + if match: + event_name = match.group(3) + protos['event_names'].append(event_name) + + protos['events'][event_name] = {} + idx = parse_event_fields(lines, idx, protos['events'][event_name]) + + # search for enums. + match = re.match(r"(\s*)enum(\s*)(\w+)", line) + + if match: + enum_name = match.group(3) + protos['enum_names'].append(enum_name) + + protos['enums'][enum_name] = {} + idx = parse_enums(lines, idx, protos['enums'][enum_name]) + + return protos + +def main(): + + # Parse args... + parser = argparse.ArgumentParser() + parser.add_argument("--proto", "-p", help="Path to proto file", required=True) + parser.add_argument("--output", "-o", help="Output filename (i.e. event.h)", required=True) + parser.add_argument("--gen_event_h", "-geh", help="Generate event header", action="store_true", default=False) + parser.add_argument("--gen_event_cpp", "-gec", help="Generate event cpp", action="store_true", default=False) + parser.add_argument("--gen_eventhandler_h", "-gehh", help="Generate eventhandler header", action="store_true", default=False) + args = parser.parse_args() + + proto_filename = args.proto + + (output_dir, output_filename) = os.path.split(args.output) + + if not output_dir: + output_dir = "." + + #print("output_dir = %s" % output_dir, file=sys.stderr) + #print("output_filename = %s" % output_filename, file=sys.stderr) + + if not os.path.exists(proto_filename): + print("Error: Could not find proto file %s" % proto_filename, file=sys.stderr) + return 1 + + protos = parse_protos(proto_filename) + + # Generate event header + if args.gen_event_h: + curdir = os.path.dirname(os.path.abspath(__file__)) + template_file = os.sep.join([curdir, 'templates', 'ar_event_h.template']) + output_fullpath = os.sep.join([output_dir, output_filename]) + + write_template_to_file(template_file, output_fullpath, + filename=output_filename, + protos=protos) + + # Generate event implementation + if args.gen_event_cpp: + curdir = os.path.dirname(os.path.abspath(__file__)) + template_file = os.sep.join([curdir, 'templates', 'ar_event_cpp.template']) + output_fullpath = os.sep.join([output_dir, output_filename]) + + write_template_to_file(template_file, output_fullpath, + filename=output_filename, + protos=protos) + + # Generate event handler header + if args.gen_eventhandler_h: + curdir = os.path.dirname(os.path.abspath(__file__)) + template_file = os.sep.join([curdir, 'templates', 'ar_eventhandler_h.template']) + output_fullpath = os.sep.join([output_dir, output_filename]) + + write_template_to_file(template_file, output_fullpath, + filename=output_filename, + event_header="gen_ar_event.h", # todo: fix this! + protos=protos) + + return 0 + +if __name__ == '__main__': + sys.exit(main()) + diff --git a/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_cpp.template b/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_cpp.template new file mode 100644 index 0000000..d033d93 --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_cpp.template @@ -0,0 +1,41 @@ +/**************************************************************************** +* Copyright (C) 2016 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +* +* @file ${filename} +* +* @brief Implementation for events. auto-generated file +* +* DO NOT EDIT +* +******************************************************************************/ +#include "common/os.h" +#include "gen_ar_event.h" +#include "gen_ar_eventhandler.h" + +using namespace ArchRast; +% for name in protos['event_names']: + +void ${name}::accept(EventHandler* pHandler) +{ + pHandler->handle(*this); +} +% endfor diff --git a/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_h.template b/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_h.template new file mode 100644 index 0000000..c1576f7 --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_event_h.template @@ -0,0 +1,89 @@ +/**************************************************************************** +* Copyright (C) 2016 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +* +* @file ${filename} +* +* @brief Definitions for events. auto-generated file +* +* DO NOT EDIT +* +******************************************************************************/ +#pragma once + +#include "common/os.h" +#include "core/state.h" + +namespace ArchRast +{ +% for name in protos['enum_names']: + enum ${name} + {<% names = protos['enums'][name]['names'] %> + % for i in range(len(names)): + ${names[i].lstrip()} + % endfor + }; +% endfor + + //Forward decl + class EventHandler; + + ////////////////////////////////////////////////////////////////////////// + /// Event - interface for handling events. + ////////////////////////////////////////////////////////////////////////// + struct Event + { + virtual void accept(EventHandler* pHandler) = 0; + }; +% for name in protos['event_names']: + + ////////////////////////////////////////////////////////////////////////// + /// ${name} + ////////////////////////////////////////////////////////////////////////// + struct ${name} : Event + {<% + field_names = protos['events'][name]['field_names'] + field_types = protos['events'][name]['field_types'] %> + // Fields + % for i in range(len(field_names)): + ${field_types[i]} ${field_names[i]}; + % endfor + + // Constructor + ${name}( + % for i in range(len(field_names)): + % if i < len(field_names)-1: + ${field_types[i]} ${field_names[i]}, + % endif + % if i == len(field_names)-1: + ${field_types[i]} ${field_names[i]}) + % endif + % endfor + { + % for i in range(len(field_names)): + this->${field_names[i]} = ${field_names[i]}; + % endfor + } + + virtual void accept(EventHandler* pHandler); + }; +% endfor +} \ No newline at end of file diff --git a/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_eventhandler_h.template b/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_eventhandler_h.template new file mode 100644 index 0000000..53e5a19 --- /dev/null +++ b/src/gallium/drivers/swr/rasterizer/scripts/templates/ar_eventhandler_h.template @@ -0,0 +1,46 @@ +/**************************************************************************** +* Copyright (C) 2016 Intel Corporation. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +* +* @file ${filename} +* +* @brief Event handler interface. auto-generated file +* +* DO NOT EDIT +* +******************************************************************************/ +#pragma once + +#include "${event_header}" + +namespace ArchRast +{ + ////////////////////////////////////////////////////////////////////////// + /// EventHandler - interface for handling events. + ////////////////////////////////////////////////////////////////////////// + class EventHandler + { + public: +% for name in protos['event_names']: + virtual void handle(${name}& event) {} +% endfor + }; +} -- 2.7.4