diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-17 00:07:20 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-17 00:07:20 +0000 |
commit | d26e0dc9edbb20145628cb25c65db63dc2664844 (patch) | |
tree | e36831e1e47b19d2456b6014efd0306d12960a6a /o3d | |
parent | 0ca1ccdea35a265e21b30ec6e5c5b002d5f5afc3 (diff) | |
download | chromium_src-d26e0dc9edbb20145628cb25c65db63dc2664844.zip chromium_src-d26e0dc9edbb20145628cb25c65db63dc2664844.tar.gz chromium_src-d26e0dc9edbb20145628cb25c65db63dc2664844.tar.bz2 |
Changing command buffer to use structs instead of
arrays, step 1
I hope I'm not stepping on any toes here. I wanted
to write some command buffer code but I didn't want
to go poking values into arrays so I thought I'd
attempt to refactor a little. I hope I'm not steping
on any toes.
Some answers to possible questions.
O3D_COMMAND_ARGS_FLAG_AT_LEAST_N is a macro because
it needs to be a compile time constant so I can generate
the table.
All the commands with a FixMe are to be done in another
CL.
The Structs don't follow the style guide because it's
just busy work to match up SET_TOKEN and SetToken.
It seems like a reasonable exception to me. This way
the functions, IDs and structs all match easily
and therefore lists that use them be automatically
generated and kept in sync.
The next step is I want to uncompress some of the
commands. As an example, it doesn't seem like
CreateTexture2D should squeeze width and height into
16bits halfs of a 32bit value. This API is not targeted
at machines with 2K of memory and the amount of code
and other scaffolding around decoding those 2 16bit
halfs far outways saving 16bits in a command that
allocates a texture. It also makes it harder to use
the command because the person generating it has to
also go through the same hoops.
Review URL: http://codereview.chromium.org/206020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26421 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r-- | o3d/command_buffer/common/cross/cmd_buffer_format.h | 627 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/cmd_parser.h | 2 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gapi_decoder.cc | 1243 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gapi_decoder.h | 14 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/mocks.h | 14 |
5 files changed, 1254 insertions, 646 deletions
diff --git a/o3d/command_buffer/common/cross/cmd_buffer_format.h b/o3d/command_buffer/common/cross/cmd_buffer_format.h index 1338329..51d0e9b 100644 --- a/o3d/command_buffer/common/cross/cmd_buffer_format.h +++ b/o3d/command_buffer/common/cross/cmd_buffer_format.h @@ -38,6 +38,7 @@ #include "base/basictypes.h" #include "command_buffer/common/cross/types.h" #include "command_buffer/common/cross/bitfield_helpers.h" +#include "core/cross/packing.h" namespace o3d { namespace command_buffer { @@ -268,74 +269,572 @@ typedef BitField<30, 1> SeparateAlpha; typedef BitField<31, 1> Enable; } // namespace set_blending + +// This macro is used to safely and convienently expand the list of commnad +// buffer commands in to various lists and never have them get out of sync. To +// add a new command, add it this list, create the corresponding structure below +// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where +// COMMAND_NAME is the name of your command structure. +// +// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) +#define O3D_COMMAND_BUFFER_CMDS \ + O3D_COMMAND_BUFFER_CMD_OP(NOOP) /* 0 */ \ + O3D_COMMAND_BUFFER_CMD_OP(SET_TOKEN) \ + O3D_COMMAND_BUFFER_CMD_OP(BEGIN_FRAME) \ + O3D_COMMAND_BUFFER_CMD_OP(END_FRAME) \ + O3D_COMMAND_BUFFER_CMD_OP(CLEAR) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_VERTEX_BUFFER) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_VERTEX_BUFFER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_BUFFER_DATA_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_VERTEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_INDEX_BUFFER) /* 10 */ \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_INDEX_BUFFER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_INDEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_INDEX_BUFFER_DATA_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_INDEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_VERTEX_STRUCT) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_VERTEX_STRUCT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_INPUT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_STRUCT) \ + O3D_COMMAND_BUFFER_CMD_OP(DRAW) \ + O3D_COMMAND_BUFFER_CMD_OP(DRAW_INDEXED) /* 20 */ \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_EFFECT) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_EFFECT_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_EFFECT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_EFFECT) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_PARAM_COUNT) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_PARAM) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_PARAM_BY_NAME) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_PARAM_BY_NAME_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_PARAM) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_PARAM_DATA) /* 30 */ \ + O3D_COMMAND_BUFFER_CMD_OP(SET_PARAM_DATA_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_PARAM_DESC) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_STREAM_COUNT) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_STREAM_DESC) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_TEXTURE) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_TEXTURE_2D) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_TEXTURE_3D) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_TEXTURE_CUBE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_TEXTURE_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_TEXTURE_DATA_IMMEDIATE) /* 40 */ \ + O3D_COMMAND_BUFFER_CMD_OP(GET_TEXTURE_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_SAMPLER) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_SAMPLER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SAMPLER_STATES) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SAMPLER_BORDER_COLOR) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SAMPLER_TEXTURE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VIEWPORT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SCISSOR) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_POINT_LINE_RASTER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_POLYGON_RASTER) /* 50 */ \ + O3D_COMMAND_BUFFER_CMD_OP(SET_POLYGON_OFFSET) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_ALPHA_TEST) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_DEPTH_TEST) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_STENCIL_TEST) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_BLENDING) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_BLENDING_COLOR) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_COLOR_WRITE) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_RENDER_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_RENDER_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_DEPTH_SURFACE) /* 60 */ \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_DEPTH_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_RENDER_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_BACK_SURFACES) \ + + // GAPI commands. enum CommandId { - NOOP, // No operation. Arbitrary argument size. - SET_TOKEN, // Sets token. 1 argument. val 0 - BEGIN_FRAME, // BeginFrame. 0 argument. - END_FRAME, // EndFrame. 0 argument. - CLEAR, // Clear. 7 arguments. - CREATE_VERTEX_BUFFER, // CreateVertexBuffer, 3 arguments. - DESTROY_VERTEX_BUFFER, // DestroyVertexBuffer. 1 argument. - SET_VERTEX_BUFFER_DATA, // SetVertexBufferData, 5 args - SET_VERTEX_BUFFER_DATA_IMMEDIATE, // SetVertexBufferData, 2 args + data - GET_VERTEX_BUFFER_DATA, // GetVertexBufferData, 5 args, - CREATE_INDEX_BUFFER, // CreateIndexBuffer, 3 arguments. val 10 - DESTROY_INDEX_BUFFER, // DestroyIndexBuffer. 1 argument. - SET_INDEX_BUFFER_DATA, // SetIndexBufferData, 5 args - SET_INDEX_BUFFER_DATA_IMMEDIATE, // SetIndexBufferData, 2 args + data - GET_INDEX_BUFFER_DATA, // GetIndexBufferData, 5 args - CREATE_VERTEX_STRUCT, // CreateVertexStruct, 2 args. - DESTROY_VERTEX_STRUCT, // DestroyVertexStruct. 1 argument. - SET_VERTEX_INPUT, // SetVertexInput, 5 args. - SET_VERTEX_STRUCT, // SetVertexStruct, 1 arg. - DRAW, // Draw, 3 args. value - DRAW_INDEXED, // DrawIndexed, 6 args. val 20 - CREATE_EFFECT, // CreateEffect, 4 args. - CREATE_EFFECT_IMMEDIATE, // CreateEffect, 2 args + data - DESTROY_EFFECT, // DestroyEffect, 1 arg. - SET_EFFECT, // SetEffect, 1 arg. - GET_PARAM_COUNT, // GetParamCount, 4 args. - CREATE_PARAM, // CreateParam, 3 args. - CREATE_PARAM_BY_NAME, // CreateParamByName, 5 args. - CREATE_PARAM_BY_NAME_IMMEDIATE, // CreateParamByName, 3 args + data - DESTROY_PARAM, // DestroyParam, 1 arg - SET_PARAM_DATA, // SetParamData, 4 args val 30 - SET_PARAM_DATA_IMMEDIATE, // SetParamData, 2 args + data - GET_PARAM_DESC, // GetParamDesc, 4 args - GET_STREAM_COUNT, // GetStreamCount, 4 args. - GET_STREAM_DESC, // GetStreamDesc, 5 args - DESTROY_TEXTURE, // DestroyTexture, 1 arg - CREATE_TEXTURE_2D, // CreateTexture2D, 4 args - CREATE_TEXTURE_3D, // CreateTexture3D, 4 args - CREATE_TEXTURE_CUBE, // CreateTextureCube, 3 args - SET_TEXTURE_DATA, // SetTextureData, 10 args - SET_TEXTURE_DATA_IMMEDIATE, // SetTextureData, 8 args + data val 40 - GET_TEXTURE_DATA, // GetTextureData, 10 args - CREATE_SAMPLER, // CreateSampler, 1 arg - DESTROY_SAMPLER, // DestroySampler, 1 arg - SET_SAMPLER_STATES, // SetSamplerStates, 2 arg - SET_SAMPLER_BORDER_COLOR, // SetSamplerBorderColor, 5 arg - SET_SAMPLER_TEXTURE, // SetSamplerTexture, 2 arg - SET_VIEWPORT, // SetViewport. 6 arguments. - SET_SCISSOR, // SetScissor, 2 args - SET_POINT_LINE_RASTER, // SetPointLineRaster, 2 args - SET_POLYGON_RASTER, // SetPolygonRaster, 1 args val 50 - SET_POLYGON_OFFSET, // SetPolygonOffest, 2 args - SET_ALPHA_TEST, // SetAlphaTest, 2 args - SET_DEPTH_TEST, // SetDepthTest, 1 args - SET_STENCIL_TEST, // SetStencilTest, 2 args - SET_BLENDING, // SetBlending, 1 args - SET_BLENDING_COLOR, // SetBlendingColor, 4 args - SET_COLOR_WRITE, // SetColorWrite, 1 args - CREATE_RENDER_SURFACE, // CreateRenderSurface, 4 args. - DESTROY_RENDER_SURFACE, // DestoryRenderSurface, 1 arg. - CREATE_DEPTH_SURFACE, // CreateRenderSurface, 2 args. val 60 - DESTROY_DEPTH_SURFACE, // DestoryRenderSurface, 1 arg. - SET_RENDER_SURFACE, // SetRenderSurface, 2 args. - SET_BACK_SURFACES // SetBackSurfaces + #define O3D_COMMAND_BUFFER_CMD_OP(name) name, + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP +}; + +namespace cmd { + +// Make sure the compiler does not add extra padding to any of the command +// structures. +O3D_PUSH_STRUCTURE_PACKING_1; + +enum ArgFlags { + kFixed = 0x0, + kAtLeastN = 0x1, +}; + +struct SharedMemory { + uint32 id; + uint32 offset; +}; + +struct NOOP { + static const CommandId kCmdId = command_buffer::NOOP; + static const ArgFlags kArgFlags = kAtLeastN; +}; + +struct SET_TOKEN { + static const CommandId kCmdId = command_buffer::SET_TOKEN; + static const ArgFlags kArgFlags = kFixed; + uint32 token; +}; + +struct BEGIN_FRAME { + static const CommandId kCmdId = command_buffer::BEGIN_FRAME; + static const ArgFlags kArgFlags = kFixed; +}; + +struct END_FRAME { + static const CommandId kCmdId = command_buffer::END_FRAME; + static const ArgFlags kArgFlags = kFixed; +}; + +struct CLEAR { + static const CommandId kCmdId = command_buffer::CLEAR; + static const ArgFlags kArgFlags = kFixed; + uint32 buffers; + float red; + float green; + float blue; + float alpha; + float depth; + uint32 stencil; +}; + +struct SET_VIEWPORT { + static const CommandId kCmdId = command_buffer::SET_VIEWPORT; + static const ArgFlags kArgFlags = kFixed; + uint32 left; + uint32 top; + uint32 width; + uint32 height; + float z_min; + float z_max; +}; + +struct CREATE_VERTEX_BUFFER { + static const CommandId kCmdId = command_buffer::CREATE_VERTEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + uint32 flags; +}; + +struct DESTROY_VERTEX_BUFFER { + static const CommandId kCmdId = command_buffer::DESTROY_VERTEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_VERTEX_BUFFER_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_VERTEX_BUFFER_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 offset; +}; + +struct SET_VERTEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::SET_VERTEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_VERTEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::GET_VERTEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_INDEX_BUFFER { + static const CommandId kCmdId = command_buffer::CREATE_INDEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + uint32 flags; +}; + +struct DESTROY_INDEX_BUFFER { + static const CommandId kCmdId = command_buffer::DESTROY_INDEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_INDEX_BUFFER_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_INDEX_BUFFER_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 offset; +}; + +struct SET_INDEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::SET_INDEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_INDEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::GET_INDEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_VERTEX_STRUCT { + static const CommandId kCmdId = command_buffer::CREATE_VERTEX_STRUCT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 input_count; +}; + +struct DESTROY_VERTEX_STRUCT { + static const CommandId kCmdId = command_buffer::DESTROY_VERTEX_STRUCT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_VERTEX_INPUT { + static const CommandId kCmdId = command_buffer::SET_VERTEX_INPUT; + static const ArgFlags kArgFlags = kAtLeastN; +}; + +struct SET_VERTEX_STRUCT { + static const CommandId kCmdId = command_buffer::SET_VERTEX_STRUCT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct DRAW { + static const CommandId kCmdId = command_buffer::DRAW; + static const ArgFlags kArgFlags = kFixed; + uint32 primitive_type; + uint32 first; + uint32 count; +}; + +struct DRAW_INDEXED { + static const CommandId kCmdId = command_buffer::DRAW_INDEXED; + static const ArgFlags kArgFlags = kFixed; + uint32 primitive_type; + uint32 index_buffer_id; + uint32 first; + uint32 count; + uint32 min_index; + uint32 max_index; +}; + +struct CREATE_EFFECT { + static const CommandId kCmdId = command_buffer::CREATE_EFFECT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_EFFECT_IMMEDIATE { + static const CommandId kCmdId = command_buffer::CREATE_EFFECT_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 size; +}; + +struct DESTROY_EFFECT { + static const CommandId kCmdId = command_buffer::DESTROY_EFFECT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_EFFECT { + static const CommandId kCmdId = command_buffer::SET_EFFECT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct GET_PARAM_COUNT { + static const CommandId kCmdId = command_buffer::GET_PARAM_COUNT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_PARAM { + static const CommandId kCmdId = command_buffer::CREATE_PARAM; + static const ArgFlags kArgFlags = kFixed; + uint32 param_id; + uint32 effect_id; + uint32 index; +}; + +struct CREATE_PARAM_BY_NAME { + static const CommandId kCmdId = command_buffer::CREATE_PARAM_BY_NAME; + static const ArgFlags kArgFlags = kFixed; + uint32 param_id; + uint32 effect_id; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_PARAM_BY_NAME_IMMEDIATE { + static const CommandId kCmdId = command_buffer::CREATE_PARAM_BY_NAME_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 param_id; + uint32 effect_id; + uint32 size; }; +struct DESTROY_PARAM { + static const CommandId kCmdId = command_buffer::DESTROY_PARAM; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_PARAM_DATA { + static const CommandId kCmdId = command_buffer::SET_PARAM_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct SET_PARAM_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_PARAM_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 size; +}; + +struct GET_PARAM_DESC { + static const CommandId kCmdId = command_buffer::GET_PARAM_DESC; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_STREAM_COUNT { + static const CommandId kCmdId = command_buffer::GET_STREAM_COUNT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_STREAM_DESC { + static const CommandId kCmdId = command_buffer::GET_STREAM_DESC; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 index; + uint32 size; + SharedMemory shared_memory; +}; + +struct DESTROY_TEXTURE { + static const CommandId kCmdId = command_buffer::DESTROY_TEXTURE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct CREATE_TEXTURE_2D { + static const CommandId kCmdId = command_buffer::CREATE_TEXTURE_2D; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct CREATE_TEXTURE_3D { + static const CommandId kCmdId = command_buffer::CREATE_TEXTURE_3D; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct CREATE_TEXTURE_CUBE { + static const CommandId kCmdId = command_buffer::CREATE_TEXTURE_CUBE; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_TEXTURE_DATA { + static const CommandId kCmdId = command_buffer::SET_TEXTURE_DATA; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_TEXTURE_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_TEXTURE_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct GET_TEXTURE_DATA { + static const CommandId kCmdId = command_buffer::GET_TEXTURE_DATA; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct CREATE_SAMPLER { + static const CommandId kCmdId = command_buffer::CREATE_SAMPLER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct DESTROY_SAMPLER { + static const CommandId kCmdId = command_buffer::DESTROY_SAMPLER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_SAMPLER_STATES { + static const CommandId kCmdId = command_buffer::SET_SAMPLER_STATES; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_SAMPLER_BORDER_COLOR { + static const CommandId kCmdId = command_buffer::SET_SAMPLER_BORDER_COLOR; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + float red; + float blue; + float green; + float alpha; +}; + +struct SET_SAMPLER_TEXTURE { + static const CommandId kCmdId = command_buffer::SET_SAMPLER_TEXTURE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 texture_id; +}; + +struct SET_SCISSOR { + static const CommandId kCmdId = command_buffer::SET_SCISSOR; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; + uint32 fixme1; +}; + +struct SET_POLYGON_OFFSET { + static const CommandId kCmdId = command_buffer::SET_POLYGON_OFFSET; + static const ArgFlags kArgFlags = kFixed; + float slope_factor; + float units; +}; + +struct SET_POINT_LINE_RASTER { + static const CommandId kCmdId = command_buffer::SET_POINT_LINE_RASTER; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; + float point_size; +}; + +struct SET_POLYGON_RASTER { + static const CommandId kCmdId = command_buffer::SET_POLYGON_RASTER; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; +}; + +struct SET_ALPHA_TEST { + static const CommandId kCmdId = command_buffer::SET_ALPHA_TEST; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; + float value; +}; + +struct SET_DEPTH_TEST { + static const CommandId kCmdId = command_buffer::SET_DEPTH_TEST; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; +}; + +struct SET_STENCIL_TEST { + static const CommandId kCmdId = command_buffer::SET_STENCIL_TEST; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_COLOR_WRITE { + static const CommandId kCmdId = command_buffer::SET_COLOR_WRITE; + static const ArgFlags kArgFlags = kFixed; + uint32 flags; +}; + +struct SET_BLENDING { + static const CommandId kCmdId = command_buffer::SET_BLENDING; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_BLENDING_COLOR { + static const CommandId kCmdId = command_buffer::SET_BLENDING_COLOR; + static const ArgFlags kArgFlags = kFixed; + float red; + float blue; + float green; + float alpha; +}; + +struct CREATE_RENDER_SURFACE { + static const CommandId kCmdId = command_buffer::CREATE_RENDER_SURFACE; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 id; + uint32 fixme1; + uint32 fixme2; + uint32 texture_id; +}; + +struct DESTROY_RENDER_SURFACE { + static const CommandId kCmdId = command_buffer::DESTROY_RENDER_SURFACE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct CREATE_DEPTH_SURFACE { + static const CommandId kCmdId = command_buffer::CREATE_DEPTH_SURFACE; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 id; + uint32 fixme1; +}; + +struct DESTROY_DEPTH_SURFACE { + static const CommandId kCmdId = command_buffer::DESTROY_DEPTH_SURFACE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_RENDER_SURFACE { + static const CommandId kCmdId = command_buffer::SET_RENDER_SURFACE; + static const ArgFlags kArgFlags = kFixed; + uint32 render_surface_id; + uint32 depth_surface_id; +}; + +struct SET_BACK_SURFACES { + static const CommandId kCmdId = command_buffer::SET_BACK_SURFACES; + static const ArgFlags kArgFlags = kFixed; +}; + +O3D_POP_STRUCTURE_PACKING; + +} // namespace cmd + } // namespace command_buffer } // namespace o3d diff --git a/o3d/command_buffer/service/cross/cmd_parser.h b/o3d/command_buffer/service/cross/cmd_parser.h index 511e52b..9c3a145 100644 --- a/o3d/command_buffer/service/cross/cmd_parser.h +++ b/o3d/command_buffer/service/cross/cmd_parser.h @@ -104,7 +104,7 @@ class AsyncAPIInterface { virtual BufferSyncInterface::ParseError DoCommand( unsigned int command, unsigned int arg_count, - CommandBufferEntry *args) = 0; + const void* args) = 0; }; } // namespace command_buffer diff --git a/o3d/command_buffer/service/cross/gapi_decoder.cc b/o3d/command_buffer/service/cross/gapi_decoder.cc index 3087733..47a3418 100644 --- a/o3d/command_buffer/service/cross/gapi_decoder.cc +++ b/o3d/command_buffer/service/cross/gapi_decoder.cc @@ -41,6 +41,40 @@ namespace o3d { namespace command_buffer { +namespace { + +template <typename T> +const void* AddressAfterStruct(const T& pod) { + return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); +} + +template <typename T> +unsigned int ImmediateSize(uint32 arg_count, const T& pod) { + return (arg_count - sizeof(pod) / sizeof(uint32)) * sizeof(uint32); +} + +// TODO(gman): Remove this. +CommandBufferEntry* TempHack(const void* foo) { + return reinterpret_cast<CommandBufferEntry*>(const_cast<void*>(foo)); +} + +struct CommandInfo { + int arg_flags; + int arg_count; +}; + +const CommandInfo g_command_info[] = { + #define O3D_COMMAND_BUFFER_CMD_OP(name) { \ + cmd::name::kArgFlags, \ + sizeof(cmd::name) / sizeof(uint32), }, \ + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP +}; + +} // anonymous namespace. + // Decode command with its arguments, and call the corresponding GAPIInterface // method. // Note: args is a pointer to the command buffer. As such, it could be changed @@ -49,586 +83,30 @@ namespace command_buffer { BufferSyncInterface::ParseError GAPIDecoder::DoCommand( unsigned int command, unsigned int arg_count, - CommandBufferEntry *args) { - switch (command) { - case NOOP: - return BufferSyncInterface::PARSE_NO_ERROR; - case SET_TOKEN: - if (arg_count == 1) { - engine_->set_token(args[0].value_uint32); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case BEGIN_FRAME: - if (arg_count == 0) { - gapi_->BeginFrame(); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case END_FRAME: - if (arg_count == 0) { - gapi_->EndFrame(); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CLEAR: - if (arg_count == 7) { - unsigned int buffers = args[0].value_uint32; - if (buffers & ~GAPIInterface::ALL_BUFFERS) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - RGBA rgba; - rgba.red = args[1].value_float; - rgba.green = args[2].value_float; - rgba.blue = args[3].value_float; - rgba.alpha = args[4].value_float; - float depth = args[5].value_float; - unsigned int stencil = args[6].value_uint32; - gapi_->Clear(buffers, rgba, depth, stencil); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_VIEWPORT: - if (arg_count == 6) { - gapi_->SetViewport(args[0].value_uint32, - args[1].value_uint32, - args[2].value_uint32, - args[3].value_uint32, - args[4].value_float, - args[5].value_float); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_VERTEX_BUFFER: - if (arg_count == 3) { - return gapi_->CreateVertexBuffer(args[0].value_uint32, - args[1].value_uint32, - args[2].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_VERTEX_BUFFER: - if (arg_count == 1) { - return gapi_->DestroyVertexBuffer(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_VERTEX_BUFFER_DATA_IMMEDIATE: { - if (arg_count < 2) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = (arg_count - 2) * sizeof(args[0]); - return gapi_->SetVertexBufferData(id, offset, size, args + 2); - } - case SET_VERTEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetVertexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_VERTEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetVertexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_INDEX_BUFFER: - if (arg_count == 3) { - return gapi_->CreateIndexBuffer(args[0].value_uint32, - args[1].value_uint32, - args[2].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_INDEX_BUFFER: - if (arg_count == 1) { - return gapi_->DestroyIndexBuffer(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + const void* args) { + if (command < arraysize(g_command_info)) { + const CommandInfo& info = g_command_info[command]; + if ((info.arg_flags == cmd::kFixed && arg_count == info.arg_count) || + (info.arg_flags == cmd::kAtLeastN && arg_count > info.arg_count)) { + switch (command) { + #define O3D_COMMAND_BUFFER_CMD_OP(name) \ + case cmd::name::kCmdId: \ + return Handle_ ## name( \ + arg_count, \ + *static_cast<const cmd::name*>(args)); \ + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP } - case SET_INDEX_BUFFER_DATA_IMMEDIATE: { - if (arg_count < 2) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = (arg_count - 2) * sizeof(args[0]); - return gapi_->SetIndexBufferData(id, offset, size, args + 2); + } else { + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } - case SET_INDEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetIndexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_INDEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetIndexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_VERTEX_STRUCT: - if (arg_count == 2) { - return gapi_->CreateVertexStruct(args[0].value_uint32, - args[1].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_VERTEX_STRUCT: - if (arg_count == 1) { - return gapi_->DestroyVertexStruct(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_VERTEX_INPUT: - return DecodeSetVertexInput(arg_count, args); - case SET_VERTEX_STRUCT: - if (arg_count == 1) { - return gapi_->SetVertexStruct(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DRAW: - if (arg_count == 3) { - unsigned int primitive_type = args[0].value_uint32; - if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - unsigned int first = args[1].value_uint32; - unsigned int count = args[2].value_uint32; - return gapi_->Draw( - static_cast<GAPIInterface::PrimitiveType>(primitive_type), - first, count); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DRAW_INDEXED: - if (arg_count == 6) { - unsigned int primitive_type = args[0].value_uint32; - if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - ResourceID index_buffer = args[1].value_uint32; - unsigned int first = args[2].value_uint32; - unsigned int count = args[3].value_uint32; - unsigned int min_index = args[4].value_uint32; - unsigned int max_index = args[5].value_uint32; - return gapi_->DrawIndexed( - static_cast<GAPIInterface::PrimitiveType>(primitive_type), - index_buffer, first, count, min_index, max_index); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_EFFECT: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateEffect(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_EFFECT_IMMEDIATE: - if (arg_count > 2) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - if (size > (arg_count-2) * sizeof(args[0])) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateEffect(id, size, args + 2); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_EFFECT: - if (arg_count == 1) { - return gapi_->DestroyEffect(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_EFFECT: - if (arg_count == 1) { - return gapi_->SetEffect(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_PARAM_COUNT: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetParamCount(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_PARAM: - if (arg_count == 3) { - ResourceID param_id = args[0].value_uint32; - ResourceID effect_id = args[1].value_uint32; - unsigned int index = args[2].value_uint32; - return gapi_->CreateParam(param_id, effect_id, index); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_PARAM_BY_NAME: - if (arg_count == 5) { - ResourceID param_id = args[0].value_uint32; - ResourceID effect_id = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateParamByName(param_id, effect_id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_PARAM_BY_NAME_IMMEDIATE: - if (arg_count > 3) { - ResourceID param_id = args[0].value_uint32; - ResourceID effect_id = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - if (size > (arg_count-1) * sizeof(args[0])) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateParamByName(param_id, effect_id, size, args + 3); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_PARAM: - if (arg_count == 1) { - return gapi_->DestroyParam(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_PARAM_DATA: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetParamData(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_PARAM_DATA_IMMEDIATE: - if (arg_count > 2) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - if (size > (arg_count-2) * sizeof(args[0])) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetParamData(id, size, args + 2); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_PARAM_DESC: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetParamDesc(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_STREAM_COUNT: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetStreamCount(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_STREAM_DESC: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int index = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetStreamDesc(id, index, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_TEXTURE: - if (arg_count == 1) { - return gapi_->DestroyTexture(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_TEXTURE_2D: - return DecodeCreateTexture2D(arg_count, args); - case CREATE_TEXTURE_3D: - return DecodeCreateTexture3D(arg_count, args); - case CREATE_TEXTURE_CUBE: - return DecodeCreateTextureCube(arg_count, args); - case SET_TEXTURE_DATA: - return DecodeSetTextureData(arg_count, args); - case SET_TEXTURE_DATA_IMMEDIATE: - return DecodeSetTextureDataImmediate(arg_count, args); - case GET_TEXTURE_DATA: - return DecodeGetTextureData(arg_count, args); - case CREATE_SAMPLER: - if (arg_count == 1) { - return gapi_->CreateSampler(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_SAMPLER: - if (arg_count == 1) { - return gapi_->DestroySampler(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_SAMPLER_STATES: - return DecodeSetSamplerStates(arg_count, args); - case SET_SAMPLER_BORDER_COLOR: - if (arg_count == 5) { - RGBA rgba; - rgba.red = args[1].value_float; - rgba.green = args[2].value_float; - rgba.blue = args[3].value_float; - rgba.alpha = args[4].value_float; - return gapi_->SetSamplerBorderColor(args[0].value_uint32, rgba); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_SAMPLER_TEXTURE: - if (arg_count == 2) { - return gapi_->SetSamplerTexture(args[0].value_uint32, - args[1].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_SCISSOR: - if (arg_count == 2) { - namespace cmd = set_scissor; - Uint32 x_y_enable = args[0].value_uint32; - if (cmd::Unused::Get(x_y_enable) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - unsigned int x = cmd::X::Get(x_y_enable); - unsigned int y = cmd::Y::Get(x_y_enable); - bool enable = cmd::Enable::Get(x_y_enable) != 0; - Uint32 width_height = args[1].value_uint32; - unsigned int width = cmd::Width::Get(width_height); - unsigned int height = cmd::Height::Get(width_height); - gapi_->SetScissor(enable, x, y, width, height); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_POLYGON_OFFSET: - if (arg_count == 2) { - gapi_->SetPolygonOffset(args[0].value_float, args[1].value_float); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_POINT_LINE_RASTER: - if (arg_count == 2) { - namespace cmd = set_point_line_raster; - Uint32 enables = args[0].value_uint32; - if (cmd::Unused::Get(enables) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - // !! to convert int to bool in a way that does not generate a - // warning in visual studio. - bool line_smooth = !!cmd::LineSmoothEnable::Get(enables); - bool point_sprite = !!cmd::PointSpriteEnable::Get(enables); - float point_size = args[1].value_float; - gapi_->SetPointLineRaster(line_smooth, point_sprite, point_size); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_POLYGON_RASTER: - if (arg_count == 1) { - namespace cmd = set_polygon_raster; - Uint32 fill_cull = args[0].value_uint32; - unsigned int fill_value = cmd::FillMode::Get(fill_cull); - unsigned int cull_value = cmd::CullMode::Get(fill_cull); - if (cmd::Unused::Get(fill_cull) != 0 || - fill_value >= GAPIInterface::NUM_POLYGON_MODE || - cull_value >= GAPIInterface::NUM_FACE_CULL_MODE) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - gapi_->SetPolygonRaster( - static_cast<GAPIInterface::PolygonMode>(fill_value), - static_cast<GAPIInterface::FaceCullMode>(cull_value)); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_ALPHA_TEST: - if (arg_count == 2) { - namespace cmd = set_alpha_test; - Uint32 func_enable = args[0].value_uint32; - if (cmd::Unused::Get(func_enable) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - // Check that the bitmask get cannot generate values outside of the - // allowed range. - COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, - set_alpha_test_Func_may_produce_invalid_values); - GAPIInterface::Comparison comp = - static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); - bool enable = cmd::Enable::Get(func_enable) != 0; - gapi_->SetAlphaTest(enable, args[1].value_float, comp); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_DEPTH_TEST: - if (arg_count == 1) { - namespace cmd = set_depth_test; - Uint32 func_enable = args[0].value_uint32; - if (cmd::Unused::Get(func_enable) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - // Check that the bitmask get cannot generate values outside of the - // allowed range. - COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, - set_alpha_test_Func_may_produce_invalid_values); - GAPIInterface::Comparison comp = - static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); - bool write_enable = cmd::WriteEnable::Get(func_enable) != 0; - bool enable = cmd::Enable::Get(func_enable) != 0; - gapi_->SetDepthTest(enable, write_enable, comp); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_STENCIL_TEST: - return DecodeSetStencilTest(arg_count, args); - case SET_COLOR_WRITE: - if (arg_count == 1) { - namespace cmd = set_color_write; - Uint32 enables = args[0].value_uint32; - if (cmd::Unused::Get(enables) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - bool red = cmd::RedMask::Get(enables) != 0; - bool green = cmd::GreenMask::Get(enables) != 0; - bool blue = cmd::BlueMask::Get(enables) != 0; - bool alpha = cmd::AlphaMask::Get(enables) != 0; - bool dither = cmd::DitherEnable::Get(enables) != 0; - gapi_->SetColorWrite(red, green, blue, alpha, dither); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_BLENDING: - return DecodeSetBlending(arg_count, args); - case SET_BLENDING_COLOR: - if (arg_count == 4) { - RGBA rgba; - rgba.red = args[0].value_float; - rgba.green = args[1].value_float; - rgba.blue = args[2].value_float; - rgba.alpha = args[3].value_float; - gapi_->SetBlendingColor(rgba); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_RENDER_SURFACE: - if (arg_count == 4) { - namespace cmd = create_render_surface_cmd; - ResourceID id = args[0].value_uint32; - unsigned int width_height = args[1].value_uint32; - unsigned int width = cmd::Width::Get(width_height); - unsigned int height = cmd::Height::Get(width_height); - unsigned int levels_side = args[2].value_uint32; - unsigned int mip_level = cmd::Levels::Get(levels_side); - unsigned int side = cmd::Side::Get(levels_side); - ResourceID texture_id = args[3].value_uint32; - return gapi_->CreateRenderSurface(id, width, height, mip_level, - side, texture_id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_RENDER_SURFACE: - if (arg_count == 1) { - ResourceID id = args[0].value_uint32; - return gapi_->DestroyRenderSurface(id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_DEPTH_SURFACE: - if (arg_count == 2) { - namespace cmd = create_render_surface_cmd; - ResourceID id = args[0].value_uint32; - unsigned int width_height = args[1].value_uint32; - unsigned int width = cmd::Width::Get(width_height); - unsigned int height = cmd::Height::Get(width_height); - return gapi_->CreateDepthSurface(id, width, height); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_DEPTH_SURFACE: - if (arg_count == 1) { - ResourceID id = args[0].value_uint32; - return gapi_->DestroyDepthSurface(id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_RENDER_SURFACE: - if (arg_count == 2) { - ResourceID render_surface_id = args[0].value_uint32; - ResourceID depth_stencil_id = args[1].value_uint32; - return gapi_->SetRenderSurface(render_surface_id, depth_stencil_id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_BACK_SURFACES: - if (arg_count == 0) { - gapi_->SetBackSurfaces(); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - default: - return BufferSyncInterface::PARSE_UNKNOWN_COMMAND; } + return BufferSyncInterface::PARSE_UNKNOWN_COMMAND; } + // Decodes the SET_VERTEX_INPUT command. BufferSyncInterface::ParseError GAPIDecoder::DecodeSetVertexInput( unsigned int arg_count, @@ -965,5 +443,620 @@ void *GAPIDecoder::GetAddressAndCheckSize(unsigned int shm_id, return static_cast<char *>(shm_addr) + offset; } +BufferSyncInterface::ParseError GAPIDecoder::Handle_NOOP( + uint32 arg_count, + const cmd::NOOP& args) { + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_TOKEN( + uint32 arg_count, + const cmd::SET_TOKEN& args) { + engine_->set_token(args.token); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_BEGIN_FRAME( + uint32 arg_count, + const cmd::BEGIN_FRAME& args) { + gapi_->BeginFrame(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_END_FRAME( + uint32 arg_count, + const cmd::END_FRAME& args) { + gapi_->EndFrame(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CLEAR( + uint32 arg_count, + const cmd::CLEAR& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 buffers = args.buffers; + if (buffers & ~GAPIInterface::ALL_BUFFERS) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + gapi_->Clear(buffers, rgba, args.depth, args.stencil); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VIEWPORT( + uint32 arg_count, + const cmd::SET_VIEWPORT& args) { + gapi_->SetViewport(args.left, + args.top, + args.width, + args.height, + args.z_min, + args.z_max); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_VERTEX_BUFFER( + uint32 arg_count, + const cmd::CREATE_VERTEX_BUFFER& args) { + return gapi_->CreateVertexBuffer(args.id, args.size, args.flags); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_VERTEX_BUFFER( + uint32 arg_count, + const cmd::DESTROY_VERTEX_BUFFER& args) { + return gapi_->DestroyVertexBuffer(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_BUFFER_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_VERTEX_BUFFER_DATA_IMMEDIATE& args) { + return gapi_->SetVertexBufferData(args.id, args.offset, + ImmediateSize(arg_count, args), + AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_BUFFER_DATA( + uint32 arg_count, + const cmd::SET_VERTEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetVertexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_VERTEX_BUFFER_DATA( + uint32 arg_count, + const cmd::GET_VERTEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetVertexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_INDEX_BUFFER( + uint32 arg_count, + const cmd::CREATE_INDEX_BUFFER& args) { + return gapi_->CreateIndexBuffer(args.id, args.size, args.flags); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_INDEX_BUFFER( + uint32 arg_count, + const cmd::DESTROY_INDEX_BUFFER& args) { + return gapi_->DestroyIndexBuffer(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_INDEX_BUFFER_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_INDEX_BUFFER_DATA_IMMEDIATE& args) { + return gapi_->SetIndexBufferData(args.id, args.offset, + ImmediateSize(arg_count, args), + AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_INDEX_BUFFER_DATA( + uint32 arg_count, + const cmd::SET_INDEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetIndexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_INDEX_BUFFER_DATA( + uint32 arg_count, + const cmd::GET_INDEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetIndexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_VERTEX_STRUCT( + uint32 arg_count, + const cmd::CREATE_VERTEX_STRUCT& args) { + return gapi_->CreateVertexStruct(args.id, args.input_count); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_VERTEX_STRUCT( + uint32 arg_count, + const cmd::DESTROY_VERTEX_STRUCT& args) { + return gapi_->DestroyVertexStruct(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_INPUT( + uint32 arg_count, + const cmd::SET_VERTEX_INPUT& args) { + // TODO(gman): fix. + return DecodeSetVertexInput(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_STRUCT( + uint32 arg_count, + const cmd::SET_VERTEX_STRUCT& args) { + return gapi_->SetVertexStruct(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DRAW( + uint32 arg_count, + const cmd::DRAW& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 primitive_type = args.primitive_type; + if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->Draw( + static_cast<GAPIInterface::PrimitiveType>(primitive_type), + args.first, args.count); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DRAW_INDEXED( + uint32 arg_count, + const cmd::DRAW_INDEXED& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 primitive_type = args.primitive_type; + if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->DrawIndexed( + static_cast<GAPIInterface::PrimitiveType>(primitive_type), + args.index_buffer_id, + args.first, args.count, args.min_index, args.max_index); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_EFFECT( + uint32 arg_count, + const cmd::CREATE_EFFECT& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateEffect(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_EFFECT_IMMEDIATE( + uint32 arg_count, + const cmd::CREATE_EFFECT_IMMEDIATE& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + if (size > ImmediateSize(arg_count, args)) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateEffect(args.id, size, AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_EFFECT( + uint32 arg_count, + const cmd::DESTROY_EFFECT& args) { + return gapi_->DestroyEffect(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_EFFECT( + uint32 arg_count, + const cmd::SET_EFFECT& args) { + return gapi_->SetEffect(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_PARAM_COUNT( + uint32 arg_count, + const cmd::GET_PARAM_COUNT& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetParamCount(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_PARAM( + uint32 arg_count, + const cmd::CREATE_PARAM& args) { + return gapi_->CreateParam(args.param_id, args.effect_id, args.index); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_PARAM_BY_NAME( + uint32 arg_count, + const cmd::CREATE_PARAM_BY_NAME& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateParamByName(args.param_id, args.effect_id, size, + data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_PARAM_BY_NAME_IMMEDIATE( + uint32 arg_count, + const cmd::CREATE_PARAM_BY_NAME_IMMEDIATE& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + if (size > ImmediateSize(arg_count, args)) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateParamByName(args.param_id, args.effect_id, size, + AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_PARAM( + uint32 arg_count, + const cmd::DESTROY_PARAM& args) { + return gapi_->DestroyParam(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_PARAM_DATA( + uint32 arg_count, + const cmd::SET_PARAM_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetParamData(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_PARAM_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_PARAM_DATA_IMMEDIATE& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + if (size > ImmediateSize(arg_count, args)) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetParamData(args.id, size, AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_PARAM_DESC( + uint32 arg_count, + const cmd::GET_PARAM_DESC& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetParamDesc(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_STREAM_COUNT( + uint32 arg_count, + const cmd::GET_STREAM_COUNT& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetStreamCount(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_STREAM_DESC( + uint32 arg_count, + const cmd::GET_STREAM_DESC& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetStreamDesc(args.id, args.index, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_TEXTURE( + uint32 arg_count, + const cmd::DESTROY_TEXTURE& args) { + return gapi_->DestroyTexture(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_TEXTURE_2D( + uint32 arg_count, + const cmd::CREATE_TEXTURE_2D& args) { + // TODO(gman): fix. + return DecodeCreateTexture2D(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_TEXTURE_3D( + uint32 arg_count, + const cmd::CREATE_TEXTURE_3D& args) { + // TODO(gman): fix. + return DecodeCreateTexture3D(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_TEXTURE_CUBE( + uint32 arg_count, + const cmd::CREATE_TEXTURE_CUBE& args) { + // TODO(gman): fix. + return DecodeCreateTextureCube(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_TEXTURE_DATA( + uint32 arg_count, + const cmd::SET_TEXTURE_DATA& args) { + // TODO(gman): fix. + return DecodeSetTextureData(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_TEXTURE_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_TEXTURE_DATA_IMMEDIATE& args) { + // TODO(gman): fix. + return DecodeSetTextureDataImmediate(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_TEXTURE_DATA( + uint32 arg_count, + const cmd::GET_TEXTURE_DATA& args) { + // TODO(gman): fix. + return DecodeGetTextureData(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_SAMPLER( + uint32 arg_count, + const cmd::CREATE_SAMPLER& args) { + return gapi_->CreateSampler(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_SAMPLER( + uint32 arg_count, + const cmd::DESTROY_SAMPLER& args) { + return gapi_->DestroySampler(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SAMPLER_STATES( + uint32 arg_count, + const cmd::SET_SAMPLER_STATES& args) { + // TODO(gman): fix. + return DecodeSetSamplerStates(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SAMPLER_BORDER_COLOR( + uint32 arg_count, + const cmd::SET_SAMPLER_BORDER_COLOR& args) { + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + return gapi_->SetSamplerBorderColor(args.id, rgba); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SAMPLER_TEXTURE( + uint32 arg_count, + const cmd::SET_SAMPLER_TEXTURE& args) { + return gapi_->SetSamplerTexture(args.id, args.texture_id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SCISSOR( + uint32 arg_count, + const cmd::SET_SCISSOR& args) { + namespace cmd = set_scissor; + Uint32 x_y_enable = args.fixme0; + if (cmd::Unused::Get(x_y_enable) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + unsigned int x = cmd::X::Get(x_y_enable); + unsigned int y = cmd::Y::Get(x_y_enable); + bool enable = cmd::Enable::Get(x_y_enable) != 0; + Uint32 width_height = args.fixme1; + unsigned int width = cmd::Width::Get(width_height); + unsigned int height = cmd::Height::Get(width_height); + gapi_->SetScissor(enable, x, y, width, height); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_POLYGON_OFFSET( + uint32 arg_count, + const cmd::SET_POLYGON_OFFSET& args) { + gapi_->SetPolygonOffset(args.slope_factor, args.units); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_POINT_LINE_RASTER( + uint32 arg_count, + const cmd::SET_POINT_LINE_RASTER& args) { + namespace cmd = set_point_line_raster; + Uint32 enables = args.fixme0; + if (cmd::Unused::Get(enables) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + bool line_smooth = !!cmd::LineSmoothEnable::Get(enables); + bool point_sprite = !!cmd::PointSpriteEnable::Get(enables); + gapi_->SetPointLineRaster(line_smooth, point_sprite, args.point_size); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_POLYGON_RASTER( + uint32 arg_count, + const cmd::SET_POLYGON_RASTER& args) { + namespace cmd = set_polygon_raster; + Uint32 fill_cull = args.fixme0; + unsigned int fill_value = cmd::FillMode::Get(fill_cull); + unsigned int cull_value = cmd::CullMode::Get(fill_cull); + if (cmd::Unused::Get(fill_cull) != 0 || + fill_value >= GAPIInterface::NUM_POLYGON_MODE || + cull_value >= GAPIInterface::NUM_FACE_CULL_MODE) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + gapi_->SetPolygonRaster( + static_cast<GAPIInterface::PolygonMode>(fill_value), + static_cast<GAPIInterface::FaceCullMode>(cull_value)); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_ALPHA_TEST( + uint32 arg_count, + const cmd::SET_ALPHA_TEST& args) { + namespace cmd = set_alpha_test; + Uint32 func_enable = args.fixme0; + if (cmd::Unused::Get(func_enable) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + // Check that the bitmask get cannot generate values outside of the + // allowed range. + COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, + set_alpha_test_Func_may_produce_invalid_values); + GAPIInterface::Comparison comp = + static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); + bool enable = cmd::Enable::Get(func_enable) != 0; + gapi_->SetAlphaTest(enable, args.value, comp); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_DEPTH_TEST( + uint32 arg_count, + const cmd::SET_DEPTH_TEST& args) { + namespace cmd = set_depth_test; + Uint32 func_enable = args.fixme0; + if (cmd::Unused::Get(func_enable) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + // Check that the bitmask get cannot generate values outside of the + // allowed range. + COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, + set_alpha_test_Func_may_produce_invalid_values); + GAPIInterface::Comparison comp = + static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); + bool write_enable = cmd::WriteEnable::Get(func_enable) != 0; + bool enable = cmd::Enable::Get(func_enable) != 0; + gapi_->SetDepthTest(enable, write_enable, comp); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_STENCIL_TEST( + uint32 arg_count, + const cmd::SET_STENCIL_TEST& args) { + // TODO(gman): fix. + return DecodeSetStencilTest(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_COLOR_WRITE( + uint32 arg_count, + const cmd::SET_COLOR_WRITE& args) { + namespace cmd = set_color_write; + Uint32 enables = args.flags; + if (cmd::Unused::Get(enables) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + bool red = cmd::RedMask::Get(enables) != 0; + bool green = cmd::GreenMask::Get(enables) != 0; + bool blue = cmd::BlueMask::Get(enables) != 0; + bool alpha = cmd::AlphaMask::Get(enables) != 0; + bool dither = cmd::DitherEnable::Get(enables) != 0; + gapi_->SetColorWrite(red, green, blue, alpha, dither); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_BLENDING( + uint32 arg_count, + const cmd::SET_BLENDING& args) { + return DecodeSetBlending(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_BLENDING_COLOR( + uint32 arg_count, + const cmd::SET_BLENDING_COLOR& args) { + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + gapi_->SetBlendingColor(rgba); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_RENDER_SURFACE( + uint32 arg_count, + const cmd::CREATE_RENDER_SURFACE& args) { + namespace cmd = create_render_surface_cmd; + unsigned int width_height = args.fixme1; + unsigned int width = cmd::Width::Get(width_height); + unsigned int height = cmd::Height::Get(width_height); + unsigned int levels_side = args.fixme2; + unsigned int mip_level = cmd::Levels::Get(levels_side); + unsigned int side = cmd::Side::Get(levels_side); + return gapi_->CreateRenderSurface(args.id, width, height, mip_level, + side, args.texture_id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_RENDER_SURFACE( + uint32 arg_count, + const cmd::DESTROY_RENDER_SURFACE& args) { + return gapi_->DestroyRenderSurface(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_DEPTH_SURFACE( + uint32 arg_count, + const cmd::CREATE_DEPTH_SURFACE& args) { + namespace cmd = create_render_surface_cmd; + unsigned int width_height = args.fixme1; + unsigned int width = cmd::Width::Get(width_height); + unsigned int height = cmd::Height::Get(width_height); + return gapi_->CreateDepthSurface(args.id, width, height); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_DEPTH_SURFACE( + uint32 arg_count, + const cmd::DESTROY_DEPTH_SURFACE& args) { + return gapi_->DestroyDepthSurface(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_RENDER_SURFACE( + uint32 arg_count, + const cmd::SET_RENDER_SURFACE& args) { + return gapi_->SetRenderSurface(args.render_surface_id, args.depth_surface_id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_BACK_SURFACES( + uint32 arg_count, + const cmd::SET_BACK_SURFACES& args) { + gapi_->SetBackSurfaces(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + } // namespace command_buffer } // namespace o3d diff --git a/o3d/command_buffer/service/cross/gapi_decoder.h b/o3d/command_buffer/service/cross/gapi_decoder.h index 24d55e0..67b1806 100644 --- a/o3d/command_buffer/service/cross/gapi_decoder.h +++ b/o3d/command_buffer/service/cross/gapi_decoder.h @@ -62,7 +62,7 @@ class GAPIDecoder : public AsyncAPIInterface { // BufferSyncInterface::ParseError otherwise. virtual ParseError DoCommand(unsigned int command, unsigned int arg_count, - CommandBufferEntry *args); + const void* args); // Sets the engine, to get shared memory buffers from, and to set the token // to. @@ -121,6 +121,18 @@ class GAPIDecoder : public AsyncAPIInterface { void *GetAddressAndCheckSize(unsigned int shm_id, unsigned int offset, unsigned int size); + + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define O3D_COMMAND_BUFFER_CMD_OP(name) \ + ParseError Handle_ ## name( \ + unsigned int arg_count, \ + const cmd::name& args); \ + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP + GAPIInterface *gapi_; CommandBufferEngine *engine_; }; diff --git a/o3d/command_buffer/service/cross/mocks.h b/o3d/command_buffer/service/cross/mocks.h index 3d150ee..353ff0c 100644 --- a/o3d/command_buffer/service/cross/mocks.h +++ b/o3d/command_buffer/service/cross/mocks.h @@ -58,11 +58,13 @@ class AsyncAPIMock : public AsyncAPIInterface { // Predicate that matches args passed to DoCommand, by looking at the values. class IsArgs { public: - IsArgs(unsigned int arg_count, CommandBufferEntry *args) + IsArgs(unsigned int arg_count, const void* args) : arg_count_(arg_count), - args_(args) { } + args_(static_cast<CommandBufferEntry*>(const_cast<void*>(args))) { } - bool operator() (CommandBufferEntry *args) const { + bool operator() (const void* _args) const { + const CommandBufferEntry* args = + static_cast<const CommandBufferEntry*>(_args); for (unsigned int i = 0; i < arg_count_; ++i) { if (args[i].value_uint32 != args_[i].value_uint32) return false; } @@ -77,7 +79,7 @@ class AsyncAPIMock : public AsyncAPIInterface { MOCK_METHOD3(DoCommand, BufferSyncInterface::ParseError( unsigned int command, unsigned int arg_count, - CommandBufferEntry *args)); + const void* args)); // Sets the engine, to forward SET_TOKEN commands to it. void set_engine(CommandBufferEngine *engine) { engine_ = engine; } @@ -85,10 +87,12 @@ class AsyncAPIMock : public AsyncAPIInterface { // Forwards the SetToken commands to the engine. void SetToken(unsigned int command, unsigned int arg_count, - CommandBufferEntry *args) { + const void* _args) { DCHECK(engine_); DCHECK_EQ(1, command); DCHECK_EQ(1, arg_count); + const CommandBufferEntry* args = + static_cast<const CommandBufferEntry*>(_args); engine_->set_token(args[0].value_uint32); } private: |