diff options
author | Lingfeng Yang <lfy@google.com> | 2017-05-11 07:54:43 -0700 |
---|---|---|
committer | Greg Hartman <ghartman@google.com> | 2018-08-23 17:30:51 -0700 |
commit | 9c7aff1e6963ba734a9cf7a8c24506fcaeee5fc7 (patch) | |
tree | 2f15143e496a89fae3780b23559c07d7e2cf776d | |
parent | 64f12142f8409da9ecc0d52828e5a9fec8fcb5bc (diff) | |
download | opengl-transport-9c7aff1e6963ba734a9cf7a8c24506fcaeee5fc7.tar.gz |
[gl] Fix 'inout' variable qualification + complex readback
- Can use variables with both input and output qualities
- Allow readback of complex structures. 3 phases:
- host_pack_tmp_alloc: custom expression to allocate aligned
temporaries for the output structs
- host_pack: custom expression to pack into stream (losing
alignment)
- guest_unpack: custom expression to unpack into object on guest
(regaining alignment)
Change-Id: I9073325efe6847762e8b2d42fd9803d81ff67374
23 files changed, 439 insertions, 88 deletions
diff --git a/host/commands/emugen/ApiGen.cpp b/host/commands/emugen/ApiGen.cpp index e343b83ab..4b40dc677 100644 --- a/host/commands/emugen/ApiGen.cpp +++ b/host/commands/emugen/ApiGen.cpp @@ -542,6 +542,7 @@ int ApiGen::genEncoderImpl(const std::string &filename) fprintf(fp, "#include <string.h>\n"); fprintf(fp, "#include \"%s_opcodes.h\"\n\n", m_basename.c_str()); fprintf(fp, "#include \"%s_enc.h\"\n\n\n", m_basename.c_str()); + fprintf(fp, "#include <vector>\n\n"); fprintf(fp, "#include <stdio.h>\n\n"); fprintf(fp, "namespace {\n\n"); @@ -778,8 +779,12 @@ int ApiGen::genEncoderImpl(const std::string &filename) indent = "\t\t"; } - fprintf(fp, "%sstream->readback(%s, __size_%s);\n", - indent, varname, varname); + if (evars[j].guestUnpackExpression() != "") { + fprintf(fp, "%s%s;\n", indent, evars[j].guestUnpackExpression().c_str()); + } else { + fprintf(fp, "%sstream->readback(%s, __size_%s);\n", + indent, varname, varname); + } fprintf(fp, "%sif (useChecksum) checksumCalculator->addBuffer(%s, __size_%s);\n", indent, varname, varname); if (evars[j].nullAllowed()) { @@ -1154,8 +1159,7 @@ R"( // Do this on every iteration, as some commands may change the checks } if (!v->isDMA()) { - if (v->pointerDir() == Var::POINTER_IN || - v->pointerDir() == Var::POINTER_INOUT) { + if (v->pointerDir() & Var::POINTER_IN) { if (pass == PASS_VariableDeclarations) { #if USE_ALIGNED_BUFFERS fprintf(fp, @@ -1172,7 +1176,8 @@ R"( // Do this on every iteration, as some commands may change the checks } } - if (pass == PASS_FunctionCall) { + if (pass == PASS_FunctionCall && + v->pointerDir() == Var::POINTER_IN) { if (v->nullAllowed()) { fprintf(fp, "size_%s == 0 ? nullptr : (%s)(inptr_%s.get())", @@ -1192,7 +1197,8 @@ R"( // Do this on every iteration, as some commands may change the checks var_name); } } - } else if (pass == PASS_DebugPrint) { + } else if (pass == PASS_DebugPrint && + v->pointerDir() == Var::POINTER_IN) { fprintf(fp, "(%s)(inptr_%s.get()), size_%s", var_type_name, @@ -1205,7 +1211,8 @@ R"( // Do this on every iteration, as some commands may change the checks var_name, varoffset.c_str()); } - if (pass == PASS_FunctionCall) { + if (pass == PASS_FunctionCall && + v->pointerDir() == Var::POINTER_IN) { if (v->nullAllowed()) { fprintf(fp, "size_%s == 0 ? NULL : (%s)(inptr_%s)", @@ -1218,7 +1225,8 @@ R"( // Do this on every iteration, as some commands may change the checks var_type_name, var_name); } - } else if (pass == PASS_DebugPrint) { + } else if (pass == PASS_DebugPrint && + v->pointerDir() == Var::POINTER_IN) { fprintf(fp, "(%s)(inptr_%s), size_%s", var_type_name, @@ -1228,7 +1236,8 @@ R"( // Do this on every iteration, as some commands may change the checks #endif // !USE_ALIGNED_BUFFERS varoffset += " + 4 + size_"; varoffset += var_name; - } else { // out pointer; + } + if (v->pointerDir() & Var::POINTER_OUT) { // out pointer; if (pass == PASS_TmpBuffAlloc) { if (!totalTmpBuffExist) { fprintf(fp, @@ -1250,18 +1259,40 @@ R"( // Do this on every iteration, as some commands may change the checks var_name, tmpBufOffset[j].c_str(), var_name); - } else if (pass == PASS_FunctionCall) { - if (v->nullAllowed()) { + // If both input and output variable, initialize with the input. + if (v->pointerDir() == Var::POINTER_INOUT) { fprintf(fp, - "size_%s == 0 ? nullptr : (%s)(outptr_%s.get())", + "\t\t\tmemcpy(outptr_%s.get(), inptr_%s.get(), size_%s);\n", + var_name, var_name, - var_type_name, var_name); - } else { + } + + if (v->hostPackExpression() != "") { + fprintf(fp, "\t\t\tvoid* forPacking_%s = nullptr;\n", var_name); + } + if (v->hostPackTmpAllocExpression() != "") { + fprintf(fp, "\t\t\t%s;\n", v->hostPackTmpAllocExpression().c_str()); + } + } else if (pass == PASS_FunctionCall) { + if (v->hostPackExpression() != "") { fprintf(fp, - "(%s)(outptr_%s.get())", + "(%s)(forPacking_%s)", var_type_name, var_name); + } else { + if (v->nullAllowed()) { + fprintf(fp, + "size_%s == 0 ? nullptr : (%s)(outptr_%s.get())", + var_name, + var_type_name, + var_name); + } else { + fprintf(fp, + "(%s)(outptr_%s.get())", + var_type_name, + var_name); + } } } else if (pass == PASS_DebugPrint) { fprintf(fp, @@ -1271,6 +1302,13 @@ R"( // Do this on every iteration, as some commands may change the checks var_name); } if (pass == PASS_FlushOutput) { + if (v->hostPackExpression() != "") { + fprintf(fp, + "\t\t\tif (size_%s) {\n" + "\t\t\t%s; }\n", + var_name, + v->hostPackExpression().c_str()); + } fprintf(fp, "\t\t\toutptr_%s.flush();\n", var_name); @@ -1305,8 +1343,10 @@ R"( // Do this on every iteration, as some commands may change the checks varoffset.c_str()); } #endif // !USE_ALIGNED_BUFFERS + if (v->pointerDir() == Var::POINTER_OUT) { varoffset += " + 4"; } + } } } diff --git a/host/commands/emugen/EntryPoint.cpp b/host/commands/emugen/EntryPoint.cpp index 6aecac16c..d7ce63566 100644 --- a/host/commands/emugen/EntryPoint.cpp +++ b/host/commands/emugen/EntryPoint.cpp @@ -159,6 +159,18 @@ Var * EntryPoint::var(const std::string & name) return v; } +const Var * EntryPoint::var(const std::string & name) const +{ + const Var *v = NULL; + for (size_t i = 0; i < m_vars.size(); i++) { + if (m_vars[i].name() == name) { + v = &m_vars[i]; + break; + } + } + return v; +} + bool EntryPoint::hasPointers() { bool pointers = false; @@ -174,62 +186,57 @@ bool EntryPoint::hasPointers() return pointers; } +int EntryPoint::validateVarAttr(const std::string& varname, size_t lc) const { + if (varname.size() == 0) { + fprintf(stderr, "ERROR: %u: Missing variable name in attribute\n", (unsigned int)lc); + return -1; + } + const Var * v = var(varname); + if (v == NULL) { + fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", + (unsigned int)lc, varname.c_str(), name().c_str()); + return -2; + } + return 0; +} + int EntryPoint::setAttribute(const std::string &line, size_t lc) { size_t pos = 0; size_t last; std::string token = getNextToken(line, 0, &last, WHITESPACE); + int err = 0; + Var* v = nullptr; if (token == "len") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'len' attribute\n", (unsigned int)lc); - return -1; - } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); - return -2; - } // set the size expression into var + v = var(varname); pos = last; v->setLenExpression(line.substr(pos)); } else if (token == "param_check") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'param_check' attribute\n", (unsigned int)lc); - return -1; - } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); - return -2; - } - // set the size expression into var + v = var(varname); pos = last; v->setParamCheckExpression(line.substr(pos)); } else if (token == "dir") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'dir' attribute\n", (unsigned int)lc); - return -1; - } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); - return -2; - } + err = validateVarAttr(varname, lc); + if (err < 0) return err; + v = var(varname); pos = last; + std::string pointerDirStr = getNextToken(line, pos, &last, WHITESPACE); if (pointerDirStr.size() == 0) { fprintf(stderr, "ERROR: %u: missing pointer directions\n", (unsigned int)lc); @@ -243,21 +250,16 @@ int EntryPoint::setAttribute(const std::string &line, size_t lc) } else if (pointerDirStr == "in") { v->setPointerDir(Var::POINTER_IN); } else { - fprintf(stderr, "ERROR: %u: unknow pointer direction %s\n", (unsigned int)lc, pointerDirStr.c_str()); + fprintf(stderr, "ERROR: %u: unknown pointer direction %s\n", + (unsigned int)lc, pointerDirStr.c_str()); } } else if (token == "var_flag") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'var_flag' attribute\n", (unsigned int)lc); - return -1; - } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); - return -2; - } + err = validateVarAttr(varname, lc); + if (err < 0) return err; + + v = var(varname); int count = 0; for (;;) { pos = last; @@ -294,52 +296,75 @@ int EntryPoint::setAttribute(const std::string &line, size_t lc) } else if (token == "custom_pack") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_pack' attribute\n", (unsigned int)lc); - return -1; - } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); - return -2; - } - // set the size expression into var + v = var(varname); pos = last; v->setPackExpression(line.substr(pos)); } else if (token == "custom_unpack") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_unpack' attribute\n", (unsigned int)lc); - return -1; - } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); + err = validateVarAttr(varname, lc); + if (err < 0) return err; + + v = var(varname); + pos = last; + v->setUnpackExpression(line.substr(pos)); + } else if (token == "custom_host_pack_tmp_alloc") { + pos = last; + std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; + + v = var(varname); + if (v->pointerDir() == Var::POINTER_IN) { + fprintf(stderr, "ERROR: %u: variable %s is not an output or inout\n", + (unsigned int)lc, varname.c_str()); return -2; } - // set the size expression into var + pos = last; - v->setUnpackExpression(line.substr(pos)); - } else if (token == "custom_write") { + v->setHostPackTmpAllocExpression(line.substr(pos)); + } else if (token == "custom_host_pack") { pos = last; std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; - if (varname.size() == 0) { - fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_write' attribute\n", (unsigned int)lc); - return -1; + v = var(varname); + if (v->pointerDir() == Var::POINTER_IN) { + fprintf(stderr, "ERROR: %u: variable %s is not an output or inout\n", + (unsigned int)lc, varname.c_str()); + return -2; } - Var * v = var(varname); - if (v == NULL) { - fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n", - (unsigned int)lc, varname.c_str(), name().c_str()); + + pos = last; + v->setHostPackExpression(line.substr(pos)); + } else if (token == "custom_guest_unpack") { + pos = last; + std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; + + v = var(varname); + if (v->pointerDir() == Var::POINTER_IN) { + fprintf(stderr, "ERROR: %u: variable %s is not an output or inout\n", + (unsigned int)lc, varname.c_str()); return -2; } + + pos = last; + v->setGuestUnpackExpression(line.substr(pos)); + } else if (token == "custom_write") { + pos = last; + std::string varname = getNextToken(line, pos, &last, WHITESPACE); + err = validateVarAttr(varname, lc); + if (err < 0) return err; + // set the size expression into var + v = var(varname); pos = last; v->setWriteExpression(line.substr(pos)); } else if (token == "flag") { diff --git a/host/commands/emugen/EntryPoint.h b/host/commands/emugen/EntryPoint.h index a50fda041..bc3fd6937 100644 --- a/host/commands/emugen/EntryPoint.h +++ b/host/commands/emugen/EntryPoint.h @@ -40,6 +40,7 @@ public: VarsArray & vars() { return m_vars; } Var & retval() { return m_retval; } Var * var(const std::string & name); + const Var * var(const std::string & name) const; bool hasPointers(); bool unsupported() const { return m_unsupported; } void setUnsupported(bool state) { m_unsupported = state; } @@ -49,6 +50,7 @@ public: void setNotApi(bool state) { m_notApi = state; } bool flushOnEncode() const { return m_flushOnEncode; } void setFlushOnEncode(bool state) { m_flushOnEncode = state; } + int validateVarAttr(const std::string& varname, size_t lc) const; int setAttribute(const std::string &line, size_t lc); private: diff --git a/host/commands/emugen/Var.h b/host/commands/emugen/Var.h index 3b50bccf6..823058d6e 100644 --- a/host/commands/emugen/Var.h +++ b/host/commands/emugen/Var.h @@ -39,6 +39,9 @@ public: m_pointerDir(dir), m_packExpression(packExpression), m_unpackExpression(unpackExpression), + m_host_packTmpAllocExpression(""), + m_host_packExpression(""), + m_guest_unpackExpression(""), m_writeExpression(writeExpression) { } @@ -54,6 +57,9 @@ public: m_lenExpression = lenExpression; m_packExpression = packExpression; m_unpackExpression = unpackExpression; + m_host_packTmpAllocExpression = ""; + m_host_packExpression = ""; + m_guest_unpackExpression = ""; m_writeExpression = writeExpression; m_pointerDir = dir; m_nullAllowed = false; @@ -68,11 +74,17 @@ public: const std::string & lenExpression() const { return m_lenExpression; } const std::string & packExpression() const { return(m_packExpression); } const std::string & unpackExpression() const { return(m_unpackExpression); } + const std::string & hostPackTmpAllocExpression() const { return(m_host_packTmpAllocExpression); } + const std::string & hostPackExpression() const { return(m_host_packExpression); } + const std::string & guestUnpackExpression() const { return(m_guest_unpackExpression); } const std::string & writeExpression() const { return(m_writeExpression); } const std::string & paramCheckExpression() const { return m_paramCheckExpression; } void setLenExpression(const std::string & lenExpression) { m_lenExpression = lenExpression; } void setPackExpression(const std::string & packExpression) { m_packExpression = packExpression; } void setUnpackExpression(const std::string & unpackExpression) { m_unpackExpression = unpackExpression; } + void setHostPackTmpAllocExpression(const std::string & expr) { m_host_packTmpAllocExpression = expr; } + void setHostPackExpression(const std::string & expr) { m_host_packExpression = expr; } + void setGuestUnpackExpression(const std::string & expr) { m_guest_unpackExpression = expr; } void setWriteExpression(const std::string & writeExpression) { m_writeExpression = writeExpression; } void setParamCheckExpression(const std::string & paramCheckExpression) { m_paramCheckExpression = paramCheckExpression; } void setPointerDir(PointerDir dir) { m_pointerDir = dir; } @@ -96,6 +108,9 @@ private: bool m_isDMA = false; std::string m_packExpression; // an expression to pack data into the stream std::string m_unpackExpression; // an expression to unpack data that has arrived from the stream + std::string m_host_packTmpAllocExpression; // an expression to create temporaries for getting into packed form for readbacks + std::string m_host_packExpression; // an expression to pack data into the stream but for readbacks + std::string m_guest_unpackExpression; // an expression to unpack readbacks on the guest std::string m_writeExpression; // an expression to write data into the stream std::string m_paramCheckExpression; //an expression to check parameter value }; diff --git a/host/commands/emugen/tests/t.001/expected/decoder/foo_dec.cpp b/host/commands/emugen/tests/t.001/expected/decoder/foo_dec.cpp index 174bdf551..ec16b177f 100644 --- a/host/commands/emugen/tests/t.001/expected/decoder/foo_dec.cpp +++ b/host/commands/emugen/tests/t.001/expected/decoder/foo_dec.cpp @@ -109,6 +109,66 @@ size_t foo_decoder_context_t::decode(void *buf, size_t len, IOStream *stream, Ch SET_LASTCALL("fooTakeConstVoidPtrConstPtr"); break; } + case OP_fooSetComplexStruct: { + uint32_t size_obj __attribute__((unused)) = Unpack<uint32_t,uint32_t>(ptr + 8); + InputBuffer inptr_obj(ptr + 8 + 4, size_obj); + void* inptr_obj_unpacked; + FooStruct unpacked; inptr_obj_unpacked = (void*)(&unpacked); fooStructUnpack((unsigned char*)(inptr_obj.get()), size_obj, inptr_obj_unpacked); + if (useChecksum) { + ChecksumCalculatorThreadInfo::validOrDie(checksumCalc, ptr, 8 + 4 + size_obj, ptr + 8 + 4 + size_obj, checksumSize, + "foo_decoder_context_t::decode, OP_fooSetComplexStruct: GL checksumCalculator failure\n"); + } + DEBUG("foo(%p): fooSetComplexStruct(%p(%u) )\n", stream, (const FooStruct*)(inptr_obj.get()), size_obj); + this->fooSetComplexStruct((const FooStruct*)(inptr_obj_unpacked)); + SET_LASTCALL("fooSetComplexStruct"); + break; + } + case OP_fooGetComplexStruct: { + uint32_t size_obj __attribute__((unused)) = Unpack<uint32_t,uint32_t>(ptr + 8); + if (useChecksum) { + ChecksumCalculatorThreadInfo::validOrDie(checksumCalc, ptr, 8 + 4, ptr + 8 + 4, checksumSize, + "foo_decoder_context_t::decode, OP_fooGetComplexStruct: GL checksumCalculator failure\n"); + } + size_t totalTmpSize = size_obj; + totalTmpSize += checksumSize; + unsigned char *tmpBuf = stream->alloc(totalTmpSize); + OutputBuffer outptr_obj(&tmpBuf[0], size_obj); + void* forPacking_obj = nullptr; + FooStruct tmp; forPacking_obj = (void*)tmp; + DEBUG("foo(%p): fooGetComplexStruct(%p(%u) )\n", stream, (FooStruct*)(outptr_obj.get()), size_obj); + this->fooGetComplexStruct((FooStruct*)(forPacking_obj)); + if (size_obj) { + fooStructPack((unsigned char*)outptr_obj.get(), (FooStruct*)forPacking_obj); } + outptr_obj.flush(); + if (useChecksum) { + ChecksumCalculatorThreadInfo::writeChecksum(checksumCalc, &tmpBuf[0], totalTmpSize - checksumSize, &tmpBuf[totalTmpSize - checksumSize], checksumSize); + } + stream->flush(); + SET_LASTCALL("fooGetComplexStruct"); + break; + } + case OP_fooInout: { + uint32_t size_count __attribute__((unused)) = Unpack<uint32_t,uint32_t>(ptr + 8); + InputBuffer inptr_count(ptr + 8 + 4, size_count); + if (useChecksum) { + ChecksumCalculatorThreadInfo::validOrDie(checksumCalc, ptr, 8 + 4 + size_count, ptr + 8 + 4 + size_count, checksumSize, + "foo_decoder_context_t::decode, OP_fooInout: GL checksumCalculator failure\n"); + } + size_t totalTmpSize = size_count; + totalTmpSize += checksumSize; + unsigned char *tmpBuf = stream->alloc(totalTmpSize); + OutputBuffer outptr_count(&tmpBuf[0], size_count); + memcpy(outptr_count.get(), inptr_count.get(), size_count); + DEBUG("foo(%p): fooInout(%p(%u) )\n", stream, (uint32_t*)(outptr_count.get()), size_count); + this->fooInout((uint32_t*)(outptr_count.get())); + outptr_count.flush(); + if (useChecksum) { + ChecksumCalculatorThreadInfo::writeChecksum(checksumCalc, &tmpBuf[0], totalTmpSize - checksumSize, &tmpBuf[totalTmpSize - checksumSize], checksumSize); + } + stream->flush(); + SET_LASTCALL("fooInout"); + break; + } default: return ptr - (unsigned char*)buf; } //switch diff --git a/host/commands/emugen/tests/t.001/expected/decoder/foo_opcodes.h b/host/commands/emugen/tests/t.001/expected/decoder/foo_opcodes.h index 7219caaf1..ee453406f 100644 --- a/host/commands/emugen/tests/t.001/expected/decoder/foo_opcodes.h +++ b/host/commands/emugen/tests/t.001/expected/decoder/foo_opcodes.h @@ -8,7 +8,10 @@ #define OP_fooUnsupported 202 #define OP_fooDoEncoderFlush 203 #define OP_fooTakeConstVoidPtrConstPtr 204 -#define OP_last 205 +#define OP_fooSetComplexStruct 205 +#define OP_fooGetComplexStruct 206 +#define OP_fooInout 207 +#define OP_last 208 #endif diff --git a/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.cpp b/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.cpp index 22ff47f9d..5371fff2f 100644 --- a/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.cpp +++ b/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.cpp @@ -15,6 +15,9 @@ int foo_server_context_t::initDispatchByName(void *(*getProc)(const char *, void fooUnsupported = (fooUnsupported_server_proc_t) getProc("fooUnsupported", userData); fooDoEncoderFlush = (fooDoEncoderFlush_server_proc_t) getProc("fooDoEncoderFlush", userData); fooTakeConstVoidPtrConstPtr = (fooTakeConstVoidPtrConstPtr_server_proc_t) getProc("fooTakeConstVoidPtrConstPtr", userData); + fooSetComplexStruct = (fooSetComplexStruct_server_proc_t) getProc("fooSetComplexStruct", userData); + fooGetComplexStruct = (fooGetComplexStruct_server_proc_t) getProc("fooGetComplexStruct", userData); + fooInout = (fooInout_server_proc_t) getProc("fooInout", userData); return 0; } diff --git a/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.h b/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.h index 713ff5fe3..4f4491925 100644 --- a/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.h +++ b/host/commands/emugen/tests/t.001/expected/decoder/foo_server_context.h @@ -15,6 +15,9 @@ struct foo_server_context_t { fooUnsupported_server_proc_t fooUnsupported; fooDoEncoderFlush_server_proc_t fooDoEncoderFlush; fooTakeConstVoidPtrConstPtr_server_proc_t fooTakeConstVoidPtrConstPtr; + fooSetComplexStruct_server_proc_t fooSetComplexStruct; + fooGetComplexStruct_server_proc_t fooGetComplexStruct; + fooInout_server_proc_t fooInout; virtual ~foo_server_context_t() {} int initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData); }; diff --git a/host/commands/emugen/tests/t.001/expected/decoder/foo_server_proc.h b/host/commands/emugen/tests/t.001/expected/decoder/foo_server_proc.h index da104a13b..593e4c411 100644 --- a/host/commands/emugen/tests/t.001/expected/decoder/foo_server_proc.h +++ b/host/commands/emugen/tests/t.001/expected/decoder/foo_server_proc.h @@ -14,6 +14,9 @@ typedef FooBoolean (foo_APIENTRY *fooIsBuffer_server_proc_t) (void*); typedef void (foo_APIENTRY *fooUnsupported_server_proc_t) (void*); typedef void (foo_APIENTRY *fooDoEncoderFlush_server_proc_t) (FooInt); typedef void (foo_APIENTRY *fooTakeConstVoidPtrConstPtr_server_proc_t) (const void* const*); +typedef void (foo_APIENTRY *fooSetComplexStruct_server_proc_t) (const FooStruct*); +typedef void (foo_APIENTRY *fooGetComplexStruct_server_proc_t) (FooStruct*); +typedef void (foo_APIENTRY *fooInout_server_proc_t) (uint32_t*); #endif diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.cpp b/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.cpp index f09e8811c..d28b5a054 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.cpp +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.cpp @@ -15,6 +15,9 @@ int foo_client_context_t::initDispatchByName(void *(*getProc)(const char *, void fooUnsupported = (fooUnsupported_client_proc_t) getProc("fooUnsupported", userData); fooDoEncoderFlush = (fooDoEncoderFlush_client_proc_t) getProc("fooDoEncoderFlush", userData); fooTakeConstVoidPtrConstPtr = (fooTakeConstVoidPtrConstPtr_client_proc_t) getProc("fooTakeConstVoidPtrConstPtr", userData); + fooSetComplexStruct = (fooSetComplexStruct_client_proc_t) getProc("fooSetComplexStruct", userData); + fooGetComplexStruct = (fooGetComplexStruct_client_proc_t) getProc("fooGetComplexStruct", userData); + fooInout = (fooInout_client_proc_t) getProc("fooInout", userData); return 0; } diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.h b/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.h index ce60329c5..d1c1675c0 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.h +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_client_context.h @@ -15,6 +15,9 @@ struct foo_client_context_t { fooUnsupported_client_proc_t fooUnsupported; fooDoEncoderFlush_client_proc_t fooDoEncoderFlush; fooTakeConstVoidPtrConstPtr_client_proc_t fooTakeConstVoidPtrConstPtr; + fooSetComplexStruct_client_proc_t fooSetComplexStruct; + fooGetComplexStruct_client_proc_t fooGetComplexStruct; + fooInout_client_proc_t fooInout; virtual ~foo_client_context_t() {} typedef foo_client_context_t *CONTEXT_ACCESSOR_TYPE(void); diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_client_proc.h b/host/commands/emugen/tests/t.001/expected/encoder/foo_client_proc.h index 6fc27f060..d9bbcb666 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_client_proc.h +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_client_proc.h @@ -14,6 +14,9 @@ typedef FooBoolean (foo_APIENTRY *fooIsBuffer_client_proc_t) (void * ctx, void*) typedef void (foo_APIENTRY *fooUnsupported_client_proc_t) (void * ctx, void*); typedef void (foo_APIENTRY *fooDoEncoderFlush_client_proc_t) (void * ctx, FooInt); typedef void (foo_APIENTRY *fooTakeConstVoidPtrConstPtr_client_proc_t) (void * ctx, const void* const*); +typedef void (foo_APIENTRY *fooSetComplexStruct_client_proc_t) (void * ctx, const FooStruct*); +typedef void (foo_APIENTRY *fooGetComplexStruct_client_proc_t) (void * ctx, FooStruct*); +typedef void (foo_APIENTRY *fooInout_client_proc_t) (void * ctx, uint32_t*); #endif diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_enc.cpp b/host/commands/emugen/tests/t.001/expected/encoder/foo_enc.cpp index c922783e4..13a4dd56b 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_enc.cpp +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_enc.cpp @@ -8,6 +8,8 @@ #include "foo_enc.h" +#include <vector> + #include <stdio.h> namespace { @@ -138,6 +140,110 @@ void fooTakeConstVoidPtrConstPtr_enc(void *self , const void* const* param) } +void fooSetComplexStruct_enc(void *self , const FooStruct* obj) +{ + + foo_encoder_context_t *ctx = (foo_encoder_context_t *)self; + IOStream *stream = ctx->m_stream; + ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator; + bool useChecksum = checksumCalculator->getVersion() > 0; + + const unsigned int __size_obj = fooStructEncodingSize(obj); + unsigned char *ptr; + unsigned char *buf; + const size_t sizeWithoutChecksum = 8 + __size_obj + 1*4; + const size_t checksumSize = checksumCalculator->checksumByteSize(); + const size_t totalSize = sizeWithoutChecksum + checksumSize; + buf = stream->alloc(totalSize); + ptr = buf; + int tmp = OP_fooSetComplexStruct;memcpy(ptr, &tmp, 4); ptr += 4; + memcpy(ptr, &totalSize, 4); ptr += 4; + + *(unsigned int *)(ptr) = __size_obj; ptr += 4; + fooStructPack(ptr, obj);ptr += __size_obj; + + if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf); + if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize; + +} + +void fooGetComplexStruct_enc(void *self , FooStruct* obj) +{ + + foo_encoder_context_t *ctx = (foo_encoder_context_t *)self; + IOStream *stream = ctx->m_stream; + ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator; + bool useChecksum = checksumCalculator->getVersion() > 0; + + const unsigned int __size_obj = fooStructEncodingSize(obj); + unsigned char *ptr; + unsigned char *buf; + const size_t sizeWithoutChecksum = 8 + 0 + 1*4; + const size_t checksumSize = checksumCalculator->checksumByteSize(); + const size_t totalSize = sizeWithoutChecksum + checksumSize; + buf = stream->alloc(totalSize); + ptr = buf; + int tmp = OP_fooGetComplexStruct;memcpy(ptr, &tmp, 4); ptr += 4; + memcpy(ptr, &totalSize, 4); ptr += 4; + + *(unsigned int *)(ptr) = __size_obj; ptr += 4; + + if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf); + if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize; + + std::vector<unsigned char> forUnpacking_obj(__size_obj); stream->readback(&forUnpacking_obj[0], __size_obj); fooStructUnpack(&forUnpacking_obj[0], obj); + if (useChecksum) checksumCalculator->addBuffer(obj, __size_obj); + if (useChecksum) { + unsigned char *checksumBufPtr = NULL; + unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize]; + if (checksumSize > 0) checksumBufPtr = &checksumBuf[0]; + stream->readback(checksumBufPtr, checksumSize); + if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) { + ALOGE("fooGetComplexStruct: GL communication error, please report this issue to b.android.com.\n"); + abort(); + } + } +} + +void fooInout_enc(void *self , uint32_t* count) +{ + + foo_encoder_context_t *ctx = (foo_encoder_context_t *)self; + IOStream *stream = ctx->m_stream; + ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator; + bool useChecksum = checksumCalculator->getVersion() > 0; + + const unsigned int __size_count = sizeof(uint32_t); + unsigned char *ptr; + unsigned char *buf; + const size_t sizeWithoutChecksum = 8 + __size_count + 1*4; + const size_t checksumSize = checksumCalculator->checksumByteSize(); + const size_t totalSize = sizeWithoutChecksum + checksumSize; + buf = stream->alloc(totalSize); + ptr = buf; + int tmp = OP_fooInout;memcpy(ptr, &tmp, 4); ptr += 4; + memcpy(ptr, &totalSize, 4); ptr += 4; + + *(unsigned int *)(ptr) = __size_count; ptr += 4; + memcpy(ptr, count, __size_count);ptr += __size_count; + + if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf); + if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize; + + stream->readback(count, __size_count); + if (useChecksum) checksumCalculator->addBuffer(count, __size_count); + if (useChecksum) { + unsigned char *checksumBufPtr = NULL; + unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize]; + if (checksumSize > 0) checksumBufPtr = &checksumBuf[0]; + stream->readback(checksumBufPtr, checksumSize); + if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) { + ALOGE("fooInout: GL communication error, please report this issue to b.android.com.\n"); + abort(); + } + } +} + } // namespace foo_encoder_context_t::foo_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator) @@ -150,5 +256,8 @@ foo_encoder_context_t::foo_encoder_context_t(IOStream *stream, ChecksumCalculato this->fooUnsupported = (fooUnsupported_client_proc_t) &enc_unsupported; this->fooDoEncoderFlush = &fooDoEncoderFlush_enc; this->fooTakeConstVoidPtrConstPtr = &fooTakeConstVoidPtrConstPtr_enc; + this->fooSetComplexStruct = &fooSetComplexStruct_enc; + this->fooGetComplexStruct = &fooGetComplexStruct_enc; + this->fooInout = &fooInout_enc; } diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_entry.cpp b/host/commands/emugen/tests/t.001/expected/encoder/foo_entry.cpp index 05bf3bb6e..92e8ef43a 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_entry.cpp +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_entry.cpp @@ -10,6 +10,9 @@ extern "C" { void fooUnsupported(void* params); void fooDoEncoderFlush(FooInt param); void fooTakeConstVoidPtrConstPtr(const void* const* param); + void fooSetComplexStruct(const FooStruct* obj); + void fooGetComplexStruct(FooStruct* obj); + void fooInout(uint32_t* count); }; #ifndef GET_CONTEXT @@ -49,3 +52,21 @@ void fooTakeConstVoidPtrConstPtr(const void* const* param) ctx->fooTakeConstVoidPtrConstPtr(ctx, param); } +void fooSetComplexStruct(const FooStruct* obj) +{ + GET_CONTEXT; + ctx->fooSetComplexStruct(ctx, obj); +} + +void fooGetComplexStruct(FooStruct* obj) +{ + GET_CONTEXT; + ctx->fooGetComplexStruct(ctx, obj); +} + +void fooInout(uint32_t* count) +{ + GET_CONTEXT; + ctx->fooInout(ctx, count); +} + diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_ftable.h b/host/commands/emugen/tests/t.001/expected/encoder/foo_ftable.h index e397e50e2..0b759b52c 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_ftable.h +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_ftable.h @@ -13,6 +13,9 @@ static const struct _foo_funcs_by_name { {"fooUnsupported", (void*)fooUnsupported}, {"fooDoEncoderFlush", (void*)fooDoEncoderFlush}, {"fooTakeConstVoidPtrConstPtr", (void*)fooTakeConstVoidPtrConstPtr}, + {"fooSetComplexStruct", (void*)fooSetComplexStruct}, + {"fooGetComplexStruct", (void*)fooGetComplexStruct}, + {"fooInout", (void*)fooInout}, }; static const int foo_num_funcs = sizeof(foo_funcs_by_name) / sizeof(struct _foo_funcs_by_name); diff --git a/host/commands/emugen/tests/t.001/expected/encoder/foo_opcodes.h b/host/commands/emugen/tests/t.001/expected/encoder/foo_opcodes.h index 7219caaf1..ee453406f 100644 --- a/host/commands/emugen/tests/t.001/expected/encoder/foo_opcodes.h +++ b/host/commands/emugen/tests/t.001/expected/encoder/foo_opcodes.h @@ -8,7 +8,10 @@ #define OP_fooUnsupported 202 #define OP_fooDoEncoderFlush 203 #define OP_fooTakeConstVoidPtrConstPtr 204 -#define OP_last 205 +#define OP_fooSetComplexStruct 205 +#define OP_fooGetComplexStruct 206 +#define OP_fooInout 207 +#define OP_last 208 #endif diff --git a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.cpp b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.cpp index 6e132b104..e8781cccb 100644 --- a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.cpp +++ b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.cpp @@ -15,6 +15,9 @@ int foo_wrapper_context_t::initDispatchByName(void *(*getProc)(const char *, voi fooUnsupported = (fooUnsupported_wrapper_proc_t) getProc("fooUnsupported", userData); fooDoEncoderFlush = (fooDoEncoderFlush_wrapper_proc_t) getProc("fooDoEncoderFlush", userData); fooTakeConstVoidPtrConstPtr = (fooTakeConstVoidPtrConstPtr_wrapper_proc_t) getProc("fooTakeConstVoidPtrConstPtr", userData); + fooSetComplexStruct = (fooSetComplexStruct_wrapper_proc_t) getProc("fooSetComplexStruct", userData); + fooGetComplexStruct = (fooGetComplexStruct_wrapper_proc_t) getProc("fooGetComplexStruct", userData); + fooInout = (fooInout_wrapper_proc_t) getProc("fooInout", userData); return 0; } diff --git a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.h b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.h index 52db4b6fb..c9853d298 100644 --- a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.h +++ b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_context.h @@ -15,6 +15,9 @@ struct foo_wrapper_context_t { fooUnsupported_wrapper_proc_t fooUnsupported; fooDoEncoderFlush_wrapper_proc_t fooDoEncoderFlush; fooTakeConstVoidPtrConstPtr_wrapper_proc_t fooTakeConstVoidPtrConstPtr; + fooSetComplexStruct_wrapper_proc_t fooSetComplexStruct; + fooGetComplexStruct_wrapper_proc_t fooGetComplexStruct; + fooInout_wrapper_proc_t fooInout; virtual ~foo_wrapper_context_t() {} typedef foo_wrapper_context_t *CONTEXT_ACCESSOR_TYPE(void); diff --git a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_entry.cpp b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_entry.cpp index 284c1c855..733c8248d 100644 --- a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_entry.cpp +++ b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_entry.cpp @@ -10,6 +10,9 @@ extern "C" { void fooUnsupported(void* params); void fooDoEncoderFlush(FooInt param); void fooTakeConstVoidPtrConstPtr(const void* const* param); + void fooSetComplexStruct(const FooStruct* obj); + void fooGetComplexStruct(FooStruct* obj); + void fooInout(uint32_t* count); }; #ifndef GET_CONTEXT @@ -48,3 +51,21 @@ void fooTakeConstVoidPtrConstPtr(const void* const* param) ctx->fooTakeConstVoidPtrConstPtr( param); } +void fooSetComplexStruct(const FooStruct* obj) +{ + GET_CONTEXT; + ctx->fooSetComplexStruct( obj); +} + +void fooGetComplexStruct(FooStruct* obj) +{ + GET_CONTEXT; + ctx->fooGetComplexStruct( obj); +} + +void fooInout(uint32_t* count) +{ + GET_CONTEXT; + ctx->fooInout( count); +} + diff --git a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_proc.h b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_proc.h index 294b9587d..66ced3138 100644 --- a/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_proc.h +++ b/host/commands/emugen/tests/t.001/expected/wrapper/foo_wrapper_proc.h @@ -14,6 +14,9 @@ typedef FooBoolean (foo_APIENTRY *fooIsBuffer_wrapper_proc_t) (void*); typedef void (foo_APIENTRY *fooUnsupported_wrapper_proc_t) (void*); typedef void (foo_APIENTRY *fooDoEncoderFlush_wrapper_proc_t) (FooInt); typedef void (foo_APIENTRY *fooTakeConstVoidPtrConstPtr_wrapper_proc_t) (const void* const*); +typedef void (foo_APIENTRY *fooSetComplexStruct_wrapper_proc_t) (const FooStruct*); +typedef void (foo_APIENTRY *fooGetComplexStruct_wrapper_proc_t) (FooStruct*); +typedef void (foo_APIENTRY *fooInout_wrapper_proc_t) (uint32_t*); #endif diff --git a/host/commands/emugen/tests/t.001/input/foo.attrib b/host/commands/emugen/tests/t.001/input/foo.attrib index 80644d8bb..9b66c5796 100644 --- a/host/commands/emugen/tests/t.001/input/foo.attrib +++ b/host/commands/emugen/tests/t.001/input/foo.attrib @@ -13,3 +13,20 @@ fooUnsupported fooDoEncoderFlush flag flushOnEncode + +fooSetComplexStruct + dir obj in + len obj fooStructEncodingSize(obj) + custom_pack obj fooStructPack(ptr, obj) + custom_unpack obj FooStruct unpacked; inptr_obj_unpacked = (void*)(&unpacked); fooStructUnpack((unsigned char*)(inptr_obj.get()), size_obj, inptr_obj_unpacked) + +fooGetComplexStruct + dir obj out + len obj fooStructEncodingSize(obj) + custom_host_pack_tmp_alloc obj FooStruct tmp; forPacking_obj = (void*)tmp + custom_host_pack obj fooStructPack((unsigned char*)outptr_obj.get(), (FooStruct*)forPacking_obj) + custom_guest_unpack obj std::vector<unsigned char> forUnpacking_obj(__size_obj); stream->readback(&forUnpacking_obj[0], __size_obj); fooStructUnpack(&forUnpacking_obj[0], obj) + +fooInout + dir count inout + len count sizeof(uint32_t) diff --git a/host/commands/emugen/tests/t.001/input/foo.in b/host/commands/emugen/tests/t.001/input/foo.in index 4e98f88b6..b12ad99f9 100644 --- a/host/commands/emugen/tests/t.001/input/foo.in +++ b/host/commands/emugen/tests/t.001/input/foo.in @@ -3,3 +3,6 @@ FOO_ENTRY(FooBoolean, fooIsBuffer, void* stuff) FOO_ENTRY(void, fooUnsupported, void* params) FOO_ENTRY(void, fooDoEncoderFlush, FooInt param) FOO_ENTRY(void, fooTakeConstVoidPtrConstPtr, const void* const* param) +FOO_ENTRY(void, fooSetComplexStruct, const FooStruct* obj) +FOO_ENTRY(void, fooGetComplexStruct, FooStruct* obj) +FOO_ENTRY(void, fooInout, uint32_t* count) diff --git a/host/commands/emugen/tests/t.001/input/foo.types b/host/commands/emugen/tests/t.001/input/foo.types index 05d72fbe2..45e17c913 100644 --- a/host/commands/emugen/tests/t.001/input/foo.types +++ b/host/commands/emugen/tests/t.001/input/foo.types @@ -8,3 +8,5 @@ FooChar 8 %d FooChar* 32 0x%08x void* 32 0x%08x void*const* 32 0x%08x +FooStruct* 32 0x%08x +uint32_t* 32 0x%08x |